diff options
author | The Android Open Source Project <initial-contribution@android.com> | 2009-03-03 19:29:28 -0800 |
---|---|---|
committer | The Android Open Source Project <initial-contribution@android.com> | 2009-03-03 19:29:28 -0800 |
commit | 441f72d43a9b550baa779fc82f70816da5f74f0e (patch) | |
tree | 477ac2b54c1ef5b8e25e4255b27bca9469ed3911 /libdw | |
parent | 7a80622f69812ca3262d2027c07a4ed0c0242945 (diff) | |
download | android_external_elfutils-441f72d43a9b550baa779fc82f70816da5f74f0e.tar.gz android_external_elfutils-441f72d43a9b550baa779fc82f70816da5f74f0e.tar.bz2 android_external_elfutils-441f72d43a9b550baa779fc82f70816da5f74f0e.zip |
auto import from //depot/cupcake/@135843
Diffstat (limited to 'libdw')
77 files changed, 8216 insertions, 0 deletions
diff --git a/libdw/ChangeLog b/libdw/ChangeLog new file mode 100644 index 00000000..f0c4b6b6 --- /dev/null +++ b/libdw/ChangeLog @@ -0,0 +1,229 @@ +2004-09-25 Ulrich Drepper <drepper@redhat.com> + + * dwarf_child.c: Make compile with gcc 4.0. + * dwarf_error.c: Likewise. + * dwarf_formblock.c: Likewise. + * dwarf_getabbrev.c: Likewise. + * dwarf_getattrs.c: Likewise. + * dwarf_getsrclines.c: Likewise. + * dwarf_tag.c: Likewise. + * libdw_form.c: Likewise. + +2004-01-20 Ulrich Drepper <drepper@redhat.com> + + * Makefile.am: Support building with mudflap. + + * dwarf_getloclist.c: Fix warnings gcc 3.4 spits out. + * dwarf_getsrclines.c: Likewise. + * dwarf_memory-access.h: Likewise. + +2004-01-19 Ulrich Drepper <drepper@redhat.com> + + * dwarf_getsrcfiles.c: Third parameter can be NULL. + + * libdw.h: Define Dwarf_macro. Declare dwarf_getmacros. + Third parameter of dwarf_getsrcfiles can be NULL. + + * libdw.map: Add dwarf_getmacros. + * Makefile.am (libdw_a_SOURCES): Add dwarf_getmacros. + * dwarf_getmacros.c: New file. + +2004-01-18 Ulrich Drepper <drepper@redhat.com> + + * libdw.h: Second parameter of dwarf_getaranges can be NULL. + + * dwarf_nextcu.c: Return -1 if dwarf parameter is NULL. + + * dwarf_getsrclines.c: + Use read_2ubyte_unaligned_inc instead of _inc-less variant. + + * dwarf_getaranges.c: Allow naranges parameter to be NULL. + + * libdwP.h (_): Use elfutils domain. + + * dwarf_getsrclines.c (dwarf_getsrclines): Add more branch prediction. + + * dwarf_getsrclines.c: Fix typo in comment. + +2004-01-17 Ulrich Drepper <drepper@redhat.com> + + * Makefile.am: Support building with mudflap. + +2004-01-16 Ulrich Drepper <drepper@redhat.com> + + * memory-access.h: Add lots of const in case a pointer passed is const. + + * dwarf_formflag.c: New file. + * dwarf_getattrs.c: New file. + * dwarf_error.c: Add new error value. + * libdw.h: Add prototypes for new functions. Adjust prototype for + dwarf_getpubnames. + * libdw.map: Add new functions. + * dwarf_getpubnames.c: Change type of return value and fourth parameter + to ptrdiff_t. + * libdwP.h: Add new error value. + * Makefile.am (libdw_a_SOURCES): Add dwarf_getattrs.c and + dwarf_formflag.c. + + * dwarf_getpubnames.c (dwarf_getpubnames): Just fail if dbg is NULL. + +2004-01-12 Ulrich Drepper <drepper@redhat.com> + + * dwarf_getarange_addr.c: New file + * dwarf_getarangeinfo.c: New file. + * dwarf_getaranges.c: New file. + * dwarf_onerange.c: New file. + * libdw.h: Declare new functions. Define Dwarf_Arange and + Dwarf_Aranges. + * libdw.map: Add new functions. + * libdwP.h: Add new errors. Add aranges member to struct Dwarf. + Define Dwarf_Aranges_s and Dwarf_Arange_s. + * Makefile.am (libdw_a_SOURCES): Add dwarf_getaranges.c, + dwarf_onearange.c, dwarf_getarangeinfo.c, dwarf_getarange_addr.c. + * dwarf_error.c: Add new message. + +2004-01-11 Ulrich Drepper <drepper@redhat.com> + + * Makefile.am (libdw_a_SOURCES): Add dwarf_lineaddr.c, dwarf_linecol.c, + dwarf_linebeginstatement.c, dwarf_lineendsequence.c, dwarf_lineblock.c, + dwarf_lineprologueend.c, dwarf_lineepiloguebegin.c, dwarf_onesrcline.c. + * dwarf_error.c: Add another message. + * dwarf_getsrc_die.c: Adjust for Dwarf_Files and Dwarf_Lines + introduction. + * dwarf_filesrc.c: Likewise. + * dwarf_getsrcfiles.c: Likewise. + * dwarf_getsrclines.c: Likewise. + * dwarf_lineaddr.c: New file. + * dwarf_linebeginstatement.c: New file. + * dwarf_lineblock.c: New file. + * dwarf_linecol.c: New file. + * dwarf_lineendsequence.c: New file. + * dwarf_lineepiloguebegin.c: New file. + * dwarf_lineno.c: New file. + * dwarf_lineprologueend.c: New file. + * dwarf_onesrcline.c: New file. + * dwarf_lineno.c: Change interface to store result in object pointed + to by second parameter. + * libdw.h: Add prototypes for new functions. Change dwarf_lineno + prototype. Define Dwarf_Files and Dwarf_Lines. + * libdw.map: Add new functions. + * libdwP.h: Define Dwarf_Files_s and Dwarf_Lines_s. + * libdw_findcu.c: Don't initialize nlines field. + + * dwarf_siblingof: Little optimization. + + * dwarf_begin.c: Remember that the ELF descriptor must be closed. + * dwarf_end.c: Close ELF descriptor if free_elf is set. + * libdwP.h (struct Dwarf): Add free_elf field. + + * Makefile.am (libdw_a_SOURCES): Add dwarf_getstring.c and + dwarf_offabbrev.c. + * dwarf_getstring.c: New file. + * dwarf_offabbrev.c: New file. + * libdw.map: Add dwarf_getstring and dwarf_offabbrev. + * dwarf_getabbrev.c (__libdw_getabbrev): Add new dbg and result + parameters. Don't allocate memory if not necessary and don't lookup + previous results if no CU given. + (dwarf_getabbrev): Adjust call to __libdw_getabbrev. + * dwarf_tag.c: Adjust call to __libdw_getabbrev. + * libdw.h: Declare dwarf_offabbrev and dwarf_getstring. + * libdwP.h: Change prototype for __libdw_getabbrev. + + * dwarf_getabbrevattr.c: Add offsetp parameter. Fill in before + returning if this is wanted. + +2004-01-09 Ulrich Drepper <drepper@redhat.com> + + * dwarf_nextcu.c: Add new parameter offset_sizep. Initialize it + with offset_size value. + * libdw.h: Adjust dwarf_nextcu prototype. + * libdwP.h (struct Dwarf_CU): Add offset_size member. + * libdw_findcu.c: Adjust dwarf_nextcu call. Initialize offset_size + member of new CU struct. + * dwarf_formstring.c: Depend on offset_size not address_size for + DW_FORM_strp handling. + * dwarf_form.c: Likewise for DW_FORM_strp and DW_FORM_ref_addr. + + * dwarf_tag.c (__libdw_findabbrev): Return correct value for + failing lookup. + (dwarf_tag): Correctly recognize failed lookup. + + * dwarf_end.c (cu_free): Call tdestroy for locs member. Use new + function noop_free. + * dwarf_error.c: Add message for DWARF_E_NO_BLOCK. + * dwarf_formblock.c: New file. + * dwarf_getloclist.c: Rewrite to handle a single block. + * libdw.h: Define Dwarf_Block. Rename Dwarf_Loc members. Remove + Dwarf_Locdesc definition. Declare dwarf_formblock. Remove + dwarf_getloclistent declaration. + * libdw.map: Add dwarf_formblock, remove dwarf_getloclistent. + * libdwP.h: Define struct loc_s and DWARF_E_NO_BLOCK. + Add locs member to struct Dwarf_CU. + * libdw_fundcu.c: Initialize locs member of new CU. + * Makefile.am (libdw_a_SOURCES): Add dwarf_formblock.c. + Remove dwarf_getloclistent.c. + +2004-01-07 Ulrich Drepper <drepper@redhat.com> + + * libdw.h: Use __nonnull__ attribute only for gcc >= 3.3. + * libdwP.h: Likewise. + + * dwarf_getloclist.c: New file. + * dwarf_getloclistent.c: New file. + * libdw.h: Define Dwarf_Loc and Dwarf_Locdesc. + Declare dwarf_getloclistent and dwarf_getloclist. + * libdw.map: Add dwarf_getloclistent and dwarf_getloclist. + * libdwP.h: Define DWARF_E_NO_LOCLIST. + * Makefile.am (libdw_a_SOURCES): Add dwarf_getloclistent.c and + dwarf_getloclist.c. + + * dwarf_error.c: More error messages. + +2004-01-06 Ulrich Drepper <drepper@redhat.com> + + * dwarf_getsrclines.c: Remove debugging support. + + * dwarf_getsrcfiles.c: New file. + * dwarf_filesrc.c: New file. + * libdw.h: Declare these functions. Define Dwarf_File. + * libdwP.c: Adjust Dwarf_File_s definition. + * libdw.map: Add these functions. + * Makefile.am (libdw_a_SOURCES): Add dwarf_getsrcfiles.c and + dwarf_filesrc.c. + * dwarf_getsrclines.c: Initialize cu->files. + +2004-01-05 Ulrich Drepper <drepper@redhat.com> + + * libdw.h: Add more nonnull function attributes. + + * dwarf_begin_elf.c (dwarf_begin_elf): Don't initialize mem_tail->next. + * dwarf_end.c (cu_free): New function. + (dwarf_end): Also free CU tree. Correct freeing of memory blocks. + * dwarf_error.c (errmsgs): Add new messages. + * dwarf_getsrc_die.c: New file. + * dwarf_getsrclines.c: New file. + * dwarf_lineno.c: New file. + * dwarf_linesrc.c: New file. + * dwarf_nextcu.c (dwarf_nextcu): Use read_*byte_unaligned_inc + instead of the *_inc-less variants. + * libdw.h: Define Dwarf_Line. Add some function attributes. Declare + dwarf_getsrclines, dwarf_getsrc_die, dwarf_lineno, and dwarf_linesrc. + * libdw.map: Add dwarf_getsrclines, dwarf_getsrc_die, dwarf_lineno, + and dwarf_linesrc. + * libdwP.h: Add more error codes. + (struct Dwarf): Remove mem_tail.next member. + (Dwarf_File): Define type. + (struct Dwarf_Line_s): Define type. + (struct Dwarf_CU): Add lines and nlines members. + (libdw_alloc): Define local variable _tail and use it. + Add some function attributes. + * libdw_alloc.c (__libdw_allocate): Don't initialize next member. + * libdw_findcu.c (__libdw_findcu): Initialize lines and nlines members. + * memory-access.h: Add unlikely for the endian conversion paths. + * Makefile.am (AM_CFLAGS): Add -std parameter. + (libdw_a_SOURCES): Add dwarf_getsrclines, dwarf_getsrc_die, + dwarf_lineno, and dwarf_linesrc. + +2003-08-11 Ulrich Drepper <drepper@redhat.com> + + * Moved to CVS archive. diff --git a/libdw/Makefile b/libdw/Makefile new file mode 100644 index 00000000..ba960d4c --- /dev/null +++ b/libdw/Makefile @@ -0,0 +1,681 @@ +# Makefile.in generated by automake 1.9.2 from Makefile.am. +# libdw/Makefile. Generated from Makefile.in by configure. + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004 Free Software Foundation, Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + + + + + +SOURCES = $(libdw_a_SOURCES) $(libdw_pic_a_SOURCES) $(libdw_so_SOURCES) + +srcdir = . +top_srcdir = .. + +pkgdatadir = $(datadir)/elfutils +pkglibdir = $(libdir)/elfutils +pkgincludedir = $(includedir)/elfutils +top_builddir = .. +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +INSTALL = /usr/bin/install -c +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = i686-pc-linux-gnu +host_triplet = i686-pc-linux-gnu +noinst_PROGRAMS = $(am__EXEEXT_1) +#am_libdw_pic_a_OBJECTS = +subdir = libdw +DIST_COMMON = $(euinclude_HEADERS) $(include_HEADERS) \ + $(noinst_HEADERS) $(srcdir)/Makefile.am $(srcdir)/Makefile.in \ + ChangeLog +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/m4/gettext.m4 \ + $(top_srcdir)/m4/iconv.m4 $(top_srcdir)/m4/lib-ld.m4 \ + $(top_srcdir)/m4/lib-link.m4 $(top_srcdir)/m4/lib-prefix.m4 \ + $(top_srcdir)/m4/progtest.m4 $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +mkinstalldirs = $(SHELL) $(top_srcdir)/config/mkinstalldirs +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; +am__vpath_adj = case $$p in \ + $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ + *) f=$$p;; \ + esac; +am__strip_dir = `echo $$p | sed -e 's|^.*/||'`; +am__installdirs = "$(DESTDIR)$(libdir)" "$(DESTDIR)$(euincludedir)" \ + "$(DESTDIR)$(includedir)" +libLIBRARIES_INSTALL = $(INSTALL_DATA) +LIBRARIES = $(lib_LIBRARIES) $(noinst_LIBRARIES) +AR = ar +ARFLAGS = cru +libdw_a_AR = $(AR) $(ARFLAGS) +libdw_a_LIBADD = +am_libdw_a_OBJECTS = dwarf_begin.$(OBJEXT) dwarf_begin_elf.$(OBJEXT) \ + dwarf_end.$(OBJEXT) dwarf_getelf.$(OBJEXT) \ + dwarf_getpubnames.$(OBJEXT) dwarf_getabbrev.$(OBJEXT) \ + dwarf_tag.$(OBJEXT) dwarf_error.$(OBJEXT) \ + dwarf_nextcu.$(OBJEXT) dwarf_diename.$(OBJEXT) \ + dwarf_offdie.$(OBJEXT) dwarf_attr.$(OBJEXT) \ + dwarf_formstring.$(OBJEXT) dwarf_abbrev_hash.$(OBJEXT) \ + dwarf_child.$(OBJEXT) dwarf_haschildren.$(OBJEXT) \ + dwarf_formaddr.$(OBJEXT) dwarf_formudata.$(OBJEXT) \ + dwarf_formsdata.$(OBJEXT) dwarf_lowpc.$(OBJEXT) \ + dwarf_highpc.$(OBJEXT) dwarf_formref.$(OBJEXT) \ + dwarf_siblingof.$(OBJEXT) dwarf_dieoffset.$(OBJEXT) \ + dwarf_cuoffset.$(OBJEXT) dwarf_hasattr.$(OBJEXT) \ + dwarf_hasform.$(OBJEXT) dwarf_whatform.$(OBJEXT) \ + dwarf_whatattr.$(OBJEXT) dwarf_bytesize.$(OBJEXT) \ + dwarf_arrayorder.$(OBJEXT) dwarf_bitsize.$(OBJEXT) \ + dwarf_bitoffset.$(OBJEXT) dwarf_srclang.$(OBJEXT) \ + dwarf_getabbrevtag.$(OBJEXT) dwarf_getabbrevcode.$(OBJEXT) \ + dwarf_abbrevhaschildren.$(OBJEXT) dwarf_getattrcnt.$(OBJEXT) \ + dwarf_getabbrevattr.$(OBJEXT) dwarf_getsrclines.$(OBJEXT) \ + dwarf_getsrc_die.$(OBJEXT) dwarf_linesrc.$(OBJEXT) \ + dwarf_lineno.$(OBJEXT) dwarf_lineaddr.$(OBJEXT) \ + dwarf_linecol.$(OBJEXT) dwarf_linebeginstatement.$(OBJEXT) \ + dwarf_lineendsequence.$(OBJEXT) dwarf_lineblock.$(OBJEXT) \ + dwarf_lineprologueend.$(OBJEXT) \ + dwarf_lineepiloguebegin.$(OBJEXT) dwarf_onesrcline.$(OBJEXT) \ + dwarf_formblock.$(OBJEXT) dwarf_getsrcfiles.$(OBJEXT) \ + dwarf_filesrc.$(OBJEXT) dwarf_getloclist.$(OBJEXT) \ + dwarf_getstring.$(OBJEXT) dwarf_offabbrev.$(OBJEXT) \ + dwarf_getaranges.$(OBJEXT) dwarf_onearange.$(OBJEXT) \ + dwarf_getarangeinfo.$(OBJEXT) dwarf_getarange_addr.$(OBJEXT) \ + dwarf_getattrs.$(OBJEXT) dwarf_formflag.$(OBJEXT) \ + dwarf_getmacros.$(OBJEXT) libdw_findcu.$(OBJEXT) \ + libdw_form.$(OBJEXT) libdw_alloc.$(OBJEXT) +libdw_a_OBJECTS = $(am_libdw_a_OBJECTS) +libdw_pic_a_AR = $(AR) $(ARFLAGS) +libdw_pic_a_LIBADD = +libdw_pic_a_OBJECTS = $(am_libdw_pic_a_OBJECTS) +am__EXEEXT_1 = libdw.so$(EXEEXT) +PROGRAMS = $(noinst_PROGRAMS) +am_libdw_so_OBJECTS = +libdw_so_OBJECTS = $(am_libdw_so_OBJECTS) +libdw_so_LDADD = $(LDADD) +DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir) +depcomp = $(SHELL) $(top_srcdir)/config/depcomp +am__depfiles_maybe = depfiles +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +CCLD = $(CC) +LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ +SOURCES = $(libdw_a_SOURCES) $(libdw_pic_a_SOURCES) \ + $(libdw_so_SOURCES) +DIST_SOURCES = $(libdw_a_SOURCES) $(libdw_pic_a_SOURCES) \ + $(libdw_so_SOURCES) +euincludeHEADERS_INSTALL = $(INSTALL_HEADER) +includeHEADERS_INSTALL = $(INSTALL_HEADER) +HEADERS = $(euinclude_HEADERS) $(include_HEADERS) $(noinst_HEADERS) +ETAGS = etags +CTAGS = ctags +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = ${SHELL} /work/elfutils/stock/elfutils-0.97/config/missing --run aclocal-1.9 +AMDEP_FALSE = # +AMDEP_TRUE = +AMTAR = ${SHELL} /work/elfutils/stock/elfutils-0.97/config/missing --run tar +AUTOCONF = ${SHELL} /work/elfutils/stock/elfutils-0.97/config/missing --run autoconf +AUTOHEADER = ${SHELL} /work/elfutils/stock/elfutils-0.97/config/missing --run autoheader +AUTOMAKE = ${SHELL} /work/elfutils/stock/elfutils-0.97/config/missing --run automake-1.9 +AWK = gawk +CC = gcc +CCDEPMODE = depmode=gcc3 +CFLAGS = -g -O2 +CPP = gcc -E +CPPFLAGS = +CYGPATH_W = echo +DATADIRNAME = ${prefix}/share +DEFS = -D_GNU_SOURCE -DHAVE_CONFIG_H +DEPDIR = .deps +ECHO_C = +ECHO_N = -n +ECHO_T = +EGREP = grep -E +EXEEXT = +GMSGFMT = /usr/bin/msgfmt +INSTALL_DATA = ${INSTALL} -m 644 +INSTALL_PROGRAM = ${INSTALL} +INSTALL_SCRIPT = ${INSTALL} +INSTALL_STRIP_PROGRAM = ${SHELL} $(install_sh) -c -s +INTLLIBS = +LDFLAGS = +LEX = flex +LEXLIB = -lfl +LEX_OUTPUT_ROOT = lex.yy +LIBICONV = -liconv +LIBINTL = +LIBOBJS = +LIBS = +LOCALEDIR = ${prefix}/share +LTLIBICONV = -liconv +LTLIBINTL = +LTLIBOBJS = +MAKEINFO = ${SHELL} /work/elfutils/stock/elfutils-0.97/config/missing --run makeinfo +MKINSTALLDIRS = config/mkinstalldirs +MSGFMT = /usr/bin/msgfmt +MSGMERGE = /usr/bin/msgmerge +MUDFLAP_FALSE = +MUDFLAP_TRUE = # +NATIVE_LD_FALSE = +NATIVE_LD_TRUE = # +OBJEXT = o +PACKAGE = elfutils +PACKAGE_BUGREPORT = http://bugzilla.redhat.com/bugzilla/ +PACKAGE_NAME = Red Hat elfutils +PACKAGE_STRING = Red Hat elfutils 0.97 +PACKAGE_TARNAME = elfutils +PACKAGE_VERSION = 0.97 +PATH_SEPARATOR = : +POSUB = po +RANLIB = ranlib +SET_MAKE = +SHELL = /bin/sh +STRIP = +USE_NLS = yes +VERSION = 1 +XGETTEXT = /usr/bin/xgettext +YACC = bison -y +ac_ct_CC = gcc +ac_ct_RANLIB = ranlib +ac_ct_STRIP = +am__fastdepCC_FALSE = # +am__fastdepCC_TRUE = +am__include = include +am__leading_dot = . +am__quote = +am__tar = ${AMTAR} chof - "$$tardir" +am__untar = ${AMTAR} xf - +base_cpu = none +bindir = ${exec_prefix}/bin +build = i686-pc-linux-gnu +build_alias = +build_cpu = i686 +build_os = linux-gnu +build_vendor = pc +datadir = ${prefix}/share +exec_prefix = ${prefix} +host = i686-pc-linux-gnu +host_alias = +host_cpu = i686 +host_os = linux-gnu +host_vendor = pc +includedir = ${prefix}/include +infodir = ${prefix}/info +install_sh = /work/elfutils/stock/elfutils-0.97/config/install-sh +libdir = ${exec_prefix}/lib +libexecdir = ${exec_prefix}/libexec +localstatedir = ${prefix}/var +mandir = ${prefix}/man +mkdir_p = mkdir -p -- +oldincludedir = /usr/include +prefix = /work/elfutils/google/linux-install-elfutils-0.97/ +program_transform_name = s,x,x, +sbindir = ${exec_prefix}/sbin +sharedstatedir = ${prefix}/com +sysconfdir = ${prefix}/etc +target_alias = +AM_CFLAGS = -Wall -Werror -Wshadow -std=gnu99 +#AM_CFLAGS = -Wall -Wshadow -std=gnu99 +INCLUDES = -I. -I$(srcdir) -I$(srcdir)/../libelf -I.. -I$(srcdir)/../lib +lib_LIBRARIES = libdw.a +noinst_LIBRARIES = libdw_pic.a +include_HEADERS = dwarf.h +euincludedir = ${includedir}/elfutils +euinclude_HEADERS = libdw.h +libdw_a_SOURCES = dwarf_begin.c dwarf_begin_elf.c dwarf_end.c dwarf_getelf.c \ + dwarf_getpubnames.c dwarf_getabbrev.c dwarf_tag.c \ + dwarf_error.c dwarf_nextcu.c dwarf_diename.c dwarf_offdie.c \ + dwarf_attr.c dwarf_formstring.c dwarf_abbrev_hash.c \ + dwarf_child.c dwarf_haschildren.c dwarf_formaddr.c \ + dwarf_formudata.c dwarf_formsdata.c dwarf_lowpc.c \ + dwarf_highpc.c dwarf_formref.c dwarf_siblingof.c \ + dwarf_dieoffset.c dwarf_cuoffset.c dwarf_hasattr.c \ + dwarf_hasform.c dwarf_whatform.c dwarf_whatattr.c \ + dwarf_bytesize.c dwarf_arrayorder.c dwarf_bitsize.c \ + dwarf_bitoffset.c dwarf_srclang.c dwarf_getabbrevtag.c \ + dwarf_getabbrevcode.c dwarf_abbrevhaschildren.c \ + dwarf_getattrcnt.c dwarf_getabbrevattr.c \ + dwarf_getsrclines.c dwarf_getsrc_die.c \ + dwarf_linesrc.c dwarf_lineno.c dwarf_lineaddr.c \ + dwarf_linecol.c dwarf_linebeginstatement.c \ + dwarf_lineendsequence.c dwarf_lineblock.c \ + dwarf_lineprologueend.c dwarf_lineepiloguebegin.c \ + dwarf_onesrcline.c dwarf_formblock.c \ + dwarf_getsrcfiles.c dwarf_filesrc.c \ + dwarf_getloclist.c dwarf_getstring.c dwarf_offabbrev.c \ + dwarf_getaranges.c dwarf_onearange.c dwarf_getarangeinfo.c \ + dwarf_getarange_addr.c dwarf_getattrs.c dwarf_formflag.c \ + dwarf_getmacros.c \ + libdw_findcu.c libdw_form.c libdw_alloc.c + +libdw_pic_a_SOURCES = +am_libdw_pic_a_OBJECTS = $(libdw_a_SOURCES:.c=.os) +libdw_so_SOURCES = +noinst_HEADERS = libdwP.h memory-access.h dwarf_abbrev_hash.h +EXTRA_DIST = libdw.map +CLEANFILES = $(am_libdw_pic_a_OBJECTS) +all: all-am + +.SUFFIXES: +.SUFFIXES: .c .o .obj +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \ + && exit 0; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnits libdw/Makefile'; \ + cd $(top_srcdir) && \ + $(AUTOMAKE) --gnits libdw/Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +install-libLIBRARIES: $(lib_LIBRARIES) + @$(NORMAL_INSTALL) + test -z "$(libdir)" || $(mkdir_p) "$(DESTDIR)$(libdir)" + @list='$(lib_LIBRARIES)'; for p in $$list; do \ + if test -f $$p; then \ + f=$(am__strip_dir) \ + echo " $(libLIBRARIES_INSTALL) '$$p' '$(DESTDIR)$(libdir)/$$f'"; \ + $(libLIBRARIES_INSTALL) "$$p" "$(DESTDIR)$(libdir)/$$f"; \ + else :; fi; \ + done + @$(POST_INSTALL) + @list='$(lib_LIBRARIES)'; for p in $$list; do \ + if test -f $$p; then \ + p=$(am__strip_dir) \ + echo " $(RANLIB) '$(DESTDIR)$(libdir)/$$p'"; \ + $(RANLIB) "$(DESTDIR)$(libdir)/$$p"; \ + else :; fi; \ + done + +uninstall-libLIBRARIES: + @$(NORMAL_UNINSTALL) + @list='$(lib_LIBRARIES)'; for p in $$list; do \ + p=$(am__strip_dir) \ + echo " rm -f '$(DESTDIR)$(libdir)/$$p'"; \ + rm -f "$(DESTDIR)$(libdir)/$$p"; \ + done + +clean-libLIBRARIES: + -test -z "$(lib_LIBRARIES)" || rm -f $(lib_LIBRARIES) + +clean-noinstLIBRARIES: + -test -z "$(noinst_LIBRARIES)" || rm -f $(noinst_LIBRARIES) +libdw.a: $(libdw_a_OBJECTS) $(libdw_a_DEPENDENCIES) + -rm -f libdw.a + $(libdw_a_AR) libdw.a $(libdw_a_OBJECTS) $(libdw_a_LIBADD) + $(RANLIB) libdw.a +libdw_pic.a: $(libdw_pic_a_OBJECTS) $(libdw_pic_a_DEPENDENCIES) + -rm -f libdw_pic.a + $(libdw_pic_a_AR) libdw_pic.a $(libdw_pic_a_OBJECTS) $(libdw_pic_a_LIBADD) + $(RANLIB) libdw_pic.a + +clean-noinstPROGRAMS: + -test -z "$(noinst_PROGRAMS)" || rm -f $(noinst_PROGRAMS) +#libdw.so$(EXEEXT): $(libdw_so_OBJECTS) $(libdw_so_DEPENDENCIES) +# @rm -f libdw.so$(EXEEXT) +# $(LINK) $(libdw_so_LDFLAGS) $(libdw_so_OBJECTS) $(libdw_so_LDADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +include ./$(DEPDIR)/dwarf_abbrev_hash.Po +include ./$(DEPDIR)/dwarf_abbrevhaschildren.Po +include ./$(DEPDIR)/dwarf_arrayorder.Po +include ./$(DEPDIR)/dwarf_attr.Po +include ./$(DEPDIR)/dwarf_begin.Po +include ./$(DEPDIR)/dwarf_begin_elf.Po +include ./$(DEPDIR)/dwarf_bitoffset.Po +include ./$(DEPDIR)/dwarf_bitsize.Po +include ./$(DEPDIR)/dwarf_bytesize.Po +include ./$(DEPDIR)/dwarf_child.Po +include ./$(DEPDIR)/dwarf_cuoffset.Po +include ./$(DEPDIR)/dwarf_diename.Po +include ./$(DEPDIR)/dwarf_dieoffset.Po +include ./$(DEPDIR)/dwarf_end.Po +include ./$(DEPDIR)/dwarf_error.Po +include ./$(DEPDIR)/dwarf_filesrc.Po +include ./$(DEPDIR)/dwarf_formaddr.Po +include ./$(DEPDIR)/dwarf_formblock.Po +include ./$(DEPDIR)/dwarf_formflag.Po +include ./$(DEPDIR)/dwarf_formref.Po +include ./$(DEPDIR)/dwarf_formsdata.Po +include ./$(DEPDIR)/dwarf_formstring.Po +include ./$(DEPDIR)/dwarf_formudata.Po +include ./$(DEPDIR)/dwarf_getabbrev.Po +include ./$(DEPDIR)/dwarf_getabbrevattr.Po +include ./$(DEPDIR)/dwarf_getabbrevcode.Po +include ./$(DEPDIR)/dwarf_getabbrevtag.Po +include ./$(DEPDIR)/dwarf_getarange_addr.Po +include ./$(DEPDIR)/dwarf_getarangeinfo.Po +include ./$(DEPDIR)/dwarf_getaranges.Po +include ./$(DEPDIR)/dwarf_getattrcnt.Po +include ./$(DEPDIR)/dwarf_getattrs.Po +include ./$(DEPDIR)/dwarf_getelf.Po +include ./$(DEPDIR)/dwarf_getloclist.Po +include ./$(DEPDIR)/dwarf_getmacros.Po +include ./$(DEPDIR)/dwarf_getpubnames.Po +include ./$(DEPDIR)/dwarf_getsrc_die.Po +include ./$(DEPDIR)/dwarf_getsrcfiles.Po +include ./$(DEPDIR)/dwarf_getsrclines.Po +include ./$(DEPDIR)/dwarf_getstring.Po +include ./$(DEPDIR)/dwarf_hasattr.Po +include ./$(DEPDIR)/dwarf_haschildren.Po +include ./$(DEPDIR)/dwarf_hasform.Po +include ./$(DEPDIR)/dwarf_highpc.Po +include ./$(DEPDIR)/dwarf_lineaddr.Po +include ./$(DEPDIR)/dwarf_linebeginstatement.Po +include ./$(DEPDIR)/dwarf_lineblock.Po +include ./$(DEPDIR)/dwarf_linecol.Po +include ./$(DEPDIR)/dwarf_lineendsequence.Po +include ./$(DEPDIR)/dwarf_lineepiloguebegin.Po +include ./$(DEPDIR)/dwarf_lineno.Po +include ./$(DEPDIR)/dwarf_lineprologueend.Po +include ./$(DEPDIR)/dwarf_linesrc.Po +include ./$(DEPDIR)/dwarf_lowpc.Po +include ./$(DEPDIR)/dwarf_nextcu.Po +include ./$(DEPDIR)/dwarf_offabbrev.Po +include ./$(DEPDIR)/dwarf_offdie.Po +include ./$(DEPDIR)/dwarf_onearange.Po +include ./$(DEPDIR)/dwarf_onesrcline.Po +include ./$(DEPDIR)/dwarf_siblingof.Po +include ./$(DEPDIR)/dwarf_srclang.Po +include ./$(DEPDIR)/dwarf_tag.Po +include ./$(DEPDIR)/dwarf_whatattr.Po +include ./$(DEPDIR)/dwarf_whatform.Po +include ./$(DEPDIR)/libdw_alloc.Po +include ./$(DEPDIR)/libdw_findcu.Po +include ./$(DEPDIR)/libdw_form.Po + +.c.o: + if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \ + then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi +# source='$<' object='$@' libtool=no \ +# DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) \ +# $(COMPILE) -c $< + +.c.obj: + if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ `$(CYGPATH_W) '$<'`; \ + then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi +# source='$<' object='$@' libtool=no \ +# DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) \ +# $(COMPILE) -c `$(CYGPATH_W) '$<'` +uninstall-info-am: +install-euincludeHEADERS: $(euinclude_HEADERS) + @$(NORMAL_INSTALL) + test -z "$(euincludedir)" || $(mkdir_p) "$(DESTDIR)$(euincludedir)" + @list='$(euinclude_HEADERS)'; for p in $$list; do \ + if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ + f=$(am__strip_dir) \ + echo " $(euincludeHEADERS_INSTALL) '$$d$$p' '$(DESTDIR)$(euincludedir)/$$f'"; \ + $(euincludeHEADERS_INSTALL) "$$d$$p" "$(DESTDIR)$(euincludedir)/$$f"; \ + done + +uninstall-euincludeHEADERS: + @$(NORMAL_UNINSTALL) + @list='$(euinclude_HEADERS)'; for p in $$list; do \ + f=$(am__strip_dir) \ + echo " rm -f '$(DESTDIR)$(euincludedir)/$$f'"; \ + rm -f "$(DESTDIR)$(euincludedir)/$$f"; \ + done +install-includeHEADERS: $(include_HEADERS) + @$(NORMAL_INSTALL) + test -z "$(includedir)" || $(mkdir_p) "$(DESTDIR)$(includedir)" + @list='$(include_HEADERS)'; for p in $$list; do \ + if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ + f=$(am__strip_dir) \ + echo " $(includeHEADERS_INSTALL) '$$d$$p' '$(DESTDIR)$(includedir)/$$f'"; \ + $(includeHEADERS_INSTALL) "$$d$$p" "$(DESTDIR)$(includedir)/$$f"; \ + done + +uninstall-includeHEADERS: + @$(NORMAL_UNINSTALL) + @list='$(include_HEADERS)'; for p in $$list; do \ + f=$(am__strip_dir) \ + echo " rm -f '$(DESTDIR)$(includedir)/$$f'"; \ + rm -f "$(DESTDIR)$(includedir)/$$f"; \ + done + +ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + mkid -fID $$unique +tags: TAGS + +TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + tags=; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$tags $$unique; \ + fi +ctags: CTAGS +CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + tags=; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + test -z "$(CTAGS_ARGS)$$tags$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$tags $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && cd $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) $$here + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \ + list='$(DISTFILES)'; for file in $$list; do \ + case $$file in \ + $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \ + $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \ + esac; \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test "$$dir" != "$$file" && test "$$dir" != "."; then \ + dir="/$$dir"; \ + $(mkdir_p) "$(distdir)$$dir"; \ + else \ + dir=''; \ + fi; \ + if test -d $$d/$$file; then \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ + fi; \ + cp -pR $$d/$$file $(distdir)$$dir || exit 1; \ + else \ + test -f $(distdir)/$$file \ + || cp -p $$d/$$file $(distdir)/$$file \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile $(LIBRARIES) $(PROGRAMS) $(HEADERS) +installdirs: + for dir in "$(DESTDIR)$(libdir)" "$(DESTDIR)$(euincludedir)" "$(DESTDIR)$(includedir)"; do \ + test -z "$$dir" || $(mkdir_p) "$$dir"; \ + done +#install: install-am +install-exec: install-exec-am +install-data: install-data-am +#uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + `test -z '$(STRIP)' || \ + echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install +mostlyclean-generic: + +clean-generic: + -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-generic clean-libLIBRARIES clean-noinstLIBRARIES \ + clean-noinstPROGRAMS mostlyclean-am + +distclean: distclean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +info: info-am + +info-am: + +install-data-am: install-euincludeHEADERS install-includeHEADERS + +install-exec-am: install-libLIBRARIES + +install-info: install-info-am + +install-man: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: uninstall-euincludeHEADERS uninstall-includeHEADERS \ + uninstall-info-am uninstall-libLIBRARIES + +.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ + clean-libLIBRARIES clean-noinstLIBRARIES clean-noinstPROGRAMS \ + ctags distclean distclean-compile distclean-generic \ + distclean-tags distdir dvi dvi-am html html-am info info-am \ + install install-am install-data install-data-am \ + install-euincludeHEADERS install-exec install-exec-am \ + install-includeHEADERS install-info install-info-am \ + install-libLIBRARIES install-man install-strip installcheck \ + installcheck-am installdirs maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-compile \ + mostlyclean-generic pdf pdf-am ps ps-am tags uninstall \ + uninstall-am uninstall-euincludeHEADERS \ + uninstall-includeHEADERS uninstall-info-am \ + uninstall-libLIBRARIES + +libdw.so: libdw_pic.a $(srcdir)/libdw.map + $(CC) -shared -o $@ -Wl,--whole-archive,$<,--no-whole-archive \ + -Wl,--version-script,$(srcdir)/libdw.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 libdw.so + $(mkinstalldirs) $(DESTDIR)$(libdir) + $(INSTALL_PROGRAM) libdw.so $(DESTDIR)$(libdir)/libdw-$(PACKAGE_VERSION).so + ln -fs libdw-$(PACKAGE_VERSION).so $(DESTDIR)$(libdir)/libdw.so.$(VERSION) + ln -fs libdw.so.$(VERSION) $(DESTDIR)$(libdir)/libdw.so + +uninstall: uninstall-am + rm -f $(DESTDIR)$(libdir)/libdw-$(PACKAGE_VERSION).so + rm -f $(DESTDIR)$(libdir)/libdw.so.$(VERSION) + rm -f $(DESTDIR)$(libdir)/libdw.so + rmdir --ignore-fail-on-non-empty $(DESTDIR)$(includedir)/elfutils +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/libdw/Makefile.am b/libdw/Makefile.am new file mode 100644 index 00000000..e452b43e --- /dev/null +++ b/libdw/Makefile.am @@ -0,0 +1,100 @@ +## Process this file with automake to create Makefile.in +## Makefile for libdw. +## +## Copyright (C) 2002, 2003, 2004 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 +if MUDFLAP +AM_CFLAGS = -Wall -Wshadow -std=gnu99 +else +AM_CFLAGS = -Wall -Werror -Wshadow -std=gnu99 +endif +INCLUDES = -I. -I$(srcdir) -I$(srcdir)/../libelf -I.. -I$(srcdir)/../lib +VERSION = 1 + +lib_LIBRARIES = libdw.a +if !MUDFLAP +noinst_LIBRARIES = libdw_pic.a +noinst_PROGRAMS = $(noinst_LIBRARIES:_pic.a=.so) +endif + +include_HEADERS = dwarf.h +euincludedir = ${includedir}/elfutils +euinclude_HEADERS = libdw.h + +libdw_a_SOURCES = dwarf_begin.c dwarf_begin_elf.c dwarf_end.c dwarf_getelf.c \ + dwarf_getpubnames.c dwarf_getabbrev.c dwarf_tag.c \ + dwarf_error.c dwarf_nextcu.c dwarf_diename.c dwarf_offdie.c \ + dwarf_attr.c dwarf_formstring.c dwarf_abbrev_hash.c \ + dwarf_child.c dwarf_haschildren.c dwarf_formaddr.c \ + dwarf_formudata.c dwarf_formsdata.c dwarf_lowpc.c \ + dwarf_highpc.c dwarf_formref.c dwarf_siblingof.c \ + dwarf_dieoffset.c dwarf_cuoffset.c dwarf_hasattr.c \ + dwarf_hasform.c dwarf_whatform.c dwarf_whatattr.c \ + dwarf_bytesize.c dwarf_arrayorder.c dwarf_bitsize.c \ + dwarf_bitoffset.c dwarf_srclang.c dwarf_getabbrevtag.c \ + dwarf_getabbrevcode.c dwarf_abbrevhaschildren.c \ + dwarf_getattrcnt.c dwarf_getabbrevattr.c \ + dwarf_getsrclines.c dwarf_getsrc_die.c \ + dwarf_linesrc.c dwarf_lineno.c dwarf_lineaddr.c \ + dwarf_linecol.c dwarf_linebeginstatement.c \ + dwarf_lineendsequence.c dwarf_lineblock.c \ + dwarf_lineprologueend.c dwarf_lineepiloguebegin.c \ + dwarf_onesrcline.c dwarf_formblock.c \ + dwarf_getsrcfiles.c dwarf_filesrc.c \ + dwarf_getloclist.c dwarf_getstring.c dwarf_offabbrev.c \ + dwarf_getaranges.c dwarf_onearange.c dwarf_getarangeinfo.c \ + dwarf_getarange_addr.c dwarf_getattrs.c dwarf_formflag.c \ + dwarf_getmacros.c \ + libdw_findcu.c libdw_form.c libdw_alloc.c + + +if !MUDFLAP +libdw_pic_a_SOURCES = +am_libdw_pic_a_OBJECTS = $(libdw_a_SOURCES:.c=.os) + +libdw_so_SOURCES = +libdw.so: libdw_pic.a $(srcdir)/libdw.map + $(CC) -shared -o $@ -Wl,--whole-archive,$<,--no-whole-archive \ + -Wl,--version-script,$(srcdir)/libdw.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 libdw.so + $(mkinstalldirs) $(DESTDIR)$(libdir) + $(INSTALL_PROGRAM) libdw.so $(DESTDIR)$(libdir)/libdw-$(PACKAGE_VERSION).so + ln -fs libdw-$(PACKAGE_VERSION).so $(DESTDIR)$(libdir)/libdw.so.$(VERSION) + ln -fs libdw.so.$(VERSION) $(DESTDIR)$(libdir)/libdw.so + +uninstall: uninstall-am + rm -f $(DESTDIR)$(libdir)/libdw-$(PACKAGE_VERSION).so + rm -f $(DESTDIR)$(libdir)/libdw.so.$(VERSION) + rm -f $(DESTDIR)$(libdir)/libdw.so + rmdir --ignore-fail-on-non-empty $(DESTDIR)$(includedir)/elfutils +endif + +noinst_HEADERS = libdwP.h memory-access.h dwarf_abbrev_hash.h + +EXTRA_DIST = libdw.map + +CLEANFILES = $(am_libdw_pic_a_OBJECTS) diff --git a/libdw/Makefile.in b/libdw/Makefile.in new file mode 100644 index 00000000..9ceb5d51 --- /dev/null +++ b/libdw/Makefile.in @@ -0,0 +1,681 @@ +# Makefile.in generated by automake 1.9.2 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004 Free Software Foundation, Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + + + +SOURCES = $(libdw_a_SOURCES) $(libdw_pic_a_SOURCES) $(libdw_so_SOURCES) + +srcdir = @srcdir@ +top_srcdir = @top_srcdir@ +VPATH = @srcdir@ +pkgdatadir = $(datadir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +top_builddir = .. +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +INSTALL = @INSTALL@ +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +@MUDFLAP_FALSE@noinst_PROGRAMS = $(am__EXEEXT_1) +@MUDFLAP_TRUE@am_libdw_pic_a_OBJECTS = +subdir = libdw +DIST_COMMON = $(euinclude_HEADERS) $(include_HEADERS) \ + $(noinst_HEADERS) $(srcdir)/Makefile.am $(srcdir)/Makefile.in \ + ChangeLog +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/m4/gettext.m4 \ + $(top_srcdir)/m4/iconv.m4 $(top_srcdir)/m4/lib-ld.m4 \ + $(top_srcdir)/m4/lib-link.m4 $(top_srcdir)/m4/lib-prefix.m4 \ + $(top_srcdir)/m4/progtest.m4 $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +mkinstalldirs = $(SHELL) $(top_srcdir)/config/mkinstalldirs +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; +am__vpath_adj = case $$p in \ + $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ + *) f=$$p;; \ + esac; +am__strip_dir = `echo $$p | sed -e 's|^.*/||'`; +am__installdirs = "$(DESTDIR)$(libdir)" "$(DESTDIR)$(euincludedir)" \ + "$(DESTDIR)$(includedir)" +libLIBRARIES_INSTALL = $(INSTALL_DATA) +LIBRARIES = $(lib_LIBRARIES) $(noinst_LIBRARIES) +AR = ar +ARFLAGS = cru +libdw_a_AR = $(AR) $(ARFLAGS) +libdw_a_LIBADD = +am_libdw_a_OBJECTS = dwarf_begin.$(OBJEXT) dwarf_begin_elf.$(OBJEXT) \ + dwarf_end.$(OBJEXT) dwarf_getelf.$(OBJEXT) \ + dwarf_getpubnames.$(OBJEXT) dwarf_getabbrev.$(OBJEXT) \ + dwarf_tag.$(OBJEXT) dwarf_error.$(OBJEXT) \ + dwarf_nextcu.$(OBJEXT) dwarf_diename.$(OBJEXT) \ + dwarf_offdie.$(OBJEXT) dwarf_attr.$(OBJEXT) \ + dwarf_formstring.$(OBJEXT) dwarf_abbrev_hash.$(OBJEXT) \ + dwarf_child.$(OBJEXT) dwarf_haschildren.$(OBJEXT) \ + dwarf_formaddr.$(OBJEXT) dwarf_formudata.$(OBJEXT) \ + dwarf_formsdata.$(OBJEXT) dwarf_lowpc.$(OBJEXT) \ + dwarf_highpc.$(OBJEXT) dwarf_formref.$(OBJEXT) \ + dwarf_siblingof.$(OBJEXT) dwarf_dieoffset.$(OBJEXT) \ + dwarf_cuoffset.$(OBJEXT) dwarf_hasattr.$(OBJEXT) \ + dwarf_hasform.$(OBJEXT) dwarf_whatform.$(OBJEXT) \ + dwarf_whatattr.$(OBJEXT) dwarf_bytesize.$(OBJEXT) \ + dwarf_arrayorder.$(OBJEXT) dwarf_bitsize.$(OBJEXT) \ + dwarf_bitoffset.$(OBJEXT) dwarf_srclang.$(OBJEXT) \ + dwarf_getabbrevtag.$(OBJEXT) dwarf_getabbrevcode.$(OBJEXT) \ + dwarf_abbrevhaschildren.$(OBJEXT) dwarf_getattrcnt.$(OBJEXT) \ + dwarf_getabbrevattr.$(OBJEXT) dwarf_getsrclines.$(OBJEXT) \ + dwarf_getsrc_die.$(OBJEXT) dwarf_linesrc.$(OBJEXT) \ + dwarf_lineno.$(OBJEXT) dwarf_lineaddr.$(OBJEXT) \ + dwarf_linecol.$(OBJEXT) dwarf_linebeginstatement.$(OBJEXT) \ + dwarf_lineendsequence.$(OBJEXT) dwarf_lineblock.$(OBJEXT) \ + dwarf_lineprologueend.$(OBJEXT) \ + dwarf_lineepiloguebegin.$(OBJEXT) dwarf_onesrcline.$(OBJEXT) \ + dwarf_formblock.$(OBJEXT) dwarf_getsrcfiles.$(OBJEXT) \ + dwarf_filesrc.$(OBJEXT) dwarf_getloclist.$(OBJEXT) \ + dwarf_getstring.$(OBJEXT) dwarf_offabbrev.$(OBJEXT) \ + dwarf_getaranges.$(OBJEXT) dwarf_onearange.$(OBJEXT) \ + dwarf_getarangeinfo.$(OBJEXT) dwarf_getarange_addr.$(OBJEXT) \ + dwarf_getattrs.$(OBJEXT) dwarf_formflag.$(OBJEXT) \ + dwarf_getmacros.$(OBJEXT) libdw_findcu.$(OBJEXT) \ + libdw_form.$(OBJEXT) libdw_alloc.$(OBJEXT) +libdw_a_OBJECTS = $(am_libdw_a_OBJECTS) +libdw_pic_a_AR = $(AR) $(ARFLAGS) +libdw_pic_a_LIBADD = +libdw_pic_a_OBJECTS = $(am_libdw_pic_a_OBJECTS) +@MUDFLAP_FALSE@am__EXEEXT_1 = libdw.so$(EXEEXT) +PROGRAMS = $(noinst_PROGRAMS) +am_libdw_so_OBJECTS = +libdw_so_OBJECTS = $(am_libdw_so_OBJECTS) +libdw_so_LDADD = $(LDADD) +DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir) +depcomp = $(SHELL) $(top_srcdir)/config/depcomp +am__depfiles_maybe = depfiles +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +CCLD = $(CC) +LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ +SOURCES = $(libdw_a_SOURCES) $(libdw_pic_a_SOURCES) \ + $(libdw_so_SOURCES) +DIST_SOURCES = $(libdw_a_SOURCES) $(libdw_pic_a_SOURCES) \ + $(libdw_so_SOURCES) +euincludeHEADERS_INSTALL = $(INSTALL_HEADER) +includeHEADERS_INSTALL = $(INSTALL_HEADER) +HEADERS = $(euinclude_HEADERS) $(include_HEADERS) $(noinst_HEADERS) +ETAGS = etags +CTAGS = ctags +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMDEP_FALSE = @AMDEP_FALSE@ +AMDEP_TRUE = @AMDEP_TRUE@ +AMTAR = @AMTAR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DATADIRNAME = @DATADIRNAME@ +DEFS = -D_GNU_SOURCE -DHAVE_CONFIG_H +DEPDIR = @DEPDIR@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +GMSGFMT = @GMSGFMT@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +INTLLIBS = @INTLLIBS@ +LDFLAGS = @LDFLAGS@ +LEX = @LEX@ +LEXLIB = @LEXLIB@ +LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ +LIBICONV = @LIBICONV@ +LIBINTL = @LIBINTL@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LOCALEDIR = @LOCALEDIR@ +LTLIBICONV = @LTLIBICONV@ +LTLIBINTL = @LTLIBINTL@ +LTLIBOBJS = @LTLIBOBJS@ +MAKEINFO = @MAKEINFO@ +MKINSTALLDIRS = @MKINSTALLDIRS@ +MSGFMT = @MSGFMT@ +MSGMERGE = @MSGMERGE@ +MUDFLAP_FALSE = @MUDFLAP_FALSE@ +MUDFLAP_TRUE = @MUDFLAP_TRUE@ +NATIVE_LD_FALSE = @NATIVE_LD_FALSE@ +NATIVE_LD_TRUE = @NATIVE_LD_TRUE@ +OBJEXT = @OBJEXT@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +POSUB = @POSUB@ +RANLIB = @RANLIB@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +USE_NLS = @USE_NLS@ +VERSION = 1 +XGETTEXT = @XGETTEXT@ +YACC = @YACC@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_RANLIB = @ac_ct_RANLIB@ +ac_ct_STRIP = @ac_ct_STRIP@ +am__fastdepCC_FALSE = @am__fastdepCC_FALSE@ +am__fastdepCC_TRUE = @am__fastdepCC_TRUE@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +base_cpu = @base_cpu@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +datadir = @datadir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +@MUDFLAP_FALSE@AM_CFLAGS = -Wall -Werror -Wshadow -std=gnu99 +@MUDFLAP_TRUE@AM_CFLAGS = -Wall -Wshadow -std=gnu99 +INCLUDES = -I. -I$(srcdir) -I$(srcdir)/../libelf -I.. -I$(srcdir)/../lib +lib_LIBRARIES = libdw.a +@MUDFLAP_FALSE@noinst_LIBRARIES = libdw_pic.a +include_HEADERS = dwarf.h +euincludedir = ${includedir}/elfutils +euinclude_HEADERS = libdw.h +libdw_a_SOURCES = dwarf_begin.c dwarf_begin_elf.c dwarf_end.c dwarf_getelf.c \ + dwarf_getpubnames.c dwarf_getabbrev.c dwarf_tag.c \ + dwarf_error.c dwarf_nextcu.c dwarf_diename.c dwarf_offdie.c \ + dwarf_attr.c dwarf_formstring.c dwarf_abbrev_hash.c \ + dwarf_child.c dwarf_haschildren.c dwarf_formaddr.c \ + dwarf_formudata.c dwarf_formsdata.c dwarf_lowpc.c \ + dwarf_highpc.c dwarf_formref.c dwarf_siblingof.c \ + dwarf_dieoffset.c dwarf_cuoffset.c dwarf_hasattr.c \ + dwarf_hasform.c dwarf_whatform.c dwarf_whatattr.c \ + dwarf_bytesize.c dwarf_arrayorder.c dwarf_bitsize.c \ + dwarf_bitoffset.c dwarf_srclang.c dwarf_getabbrevtag.c \ + dwarf_getabbrevcode.c dwarf_abbrevhaschildren.c \ + dwarf_getattrcnt.c dwarf_getabbrevattr.c \ + dwarf_getsrclines.c dwarf_getsrc_die.c \ + dwarf_linesrc.c dwarf_lineno.c dwarf_lineaddr.c \ + dwarf_linecol.c dwarf_linebeginstatement.c \ + dwarf_lineendsequence.c dwarf_lineblock.c \ + dwarf_lineprologueend.c dwarf_lineepiloguebegin.c \ + dwarf_onesrcline.c dwarf_formblock.c \ + dwarf_getsrcfiles.c dwarf_filesrc.c \ + dwarf_getloclist.c dwarf_getstring.c dwarf_offabbrev.c \ + dwarf_getaranges.c dwarf_onearange.c dwarf_getarangeinfo.c \ + dwarf_getarange_addr.c dwarf_getattrs.c dwarf_formflag.c \ + dwarf_getmacros.c \ + libdw_findcu.c libdw_form.c libdw_alloc.c + +@MUDFLAP_FALSE@libdw_pic_a_SOURCES = +@MUDFLAP_FALSE@am_libdw_pic_a_OBJECTS = $(libdw_a_SOURCES:.c=.os) +@MUDFLAP_FALSE@libdw_so_SOURCES = +noinst_HEADERS = libdwP.h memory-access.h dwarf_abbrev_hash.h +EXTRA_DIST = libdw.map +CLEANFILES = $(am_libdw_pic_a_OBJECTS) +all: all-am + +.SUFFIXES: +.SUFFIXES: .c .o .obj +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \ + && exit 0; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnits libdw/Makefile'; \ + cd $(top_srcdir) && \ + $(AUTOMAKE) --gnits libdw/Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +install-libLIBRARIES: $(lib_LIBRARIES) + @$(NORMAL_INSTALL) + test -z "$(libdir)" || $(mkdir_p) "$(DESTDIR)$(libdir)" + @list='$(lib_LIBRARIES)'; for p in $$list; do \ + if test -f $$p; then \ + f=$(am__strip_dir) \ + echo " $(libLIBRARIES_INSTALL) '$$p' '$(DESTDIR)$(libdir)/$$f'"; \ + $(libLIBRARIES_INSTALL) "$$p" "$(DESTDIR)$(libdir)/$$f"; \ + else :; fi; \ + done + @$(POST_INSTALL) + @list='$(lib_LIBRARIES)'; for p in $$list; do \ + if test -f $$p; then \ + p=$(am__strip_dir) \ + echo " $(RANLIB) '$(DESTDIR)$(libdir)/$$p'"; \ + $(RANLIB) "$(DESTDIR)$(libdir)/$$p"; \ + else :; fi; \ + done + +uninstall-libLIBRARIES: + @$(NORMAL_UNINSTALL) + @list='$(lib_LIBRARIES)'; for p in $$list; do \ + p=$(am__strip_dir) \ + echo " rm -f '$(DESTDIR)$(libdir)/$$p'"; \ + rm -f "$(DESTDIR)$(libdir)/$$p"; \ + done + +clean-libLIBRARIES: + -test -z "$(lib_LIBRARIES)" || rm -f $(lib_LIBRARIES) + +clean-noinstLIBRARIES: + -test -z "$(noinst_LIBRARIES)" || rm -f $(noinst_LIBRARIES) +libdw.a: $(libdw_a_OBJECTS) $(libdw_a_DEPENDENCIES) + -rm -f libdw.a + $(libdw_a_AR) libdw.a $(libdw_a_OBJECTS) $(libdw_a_LIBADD) + $(RANLIB) libdw.a +libdw_pic.a: $(libdw_pic_a_OBJECTS) $(libdw_pic_a_DEPENDENCIES) + -rm -f libdw_pic.a + $(libdw_pic_a_AR) libdw_pic.a $(libdw_pic_a_OBJECTS) $(libdw_pic_a_LIBADD) + $(RANLIB) libdw_pic.a + +clean-noinstPROGRAMS: + -test -z "$(noinst_PROGRAMS)" || rm -f $(noinst_PROGRAMS) +@MUDFLAP_TRUE@libdw.so$(EXEEXT): $(libdw_so_OBJECTS) $(libdw_so_DEPENDENCIES) +@MUDFLAP_TRUE@ @rm -f libdw.so$(EXEEXT) +@MUDFLAP_TRUE@ $(LINK) $(libdw_so_LDFLAGS) $(libdw_so_OBJECTS) $(libdw_so_LDADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarf_abbrev_hash.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarf_abbrevhaschildren.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarf_arrayorder.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarf_attr.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarf_begin.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarf_begin_elf.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarf_bitoffset.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarf_bitsize.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarf_bytesize.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarf_child.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarf_cuoffset.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarf_diename.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarf_dieoffset.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarf_end.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarf_error.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarf_filesrc.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarf_formaddr.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarf_formblock.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarf_formflag.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarf_formref.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarf_formsdata.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarf_formstring.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarf_formudata.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarf_getabbrev.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarf_getabbrevattr.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarf_getabbrevcode.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarf_getabbrevtag.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarf_getarange_addr.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarf_getarangeinfo.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarf_getaranges.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarf_getattrcnt.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarf_getattrs.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarf_getelf.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarf_getloclist.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarf_getmacros.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarf_getpubnames.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarf_getsrc_die.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarf_getsrcfiles.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarf_getsrclines.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarf_getstring.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarf_hasattr.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarf_haschildren.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarf_hasform.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarf_highpc.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarf_lineaddr.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarf_linebeginstatement.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarf_lineblock.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarf_linecol.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarf_lineendsequence.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarf_lineepiloguebegin.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarf_lineno.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarf_lineprologueend.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarf_linesrc.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarf_lowpc.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarf_nextcu.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarf_offabbrev.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarf_offdie.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarf_onearange.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarf_onesrcline.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarf_siblingof.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarf_srclang.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarf_tag.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarf_whatattr.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarf_whatform.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdw_alloc.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdw_findcu.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdw_form.Po@am__quote@ + +.c.o: +@am__fastdepCC_TRUE@ if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \ +@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(COMPILE) -c $< + +.c.obj: +@am__fastdepCC_TRUE@ if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ `$(CYGPATH_W) '$<'`; \ +@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'` +uninstall-info-am: +install-euincludeHEADERS: $(euinclude_HEADERS) + @$(NORMAL_INSTALL) + test -z "$(euincludedir)" || $(mkdir_p) "$(DESTDIR)$(euincludedir)" + @list='$(euinclude_HEADERS)'; for p in $$list; do \ + if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ + f=$(am__strip_dir) \ + echo " $(euincludeHEADERS_INSTALL) '$$d$$p' '$(DESTDIR)$(euincludedir)/$$f'"; \ + $(euincludeHEADERS_INSTALL) "$$d$$p" "$(DESTDIR)$(euincludedir)/$$f"; \ + done + +uninstall-euincludeHEADERS: + @$(NORMAL_UNINSTALL) + @list='$(euinclude_HEADERS)'; for p in $$list; do \ + f=$(am__strip_dir) \ + echo " rm -f '$(DESTDIR)$(euincludedir)/$$f'"; \ + rm -f "$(DESTDIR)$(euincludedir)/$$f"; \ + done +install-includeHEADERS: $(include_HEADERS) + @$(NORMAL_INSTALL) + test -z "$(includedir)" || $(mkdir_p) "$(DESTDIR)$(includedir)" + @list='$(include_HEADERS)'; for p in $$list; do \ + if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ + f=$(am__strip_dir) \ + echo " $(includeHEADERS_INSTALL) '$$d$$p' '$(DESTDIR)$(includedir)/$$f'"; \ + $(includeHEADERS_INSTALL) "$$d$$p" "$(DESTDIR)$(includedir)/$$f"; \ + done + +uninstall-includeHEADERS: + @$(NORMAL_UNINSTALL) + @list='$(include_HEADERS)'; for p in $$list; do \ + f=$(am__strip_dir) \ + echo " rm -f '$(DESTDIR)$(includedir)/$$f'"; \ + rm -f "$(DESTDIR)$(includedir)/$$f"; \ + done + +ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + mkid -fID $$unique +tags: TAGS + +TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + tags=; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$tags $$unique; \ + fi +ctags: CTAGS +CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + tags=; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + test -z "$(CTAGS_ARGS)$$tags$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$tags $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && cd $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) $$here + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \ + list='$(DISTFILES)'; for file in $$list; do \ + case $$file in \ + $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \ + $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \ + esac; \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test "$$dir" != "$$file" && test "$$dir" != "."; then \ + dir="/$$dir"; \ + $(mkdir_p) "$(distdir)$$dir"; \ + else \ + dir=''; \ + fi; \ + if test -d $$d/$$file; then \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ + fi; \ + cp -pR $$d/$$file $(distdir)$$dir || exit 1; \ + else \ + test -f $(distdir)/$$file \ + || cp -p $$d/$$file $(distdir)/$$file \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile $(LIBRARIES) $(PROGRAMS) $(HEADERS) +installdirs: + for dir in "$(DESTDIR)$(libdir)" "$(DESTDIR)$(euincludedir)" "$(DESTDIR)$(includedir)"; do \ + test -z "$$dir" || $(mkdir_p) "$$dir"; \ + done +@MUDFLAP_TRUE@install: install-am +install-exec: install-exec-am +install-data: install-data-am +@MUDFLAP_TRUE@uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + `test -z '$(STRIP)' || \ + echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install +mostlyclean-generic: + +clean-generic: + -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-generic clean-libLIBRARIES clean-noinstLIBRARIES \ + clean-noinstPROGRAMS mostlyclean-am + +distclean: distclean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +info: info-am + +info-am: + +install-data-am: install-euincludeHEADERS install-includeHEADERS + +install-exec-am: install-libLIBRARIES + +install-info: install-info-am + +install-man: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: uninstall-euincludeHEADERS uninstall-includeHEADERS \ + uninstall-info-am uninstall-libLIBRARIES + +.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ + clean-libLIBRARIES clean-noinstLIBRARIES clean-noinstPROGRAMS \ + ctags distclean distclean-compile distclean-generic \ + distclean-tags distdir dvi dvi-am html html-am info info-am \ + install install-am install-data install-data-am \ + install-euincludeHEADERS install-exec install-exec-am \ + install-includeHEADERS install-info install-info-am \ + install-libLIBRARIES install-man install-strip installcheck \ + installcheck-am installdirs maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-compile \ + mostlyclean-generic pdf pdf-am ps ps-am tags uninstall \ + uninstall-am uninstall-euincludeHEADERS \ + uninstall-includeHEADERS uninstall-info-am \ + uninstall-libLIBRARIES + +@MUDFLAP_FALSE@libdw.so: libdw_pic.a $(srcdir)/libdw.map +@MUDFLAP_FALSE@ $(CC) -shared -o $@ -Wl,--whole-archive,$<,--no-whole-archive \ +@MUDFLAP_FALSE@ -Wl,--version-script,$(srcdir)/libdw.map,--no-undefined \ +@MUDFLAP_FALSE@ -Wl,--soname,$@.$(VERSION),-z,defs \ +@MUDFLAP_FALSE@ ../libelf/libelf.so +@MUDFLAP_FALSE@ ln -fs $@ $@.$(VERSION) + +@MUDFLAP_FALSE@%.os: %.c %.o +@MUDFLAP_FALSE@ if $(COMPILE) -c -o $@ -fpic -DPIC -DSHARED -MT $@ -MD -MP \ +@MUDFLAP_FALSE@ -MF "$(DEPDIR)/$*.Tpo" `test -f '$<' || echo '$(srcdir)/'`$<; \ +@MUDFLAP_FALSE@ then cat "$(DEPDIR)/$*.Tpo" >> "$(DEPDIR)/$*.Po"; \ +@MUDFLAP_FALSE@ rm -f "$(DEPDIR)/$*.Tpo"; \ +@MUDFLAP_FALSE@ else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; \ +@MUDFLAP_FALSE@ fi + +@MUDFLAP_FALSE@install: install-am libdw.so +@MUDFLAP_FALSE@ $(mkinstalldirs) $(DESTDIR)$(libdir) +@MUDFLAP_FALSE@ $(INSTALL_PROGRAM) libdw.so $(DESTDIR)$(libdir)/libdw-$(PACKAGE_VERSION).so +@MUDFLAP_FALSE@ ln -fs libdw-$(PACKAGE_VERSION).so $(DESTDIR)$(libdir)/libdw.so.$(VERSION) +@MUDFLAP_FALSE@ ln -fs libdw.so.$(VERSION) $(DESTDIR)$(libdir)/libdw.so + +@MUDFLAP_FALSE@uninstall: uninstall-am +@MUDFLAP_FALSE@ rm -f $(DESTDIR)$(libdir)/libdw-$(PACKAGE_VERSION).so +@MUDFLAP_FALSE@ rm -f $(DESTDIR)$(libdir)/libdw.so.$(VERSION) +@MUDFLAP_FALSE@ rm -f $(DESTDIR)$(libdir)/libdw.so +@MUDFLAP_FALSE@ rmdir --ignore-fail-on-non-empty $(DESTDIR)$(includedir)/elfutils +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/libdw/dwarf.h b/libdw/dwarf.h new file mode 100644 index 00000000..69be35a7 --- /dev/null +++ b/libdw/dwarf.h @@ -0,0 +1,554 @@ +/* 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_def_cfa_expression = 0x0f, + DW_CFA_expression = 0x10, + DW_CFA_offset_extended_sf = 0x11, + DW_CFA_def_cfa_sf = 0x12, + DW_CFA_def_cfa_offset_sf = 0x13, + 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/libdw/dwarf_abbrev_hash.c b/libdw/dwarf_abbrev_hash.c new file mode 100644 index 00000000..009e757f --- /dev/null +++ b/libdw/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 "libdwP.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/libdw/dwarf_abbrev_hash.h b/libdw/dwarf_abbrev_hash.h new file mode 100644 index 00000000..ef3cc48b --- /dev/null +++ b/libdw/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/libdw/dwarf_abbrevhaschildren.c b/libdw/dwarf_abbrevhaschildren.c new file mode 100644 index 00000000..2261b2f3 --- /dev/null +++ b/libdw/dwarf_abbrevhaschildren.c @@ -0,0 +1,29 @@ +/* Return true if abbreviation is children flag set. + Copyright (C) 2003 Red Hat, Inc. + Written by Ulrich Drepper <drepper@redhat.com>, 2003. + + 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 <dwarf.h> +#include "libdwP.h" + + +int +dwarf_abbrevhaschildren (abbrev) + Dwarf_Abbrev *abbrev; +{ + return abbrev == NULL ? -1 : abbrev->has_children; +} diff --git a/libdw/dwarf_arrayorder.c b/libdw/dwarf_arrayorder.c new file mode 100644 index 00000000..072e70db --- /dev/null +++ b/libdw/dwarf_arrayorder.c @@ -0,0 +1,32 @@ +/* Return array order attribute of DIE. + Copyright (C) 2003 Red Hat, Inc. + Written by Ulrich Drepper <drepper@redhat.com>, 2003. + + 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 "libdwP.h" + + +int +dwarf_arrayorder (die) + Dwarf_Die *die; +{ + Dwarf_Attribute attr_mem; + Dwarf_Word value; + + return dwarf_formudata (dwarf_attr (die, DW_AT_ordering, &attr_mem), + &value) == 0 ? (int) value : -1; +} diff --git a/libdw/dwarf_attr.c b/libdw/dwarf_attr.c new file mode 100644 index 00000000..a09f11ac --- /dev/null +++ b/libdw/dwarf_attr.c @@ -0,0 +1,39 @@ +/* Return specific DWARF attribute of a DIE. + Copyright (C) 2003 Red Hat, Inc. + Written by Ulrich Drepper <drepper@redhat.com>, 2003. + + 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 "libdwP.h" + + +Dwarf_Attribute * +dwarf_attr (die, search_name, result) + Dwarf_Die *die; + unsigned int search_name; + Dwarf_Attribute *result; +{ + if (die == NULL) + return NULL; + + /* Search for the attribute with the given name. */ + result->valp = __libdw_find_attr (die, search_name, &result->code, + &result->form); + /* Always fill in the CU information. */ + result->cu = die->cu; + + return result->code == search_name ? result : NULL; +} diff --git a/libdw/dwarf_begin.c b/libdw/dwarf_begin.c new file mode 100644 index 00000000..a2ffa1c6 --- /dev/null +++ b/libdw/dwarf_begin.c @@ -0,0 +1,85 @@ +/* Create descriptor from file descriptor for processing file. + Copyright (C) 2002, 2003, 2004 Red Hat, Inc. + Written by Ulrich Drepper <drepper@redhat.com>, 2002. + + 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 <errno.h> +#include <stddef.h> +#include <sys/stat.h> + +#include <libdwP.h> + + +Dwarf * +dwarf_begin (fd, cmd) + int fd; + Dwarf_Cmd cmd; +{ + Elf *elf; + Elf_Cmd elfcmd; + Dwarf *result = NULL; + + switch (cmd) + { + case DWARF_C_READ: + elfcmd = ELF_C_READ_MMAP; + break; + case DWARF_C_WRITE: + elfcmd = ELF_C_WRITE; + break; + case DWARF_C_RDWR: + elfcmd = ELF_C_RDWR; + break; + default: + /* No valid mode. */ + __libdw_seterrno (DWARF_E_INVALID_CMD); + return NULL; + } + + /* 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, elfcmd, NULL); + if (elf == NULL) + { + /* Test why the `elf_begin" call failed. */ + struct stat64 st; + + if (fstat64 (fd, &st) == 0 && ! S_ISREG (st.st_mode)) + __libdw_seterrno (DWARF_E_NO_REGFILE); + else if (errno == EBADF) + __libdw_seterrno (DWARF_E_INVALID_FILE); + else + __libdw_seterrno (DWARF_E_IO_ERROR); + } + else + { + /* Do the real work now that we have an ELF descriptor. */ + result = dwarf_begin_elf (elf, cmd, NULL); + + /* If this failed, free the resources. */ + if (result == NULL) + elf_end (elf); + else + result->free_elf = true; + } + + return result; +} diff --git a/libdw/dwarf_begin_elf.c b/libdw/dwarf_begin_elf.c new file mode 100644 index 00000000..a9aa197c --- /dev/null +++ b/libdw/dwarf_begin_elf.c @@ -0,0 +1,251 @@ +/* Create descriptor from ELF descriptor for processing file. + Copyright (C) 2002, 2003, 2004 Red Hat, Inc. + Written by Ulrich Drepper <drepper@redhat.com>, 2002. + + 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 <stdbool.h> +#include <stddef.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> +#include <sys/stat.h> + +#include "libdwP.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])) + + +static void +check_section (Dwarf *result, GElf_Ehdr *ehdr, Elf_Scn *scn, bool inscngrp) +{ + GElf_Shdr shdr_mem; + GElf_Shdr *shdr; + + /* 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 (); + + + /* Make sure the section is part of a section group only iff we + really need it. If we are looking for the global (= non-section + group debug info) we have to ignore all the info in section + groups. If we are looking into a section group we cannot look at + a section which isn't part of the section group. */ + if (! inscngrp && (shdr->sh_flags & SHF_GROUP) != 0) + /* Ignore the section. */ + return; + + + /* We recognize the DWARF section by their names. This is not very + safe and stable but the best we can do. */ + const char *scnname = elf_strptr (result->elf, ehdr->e_shstrndx, + shdr->sh_name); + if (scnname == NULL) + { + /* The section name must be valid. Otherwise is the ELF file + invalid. */ + __libdw_seterrno (DWARF_E_INVALID_ELF); + free (result); + return; + } + + + /* Recognize the various sections. Most names start with .debug_. */ + size_t cnt; + for (cnt = 0; cnt < ndwarf_scnnames; ++cnt) + if (strcmp (scnname, dwarf_scnnames[cnt]) == 0) + { + /* Found it. Remember where the data is. */ + if (unlikely (result->sectiondata[cnt] != NULL)) + /* A section appears twice. That's bad. We ignore the section. */ + break; + + /* Get the section data. */ + Elf_Data *data = elf_getdata (scn, NULL); + if (data != NULL && data->d_size != 0) + /* Yep, there is actually data available. */ + result->sectiondata[cnt] = data; + + break; + } +} + + +/* Check whether all the necessary DWARF information is available. */ +static Dwarf * +valid_p (Dwarf *result) +{ + /* 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 (unlikely (result->sectiondata[IDX_debug_info] == NULL)) + { + __libdw_seterrno (DWARF_E_NO_DWARF); + result = NULL; + } + + return result; +} + + +static Dwarf * +global_read (Dwarf *result, Elf *elf, GElf_Ehdr *ehdr, Dwarf_Cmd cmd) +{ + Elf_Scn *scn = NULL; + + while ((scn = elf_nextscn (elf, scn)) != NULL) + check_section (result, ehdr, scn, false); + + return valid_p (result); +} + + +static Dwarf * +scngrp_read (Dwarf *result, Elf *elf, GElf_Ehdr *ehdr, Dwarf_Cmd cmd, + Elf_Scn *scngrp) +{ + /* SCNGRP is the section descriptor for a section group which might + contain debug sections. */ + Elf_Data *data = elf_getdata (scngrp, NULL); + if (data == NULL) + { + /* We cannot read the section content. Fail! */ + free (result); + return NULL; + } + + /* The content of the section is a number of 32-bit words which + represent section indices. The first word is a flag word. */ + Elf32_Word *scnidx = (Elf32_Word *) data->d_buf; + size_t cnt; + for (cnt = 1; cnt * sizeof (Elf32_Word) <= data->d_size; ++cnt) + { + Elf_Scn *scn = elf_getscn (elf, scnidx[cnt]); + if (scn == NULL) + { + /* A section group refers to a non-existing section. Should + never happen. */ + __libdw_seterrno (DWARF_E_INVALID_ELF); + free (result); + return NULL; + } + + check_section (result, ehdr, scn, true); + } + + return valid_p (result); +} + + +Dwarf * +dwarf_begin_elf (elf, cmd, scngrp) + Elf *elf; + Dwarf_Cmd cmd; + Elf_Scn *scngrp; +{ + GElf_Ehdr *ehdr; + GElf_Ehdr ehdr_mem; + + /* Get the ELF header of the file. We need various pieces of + information from it. */ + ehdr = gelf_getehdr (elf, &ehdr_mem); + if (ehdr == NULL) + { + if (elf_kind (elf) != ELF_K_ELF) + __libdw_seterrno (DWARF_E_NOELF); + else + __libdw_seterrno (DWARF_E_GETEHDR_ERROR); + + return NULL; + } + + + /* Default memory allocation size. */ + size_t mem_default_size = sysconf (_SC_PAGESIZE) - 4 * sizeof (void *); + + /* Allocate the data structure. */ + Dwarf *result = (Dwarf *) calloc (1, sizeof (Dwarf) + mem_default_size); + if (result == NULL) + { + __libdw_seterrno (DWARF_E_NOMEM); + return NULL; + } + + /* Fill in some values. */ + if ((BYTE_ORDER == LITTLE_ENDIAN && ehdr->e_ident[EI_DATA] == ELFDATA2MSB) + || (BYTE_ORDER == BIG_ENDIAN && ehdr->e_ident[EI_DATA] == ELFDATA2LSB)) + result->other_byte_order = true; + + result->elf = elf; + + /* Initialize the memory handling. */ + result->mem_default_size = mem_default_size; + result->oom_handler = __libdw_oom; + result->mem_tail = (struct libdw_memblock *) (result + 1); + result->mem_tail->size = (result->mem_default_size + - offsetof (struct libdw_memblock, mem)); + result->mem_tail->remaining = result->mem_tail->size; + result->mem_tail->prev = NULL; + + + if (cmd == DWARF_C_READ || cmd == DWARF_C_RDWR) + { + /* If the caller provides a section group we get the DWARF + sections only from this setion group. Otherwise we search + for the first section with the required name. Further + sections with the name are ignored. The DWARF specification + does not really say this is allowed. */ + if (scngrp == NULL) + return global_read (result, elf, ehdr, cmd); + else + return scngrp_read (result, elf, ehdr, cmd, scngrp); + } + else if (cmd == DWARF_C_WRITE) + { + __libdw_seterrno (DWARF_E_UNIMPL); + free (result); + return NULL; + } + + __libdw_seterrno (DWARF_E_INVALID_CMD); + free (result); + return NULL; +} diff --git a/libdw/dwarf_bitoffset.c b/libdw/dwarf_bitoffset.c new file mode 100644 index 00000000..6addbd72 --- /dev/null +++ b/libdw/dwarf_bitoffset.c @@ -0,0 +1,32 @@ +/* Return bit offset attribute of DIE. + Copyright (C) 2003 Red Hat, Inc. + Written by Ulrich Drepper <drepper@redhat.com>, 2003. + + 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 "libdwP.h" + + +int +dwarf_bitoffset (die) + Dwarf_Die *die; +{ + Dwarf_Attribute attr_mem; + Dwarf_Word value; + + return dwarf_formudata (dwarf_attr (die, DW_AT_bit_offset, &attr_mem), + &value) == 0 ? (int) value : -1; +} diff --git a/libdw/dwarf_bitsize.c b/libdw/dwarf_bitsize.c new file mode 100644 index 00000000..93688243 --- /dev/null +++ b/libdw/dwarf_bitsize.c @@ -0,0 +1,32 @@ +/* Return bit size attribute of DIE. + Copyright (C) 2003 Red Hat, Inc. + Written by Ulrich Drepper <drepper@redhat.com>, 2003. + + 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 "libdwP.h" + + +int +dwarf_bitsize (die) + Dwarf_Die *die; +{ + Dwarf_Attribute attr_mem; + Dwarf_Word value; + + return dwarf_formudata (dwarf_attr (die, DW_AT_bit_size, &attr_mem), + &value) == 0 ? (int) value : -1; +} diff --git a/libdw/dwarf_bytesize.c b/libdw/dwarf_bytesize.c new file mode 100644 index 00000000..8374676d --- /dev/null +++ b/libdw/dwarf_bytesize.c @@ -0,0 +1,32 @@ +/* Return byte size attribute of DIE. + Copyright (C) 2003 Red Hat, Inc. + Written by Ulrich Drepper <drepper@redhat.com>, 2003. + + 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 "libdwP.h" + + +int +dwarf_bytesize (die) + Dwarf_Die *die; +{ + Dwarf_Attribute attr_mem; + Dwarf_Word value; + + return dwarf_formudata (dwarf_attr (die, DW_AT_byte_size, &attr_mem), + &value) == 0 ? (int) value : -1; +} diff --git a/libdw/dwarf_child.c b/libdw/dwarf_child.c new file mode 100644 index 00000000..0ccac099 --- /dev/null +++ b/libdw/dwarf_child.c @@ -0,0 +1,158 @@ +/* Return vhild of current DIE. + Copyright (C) 2003, 2004 Red Hat, Inc. + Written by Ulrich Drepper <drepper@redhat.com>, 2003. + + 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 "libdwP.h" +#include <string.h> + +/* Some arbitrary value not conflicting with any existing code. */ +#define INVALID 0xffffe444 + + +unsigned char * +internal_function_def +__libdw_find_attr (Dwarf_Die *die, unsigned int search_name, + unsigned int *codep, unsigned int *formp) +{ + Dwarf *dbg = die->cu->dbg; + unsigned char *readp = (unsigned char *) die->addr; + + /* First we have to get the abbreviation code so that we can decode + the data in the DIE. */ + unsigned int abbrev_code; + get_uleb128 (abbrev_code, readp); + + /* Find the abbreviation entry. */ + Dwarf_Abbrev *abbrevp = die->abbrev; + if (abbrevp == NULL) + { + abbrevp = __libdw_findabbrev (die->cu, abbrev_code); + die->abbrev = abbrevp ?: (Dwarf_Abbrev *) -1l; + } + if (unlikely (die->abbrev == (Dwarf_Abbrev *) -1l)) + { + __libdw_seterrno (DWARF_E_INVALID_DWARF); + return NULL; + } + + /* Search the name attribute. */ + unsigned char *const endp + = ((unsigned char *) dbg->sectiondata[IDX_debug_abbrev]->d_buf + + dbg->sectiondata[IDX_debug_abbrev]->d_size); + + unsigned char *attrp = die->abbrev->attrp; + while (1) + { + /* Are we still in bounds? This test needs to be refined. */ + if (unlikely (attrp + 1 >= endp)) + { + __libdw_seterrno (DWARF_E_INVALID_DWARF); + return NULL; + } + + /* Get attribute name and form. + + XXX We don't check whether this reads beyond the end of the + section. */ + unsigned int attr_name; + get_uleb128 (attr_name, attrp); + unsigned int attr_form; + 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 == search_name && search_name != INVALID) + { + if (codep != NULL) + *codep = attr_name; + if (formp != NULL) + *formp = attr_form; + + return readp; + } + + /* Skip over the rest of this attribute (if there is any). */ + if (attr_form != 0) + { + size_t len = __libdw_form_val_len (dbg, die->cu, attr_form, readp); + + if (unlikely (len == (size_t) -1l)) + { + readp = NULL; + break; + } + + // XXX We need better boundary checks. + readp += len; + } + } + + // XXX Do we need other values? + if (codep != NULL) + *codep = INVALID; + if (formp != NULL) + *formp = INVALID; + + return readp; +} + + +int +dwarf_child (die, result) + Dwarf_Die *die; + Dwarf_Die *result; +{ + /* Ignore previous errors. */ + if (die == NULL) + return -1; + + /* Skip past the last attribute. */ + void *addr = NULL; + + /* If we already know there are no children do not search. */ + if (die->abbrev != (Dwarf_Abbrev *) -1 + && (die->abbrev == NULL || die->abbrev->has_children)) + addr = __libdw_find_attr (die, INVALID, NULL, NULL); + if (die->abbrev == (Dwarf_Abbrev *) -1l) + return -1; + + /* Make sure the DIE really has children. */ + if (! die->abbrev->has_children) + /* There cannot be any children. */ + return 1; + + if (addr == NULL) + return -1; + + /* RESULT can be the same as DIE. So preserve what we need. */ + struct Dwarf_CU *cu = die->cu; + + /* Clear the entire DIE structure. This signals we have not yet + determined any of the information. */ + memset (result, '\0', sizeof (Dwarf_Die)); + + /* We have the address. */ + result->addr = addr; + + /* Same CU as the parent. */ + result->cu = cu; + + return 0; +} diff --git a/libdw/dwarf_cuoffset.c b/libdw/dwarf_cuoffset.c new file mode 100644 index 00000000..f3adfa83 --- /dev/null +++ b/libdw/dwarf_cuoffset.c @@ -0,0 +1,32 @@ +/* Return offset of DIE in CU. + Copyright (C) 2003 Red Hat, Inc. + Written by Ulrich Drepper <drepper@redhat.com>, 2003. + + 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 "libdwP.h" + + +Dwarf_Off +dwarf_cuoffset (die) + Dwarf_Die *die; +{ + return (die == NULL + ? (Dwarf_Off) -1l + : (die->addr + - die->cu->dbg->sectiondata[IDX_debug_info]->d_buf + - die->cu->start)); +} diff --git a/libdw/dwarf_diename.c b/libdw/dwarf_diename.c new file mode 100644 index 00000000..78555dc3 --- /dev/null +++ b/libdw/dwarf_diename.c @@ -0,0 +1,30 @@ +/* Return string in name attribute of DIE. + Copyright (C) 2002 Red Hat, Inc. + Written by Ulrich Drepper <drepper@redhat.com>, 2002. + + 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 "libdwP.h" + + +const char * +dwarf_diename (die) + Dwarf_Die *die; +{ + Dwarf_Attribute attr_mem; + + return dwarf_formstring (dwarf_attr (die, DW_AT_name, &attr_mem)); +} diff --git a/libdw/dwarf_dieoffset.c b/libdw/dwarf_dieoffset.c new file mode 100644 index 00000000..2657c223 --- /dev/null +++ b/libdw/dwarf_dieoffset.c @@ -0,0 +1,30 @@ +/* Return offset of DIE. + Copyright (C) 2003 Red Hat, Inc. + Written by Ulrich Drepper <drepper@redhat.com>, 2003. + + 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 "libdwP.h" + + +Dwarf_Off +dwarf_dieoffset (die) + Dwarf_Die *die; +{ + return (die == NULL + ? -1l + : die->addr - die->cu->dbg->sectiondata[IDX_debug_info]->d_buf); +} diff --git a/libdw/dwarf_end.c b/libdw/dwarf_end.c new file mode 100644 index 00000000..0745d717 --- /dev/null +++ b/libdw/dwarf_end.c @@ -0,0 +1,75 @@ +/* Release debugging handling context. + Copyright (C) 2002, 2003, 2004 Red Hat, Inc. + Written by Ulrich Drepper <drepper@redhat.com>, 2002. + + 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 <search.h> +#include <stdlib.h> + +#include "libdwP.h" + + + +static void +noop_free (void *arg) +{ +} + + +static void +cu_free (void *arg) +{ + struct Dwarf_CU *p = (struct Dwarf_CU *) arg; + + Dwarf_Abbrev_Hash_free (&p->abbrev_hash); + + tdestroy (p->locs, noop_free); +} + + +int +dwarf_end (dwarf) + Dwarf *dwarf; +{ + if (dwarf != NULL) + { + /* The search tree for the CUs. NB: the CU data itself is + allocated separately, but the abbreviation hash tables need + to be handled. */ + tdestroy (dwarf->cu_tree, cu_free); + + struct libdw_memblock *memp = dwarf->mem_tail; + /* The first block is allocated together with the Dwarf object. */ + while (memp->prev != NULL) + { + struct libdw_memblock *prevp = memp->prev; + free (memp); + memp = prevp; + } + + /* Free the pubnames helper structure. */ + free (dwarf->pubnames_sets); + + /* Free the ELF descriptor if necessary. */ + if (dwarf->free_elf) + elf_end (dwarf->elf); + + /* Free the context descriptor. */ + free (dwarf); + } + + return 0; +} diff --git a/libdw/dwarf_error.c b/libdw/dwarf_error.c new file mode 100644 index 00000000..fe8966ee --- /dev/null +++ b/libdw/dwarf_error.c @@ -0,0 +1,177 @@ +/* Retrieve ELF descriptor used for DWARF access. + Copyright (C) 2002, 2003, 2004 Red Hat, Inc. + Written by Ulrich Drepper <drepper@redhat.com>, 2002. + + 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 <stddef.h> + +#include "libdwP.h" + + +#ifdef USE_TLS +/* The error number. */ +static int global_error; +#else +/* This is the key for the thread specific memory. */ +static tls_key_t key; + +/* The error number. Used in non-threaded programs. */ +static int global_error; +static bool threaded; +/* We need to initialize the thread-specific data. */ +once_define (static, once); + +/* The initialization and destruction functions. */ +static void init (void); +static void free_key_mem (void *mem); +#endif /* TLS */ + + +int +dwarf_errno (void) +{ + int result; + +#ifndef USE_TLS + /* If we have not yet initialized the buffer do it now. */ + once_execute (once, init); + + if (threaded) + { + /* We do not allocate memory for the data. It is only a word. + We can store it in place of the pointer. */ + result = (intptr_t) getspecific (key); + + setspecific (key, (void *) (intptr_t) DWARF_E_NOERROR); + return result; + } +#endif /* TLS */ + + result = global_error; + global_error = DWARF_E_NOERROR; + return result; +} + + +/* XXX For now we use string pointers. Once the table stablelizes + make it more DSO-friendly. */ +static const char *errmsgs[] = + { + [DWARF_E_NOERROR] = N_("no error"), + [DWARF_E_UNKNOWN_ERROR] = N_("unknown error"), + [DWARF_E_INVALID_ACCESS] = N_("invalid access"), + [DWARF_E_NO_REGFILE] = N_("no regular file"), + [DWARF_E_IO_ERROR] = N_("I/O error"), + [DWARF_E_INVALID_ELF] = N_("invalid ELF file"), + [DWARF_E_NO_DWARF] = N_("no DWARF information"), + [DWARF_E_NOELF] = N_("no ELF file"), + [DWARF_E_GETEHDR_ERROR] = N_("cannot get ELF header"), + [DWARF_E_NOMEM] = N_("out of memory"), + [DWARF_E_UNIMPL] = N_("not implemented"), + [DWARF_E_INVALID_CMD] = N_("invalid command"), + [DWARF_E_INVALID_VERSION] = N_("invalid version"), + [DWARF_E_INVALID_FILE] = N_("invalid file"), + [DWARF_E_NO_ENTRY] = N_("no entries found"), + [DWARF_E_INVALID_DWARF] = N_("invalid DWARF"), + [DWARF_E_NO_STRING] = N_("no string data"), + [DWARF_E_NO_ADDR] = N_("no address value"), + [DWARF_E_NO_CONSTANT] = N_("no constant value"), + [DWARF_E_NO_REFERENCE] = N_("no reference value"), + [DWARF_E_INVALID_REFERENCE] = N_("invalid reference value"), + [DWARF_E_NO_DEBUG_LINE] = N_(".debug_line section missing"), + [DWARF_E_INVALID_DEBUG_LINE] = N_("invalid .debug_line section"), + [DWARF_E_TOO_BIG] = N_("debug information too big"), + [DWARF_E_VERSION] = N_("invalid DWARF version"), + [DWARF_E_INVALID_DIR_IDX] = N_("invalid directory index"), + [DWARF_E_ADDR_OUTOFRANGE] = N_("address out of range"), + [DWARF_E_NO_LOCLIST] = N_("no location list value"), + [DWARF_E_NO_BLOCK] = N_("no block data"), + [DWARF_E_INVALID_LINE_IDX] = N_("invalid line index"), + [DWARF_E_INVALID_ARANGE_IDX] = N_("invalid address range index"), + [DWARF_E_NO_MATCH] = N_("no matching address range"), + [DWARF_E_NO_FLAG] = N_("no flag value"), + }; +#define nerrmsgs (sizeof (errmsgs) / sizeof (errmsgs[0])) + + +void +__libdw_seterrno (value) + int value; +{ +#ifndef USE_TLS + /* If we have not yet initialized the buffer do it now. */ + once_execute (once, init); + + if (threaded) + /* We do not allocate memory for the data. It is only a word. + We can store it in place of the pointer. */ + setspecific (key, (void *) (intptr_t) value); +#endif /* TLS */ + + global_error = (value >= 0 && value < (int) nerrmsgs + ? value : DWARF_E_UNKNOWN_ERROR); +} + + +const char * +dwarf_errmsg (error) + int error; +{ + int last_error; + +#ifndef USE_TLS + /* If we have not yet initialized the buffer do it now. */ + once_execute (once, init); + + if ((error == 0 || error == -1) && threaded) + /* We do not allocate memory for the data. It is only a word. + We can store it in place of the pointer. */ + last_error = (intptr_t) getspecific (key); + else +#endif /* TLS */ + last_error = global_error; + + if (error == 0) + return last_error != 0 ? _(errmsgs[last_error]) : NULL; + else if (error < -1 || error >= (int) nerrmsgs) + return _(errmsgs[DWARF_E_UNKNOWN_ERROR]); + + return _(errmsgs[error == -1 ? last_error : error]); +} + + +#ifndef USE_TLS +/* Free the thread specific data, this is done if a thread terminates. */ +static void +free_key_mem (void *mem) +{ + setspecific (key, NULL); +} + + +/* Initialize the key for the global variable. */ +static void +init (void) +{ + // XXX Screw you, gcc4, the unused function attribute does not work. + __asm ("" :: "r" (free_key_mem)); + + if (key_create (&key, free_key_mem) == 0) + /* Creating the key succeeded. */ + threaded = true; +} +#endif /* TLS */ diff --git a/libdw/dwarf_filesrc.c b/libdw/dwarf_filesrc.c new file mode 100644 index 00000000..770c004b --- /dev/null +++ b/libdw/dwarf_filesrc.c @@ -0,0 +1,36 @@ +/* Find source file information. + Copyright (C) 2004 Red Hat, Inc. + Written by Ulrich Drepper <drepper@redhat.com>, 2004. + + 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 "libdwP.h" + + +const char * +dwarf_filesrc (Dwarf_Files *file, size_t idx, Dwarf_Word *mtime, + Dwarf_Word *length) +{ + if (file == NULL || idx >= file->nfiles) + return NULL; + + if (mtime != NULL) + *mtime = file->info[idx].mtime; + + if (length != NULL) + *length = file->info[idx].length; + + return file->info[idx].name; +} diff --git a/libdw/dwarf_formaddr.c b/libdw/dwarf_formaddr.c new file mode 100644 index 00000000..4e8cdb0b --- /dev/null +++ b/libdw/dwarf_formaddr.c @@ -0,0 +1,43 @@ +/* Return address represented by attribute. + Copyright (C) 2003 Red Hat, Inc. + Written by Ulrich Drepper <drepper@redhat.com>, 2003. + + 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 "libdwP.h" + + +int +dwarf_formaddr (attr, return_addr) + Dwarf_Attribute *attr; + Dwarf_Addr *return_addr; +{ + if (attr == NULL) + return -1; + + if (unlikely (attr->form != DW_FORM_addr)) + { + __libdw_seterrno (DWARF_E_NO_ADDR); + return -1; + } + + if (attr->cu->address_size == 8) + *return_addr = read_8ubyte_unaligned (attr->cu->dbg, attr->valp); + else + *return_addr = read_4ubyte_unaligned (attr->cu->dbg, attr->valp); + + return 0; +} diff --git a/libdw/dwarf_formblock.c b/libdw/dwarf_formblock.c new file mode 100644 index 00000000..08566829 --- /dev/null +++ b/libdw/dwarf_formblock.c @@ -0,0 +1,73 @@ +/* Return block represented by attribute. + Copyright (C) 2004 Red Hat, Inc. + Written by Ulrich Drepper <drepper@redhat.com>, 2004. + + 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 "libdwP.h" + + +int +dwarf_formblock (attr, return_block) + Dwarf_Attribute *attr; + Dwarf_Block *return_block; +{ + if (attr == NULL) + return -1; + + unsigned int u128; + unsigned char *datap; + + switch (attr->form) + { + case DW_FORM_block1: + return_block->length = *(uint8_t *) attr->valp; + return_block->data = attr->valp + 1; + break; + + case DW_FORM_block2: + return_block->length = read_2ubyte_unaligned (attr->cu->dbg, attr->valp); + return_block->data = attr->valp + 2; + break; + + case DW_FORM_block4: + return_block->length = read_4ubyte_unaligned (attr->cu->dbg, attr->valp); + return_block->data = attr->valp + 4; + break; + + case DW_FORM_block: + datap = attr->valp; + get_uleb128 (u128, datap); + return_block->length = u128; + return_block->data = datap; + break; + + default: + __libdw_seterrno (DWARF_E_NO_BLOCK); + return -1; + } + + if (return_block->data + return_block->length + > ((unsigned char *) attr->cu->dbg->sectiondata[IDX_debug_info]->d_buf + + attr->cu->dbg->sectiondata[IDX_debug_info]->d_size)) + { + /* Block does not fit. */ + __libdw_seterrno (DWARF_E_INVALID_DWARF); + return -1; + } + + return 0; +} diff --git a/libdw/dwarf_formflag.c b/libdw/dwarf_formflag.c new file mode 100644 index 00000000..ac344019 --- /dev/null +++ b/libdw/dwarf_formflag.c @@ -0,0 +1,40 @@ +/* Return flag represented by attribute. + Copyright (C) 2004 Red Hat, Inc. + Written by Ulrich Drepper <drepper@redhat.com>, 2004. + + 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 "libdwP.h" + + +int +dwarf_formflag (attr, return_bool) + Dwarf_Attribute *attr; + bool *return_bool; +{ + if (attr == NULL) + return -1; + + if (unlikely (attr->form != DW_FORM_flag)) + { + __libdw_seterrno (DWARF_E_NO_FLAG); + return -1; + } + + *return_bool = *attr->valp != 0; + + return 0; +} diff --git a/libdw/dwarf_formref.c b/libdw/dwarf_formref.c new file mode 100644 index 00000000..d6b1f0f6 --- /dev/null +++ b/libdw/dwarf_formref.c @@ -0,0 +1,68 @@ +/* Return reference offset represented by attribute. + Copyright (C) 2003 Red Hat, Inc. + Written by Ulrich Drepper <drepper@redhat.com>, 2003. + + 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 "libdwP.h" + + +int +dwarf_formref (attr, return_offset) + Dwarf_Attribute *attr; + Dwarf_Off *return_offset; +{ + if (attr == NULL) + return -1; + + unsigned int u128; + unsigned char *datap; + + 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: + datap = attr->valp; + get_uleb128 (u128, datap); + *return_offset = u128; + break; + + case DW_FORM_ref_addr: + __libdw_seterrno (DWARF_E_INVALID_REFERENCE); + return -1; + + default: + __libdw_seterrno (DWARF_E_NO_REFERENCE); + return -1; + } + + return 0; +} diff --git a/libdw/dwarf_formsdata.c b/libdw/dwarf_formsdata.c new file mode 100644 index 00000000..ad845102 --- /dev/null +++ b/libdw/dwarf_formsdata.c @@ -0,0 +1,70 @@ +/* Return signed constant represented by attribute. + Copyright (C) 2003 Red Hat, Inc. + Written by Ulrich Drepper <drepper@redhat.com>, 2003. + + 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 "libdwP.h" + + +int +dwarf_formsdata (attr, return_sval) + Dwarf_Attribute *attr; + Dwarf_Sword *return_sval; +{ + if (attr == NULL) + return -1; + + unsigned int u128; + unsigned char *datap; + + 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: + datap = attr->valp; + get_sleb128 (u128, datap); + *return_sval = u128; + break; + + case DW_FORM_udata: + datap = attr->valp; + get_uleb128 (u128, datap); + *return_sval = u128; + break; + + default: + __libdw_seterrno (DWARF_E_NO_CONSTANT); + return -1; + } + + return 0; +} diff --git a/libdw/dwarf_formstring.c b/libdw/dwarf_formstring.c new file mode 100644 index 00000000..c4e59d78 --- /dev/null +++ b/libdw/dwarf_formstring.c @@ -0,0 +1,57 @@ +/* Return string associated with given attribute. + Copyright (C) 2003, 2004 Red Hat, Inc. + Written by Ulrich Drepper <drepper@redhat.com>, 2003. + + 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 "libdwP.h" + + +const char * +dwarf_formstring (attrp) + Dwarf_Attribute *attrp; +{ + /* Ignore earlier errors. */ + if (attrp == NULL) + return NULL; + + /* We found it. Now determine where the string is stored. */ + if (attrp->form == DW_FORM_string) + /* A simple inlined string. */ + return (const char *) attrp->valp; + + Dwarf *dbg = attrp->cu->dbg; + + if (unlikely (attrp->form != DW_FORM_strp) + || dbg->sectiondata[IDX_debug_str] == NULL) + { + invalid_error: + __libdw_seterrno (DWARF_E_NO_STRING); + return NULL; + } + + uint64_t off; + // XXX We need better boundary checks. + if (attrp->cu->offset_size == 8) + off = read_8ubyte_unaligned (dbg, attrp->valp); + else + off = read_4ubyte_unaligned (dbg, attrp->valp); + + if (off >= dbg->sectiondata[IDX_debug_str]->d_size) + goto invalid_error; + + return (const char *) dbg->sectiondata[IDX_debug_str]->d_buf + off; +} diff --git a/libdw/dwarf_formudata.c b/libdw/dwarf_formudata.c new file mode 100644 index 00000000..66b8c2a3 --- /dev/null +++ b/libdw/dwarf_formudata.c @@ -0,0 +1,70 @@ +/* Return unsigned constant represented by attribute. + Copyright (C) 2003 Red Hat, Inc. + Written by Ulrich Drepper <drepper@redhat.com>, 2003. + + 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 "libdwP.h" + + +int +dwarf_formudata (attr, return_uval) + Dwarf_Attribute *attr; + Dwarf_Word *return_uval; +{ + if (attr == NULL) + return -1; + + unsigned int u128; + unsigned char *datap; + + 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: + datap = attr->valp; + get_sleb128 (u128, datap); + *return_uval = u128; + break; + + case DW_FORM_udata: + datap = attr->valp; + get_uleb128 (u128, datap); + *return_uval = u128; + break; + + default: + __libdw_seterrno (DWARF_E_NO_CONSTANT); + return -1; + } + + return 0; +} diff --git a/libdw/dwarf_getabbrev.c b/libdw/dwarf_getabbrev.c new file mode 100644 index 00000000..0021e222 --- /dev/null +++ b/libdw/dwarf_getabbrev.c @@ -0,0 +1,127 @@ +/* Get abbreviation at given offset. + Copyright (C) 2003, 2004 Red Hat, Inc. + Written by Ulrich Drepper <drepper@redhat.com>, 2003. + + 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 <dwarf.h> +#include "libdwP.h" + + +Dwarf_Abbrev * +internal_function_def +__libdw_getabbrev (dbg, cu, offset, lengthp, result) + Dwarf *dbg; + struct Dwarf_CU *cu; + Dwarf_Off offset; + size_t *lengthp; + Dwarf_Abbrev *result; +{ + /* Don't fail if there is not .debug_abbrev section. */ + if (dbg->sectiondata[IDX_debug_abbrev] == NULL) + return NULL; + + unsigned char *abbrevp + = (unsigned char *) dbg->sectiondata[IDX_debug_abbrev]->d_buf + offset; + if (*abbrevp == '\0') + /* We are past the last entry. */ + return NULL; + + /* 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. */ + unsigned char *start_abbrevp = abbrevp; + unsigned int code; + get_uleb128 (code, abbrevp); + + /* Check whether this code is already in the hash table. */ + bool foundit = false; + Dwarf_Abbrev *abb = NULL; + if (cu == NULL + || (abb = Dwarf_Abbrev_Hash_find (&cu->abbrev_hash, code, NULL)) == NULL) + { + if (result == NULL) + abb = libdw_typed_alloc (dbg, Dwarf_Abbrev); + else + abb = result; + } + else + { + foundit = true; + + assert (abb->offset == offset); + + /* If the caller doesn't need the length we are done. */ + if (lengthp == NULL) + goto out; + } + + /* If there is already a value in the hash table we are going to + overwrite its content. This must not be a problem, since the + content better be the same. */ + abb->code = code; + get_uleb128 (abb->tag, abbrevp); + abb->has_children = *abbrevp++ == DW_CHILDREN_yes; + abb->attrp = abbrevp; + abb->offset = offset; + + /* Skip over all the attributes and count them while doing so. */ + abb->attrcnt = 0; + unsigned int attrname; + unsigned int attrform; + do + { + get_uleb128 (attrname, abbrevp); + get_uleb128 (attrform, abbrevp); + } + while (attrname != 0 && attrform != 0 && ++abb->attrcnt); + + /* Return the length to the caller if she asked for it. */ + if (lengthp != NULL) + *lengthp = abbrevp - start_abbrevp; + + /* Add the entry to the hash table. */ + if (cu != NULL && ! foundit) + (void) Dwarf_Abbrev_Hash_insert (&cu->abbrev_hash, abb->code, abb); + + out: + return abb; +} + + +Dwarf_Abbrev * +dwarf_getabbrev (die, offset, lengthp) + Dwarf_Die *die; + Dwarf_Off offset; + size_t *lengthp; +{ + return __libdw_getabbrev (die->cu->dbg, die->cu, + die->cu->orig_abbrev_offset + offset, lengthp, + NULL); +} diff --git a/libdw/dwarf_getabbrevattr.c b/libdw/dwarf_getabbrevattr.c new file mode 100644 index 00000000..d9337aac --- /dev/null +++ b/libdw/dwarf_getabbrevattr.c @@ -0,0 +1,64 @@ +/* Get specific attribute of abbreviation. + Copyright (C) 2003, 2004 Red Hat, Inc. + Written by Ulrich Drepper <drepper@redhat.com>, 2003. + + 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 <dwarf.h> +#include "libdwP.h" + + +int +dwarf_getabbrevattr (abbrev, idx, namep, formp, offsetp) + Dwarf_Abbrev *abbrev; + size_t idx; + unsigned int *namep; + unsigned int *formp; + Dwarf_Off *offsetp; +{ + if (abbrev == NULL) + return -1; + + size_t cnt = 0; + unsigned char *attrp = abbrev->attrp; + unsigned char *start_attrp; + unsigned int name; + unsigned int form; + + do + { + start_attrp = attrp; + + /* Attribute code and form are encoded as ULEB128 values. */ + get_uleb128 (name, attrp); + get_uleb128 (form, attrp); + + /* If both values are zero the index is out of range. */ + if (name == 0 && form == 0) + return -1; + } + while (cnt++ < idx); + + /* Store the result if requested. */ + if (namep != NULL) + *namep = name; + if (formp != NULL) + *formp = form; + if (offsetp != NULL) + *offsetp = (start_attrp - abbrev->attrp) + abbrev->offset; + + return 0; +} diff --git a/libdw/dwarf_getabbrevcode.c b/libdw/dwarf_getabbrevcode.c new file mode 100644 index 00000000..ef3dac46 --- /dev/null +++ b/libdw/dwarf_getabbrevcode.c @@ -0,0 +1,29 @@ +/* Get abbreviation code. + Copyright (C) 2003 Red Hat, Inc. + Written by Ulrich Drepper <drepper@redhat.com>, 2003. + + 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 <dwarf.h> +#include "libdwP.h" + + +unsigned int +dwarf_getabbrevcode (abbrev) + Dwarf_Abbrev *abbrev; +{ + return abbrev == NULL ? 0 : abbrev->code; +} diff --git a/libdw/dwarf_getabbrevtag.c b/libdw/dwarf_getabbrevtag.c new file mode 100644 index 00000000..4707fdd1 --- /dev/null +++ b/libdw/dwarf_getabbrevtag.c @@ -0,0 +1,29 @@ +/* Get abbreviation tag. + Copyright (C) 2003 Red Hat, Inc. + Written by Ulrich Drepper <drepper@redhat.com>, 2003. + + 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 <dwarf.h> +#include "libdwP.h" + + +unsigned int +dwarf_getabbrevtag (abbrev) + Dwarf_Abbrev *abbrev; +{ + return abbrev == NULL ? 0 : abbrev->tag; +} diff --git a/libdw/dwarf_getarange_addr.c b/libdw/dwarf_getarange_addr.c new file mode 100644 index 00000000..df143d02 --- /dev/null +++ b/libdw/dwarf_getarange_addr.c @@ -0,0 +1,37 @@ +/* Get address range which includes given address. + Copyright (C) 2004 Red Hat, Inc. + Written by Ulrich Drepper <drepper@redhat.com>, 2004. + + 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 <libdwP.h> + + +Dwarf_Arange * +dwarf_getarange_addr (aranges, addr) + Dwarf_Aranges *aranges; + Dwarf_Addr addr; +{ + if (aranges == NULL) + return NULL; + + for (size_t cnt = 0; cnt < aranges->naranges; ++cnt) + if (aranges->info[cnt].addr <= addr + && addr < aranges->info[cnt].addr + aranges->info[cnt].length) + return &aranges->info[cnt]; + + __libdw_seterrno (DWARF_E_NO_MATCH); + return NULL; +} diff --git a/libdw/dwarf_getarangeinfo.c b/libdw/dwarf_getarangeinfo.c new file mode 100644 index 00000000..b96c6316 --- /dev/null +++ b/libdw/dwarf_getarangeinfo.c @@ -0,0 +1,37 @@ +/* Return list address ranges. + Copyright (C) 2000, 2001, 2002, 2004 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 <libdwP.h> + + +int +dwarf_getarangeinfo (Dwarf_Arange *arange, Dwarf_Addr *addrp, + Dwarf_Word *lengthp, Dwarf_Off *offsetp) +{ + if (arange == NULL) + return -1; + + if (addrp != NULL) + *addrp = arange->addr; + if (lengthp != NULL) + *lengthp = arange->length; + if (offsetp != NULL) + *offsetp = arange->offset; + + return 0; +} diff --git a/libdw/dwarf_getaranges.c b/libdw/dwarf_getaranges.c new file mode 100644 index 00000000..754baeca --- /dev/null +++ b/libdw/dwarf_getaranges.c @@ -0,0 +1,184 @@ +/* Return list address ranges. + Copyright (C) 2000, 2001, 2002, 2004 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 <libdwP.h> + + +struct arangelist +{ + Dwarf_Arange arange; + struct arangelist *next; +}; + + +int +dwarf_getaranges (dbg, aranges, naranges) + Dwarf *dbg; + Dwarf_Aranges **aranges; + size_t *naranges; +{ + if (dbg == NULL) + return -1; + + if (dbg->aranges != NULL) + { + *aranges = dbg->aranges; + if (naranges != NULL) + *naranges = dbg->aranges->naranges; + return 0; + } + + if (dbg->sectiondata[IDX_debug_aranges]->d_buf == NULL) + return -1; + + struct arangelist *arangelist = NULL; + unsigned int narangelist = 0; + + const char *readp + = (const char *) dbg->sectiondata[IDX_debug_aranges]->d_buf; + const char *readendp = readp + dbg->sectiondata[IDX_debug_aranges]->d_size; + + while (readp < readendp) + { + const char *hdrstart = readp; + + /* 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. */ + Dwarf_Word length = read_4ubyte_unaligned_inc (dbg, readp); + unsigned int length_bytes = 4; + if (length == 0xffffffff) + { + length = read_8ubyte_unaligned_inc (dbg, readp); + length_bytes = 8; + } + + unsigned int version = read_2ubyte_unaligned_inc (dbg, readp); + if (version != 2) + { + invalid: + __libdw_seterrno (DWARF_E_INVALID_DWARF); + return -1; + } + + Dwarf_Word offset; + if (length_bytes == 4) + offset = read_4ubyte_unaligned_inc (dbg, readp); + else + offset = read_8ubyte_unaligned_inc (dbg, readp); + + unsigned int address_size = *readp++; + if (address_size != 4 && address_size != 8) + goto invalid; + + /* Ignore the segment size value. */ + // XXX Really? + (void) *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->offset = offset; + + while (1) + { + Dwarf_Word range_address; + Dwarf_Word range_length; + + if (address_size == 4) + { + range_address = read_4ubyte_unaligned_inc (dbg, readp); + range_length = read_4ubyte_unaligned_inc (dbg, readp); + } + else + { + range_address = read_8ubyte_unaligned_inc (dbg, readp); + range_length = read_8ubyte_unaligned_inc (dbg, readp); + } + + /* Two zero values mark the end. */ + if (range_address == 0 && range_length == 0) + break; + + struct arangelist *new_arange = + (struct arangelist *) alloca (sizeof (struct arangelist)); + + new_arange->arange.addr = range_address; + new_arange->arange.length = range_length; + + /* We store the actual CU DIE offset, not the CU header offset. */ + const char *cu_header = (dbg->sectiondata[IDX_debug_info]->d_buf + + offset); + unsigned int offset_size; + if (read_4ubyte_unaligned_noncvt (cu_header) == 0xffffffff) + offset_size = 8; + else + offset_size = 4; + new_arange->arange.offset = offset + 3 * offset_size - 4 + 3; + + new_arange->next = arangelist; + arangelist = new_arange; + ++narangelist; + } + } + + if (narangelist == 0) + { + if (naranges != NULL) + *naranges = 0; + *aranges = NULL; + return 0; + } + + /* Allocate the array for the result. */ + if (naranges != NULL) + *naranges = narangelist; + *aranges = libdw_alloc (dbg, Dwarf_Aranges, + sizeof (Dwarf_Aranges) + + narangelist * sizeof (Dwarf_Arange), 1); + + (*aranges)->dbg = dbg; + (*aranges)->naranges = narangelist; + + while (narangelist-- > 0) + { + (*aranges)->info[narangelist] = arangelist->arange; + arangelist = arangelist->next; + } + + dbg->aranges = *aranges; + + return 0; +} diff --git a/libdw/dwarf_getattrcnt.c b/libdw/dwarf_getattrcnt.c new file mode 100644 index 00000000..0758e030 --- /dev/null +++ b/libdw/dwarf_getattrcnt.c @@ -0,0 +1,33 @@ +/* Get number of attributes of abbreviation. + Copyright (C) 2003, 2004 Red Hat, Inc. + Written by Ulrich Drepper <drepper@redhat.com>, 2003. + + 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 "libdwP.h" + + +int +dwarf_getattrcnt (abbrev, attrcntp) + Dwarf_Abbrev *abbrev; + size_t *attrcntp; +{ + if (abbrev == NULL) + return -1; + + *attrcntp = abbrev->attrcnt; + + return 0; +} diff --git a/libdw/dwarf_getattrs.c b/libdw/dwarf_getattrs.c new file mode 100644 index 00000000..4ead80cc --- /dev/null +++ b/libdw/dwarf_getattrs.c @@ -0,0 +1,94 @@ +/* Get attributes of the DIE. + Copyright (C) 2004 Red Hat, Inc. + Written by Ulrich Drepper <drepper@redhat.com>, 2004. + + 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 "libdwP.h" + + +ptrdiff_t +dwarf_getattrs (Dwarf_Die *die, int (*callback) (Dwarf_Attribute *, void *), + void *arg, ptrdiff_t offset) +{ + if (die == NULL) + return -1l; + + unsigned char *die_addr = die->addr; + + /* Get the abbreviation code. */ + unsigned int u128; + get_uleb128 (u128, die_addr); + + if (die->abbrev == NULL) + /* Find the abbreviation. */ + die->abbrev = __libdw_findabbrev (die->cu, u128); + + if (die->abbrev == (Dwarf_Abbrev *) -1l) + { + __libdw_seterrno (DWARF_E_INVALID_DWARF); + return -1l; + } + + /* This is where the attributes start. */ + unsigned char *attrp = die->abbrev->attrp + offset; + + /* Go over the list of attributes. */ + Dwarf *dbg = die->cu->dbg; + while (1) + { + /* Are we still in bounds? */ + if (unlikely (attrp + >= ((unsigned char *) dbg->sectiondata[IDX_debug_abbrev]->d_buf + + dbg->sectiondata[IDX_debug_abbrev]->d_size))) + { + __libdw_seterrno (DWARF_E_INVALID_DWARF); + return -1; + } + + /* Get attribute name and form. */ + Dwarf_Attribute attr; + // XXX Fix bound checks + get_uleb128 (attr.code, attrp); + get_uleb128 (attr.form, attrp); + + /* We can stop if we found the attribute with value zero. */ + if (attr.code == 0 && attr.form == 0) + return 0; + + /* Fill in the rest. */ + attr.valp = die_addr; + attr.cu = die->cu; + + /* Now call the callback function. */ + if (callback (&attr, arg) != DWARF_CB_OK) + return attrp - die->abbrev->attrp; + + /* Skip over the rest of this attribute (if there is any). */ + if (attr.form != 0) + { + size_t len = __libdw_form_val_len (dbg, die->cu, attr.form, + die_addr); + + if (unlikely (len == (size_t) -1l)) + /* Something wrong with the file. */ + return -1l; + + // XXX We need better boundary checks. + die_addr += len; + } + } + /* NOTREACHED */ +} diff --git a/libdw/dwarf_getelf.c b/libdw/dwarf_getelf.c new file mode 100644 index 00000000..1e2a06aa --- /dev/null +++ b/libdw/dwarf_getelf.c @@ -0,0 +1,33 @@ +/* Retrieve ELF descriptor used for DWARF access. + Copyright (C) 2002, 2004 Red Hat, Inc. + Written by Ulrich Drepper <drepper@redhat.com>, 2002. + + 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 "libdwP.h" + + +Elf * +dwarf_get_elf (dwarf) + Dwarf *dwarf; +{ + if (dwarf == NULL) + /* Some error occurred before. */ + return NULL; + + return dwarf->elf; +} diff --git a/libdw/dwarf_getloclist.c b/libdw/dwarf_getloclist.c new file mode 100644 index 00000000..6339a8c8 --- /dev/null +++ b/libdw/dwarf_getloclist.c @@ -0,0 +1,296 @@ +/* Return location expression list. + Copyright (C) 2000, 2001, 2002, 2004 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 <search.h> +#include <stdlib.h> + +#include <libdwP.h> + + +struct loclist +{ + uint8_t atom; + Dwarf_Word number; + Dwarf_Word number2; + Dwarf_Word offset; + struct loclist *next; +}; + + +static int +loc_compare (const void *p1, const void *p2) +{ + const struct loc_s *l1 = (const struct loc_s *) p1; + const struct loc_s *l2 = (const struct loc_s *) p2; + + if ((uintptr_t) l1->addr < (uintptr_t) l2->addr) + return -1; + if ((uintptr_t) l1->addr > (uintptr_t) l2->addr) + return 1; + + return 0; +} + + +int +dwarf_getloclist (attr, llbuf, listlen) + Dwarf_Attribute *attr; + Dwarf_Loc **llbuf; + size_t *listlen; +{ + /* 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) + { + __libdw_seterrno (DWARF_E_NO_LOCLIST); + return -1; + } + + struct Dwarf_CU *cu = attr->cu; + Dwarf *dbg = cu->dbg; + + /* Must have the form data4 or data8 which act as an offset. */ + Dwarf_Block block; + if (dwarf_formblock (attr, &block) != 0) + return -1; + + /* Check whether we already looked at this list. */ + struct loc_s fake = { .addr = block.data }; + struct loc_s **found = tfind (&fake, &cu->locs, loc_compare); + if (found != NULL) + { + /* We already saw it. */ + *llbuf = (*found)->loc; + *listlen = (*found)->nloc; + + return 0; + } + + unsigned char *data = block.data; + unsigned char *const end_data = data + block.length; + + struct loclist *loclist = NULL; + unsigned int n = 0; + /* Decode the opcodes. It is possible in some situations to have a + block of size zero. */ + while (data < end_data) + { + struct loclist *newloc; + newloc = (struct loclist *) alloca (sizeof (struct loclist)); + newloc->number = 0; + newloc->number2 = 0; + newloc->offset = data - block.data; + newloc->next = loclist; + loclist = newloc; + ++n; + + switch ((newloc->atom = *data++)) + { + case DW_OP_addr: + /* Address, depends on address size of CU. */ + if (cu->address_size == 4) + { + if (unlikely (data + 4 > end_data)) + { + invalid: + __libdw_seterrno (DWARF_E_INVALID_DWARF); + return -1; + } + + newloc->number = read_4ubyte_unaligned_inc (dbg, data); + } + else + { + if (unlikely (data + 8 > end_data)) + goto invalid; + + newloc->number = read_8ubyte_unaligned_inc (dbg, data); + } + 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 ... DW_OP_lit31: + case DW_OP_reg0 ... 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 (data >= end_data)) + goto invalid; + + newloc->number = *data++; + break; + + case DW_OP_const1s: + if (unlikely (data >= end_data)) + goto invalid; + + newloc->number = *((int8_t *) data); + ++data; + break; + + case DW_OP_const2u: + if (unlikely (data + 2 > end_data)) + goto invalid; + + newloc->number = read_2ubyte_unaligned_inc (dbg, data); + break; + + case DW_OP_const2s: + case DW_OP_skip: + case DW_OP_bra: + case DW_OP_call2: + if (unlikely (data + 2 > end_data)) + goto invalid; + + newloc->number = read_2sbyte_unaligned_inc (dbg, data); + break; + + case DW_OP_const4u: + if (unlikely (data + 4 > end_data)) + goto invalid; + + newloc->number = read_4ubyte_unaligned_inc (dbg, data); + break; + + case DW_OP_const4s: + case DW_OP_call4: + if (unlikely (data + 4 > end_data)) + goto invalid; + + newloc->number = read_4sbyte_unaligned_inc (dbg, data); + break; + + case DW_OP_const8u: + if (unlikely (data + 8 > end_data)) + goto invalid; + + newloc->number = read_8ubyte_unaligned_inc (dbg, data); + break; + + case DW_OP_const8s: + if (unlikely (data + 8 > end_data)) + goto invalid; + + newloc->number = read_8sbyte_unaligned_inc (dbg, data); + 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, data); + break; + + case DW_OP_consts: + case DW_OP_breg0 ... DW_OP_breg31: + case DW_OP_fbreg: + /* XXX Check size. */ + get_sleb128 (newloc->number, data); + break; + + case DW_OP_bregx: + /* XXX Check size. */ + get_uleb128 (newloc->number, data); + get_sleb128 (newloc->number2, data); + break; + + default: + goto invalid; + } + } + + if (unlikely (n == 0)) + { + /* This is not allowed. + + XXX Is it? */ + goto invalid; + } + + /* Allocate the array. */ + Dwarf_Loc *result = libdw_alloc (dbg, Dwarf_Loc, sizeof (Dwarf_Loc), n); + + /* Store the result. */ + *llbuf = result; + *listlen = n; + + do + { + /* We populate the array from the back since the list is + backwards. */ + --n; + result[n].atom = loclist->atom; + result[n].number = loclist->number; + result[n].number2 = loclist->number2; + result[n].offset = loclist->offset; + + loclist = loclist->next; + } + while (n > 0); + + /* Insert a record in the search tree so that we can find it again + later. */ + struct loc_s *newp = libdw_alloc (dbg, struct loc_s, sizeof (struct loc_s), + 1); + newp->addr = block.data; + newp->loc = result; + newp->nloc = *listlen; + (void) tsearch (newp, &cu->locs, loc_compare); + + /* We did it. */ + return 0; +} diff --git a/libdw/dwarf_getmacros.c b/libdw/dwarf_getmacros.c new file mode 100644 index 00000000..f6f933aa --- /dev/null +++ b/libdw/dwarf_getmacros.c @@ -0,0 +1,114 @@ +/* Get public symbol information. + Copyright (C) 2002, 2003, 2004 Red Hat, Inc. + Written by Ulrich Drepper <drepper@redhat.com>, 2002. + + 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 <libdwP.h> + + +ptrdiff_t +dwarf_getmacros (die, callback, arg, offset) + Dwarf_Die *die; + int (*callback) (Dwarf_Macro *, void *); + void *arg; + ptrdiff_t offset; +{ + /* Get the appropriate attribute. */ + Dwarf_Attribute attr; + if (dwarf_attr (die, DW_AT_macro_info, &attr) == NULL) + return -1; + + /* Offset into the .debug_macinfo section. */ + Dwarf_Word macoff; + if (dwarf_formudata (&attr, &macoff) != 0) + return -1; + + const unsigned char *readp + = die->cu->dbg->sectiondata[IDX_debug_macinfo]->d_buf + offset; + const unsigned char *readendp + = readp + die->cu->dbg->sectiondata[IDX_debug_macinfo]->d_size; + + if (readp == readendp) + return 0; + + if (*readp != DW_MACINFO_start_file) + goto invalid; + + while (readp < readendp) + { + unsigned int opcode = *readp++; + unsigned int u128; + unsigned int u128_2 = 0; + const char *str = NULL; + const unsigned char *endp; + + switch (opcode) + { + case DW_MACINFO_define: + case DW_MACINFO_undef: + case DW_MACINFO_vendor_ext: + /* For the first two opcodes the parameters are + line, string + For the latter + number, string. + We can treat these cases together. */ + get_uleb128 (u128, readp); + + endp = memchr (readp, '\0', readendp - readp); + if (endp == NULL) + goto invalid; + + str = (char *) readp; + readp = endp + 1; + break; + + case DW_MACINFO_start_file: + /* The two parameters are line and file index. */ + get_uleb128 (u128, readp); + get_uleb128 (u128_2, readp); + break; + + case DW_MACINFO_end_file: + /* Nothing more to do. */ + return 0; + + default: + goto invalid; + } + + Dwarf_Macro mac; + mac.opcode = opcode; + mac.param1 = u128; + if (str == NULL) + mac.param2.u = u128_2; + else + mac.param2.s = str; + + if (callback (&mac, arg) != DWARF_CB_OK) + return (readp + - ((unsigned char *) die->cu->dbg->sectiondata[IDX_debug_macinfo]->d_buf + + offset)); + } + + /* If we come here the termination of the data for the CU is not + present. */ + invalid: + __libdw_seterrno (DWARF_E_INVALID_DWARF); + return -1; +} diff --git a/libdw/dwarf_getpubnames.c b/libdw/dwarf_getpubnames.c new file mode 100644 index 00000000..c3cb5e2e --- /dev/null +++ b/libdw/dwarf_getpubnames.c @@ -0,0 +1,205 @@ +/* Get public symbol information. + Copyright (C) 2002, 2003, 2004 Red Hat, Inc. + Written by Ulrich Drepper <drepper@redhat.com>, 2002. + + 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 <string.h> +#include <sys/param.h> + +#include <libdwP.h> + + +static int +get_offsets (Dwarf *dbg) +{ + size_t allocated = 0; + size_t cnt = 0; + struct pubnames_s *mem = NULL; + const size_t entsize = sizeof (struct pubnames_s); + unsigned char *const startp = dbg->sectiondata[IDX_debug_pubnames]->d_buf; + unsigned char *readp = startp; + unsigned char *endp = readp + dbg->sectiondata[IDX_debug_pubnames]->d_size; + + while (readp + 14 < endp) + { + /* If necessary, allocate more entries. */ + if (cnt >= allocated) + { + allocated = MAX (10, 2 * allocated); + struct pubnames_s *newmem + = (struct pubnames_s *) realloc (mem, allocated * entsize); + if (newmem == NULL) + { + __libdw_seterrno (DWARF_E_NOMEM); + err_return: + free (mem); + return -1; + } + + mem = newmem; + } + + /* Read the set header. */ + int len_bytes = 4; + Dwarf_Off len = read_4ubyte_unaligned_inc (dbg, readp); + if (len == 0xffffffff) + { + len = read_8ubyte_unaligned_inc (dbg, readp); + len_bytes = 8; + } + + /* Now we know the offset of the first offset/name pair. */ + mem[cnt].set_start = readp + 2 + 2 * len_bytes - startp; + mem[cnt].address_len = len_bytes; + if (mem[cnt].set_start >= dbg->sectiondata[IDX_debug_pubnames]->d_size) + /* Something wrong, the first entry is beyond the end of + the section. */ + break; + + /* Read the version. It better be two for now. */ + uint16_t version = read_2ubyte_unaligned (dbg, readp); + if (version != 2) + { + __libdw_seterrno (DWARF_E_INVALID_VERSION); + goto err_return; + } + + /* Get the CU offset. */ + if (len_bytes == 4) + mem[cnt].cu_offset = read_4ubyte_unaligned (dbg, readp + 2); + else + mem[cnt].cu_offset = read_8ubyte_unaligned (dbg, readp + 2); + + /* Determine the size of the CU header. */ + assert (dbg->sectiondata[IDX_debug_info] != NULL); + assert (dbg->sectiondata[IDX_debug_info]->d_buf != NULL); + assert (mem[cnt].cu_offset + 3 + < dbg->sectiondata[IDX_debug_info]->d_size); + unsigned char *infop + = ((unsigned char *) dbg->sectiondata[IDX_debug_info]->d_buf + + mem[cnt].cu_offset); + if (read_4ubyte_unaligned_noncvt (infop) == 0xffffffff) + mem[cnt].cu_header_size = 23; + else + mem[cnt].cu_header_size = 11; + + ++cnt; + + /* Advance to the next set. */ + readp += len; + } + + if (mem == NULL) + { + __libdw_seterrno (DWARF_E_NO_ENTRY); + return -1; + } + + dbg->pubnames_sets = (struct pubnames_s *) realloc (mem, cnt * entsize); + dbg->pubnames_nsets = cnt; + + return 0; +} + + +ptrdiff_t +dwarf_getpubnames (dbg, callback, arg, offset) + Dwarf *dbg; + int (*callback) (Dwarf *, Dwarf_Global *, void *); + void *arg; + ptrdiff_t offset; +{ + if (dbg == NULL) + return -1l; + + /* Make sure it is a valid offset. */ + if (unlikely (dbg->sectiondata[IDX_debug_pubnames] == NULL + || offset >= dbg->sectiondata[IDX_debug_pubnames]->d_size)) + /* No (more) entry. */ + return 0; + + /* If necessary read the set information. */ + if (dbg->pubnames_nsets == 0 && get_offsets (dbg) != 0) + return -1l; + + /* Find the place where to start. */ + size_t cnt; + if (offset == 0) + { + cnt = 0; + offset = dbg->pubnames_sets[0].set_start; + } + else + { + for (cnt = 0; cnt + 1 < dbg->pubnames_nsets; ++cnt) + if (offset >= dbg->pubnames_sets[cnt].set_start) + { + assert (offset < dbg->pubnames_sets[cnt + 1].set_start); + break; + } + assert (cnt + 1 < dbg->pubnames_nsets); + } + + unsigned char *startp + = (unsigned char *) dbg->sectiondata[IDX_debug_pubnames]->d_buf; + unsigned char *readp = startp + offset; + while (1) + { + Dwarf_Global gl; + + gl.cu_offset = (dbg->pubnames_sets[cnt].cu_offset + + dbg->pubnames_sets[cnt].cu_header_size); + + while (1) + { + /* READP points to the next offset/name pair. */ + if (dbg->pubnames_sets[cnt].address_len == 4) + gl.die_offset = read_4ubyte_unaligned_inc (dbg, readp); + else + gl.die_offset = read_8ubyte_unaligned_inc (dbg, readp); + + /* If the offset is zero we reached the end of the set. */ + if (gl.die_offset == 0) + break; + + /* Add the CU offset. */ + gl.die_offset += dbg->pubnames_sets[cnt].cu_offset; + + gl.name = (char *) readp; + readp = (unsigned char *) rawmemchr (gl.name, '\0') + 1; + + /* We found name and DIE offset. Report it. */ + if (callback (dbg, &gl, arg) != DWARF_CB_OK) + { + /* The user wants us to stop. Return the offset of the + next entry. */ + return readp - startp; + } + } + + if (++cnt == dbg->pubnames_nsets) + /* This was the last set. */ + break; + + startp = (unsigned char *) dbg->sectiondata[IDX_debug_pubnames]->d_buf; + readp = startp + dbg->pubnames_sets[cnt].set_start; + } + + /* We are done. No more entries. */ + return 0; +} diff --git a/libdw/dwarf_getsrc_die.c b/libdw/dwarf_getsrc_die.c new file mode 100644 index 00000000..33cbd7b3 --- /dev/null +++ b/libdw/dwarf_getsrc_die.c @@ -0,0 +1,38 @@ +/* Find line information for address. + Copyright (C) 2004 Red Hat, Inc. + Written by Ulrich Drepper <drepper@redhat.com>, 2004. + + 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 "libdwP.h" + + +Dwarf_Line * +dwarf_getsrc_die (Dwarf_Die *cudie, Dwarf_Addr addr) +{ + Dwarf_Lines *lines; + size_t nlines; + + if (dwarf_getsrclines (cudie, &lines, &nlines) != 0) + return NULL; + + if (addr >= lines->info[0].addr ) + for (size_t n = 1; n < nlines; ++n) + if (addr < lines->info[n].addr) + return &lines->info[n - 1]; + + __libdw_seterrno (DWARF_E_ADDR_OUTOFRANGE); + return NULL; +} diff --git a/libdw/dwarf_getsrcfiles.c b/libdw/dwarf_getsrcfiles.c new file mode 100644 index 00000000..1775168d --- /dev/null +++ b/libdw/dwarf_getsrcfiles.c @@ -0,0 +1,58 @@ +/* Return source file information of CU. + Copyright (C) 2004 Red Hat, Inc. + Written by Ulrich Drepper <drepper@redhat.com>, 2004. + + 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 <dwarf.h> +#include "libdwP.h" + + +int +dwarf_getsrcfiles (Dwarf_Die *cudie, Dwarf_Files **files, size_t *nfiles) +{ + if (unlikely (cudie == NULL || dwarf_tag (cudie) != DW_TAG_compile_unit)) + return -1; + + int res = -1; + + /* Get the information if it is not already known. */ + struct Dwarf_CU *const cu = cudie->cu; + if (cu->lines == NULL) + { + Dwarf_Lines *lines; + size_t nlines; + + /* Let the more generic function do the work. It'll create more + data but that will be needed in an real program anyway. */ + res = dwarf_getsrclines (cudie, &lines, &nlines); + } + else if (cu->files != (void *) -1l) + /* We already have the information. */ + res = 0; + + if (likely (res == 0)) + { + assert (cu->files != NULL && cu->files != (void *) -1l); + *files = cu->files; + if (nfiles != NULL) + *nfiles = cu->files->nfiles; + } + + // XXX Eventually: unlocking here. + + return res; +} diff --git a/libdw/dwarf_getsrclines.c b/libdw/dwarf_getsrclines.c new file mode 100644 index 00000000..a372af2f --- /dev/null +++ b/libdw/dwarf_getsrclines.c @@ -0,0 +1,613 @@ +/* Return line number information of CU. + Copyright (C) 2004 Red Hat, Inc. + Written by Ulrich Drepper <drepper@redhat.com>, 2004. + + 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 <string.h> +#include "dwarf.h" +#include "libdwP.h" + + +struct filelist +{ + Dwarf_Fileinfo info; + 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)); \ + \ + /* 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_getsrclines (Dwarf_Die *cudie, Dwarf_Lines **lines, size_t *nlines) +{ + if (unlikely (cudie == NULL || dwarf_tag (cudie) != DW_TAG_compile_unit)) + return -1; + + int res = -1; + + /* Get the information if it is not already known. */ + struct Dwarf_CU *const cu = cudie->cu; + if (cu->lines == NULL) + { + /* Failsafe mode: no data found. */ + cu->lines = (void *) -1l; + cu->files = (void *) -1l; + + /* The die must have a statement list associated. */ + Dwarf_Attribute stmt_list_mem; + Dwarf_Attribute *stmt_list = dwarf_attr (cudie, DW_AT_stmt_list, + &stmt_list_mem); + + /* Get the offset into the .debug_line section. NB: this call + also checks whether the previous dwarf_attr call failed. */ + Dwarf_Word offset; + if (dwarf_formudata (stmt_list, &offset) != 0) + goto out; + + Dwarf *dbg = cu->dbg; + if (dbg->sectiondata[IDX_debug_line] == NULL) + { + __libdw_seterrno (DWARF_E_NO_DEBUG_LINE); + goto out; + } + uint8_t *linep = dbg->sectiondata[IDX_debug_line]->d_buf + offset; + uint8_t *lineendp = (dbg->sectiondata[IDX_debug_line]->d_buf + + dbg->sectiondata[IDX_debug_line]->d_size); + + /* Get the compilation directory. */ + Dwarf_Attribute compdir_attr_mem; + Dwarf_Attribute *compdir_attr = dwarf_attr (cudie, DW_AT_comp_dir, + &compdir_attr_mem); + const char *comp_dir = dwarf_formstring (compdir_attr); + + if (unlikely (linep + 4 > lineendp)) + { + invalid_data: + __libdw_seterrno (DWARF_E_INVALID_DEBUG_LINE); + goto out; + } + Dwarf_Word unit_length = read_4ubyte_unaligned_inc (dbg, linep); + unsigned int length = 4; + if (unlikely (unit_length == 0xffffffff)) + { + if (unlikely (linep + 8 > lineendp)) + goto invalid_data; + unit_length = read_8ubyte_unaligned_inc (dbg, linep); + length = 8; + } + + /* Check whether we have enough room in the section. */ + if (unit_length < 2 + length + 5 * 1 + || unlikely (linep + unit_length > lineendp)) + goto invalid_data; + lineendp = linep + unit_length; + + /* The next element of the header is the version identifier. */ + uint_fast16_t version = read_2ubyte_unaligned_inc (dbg, linep); + if (unlikely (version != DWARF_VERSION)) + { + __libdw_seterrno (DWARF_E_VERSION); + goto out; + } + + /* Next comes the header length. */ + Dwarf_Word header_length; + if (length == 4) + header_length = read_4ubyte_unaligned_inc (dbg, linep); + else + header_length = read_8ubyte_unaligned_inc (dbg, linep); + unsigned char *header_start = linep; + + /* Next the minimum instruction length. */ + uint_fast8_t minimum_instr_len = *linep++; + + /* Then the flag determining the default value of the is_stmt + register. */ + uint_fast8_t default_is_stmt = *linep++; + + /* Now the line base. */ + int_fast8_t line_base = *((int_fast8_t *) linep); + ++linep; + + /* And the line range. */ + uint_fast8_t line_range = *linep++; + + /* The opcode base. */ + uint_fast8_t opcode_base = *linep++; + + /* Remember array with the standard opcode length (-1 to account for + the opcode with value zero not being mentioned). */ + uint8_t *standard_opcode_lengths = linep - 1; + linep += opcode_base - 1; + if (unlikely (linep >= lineendp)) + goto invalid_data; + + /* First comes the list of directories. Add the compilation + directory first since the index zero is used for it. */ + struct dirlist + { + const char *dir; + size_t len; + struct dirlist *next; + } comp_dir_elem = + { + .dir = comp_dir, + .len = comp_dir ? strlen (comp_dir) : 0, + .next = NULL + }; + struct dirlist *dirlist = &comp_dir_elem; + unsigned int ndirlist = 1; + + // XXX Directly construct array to conserve memory? + while (*linep != 0) + { + struct dirlist *new_dir = + (struct dirlist *) alloca (sizeof (*new_dir)); + + new_dir->dir = (char *) linep; + uint8_t *endp = memchr (linep, '\0', lineendp - linep); + if (endp == NULL) + goto invalid_data; + new_dir->len = endp - linep; + new_dir->next = dirlist; + dirlist = new_dir; + ++ndirlist; + linep = endp + 1; + } + /* Skip the final NUL byte. */ + ++linep; + + /* Rearrange the list in array form. */ + struct dirlist **dirarray + = (struct dirlist **) alloca (ndirlist * sizeof (*dirarray)); + while (ndirlist-- > 0) + { + dirarray[ndirlist] = dirlist; + dirlist = dirlist->next; + } + + /* Now read the files. */ + struct filelist null_file = + { + .info = + { + .name = "???", + .mtime = 0, + .length = 0 + }, + .next = NULL + }; + struct filelist *filelist = &null_file; + unsigned int nfilelist = 1; + + if (unlikely (linep >= lineendp)) + goto invalid_data; + while (*linep != 0) + { + struct filelist *new_file = + (struct filelist *) alloca (sizeof (*new_file)); + + /* First comes the file name. */ + char *fname = (char *) linep; + uint8_t *endp = memchr (fname, '\0', lineendp - linep); + if (endp == NULL) + goto invalid_data; + size_t fnamelen = endp - (uint8_t *) fname; + linep = endp + 1; + + /* Then the index. */ + Dwarf_Word diridx; + get_uleb128 (diridx, linep); + if (unlikely (diridx >= ndirlist)) + { + __libdw_seterrno (DWARF_E_INVALID_DIR_IDX); + goto out; + } + + if (*fname == '/') + /* It's an absolute path. */ + new_file->info.name = fname; + else + { + new_file->info.name = libdw_alloc (dbg, char, 1, + dirarray[diridx]->len + 1 + + fnamelen + 1); + char *cp = new_file->info.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); + assert (strlen (new_file->info.name) + < dirarray[diridx]->len + 1 + fnamelen + 1); + } + + /* Next comes the modification time. */ + get_uleb128 (new_file->info.mtime, linep); + + /* Finally the length of the file. */ + get_uleb128 (new_file->info.length, linep); + + new_file->next = filelist; + filelist = new_file; + ++nfilelist; + } + /* Skip the final NUL byte. */ + ++linep; + + /* Consistency check. */ + if (unlikely (linep != header_start + header_length)) + { + __libdw_seterrno (DWARF_E_INVALID_DWARF); + goto out; + } + + /* We are about to process the statement program. Initialize the + state machine registers (see 6.2.2 in the v2.1 specification). */ + Dwarf_Word address = 0; + size_t file = 1; + size_t line = 1; + size_t column = 0; + uint_fast8_t is_stmt = default_is_stmt; + int basic_block = 0; + int prologue_end = 0; + int epilogue_begin = 0; + + /* Process the instructions. */ + struct linelist *linelist = NULL; + unsigned int 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_instr_len + * ((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. */ + if (unlikely (linep + 2 > lineendp)) + goto invalid_data; + + /* The length. */ + unsigned int len = *linep++; + + if (unlikely (linep + len > lineendp)) + goto invalid_data; + + /* The sub-opcode. */ + 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: + /* The value is an address. The size is defined as + apporiate for the target machine. We use the + address size field from the CU header. */ + if (cu->address_size == 4) + address = read_4ubyte_unaligned_inc (dbg, linep); + else + address = read_8ubyte_unaligned_inc (dbg, linep); + break; + + case DW_LNE_define_file: + { + char *fname = (char *) linep; + uint8_t *endp = memchr (linep, '\0', lineendp - linep); + if (endp == NULL) + goto invalid_data; + size_t fnamelen = endp - linep; + linep = endp + 1; + + unsigned int diridx; + get_uleb128 (diridx, linep); + Dwarf_Word mtime; + get_uleb128 (mtime, linep); + Dwarf_Word filelength; + get_uleb128 (filelength, linep); + + struct filelist *new_file = + (struct filelist *) alloca (sizeof (*new_file)); + if (fname[0] == '/') + new_file->info.name = fname; + else + { + new_file->info.name = + libdw_alloc (dbg, char, 1, (dirarray[diridx]->len + 1 + + fnamelen + 1)); + char *cp = new_file->info.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); + } + + new_file->info.mtime = mtime; + new_file->info.length = filelength; + 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)) + goto invalid_data; + + /* 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)) + goto invalid_data; + + get_uleb128 (u128, linep); + address += minimum_instr_len * u128; + break; + + case DW_LNS_advance_line: + /* Takes one sleb128 parameter which is added to the + line. */ + if (unlikely (standard_opcode_lengths[opcode] != 1)) + goto invalid_data; + + 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)) + goto invalid_data; + + 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)) + goto invalid_data; + + get_uleb128 (u128, linep); + column = u128; + break; + + case DW_LNS_negate_stmt: + /* Takes no argument. */ + if (unlikely (standard_opcode_lengths[opcode] != 0)) + goto invalid_data; + + is_stmt = 1 - is_stmt; + break; + + case DW_LNS_set_basic_block: + /* Takes no argument. */ + if (unlikely (standard_opcode_lengths[opcode] != 0)) + goto invalid_data; + + basic_block = 1; + break; + + case DW_LNS_const_add_pc: + /* Takes no argument. */ + if (unlikely (standard_opcode_lengths[opcode] != 0)) + goto invalid_data; + + address += (minimum_instr_len + * ((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)) + goto invalid_data; + + address += read_2ubyte_unaligned_inc (dbg, linep); + break; + + case DW_LNS_set_prologue_end: + /* Takes no argument. */ + if (unlikely (standard_opcode_lengths[opcode] != 0)) + goto invalid_data; + + prologue_end = 1; + break; + + case DW_LNS_set_epilog_begin: + /* Takes no argument. */ + if (unlikely (standard_opcode_lengths[opcode] != 0)) + goto invalid_data; + + 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. Read all the parameters for this opcode. */ + for (int n = standard_opcode_lengths[opcode]; n > 0; --n) + get_uleb128 (u128, linep); + + /* Next round, ignore this opcode. */ + continue; + } + } + + /* Put all the files in an array. */ + Dwarf_Files *files = libdw_alloc (dbg, Dwarf_Files, + sizeof (Dwarf_Files) + + nfilelist * sizeof (Dwarf_Fileinfo), + 1); + files->nfiles = nfilelist; + while (nfilelist-- > 0) + { + files->info[nfilelist] = filelist->info; + filelist = filelist->next; + } + assert (filelist == NULL); + + /* Remember the debugging descriptor. */ + files->dbg = dbg; + + /* Make the file data structure available through the CU. */ + cu->files = files; + + cu->lines = libdw_alloc (dbg, Dwarf_Lines, (sizeof (Dwarf_Lines) + + (sizeof (Dwarf_Line) + * nlinelist)), 1); + cu->lines->nlines = nlinelist; + while (nlinelist-- > 0) + { + cu->lines->info[nlinelist] = linelist->line; + cu->lines->info[nlinelist].files = files; + linelist = linelist->next; + } + assert (linelist == NULL); + + /* Success. */ + res = 0; + } + else if (cu->lines != (void *) -1l) + /* We already have the information. */ + res = 0; + + if (likely (res == 0)) + { + *lines = cu->lines; + *nlines = cu->lines->nlines; + } + out: + + // XXX Eventually: unlocking here. + + return res; +} diff --git a/libdw/dwarf_getstring.c b/libdw/dwarf_getstring.c new file mode 100644 index 00000000..e4abe8cb --- /dev/null +++ b/libdw/dwarf_getstring.c @@ -0,0 +1,51 @@ +/* Get string. + Copyright (C) 2004 Red Hat, Inc. + Written by Ulrich Drepper <drepper@redhat.com>, 2004. + + 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 "libdwP.h" + + +const char * +dwarf_getstring (dbg, offset, lenp) + Dwarf *dbg; + Dwarf_Off offset; + size_t *lenp; +{ + if (dbg == NULL) + return NULL; + + if (dbg->sectiondata[IDX_debug_str] == NULL + || offset >= dbg->sectiondata[IDX_debug_str]->d_size) + { + no_string: + __libdw_seterrno (DWARF_E_NO_STRING); + return NULL; + } + + const char *result = ((const char *) dbg->sectiondata[IDX_debug_str]->d_buf + + offset); + const char *endp = memchr (result, '\0', + dbg->sectiondata[IDX_debug_str]->d_size - offset); + if (endp == NULL) + goto no_string; + + if (lenp != NULL) + *lenp = endp - result; + + return result; +} diff --git a/libdw/dwarf_hasattr.c b/libdw/dwarf_hasattr.c new file mode 100644 index 00000000..15ad8daa --- /dev/null +++ b/libdw/dwarf_hasattr.c @@ -0,0 +1,36 @@ +/* Check whether given DIE has specific attribute. + Copyright (C) 2003 Red Hat, Inc. + Written by Ulrich Drepper <drepper@redhat.com>, 2003. + + 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 "libdwP.h" + + +int +dwarf_hasattr (die, search_name) + Dwarf_Die *die; + unsigned int search_name; +{ + if (die == NULL) + return 0; + + /* Search for the attribute with the given name. */ + unsigned int code; + (void) __libdw_find_attr (die, search_name, &code, NULL); + + return code == search_name; +} diff --git a/libdw/dwarf_haschildren.c b/libdw/dwarf_haschildren.c new file mode 100644 index 00000000..2a9fe5ff --- /dev/null +++ b/libdw/dwarf_haschildren.c @@ -0,0 +1,48 @@ +/* Return string associated with given attribute. + Copyright (C) 2003 Red Hat, Inc. + Written by Ulrich Drepper <drepper@redhat.com>, 2003. + + 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 "libdwP.h" +#include <string.h> + + +int +dwarf_haschildren (die) + Dwarf_Die *die; +{ + /* Find the abbreviation entry. */ + Dwarf_Abbrev *abbrevp = die->abbrev; + if (abbrevp != (Dwarf_Abbrev *) -1l) + { + unsigned char *readp = (unsigned char *) die->addr; + + /* First we have to get the abbreviation code so that we can decode + the data in the DIE. */ + unsigned int abbrev_code; + get_uleb128 (abbrev_code, readp); + + abbrevp = __libdw_findabbrev (die->cu, abbrev_code); + die->abbrev = abbrevp ?: (Dwarf_Abbrev *) -1l; + } + if (unlikely (die->abbrev == (Dwarf_Abbrev *) -1l)) + { + __libdw_seterrno (DWARF_E_INVALID_DWARF); + return 0; + } + + return die->abbrev->has_children; +} diff --git a/libdw/dwarf_hasform.c b/libdw/dwarf_hasform.c new file mode 100644 index 00000000..392b1f13 --- /dev/null +++ b/libdw/dwarf_hasform.c @@ -0,0 +1,32 @@ +/* Check whether given attribute has specific form. + Copyright (C) 2003 Red Hat, Inc. + Written by Ulrich Drepper <drepper@redhat.com>, 2003. + + 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 "libdwP.h" + + +int +dwarf_hasform (attr, search_form) + Dwarf_Attribute *attr; + unsigned int search_form; +{ + if (attr == NULL) + return 0; + + return attr->form == search_form; +} diff --git a/libdw/dwarf_highpc.c b/libdw/dwarf_highpc.c new file mode 100644 index 00000000..019cf141 --- /dev/null +++ b/libdw/dwarf_highpc.c @@ -0,0 +1,32 @@ +/* Return high PC attribute of DIE. + Copyright (C) 2003 Red Hat, Inc. + Written by Ulrich Drepper <drepper@redhat.com>, 2003. + + 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 "libdwP.h" + + +int +dwarf_highpc (die, return_addr) + Dwarf_Die *die; + Dwarf_Addr *return_addr; +{ + Dwarf_Attribute attr_mem; + + return dwarf_formaddr (dwarf_attr (die, DW_AT_high_pc, &attr_mem), + return_addr); +} diff --git a/libdw/dwarf_lineaddr.c b/libdw/dwarf_lineaddr.c new file mode 100644 index 00000000..ddfc01ba --- /dev/null +++ b/libdw/dwarf_lineaddr.c @@ -0,0 +1,31 @@ +/* Return line address. + Copyright (C) 2004 Red Hat, Inc. + Written by Ulrich Drepper <drepper@redhat.com>, 2004. + + 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 "libdwP.h" + + +int +dwarf_lineaddr (Dwarf_Line *line, Dwarf_Addr *addrp) +{ + if (line == NULL) + return -1; + + *addrp = line->addr; + + return 0; +} diff --git a/libdw/dwarf_linebeginstatement.c b/libdw/dwarf_linebeginstatement.c new file mode 100644 index 00000000..d974d8f4 --- /dev/null +++ b/libdw/dwarf_linebeginstatement.c @@ -0,0 +1,31 @@ +/* Return true if record is for beginning of a statement. + Copyright (C) 2004 Red Hat, Inc. + Written by Ulrich Drepper <drepper@redhat.com>, 2004. + + 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 "libdwP.h" + + +int +dwarf_linebeginstatement (Dwarf_Line *line, bool *flagp) +{ + if (line == NULL) + return -1; + + *flagp = line->is_stmt; + + return 0; +} diff --git a/libdw/dwarf_lineblock.c b/libdw/dwarf_lineblock.c new file mode 100644 index 00000000..a6b8e0c2 --- /dev/null +++ b/libdw/dwarf_lineblock.c @@ -0,0 +1,31 @@ +/* Return true if record is for beginning of a basic block. + Copyright (C) 2004 Red Hat, Inc. + Written by Ulrich Drepper <drepper@redhat.com>, 2004. + + 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 "libdwP.h" + + +int +dwarf_lineblock (Dwarf_Line *line, bool *flagp) +{ + if (line == NULL) + return -1; + + *flagp = line->basic_block; + + return 0; +} diff --git a/libdw/dwarf_linecol.c b/libdw/dwarf_linecol.c new file mode 100644 index 00000000..2430d372 --- /dev/null +++ b/libdw/dwarf_linecol.c @@ -0,0 +1,31 @@ +/* Return column in line. + Copyright (C) 2004 Red Hat, Inc. + Written by Ulrich Drepper <drepper@redhat.com>, 2004. + + 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 "libdwP.h" + + +int +dwarf_linecol (Dwarf_Line *line, int *colp) +{ + if (line == NULL) + return -1; + + *colp = line->column; + + return 0; +} diff --git a/libdw/dwarf_lineendsequence.c b/libdw/dwarf_lineendsequence.c new file mode 100644 index 00000000..c49fabe2 --- /dev/null +++ b/libdw/dwarf_lineendsequence.c @@ -0,0 +1,31 @@ +/* Return true if record is for end of sequence. + Copyright (C) 2004 Red Hat, Inc. + Written by Ulrich Drepper <drepper@redhat.com>, 2004. + + 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 "libdwP.h" + + +int +dwarf_lineendsequence (Dwarf_Line *line, bool *flagp) +{ + if (line == NULL) + return -1; + + *flagp = line->end_sequence; + + return 0; +} diff --git a/libdw/dwarf_lineepiloguebegin.c b/libdw/dwarf_lineepiloguebegin.c new file mode 100644 index 00000000..ee4f5bb7 --- /dev/null +++ b/libdw/dwarf_lineepiloguebegin.c @@ -0,0 +1,31 @@ +/* Return true if record is for beginning of epilogue. + Copyright (C) 2004 Red Hat, Inc. + Written by Ulrich Drepper <drepper@redhat.com>, 2004. + + 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 "libdwP.h" + + +int +dwarf_lineepiloguebegin (Dwarf_Line *line, bool *flagp) +{ + if (line == NULL) + return -1; + + *flagp = line->epilogue_begin; + + return 0; +} diff --git a/libdw/dwarf_lineno.c b/libdw/dwarf_lineno.c new file mode 100644 index 00000000..5ad24067 --- /dev/null +++ b/libdw/dwarf_lineno.c @@ -0,0 +1,31 @@ +/* Return line number. + Copyright (C) 2004 Red Hat, Inc. + Written by Ulrich Drepper <drepper@redhat.com>, 2004. + + 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 "libdwP.h" + + +int +dwarf_lineno (Dwarf_Line *line, int *linep) +{ + if (line == NULL) + return -1; + + *linep = line->line; + + return 0; +} diff --git a/libdw/dwarf_lineprologueend.c b/libdw/dwarf_lineprologueend.c new file mode 100644 index 00000000..e869025c --- /dev/null +++ b/libdw/dwarf_lineprologueend.c @@ -0,0 +1,31 @@ +/* Return true if record is for end of prologue. + Copyright (C) 2004 Red Hat, Inc. + Written by Ulrich Drepper <drepper@redhat.com>, 2004. + + 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 "libdwP.h" + + +int +dwarf_lineprologueend (Dwarf_Line *line, bool *flagp) +{ + if (line == NULL) + return -1; + + *flagp = line->prologue_end; + + return 0; +} diff --git a/libdw/dwarf_linesrc.c b/libdw/dwarf_linesrc.c new file mode 100644 index 00000000..0aca1d6f --- /dev/null +++ b/libdw/dwarf_linesrc.c @@ -0,0 +1,41 @@ +/* Find line information for address. + Copyright (C) 2004 Red Hat, Inc. + Written by Ulrich Drepper <drepper@redhat.com>, 2004. + + 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 "libdwP.h" + + +const char * +dwarf_linesrc (Dwarf_Line *line, Dwarf_Word *mtime, Dwarf_Word *length) +{ + if (line == NULL) + return NULL; + + if (line->file >= line->files->nfiles) + { + __libdw_seterrno (DWARF_E_INVALID_DWARF); + return NULL; + } + + if (mtime != NULL) + *mtime = line->files->info[line->file].mtime; + + if (length != NULL) + *length = line->files->info[line->file].length; + + return line->files->info[line->file].name; +} diff --git a/libdw/dwarf_lowpc.c b/libdw/dwarf_lowpc.c new file mode 100644 index 00000000..95d29120 --- /dev/null +++ b/libdw/dwarf_lowpc.c @@ -0,0 +1,32 @@ +/* Return low PC attribute of DIE. + Copyright (C) 2003 Red Hat, Inc. + Written by Ulrich Drepper <drepper@redhat.com>, 2003. + + 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 "libdwP.h" + + +int +dwarf_lowpc (die, return_addr) + Dwarf_Die *die; + Dwarf_Addr *return_addr; +{ + Dwarf_Attribute attr_mem; + + return dwarf_formaddr (dwarf_attr (die, DW_AT_low_pc, &attr_mem), + return_addr); +} diff --git a/libdw/dwarf_nextcu.c b/libdw/dwarf_nextcu.c new file mode 100644 index 00000000..e674a66e --- /dev/null +++ b/libdw/dwarf_nextcu.c @@ -0,0 +1,131 @@ +/* Advance to next CU header. + Copyright (C) 2002, 2003, 2004 Red Hat, Inc. + Written by Ulrich Drepper <drepper@redhat.com>, 2002. + + 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 <libdwP.h> + + +int +dwarf_nextcu (dwarf, off, next_off, header_sizep, abbrev_offsetp, + address_sizep, offset_sizep) + Dwarf *dwarf; + Dwarf_Off off; + Dwarf_Off *next_off; + size_t *header_sizep; + Dwarf_Off *abbrev_offsetp; + uint8_t *address_sizep; + uint8_t *offset_sizep; +{ + /* Maybe there has been an error before. */ + if (dwarf == NULL) + return -1; + + /* If we reached the end before don't do anything. */ + if (off == (Dwarf_Off) -1l + /* 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. */ + || unlikely (off + 4 >= dwarf->sectiondata[IDX_debug_info]->d_size)) + { + *next_off = (Dwarf_Off) -1l; + return 1; + } + + /* This points into the .debug_info section to the beginning of the + CU entry. */ + char *bytes = (char *) dwarf->sectiondata[IDX_debug_info]->d_buf + off; + + /* 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. */ + uint64_t length = read_4ubyte_unaligned_inc (dwarf, bytes); + size_t offset_size = 4; + if (length == 0xffffffffu) + 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 (off + 2 * offset_size - 4 + sizeof (uint16_t) + + offset_size + sizeof (uint8_t) + >= dwarf->sectiondata[IDX_debug_info]->d_size)) + { + *next_off = -1; + return 1; + } + + if (length == 0xffffffffu) + /* This is a 64-bit DWARF format. */ + length = read_8ubyte_unaligned_inc (dwarf, bytes); + + /* Read the version stamp. Always a 16-bit value. + XXX Do we need the value? */ + read_2ubyte_unaligned_inc (dwarf, bytes); + + /* 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. */ + uint64_t abbrev_offset; + if (offset_size == 4) + abbrev_offset = read_4ubyte_unaligned_inc (dwarf, bytes); + else + abbrev_offset = read_8ubyte_unaligned_inc (dwarf, bytes); + if (abbrev_offsetp != NULL) + *abbrev_offsetp = abbrev_offset; + + /* The address size. Always an 8-bit value. */ + uint8_t address_size = *bytes++; + if (address_sizep != NULL) + *address_sizep = address_size; + + /* Store the offset size. */ + if (offset_sizep != NULL) + *offset_sizep = offset_size; + + /* Store the header length. */ + if (header_sizep != NULL) + *header_sizep = (bytes + - ((char *) dwarf->sectiondata[IDX_debug_info]->d_buf + + off)); + + /* See above for an explanation of the trick in this formula. */ + *next_off = off + 2 * offset_size - 4 + length; + + return 0; +} diff --git a/libdw/dwarf_offabbrev.c b/libdw/dwarf_offabbrev.c new file mode 100644 index 00000000..17978fbc --- /dev/null +++ b/libdw/dwarf_offabbrev.c @@ -0,0 +1,30 @@ +/* Get abbreviation at given offset. + Copyright (C) 2004 Red Hat, Inc. + Written by Ulrich Drepper <drepper@redhat.com>, 2004. + + 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 "libdwP.h" + + +int +dwarf_offabbrev (Dwarf *dbg, Dwarf_Off offset, size_t *lengthp, + Dwarf_Abbrev *abbrevp) +{ + if (dbg == NULL) + return -1; + + return __libdw_getabbrev (dbg, NULL, offset, lengthp, abbrevp) == NULL; +} diff --git a/libdw/dwarf_offdie.c b/libdw/dwarf_offdie.c new file mode 100644 index 00000000..6ef5595c --- /dev/null +++ b/libdw/dwarf_offdie.c @@ -0,0 +1,54 @@ +/* Return DIE at given offset. + Copyright (C) 2002, 2003 Red Hat, Inc. + Written by Ulrich Drepper <drepper@redhat.com>, 2002. + + 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 "libdwP.h" + + +Dwarf_Die * +dwarf_offdie (dbg, offset, result) + Dwarf *dbg; + Dwarf_Off offset; + Dwarf_Die *result; +{ + if (dbg == NULL) + return NULL; + + if (offset >= dbg->sectiondata[IDX_debug_info]->d_size) + { + __libdw_seterrno (DWARF_E_INVALID_DWARF); + return NULL; + } + + /* Clear the entire DIE structure. This signals we have not yet + determined any of the information. */ + memset (result, '\0', sizeof (Dwarf_Die)); + + result->addr = (char *) dbg->sectiondata[IDX_debug_info]->d_buf + offset; + + /* Get the CU. */ + result->cu = __libdw_findcu (dbg, offset); + if (result->cu == NULL) + { + /* This should never happen. The input file is malformed. */ + __libdw_seterrno (DWARF_E_INVALID_DWARF); + result = NULL; + } + + return result; +} diff --git a/libdw/dwarf_onearange.c b/libdw/dwarf_onearange.c new file mode 100644 index 00000000..0c372526 --- /dev/null +++ b/libdw/dwarf_onearange.c @@ -0,0 +1,35 @@ +/* Return one of the address range entries. + Copyright (C) 2004 Red Hat, Inc. + Written by Ulrich Drepper <drepper@redhat.com>, 2004. + + 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 "libdwP.h" + + +Dwarf_Arange * +dwarf_onearange (Dwarf_Aranges *aranges, size_t idx) +{ + if (aranges == NULL) + return NULL; + + if (idx >= aranges->naranges) + { + __libdw_seterrno (DWARF_E_INVALID_ARANGE_IDX); + return NULL; + } + + return &aranges->info[idx]; +} diff --git a/libdw/dwarf_onesrcline.c b/libdw/dwarf_onesrcline.c new file mode 100644 index 00000000..9234ef9a --- /dev/null +++ b/libdw/dwarf_onesrcline.c @@ -0,0 +1,35 @@ +/* Return one of the sources lines of a CU. + Copyright (C) 2004 Red Hat, Inc. + Written by Ulrich Drepper <drepper@redhat.com>, 2004. + + 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 "libdwP.h" + + +Dwarf_Line * +dwarf_onesrcline (Dwarf_Lines *lines, size_t idx) +{ + if (lines == NULL) + return NULL; + + if (idx >= lines->nlines) + { + __libdw_seterrno (DWARF_E_INVALID_LINE_IDX); + return NULL; + } + + return &lines->info[idx]; +} diff --git a/libdw/dwarf_siblingof.c b/libdw/dwarf_siblingof.c new file mode 100644 index 00000000..90081c64 --- /dev/null +++ b/libdw/dwarf_siblingof.c @@ -0,0 +1,104 @@ +/* Return sibling of given DIE. + Copyright (C) 2003, 2004 Red Hat, Inc. + Written by Ulrich Drepper <drepper@redhat.com>, 2003. + + 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 "libdwP.h" +#include <dwarf.h> +#include <string.h> + + +int +dwarf_siblingof (die, result) + Dwarf_Die *die; + Dwarf_Die *result; +{ + /* Ignore previous errors. */ + if (die == NULL) + return -1; + + unsigned int level = 0; + + /* Copy of the current DIE. */ + Dwarf_Die this_die = *die; + /* Temporary attributes we create. */ + Dwarf_Attribute sibattr; + /* Copy of the CU in the request. */ + sibattr.cu = this_die.cu; + /* That's the address we start looking. */ + unsigned char *addr = this_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 + { + /* Find the end of the DIE or the sibling attribute. */ + addr = __libdw_find_attr (&this_die, DW_AT_sibling, &sibattr.code, + &sibattr.form); + if (sibattr.code == DW_AT_sibling) + { + Dwarf_Off offset; + sibattr.valp = addr; + if (dwarf_formref (&sibattr, &offset) != 0) + /* Something went wrong. */ + return -1; + + /* Compute the next address. */ + addr = ((unsigned char *) + sibattr.cu->dbg->sectiondata[IDX_debug_info]->d_buf + + sibattr.cu->start + offset); + } + else if (unlikely (addr == NULL) + || unlikely (this_die.abbrev == (Dwarf_Abbrev *) -1l)) + return -1; + else if (this_die.abbrev->has_children) + /* This abbreviation has children. */ + ++level; + + /* Check that we are not yet at the end. */ + while (*addr == '\0') + { + if (level-- == 0) + /* No more sibling at all. */ + return 1; + + ++addr; + } + + /* Initialize the 'current DIE'. */ + this_die.addr = addr; + this_die.abbrev = NULL; + } + while (level > 0); + + /* Maybe we reached the end of the CU. */ + if (addr + >= ((unsigned char *) sibattr.cu->dbg->sectiondata[IDX_debug_info]->d_buf + + sibattr.cu->end)) + return 1; + + /* Clear the entire DIE structure. This signals we have not yet + determined any of the information. */ + memset (result, '\0', sizeof (Dwarf_Die)); + + /* We have the address. */ + result->addr = addr; + + /* Same CU as the parent. */ + result->cu = sibattr.cu; + + return 0; +} diff --git a/libdw/dwarf_srclang.c b/libdw/dwarf_srclang.c new file mode 100644 index 00000000..fc256321 --- /dev/null +++ b/libdw/dwarf_srclang.c @@ -0,0 +1,32 @@ +/* Return source language attribute of DIE. + Copyright (C) 2003 Red Hat, Inc. + Written by Ulrich Drepper <drepper@redhat.com>, 2003. + + 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 "libdwP.h" + + +int +dwarf_srclang (die) + Dwarf_Die *die; +{ + Dwarf_Attribute attr_mem; + Dwarf_Word value; + + return dwarf_formudata (dwarf_attr (die, DW_AT_language, &attr_mem), + &value) == 0 ? (int) value : -1; +} diff --git a/libdw/dwarf_tag.c b/libdw/dwarf_tag.c new file mode 100644 index 00000000..23814cbc --- /dev/null +++ b/libdw/dwarf_tag.c @@ -0,0 +1,81 @@ +/* Return tag of given DIE. + Copyright (C) 2003, 2004 Red Hat, Inc. + Written by Ulrich Drepper <drepper@redhat.com>, 2003. + + 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 "libdwP.h" + + +Dwarf_Abbrev * +internal_function_def +__libdw_findabbrev (struct Dwarf_CU *cu, unsigned int code) +{ + Dwarf_Abbrev *abb; + + /* See whether the entry is already in the hash table. */ + abb = Dwarf_Abbrev_Hash_find (&cu->abbrev_hash, code, NULL); + if (abb == NULL) + while (cu->last_abbrev_offset != (size_t) -1l) + { + size_t length; + + /* Find the next entry. It gets automatically added to the + hash table. */ + abb = __libdw_getabbrev (cu->dbg, cu, cu->last_abbrev_offset, &length, + NULL); + if (abb == NULL) + { + /* Make sure we do not try to search for it again. */ + cu->last_abbrev_offset = (size_t) -1l; + abb = (void *) -1l; + break; + } + + cu->last_abbrev_offset += length; + + /* Is this the code we are looking for? */ + if (abb->code == code) + break; + } + + return abb; +} + + +int +dwarf_tag (die) + Dwarf_Die *die; +{ + /* Do we already know the abbreviation? */ + if (die->abbrev == NULL) + { + /* Get the abbreviation code. */ + unsigned int u128; + unsigned char *addr = die->addr; + get_uleb128 (u128, addr); + + /* Find the abbreviation. */ + die->abbrev = __libdw_findabbrev (die->cu, u128); + } + + if (die->abbrev == (Dwarf_Abbrev *) -1l) + { + __libdw_seterrno (DWARF_E_INVALID_DWARF); + return DW_TAG_invalid; + } + + return die->abbrev->tag; +} diff --git a/libdw/dwarf_whatattr.c b/libdw/dwarf_whatattr.c new file mode 100644 index 00000000..ad5d868f --- /dev/null +++ b/libdw/dwarf_whatattr.c @@ -0,0 +1,28 @@ +/* Return attribute code of given attribute. + Copyright (C) 2003 Red Hat, Inc. + Written by Ulrich Drepper <drepper@redhat.com>, 2003. + + 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 "libdwP.h" + + +unsigned int +dwarf_whatattr (attr) + Dwarf_Attribute *attr; +{ + return attr == NULL ? 0 : attr->code; +} diff --git a/libdw/dwarf_whatform.c b/libdw/dwarf_whatform.c new file mode 100644 index 00000000..99da1c97 --- /dev/null +++ b/libdw/dwarf_whatform.c @@ -0,0 +1,28 @@ +/* Return form code of given attribute. + Copyright (C) 2003 Red Hat, Inc. + Written by Ulrich Drepper <drepper@redhat.com>, 2003. + + 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 "libdwP.h" + + +unsigned int +dwarf_whatform (attr) + Dwarf_Attribute *attr; +{ + return attr == NULL ? 0 : attr->form; +} diff --git a/libdw/libdw.h b/libdw/libdw.h new file mode 100644 index 00000000..eee986ff --- /dev/null +++ b/libdw/libdw.h @@ -0,0 +1,453 @@ +/* Interfaces for libdw. + Copyright (C) 2002, 2004 Red Hat, Inc. + Contributed by Ulrich Drepper <drepper@redhat.com>, 2002. + + 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 _LIBDW_H +#define _LIBDW_H 1 + +#include <gelf.h> +#include <stdbool.h> +#include <stddef.h> + + +#if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 3) +# define __nonnull_attribute__(...) __attribute__ ((__nonnull__ (__VA_ARGS__))) +#else +# define __nonnull_attribute__(args...) +#endif + + +/* Mode for the session. */ +typedef enum + { + DWARF_C_READ, /* Read .. */ + DWARF_C_RDWR, /* Read and write .. */ + DWARF_C_WRITE, /* Write .. */ + } +Dwarf_Cmd; + + +/* Callback results. */ +enum +{ + DWARF_CB_OK = 0, + DWARF_CB_ABORT +}; + + +/* Error values. */ +enum + { + DW_TAG_invalid = 0 +#define DW_TAG_invalid DW_TAG_invalid + }; + + +/* Type for offset in DWARF file. */ +typedef GElf_Off Dwarf_Off; + +/* Type for address in DWARF file. */ +typedef GElf_Addr Dwarf_Addr; + +/* Integer types. Big enough to hold any numeric value. */ +typedef GElf_Xword Dwarf_Word; +typedef GElf_Sxword Dwarf_Sword; +/* For the times we know we do not need that much. */ +typedef GElf_Half Dwarf_Half; + + +/* DWARF abbreviation record. */ +typedef struct Dwarf_Abbrev Dwarf_Abbrev; + +/* Source code line information for CU. */ +typedef struct Dwarf_Lines_s Dwarf_Lines; + +/* One source code line information. */ +typedef struct Dwarf_Line_s Dwarf_Line; + +/* Source file information. */ +typedef struct Dwarf_Files_s Dwarf_Files; + +/* One address range record. */ +typedef struct Dwarf_Arange_s Dwarf_Arange; + +/* Address ranges of a file. */ +typedef struct Dwarf_Aranges_s Dwarf_Aranges; + +/* CU representation. */ +struct Dwarf_CU; + +/* Attribute representation. */ +typedef struct +{ + unsigned int code; + unsigned int form; + unsigned char *valp; + struct Dwarf_CU *cu; +} Dwarf_Attribute; + + +/* Data block representation. */ +typedef struct +{ + Dwarf_Word length; + unsigned char *data; +} Dwarf_Block; + + +/* Macro information. */ +typedef struct +{ + unsigned int opcode; + Dwarf_Word param1; + union + { + Dwarf_Word u; + const char *s; + } param2; +} Dwarf_Macro; + + +/* DIE information. */ +typedef struct +{ + /* The offset can be computed from the address. */ + void *addr; + struct Dwarf_CU *cu; + Dwarf_Abbrev *abbrev; + // XXX We'll see what other information will be needed. +} Dwarf_Die; + +/* Returned to show the last DIE has be returned. */ +#define DWARF_END_DIE ((Dwarf_Die *) -1l) + + +/* Global symbol information. */ +typedef struct +{ + Dwarf_Off cu_offset; + Dwarf_Off die_offset; + const char *name; +} Dwarf_Global; + + +// XXX It remains to be seen whether the next two need to be exported. +/* Location record. */ +typedef struct +{ + uint8_t atom; /* Operation */ + Dwarf_Word number; /* Operand */ + Dwarf_Word number2; /* Possible second operand */ + Dwarf_Word offset; /* Offset in location expression */ +} Dwarf_Loc; + + +/* Handle for debug sessions. */ +typedef struct Dwarf Dwarf; + + +/* Out-Of-Memory handler. */ +typedef void (*__attribute__ ((noreturn)) Dwarf_OOM) (void); + + +/* Create a handle for a new debug session. */ +extern Dwarf *dwarf_begin (int fildes, Dwarf_Cmd cmd); + +/* Create a handle for a new debug session for an ELF file. */ +extern Dwarf *dwarf_begin_elf (Elf *elf, Dwarf_Cmd cmd, Elf_Scn *scngrp); + +/* Retrieve ELF descriptor used for DWARF access. */ +extern Elf *dwarf_getelf (Dwarf *dwarf); + +/* Release debugging handling context. */ +extern int dwarf_end (Dwarf *dwarf); + + +/* Get the data block for the .debug_info section. */ +extern Elf_Data *dwarf_getscn_info (Dwarf *dwarf); + +/* Read the header for the DWARF CU header. */ +extern int dwarf_nextcu (Dwarf *dwarf, Dwarf_Off off, Dwarf_Off *next_off, + size_t *header_sizep, Dwarf_Off *abbrev_offsetp, + uint8_t *address_sizep, uint8_t *offset_sizep) + __nonnull_attribute__ (3); + + +/* Return DIE at given offset. */ +extern Dwarf_Die *dwarf_offdie (Dwarf *dbg, Dwarf_Off offset, + Dwarf_Die *result) __nonnull_attribute__ (3); + +/* Return offset of DIE. */ +extern Dwarf_Off dwarf_dieoffset (Dwarf_Die *die); + +/* Return offset of DIE in CU. */ +extern Dwarf_Off dwarf_cuoffset (Dwarf_Die *die); + +/* Return vhild of current DIE. */ +extern int dwarf_child (Dwarf_Die *die, Dwarf_Die *result) + __nonnull_attribute__ (2); + +/* Return sibling of given DIE. */ +extern int dwarf_siblingof (Dwarf_Die *die, Dwarf_Die *result) + __nonnull_attribute__ (2); + +/* Check whether the DIE has children. */ +extern int dwarf_haschildren (Dwarf_Die *die); + +/* Get attributes of the DIE. */ +extern ptrdiff_t dwarf_getattrs (Dwarf_Die *die, + int (*callback) (Dwarf_Attribute *, void *), + void *arg, ptrdiff_t offset); + +/* Return tag of given DIE. */ +extern int dwarf_tag (Dwarf_Die *die); + + +/* Return specific attribute of DIE. */ +extern Dwarf_Attribute *dwarf_attr (Dwarf_Die *die, unsigned int search_name, + Dwarf_Attribute *result) + __nonnull_attribute__ (3); + +/* Check whether given DIE has specific attribute. */ +extern int dwarf_hasattr (Dwarf_Die *die, unsigned int search_name); + + +/* Check whether given attribute has specific form. */ +extern int dwarf_hasform (Dwarf_Attribute *attr, unsigned int search_form); + +/* Return attribute code of given attribute. */ +extern unsigned int dwarf_whatattr (Dwarf_Attribute *attr); + +/* Return form code of given attribute. */ +extern unsigned int dwarf_whatform (Dwarf_Attribute *attr); + + +/* Return string associated with given attribute. */ +extern const char *dwarf_formstring (Dwarf_Attribute *attrp); + +/* Return unsigned constant represented by attribute. */ +extern int dwarf_formudata (Dwarf_Attribute *attr, Dwarf_Word *return_uval) + __nonnull_attribute__ (2); + +/* Return signed constant represented by attribute. */ +extern int dwarf_formsdata (Dwarf_Attribute *attr, Dwarf_Sword *return_uval) + __nonnull_attribute__ (2); + +/* Return address represented by attribute. */ +extern int dwarf_formaddr (Dwarf_Attribute *attr, Dwarf_Addr *return_addr) + __nonnull_attribute__ (2); + +/* Return reference offset represented by attribute. */ +extern int dwarf_formref (Dwarf_Attribute *attr, Dwarf_Off *return_offset) + __nonnull_attribute__ (2); + +/* Return block represented by attribute. */ +extern int dwarf_formblock (Dwarf_Attribute *attr, Dwarf_Block *return_block) + __nonnull_attribute__ (2); + +/* Return flag represented by attribute. */ +extern int dwarf_formflag (Dwarf_Attribute *attr, bool *return_bool) + __nonnull_attribute__ (2); + + +/* Simplified attribute value access functions. */ + +/* Return string in name attribute of DIE. */ +extern const char *dwarf_diename (Dwarf_Die *die); + +/* Return high PC attribute of DIE. */ +extern int dwarf_highpc (Dwarf_Die *die, Dwarf_Addr *return_addr) + __nonnull_attribute__ (2); + +/* Return low PC attribute of DIE. */ +extern int dwarf_lowpc (Dwarf_Die *die, Dwarf_Addr *return_addr) + __nonnull_attribute__ (2); + +/* Return byte size attribute of DIE. */ +extern int dwarf_bytesize (Dwarf_Die *die); + +/* Return bit size attribute of DIE. */ +extern int dwarf_bitsize (Dwarf_Die *die); + +/* Return bit offset attribute of DIE. */ +extern int dwarf_bitoffset (Dwarf_Die *die); + +/* Return array order attribute of DIE. */ +extern int dwarf_arrayorder (Dwarf_Die *die); + +/* Return source language attribute of DIE. */ +extern int dwarf_srclang (Dwarf_Die *die); + + +/* Get abbreviation at given offset for given DIE. */ +extern Dwarf_Abbrev *dwarf_getabbrev (Dwarf_Die *die, Dwarf_Off offset, + size_t *lengthp); + +/* Get abbreviation at given offset in .debug_abbrev section. */ +extern int dwarf_offabbrev (Dwarf *dbg, Dwarf_Off offset, size_t *lengthp, + Dwarf_Abbrev *abbrevp) + __nonnull_attribute__ (4); + +/* Get abbreviation code. */ +extern unsigned int dwarf_getabbrevcode (Dwarf_Abbrev *abbrev); + +/* Get abbreviation tag. */ +extern unsigned int dwarf_getabbrevtag (Dwarf_Abbrev *abbrev); + +/* Return true if abbreviation is children flag set. */ +extern int dwarf_abbrevhaschildren (Dwarf_Abbrev *abbrev); + +/* Get number of attributes of abbreviation. */ +extern int dwarf_getattrcnt (Dwarf_Abbrev *abbrev, size_t *attrcntp) + __nonnull_attribute__ (2); + +/* Get specific attribute of abbreviation. */ +extern int dwarf_getabbrevattr (Dwarf_Abbrev *abbrev, size_t idx, + unsigned int *namep, unsigned int *formp, + Dwarf_Off *offset); + + +/* Get string from-debug_str section. */ +extern const char *dwarf_getstring (Dwarf *dbg, Dwarf_Off offset, + size_t *lenp); + + +/* Get public symbol information. */ +extern ptrdiff_t dwarf_getpubnames (Dwarf *dbg, + int (*callback) (Dwarf *, Dwarf_Global *, + void *), + void *arg, ptrdiff_t offset) + __nonnull_attribute__ (2); + + +/* Get source file information for CU. */ +extern int dwarf_getsrclines (Dwarf_Die *cudie, Dwarf_Lines **lines, + size_t *nlines) __nonnull_attribute__ (2, 3); + +/* Return one of the source lines of the CU. */ +extern Dwarf_Line *dwarf_onesrcline (Dwarf_Lines *lines, size_t idx); + +/* Get the file source files used in the CU. */ +extern int dwarf_getsrcfiles (Dwarf_Die *cudie, Dwarf_Files **files, + size_t *nfiles) + __nonnull_attribute__ (2); + + +/* Get source for address in CU. */ +extern Dwarf_Line *dwarf_getsrc_die (Dwarf_Die *cudie, Dwarf_Addr addr); + +/* Return line address. */ +extern int dwarf_lineaddr (Dwarf_Line *line, Dwarf_Addr *addrp); + +/* Return line number. */ +extern int dwarf_lineno (Dwarf_Line *line, int *linep) + __nonnull_attribute__ (2); + +/* Return column in line. */ +extern int dwarf_linecol (Dwarf_Line *line, int *colp) + __nonnull_attribute__ (2); + +/* Return true if record is for beginning of a statement. */ +extern int dwarf_linebeginstatement (Dwarf_Line *line, bool *flagp) + __nonnull_attribute__ (2); + +/* Return true if record is for end of sequence. */ +extern int dwarf_lineendsequence (Dwarf_Line *line, bool *flagp) + __nonnull_attribute__ (2); + +/* Return true if record is for beginning of a basic block. */ +extern int dwarf_lineblock (Dwarf_Line *line, bool *flagp) + __nonnull_attribute__ (2); + +/* Return true if record is for end of prologue. */ +extern int dwarf_lineprologueend (Dwarf_Line *line, bool *flagp) + __nonnull_attribute__ (2); + +/* Return true if record is for beginning of epilogue. */ +extern int dwarf_lineepiloguebegin (Dwarf_Line *line, bool *flagp) + __nonnull_attribute__ (2); + + +/* Find line information for address. */ +extern const char *dwarf_linesrc (Dwarf_Line *line, + Dwarf_Word *mtime, Dwarf_Word *length); + +/* Return file information. */ +extern const char *dwarf_filesrc (Dwarf_Files *file, size_t idx, + Dwarf_Word *mtime, Dwarf_Word *length); + + +/* Return location expression list. */ +extern int dwarf_getloclist (Dwarf_Attribute *attr, Dwarf_Loc **llbuf, + size_t *listlen) __nonnull_attribute__ (2, 3); + + + +/* Return list address ranges. */ +extern int dwarf_getaranges (Dwarf *dbg, Dwarf_Aranges **aranges, + size_t *naranges) + __nonnull_attribute__ (2); + +/* Return one of the address range entries. */ +extern Dwarf_Arange *dwarf_onearange (Dwarf_Aranges *aranges, size_t idx); + +/* Return information in address range record. */ +extern int dwarf_getarangeinfo (Dwarf_Arange *arange, Dwarf_Addr *addrp, + Dwarf_Word *lengthp, Dwarf_Off *offsetp); + +/* Get address range which includes given address. */ +extern Dwarf_Arange *dwarf_getarange_addr (Dwarf_Aranges *aranges, + Dwarf_Addr addr); + + +/* Call callback function for each of the macro information entry for + the CU. */ +extern ptrdiff_t dwarf_getmacros (Dwarf_Die *cudie, + int (*callback) (Dwarf_Macro *, void *), + void *arg, ptrdiff_t offset) + __nonnull_attribute__ (2); + + +/* Return error code of last failing function call. This value is kept + separately for each thread. */ +extern int dwarf_errno (void); + +/* Return error string for ERROR. If ERROR is zero, return error string + for most recent error or NULL is none occurred. If ERROR is -1 the + behaviour is similar to the last case except that not NULL but a legal + string is returned. */ +extern const char *dwarf_errmsg (int err); + + +/* Register new Out-Of-Memory handler. The old handler is returned. */ +extern Dwarf_OOM dwarf_new_oom_handler (Dwarf *dbg, Dwarf_OOM handler); + + +/* Inline optimizations. */ +#ifdef __OPTIMIZE__ +/* Return attribute code of given attribute. */ +extern inline unsigned int +dwarf_whatattr (Dwarf_Attribute *attr) +{ + return attr == NULL ? 0 : attr->code; +} + +/* Return attribute code of given attribute. */ +extern inline unsigned int +dwarf_whatform (Dwarf_Attribute *attr) +{ + return attr == NULL ? 0 : attr->form; +} +#endif /* Optimize. */ + +#endif /* libdw.h */ diff --git a/libdw/libdw.map b/libdw/libdw.map new file mode 100644 index 00000000..e9ae2b9b --- /dev/null +++ b/libdw/libdw.map @@ -0,0 +1,72 @@ +ELFUTILS_1.0 { + global: + dwarf_abbrevhaschildren; + dwarf_attr; + dwarf_arrayorder; + dwarf_begin; + dwarf_begin_elf; + dwarf_bitoffset; + dwarf_bitsize; + dwarf_bytesize; + dwarf_child; + dwarf_cuoffset; + dwarf_diename; + dwarf_dieoffset; + dwarf_end; + dwarf_errmsg; + dwarf_errno; + dwarf_filesrc; + dwarf_formaddr; + dwarf_formblock; + dwarf_formflag; + dwarf_formref; + dwarf_formsdata; + dwarf_formstring; + dwarf_formudata; + dwarf_getabbrev; + dwarf_getabbrevattr; + dwarf_getabbrevcode; + dwarf_getabbrevtag; + dwarf_getarange_addr; + dwarf_getarangeinfo; + dwarf_getaranges; + dwarf_getattrcnt; + dwarf_getattrs; + dwarf_getelf; + dwarf_getloclist; + dwarf_getmacros; + dwarf_getpubnames; + dwarf_getscn_info; + dwarf_getsrc_die; + dwarf_getsrcfiles; + dwarf_getsrclines; + dwarf_getstring; + dwarf_hasattr; + dwarf_haschildren; + dwarf_hasform; + dwarf_highpc; + dwarf_lineaddr; + dwarf_linebeginstatement; + dwarf_lineblock; + dwarf_linecol; + dwarf_lineendsequence; + dwarf_lineepiloguebegin; + dwarf_lineno; + dwarf_lineprologueend; + dwarf_linesrc; + dwarf_lowpc; + dwarf_offabbrev; + dwarf_offdie; + dwarf_onearange; + dwarf_onesrcline; + dwarf_nextcu; + dwarf_new_oom_handler; + dwarf_siblingof; + dwarf_srclang; + dwarf_tag; + dwarf_whatattr; + dwarf_whatform; + + local: + *; +}; diff --git a/libdw/libdwP.h b/libdw/libdwP.h new file mode 100644 index 00000000..892ad513 --- /dev/null +++ b/libdw/libdwP.h @@ -0,0 +1,315 @@ +/* Internal definitions for libdwarf. + Copyright (C) 2002, 2003, 2004 Red Hat, Inc. + Written by Ulrich Drepper <drepper@redhat.com>, 2002. + + 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 _LIBDWP_H +#define _LIBDWP_H 1 + +#include <libintl.h> +#include <stdbool.h> + +#include <libdw.h> + + +/* gettext helper macros. */ +#define _(Str) dgettext ("elfutils", Str) + + +/* Version of the DWARF specification we support. */ +#define DWARF_VERSION 2 + +/* Version of the CIE format. */ +#define CIE_VERSION 1 + + +/* Known location lists. */ +struct loc_s +{ + void *addr; + Dwarf_Loc *loc; + size_t nloc; +}; + +/* 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 + }; + + +/* Error values. */ +enum +{ + DWARF_E_NOERROR = 0, + DWARF_E_UNKNOWN_ERROR, + DWARF_E_INVALID_ACCESS, + DWARF_E_NO_REGFILE, + DWARF_E_IO_ERROR, + DWARF_E_INVALID_ELF, + DWARF_E_NO_DWARF, + DWARF_E_NOELF, + DWARF_E_GETEHDR_ERROR, + DWARF_E_NOMEM, + DWARF_E_UNIMPL, + DWARF_E_INVALID_CMD, + DWARF_E_INVALID_VERSION, + DWARF_E_INVALID_FILE, + DWARF_E_NO_ENTRY, + DWARF_E_INVALID_DWARF, + DWARF_E_NO_STRING, + DWARF_E_NO_ADDR, + DWARF_E_NO_CONSTANT, + DWARF_E_NO_REFERENCE, + DWARF_E_INVALID_REFERENCE, + DWARF_E_NO_DEBUG_LINE, + DWARF_E_INVALID_DEBUG_LINE, + DWARF_E_TOO_BIG, + DWARF_E_VERSION, + DWARF_E_INVALID_DIR_IDX, + DWARF_E_ADDR_OUTOFRANGE, + DWARF_E_NO_LOCLIST, + DWARF_E_NO_BLOCK, + DWARF_E_INVALID_LINE_IDX, + DWARF_E_INVALID_ARANGE_IDX, + DWARF_E_NO_MATCH, + DWARF_E_NO_FLAG, +}; + + +/* This is the structure representing the debugging state. */ +struct Dwarf +{ + /* The underlying ELF file. */ + Elf *elf; + + /* The section data. */ + Elf_Data *sectiondata[IDX_last]; + + /* True if the file has a byte order different from the host. */ + bool other_byte_order; + + /* If true, we allocated the ELF descriptor ourselves. */ + bool free_elf; + + /* Information for traversing the .debug_pubnames section. This is + an array and separately allocated with malloc. */ + struct pubnames_s + { + Dwarf_Off cu_offset; + Dwarf_Off set_start; + unsigned int cu_header_size; + int address_len; + } *pubnames_sets; + size_t pubnames_nsets; + + /* Search tree for the CUs. */ + void *cu_tree; + Dwarf_Off next_cu_offset; + + /* Address ranges. */ + Dwarf_Aranges *aranges; + + /* Internal memory handling. This is basically a simplified + reimplementation of obstacks. Unfortunately the standard obstack + implementation is not usable in libraries. */ + struct libdw_memblock + { + size_t size; + size_t remaining; + struct libdw_memblock *prev; + char mem[0]; + } *mem_tail; + + /* Default size of allocated memory blocks. */ + size_t mem_default_size; + + /* Registered OOM handler. */ + Dwarf_OOM oom_handler; +}; + + +/* Abbreviation representation. */ +struct Dwarf_Abbrev +{ + unsigned int code; + unsigned int tag; + int has_children; + unsigned int attrcnt; + unsigned char *attrp; + Dwarf_Off offset; +}; + +#include "dwarf_abbrev_hash.h" + + +/* Files in line information records. */ +struct Dwarf_Files_s + { + Dwarf *dbg; + unsigned int nfiles; + struct Dwarf_Fileinfo_s + { + char *name; + Dwarf_Word mtime; + Dwarf_Word length; + } info[0]; + }; +typedef struct Dwarf_Fileinfo_s Dwarf_Fileinfo; + + +/* Representation of a row in the line table. */ +struct Dwarf_Lines_s + { + size_t nlines; + + 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_Files *files; + } info[0]; + }; + + +/* Representation of address ranges. */ +struct Dwarf_Aranges_s +{ + Dwarf *dbg; + size_t naranges; + + struct Dwarf_Arange_s + { + Dwarf_Addr addr; + Dwarf_Word length; + Dwarf_Off offset; + } info[0]; +}; + + +/* CU representation. */ +struct Dwarf_CU +{ + Dwarf *dbg; + Dwarf_Off start; + Dwarf_Off end; + uint8_t address_size; + uint8_t offset_size; + + /* Hash table for the abbreviations. */ + Dwarf_Abbrev_Hash abbrev_hash; + /* Offset of the first abbreviation. */ + size_t orig_abbrev_offset; + /* Offset past last read abbreviation. */ + size_t last_abbrev_offset; + + /* The srcline information. */ + Dwarf_Lines *lines; + + /* The source file information. */ + Dwarf_Files *files; + + /* Known location lists. */ + void *locs; +}; + + +/* We have to include the file at this point because the inline + functions access internals of the Dwarf structure. */ +#include "memory-access.h" + + +/* Set error value. */ +extern void __libdw_seterrno (int value) internal_function; + + +/* Memory handling, the easy parts. This macro does not do any locking. */ +#define libdw_alloc(dbg, type, tsize, cnt) \ + ({ struct libdw_memblock *_tail = (dbg)->mem_tail; \ + size_t _required = (tsize) * (cnt); \ + type *_result = (type *) (_tail->mem + (_tail->size - _tail->remaining));\ + size_t _padding = ((__alignof (type) \ + - ((uintptr_t) _result & (__alignof (type) - 1))) \ + & (__alignof (type) - 1)); \ + if (unlikely (_tail->remaining < _required + _padding)) \ + { \ + _result = (type *) __libdw_allocate (dbg, _required); \ + _tail = (dbg)->mem_tail; \ + } \ + else \ + { \ + _required += _padding; \ + _result = (type *) ((char *) _result + _padding); \ + } \ + _tail->remaining -= _required; \ + _result; }) + +#define libdw_typed_alloc(dbg, type) \ + libdw_alloc (dbg, type, sizeof (type), 1) + +/* Callback to allocate more. */ +extern void *__libdw_allocate (Dwarf *dbg, size_t minsize) + __attribute__ ((__malloc__)) __nonnull_attribute__ (1); + +/* Default OOM handler. */ +extern void __libdw_oom (void) __attribute ((noreturn, visibility ("hidden"))); + +/* Find CU for given offset. */ +extern struct Dwarf_CU *__libdw_findcu (Dwarf *dbg, Dwarf_Off offset) + __nonnull_attribute__ (1) internal_function; + +/* Return tag of given DIE. */ +extern Dwarf_Abbrev *__libdw_findabbrev (struct Dwarf_CU *cu, + unsigned int code) + __nonnull_attribute__ (1) internal_function; + +/* Get abbreviation at given offset. */ +extern Dwarf_Abbrev *__libdw_getabbrev (Dwarf *dbg, struct Dwarf_CU *cu, + Dwarf_Off offset, size_t *lengthp, + Dwarf_Abbrev *result) + __nonnull_attribute__ (1) internal_function; + +/* Helper functions for form handling. */ +extern size_t __libdw_form_val_len (Dwarf *dbg, struct Dwarf_CU *cu, + unsigned int form, unsigned char *valp) + __nonnull_attribute__ (1, 2, 4) internal_function; + +/* Helper function to locate attribute. */ +extern unsigned char *__libdw_find_attr (Dwarf_Die *die, + unsigned int search_name, + unsigned int *codep, + unsigned int *formp) + __nonnull_attribute__ (1) internal_function; + +#endif /* libdwP.h */ diff --git a/libdw/libdw_alloc.c b/libdw/libdw_alloc.c new file mode 100644 index 00000000..1c53d366 --- /dev/null +++ b/libdw/libdw_alloc.c @@ -0,0 +1,59 @@ +/* Memory handling for libdw. + Copyright (C) 2003, 2004 Red Hat, Inc. + Written by Ulrich Drepper <drepper@redhat.com>, 2003. + + 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 <error.h> +#include <errno.h> +#include <stdlib.h> +#include <sys/param.h> +#include "libdwP.h" + + +void * +__libdw_allocate (Dwarf *dbg, size_t minsize) +{ + size_t size = MAX (dbg->mem_default_size, + 2 * minsize + offsetof (struct libdw_memblock, mem)); + struct libdw_memblock *newp = malloc (size); + if (newp == NULL) + dbg->oom_handler (); + + newp->size = newp->remaining = size - offsetof (struct libdw_memblock, mem); + + newp->prev = dbg->mem_tail; + dbg->mem_tail = newp; + + return newp->mem; +} + + +Dwarf_OOM +dwarf_new_oom_handler (Dwarf *dbg, Dwarf_OOM handler) +{ + Dwarf_OOM old = dbg->oom_handler; + dbg->oom_handler = handler; + return old; +} + + +void +__attribute ((noreturn, visibility ("hidden"))) +__libdw_oom (void) +{ + while (1) + error (EXIT_FAILURE, ENOMEM, "libdw"); +} diff --git a/libdw/libdw_findcu.c b/libdw/libdw_findcu.c new file mode 100644 index 00000000..b8166572 --- /dev/null +++ b/libdw/libdw_findcu.c @@ -0,0 +1,109 @@ +/* Find CU for given offset. + Copyright (C) 2003, 2004 Red Hat, Inc. + Written by Ulrich Drepper <drepper@redhat.com>, 2003. + + 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 <search.h> +#include "libdwP.h" + + +static int +findcu_cb (const void *arg1, const void *arg2) +{ + struct Dwarf_CU *cu1 = (struct Dwarf_CU *) arg1; + struct Dwarf_CU *cu2 = (struct Dwarf_CU *) arg2; + + /* Find out which of the two arguments is the search value. It has + end offset 0. */ + if (cu1->end == 0) + { + if (cu1->start < cu2->start) + return -1; + if (cu1->start >= cu2->end) + return 1; + } + else + { + if (cu2->start < cu1->start) + return 1; + if (cu2->start >= cu1->end) + return -1; + } + + return 0; +} + + +struct Dwarf_CU * +__libdw_findcu (dbg, start) + Dwarf *dbg; + Dwarf_Off start; +{ + /* Maybe we already know that CU. */ + struct Dwarf_CU fake = { .start = start, .end = 0 }; + struct Dwarf_CU **found = tfind (&fake, &dbg->cu_tree, findcu_cb); + if (found != NULL) + return *found; + + if (start < dbg->next_cu_offset) + { + __libdw_seterrno (DWARF_E_INVALID_DWARF); + return NULL; + } + + /* No. Then read more CUs. */ + while (1) + { + Dwarf_Off oldoff = dbg->next_cu_offset; + uint8_t address_size; + uint8_t offset_size; + Dwarf_Off abbrev_offset; + + if (dwarf_nextcu (dbg, oldoff, &dbg->next_cu_offset, NULL, + &abbrev_offset, &address_size, &offset_size) != 0) + /* No more entries. */ + return NULL; + + /* Create an entry for this CU. */ + struct Dwarf_CU *newp = libdw_typed_alloc (dbg, struct Dwarf_CU); + + newp->dbg = dbg; + newp->start = oldoff; + newp->end = dbg->next_cu_offset; + newp->address_size = address_size; + newp->offset_size = offset_size; + Dwarf_Abbrev_Hash_init (&newp->abbrev_hash, 41); + newp->orig_abbrev_offset = newp->last_abbrev_offset = abbrev_offset; + newp->lines = NULL; + newp->locs = NULL; + + /* Add the new entry to the search tree. */ + if (tsearch (newp, &dbg->cu_tree, findcu_cb) == NULL) + { + /* Something went wrong. Unfo the operation. */ + dbg->next_cu_offset = oldoff; + __libdw_seterrno (DWARF_E_NOMEM); + return NULL; + } + + /* Is this the one we are looking for? */ + if (start < dbg->next_cu_offset) + // XXX Match exact offset. + return newp; + } + /* NOTREACHED */ +} diff --git a/libdw/libdw_form.c b/libdw/libdw_form.c new file mode 100644 index 00000000..2543f5a2 --- /dev/null +++ b/libdw/libdw_form.c @@ -0,0 +1,112 @@ +/* Helper functions for form handling. + Copyright (C) 2003, 2004 Red Hat, Inc. + Written by Ulrich Drepper <drepper@redhat.com>, 2003. + + 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 "libdwP.h" + + +size_t +internal_function_def +__libdw_form_val_len (Dwarf *dbg, struct Dwarf_CU *cu, unsigned int form, + unsigned char *valp) +{ + unsigned char *saved; + unsigned int u128; + size_t result; + + switch (form) + { + case DW_FORM_addr: + result = cu->address_size; + break; + + case DW_FORM_strp: + case DW_FORM_ref_addr: + result = cu->offset_size; + break; + + case DW_FORM_block1: + result = *valp + 1; + break; + + case DW_FORM_block2: + result = read_2ubyte_unaligned (dbg, valp) + 2; + break; + + case DW_FORM_block4: + result = read_4ubyte_unaligned (dbg, valp) + 4; + break; + + case DW_FORM_block: + saved = valp; + get_uleb128 (u128, valp); + result = u128 + (valp - saved); + break; + + case DW_FORM_ref1: + case DW_FORM_data1: + case DW_FORM_flag: + result = 1; + break; + + case DW_FORM_data2: + case DW_FORM_ref2: + result = 2; + break; + + case DW_FORM_data4: + case DW_FORM_ref4: + result = 4; + break; + + case DW_FORM_data8: + case DW_FORM_ref8: + result = 8; + break; + + case DW_FORM_string: + result = strlen ((char *) valp) + 1; + break; + + case DW_FORM_sdata: + case DW_FORM_udata: + case DW_FORM_ref_udata: + saved = valp; + get_uleb128 (u128, valp); + result = valp - saved; + break; + + case DW_FORM_indirect: + saved = valp; + get_uleb128 (u128, valp); + // XXX Is this really correct? + result = __libdw_form_val_len (dbg, cu, u128, valp); + if (result != (size_t) -1) + result += valp - saved; + break; + + default: + __libdw_seterrno (DWARF_E_INVALID_DWARF); + result = (size_t) -1l; + break; + } + + return result; +} diff --git a/libdw/memory-access.h b/libdw/memory-access.h new file mode 100644 index 00000000..babe976f --- /dev/null +++ b/libdw/memory-access.h @@ -0,0 +1,238 @@ +/* Unaligned memory access functionality. + Copyright (C) 2000, 2001, 2002, 2003, 2004 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. */ + +#ifndef _MEMORY_ACCESS_H +#define _MEMORY_ACCESS_H 1 + +#include <byteswap.h> +#include <limits.h> +#include <stdint.h> + + +/* Number decoding macros. See 7.6 Variable Length Data. */ +#define get_uleb128(var, addr) \ + do { \ + unsigned char __b = *((const unsigned char *) addr); \ + addr = (__typeof (addr)) (((uintptr_t) (addr)) + 1); \ + var = __b & 0x7f; \ + if (__b & 0x80) \ + { \ + __b = *((const unsigned char *) addr); \ + addr = (__typeof (addr)) (((uintptr_t) (addr)) + 1); \ + var |= (__b & 0x7f) << 7; \ + if (__b & 0x80) \ + { \ + __b = *((const unsigned char *) addr); \ + addr = (__typeof (addr)) (((uintptr_t) (addr)) + 1); \ + var |= (__b & 0x7f) << 14; \ + if (__b & 0x80) \ + { \ + __b = *((const unsigned char *) addr); \ + addr = (__typeof (addr)) (((uintptr_t) (addr)) + 1); \ + 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 { \ + unsigned char __b = *((const unsigned char *) addr); \ + addr = (__typeof (addr)) (((uintptr_t) (addr)) + 1); \ + int32_t __res = __b & 0x7f; \ + if ((__b & 0x80) == 0) \ + { \ + if (__b & 0x40) \ + __res |= 0xffffff80; \ + } \ + else \ + { \ + __b = *((const unsigned char *) addr); \ + addr = (__typeof (addr)) (((uintptr_t) (addr)) + 1); \ + __res |= (__b & 0x7f) << 7; \ + if ((__b & 0x80) == 0) \ + { \ + if (__b & 0x40) \ + __res |= 0xffffc000; \ + } \ + else \ + { \ + __b = *((const unsigned char *) addr); \ + addr = (__typeof (addr)) (((uintptr_t) (addr)) + 1); \ + __res |= (__b & 0x7f) << 14; \ + if ((__b & 0x80) == 0) \ + { \ + if (__b & 0x40) \ + __res |= 0xffe00000; \ + } \ + else \ + { \ + __b = *((const unsigned char *) addr); \ + addr = (__typeof (addr)) (((uintptr_t) (addr)) + 1); \ + __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) \ + (unlikely ((Dbg)->other_byte_order) \ + ? bswap_16 (*((const uint16_t *) (Addr))) \ + : *((const uint16_t *) (Addr))) +# define read_2sbyte_unaligned(Dbg, Addr) \ + (unlikely ((Dbg)->other_byte_order) \ + ? (int16_t) bswap_16 (*((const int16_t *) (Addr))) \ + : *((const int16_t *) (Addr))) + +# define read_4ubyte_unaligned_noncvt(Addr) \ + *((const uint32_t *) (Addr)) +# define read_4ubyte_unaligned(Dbg, Addr) \ + (unlikely ((Dbg)->other_byte_order) \ + ? bswap_32 (*((const uint32_t *) (Addr))) \ + : *((const uint32_t *) (Addr))) +# define read_4sbyte_unaligned(Dbg, Addr) \ + (unlikely ((Dbg)->other_byte_order) \ + ? (int32_t) bswap_32 (*((const int32_t *) (Addr))) \ + : *((const int32_t *) (Addr))) + +# define read_8ubyte_unaligned(Dbg, Addr) \ + (unlikely ((Dbg)->other_byte_order) \ + ? bswap_64 (*((const uint64_t *) (Addr))) \ + : *((const uint64_t *) (Addr))) +# define read_8sbyte_unaligned(Dbg, Addr) \ + (unlikely ((Dbg)->other_byte_order) \ + ? (int64_t) bswap_64 (*((const int64_t *) (Addr))) \ + : *((const int64_t *) (Addr))) + +#else + +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 *dbg, const void *p) +{ + const 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 *dbg, const void *p) +{ + const 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 (const void *p) +{ + const union unaligned *up = p; + return up->u4; +} +static inline uint32_t +read_4ubyte_unaligned (Dwarf *dbg, const void *p) +{ + const 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 *dbg, const void *p) +{ + const 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 *dbg, const void *p) +{ + const 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 *dbg, const void *p) +{ + const union unaligned *up = p; + if (dbg->other_byte_order) + return (int64_t) bswap_64 (up->u8); + return up->s8; +} + +#endif /* allow unaligned */ + + +#define read_2ubyte_unaligned_inc(Dbg, Addr) \ + ({ uint16_t t_ = read_2ubyte_unaligned (Dbg, Addr); \ + Addr = (__typeof (Addr)) (((uintptr_t) (Addr)) + 2); \ + t_; }) +#define read_2sbyte_unaligned_inc(Dbg, Addr) \ + ({ int16_t t_ = read_2sbyte_unaligned (Dbg, Addr); \ + Addr = (__typeof (Addr)) (((uintptr_t) (Addr)) + 2); \ + t_; }) + +#define read_4ubyte_unaligned_inc(Dbg, Addr) \ + ({ uint32_t t_ = read_4ubyte_unaligned (Dbg, Addr); \ + Addr = (__typeof (Addr)) (((uintptr_t) (Addr)) + 4); \ + t_; }) +#define read_4sbyte_unaligned_inc(Dbg, Addr) \ + ({ int32_t t_ = read_4sbyte_unaligned (Dbg, Addr); \ + Addr = (__typeof (Addr)) (((uintptr_t) (Addr)) + 4); \ + t_; }) + +#define read_8ubyte_unaligned_inc(Dbg, Addr) \ + ({ uint64_t t_ = read_8ubyte_unaligned (Dbg, Addr); \ + Addr = (__typeof (Addr)) (((uintptr_t) (Addr)) + 8); \ + t_; }) +#define read_8sbyte_unaligned_inc(Dbg, Addr) \ + ({ int64_t t_ = read_8sbyte_unaligned (Dbg, Addr); \ + Addr = (__typeof (Addr)) (((uintptr_t) (Addr)) + 8); \ + t_; }) + +#endif /* memory-access.h */ |