summaryrefslogtreecommitdiff
path: root/dwarfdump
diff options
context:
space:
mode:
Diffstat (limited to 'dwarfdump')
-rw-r--r--dwarfdump/CODINGSTYLE44
-rw-r--r--dwarfdump/COPYING31
-rw-r--r--dwarfdump/ChangeLog2
-rw-r--r--dwarfdump/ChangeLog2006332
-rw-r--r--dwarfdump/ChangeLog2007108
-rw-r--r--dwarfdump/ChangeLog200896
-rw-r--r--dwarfdump/ChangeLog2009280
-rw-r--r--dwarfdump/ChangeLog2010105
-rw-r--r--dwarfdump/DWARFDUMPCOPYRIGHT85
-rw-r--r--dwarfdump/GPL.txt339
-rw-r--r--dwarfdump/Makefile.in191
-rw-r--r--dwarfdump/NEWS206
-rw-r--r--dwarfdump/README82
-rw-r--r--dwarfdump/addrmap.c149
-rw-r--r--dwarfdump/addrmap.h33
-rw-r--r--dwarfdump/checkutil.c565
-rw-r--r--dwarfdump/checkutil.h98
-rw-r--r--dwarfdump/common.c88
-rw-r--r--dwarfdump/common.h42
-rw-r--r--dwarfdump/config.h.in100
-rwxr-xr-xdwarfdump/configure5109
-rw-r--r--dwarfdump/configure.in98
-rw-r--r--dwarfdump/dwarfdump.1523
-rw-r--r--dwarfdump/dwarfdump.c2357
-rw-r--r--dwarfdump/dwarfdump.conf810
-rw-r--r--dwarfdump/dwconf.c1424
-rw-r--r--dwarfdump/dwconf.h106
-rw-r--r--dwarfdump/esb.c242
-rw-r--r--dwarfdump/esb.h86
-rw-r--r--dwarfdump/globals.h459
-rwxr-xr-xdwarfdump/install.sh119
-rw-r--r--dwarfdump/makename.c68
-rw-r--r--dwarfdump/makename.h53
-rw-r--r--dwarfdump/naming.c261
-rw-r--r--dwarfdump/naming.h73
-rw-r--r--dwarfdump/print_abbrevs.c304
-rw-r--r--dwarfdump/print_aranges.c267
-rw-r--r--dwarfdump/print_die.c3540
-rw-r--r--dwarfdump/print_frames.c1823
-rw-r--r--dwarfdump/print_frames.h47
-rw-r--r--dwarfdump/print_lines.c433
-rw-r--r--dwarfdump/print_locs.c128
-rw-r--r--dwarfdump/print_macros.c216
-rw-r--r--dwarfdump/print_pubnames.c300
-rw-r--r--dwarfdump/print_ranges.c106
-rw-r--r--dwarfdump/print_reloc.c1150
-rw-r--r--dwarfdump/print_reloc.h307
-rw-r--r--dwarfdump/print_sections.c206
-rw-r--r--dwarfdump/print_sections.h54
-rw-r--r--dwarfdump/print_static_funcs.c137
-rw-r--r--dwarfdump/print_static_vars.c104
-rw-r--r--dwarfdump/print_strings.c80
-rw-r--r--dwarfdump/print_types.c141
-rw-r--r--dwarfdump/print_weaknames.c104
-rwxr-xr-xdwarfdump/strstrnocase.c118
-rw-r--r--dwarfdump/tag_attr.c286
-rw-r--r--dwarfdump/tag_attr.list880
-rw-r--r--dwarfdump/tag_attr_ext.list78
-rw-r--r--dwarfdump/tag_common.c145
-rw-r--r--dwarfdump/tag_common.h123
-rw-r--r--dwarfdump/tag_tree.c290
-rw-r--r--dwarfdump/tag_tree.list486
-rw-r--r--dwarfdump/tag_tree_ext.list63
-rw-r--r--dwarfdump/testesb.c78
-rw-r--r--dwarfdump/uri.c493
-rw-r--r--dwarfdump/uri.h37
-rw-r--r--dwarfdump/uritablebuild.c146
67 files changed, 27434 insertions, 0 deletions
diff --git a/dwarfdump/CODINGSTYLE b/dwarfdump/CODINGSTYLE
new file mode 100644
index 0000000..64bbb48
--- /dev/null
+++ b/dwarfdump/CODINGSTYLE
@@ -0,0 +1,44 @@
+This document is a brief description of the main
+coding style conventions in dwarfdump. Many of them
+will be obvious from the code, but over time some
+accidental diffences crept in.
+
+
+Code should be indented in multiples of 4 spaces, and
+tabs should not be used to indent the source code.
+Use the dicheck program to check indenting.
+
+The struct naming convention is 'struct my_struct_s' for the
+struct defined here (meaning the name should end with _s).
+It is better to not do struct typedefs of local structs.
+Coders should type 'struct mystruct_s'. Readability
+is much more important than brevity.
+
+Any data or function not referenced outside the
+defining source file should be declared 'static'.
+
+Any duplicated code is a candidate for refactoring
+into a subprogram.
+
+Function names should be all lower case with underbars
+with the goal that statements and comments 'read well'.
+
+Variables should be lower-case with
+underbars for readability. It's ok for a small loop
+with counters to use single letter names like i or k or m.
+
+Structure members should have a struct-specific
+2-character prefix to the name (followed by
+an underbar). That makes it much
+easier to grep for uses of members.
+
+Try to keep lines under 80 characters in length.
+
+Ensure every if() has {} to enclose the actions.
+
+Use libdwarf.h types for all the data objects you define,
+though sometimes an 'unsigned' or 'int' or 'size_t' is
+ok in restricted circumstances. Dwarf_Unsigned and
+Dwarf_Signed are the preferred integer types for general use.
+
+------------
diff --git a/dwarfdump/COPYING b/dwarfdump/COPYING
new file mode 100644
index 0000000..355bd60
--- /dev/null
+++ b/dwarfdump/COPYING
@@ -0,0 +1,31 @@
+
+David Anderson: December 2006
+The code in the dwarfdump directory is (if you look
+in each file) covered by the GPL (not the LGPL). The
+DWARFDUMPCOPYRIGHT file, though, said (before December 24,
+2006) the copyright is LGPL. There is no doubt in my (David
+Anderson) mind that the intent was always that dwarfdump be
+GPL and the copyright markings in each file are correct.
+
+There are three files marked with the LGPL: tag_tree.list
+tag_attr.list acconfig.h. These markings are left as is and
+these are are therefore LGPL files.
+
+The DWARFDUMPCOPYRIGHT file now (Dec 24 2006) has both
+copyrights and an explanation of where each applies.
+
+
+
+-------------------------------------------
+The text present for years, thru Dec 23, 2006:
+The files:
+ dwarfdump.c
+ and all the .h and .c files in this implementation of
+ dwarfdump are copyrighted according to the file
+ DWARFDUMPCOPYRIGHT.
+
+
+
+$Source: /plroot/cmplrs.src/v7.4.5m/.RCS/PL/dwarfdump/RCS/COPYING,v $
+$Revision: 1.1 $
+$Date: 2001/01/16 17:47:55 $
diff --git a/dwarfdump/ChangeLog b/dwarfdump/ChangeLog
new file mode 100644
index 0000000..03bb4a1
--- /dev/null
+++ b/dwarfdump/ChangeLog
@@ -0,0 +1,2 @@
+2012-04-10 DavidAnderson <davea42@earthlink.net>
+ * dwarfdump.c, common.c: Updated version string.
diff --git a/dwarfdump/ChangeLog2006 b/dwarfdump/ChangeLog2006
new file mode 100644
index 0000000..dbedb67
--- /dev/null
+++ b/dwarfdump/ChangeLog2006
@@ -0,0 +1,332 @@
+2006-12-24 David Anderson <davea@sgi.com>
+ * DWARFDUMPCOPYRIGHT: Added GPL copyright text with
+ explanation of the intended content.
+ * COPYING: added text explaining confusion of GPL vs LGPL.
+ Thanks to Chris Quenelle for pointing out the disconnect
+ between DWARFDUMPCOPYRIGHT and the source files in dwarfdump.
+2006-12-21 David Anderson <davea@sgi.com>
+ * tag_tree.list: add tags to make allowed list more complete.
+ Omission noticed by Marcel Mettes.
+2006-06-14 David Anderson <davea@sgi.com>
+ * print_frames.c: Clean up printing of augmentation data by
+ eliminating dangling 0x (for eh_frame).
+2006-04-28 David Anderson <davea@sgi.com>
+ * dwarfdump.conf: Now has x86_64 register names.
+ x86_64 with help from Tom Hughes (verified
+ from independent sources).
+ Added m68k register names and refined x86 list
+ by looking at various information-sources.
+2006-04-18 David Anderson <davea@sgi.com>
+ * *.c: Ran indent so all now follow a standard look.
+ * dwconf.c: Added fclose(conf_stream).
+2006-04-18 David Anderson <davea@sgi.com>
+ * dwarfdump.c: Forgot to call key new functions for
+ handling variable-size frame data and different
+ frame rule initialization value.
+ * dwconf.c: Add a default print for CFA in case of
+ an omission in dwarfdump.conf.
+ * dwarfdump.conf: Move setup and rename the ABIs slightly.
+2006-04-17 David Anderson <davea@sgi.com>
+ * dwarfdump.conf: Correct typos. Remove some register names.
+ * dwarfdump.c: Fix compiler warnings, fix -x option usage message.
+ * dwconf.h: Fix compiler warnings by changing types.
+ * dwconf.c: Change error checking so we check all errors, do
+ not stop at first error. Ran indent. Added code to check
+ for extra junk after operand(s).
+ * print_frames.c: Fix compiler warnings.
+ * Makefile.in: get <prefix> used in install rule and creating
+ places to search for dwarfdump.conf
+2006-04-16 David Anderson <davea@sgi.com>
+ * dwarfdump.conf: New dwarfdump configuration file. Makes using frame
+ information easy to read and correct for any ABI/ISA
+ without rebuilding dwarfdump.
+ * Makefile.in: Added new files dwconf.h dwconf.c
+ * dwconf.h dwconf.c: New files implement reading dwarfdump.conf
+ and help print_frames.c print frame information correctly
+ for ABIs specified at runtime.
+ * dwarfdump.1: document -x commands.
+ * globals.h: Minor changes to support dwarfdump.conf
+ * print_frames.c: Major changes to support a run-time description of
+ the frames info and dwarfdump.conf.
+ * print_frames.h: Changes to support a run-time description of
+ the frames info and dwarfdump.conf.
+ * print_sections.c: Minor tweaks to support a run-time
+ description of the frames info and dwarfdump.conf.
+
+2006-03-31 David Anderson <davea@sgi.com>
+ * Makefile.in globals.h print_sections.c: Refer to new
+ print_frames.h print_frames.c.
+ * print_frames.h print_frames.c: Extract cie, fde printing
+ to separate file, separating loop logic from the printing
+ of an entry from the loop.
+2006-03-31 David Anderson <davea@sgi.com>
+ * dwarfdump.c global.h print_sections.c: Preparing for
+ dwarf3 frame interface.
+ * print_die.c: Corrects handling of DW_AT_encoding (etc) value.
+2006-03-29 David Anderson <davea@sgi.com>
+ * print_sections.c: define DWARFDUMP_TURN_OFF_MIPS_REG_NAMES
+ at compile time
+ to turn off the MIPS register names printing. Instead
+ (aside from cfa) use a name like r4 (where the DWARF
+ register number follows the letter 'r').
+ Indent. Initialize some local variables at declarations.
+2006-03-13 David Anderson <davea@sgi.com>
+ * print_sections.c: Now gets gnu eh_augmentation data by calling
+ dwarf_get_cie_augmentation_data() or dwarf_get_fde_augmentation_data()
+ and prints it (use -v to see cie data).
+ Now prints DWARF3 frame information.
+2006-03-08 David Anderson <davea@sgi.com>
+ * print_sections.c: Add 'break;' at line 710.
+ Thanks to Richard Stuckey for noticing.
+2005-12-01 David Anderson <davea@sgi.com>
+ * dwarf_names.awk: use snprintf instead of sprintf for safety.
+2005-12-01 David Anderson <davea@sgi.com>
+ * Makefile.in: Build attr/tag trees with
+ individual commands to catch build errors.
+ * tag_attr.c,tag_tree.c: Verify that
+ tables fit in the generated C code and check for
+ format errors in the *.list files.
+ * tag_attr.list, tag_tree.list: Added some valid entries.
+ * globals.h: add DWARF_ERROR3 macro for better diagnostics.
+ * print_die.c: Show both sides of questionable tag relation
+ in CHECK -k diagnostic output.
+
+2005-11-25 David Anderson <davea@sgi.com>
+ * print_die.c: DW_AT_stride_size changed to DW_AT_bit_stride,
+ added DW_AT_byte_stride.
+ * tag_attr.c,tag_tree.c: fixed array size now a #define for
+ readability.
+ * tag_attr.list: Added DWARF3 attributes, also new TAGs.
+ * tag_tree.list: Added DWARF3 TAGs.
+
+2005-11-08 David Anderson <davea@sgi.com>
+ * makename.c: remove non-standard malloc.h include,
+ stdlib.h suffices and is already included.
+
+2005-10-24 David Anderson <davea@sgi.com>
+ * tag_attr.c tag_tree.c: added DWARF3 TAGs to string array.
+
+2005-08-01 David Anderson <davea@sgi.com>
+ * Makefile.in: Add esb.o and test rule (test code for esb.c).
+ * dwarfdump.c: Remove old static buffer initialization.
+ * print_die.c: Use esb now, avoid crash due to long loclist
+ overrunning static buffer. Uses snprintf now, not sprintf.
+ snprintf is for safety.
+ * esb.h esb.c: Adding extensible string buffer (esb) code.
+ * testesb.c: Test code for esb.c.
+ * print_reloc.c: size field is now Elf64_Xword for
+ Elf64 as Elf64_Word is only 32 bits.
+
+2005-07-15 David Anderson <davea@sgi.com>
+ * dwarfdump.c: Add print of .debug_pubtypes, remove
+ erroneous dealloc after dwarf_formstring() call.
+ * globals.h: Add declarations for .debug_pubtypes print. Add
+ declaration for full dealloc.
+ * print_die.c: Remove erroneous dealloc after dwarf_formstring() call.
+ * print_exception_tables.c: Call dwarf_fde_cie_list_dealloc()
+ for complete dealloc.
+ * print_sections.c: Remove incorrect dealloc() call.
+ Add calls to new dealloc routines. Add support of .debug_pubtypes
+ print.
+2005-07-14 David Anderson <davea@sgi.com>
+ * print_sections.c (print_line_numbers_this_cu): Use new
+ dwarf_srclines_dealloc() for deallocation after
+ dwarf_srclines() called.
+
+2005-04-13 David Anderson <davea@sgi.com>
+ * print_sections.c: Factors out common print code into
+ a new routine. Avoid indexing past end of register names
+ array. Adds checks and prints so that certain errors
+ in pubnames-like sections are printed usefully (and dwarfdump
+ then stops if libdwarf gave an error).
+
+2005-03-21 David Anderson <davea@sgi.com>
+ * dwarfdump.c: Add -F flag to
+ request .eh_frame section print. Changed -f flag meaning
+ to print .debug_frame only. -a flag no longer
+ prints .debug_frame by default.
+ * print_sections.c: avoid printing an eh_frame we don't understand.
+ Add new information per CU when printing line info: specifically
+ the line section offset.
+ * globals.h: Added arguments to print_frames() for -F flag.
+
+2005-03-18 David Anderson <davea@sgi.com>
+ * print_sections.c: Correct macro section printing.
+
+2004-10-28 David Anderson <davea@sgi.com>
+ * DWARFDUMPCOPYRIGHT config.h defs.h dwarfdump.c globals.h
+ makename.c makename.h print_die.c print_exception_tables.c
+ print_reloc.c print_sections.c tag_attr.c tag_attr.list
+ tag_tree.c tag_tree.list: Copyright update, SGI
+ corporate address change.
+
+2004-10-26 David Anderson <davea@sgi.com>
+ * acconfig.h: removed. Was old style autoconf usage.
+ * configure.in: Updated AC_DEFINE usage, adding args 2 & 3.
+ * config.guess: Updated. timestamp='2004-06-11'.
+ * config.sub: Updated. timestamp='2004-03-12'.
+ * configure config.h.in: regenerated with autoconf 2.58.
+
+2004-05-14 David Anderson <davea@sgi.com>
+
+ * print_die.c (print_die_and_children): Change to iteration
+ on siblings (still recursing on children).
+
+
+2004-03-30 David Anderson <davea@sgi.com>
+ * dwarfdump.c (main): getopt() string should contain k:g
+ not kg: Thanks to Peter Seiderer for pointing this out.
+
+2003-12-31 David Anderson <davea@sgi.com>
+ * README: Added configure example.
+ * Makefile.in: Removed bogus LIBS line, updated copyright date.
+ * acconfig.h: Added LGPL copyright to match libdwarf
+ Silly, but it matches libdwarf version boilerplate.
+ * config.guess config.sub: new versions from automake-1.6.
+ * config.h.in configure: Regenerated.
+
+
+2003-10-06 David Anderson <davea@sgi.com>
+ * dwarfdump.c print_sections.c: applied indent(1).
+ * print_die.c: applied indent and added ; after
+ invocations of macros PUSH_DIE_STACK POP_DIE_STACK SPACE
+ as these were confusing indent a bit.
+ The indent control file .indent.pro contained:
+ -bad -bap -nbbo -br -ce -brs
+ -l72 -lc72 -hnl -nprs
+ -fca -i4 -lp -psl -npcs
+
+
+
+2003-10-02 David Anderson <davea@sgi.com>
+ * dwarfdump.c: Add -g to indicate use of older
+ location entry code in libdwarf. So dwarf_loclist
+ and dwarf_loclist_n are testable.
+ * globals.h: Added use_old_dwarf_loclist flag so one
+ can choose the old dwarf_loclist() interface.
+ For testing.
+ * print_die.c: Rearranged to avoid code duplication.
+ Now supports .debug_loc fully.
+ * print_sections.c: Prints .debug_loc now.
+
+2003-09-29 David Anderson <davea@sgi.com>
+
+ * print_die.c: with -v, print 'loclist' start and
+ end addr and also a hint that DW_FORM_indirect is used.
+ No change for normal output (for now).
+
+2003-05-19 David Anderson <davea@sgi.com>
+ * dwarfdump.c call dwarf_srcfiles() to get file names
+ per cu and pass down to die print routines.
+ Removed incorrect tests for when to print ".debug_info",
+ leaving simpler test.
+ * print_die.c globals.h: print file name (from line info)
+ with DW_AT_decl_file, adding data from dwarf_srcfiles
+ to argument list of a few routines to make that possible.
+ * print_sections.c: moved "line number info" string print so
+ it prints for -v as well as normal line ouput.
+
+2002-10-23 Amaury Le Leyzour amaury@sgi.com
+ * print_sections.c (print_weaknames): Changed
+ DW_DLA_TYPENAME to DW_DLA_WEAK at dwarf_dealloc().
+
+2002-10-22 Tom Hughes <thh@cyberscience.com>
+ * print_sections.c: macro printing now supported.
+ * dwarfdump.c: removed erroneous dwarf_dealloc()
+ of string returned by dwarf_errmsg().
+
+2002-11-22 David Anderson <davea@sgi.com>
+ * dwarf_names.awk at_list.awk: Allow an name to have two
+ spellings so the historical name preserved yet the dwarf3
+ version is supported. First name seen is used/reported
+ by dwarfdump.
+ * dwarf.h: DW_TAG_template_type_param(eter)
+ DW_TAG_template_value_param(eter) DW_AT_namelist_itm(s)
+ are the ones with alternate spellings now.
+ Added Universal Parallel C TAGs/Attributes in
+ user namespace.
+ * tag_attr.c tag_attr.list tag_tree.c tag_tree.list:
+ Use the DW_TAG_template_* dwarf3 spellings.
+
+
+2002-05-08 David Anderson <davea@sgi.com>
+ * tag_attr.list dwarf.h: DW_AT_namelist_items is
+ wrong, changed to DW_AT_namelist_item
+
+2002-04-29 Stephen Clarke <stephen.clarke@superh.com>
+ * dwarfdump.c (main): #ifdef for __CYGWIN__ on open().
+
+2001-06-14 David Anderson <davea@sgi.com>
+
+ * print_sections.c: Calling the new libdwarf function
+ dwarf_get_arange_cu_header_offset() so we can print
+ the cu header offset for aranges.
+
+
+2000-07-14 Fred Fish <fnf@ninemoons.com>
+
+ * configure.in (LOCATION_OF_LIBELFHEADER): Fix typo for configure
+ variable to be tested and enclose libelf/libelf.h in <>.
+ * configure: Regenerated.
+
+2000-07-10 Fred Fish <fnf@ninemoons.com>
+
+ * Makefile.in (install): Install dwarfdump.1 from $(srcdir).
+
+2000 June 12 davea@sgi.com
+ print_sections.c the DW_CFA_offset_extended print
+ did not multiply by data-alignment factor in the
+ -v -v detailed output.
+ And the offsets used %2d when the values were
+ unsigned int, so now %2u.
+
+ And not all cfa prints of values had
+ necessarily a type to match
+ %llu or %lld where required. Depended on the size of Dwarf_Signed
+ and Dwarf_Unsigned.
+ So now explicitly use cast to the
+ right type to match the % format.
+2000 April 13 davea@sgi.com
+ print_sections.c - 1.56
+ - A single byte of zero is a perfectly legitmate null
+ abbreviation entry (in .debug_abbrev)
+ now we print those directly and avoid a warning
+ from dwarfdump
+
+ print_die.c - 1.42
+ - Explain what combo checker is doing and make it
+ more maintainable (and fix bug which would
+ not be hit, but was real enough (in combo checker),
+ using too large a number as highest tag number).
+
+ tag_tree.list - 1.2
+ - Add valid parent/child relationships so checker
+ does not report valid entries as bogus.
+
+
+
+
+2000 Feb 24
+ Jason Merrill <jason@cygnus.com> noticed that gcc did
+ not like gcc -E foo.list, so incorporated his fix so
+ now the Makefile.in makes a link and does gcc -E _tmp.c
+
+2000 Jan 26
+ elena.demikhovsky@intel.com noticed that 3 statements in
+ print_sections.c got warnings from the compiler
+ she was using. Simple casts (provided by her) fixed these.
+
+1999 July 21
+ davea@sgi.com
+ print_sections changed to allow printing
+ of dwarf-ish egcs c++ .eh_frame data
+
+
+1999 June 14
+ Fred Fish fnf@ninemoons.com contributed
+ autoconf'ing of the libdwarf and dwarfdump source.
+
+
+
+1999 June 10
+ ChangeLog started. davea@sgi.com David Anderson
diff --git a/dwarfdump/ChangeLog2007 b/dwarfdump/ChangeLog2007
new file mode 100644
index 0000000..d1230b5
--- /dev/null
+++ b/dwarfdump/ChangeLog2007
@@ -0,0 +1,108 @@
+2007-12-09 DavidAnderson <davea42@earthlink.net>
+ * print_sections.c print_frames.c: Forgot to commit yesterday.
+ yesterday's commit includes renaming _dwarf_fde_section_offset
+ _dwarf_cie_section_offset, _dwarf_print_lines, _dwarf_ld_sort_lines
+ to dwarf_* form while retaining support for the now obsolete
+ _dwarf_* form.
+2007-12-08 DavidAnderson <davea42@earthlink.net>
+ * config.h.in, configure.in: Latest linux libelf.h requires
+ _GNU_SOURCE to get off64_t defined so dwarfdump compiles.
+ Only define _GNU_SOURCE if libelf.h defines off64_t.
+ Regenerated configure.
+ * config.guess, config.sub: Updated to 2.61
+ * acconfig.h: Deleted, removing autoconf complaint.
+2007-10-15 DavidAnderson <davea42@earthlink.net>
+ * print_die.c (clean_up_die_esb): New function
+ cleans up malloc space.
+ * print_reloc.c (clean_up_syms_malloc_data): New function
+ cleans up malloc space.
+ * dwarfdump.c (main): Call new cleanup functions at end.
+ * globals.h: Declare new cleanup functions.
+
+2007-09-04 DavidAnderson <davea42@earthlink.net>
+ * print_die.c (print_attribute): For DWARF4: DW_AT_high_pc:
+ add qualifier to value when the value is an offset from
+ DW_AT_low_pc (thus not itself a address).
+ Update the address of the FSF.
+ * print_frames.h DWARFDUMPCOPYRIGHT print_sections.c
+ print_reloc.c dwarfdump.c tag_tree.c tag_attr.c
+ esb.c esb.h makename.c acconfig.h dwconf.c makename.h
+ dwconf.h globals.h print_frames.c:
+ Update the address of the FSF.
+
+2007-07-03 DavidAnderson <davea42@earthlink.net>
+ * print_sections.c (dump_block): Removed superfluous return byte from
+ printed characters. Removed unused variables.
+ * print_die.c: A little refactoring for clarity.
+ * globals.h: dwarfdump_print_one_locdesc() is now a
+ global-to-dwarfdump function.
+ * print_frames.c: Now (with -v) prints dwarf expression bytes
+ in frame expressions readably.
+2007-07-02 DavidAnderson <davea42@earthlink.net>
+ * dwarfdump.c: Add new -R option for 'generic' register sets.
+ * dwarfdump.1: document -R, add new -x documentation.
+ * dwconf.c: Set up -R configuration. Slight revision of
+ register printing code.
+ * dwconf.h: Interface to register name printing simplified.
+ * print_frames.c: Use the simpler register name interface.
+ * dwarfdump.conf: Add new 'generic' abi for up to 1000 registers.
+
+2007-07-01 DavidAnderson <davea42@earthlink.net>
+ * print_frames.c: For DW_CFA_def_cfa_sf & DW_CFA_def_cfa_offset_sf
+ print a computed data alignment factor.
+2007-06-29 DavidAnderson <davea42@earthlink.net>
+ * dwarfdump.1: Corrected spelling error.
+2007-05-25 DavidAnderson <davea42@earthlink.net>
+ * dwconf.h dwconf.c: Changed field name to
+ cf_named_regs_table_size as old name was less than clear.
+ * dwarfdump.c: Call frame table setup with
+ cf_table_entry_count not cf_named_regs_table_size. The newly
+ renamed field makes it clearer the call was wrong.
+2007-05-04 DavidAnderson <davea42@earthlink.net>
+ * print_die.c: printing of global offset of DIEs
+ with -G is now more in the style of previous output.
+2007-04-18 Chris Quenelle <chris.quenelle@sun.com>
+ * Makefile.in:
+ - use $(srcdir) for files in source directory
+ - support running rules in parallel by
+ - use different tmp file names in different rules.
+ - use more accurate target for dwarf_names.{c,h}
+ * dwarf_names.awk: Enhance script to be able to generate either
+ #define-style headers or enum-style headers
+ * dwarfdump.c: dump most everything by default if no arguments
+ are given to dwarfdump. This seems to be a more useful default
+ than showing nothing at all. Also add a -G option to show
+ the (G)lobal section offset for each die within an a.out. If you
+ think you're seeing data corruption inside a .debug_info
+ section, this is a useful option to have.
+ * print_die.c: Support compressed integer blocks. This is an
+ array (DW_FORM_block) of LEB numbers used as part of a Sun
+ extension, DW_AT_SUN_func_offsets. Also add support for
+ a new dwarf enum DW_ATCF_xxxx. This is used in DW_AT_SUN_cf_kind.
+ Also, fix DW_AT_upper_bound so it can be a constant or a location
+ list. DW_AT_count and DW_AT_data_member_location should also be
+ fixed eventually.
+ * print_sections.c: Changes to support zero-padding in the middle of
+ section data. Change offset labels to be a little more clear.
+ Not sure about the get_str failure.
+ * tag_tree.list: DW_TAG_compile_unit can contain a DW_TAG_namespace
+2007-04-10 David Anderson <davea42@earthlink.net>
+ * print_reloc.c dwarfdump.c print_frames.c: Unified
+ copyright to the SGI form. No copyright change.
+
+2007-04-06 David Anderson <davea42@earthlink.net>
+ * print_die.c (print_die_and_children): Increase static
+ depth of die stack. Notice if it overflows and
+ print error.
+2007-02-23 David Anderson <davea42@earthlink.net>
+ * print_reloc.c: 2 lines added (long) cast in printf
+ and made %3ld instead of %3d to fix compiler warning.
+ * print_frames.c: newline was missing from the output.
+ Thanks to Chris Quenelle for noticing.
+2007-02-20 David Anderson <davea42@earthlink.net>
+ * print_frame.c (print_frame_inst_bytes): Fixed
+ an off by one error (several places)
+ when printing dwarf expressions and added commentary about it.
+ Thanks to Julian Seward for pointing out it was off by one.
+ * dwarfdump.c (print_error): added fflush of stdout, stderr
+ where we are going to exit right away anyway.
diff --git a/dwarfdump/ChangeLog2008 b/dwarfdump/ChangeLog2008
new file mode 100644
index 0000000..24a1ffa
--- /dev/null
+++ b/dwarfdump/ChangeLog2008
@@ -0,0 +1,96 @@
+2008-12-30 David Anderson <davea42@earthlink.net>
+ * tag_attr.list: Mark DW_AT_artificial as sensible on
+ DW_TAG_variable.
+ * dwarfdump.1: Document -N option to print .debug_ranges.
+ * Makefile.in: add new source header files
+ * dwarfdump.c: Implement -N to print .debug_ranges.
+ * print_sections.c: Allow more flexible printing
+ of function names for .debug_frame section.
+ With -N, print .debug_ranges.
+ * print_die.c: Print .debug_ranges details.
+ * print_frames.c: Delete useless comment.
+ * globals.h: Allow re-use of debug_ranges formatting code.
+ * Makefile.in: Make the header dependency list more complete.
+ * makename.h: Comment tweaked.
+2008-12-08 David Anderson <davea42@earthlink.net>
+ * print_die.c: the -M option now also prints the form
+ number (after the form name). And -v prints the DIE
+ abbreviation code, the index into the relevant abbreviation
+ table.
+ * globals.h: Removed unused global variable.
+ * dwarfdump.c: Removed unused global variable.
+ * dwarfdump.1: document -M and the new -v features.
+2008-12-07 David Anderson <davea42@earthlink.net>
+ * print_reloc.c (print_relocinfo): Removed unused local variable.
+2008-11-19 David Anderson <davea42@earthlink.net>
+ * globals.h: Added new boolean to support -M.
+ * dwarfdump.1: Mentioning the -M option.
+ * dwarfdump.c: Implementing -M, which has each attribute line
+ show the name of the form.
+ * print_die.c: Implementing -M option.
+2008-10-12 David Anderson <davea42@earthlink.net>
+ * dwarfdump.conf: Adding power pc register names and table
+ size for use with -x abi=ppc .
+2008-08-13 David Anderson <davea42@earthlink.net>
+ * dwarfdump.1: When no options (just object files) present
+ all sections print, now we say that. Renamed fields
+ in synopsis for readability.
+2008-06-23 David Anderson <davea42@earthlink.net>
+ * print_reloc.c (print_reloc_information_64): Was testing
+ sym_data_entry_count one place where sym_data_64_entry_count
+ should have been tested. Thanks to Carlos Alberto Enciso
+ for noticing.
+2008-06-17 David Anderson <davea42@earthlink.net>
+ * print_die.c: Add to dwarf_formstring failure message.
+ * README: Correct email: the old sgi.com address is no
+ longer correct.
+2008-06-13 David Anderson <davea42@earthlink.net>
+ * dwconf.c: Fix an off-by-one condition where
+ we could index off the end of the cf_regs array in printing
+ a register name.
+2008-04-12 David Anderson <davea42@earthlink.net>
+ * print_reloc.c: Verify stringtab exists and is
+ large enough before indexing into it to get a string
+ in printing relocations.
+ (Providing default name "<no name>" so it's evident from
+ the output that we used a default name string).
+2008-04-09 David Anderson <davea42@earthlink.net>
+ * print_sections.c (get_fde_proc_name): Initialize some
+ local variables at declaration. The function is very slow
+ and needs a replacement.
+ * print_die.c: Fixes a typo in a comment.
+ * dwarfdump.c: Added -n option to suppress function name search
+ when printing FDEs. Current dwarfdump is n-squared at least
+ getting those names, this is a bandage-type-workaround when
+ there are so many FDEs the slowness is painful.
+ * globals.h: Support for -n option.
+ * print_frames.c: Support for -n option.
+2008-04-08 David Anderson <davea42@earthlink.net>
+ * dwarfdump.c: Added -H option for testing
+ (it limits the run length).
+ And the support for -H in printing DIEs.
+ * globals.h: Added extern for -H option declaration.
+ * print_sections.c: Added -H option support to limit frames printing.
+
+2008-04-04 David Anderson <davea42@earthlink.net>
+ * print_die.c (tag_tree_combination, tag_attr_combination):
+ Ensure we do not index off the end of the -k checking arrays.
+ * print_sections.c: Increase the size of a local variable,.
+2008-03-03 David Anderson <davea42@earthlink.net>
+ * dwarfdump.1: Add description of -ka option.
+ * print_frames.h print_sections.c testesb.c print_die.c print_reloc.c
+ dwarfdump.c tag_tree.c tag_attr.c esb.c esb.h makename.c dwconf.c
+ makename.h dwconf.h globals.h print_frames.c: Change tabs
+ to spaces with expand(1).
+2008-03-03 David Anderson <davea42@earthlink.net>
+ * print_die.c: Now check that DW_AT_decl_file
+ and DW_AT_call_file indexes are valid and count instances of the
+ attribute and errors found in it.
+ * dwarfdump.c: With -ka and -ky now check that DW_AT_decl_file
+ and DW_AT_call_file indexes are valid and warn if bad.
+ Thanks to Carlos Alberto Enciso for the suggestion.
+ * globals.h: Declare new fields for the DW_AT_decl_file
+ DW_AT_call_file checks.
+2008-02-26 David Anderson <davea42@earthlink.net>
+ * print_die.c (get_attr_value): Print DW_AT_call_file,
+ DW_AT_call_line, DW_AT_call_column nicely.
diff --git a/dwarfdump/ChangeLog2009 b/dwarfdump/ChangeLog2009
new file mode 100644
index 0000000..9d9a2d5
--- /dev/null
+++ b/dwarfdump/ChangeLog2009
@@ -0,0 +1,280 @@
+2009-12-30 DavidAnderson <davea42@earthlink.net>
+ * configure: Regenerated with autoconf 2.64.
+ * config.guess, config.sub: Delete these, best not
+ to have them.
+2009-11-24 DavidAnderson <davea42@earthlink.net>
+ * tag_common.h: Updated 'standard tag table row' and
+ tag table column maximums now the DWARF4 entries are
+ in the .list files. Removed dos 'CR' characters at line ends.
+ * tag_tree.list, tag_attr.list: Added various
+ DWARF4 entries and added DW_TAG_enumeration_type
+ under DW_TAG_union_type.
+2009-11-17 DavidAnderson <davea42@earthlink.net>
+ * dwarfdump.1: Document the -u option more fully.
+ * print_die.c: Check for both info_flag and
+ cu_name_flag to decide when to print DIEs.
+2009-10-12 DavidAnderson <davea42@earthlink.net>
+ * dwarfdump.c: Updated dwarfdump version string to today.
+2009-09-30 DavidAnderson <davea42@earthlink.net>
+ * dwarfdump.c: Added globals for aranges checking and
+ to print the resulting error count.
+ * print_aranges.c: Added checking that all 3 ways
+ of computing a cu_die_offset from an arange get
+ the same offset (checked with -r -ka).
+ * print_frames.c: DW_CFA_cfa_offset_extended_sf
+ corrected to DW_CFA_offset_extended_sf.
+2009-09-01 DavidAnderson <davea42@earthlink.net>
+ * tag_tree.list: We add
+ DW_TAG_class_type as a valid child of a DW_TAG_union_type.
+2009-08-05 DavidAnderson <davea42@earthlink.net>
+ * gennames.c: Change include from getopt.h to unistd.h
+ so the code is more universally compilable.
+2009-07-24: David Anderson <davea42@earthlink.net>
+ * tag_attr.c: Remove duplicate include of naming.h.
+2009-06-23: David Anderson <davea42@earthlink.net>
+ * strstrnocase.c: Corrected typo in TEST code and
+ added a new test.
+2009-06-22: David Anderson <davea42@earthlink.net>
+ * Makefile.in: switched to personally written
+ string comparison, strstrnocase.c.
+ * stristr.c: deleted.
+ * strstrnocase.c: New code, written by me so no
+ license issues.
+ * print_die.c: Call is_strstrnocase(), the new function.
+ * dwarfdump.1: More fully document -S.
+ * globals.h: Create extern for is_strstrnocase().
+2009-06-18: David Anderson <davea42@earthlink.net>
+ * configure: Regenerated.
+ * Makefile.in: Add stristr.o
+ * stristr.c: public domain source added to dwarfdump
+ * print_die.c: Add code and arguments to support -S.
+ * print_lines.c: print_one_die argument list changed, added
+ the require argument..
+ * dwarfdump.c: Added the -S option.
+
+ * configure.in: Add test to set HAVE_REGEX for the -S option.
+ * dwarfdump.1: Document the -S options.
+ * config.h.in: Set the default HAVE_REGEX
+ * globals.h: Add -S globals, change the print_one_die()
+ prototype to support -S.
+ * print_aranges.c: Alter the print_one_die calls added
+ to support -S.
+2009-06-06: David Anderson <davea42@earthlink.net>
+ * naming.c,naming.h: New files that implement the
+ ellipsis functionality of dwarfdump and defer to
+ libdwarf to get the names of the TAGs, attributes, FORMs, etc.
+ * gennames.c: This file has moved to libdwarf, no longer
+ present in dwarfdump.
+ * esb.h, esb.c: Change certain char* arguments to const char*
+ to avoid compiler warnings.
+ * print_static_vars.c,print_static_funcs.c,
+ print_sections.c,print_strings.c, print_locs.c,
+ print_lines.c, print_pubnames.c,print_ranges.c,
+ print_macros.c,print_types.c,tag_common.c,
+ print_weaknames.c, print_aranges.c: Include
+ changed from dwarf_names.h to naming.h
+ * tag_common.h: Removed the tag_name array, libdwarf
+ provides the TAG, ATTR, etc name strings now.
+ * dwarfdump.c: Updated DWARFDUMP_VERSION string.
+ * tag_tree.c,tag_attr.c: Include changed from dwarf_names.h to
+ naming.h. simplified long complicated lines, remove dbg argument
+ to get_TAG_name.
+ * print_die.c,print_abbrevs.c: Include changed from dwarf_names.h
+ to naming.h.
+ Calls to get_TAG_name (etc) no longer have a dbg argument.
+ * Makefile.in: We no longer build generated file names.c,
+ we build naming.c (hand coded, not generated).
+2009-05-07: David Anderson <davea42@earthlink.net>
+ * dwarfdump.cc: updated DWARF_VERSION string.
+ * Makefile.in: dwarf_names* are now generated by C,
+ so 'clean' now cleans them out.
+2009-05-04: David Anderson <davea42@earthlink.net>
+ * common.h, common.c: Extracted simple utility routines
+ into their own files.
+ * dwarf_names.awk, at_list.awk: deleted. gennames.c replaces these.
+ * tag_common.c, tag_common.h: Removed the simple utility
+ routines from these files to simplify dependencies.
+ * tag_attr.c, tag_tree.c: Include new common.h.
+ * print_frames.c: Adding address_size argument to call.
+ * print_frames.h: Adding new address_size argument to
+ get_string_from_locs() declaration.
+ * print_locs.c: Gets and uses CU-specific address_size.
+ * print_ranges.c: Adding commentary.
+ * print_die.c: adding DIE argument to ensure correct
+ address size used for the CU in question.
+ * Makefile.in: Now handles common.* and gennames.c changes.
+ * gennames.c: New code emitting string 'get name' source.
+ Replaces awk source.
+2009-04-04: David Anderson <davea42@earthlink.net>
+ * Makefile.in: clean up 'clean' and 'distclean'
+ so that distributed files are not cleaned out by 'clean'
+ and all generated files (even those shipped in
+ distribution) are cleaned out by distclean.
+ * dwarfdump.c: Now calls the new
+ libdwarf function dwarf_set_frame_cfa_value() and other
+ such functions to specify all the values libdwarf needs.
+ * dwarfdump.conf: Sets the cfa_reg: value to
+ a new higher value (1436) to avoid conflict with largest
+ known register count.
+ * dwconf.h: Corrected commentary on DW_FRAME_CFA_COL3.
+ * dwconf.c: Now uses DW_FRAME_CFA_COL3 as default for
+ interface 3, rather than a directly typed number.
+ Sets undefined-value and same-value pseudo-register numbers.
+2009-04-03: David Anderson <davea42@earthlink.net>
+ * dwarfdump.1: Amplified -R and -x abi= documentation.
+ * dwarfdump.conf: Added generic500 generic100 abis.
+2009-03-29: David Anderson <davea42@earthlink.net>
+ * print_die.c: Moved print_infos() to here.
+ * dwarfdump.c: Moved print_infos() out of here.
+ * globals.h: Declarations changed to allow moving
+ print_infos().
+ * dwarf_names.awk: Eliminate a pointless space before
+ a newline in the generated code.
+ * print_locs.c: Add -v section offset output to loclist printing
+ of the debug_loc section so the entries can be matched to
+ loclist printing initiated from .debug_info.
+2009-03-24: David Anderson <davea42@earthlink.net>
+ * README: Would be nice if all could use dwarfdump2,
+ not this C dwarfdump.
+ * dwconf.c: Initialize new frame regs configure data and
+ parse it in the .conf file. Fixed old formatting mistakes.
+ * dwconf.h: Add new fields to frame regs configure struct. Make -R
+ be 1200 regs so that -R covers all the currently popular ABIs.
+ * print_die.c, print_lines.c, print_frames.c: Change %# to
+ 0x% so that zero prints with leading 0x consistently.
+ * dwarfdump.c: -R is now 1200 registers. So config function
+ changed and usage message needed update.
+ * dwarfdump.1: Change -R to 1200 and document -C.
+ * dwarfdump.conf: Add same_val_reg: and undefined_val_reg:
+ initial values where needed or interesting.
+ * print_macros.c: Fix old formatting mistake.
+2009-03-23: David Anderson <davea42@earthlink.net>
+ * print_sections.h: New file for print_*.c
+ sources.
+ * dwarfdump.1: Added -C documentation.
+ * Makefile.in: updated 'mandir' so it works with
+ current configure (so now make install properly installs
+ the man page).
+ * print_sections.c: Moved get_fde_proc_name() and related
+ code to print_frames.c, where it is referenced.
+ * dwarfdump.c: No longer turn on info_flag with -f or -F.
+ Moved the Usage strings into a string table and loop through
+ to print them.
+ * globals.h: Removed get_fde_proc_name() declaration.
+ * print_frames.c: Added get_fde_proc_name() here
+ and removed the 'inlined:' from the abstract origin
+ name.
+2009-03-20: David Anderson <davea42@earthlink.net>
+ * print_static_vars.c, print_static_funcs.c, print_strings.c,
+ print_locs.c, print_pubnames.c, print_lines.c, print_ranges.c,
+ print_abbrevs.c, print_macros.c, print_types.c, print_weaknames.c,
+ print_aranges.c: Moved the print_* functions from print_sections.c
+ into individual sourcefiles.
+ * Makefile.in: Now lists the new sourcefiles.
+ * print_sections.c: Deleted code moved to individual sourcefiles.
+ Added code to try to find the name from a DW_AT_abstract_origin
+ DIE when a subprogram DIE itself has no DW_AT_name;
+ * dwarfdump.c: Remove unused local variables. Use DWARFDUMP_VERSION
+ #define to set version string.
+ * tag_tree.c: Fix && || problem with parentheses.
+ * tag_attr.c: Fix && || problem with parentheses.
+ * print_frames.c: Moved the 'print_frames' function itself from
+ print_sections.c to here.
+2009-03-17: David Anderson <davea42@earthlink.net>
+ * globals.h: Created predicate function
+ should_skip_this_cu() predicate function. Eliminating
+ code duplication.
+ * print_frames.c: Fix a hex value output to have a leading
+ 0x as all hex values should (when printed).
+ * print_sections.c: Call should_skip_this_cu(), which
+ replaces duplicate code.
+ Fix the arange print: now the hex value has a leading 0x
+ as all hex values should. get_proc_name() had local
+ variable funcnamefound initialized incorrectly, now is
+ set to 0 as it should be. get_nested_proc_name()
+ now initializes string buffers. get_fde_proc_name()
+ now initializes its string buffer. Surprisingly
+ things worked adequately before in spite of the errors.
+ * dwarfdump.c: Call should_skip_this_cu(). Implementation
+ of that new function is in this source file.
+2009-03-16: David Anderson <davea42@earthlink.net>
+ * print_frames.c:DW_CFA_restore output had a spurious newline.
+ Removed 2 pointless blank lines an initialized 2 local variables.
+ * print_sections.c: Removed a pointless redeclaration of a function
+ in libdwarf.h. check_info_offset_sanity() was missing a
+ return statement in one place, which could lead to spurious
+ extra (and silly) error text.
+2009-03-09: David Anderson <davea42@earthlink.net>
+ * print_die.c: Make a comment easier to understand.
+2009-02-28: David Anderson <davea42@earthlink.net>
+ * Makefile.in: add tmp-*.tmp to the 'clean' rule.
+2009-02-17: David Anderson <davea42@earthlink.net>
+ * print_sections.c,print_die.c,tag_common.c,print_frames.c: C99
+ in-line declarations and // comments are not intended here,
+ this removes a few that were introduced accidentally.
+2009-02-16: David Anderson <davea42@earthlink.net>
+ * Makefile.in: Removed some use of awk and
+ simplified some shell scripting here.
+ renamed temp files, no longer named with
+ underbars, they uniformly start with 'tmp-'.
+ * print_sections.c: Added the new argument required
+ by the updated dwarf_names.c functions argument lists.
+ * tag_tree_ext.list: List 'common extensions'
+ of tag->tag relationships.
+ * tag_attr_ext.list: List 'common extensions'
+ of tag->attr relationships.
+ * print_die.c: New 'common extension' tables used
+ for checking tag->tag and tag->attr relationships
+ unless turned off with -C.
+ * dwarf_names.awk: Removed tabs so generated names.c not so
+ spread out. Added argument to the generated functions so
+ tag_tree.c, tag_attr.c can use these generated functions nicely.
+ * dwarfdump.c: Adding -C option, which exposes
+ some 'common extensions' of dwarf uses as DWARF CHECK
+ (-ka) warnings. By default these extensions not reported
+ as warnings.
+ * tag_tree.c: Now generates base and extensions tables.
+ Code in common with tag_attr.c is in tag_common* files.
+ * tag_attr.c: Now generates base and extensions tables.
+ Code in common with tag_tree.c is in tag_common* files.
+ * tag_common.c, tag_common.h: New files with the common
+ data extracted from tag_tree.c and tag_attr.c
+ * globals.h: global flag added for -C.
+
+2009-02-14: David Anderson <davea42@earthlink.net>
+ * configure.in: Define --enable-nonstandardprintf
+ * config.h.in: new #undef HAVE_NONSTANDARD_PRINTF_64_FORMAT
+ * configure: Regenerated.
+ * config.guess, config.sub: Latest version from GNU.
+ * Makefile.in: Referenced configure variable to avoid
+ irritating message at configure time.
+ * README: document --enable-nonstandardprintf
+ * print_sections.c, print_die.c, print_reloc.c, dwarfdump.c,
+ dwconf.c, print_frames.c: Use libdwarf.h DW_PR_ printf macros
+ for for better portability.
+2009-02-13: David Anderson <davea42@earthlink.net>
+ * print_sections.c: Ensure we are checking line table header
+ correctness whichever line-table-print code is being used.
+ Allow ARM line header table (which has a bug) to be used.
+ * dwarfdump.c: Print lines_result total with checking on.
+ * globals.h: Add lines_result global to count line botches.
+2009-02-11: David Anderson <davea42@earthlink.net>
+ * print_sections.c, print_die.c: DWARF_CHECK_ERROR*
+ macros now get the count struct passed in.
+ * tag_tree.c, tag_attr.c: Add a comment in the output
+ identifying the output as generated code and
+ with the generation date/time inserted.
+ * globals.h: Accept the struct in DWARF_CHECK_ERROR*
+ macros so we can update the error count in the macro.
+2009-01-31: David Anderson <davea42@earthlink.net>
+ * Makefile.in: Remove compilation of _tag_attr_table.c
+ and _tag_tree_table.c as those are #included in
+ print_die.c, not separately compiled.
+ * print_frames.c: A formerly-static function now called
+ from another file, so declare it here.
+ * print_sections.c: Improve the printing of the .debug_loc
+ section.
+ * print_die.c: A couple of errors were missing their error
+ count increment.
+ * tag_attr.list tag_tree.list: Some normal relationships
+ were left out of the tables: fixed now.
diff --git a/dwarfdump/ChangeLog2010 b/dwarfdump/ChangeLog2010
new file mode 100644
index 0000000..e281cae
--- /dev/null
+++ b/dwarfdump/ChangeLog2010
@@ -0,0 +1,105 @@
+2010-09-30 DavidAnderson <davea42@earthlink.net>
+ * dwarfdump.c: Now -a no longer implies -c because
+ the -c option is not guaranteed to work by the DWARF spec,
+ nor is -c really necessary.
+ * README: More tweaks on the 'install' issue.
+2010-09-29 DavidAnderson <davea42@earthlink.net>
+ * README, Makefile.in: Amplified make install instructions.
+2010-09-20 DavidAnderson <da
+ * dwarfdump.1: The -c option is not guaranteed to work.
+ Because .debug_loc can have garbage bytes in areas
+ not referenced by .debug_info.
+2010-06-29 DavidAnderson <davea42@earthlink.net>
+ * print_die.c: If a location form is wrong report
+ an error but continue operating.
+ * dwarfdump.c: Implement print_error_and_continue().
+ Fix mistakes in usage message.
+ * globals.h: Declare print_error_and_continue().
+2010-04-04 DavidAnderson
+ * dwarfdump.c: New version date.
+ * configure: regenerated.
+ * addrmap.c: Added a comment to mention that tdestroy is
+ GNU only, POSIX does not mention a way to delete the
+ tsearch tree. Hence the code does #define USE_GNU 1
+ to expose the tdestroy function prototype.
+2010-04-03 DavidAnderson <davea42@earthlink.net>
+ * print_frames.h: Added new arguments to a function to get better
+ function names printing.
+ * configure.in: Added test for tsearch functions so dwarfdump
+ will still compile if they are not present.
+ See HAVE_TSEARCH macro.
+ * configure: regenerated.
+ * Makefile.in: Now names object for addrmap.c
+ * addrmap.c: New file to map pc address to function names
+ so fde printing gets functions named properly (using tsearch).
+ * addrmap.h: New file to map pc address to function names
+ so fde printing gets functions named properly (using tsearch).
+ * print_lines.c: Correct the calculation of the number
+ of error checks.
+ * dwarfdump.c: Added fdes error check print.
+ * config.h.in: Now handles the HAVE_TSEARCH macro.
+ * globals.h: Added declarations for the fde error check
+ globals.
+ * print_frames.c: Now uses addrmap.h functions to do a
+ better job of printing function names in the frame output.
+2010-03-31 DavidAnderson <davea42@earthlink.net>
+ * dwarfdump.1: Added some text about 'harmless'
+ errors.
+ * dwarfdump.c: Change the size of the harmless error list
+ to 50. Change harmless error reporting to be associated
+ with -k flags.
+ * dwconf.c: Initialize uninitialized fields to satisfy
+ a compiler warning.
+ * globals.h: Declarations added for 'harmless' error
+ reporting.
+ * print_die.c: Added commentary.
+ * print_frames.cc: Change harmless error reporting to be
+ associated with -k flags.
+ * print_aranges.c: Now calls dwarf_get_arange_info_b()
+ allowing proper printing of DWARF4 segment-sensitive
+ aranges. Change harmless error reporting to be
+ associated with -k flags.
+2010-03-28 DavidAnderson <davea42@earthlink.net>
+ * dwarf_globals.h: Added interface to print_any_harmless_errors().
+ * dwarfdump.c: Added print_any_harmless_errors() implementation
+ and we call it just before closing libdwarf.
+ * print_frames.c: Call print_any_harmless_errors after
+ getting cie/fde list.
+ * dwarfdump.conf: Add abi named 'arm' for Arm users.
+ * print_die.c: Initialize a local string pointer to NULL at
+ the point of definition.
+2010-02-14 DavidAnderson <davea42@earthlink.net>
+ * print_die.c: Add newer DW_OP operators, remove
+ bogus test of DW_OP_nop as the highest valid operator.
+ Add table of DW_OPs to simplify testing for zero-operand
+ operators.
+ Revise so that the FORM of all attributes print with -M.
+ Move a local variable declaration to the front of a block
+ to match C 1990 rules.
+ String searches now also match on attribute name.
+ * tag_attr.list: Updated copyright.
+ * dwarfdump.c: Remove a switch FALL THROUGH in the 'g' case.
+ * tag_tree_ext.list, tag_attr_ext.list: Added GNU template
+ parameter tags, attributes. Updated copyright.
+ * tag_tree.list: Added template parameter tags. Added
+ entry for nested classes. Updated copyright.
+ * tag_common.h: Increased STD_TAG_TABLE_COLUMNS and
+ EXT_ATTR_TABLE_COLS.
+2010-01-30 DavidAnderson <davea42@earthlink.net>
+ * print_die.c: Changed the spelling of one
+ 'DW_AT_type offset does not point to type info' error message so
+ one can distinguish which check lead to the message.
+2010-01-26 DavidAnderson <davea42@earthlink.net>
+ * dwarfdump.1, dwconf.c, dwconf.h, dwarfdump.conf: The default
+ frame values in frame
+ output are now generic registers like r0 to r99
+ instead of MIPS register names.
+ For the MIPS register names use '-x abi=mips'.
+ * print_frames.c: Added commentary.
+2010-01-17 DavidAnderson <davea42@earthlink.net>
+ * print_die.c: The special case DW_AT_SUN_func_offsets
+ now prints identically in dwarfdump and dwarfdump2.
+2010-01-03 DavidAnderson <davea42@earthlink.net>
+ * tag_common.c, common.h, common.c: Remove <cr> line
+ terminator characters. Update copyright year.
+ * All other files: Update copyright year.
diff --git a/dwarfdump/DWARFDUMPCOPYRIGHT b/dwarfdump/DWARFDUMPCOPYRIGHT
new file mode 100644
index 0000000..cf465e2
--- /dev/null
+++ b/dwarfdump/DWARFDUMPCOPYRIGHT
@@ -0,0 +1,85 @@
+
+========The dwarfdump copyright=======
+
+The full text of the GPL version 2 is provided in the file GPL.txt.
+
+Nearly all the files in this directory have contained a GPL
+copyright, not an LGPL copyright, for years. The following
+is an example of that copyright as used in the dwarfdump
+source, and is what SGI always intended (in David
+Anderson's opinion) to have present in
+the DWARFDUMPCOPYRIGHT file. (tag_tree.list tag_attr.list
+acconfig.h have long been marked LGPL and therefore the LGPL
+copyright, not GPL, applies to those three files.) This GPL
+copyright text added here to DWARFDUMPCOPYRIGHT Dec 4, 2006
+
+ Copyright (C) 2000,2002,2004,2005 Silicon Graphics, Inc. All Rights Reserved.
+
+ This program is free software; you can redistribute it and/or modify it
+ under the terms of version 2 of the GNU General Public License as
+ published by the Free Software Foundation.
+
+ This program is distributed in the hope that it would be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+ Further, this software is distributed without any warranty that it is
+ free of the rightful claim of any third person regarding infringement
+ or the like. Any license provided herein, whether implied or
+ otherwise, applies only to this software file. Patent licenses, if
+ any, provided herein do not apply to combinations of this program with
+ other software, or any other product whatsoever.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write the Free Software Foundation, Inc., 51
+ Franklin Street - Fifth Floor, Boston MA 02110-1301, USA.
+
+ Contact information: Silicon Graphics, Inc., 1500 Crittenden Lane,
+ Mountain View, CA 94043, or:
+
+ http://www.sgi.com
+
+ For further information regarding this notice, see:
+
+ http://oss.sgi.com/projects/GenInfo/NoticeExplan
+
+
+The following was the entire content of this file before
+December 24 2006, Being the LGPL text this is in conflict
+with the individual source files and I (David Anderson)
+believe the source file copyright was intended for dwarfdump
+not the LGPL source directly following this note. However the
+3 files tag_tree.list tag_attr.list acconfig.h have long been
+marked LGPL and the following copyright applies to those three.
+
+ Copyright (C) 2000,2004 Silicon Graphics, Inc. All Rights Reserved.
+
+ This program is free software; you can redistribute it and/or modify it
+ under the terms of version 2.1 of the GNU Lesser General Public License
+ as published by the Free Software Foundation.
+
+ This program is distributed in the hope that it would be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+ Further, this software is distributed without any warranty that it is
+ free of the rightful claim of any third person regarding infringement
+ or the like. Any license provided herein, whether implied or
+ otherwise, applies only to this software file. Patent licenses, if
+ any, provided herein do not apply to combinations of this program with
+ other software, or any other product whatsoever.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this program; if not, write the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307,
+ USA.
+
+ Contact information: Silicon Graphics, Inc., 1500 Crittenden Lane,
+ Mountain View, CA 94043, or:
+
+ http://www.sgi.com
+
+ For further information regarding this notice, see:
+
+ http://oss.sgi.com/projects/GenInfo/NoticeExplan
+
diff --git a/dwarfdump/GPL.txt b/dwarfdump/GPL.txt
new file mode 100644
index 0000000..d511905
--- /dev/null
+++ b/dwarfdump/GPL.txt
@@ -0,0 +1,339 @@
+ GNU GENERAL PUBLIC LICENSE
+ Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users. This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it. (Some other Free Software Foundation software is covered by
+the GNU Lesser General Public License instead.) You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+ To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have. You must make sure that they, too, receive or can get the
+source code. And you must show them these terms so they know their
+rights.
+
+ We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+ Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software. If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+ Finally, any free program is threatened constantly by software
+patents. We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary. To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ GNU GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License. The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language. (Hereinafter, translation is included without limitation in
+the term "modification".) Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+ 1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+ 2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+ a) You must cause the modified files to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ b) You must cause any work that you distribute or publish, that in
+ whole or in part contains or is derived from the Program or any
+ part thereof, to be licensed as a whole at no charge to all third
+ parties under the terms of this License.
+
+ c) If the modified program normally reads commands interactively
+ when run, you must cause it, when started running for such
+ interactive use in the most ordinary way, to print or display an
+ announcement including an appropriate copyright notice and a
+ notice that there is no warranty (or else, saying that you provide
+ a warranty) and that users may redistribute the program under
+ these conditions, and telling the user how to view a copy of this
+ License. (Exception: if the Program itself is interactive but
+ does not normally print such an announcement, your work based on
+ the Program is not required to print an announcement.)
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+ a) Accompany it with the complete corresponding machine-readable
+ source code, which must be distributed under the terms of Sections
+ 1 and 2 above on a medium customarily used for software interchange; or,
+
+ b) Accompany it with a written offer, valid for at least three
+ years, to give any third party, for a charge no more than your
+ cost of physically performing source distribution, a complete
+ machine-readable copy of the corresponding source code, to be
+ distributed under the terms of Sections 1 and 2 above on a medium
+ customarily used for software interchange; or,
+
+ c) Accompany it with the information you received as to the offer
+ to distribute corresponding source code. (This alternative is
+ allowed only for noncommercial distribution and only if you
+ received the program in object code or executable form with such
+ an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it. For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable. However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+ 4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License. Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+ 5. You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Program or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+ 6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+ 7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all. For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+ 8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded. In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+ 9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation. If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+ 10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission. For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this. Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+ NO WARRANTY
+
+ 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+ 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+ END OF TERMS AND CONDITIONS
+
+ How to Apply These Terms to Your New Programs
+
+ If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+ To do so, attach the following notices to the program. It is safest
+to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+ <one line to give the program's name and a brief idea of what it does.>
+ Copyright (C) <year> <name of author>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+ Gnomovision version 69, Copyright (C) year name of author
+ Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+ This is free software, and you are welcome to redistribute it
+ under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License. Of course, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary. Here is a sample; alter the names:
+
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+ `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+ <signature of Ty Coon>, 1 April 1989
+ Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs. If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library. If this is what you want to do, use the GNU Lesser General
+Public License instead of this License.
diff --git a/dwarfdump/Makefile.in b/dwarfdump/Makefile.in
new file mode 100644
index 0000000..19278f3
--- /dev/null
+++ b/dwarfdump/Makefile.in
@@ -0,0 +1,191 @@
+#
+# Makefile for dwarfdump
+# This is made very simple so it should work with
+# any 'make'.
+# The Makefile does assume that libdwarf is at ../libdwarf
+# from the dwarfdump2 source directory.
+#
+
+srcdir = @srcdir@
+VPATH = @srcdir@
+
+prefix = @prefix@
+exec_prefix = @exec_prefix@
+bindir = $(exec_prefix)/bin
+libdir = $(exec_prefix)/lib
+mandir = $(exec_prefix)/share/man
+man1dir = $(mandir)/man1
+
+
+INSTALL = @INSTALL@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_DATA = @INSTALL_DATA@
+DATAROOT = @datarootdir@
+SHELL = /bin/sh
+CC = @CC@
+AR = @AR@
+ARFLAGS = @ARFLAGS@
+RM = rm
+RANLIB = @RANLIB@
+DEFS = @DEFS@
+# ../libdwarf gets us to local headers and a libdwarf
+# archive, usually, so we assume it.
+DIRINC = $(srcdir)/../libdwarf
+LIBS = @LIBS@ -L../libdwarf -ldwarf -lelf
+INCLUDES = -I. -I$(srcdir) -I$(srcdir)/../libdwarf
+CFLAGS = $(PREINCS) @CFLAGS@ $(INCLUDES) -DCONFPREFIX=${libdir} $(POSTINCS)
+LDFLAGS = $(PRELIBS) @LDFLAGS@ $(LIBS) $(POSTLIBS)
+
+
+INSTALL = cp
+
+binprefix =
+
+FINALOBJECTS = \
+ addrmap.o \
+ checkutil.o \
+ dwarfdump.o \
+ dwconf.o \
+ esb.o \
+ print_abbrevs.o \
+ print_aranges.o \
+ print_die.o \
+ print_frames.o \
+ print_lines.o \
+ print_locs.o \
+ print_macros.o \
+ print_pubnames.o \
+ print_ranges.o \
+ print_reloc.o \
+ print_sections.o \
+ print_static_funcs.o \
+ print_static_vars.o \
+ print_strings.o \
+ print_types.o \
+ print_weaknames.o \
+ strstrnocase.o \
+ uri.o
+GEN_HFILES = common.o \
+ tmp-tt-table.c \
+ tmp-ta-table.c \
+ tmp-ta-ext-table.c \
+ tmp-tt-ext-table.c
+
+all: dwarfdump
+
+HEADERS = $(srcdir)/checkutil.h \
+ $(srcdir)/common.h \
+ $(srcdir)/dwconf.h \
+ $(srcdir)/esb.h \
+ $(srcdir)/globals.h \
+ $(srcdir)/makename.h \
+ $(srcdir)/print_frames.h \
+ $(srcdir)/uri.h
+
+$(FINALOBJECTS): $(GEN_HFILES) $(HEADERS) $(srcdir)/naming.c
+
+default: $(TARGETS)
+
+dwarfdump: $(FINALOBJECTS) makename.o naming.o common.o
+ $(CC) $(CFLAGS) -o $@ $(FINALOBJECTS) common.o makename.o naming.o $(LDFLAGS)
+
+#tag_common.o: $(srcdir)/tag_common.c $(HEADERS) dwarf_names.h
+# $(CC) $(CFLAGS) -c $(srcdir)/tag_common.c
+makename.o: $(srcdir)/makename.h $(srcdir)/makename.c
+ $(CC) $(CFLAGS) -c $(srcdir)/makename.c
+common.o: $(srcdir)/common.c $(srcdir)/common.h
+ $(CC) $(CFLAGS) -c $(srcdir)/common.c
+gennames: $(srcdir)/gennames.c $(DIRINC)/dwarf.h $(HEADERS) common.o
+ $(CC) $(CFLAGS) $(srcdir)/gennames.c common.o $(LDFLAGS) -o gennames
+naming.o: $(srcdir)/naming.c $(srcdir)/naming.h
+ $(CC) $(CFLAGS) -c $(srcdir)/naming.c
+
+# We need this as naming.o has external references we cannot have
+# in the tree builds.
+trivial_naming.o: $(srcdir)/naming.c
+ $(CC) $(CFLAGS) -DTRIVIAL_NAMING -c $(srcdir)/naming.c -o trivial_naming.o
+
+tag_tree_build: $(srcdir)/tag_tree.c $(DIRINC)/dwarf.h $(HEADERS) tag_common.o makename.o common.o trivial_naming.o
+ $(CC) $(CFLAGS) $(srcdir)/tag_tree.c tag_common.o common.o makename.o trivial_naming.o $(LDFLAGS) -o tag_tree_build
+
+tag_attr_build: $(srcdir)/tag_attr.c $(DIRINC)/dwarf.h $(HEADERS) tag_common.o makename.o common.o trivial_naming.o
+ $(CC) $(CFLAGS) $(srcdir)/tag_attr.c tag_common.o common.o makename.o trivial_naming.o $(LDFLAGS) -o tag_attr_build
+
+tmp-tt-table.c tmp-tt-ext-table.c: $(srcdir)/tag_tree_ext.list $(srcdir)/tag_tree.list tag_tree_build
+ # gcc -E tag_tree.list does not work, so use a .c name
+ -rm -f tmp-t1.c
+ cp $(srcdir)/tag_tree.list tmp-t1.c
+ $(CC) $(CFLAGS) -E tmp-t1.c > ./tmp-tag-tree-build1.tmp
+ ./tag_tree_build -s -i tmp-tag-tree-build1.tmp -o tmp-tt-table.c
+ -rm -f tmp-t4.c
+ cp $(srcdir)/tag_tree_ext.list tmp-t4.c
+ $(CC) $(CFLAGS) -E tmp-t4.c > ./tmp-tag-tree-build4.tmp
+ ./tag_tree_build -e -i tmp-tag-tree-build4.tmp -o tmp-tt-ext-table.c
+
+tmp-ta-table.c tmp-ta-ext-table.c: $(srcdir)/tag_attr_ext.list $(srcdir)/tag_attr.list tag_attr_build
+ # gcc -E tag_attr.list does not work, so use a .c name
+ -rm -f tmp-t2.c
+ cp $(srcdir)/tag_attr.list tmp-t2.c
+ $(CC) $(CFLAGS) -E tmp-t2.c > ./tmp-tag-attr-build2.tmp
+ ./tag_attr_build -s -i tmp-tag-attr-build2.tmp -o tmp-ta-table.c
+ -rm -f tmp-t3.c
+ cp $(srcdir)/tag_attr_ext.list tmp-t3.c
+ $(CC) $(CFLAGS) -E tmp-t3.c > ./tmp-tag-attr-build3.tmp
+ ./tag_attr_build -e -i tmp-tag-attr-build3.tmp -o tmp-ta-ext-table.c
+
+
+# The file dwarf_names.awk generates BOTH dwarf_names.h and dwarf_names.c
+# be careful of the make dependencies here
+dwarf_names.h: gennames $(DIRINC)/dwarf.h
+ rm -f dwarf_names.h dwarf_names.c
+ ./gennames -s -i ../libdwarf -o .
+dwarf_names.c: dwarf_names.h
+
+test: esb.o $(srcdir)/testesb.c
+ $(CC) -o test $(srcdir)/testesb.c esb.o
+ ./test
+ -rm -f ./test
+
+
+# This simply assumes that a default INSTALL (cp) command
+# will work and leave sensible permissions on the resulting files.
+# Some adjustment might be required, see README.
+install: all
+ $(INSTALL) dwarfdump $(bindir)/dwarfdump
+ $(INSTALL) $(srcdir)/dwarfdump.conf $(libdir)/dwarfdump.conf
+ $(INSTALL) $(srcdir)/dwarfdump.1 $(man1dir)/dwarfdump.1
+
+uninstall:
+ -rm -f $(bindir)/dwarfdump
+ -rm -f $(man1dir)/dwarfdump.1
+ -rm -f $(libdir)/dwarfdump.conf
+
+clean:
+ rm -f *.o dwarfdump
+ rm -f _tag_attr_table.c
+ rm -f _tag_attr_ext_table.c
+ rm -f _tag_tree_table.c
+ rm -f _tag_tree_ext_table.c
+ -rm -f tag_attr_build*.tmp
+ -rm -f tag_tree_build*.tmp
+ rm -f tag_tree_build
+ rm -f tag_attr_build
+ -rm -f _*.c _*.h
+ -rm -f tmp-*.c tmp-*.h tmp-*.tmp
+ rm -f gennames
+ rm -f dwarf_names_new.c
+ rm -f dwarf_names_new.h
+ rm -f dwarf_names_enum.h
+ rm -f dwarf_names.h
+ rm -f dwarf_names.c
+
+
+distclean: clean
+ rm -f config.log config.h config.cache config.status
+ rm -rf autom4te.cache
+ rm -rf Makefile
+
+shar:
+ @echo "shar not set up yet"
+dist:
+ @echo "dist not set up yet"
diff --git a/dwarfdump/NEWS b/dwarfdump/NEWS
new file mode 100644
index 0000000..ed4428b
--- /dev/null
+++ b/dwarfdump/NEWS
@@ -0,0 +1,206 @@
+December 13, 2011
+ Now prints missing line table column number as 0 (now
+ matching the DWARF spec), the previous
+ practice of printing -1 was always wrong.
+ And prints the DWARF3/4 new line table fields (when present).
+October 29, 2011
+ Added support for printing .debug_types (type unit) data.
+October 26, 2011
+ Added new features to Makefile.in and documented in README
+ how to build dwarfdump with headers or libraries in
+ non-standard places.
+October 23, 2011
+ By default the various places with string option values
+ and file paths all use URI transformation on input and
+ if the transformation does anything at all dwarfdump reports
+ the input and transformed strings. This makes it easy
+ to deal with strings and expressions and file paths
+ that are difficult to express in a shell (or that getopt
+ mangles). Options -q and -U give you control over this process.
+October 07, 2011
+ The -x abi=mips frame register abi in dwarfdump.conf is now
+ usable with modern MIPS objects as well as old IRIX objects.
+ There are other mips-* frame register setups described
+ in dwarfdump.conf for anyone testing that nothing new has
+ been added that conflicts with old IRIX/MIPS frame generation.
+June 04, 2011
+ Error checking is now distinct from section printing, making
+ error checking (the -k options) much easier to work with on
+ large objects.
+ So compiler-created errors can be found, the error reporting
+ now prints context information.
+March 29, 2011
+ Added many new correctness tests. Changed the format of
+ various items (line data prints in a more compact form, numbers
+ are more uniformly hexadecimal fixed length where that makes sense).
+ All the source files are uniformly indented to a multiple of 4
+ characters and all intent-tabs in the source have been removed.
+ Major logic changes involved changing error-reporting to be
+ more detailed and adding new tests for incorrect DWARF.
+ Now reports error summary by the compiler name, not just overall.
+January 26, 2010
+ Changed the default frame-data register names from MIPS to
+ a generic set of registers.
+ Try '-x abi=mips' to get the traditional old MIPS register
+ naming.
+June 22, 2009
+ Added the -S option to dwarfdump.
+June 10, 2009
+ Moved the gennames.c code to libdwarf.
+May 4, 2009
+ Replaced awk source-generation of certain functions
+ with new gennames.c code.
+ Now we can print an object with an address_size that
+ varies by compilation unit.
+April 4, 2009
+ Corrected aspects of the frame-printing by ensuring we pass
+ all the information libdwarf needs for fully consistent behavior.
+ Three newly defined libdwarf calls calls made to ensure
+ that better behavior (specifically having dwarfdump consistently
+ recognize when registers are the cfa, undefined-value or same-value
+ pseudo registers). Updated dwarfdump.conf to set these same
+ things consistently.
+Mar 22, 2009
+ The -f and -F flags no longer also imply -i (it just
+ did not make sense to tie them (cannot recall why
+ it might have been tied before).
+Mar 20, 2009
+ Moved print_* functions from print_sections.c to individual
+ source files. Hopefully making the code a bit easier
+ to read.
+Feb 16, 2009
+ Added the -C option. It is a sort of 'pedantic' option
+ as it turns on warnings about certain commonly used
+ non-standard tag->tag and tag->attr relationships.
+ Added the tag_attr_ext.list tag_tree_ext.list files which
+ define the 'common use' extensions.
+Feb 14, 2009
+ Added configure option --enable-nonstandardprintf
+ which makes it easy to get printf of Dwarf_Unsigned (etc)
+ types correct even for non-standard compilers.
+December 30, 2008
+ Now we print the .debug_ranges section (with -N)
+ and the data for DW_AT_ranges (with -i).
+December 8, 2008
+ The -M option now causes printing of FORM details.
+ And -v adds details about abbreviation 'indexes' into
+ an abbreviation table (.debug_abbrev)
+ providing more detail for folks debugging or
+ improving their understanding of DWARF data.
+April 9, 2008
+ Added -H <num> to limit the number of compilation-units/FDEs
+ dwarfdump prints in one run. Added -n to eliminate function-name
+ printing in .debug_frame output (with a large-enough debug_info
+ section function-name printing is too slow). The function name
+ printing will be fixed in another release.
+December 8, 2007
+ Had to add an ugly configure conditional as libelf has
+ unconditional use of off64_t in recent libelf.h
+July 3, 2007
+ Now with -v dwarf expression blocks in frame operations
+ are printed expanded out.
+July 2, 2007
+ Added a new abi -x abi=general usable for any cpu with
+ up to 1000 registers.
+May 7, 2007
+ Sun Microsystems contributes new dwarf.h extensions and a new -G option
+ to dwarfdump -i (so one can see the 'global' offset to DIEs).
+ Thanks to Chris Quenelle of Sun.
+April 17, 2006
+ New -x name=<conf file> -x abi=<abiname> and configuration file
+ enable sensible printing of a wide range of .debug_frame eh_frame
+ correctly without recompiling dwarfdump or touching libdwarf.h or
+ dwarf.h.
+March 29, 2005
+ Now handles DWARF3. For non-MIPS objects, the list of register
+ names in print_sections.c is not appropriate, #define
+ DWARFDUMP_TURN_OFF_MIPS_REG_NAMES to turn off the MIPS names.
+December 1, 2005
+ Added new DWARF3 TAGs and ATtributes to the -k lists,
+ clarified the -k reporting, and made the build more robust
+ in the face of errors in the *.list relationship-spec-files.
+
+August 1, 2005
+ Now print_die.c deals with long loclists without a coredump.
+ Added esb.h esb.c (and testesb.c for testing) to encapsulate
+ getting space for possibly-long strings.
+ Now print_die.c uses snprintf() not sprintf (hopefully this
+ will not inconvenience anyone, snprintf() has been available
+ on most systems for years now).
+ Altered print of location lists a little bit - for better appearance.
+
+July 15, 2005
+ Now completely frees all allocated memory. Various
+ routines were not calling dealloc() code and
+ new libdwarf dealloc routines are now used where those
+ are needed.
+
+ Now prints DWARF3 .debug_pubtypes section (with -a or -y).
+ The .debug_pubtypes section and SGI-specific .debug_typenames
+ are equvalent so they are treated alike.
+
+Mar 21, 2005
+ The -f flag now prints only .debug_frame data. The .eh_frame section
+ (GNU exceptions data) now prints with -F (not -a).
+ Printing gcc 3.3 or 3.4 .eh_frame with zR augmentation
+ does not work at this time, so do not use -F
+ to print such an object.
+ The line section print now prints a CU-DIE offset for each such DIEs
+ line information. This makes it much easier to correctly associate
+ -l (or -v -l) output with -v -v -l when debugging a faulty
+ linetable in an executable.
+ With -v -v -l (two -v) the output of line info continues to be a
+ completely different format than zero or one -v, the two-v
+ form showing the detailed line table opcodes.
+ With g++ 3.3.3 one sees bad line addresses at times as the
+ DW_LNE_set_address address for header files do not always
+ get their relocations applied. I am told this is fixed in 3.4.x.
+
+
+Mar 18, 2005
+ In correcting printing of macro information the format
+ of the macro (-m) output has changed substantially.
+ Much more complete now. Still could use enhancement.
+
+Oct 28, 2004
+ Updated contact address in copyright: SGI moved 1/4 mile
+ to a new address: 1500 Crittenden Lane.
+
+Oct 02, 2003
+ Now fully supports .debug_loc section.
+
+June 14, 2001
+ Now calling a new function dwarf_get_arange_cu_header_offset()
+ in libdwarf and printing the returned cu header offset for
+ aranges entries. Making it easier to track down internal
+ errors in the dwarf2 data. Also added small other
+ consistency checks, printing a message and exit()ing on
+ error.
+
+April 14, 2000
+ The libdwarf copyright has changed to
+ version 2.1 of the GNU Lesser General Public License.
+ Anyone holding a version of libdwarf that was published
+ before this new copyright
+ is allowed to use
+ the copyright published in that earlier libdwarf source
+ on the earlier source
+ or to use
+ this new copyright on the earlier source,
+ at their option.
+
+July 21, 1999
+ Added gnu extensions to the frame information printer
+ and handling for egcs eh_frame printing.
+ libdwarf changes mean this now can print little-endian
+ object dwarf on a big-endian system and vice-versa.
+
+December, 1998
+ added dwarfdump to the dwarf public source distribution.
+
+June, 1994
+ libdwarf consumer interface changed completely so updated to match.
+
+May, 1993
+ Initial version of dwarfdump for dwarf version 2
+ written at sgi.
diff --git a/dwarfdump/README b/dwarfdump/README
new file mode 100644
index 0000000..515e2b6
--- /dev/null
+++ b/dwarfdump/README
@@ -0,0 +1,82 @@
+I would prefer you try using ../dwarfdump2, not this source.
+If you must use this for some reason, could you let me know why?
+Thanks.
+
+To build dwarfdump, first build libdwarf in the neighboring
+directory then type
+ ./configure
+ make
+
+Installation is a bit primitive.
+ sudo make install
+may or may not work.
+Some or all of the following might be required on Unix or Linux or MacOS:
+ sudo mkdir -p /usr/local/share/man/man1/
+ sudo mkdir -p /usr/local/lib
+ sudo mkdir -p /usr/local/bin
+Then retry the 'sudo make install' and (if necessary) try
+ sudo chmod a+x /usr/local/bin/dwarfdump
+ sudo chmod a+r /usr/local/share/man/man1/dwarfdump.1
+ sudo chmod a+r /usr/local/lib/dwarfdump.conf
+You don't really need the dwarfdump.1 man page,
+but you might as well have it. If the man page is not visible
+with 'man dwarfdump' try 'man manpath' for hints.
+
+If you don't need others using dwarfdump on your computer,
+just
+ cp dwarfdump $HOME/bin/dwarfdump
+(by convention many people put personal executables in $HOME/bin
+and fix up $PATH to refer there) which suffices as 'installation'.
+Also
+ cp dwarfdump.conf $HOME
+
+To use dwarf or libdwarf, you may want to install dwarf.h
+and libdwarf.h somewhere convenient.
+You can just copy those two headers to /usr/local/include by hand
+(or anywhere, really, that you have permission to copy to)
+(you may need to use -I/usr/local/include on compile lines
+to reference them there, but see below on configure and make).
+
+Notice that dwarf_names.c and dwarf_names.h are supplied by
+the release though the Makefile can and may rebuild them.
+Some users find it difficult to get a reliable awk(1) program,
+so for them these prebuilt versions may be useful.
+
+If your headers or libelf/libdwarf are not in the expected places,
+use the make command line to add flags and include directories.
+For example
+ ./configure
+ PREINCS="-I /usr/local/include" POSTINCS="-I /home/x/include" make
+PREINCS content is inserted before CFLAGS as make(1) is running.
+POSTINCS content is added after the CFLAGS value.
+
+To set LDFLAGS,
+do so at configure time, for example:
+ ./configure LDFLAGS="-L /some/dir"
+And/or use PRELIBS and/or POSTLIBS at 'make' time similar to the use
+of PREINCS and POSTINCS.
+
+If the libdwarf directory
+has both libdwarf.so and libdwarf.a, the libdwarf.so
+will be picked up and
+ "./tag_tree_build: error while loading shared libraries:
+ libdwarf.so: cannot open shared object file:
+ No such file or directory"
+will probably result.
+Either: remove libdwarf.so and rebuild or set
+the environment variable LD_LIBRARY_PATH to the directory
+containing the .so or use LDFLAGS to set rpath (see just below).
+It is perhaps simpler to ensure that the libdwarf directory
+only has an archive, not a shared-library.
+But sometimes one wants a shared library.
+In that case
+one can set ld's -rpath on the gcc command line like this:
+ LDFLAGS="-Wl,-rpath=/some/path/libdir"
+so the shared library can be found at run time automatically.
+
+The same problem may arise with libelf, and the same approach
+will solve the problem.
+
+
+
+David Anderson. davea42 at earthlink dot net.
diff --git a/dwarfdump/addrmap.c b/dwarfdump/addrmap.c
new file mode 100644
index 0000000..fb7ba79
--- /dev/null
+++ b/dwarfdump/addrmap.c
@@ -0,0 +1,149 @@
+/*
+ Copyright 2010-2011 David Anderson. All rights reserved.
+
+ This program is free software; you can redistribute it and/or modify it
+ under the terms of version 2 of the GNU General Public License as
+ published by the Free Software Foundation.
+
+ This program is distributed in the hope that it would be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+ Further, this software is distributed without any warranty that it is
+ free of the rightful claim of any third person regarding infringement
+ or the like. Any license provided herein, whether implied or
+ otherwise, applies only to this software file. Patent licenses, if
+ any, provided herein do not apply to combinations of this program with
+ other software, or any other product whatsoever.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write the Free Software Foundation, Inc., 51
+ Franklin Street - Fifth Floor, Boston MA 02110-1301, USA.
+
+*/
+
+/* If memory full we do not exit, we just keep going as if
+ all were well. */
+
+#include "globals.h"
+#include <stdio.h>
+#include "addrmap.h"
+#ifndef HAVE_TSEARCH
+struct Addr_Map_Entry * addr_map_insert( Dwarf_Unsigned addr,
+ char *name,void **tree1)
+{ return 0; }
+struct Addr_Map_Entry * addr_map_find(Dwarf_Unsigned addr,void **tree1)
+{ return 0; }
+void addr_map_destroy(void *map)
+{ return;}
+
+
+
+#else /* HAVE_TSEARCH */
+#define __USE_GNU 1
+#include <search.h>
+
+char firststringcontent[100];
+char *firststring = 0;
+struct Addr_Map_Entry *firstaddr = 0;
+
+static struct Addr_Map_Entry *
+addr_map_create_entry(Dwarf_Unsigned k,char *name)
+{
+ struct Addr_Map_Entry *mp =
+ (struct Addr_Map_Entry *)malloc(sizeof(struct Addr_Map_Entry));
+ if(!mp) {
+ return 0;
+ }
+ mp->mp_key = k;
+ if(name) {
+ mp->mp_name = strdup(name);
+ } else {
+ mp->mp_name = 0;
+ }
+ return mp;
+}
+static void
+addr_map_free_func(void *mx)
+{
+ struct Addr_Map_Entry *m = mx;
+ if(!m) {
+ return;
+ }
+ free(m->mp_name);
+ m->mp_name = 0;
+ free(m);
+ return;
+}
+
+static void
+DUMPFIRST(int line)
+{
+ if(!firststring) {
+ return;
+ }
+}
+
+static int
+addr_map_compare_func(const void *l, const void *r)
+{
+ const struct Addr_Map_Entry *ml = l;
+ const struct Addr_Map_Entry *mr = r;
+ if(ml->mp_key < mr->mp_key) {
+ return -1;
+ }
+ if(ml->mp_key > mr->mp_key) {
+ return 1;
+ }
+ return 0;
+}
+struct Addr_Map_Entry *
+addr_map_insert( Dwarf_Unsigned addr,char *name,void **tree1)
+{
+ void *retval = 0;
+ struct Addr_Map_Entry *re = 0;
+ struct Addr_Map_Entry *e;
+ e = addr_map_create_entry(addr,name);
+ DUMPFIRST(__LINE__);
+ /* tsearch records e's contents unless e
+ is already present . We must not free it till
+ destroy time if it got added to tree1. */
+ retval = tsearch(e,tree1, addr_map_compare_func);
+ if(retval) {
+ re = *(struct Addr_Map_Entry **)retval;
+ if ( re != e) {
+ /* We returned an existing record, e not needed. */
+ addr_map_free_func(e);
+ } else {
+ /* Record e got added to tree1, do not free record e. */
+ }
+ }
+ return re;
+}
+struct Addr_Map_Entry *
+addr_map_find(Dwarf_Unsigned addr,void **tree1)
+{
+ void *retval = 0;
+ struct Addr_Map_Entry *re = 0;
+ struct Addr_Map_Entry *e = 0;
+
+ e = addr_map_create_entry(addr,NULL);
+ DUMPFIRST(__LINE__);
+ retval = tfind(e,tree1, addr_map_compare_func);
+ if(retval) {
+ re = *(struct Addr_Map_Entry **)retval;
+ }
+ /* The one we created here must be deleted, it is dead.
+ We look at the returned one instead. */
+ addr_map_free_func(e);
+ return re;
+}
+
+void
+addr_map_destroy(void *map)
+{
+ /* tdestroy is not part of Posix, it is a GNU libc function. */
+ tdestroy(map,addr_map_free_func);
+}
+
+#endif /* HAVE_TSEARCH */
diff --git a/dwarfdump/addrmap.h b/dwarfdump/addrmap.h
new file mode 100644
index 0000000..a7b26df
--- /dev/null
+++ b/dwarfdump/addrmap.h
@@ -0,0 +1,33 @@
+/*
+ Copyright 2010 David Anderson. All rights reserved.
+
+ This program is free software; you can redistribute it and/or modify it
+ under the terms of version 2 of the GNU General Public License as
+ published by the Free Software Foundation.
+
+ This program is distributed in the hope that it would be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+ Further, this software is distributed without any warranty that it is
+ free of the rightful claim of any third person regarding infringement
+ or the like. Any license provided herein, whether implied or
+ otherwise, applies only to this software file. Patent licenses, if
+ any, provided herein do not apply to combinations of this program with
+ other software, or any other product whatsoever.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write the Free Software Foundation, Inc., 51
+ Franklin Street - Fifth Floor, Boston MA 02110-1301, USA.
+
+*/
+
+struct Addr_Map_Entry {
+ Dwarf_Unsigned mp_key;
+ char * mp_name;
+};
+
+struct Addr_Map_Entry * addr_map_insert(Dwarf_Unsigned addr,
+ char *name, void **map);
+struct Addr_Map_Entry * addr_map_find(Dwarf_Unsigned addr, void **map);
+void addr_map_destroy(void *map);
diff --git a/dwarfdump/checkutil.c b/dwarfdump/checkutil.c
new file mode 100644
index 0000000..6ba756c
--- /dev/null
+++ b/dwarfdump/checkutil.c
@@ -0,0 +1,565 @@
+/*
+ Copyright (C) 2011 SN Systems Ltd. All Rights Reserved.
+ Portions Copyright (C) 2011 David Anderson. All Rights Reserved.
+
+ This program is free software; you can redistribute it and/or modify it
+ under the terms of version 2 of the GNU General Public License as
+ published by the Free Software Foundation.
+
+ This program is distributed in the hope that it would be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+ Further, this software is distributed without any warranty that it is
+ free of the rightful claim of any third person regarding infringement
+ or the like. Any license provided herein, whether implied or
+ otherwise, applies only to this software file. Patent licenses, if
+ any, provided herein do not apply to combinations of this program with
+ other software, or any other product whatsoever.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write the Free Software Foundation, Inc., 51
+ Franklin Street - Fifth Floor, Boston MA 02110-1301, USA.
+
+*/
+/*
+
+ These simple list-processing functions are in support
+ of checking DWARF for compiler-errors of various sorts.
+
+
+*/
+
+#include "globals.h"
+#include <assert.h>
+
+/* Private function */
+static void DumpFullBucketGroup(Bucket_Group *pBucketGroup);
+static int FindDataIndexInBucket(Bucket_Group *pBucketGroup,
+ Bucket_Data *pBucketData);
+static void PrintBucketData(Bucket_Group *pBucketGroup,
+ Bucket_Data *pBucketData);
+static void ProcessBucketGroup(Bucket_Group *pBucketGroup,
+ void (*pFunction)(Bucket_Group *pBucketGroup,Bucket_Data *pBucketData));
+
+Bucket_Group *
+AllocateBucketGroup(int kind)
+{
+ Bucket_Group *pBucketGroup = (Bucket_Group *)calloc(1,sizeof(Bucket_Group));
+ pBucketGroup->kind = kind;
+ return pBucketGroup;
+}
+
+void
+ReleaseBucketGroup(Bucket_Group *pBucketGroup)
+{
+ Bucket *pBucket = 0;
+ Bucket *pNext = 0;
+
+ assert(pBucketGroup);
+ for (pBucket = pBucketGroup->pHead; pBucket; /*pBucket = pBucket->pNext*/) {
+ pNext = pBucket->pNext;
+ free(pBucket);
+ pBucket = pNext;
+ }
+ pBucketGroup->pHead = NULL;
+ pBucketGroup->pTail = NULL;
+ free(pBucketGroup);
+}
+
+void
+ResetBucketGroup(Bucket_Group *pBucketGroup)
+{
+ Bucket *pBucket = 0;
+
+ assert(pBucketGroup);
+ for (pBucket = pBucketGroup->pHead; pBucket; pBucket = pBucket->pNext) {
+ pBucket->nEntries = 0;
+ }
+ ResetSentinelBucketGroup(pBucketGroup);
+}
+
+/* Reset sentinels in a Bucket Group. */
+void
+ResetSentinelBucketGroup(Bucket_Group *pBucketGroup)
+{
+ /* Sanity checks */
+ assert(pBucketGroup);
+ pBucketGroup->pFirst = NULL;
+ pBucketGroup->pLast = NULL;
+}
+
+void PrintBucketGroup(Bucket_Group *pBucketGroup,Dwarf_Bool bFull)
+{
+ assert(pBucketGroup);
+ if (bFull) {
+ DumpFullBucketGroup(pBucketGroup);
+ } else {
+ if (pBucketGroup->pFirst && pBucketGroup->pLast) {
+ printf("\nBegin Traversing, First = 0x%08" DW_PR_DUx
+ ", Last = 0x%08" DW_PR_DUx "\n",
+ pBucketGroup->pFirst->key,pBucketGroup->pLast->key);
+ ProcessBucketGroup(pBucketGroup,PrintBucketData);
+ }
+ }
+}
+
+static void
+PrintBucketData(Bucket_Group *pBucketGroup,Bucket_Data *pBucketData)
+{
+ int nCount = 0;
+ assert(pBucketGroup);
+ assert(pBucketData);
+
+ nCount = FindDataIndexInBucket(pBucketGroup,pBucketData);
+ printf("[%06d] Key = 0x%08" DW_PR_DUx ", Base = 0x%08" DW_PR_DUx
+ ", Low = 0x%08" DW_PR_DUx ", High = 0x%08" DW_PR_DUx
+ ", Flag = %d, Name = '%s'\n",
+ ++nCount,
+ pBucketData->key,
+ pBucketData->base,
+ pBucketData->low,
+ pBucketData->high,
+ pBucketData->bFlag,
+ pBucketData->name);
+}
+
+static void
+DumpFullBucketGroup(Bucket_Group *pBucketGroup)
+{
+ int nBucketNo = 1;
+ int nIndex = 0;
+ int nCount = 0;
+ Bucket *pBucket = 0;
+ Bucket_Data *pBucketData = 0;
+
+ assert(pBucketGroup);
+ for (pBucket = pBucketGroup->pHead; pBucket && pBucket->nEntries;
+ pBucket = pBucket->pNext) {
+
+ printf("\nLowPC & HighPC records for bucket %d, at 0x%08lx\n",
+ nBucketNo++,(unsigned long)pBucket);
+ for (nIndex = 0; nIndex < pBucket->nEntries; ++nIndex) {
+ pBucketData = &pBucket->Entries[nIndex];
+ printf("[%06d] Key = 0x%08" DW_PR_DUx ", Base = 0x%08" DW_PR_DUx
+ ", Low = 0x%08" DW_PR_DUx ", High = 0x%08" DW_PR_DUx
+ ", Flag = %d, Name = '%s'\n",
+ ++nCount,
+ pBucketData->key,
+ pBucketData->base,
+ pBucketData->low,
+ pBucketData->high,
+ pBucketData->bFlag,
+ pBucketData->name);
+ }
+ }
+}
+
+/* Insert entry into Bucket Group.
+ We make no check for duplicate information. */
+void
+AddEntryIntoBucketGroup(Bucket_Group *pBucketGroup,
+ Dwarf_Addr key,Dwarf_Addr base,
+ Dwarf_Addr low,Dwarf_Addr high,
+ const char *name,
+ Dwarf_Bool bFlag)
+{
+ Bucket *pBucket = 0;
+ Bucket_Data data;
+
+ data.bFlag = bFlag;
+ data.name = name;
+ data.key = key;
+ data.base = base;
+ data.low = low;
+ data.high = high;
+
+ assert(pBucketGroup);
+ if (!pBucketGroup->pHead) {
+ /* Allocate first bucket */
+ pBucket = (Bucket *)calloc(1,sizeof(Bucket));
+ pBucketGroup->pHead = pBucket;
+ pBucketGroup->pTail = pBucket;
+ pBucket->nEntries = 1;
+ pBucket->Entries[0] = data;
+ return;
+ }
+
+ pBucket = pBucketGroup->pTail;
+
+ /* Check if we have a previous allocated set of
+ buckets (have been cleared */
+ if (pBucket->nEntries) {
+ if (pBucket->nEntries < BUCKET_SIZE) {
+ pBucket->Entries[pBucket->nEntries++] = data;
+ } else {
+ /* Allocate new bucket */
+ pBucket = (Bucket *)calloc(1,sizeof(Bucket));
+ pBucketGroup->pTail->pNext = pBucket;
+ pBucketGroup->pTail = pBucket;
+ pBucket->nEntries = 1;
+ pBucket->Entries[0] = data;
+ }
+ } else {
+ /* We have an allocated bucket with zero entries; search for the
+ first available bucket to be used as the current
+ insertion point */
+ for (pBucket = pBucketGroup->pHead; pBucket;
+ pBucket = pBucket->pNext) {
+
+ if (pBucket->nEntries < BUCKET_SIZE) {
+ pBucket->Entries[pBucket->nEntries++] = data;
+ break;
+ }
+ }
+ }
+}
+
+/* For Groups where entries are individually deleted, this does
+ that work. */
+Dwarf_Bool
+DeleteKeyInBucketGroup(Bucket_Group *pBucketGroup,Dwarf_Addr key)
+{
+ int nIndex = 0;
+ Bucket *pBucket = 0;
+ Bucket_Data *pBucketData = 0;
+
+ /* Sanity checks */
+ assert(pBucketGroup);
+
+ /* For now do a linear search */
+ for (pBucket = pBucketGroup->pHead; pBucket && pBucket->nEntries;
+ pBucket = pBucket->pNext) {
+
+ for (nIndex = 0; nIndex < pBucket->nEntries; ++nIndex) {
+ pBucketData = &pBucket->Entries[nIndex];
+ if (pBucketData->key == key) {
+ Bucket_Data data = {FALSE,NULL,0,0,0,0};
+ int nStart;
+ for (nStart = nIndex + 1; nStart < pBucket->nEntries;
+ ++nStart) {
+
+ pBucket->Entries[nIndex] = pBucket->Entries[nStart];
+ ++nIndex;
+ }
+ pBucket->Entries[nIndex] = data;
+ --pBucket->nEntries;
+ return TRUE;
+ }
+ }
+ }
+ return FALSE;
+}
+
+/* Search to see if the address is in the range between
+ low and high addresses in some Bucked Data record.
+ This matches == if high is exact match (which usually means
+ one-past-true-high). */
+Dwarf_Bool
+FindAddressInBucketGroup(Bucket_Group *pBucketGroup,Dwarf_Addr address)
+{
+ int nIndex = 0;
+ Bucket *pBucket = 0;
+ Bucket_Data *pBucketData = 0;
+
+ assert(pBucketGroup);
+ /* For now do a linear search */
+ for (pBucket = pBucketGroup->pHead; pBucket && pBucket->nEntries;
+ pBucket = pBucket->pNext) {
+
+ for (nIndex = 0; nIndex < pBucket->nEntries; ++nIndex) {
+ pBucketData = &pBucket->Entries[nIndex];
+ if (address >= pBucketData->low &&
+ address <= pBucketData->high) {
+ return TRUE;
+ }
+ }
+ }
+ return FALSE;
+}
+
+/* Search an entry (Bucket Data) in the Bucket Set */
+Bucket_Data *FindDataInBucketGroup(Bucket_Group *pBucketGroup,Dwarf_Addr key)
+{
+ int mid = 0;
+ int low = 0;
+ int high = 0;
+ Bucket *pBucket = 0;
+ Bucket_Data *pBucketData = 0;
+
+ assert(pBucketGroup);
+
+ for (pBucket = pBucketGroup->pHead; pBucket; pBucket = pBucket->pNext) {
+ /* Get lower and upper references */
+ if (pBucket->nEntries) {
+ low = 0;
+ high = pBucket->nEntries;
+ while (low < high) {
+ mid = low + (high - low) / 2;
+ if (pBucket->Entries[mid].key < key) {
+ low = mid + 1;
+ } else {
+ high = mid;
+ }
+ }
+ if ((low < pBucket->nEntries) &&
+ (pBucket->Entries[low].key == key)) {
+
+ pBucketData = &pBucket->Entries[low];
+ /* Update sentinels to allow traversing the table */
+ if (!pBucketGroup->pFirst) {
+ pBucketGroup->pFirst = pBucketData;
+ }
+ pBucketGroup->pLast = pBucketData;
+ return pBucketData;
+ }
+ }
+ }
+ return (Bucket_Data *)NULL;
+}
+
+/* Find the Bucket that contains a given Bucket Data
+ and return its local index. Else return -1. */
+static int
+FindDataIndexInBucket(Bucket_Group *pBucketGroup,Bucket_Data *pBucketData)
+{
+ Bucket *pBucket = 0;
+ Bucket_Data *pLower = 0;
+ Bucket_Data *pUpper = 0;
+
+ /* Sanity checks */
+ assert(pBucketGroup);
+ assert(pBucketData);
+
+ /* Use sentinels if any. */
+ if (pBucketGroup->pFirst && pBucketGroup->pLast &&
+ pBucketData >= pBucketGroup->pFirst &&
+ pBucketData <= pBucketGroup->pLast) {
+
+ /* Find bucket that contains the first sentinel */
+ for (pBucket = pBucketGroup->pHead; pBucket && pBucket->nEntries;
+ pBucket = pBucket->pNext) {
+
+ pLower = &pBucket->Entries[0];
+ pUpper = &pBucket->Entries[pBucket->nEntries - 1];
+
+ /* Check if the first sentinel is in this bucket. */
+ if (pBucketGroup->pFirst >= pLower &&
+ pBucketGroup->pFirst <= pUpper) {
+ /* We have found the bucket, return the index. */
+ return pBucketData - pBucketGroup->pFirst;
+ }
+ }
+ } else {
+ /* Find bucket that contains the entry */
+ for (pBucket = pBucketGroup->pHead; pBucket && pBucket->nEntries;
+ pBucket = pBucket->pNext) {
+
+ pLower = &pBucket->Entries[0];
+ pUpper = &pBucket->Entries[pBucket->nEntries - 1];
+
+ /* Check if the first sentinel is in this bucket */
+ if (pBucketData >= pLower && pBucketData <= pUpper) {
+ /* We have found the bucket, return the index */
+ return pBucketData - pLower;
+ }
+ }
+ }
+ /* Invalid data; just return index indicating not-found */
+ return -1;
+}
+
+/* Search an entry (Bucket Data) in the Bucket Group.
+ The key is an offset, a DIE offset
+ within Visited info. */
+Bucket_Data *FindKeyInBucketGroup(Bucket_Group *pBucketGroup,Dwarf_Addr key)
+{
+ int nIndex = 0;
+ Bucket *pBucket = 0;
+ Bucket_Data *pBucketData = 0;
+
+ /* Sanity checks */
+ assert(pBucketGroup);
+
+ /* For now do a linear search */
+ for (pBucket = pBucketGroup->pHead; pBucket && pBucket->nEntries;
+ pBucket = pBucket->pNext) {
+ for (nIndex = 0; nIndex < pBucket->nEntries; ++nIndex) {
+ pBucketData = &pBucket->Entries[nIndex];
+ if (pBucketData->key == key) {
+ return pBucketData;
+ }
+ }
+ }
+ return (Bucket_Data *)NULL;
+}
+
+/* Search an entry (Bucket Data) in the Bucket Set by name.
+ Used to find link-once section names. */
+Bucket_Data *
+FindNameInBucketGroup(Bucket_Group *pBucketGroup,char *name)
+{
+ int nIndex = 0;
+ Bucket *pBucket = 0;
+ Bucket_Data *pBucketData = 0;
+
+ assert(pBucketGroup);
+ /* For now do a linear search. */
+ for (pBucket = pBucketGroup->pHead; pBucket && pBucket->nEntries;
+ pBucket = pBucket->pNext) {
+ for (nIndex = 0; nIndex < pBucket->nEntries; ++nIndex) {
+ pBucketData = &pBucket->Entries[nIndex];
+ if (!strcmp(pBucketData->name,name)) {
+ return pBucketData;
+ }
+ }
+ }
+ return (Bucket_Data *)NULL;
+}
+
+/* Check if an address valid or not. That is,
+ check if it is in the lower -> upper range of a bucket.
+ It checks <= and >= so the lower end
+ and one-past on the upper end matches.
+*/
+Dwarf_Bool
+IsValidInBucketGroup(Bucket_Group *pBucketGroup,Dwarf_Addr address)
+{
+ Bucket *pBucket = 0;
+ Bucket_Data *pBucketData = 0;
+ int nIndex = 0;
+
+ assert(pBucketGroup);
+ /* Check the address is within the allowed limits */
+ if (address >= pBucketGroup->lower && address <= pBucketGroup->upper) {
+ for (pBucket = pBucketGroup->pHead; pBucket && pBucket->nEntries;
+ pBucket = pBucket->pNext) {
+
+ for (nIndex = 0; nIndex < pBucket->nEntries; ++nIndex) {
+ pBucketData = &pBucket->Entries[nIndex];
+ if (address >= pBucketData->low &&
+ address <= pBucketData->high) {
+ return TRUE;
+ }
+ }
+ }
+ }
+ return FALSE;
+}
+
+/* Reset limits for values in the Bucket Set */
+void
+ResetLimitsBucketSet(Bucket_Group *pBucketGroup)
+{
+ assert(pBucketGroup);
+ pBucketGroup->lower = 0;
+ pBucketGroup->upper = 0;
+}
+
+/* Limits are set only for ranges, so only in pRangesInfo. */
+void
+SetLimitsBucketGroup(Bucket_Group *pBucketGroup,
+ Dwarf_Addr lower,Dwarf_Addr upper)
+{
+ assert(pBucketGroup);
+ if (lower < upper) {
+ pBucketGroup->lower = lower;
+ pBucketGroup->upper = upper;
+ }
+}
+
+/* Traverse Bucket Set and execute a supplied function */
+static void
+ProcessBucketGroup(Bucket_Group *pBucketGroup,
+ void (*pFunction)(Bucket_Group *pBucketGroup,Bucket_Data *pBucketData))
+{
+ int nIndex = 0;
+ int nStart = 0;
+ Bucket *pBucket = 0;
+ Bucket_Data *pBucketData = 0;
+ Bucket_Data *pLower = 0;
+ Bucket_Data *pUpper = 0;
+ Dwarf_Bool bFound = FALSE;
+
+ /* Sanity checks */
+ assert(pBucketGroup);
+
+ /* No sentinels present; do nothing */
+ if (!pBucketGroup->pFirst || !pBucketGroup->pLast) {
+ return;
+ }
+
+ /* Find bucket that contains the first sentinel */
+ for (pBucket = pBucketGroup->pHead; pBucket && pBucket->nEntries;
+ pBucket = pBucket->pNext) {
+
+ pLower = &pBucket->Entries[0];
+ pUpper = &pBucket->Entries[pBucket->nEntries - 1];
+
+ /* Check if the first sentinel is in this bucket */
+ if (pBucketGroup->pFirst >= pLower && pBucketGroup->pFirst <= pUpper) {
+ /* Low sentinel is in this bucket */
+ bFound = TRUE;
+ break;
+ }
+ }
+
+ /* Invalid sentinel; do nothing */
+ if (!bFound) {
+ return;
+ }
+
+ /* Calculate index for first sentinel */
+ nStart = pBucketGroup->pFirst - pLower;
+
+ /* Start traversing from found bucket */
+ for (; pBucket && pBucket->nEntries; pBucket = pBucket->pNext) {
+ for (nIndex = nStart; nIndex < pBucket->nEntries; ++nIndex) {
+ pBucketData = &pBucket->Entries[nIndex];
+ if (pBucketData > pBucketGroup->pLast) {
+ return;
+ }
+ /* Call the user supplied function */
+ if (pFunction) {
+ pFunction(pBucketGroup,pBucketData);
+ }
+ }
+ /* For next bucket start with first entry */
+ nStart = 0;
+ }
+}
+
+/* Check if a given (lopc,hipc) are valid for a linkonce.
+ We pass in the linkonce (instead of
+ referencing the global pLinkonceInfo) as that means
+ searches for pLinkonceInfo find all the uses,
+ making understanding of the code a tiny bit easier.
+ The section name created is supposed to be the appropriate
+ linkonce section name.
+*/
+Dwarf_Bool IsValidInLinkonce(Bucket_Group *pLo,
+ const char *name,Dwarf_Addr lopc,Dwarf_Addr hipc)
+{
+#define SECTION_NAME_LEN 2048 /* Guessing a sensible length */
+ static char section_name[SECTION_NAME_LEN];
+ Bucket_Data *pBucketData = 0;
+ /* Since text is quite uniformly just this name, no need to get it
+ from elsewhere, though it will not work for non-elf. */
+ const char *lo_text = ".text";
+
+ /* Build the name that represents the linkonce section (.text).
+ This is not defined in DWARF so not correct for all
+ compilers. */
+ snprintf(section_name,sizeof(section_name),"%s%s",lo_text,name);
+
+ pBucketData = FindNameInBucketGroup(pLo,section_name);
+ if (pBucketData) {
+ if (lopc >= pBucketData->low && lopc <= pBucketData->high) {
+ if (hipc >= pBucketData->low && hipc <= pBucketData->high) {
+ return TRUE;
+ }
+ }
+ }
+ return FALSE;
+}
+
diff --git a/dwarfdump/checkutil.h b/dwarfdump/checkutil.h
new file mode 100644
index 0000000..d922b98
--- /dev/null
+++ b/dwarfdump/checkutil.h
@@ -0,0 +1,98 @@
+/*
+ Copyright (C) 2011 SN Systems Ltd. All Rights Reserved.
+ Portions Copyright (C) 2011 David Anderson. All Rights Reserved.
+
+ This program is free software; you can redistribute it and/or modify it
+ under the terms of version 2 of the GNU General Public License as
+ published by the Free Software Foundation.
+
+ This program is distributed in the hope that it would be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+ Further, this software is distributed without any warranty that it is
+ free of the rightful claim of any third person regarding infringement
+ or the like. Any license provided herein, whether implied or
+ otherwise, applies only to this software file. Patent licenses, if
+ any, provided herein do not apply to combinations of this program with
+ other software, or any other product whatsoever.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write the Free Software Foundation, Inc., 51
+ Franklin Street - Fifth Floor, Boston MA 02110-1301, USA.
+
+*/
+
+#ifndef CHECKUTIL_H
+#define CHECKUTIL_H
+
+/* Map information.
+ Depending on the specific functions used various
+ fields here are either used or ignored.
+
+*/
+typedef struct {
+ Dwarf_Bool bFlag; /* General flag */
+ const char *name; /* Generic name */
+ Dwarf_Addr key; /* Used for binary search, the key
+ is either a pc address or a DIE offset
+ depending on which bucket table is in use. */
+ Dwarf_Addr base; /* Used for base address */
+ Dwarf_Addr low; /* Used for Low PC */
+ Dwarf_Addr high; /* Used for High PC */
+} Bucket_Data;
+
+/* This groups Bucket_Data records into
+ a 'bucket' so that a single malloc creates
+ BUCKET_SIZE entries. The intent is to reduce
+ overhead (as compared to having next/previous
+ pointers in each Bucket_Data and mallocing
+ each Bucket_Data individually.
+*/
+
+#define BUCKET_SIZE 2040
+typedef struct bucket {
+ int nEntries;
+ Bucket_Data Entries[BUCKET_SIZE];
+ struct bucket *pNext;
+} Bucket;
+
+/* This Forms the head record of a list of Buckets.
+*/
+typedef struct {
+ int kind; /* Kind of bucket */
+ Dwarf_Addr lower; /* Lower value for data */
+ Dwarf_Addr upper; /* Upper value for data */
+ Bucket_Data *pFirst; /* First sentinel */
+ Bucket_Data *pLast; /* Last sentinel */
+ Bucket *pHead; /* First bucket in set */
+ Bucket *pTail; /* Last bucket in set */
+} Bucket_Group;
+
+Bucket_Group *AllocateBucketGroup(int kind);
+void ReleaseBucketGroup(Bucket_Group *pBucketGroup);
+void ResetBucketGroup(Bucket_Group *pBucketGroup);
+void ResetSentinelBucketGroup(Bucket_Group *pBucketGroup);
+
+void PrintBucketGroup(Bucket_Group *pBucketGroup,Dwarf_Bool bFull);
+
+void AddEntryIntoBucketGroup(Bucket_Group *pBucketGroup,
+ Dwarf_Addr key,Dwarf_Addr base,Dwarf_Addr low,Dwarf_Addr high,
+ const char *name, Dwarf_Bool bFlag);
+
+Dwarf_Bool DeleteKeyInBucketGroup(Bucket_Group *pBucketGroup,Dwarf_Addr key);
+
+Dwarf_Bool FindAddressInBucketGroup(Bucket_Group *pBucketGroup,Dwarf_Addr address);
+Bucket_Data *FindDataInBucketGroup(Bucket_Group *pBucketGroup,Dwarf_Addr key);
+Bucket_Data *FindKeyInBucketGroup(Bucket_Group *pBucketGroup,Dwarf_Addr key);
+Bucket_Data *FindNameInBucketGroup(Bucket_Group *pBucketGroup,char *name);
+
+Dwarf_Bool IsValidInBucketGroup(Bucket_Group *pBucketGroup,Dwarf_Addr pc);
+
+void ResetLimitsBucketSet(Bucket_Group *pBucketGroup);
+void SetLimitsBucketGroup(Bucket_Group *pBucketGroup,Dwarf_Addr lower,Dwarf_Addr upper);
+Dwarf_Bool IsValidInLinkonce(Bucket_Group *pLo,
+ const char *name,Dwarf_Addr lopc,Dwarf_Addr hipc);
+
+
+#endif /* CHECKUTIL_H */
diff --git a/dwarfdump/common.c b/dwarfdump/common.c
new file mode 100644
index 0000000..2788578
--- /dev/null
+++ b/dwarfdump/common.c
@@ -0,0 +1,88 @@
+/*
+ Copyright (C) 2008-2010 SN Systems. All Rights Reserved.
+ Portions Copyright (C) 2008-2011 David Anderson. All Rights Reserved.
+ Portions Copyright (C) 2011 SN Systems Ltd. . All Rights Reserved.
+
+ This program is free software; you can redistribute it and/or modify it
+ under the terms of version 2 of the GNU General Public License as
+ published by the Free Software Foundation.
+
+ This program is distributed in the hope that it would be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+ Further, this software is distributed without any warranty that it is
+ free of the rightful claim of any third person regarding infringement
+ or the like. Any license provided herein, whether implied or
+ otherwise, applies only to this software file. Patent licenses, if
+ any, provided herein do not apply to combinations of this program with
+ other software, or any other product whatsoever.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write the Free Software Foundation, Inc., 51
+ Franklin Street - Fifth Floor, Boston MA 02110-1301, USA.
+
+ Contact information: Silicon Graphics, Inc., 1500 Crittenden Lane,
+ Mountain View, CA 94043, or:
+
+ http://www.sgi.com
+
+ For further information regarding this notice, see:
+
+ http://oss.sgi.com/projects/GenInfo/NoticeExplan
+
+*/
+
+/* These do little except on Windows */
+
+#include "common.h"
+#include <stdio.h>
+#define DWARFDUMP_VERSION " Tue Apr 10 11:43:32 PDT 2012 "
+
+/* The Linux/Unix version does not want a version string to print
+ unless -V is on the command line. */
+void
+print_version_details(const char * name,int alwaysprint)
+{
+#ifdef WIN32
+# ifdef _DEBUG
+ char *acType = "Debug";
+# else
+ char *acType = "Release";
+# endif /* _DEBUG */
+ static char acVersion[32];
+ snprintf(acVersion,sizeof(acVersion),
+ "[%s %s %s]",__DATE__,__TIME__,acType);
+ printf("%s %s\n",name,acVersion);
+#else /* !WIN32 */
+ if(alwaysprint) {
+ printf("%s\n",DWARFDUMP_VERSION);
+ }
+#endif /* WIN32 */
+}
+
+
+void
+print_args(int argc, char *argv[])
+{
+#ifdef WIN32
+ int index = 1;
+ printf("Arguments: ");
+ for (index = 1; index < argc; ++index) {
+ printf("%s ",argv[index]);
+ }
+ printf("\n");
+#endif /* WIN32 */
+}
+
+void
+print_usage_message(const char *program_name, const char **text)
+{
+ unsigned i = 0;
+#ifndef WIN32
+ fprintf(stderr,"Usage: %s <options> <object file>\n", program_name);
+#endif
+ for (i = 0; *text[i]; ++i) {
+ fprintf(stderr,"%s\n", text[i]);
+ }
+}
diff --git a/dwarfdump/common.h b/dwarfdump/common.h
new file mode 100644
index 0000000..f1a598e
--- /dev/null
+++ b/dwarfdump/common.h
@@ -0,0 +1,42 @@
+/*
+ Copyright (C) 2009-2010 SN Systems. All Rights Reserved.
+ Portions Copyright (C) 2009-2010 David Anderson. All Rights Reserved.
+
+ This program is free software; you can redistribute it and/or modify it
+ under the terms of version 2 of the GNU General Public License as
+ published by the Free Software Foundation.
+
+ This program is distributed in the hope that it would be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+ Further, this software is distributed without any warranty that it is
+ free of the rightful claim of any third person regarding infringement
+ or the like. Any license provided herein, whether implied or
+ otherwise, applies only to this software file. Patent licenses, if
+ any, provided herein do not apply to combinations of this program with
+ other software, or any other product whatsoever.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write the Free Software Foundation, Inc., 51
+ Franklin Street - Fifth Floor, Boston MA 02110-1301, USA.
+
+ Contact information: Silicon Graphics, Inc., 1500 Crittenden Lane,
+ Mountain View, CA 94043, or:
+
+ http://www.sgi.com
+
+ For further information regarding this notice, see:
+
+ http://oss.sgi.com/projects/GenInfo/NoticeExplan
+
+*/
+
+#ifndef COMMON_INCLUDED_H
+#define COMMON_INCLUDED_H
+
+void print_args(int argc, char *argv[]);
+void print_version_details(const char *name, int alwaysprint);
+void print_usage_message(const char *program_name, const char **text);
+
+#endif /* COMMON_INCLUDED_H */
diff --git a/dwarfdump/config.h.in b/dwarfdump/config.h.in
new file mode 100644
index 0000000..a1a11db
--- /dev/null
+++ b/dwarfdump/config.h.in
@@ -0,0 +1,100 @@
+/* config.h.in. Generated from configure.in by autoheader. */
+
+/* Define to 1 if the elf64_getehdr function is in libelf.a. */
+#undef HAVE_ELF64_GETEHDR
+
+/* Define to 1 if the Elf64_Rel structure has r_info field. */
+#undef HAVE_ELF64_R_INFO
+
+/* Define to 1 if you have the <elf.h> header file. */
+#undef HAVE_ELF_H
+
+/* Define to 1 if you have the <getopt.h> header file. */
+#undef HAVE_GETOPT_H
+
+/* Define to 1 if you have the <inttypes.h> header file. */
+#undef HAVE_INTTYPES_H
+
+/* Define to 1 if you have the <libelf.h> header file. */
+#undef HAVE_LIBELF_H
+
+/* Define to 1 if you have the <libelf/libelf.h> header file. */
+#undef HAVE_LIBELF_LIBELF_H
+
+/* Define 1 if off64 is defined via libelf with GNU_SOURCE. */
+#undef HAVE_LIBELF_OFF64_OK
+
+/* Define to 1 if you have the <memory.h> header file. */
+#undef HAVE_MEMORY_H
+
+/* Define 1 if need nonstandard printf format for 64bit */
+#undef HAVE_NONSTANDARD_PRINTF_64_FORMAT
+
+/* Define 1 if plain libelf builds. */
+#undef HAVE_RAW_LIBELF_OK
+
+/* Define 1 if regex seems to be defined */
+#undef HAVE_REGEX
+
+/* Define to 1 if you have the <sgidefs.h> header file. */
+#undef HAVE_SGIDEFS_H
+
+/* Define 1 if we have the Windows specific header stdafx.h */
+#undef HAVE_STDAFX_H
+
+/* Define to 1 if you have the <stdint.h> header file. */
+#undef HAVE_STDINT_H
+
+/* Define to 1 if you have the <stdlib.h> header file. */
+#undef HAVE_STDLIB_H
+
+/* Define to 1 if you have the <strings.h> header file. */
+#undef HAVE_STRINGS_H
+
+/* Define to 1 if you have the <string.h> header file. */
+#undef HAVE_STRING_H
+
+/* Define to 1 if you have the <sys/stat.h> header file. */
+#undef HAVE_SYS_STAT_H
+
+/* Define to 1 if you have the <sys/types.h> header file. */
+#undef HAVE_SYS_TYPES_H
+
+/* Define 1 if the tsearch functions seem to be defined */
+#undef HAVE_TSEARCH
+
+/* Define to 1 if you have the <unistd.h> header file. */
+#undef HAVE_UNISTD_H
+
+/* See if __uint32_t is predefined in the compiler. */
+#undef HAVE___UINT32_T
+
+/* Define 1 if sys/types.h defines __uint32_t. */
+#undef HAVE___UINT32_T_IN_SYS_TYPES_H
+
+/* See if __uint64_t is predefined in the compiler. */
+#undef HAVE___UINT64_T
+
+/* Define to header that first defines elf. */
+#undef LOCATION_OF_LIBELFHEADER
+
+/* Define to the address where bug reports for this package should be sent. */
+#undef PACKAGE_BUGREPORT
+
+/* Define to the full name of this package. */
+#undef PACKAGE_NAME
+
+/* Define to the full name and version of this package. */
+#undef PACKAGE_STRING
+
+/* Define to the one symbol short name of this package. */
+#undef PACKAGE_TARNAME
+
+/* Define to the home page for this package. */
+#undef PACKAGE_URL
+
+/* Define to the version of this package. */
+#undef PACKAGE_VERSION
+
+/* Define to 1 if you have the ANSI C header files. */
+#undef STDC_HEADERS
diff --git a/dwarfdump/configure b/dwarfdump/configure
new file mode 100755
index 0000000..67ede72
--- /dev/null
+++ b/dwarfdump/configure
@@ -0,0 +1,5109 @@
+#! /bin/sh
+# Guess values for system-dependent variables and create Makefiles.
+# Generated by GNU Autoconf 2.68.
+#
+#
+# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001,
+# 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 Free Software
+# Foundation, Inc.
+#
+#
+# This configure script is free software; the Free Software Foundation
+# gives unlimited permission to copy, distribute and modify it.
+## -------------------- ##
+## M4sh Initialization. ##
+## -------------------- ##
+
+# Be more Bourne compatible
+DUALCASE=1; export DUALCASE # for MKS sh
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then :
+ emulate sh
+ NULLCMD=:
+ # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which
+ # is contrary to our usage. Disable this feature.
+ alias -g '${1+"$@"}'='"$@"'
+ setopt NO_GLOB_SUBST
+else
+ case `(set -o) 2>/dev/null` in #(
+ *posix*) :
+ set -o posix ;; #(
+ *) :
+ ;;
+esac
+fi
+
+
+as_nl='
+'
+export as_nl
+# Printing a long string crashes Solaris 7 /usr/bin/printf.
+as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'
+as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo
+as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo
+# Prefer a ksh shell builtin over an external printf program on Solaris,
+# but without wasting forks for bash or zsh.
+if test -z "$BASH_VERSION$ZSH_VERSION" \
+ && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then
+ as_echo='print -r --'
+ as_echo_n='print -rn --'
+elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then
+ as_echo='printf %s\n'
+ as_echo_n='printf %s'
+else
+ if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then
+ as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"'
+ as_echo_n='/usr/ucb/echo -n'
+ else
+ as_echo_body='eval expr "X$1" : "X\\(.*\\)"'
+ as_echo_n_body='eval
+ arg=$1;
+ case $arg in #(
+ *"$as_nl"*)
+ expr "X$arg" : "X\\(.*\\)$as_nl";
+ arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;;
+ esac;
+ expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl"
+ '
+ export as_echo_n_body
+ as_echo_n='sh -c $as_echo_n_body as_echo'
+ fi
+ export as_echo_body
+ as_echo='sh -c $as_echo_body as_echo'
+fi
+
+# The user is always right.
+if test "${PATH_SEPARATOR+set}" != set; then
+ PATH_SEPARATOR=:
+ (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && {
+ (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 ||
+ PATH_SEPARATOR=';'
+ }
+fi
+
+
+# IFS
+# We need space, tab and new line, in precisely that order. Quoting is
+# there to prevent editors from complaining about space-tab.
+# (If _AS_PATH_WALK were called with IFS unset, it would disable word
+# splitting by setting IFS to empty value.)
+IFS=" "" $as_nl"
+
+# Find who we are. Look in the path if we contain no directory separator.
+as_myself=
+case $0 in #((
+ *[\\/]* ) as_myself=$0 ;;
+ *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
+ done
+IFS=$as_save_IFS
+
+ ;;
+esac
+# We did not find ourselves, most probably we were run as `sh COMMAND'
+# in which case we are not to be found in the path.
+if test "x$as_myself" = x; then
+ as_myself=$0
+fi
+if test ! -f "$as_myself"; then
+ $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2
+ exit 1
+fi
+
+# Unset variables that we do not need and which cause bugs (e.g. in
+# pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1"
+# suppresses any "Segmentation fault" message there. '((' could
+# trigger a bug in pdksh 5.2.14.
+for as_var in BASH_ENV ENV MAIL MAILPATH
+do eval test x\${$as_var+set} = xset \
+ && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || :
+done
+PS1='$ '
+PS2='> '
+PS4='+ '
+
+# NLS nuisances.
+LC_ALL=C
+export LC_ALL
+LANGUAGE=C
+export LANGUAGE
+
+# CDPATH.
+(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
+
+if test "x$CONFIG_SHELL" = x; then
+ as_bourne_compatible="if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then :
+ emulate sh
+ NULLCMD=:
+ # Pre-4.2 versions of Zsh do word splitting on \${1+\"\$@\"}, which
+ # is contrary to our usage. Disable this feature.
+ alias -g '\${1+\"\$@\"}'='\"\$@\"'
+ setopt NO_GLOB_SUBST
+else
+ case \`(set -o) 2>/dev/null\` in #(
+ *posix*) :
+ set -o posix ;; #(
+ *) :
+ ;;
+esac
+fi
+"
+ as_required="as_fn_return () { (exit \$1); }
+as_fn_success () { as_fn_return 0; }
+as_fn_failure () { as_fn_return 1; }
+as_fn_ret_success () { return 0; }
+as_fn_ret_failure () { return 1; }
+
+exitcode=0
+as_fn_success || { exitcode=1; echo as_fn_success failed.; }
+as_fn_failure && { exitcode=1; echo as_fn_failure succeeded.; }
+as_fn_ret_success || { exitcode=1; echo as_fn_ret_success failed.; }
+as_fn_ret_failure && { exitcode=1; echo as_fn_ret_failure succeeded.; }
+if ( set x; as_fn_ret_success y && test x = \"\$1\" ); then :
+
+else
+ exitcode=1; echo positional parameters were not saved.
+fi
+test x\$exitcode = x0 || exit 1"
+ as_suggested=" as_lineno_1=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_1a=\$LINENO
+ as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO
+ eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" &&
+ test \"x\`expr \$as_lineno_1'\$as_run' + 1\`\" = \"x\$as_lineno_2'\$as_run'\"' || exit 1
+test \$(( 1 + 1 )) = 2 || exit 1"
+ if (eval "$as_required") 2>/dev/null; then :
+ as_have_required=yes
+else
+ as_have_required=no
+fi
+ if test x$as_have_required = xyes && (eval "$as_suggested") 2>/dev/null; then :
+
+else
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+as_found=false
+for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ as_found=:
+ case $as_dir in #(
+ /*)
+ for as_base in sh bash ksh sh5; do
+ # Try only shells that exist, to save several forks.
+ as_shell=$as_dir/$as_base
+ if { test -f "$as_shell" || test -f "$as_shell.exe"; } &&
+ { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$as_shell"; } 2>/dev/null; then :
+ CONFIG_SHELL=$as_shell as_have_required=yes
+ if { $as_echo "$as_bourne_compatible""$as_suggested" | as_run=a "$as_shell"; } 2>/dev/null; then :
+ break 2
+fi
+fi
+ done;;
+ esac
+ as_found=false
+done
+$as_found || { if { test -f "$SHELL" || test -f "$SHELL.exe"; } &&
+ { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$SHELL"; } 2>/dev/null; then :
+ CONFIG_SHELL=$SHELL as_have_required=yes
+fi; }
+IFS=$as_save_IFS
+
+
+ if test "x$CONFIG_SHELL" != x; then :
+ # We cannot yet assume a decent shell, so we have to provide a
+ # neutralization value for shells without unset; and this also
+ # works around shells that cannot unset nonexistent variables.
+ # Preserve -v and -x to the replacement shell.
+ BASH_ENV=/dev/null
+ ENV=/dev/null
+ (unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV
+ export CONFIG_SHELL
+ case $- in # ((((
+ *v*x* | *x*v* ) as_opts=-vx ;;
+ *v* ) as_opts=-v ;;
+ *x* ) as_opts=-x ;;
+ * ) as_opts= ;;
+ esac
+ exec "$CONFIG_SHELL" $as_opts "$as_myself" ${1+"$@"}
+fi
+
+ if test x$as_have_required = xno; then :
+ $as_echo "$0: This script requires a shell more modern than all"
+ $as_echo "$0: the shells that I found on your system."
+ if test x${ZSH_VERSION+set} = xset ; then
+ $as_echo "$0: In particular, zsh $ZSH_VERSION has bugs and should"
+ $as_echo "$0: be upgraded to zsh 4.3.4 or later."
+ else
+ $as_echo "$0: Please tell bug-autoconf@gnu.org about your system,
+$0: including any error possibly output before this
+$0: message. Then install a modern shell, or manually run
+$0: the script under such a shell if you do have one."
+ fi
+ exit 1
+fi
+fi
+fi
+SHELL=${CONFIG_SHELL-/bin/sh}
+export SHELL
+# Unset more variables known to interfere with behavior of common tools.
+CLICOLOR_FORCE= GREP_OPTIONS=
+unset CLICOLOR_FORCE GREP_OPTIONS
+
+## --------------------- ##
+## M4sh Shell Functions. ##
+## --------------------- ##
+# as_fn_unset VAR
+# ---------------
+# Portably unset VAR.
+as_fn_unset ()
+{
+ { eval $1=; unset $1;}
+}
+as_unset=as_fn_unset
+
+# as_fn_set_status STATUS
+# -----------------------
+# Set $? to STATUS, without forking.
+as_fn_set_status ()
+{
+ return $1
+} # as_fn_set_status
+
+# as_fn_exit STATUS
+# -----------------
+# Exit the shell with STATUS, even in a "trap 0" or "set -e" context.
+as_fn_exit ()
+{
+ set +e
+ as_fn_set_status $1
+ exit $1
+} # as_fn_exit
+
+# as_fn_mkdir_p
+# -------------
+# Create "$as_dir" as a directory, including parents if necessary.
+as_fn_mkdir_p ()
+{
+
+ case $as_dir in #(
+ -*) as_dir=./$as_dir;;
+ esac
+ test -d "$as_dir" || eval $as_mkdir_p || {
+ as_dirs=
+ while :; do
+ case $as_dir in #(
+ *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'(
+ *) as_qdir=$as_dir;;
+ esac
+ as_dirs="'$as_qdir' $as_dirs"
+ as_dir=`$as_dirname -- "$as_dir" ||
+$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$as_dir" : 'X\(//\)[^/]' \| \
+ X"$as_dir" : 'X\(//\)$' \| \
+ X"$as_dir" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$as_dir" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)[^/].*/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\).*/{
+ s//\1/
+ q
+ }
+ s/.*/./; q'`
+ test -d "$as_dir" && break
+ done
+ test -z "$as_dirs" || eval "mkdir $as_dirs"
+ } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir"
+
+
+} # as_fn_mkdir_p
+# as_fn_append VAR VALUE
+# ----------------------
+# Append the text in VALUE to the end of the definition contained in VAR. Take
+# advantage of any shell optimizations that allow amortized linear growth over
+# repeated appends, instead of the typical quadratic growth present in naive
+# implementations.
+if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then :
+ eval 'as_fn_append ()
+ {
+ eval $1+=\$2
+ }'
+else
+ as_fn_append ()
+ {
+ eval $1=\$$1\$2
+ }
+fi # as_fn_append
+
+# as_fn_arith ARG...
+# ------------------
+# Perform arithmetic evaluation on the ARGs, and store the result in the
+# global $as_val. Take advantage of shells that can avoid forks. The arguments
+# must be portable across $(()) and expr.
+if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then :
+ eval 'as_fn_arith ()
+ {
+ as_val=$(( $* ))
+ }'
+else
+ as_fn_arith ()
+ {
+ as_val=`expr "$@" || test $? -eq 1`
+ }
+fi # as_fn_arith
+
+
+# as_fn_error STATUS ERROR [LINENO LOG_FD]
+# ----------------------------------------
+# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are
+# provided, also output the error to LOG_FD, referencing LINENO. Then exit the
+# script with STATUS, using 1 if that was 0.
+as_fn_error ()
+{
+ as_status=$1; test $as_status -eq 0 && as_status=1
+ if test "$4"; then
+ as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4
+ fi
+ $as_echo "$as_me: error: $2" >&2
+ as_fn_exit $as_status
+} # as_fn_error
+
+if expr a : '\(a\)' >/dev/null 2>&1 &&
+ test "X`expr 00001 : '.*\(...\)'`" = X001; then
+ as_expr=expr
+else
+ as_expr=false
+fi
+
+if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then
+ as_basename=basename
+else
+ as_basename=false
+fi
+
+if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then
+ as_dirname=dirname
+else
+ as_dirname=false
+fi
+
+as_me=`$as_basename -- "$0" ||
+$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
+ X"$0" : 'X\(//\)$' \| \
+ X"$0" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X/"$0" |
+ sed '/^.*\/\([^/][^/]*\)\/*$/{
+ s//\1/
+ q
+ }
+ /^X\/\(\/\/\)$/{
+ s//\1/
+ q
+ }
+ /^X\/\(\/\).*/{
+ s//\1/
+ q
+ }
+ s/.*/./; q'`
+
+# Avoid depending upon Character Ranges.
+as_cr_letters='abcdefghijklmnopqrstuvwxyz'
+as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
+as_cr_Letters=$as_cr_letters$as_cr_LETTERS
+as_cr_digits='0123456789'
+as_cr_alnum=$as_cr_Letters$as_cr_digits
+
+
+ as_lineno_1=$LINENO as_lineno_1a=$LINENO
+ as_lineno_2=$LINENO as_lineno_2a=$LINENO
+ eval 'test "x$as_lineno_1'$as_run'" != "x$as_lineno_2'$as_run'" &&
+ test "x`expr $as_lineno_1'$as_run' + 1`" = "x$as_lineno_2'$as_run'"' || {
+ # Blame Lee E. McMahon (1931-1989) for sed's syntax. :-)
+ sed -n '
+ p
+ /[$]LINENO/=
+ ' <$as_myself |
+ sed '
+ s/[$]LINENO.*/&-/
+ t lineno
+ b
+ :lineno
+ N
+ :loop
+ s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/
+ t loop
+ s/-\n.*//
+ ' >$as_me.lineno &&
+ chmod +x "$as_me.lineno" ||
+ { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; }
+
+ # Don't try to exec as it changes $[0], causing all sort of problems
+ # (the dirname of $[0] is not the place where we might find the
+ # original and so on. Autoconf is especially sensitive to this).
+ . "./$as_me.lineno"
+ # Exit status is that of the last command.
+ exit
+}
+
+ECHO_C= ECHO_N= ECHO_T=
+case `echo -n x` in #(((((
+-n*)
+ case `echo 'xy\c'` in
+ *c*) ECHO_T=' ';; # ECHO_T is single tab character.
+ xy) ECHO_C='\c';;
+ *) echo `echo ksh88 bug on AIX 6.1` > /dev/null
+ ECHO_T=' ';;
+ esac;;
+*)
+ ECHO_N='-n';;
+esac
+
+rm -f conf$$ conf$$.exe conf$$.file
+if test -d conf$$.dir; then
+ rm -f conf$$.dir/conf$$.file
+else
+ rm -f conf$$.dir
+ mkdir conf$$.dir 2>/dev/null
+fi
+if (echo >conf$$.file) 2>/dev/null; then
+ if ln -s conf$$.file conf$$ 2>/dev/null; then
+ as_ln_s='ln -s'
+ # ... but there are two gotchas:
+ # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail.
+ # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable.
+ # In both cases, we have to default to `cp -p'.
+ ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe ||
+ as_ln_s='cp -p'
+ elif ln conf$$.file conf$$ 2>/dev/null; then
+ as_ln_s=ln
+ else
+ as_ln_s='cp -p'
+ fi
+else
+ as_ln_s='cp -p'
+fi
+rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file
+rmdir conf$$.dir 2>/dev/null
+
+if mkdir -p . 2>/dev/null; then
+ as_mkdir_p='mkdir -p "$as_dir"'
+else
+ test -d ./-p && rmdir ./-p
+ as_mkdir_p=false
+fi
+
+if test -x / >/dev/null 2>&1; then
+ as_test_x='test -x'
+else
+ if ls -dL / >/dev/null 2>&1; then
+ as_ls_L_option=L
+ else
+ as_ls_L_option=
+ fi
+ as_test_x='
+ eval sh -c '\''
+ if test -d "$1"; then
+ test -d "$1/.";
+ else
+ case $1 in #(
+ -*)set "./$1";;
+ esac;
+ case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in #((
+ ???[sx]*):;;*)false;;esac;fi
+ '\'' sh
+ '
+fi
+as_executable_p=$as_test_x
+
+# Sed expression to map a string onto a valid CPP name.
+as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"
+
+# Sed expression to map a string onto a valid variable name.
+as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'"
+
+
+test -n "$DJDIR" || exec 7<&0 </dev/null
+exec 6>&1
+
+# Name of the host.
+# hostname on some systems (SVR3.2, old GNU/Linux) returns a bogus exit status,
+# so uname gets run too.
+ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q`
+
+#
+# Initializations.
+#
+ac_default_prefix=/usr/local
+ac_clean_files=
+ac_config_libobj_dir=.
+LIBOBJS=
+cross_compiling=no
+subdirs=
+MFLAGS=
+MAKEFLAGS=
+
+# Identity of this package.
+PACKAGE_NAME=
+PACKAGE_TARNAME=
+PACKAGE_VERSION=
+PACKAGE_STRING=
+PACKAGE_BUGREPORT=
+PACKAGE_URL=
+
+ac_unique_file="dwarfdump.c"
+# Factoring default headers for most tests.
+ac_includes_default="\
+#include <stdio.h>
+#ifdef HAVE_SYS_TYPES_H
+# include <sys/types.h>
+#endif
+#ifdef HAVE_SYS_STAT_H
+# include <sys/stat.h>
+#endif
+#ifdef STDC_HEADERS
+# include <stdlib.h>
+# include <stddef.h>
+#else
+# ifdef HAVE_STDLIB_H
+# include <stdlib.h>
+# endif
+#endif
+#ifdef HAVE_STRING_H
+# if !defined STDC_HEADERS && defined HAVE_MEMORY_H
+# include <memory.h>
+# endif
+# include <string.h>
+#endif
+#ifdef HAVE_STRINGS_H
+# include <strings.h>
+#endif
+#ifdef HAVE_INTTYPES_H
+# include <inttypes.h>
+#endif
+#ifdef HAVE_STDINT_H
+# include <stdint.h>
+#endif
+#ifdef HAVE_UNISTD_H
+# include <unistd.h>
+#endif"
+
+ac_subst_vars='LTLIBOBJS
+LIBOBJS
+AR
+RANLIB
+INSTALL_DATA
+INSTALL_SCRIPT
+INSTALL_PROGRAM
+EGREP
+GREP
+CPP
+OBJEXT
+EXEEXT
+ac_ct_CC
+CPPFLAGS
+LDFLAGS
+CFLAGS
+CC
+target_alias
+host_alias
+build_alias
+LIBS
+ECHO_T
+ECHO_N
+ECHO_C
+DEFS
+mandir
+localedir
+libdir
+psdir
+pdfdir
+dvidir
+htmldir
+infodir
+docdir
+oldincludedir
+includedir
+localstatedir
+sharedstatedir
+sysconfdir
+datadir
+datarootdir
+libexecdir
+sbindir
+bindir
+program_transform_name
+prefix
+exec_prefix
+PACKAGE_URL
+PACKAGE_BUGREPORT
+PACKAGE_STRING
+PACKAGE_VERSION
+PACKAGE_TARNAME
+PACKAGE_NAME
+PATH_SEPARATOR
+SHELL'
+ac_subst_files=''
+ac_user_opts='
+enable_option_checking
+enable_nonstandardprintf
+'
+ ac_precious_vars='build_alias
+host_alias
+target_alias
+CC
+CFLAGS
+LDFLAGS
+LIBS
+CPPFLAGS
+CPP'
+
+
+# Initialize some variables set by options.
+ac_init_help=
+ac_init_version=false
+ac_unrecognized_opts=
+ac_unrecognized_sep=
+# The variables have the same names as the options, with
+# dashes changed to underlines.
+cache_file=/dev/null
+exec_prefix=NONE
+no_create=
+no_recursion=
+prefix=NONE
+program_prefix=NONE
+program_suffix=NONE
+program_transform_name=s,x,x,
+silent=
+site=
+srcdir=
+verbose=
+x_includes=NONE
+x_libraries=NONE
+
+# Installation directory options.
+# These are left unexpanded so users can "make install exec_prefix=/foo"
+# and all the variables that are supposed to be based on exec_prefix
+# by default will actually change.
+# Use braces instead of parens because sh, perl, etc. also accept them.
+# (The list follows the same order as the GNU Coding Standards.)
+bindir='${exec_prefix}/bin'
+sbindir='${exec_prefix}/sbin'
+libexecdir='${exec_prefix}/libexec'
+datarootdir='${prefix}/share'
+datadir='${datarootdir}'
+sysconfdir='${prefix}/etc'
+sharedstatedir='${prefix}/com'
+localstatedir='${prefix}/var'
+includedir='${prefix}/include'
+oldincludedir='/usr/include'
+docdir='${datarootdir}/doc/${PACKAGE}'
+infodir='${datarootdir}/info'
+htmldir='${docdir}'
+dvidir='${docdir}'
+pdfdir='${docdir}'
+psdir='${docdir}'
+libdir='${exec_prefix}/lib'
+localedir='${datarootdir}/locale'
+mandir='${datarootdir}/man'
+
+ac_prev=
+ac_dashdash=
+for ac_option
+do
+ # If the previous option needs an argument, assign it.
+ if test -n "$ac_prev"; then
+ eval $ac_prev=\$ac_option
+ ac_prev=
+ continue
+ fi
+
+ case $ac_option in
+ *=?*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;;
+ *=) ac_optarg= ;;
+ *) ac_optarg=yes ;;
+ esac
+
+ # Accept the important Cygnus configure options, so we can diagnose typos.
+
+ case $ac_dashdash$ac_option in
+ --)
+ ac_dashdash=yes ;;
+
+ -bindir | --bindir | --bindi | --bind | --bin | --bi)
+ ac_prev=bindir ;;
+ -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*)
+ bindir=$ac_optarg ;;
+
+ -build | --build | --buil | --bui | --bu)
+ ac_prev=build_alias ;;
+ -build=* | --build=* | --buil=* | --bui=* | --bu=*)
+ build_alias=$ac_optarg ;;
+
+ -cache-file | --cache-file | --cache-fil | --cache-fi \
+ | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c)
+ ac_prev=cache_file ;;
+ -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \
+ | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*)
+ cache_file=$ac_optarg ;;
+
+ --config-cache | -C)
+ cache_file=config.cache ;;
+
+ -datadir | --datadir | --datadi | --datad)
+ ac_prev=datadir ;;
+ -datadir=* | --datadir=* | --datadi=* | --datad=*)
+ datadir=$ac_optarg ;;
+
+ -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \
+ | --dataroo | --dataro | --datar)
+ ac_prev=datarootdir ;;
+ -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \
+ | --dataroot=* | --dataroo=* | --dataro=* | --datar=*)
+ datarootdir=$ac_optarg ;;
+
+ -disable-* | --disable-*)
+ ac_useropt=`expr "x$ac_option" : 'x-*disable-\(.*\)'`
+ # Reject names that are not valid shell variable names.
+ expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
+ as_fn_error $? "invalid feature name: $ac_useropt"
+ ac_useropt_orig=$ac_useropt
+ ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
+ case $ac_user_opts in
+ *"
+"enable_$ac_useropt"
+"*) ;;
+ *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--disable-$ac_useropt_orig"
+ ac_unrecognized_sep=', ';;
+ esac
+ eval enable_$ac_useropt=no ;;
+
+ -docdir | --docdir | --docdi | --doc | --do)
+ ac_prev=docdir ;;
+ -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*)
+ docdir=$ac_optarg ;;
+
+ -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv)
+ ac_prev=dvidir ;;
+ -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*)
+ dvidir=$ac_optarg ;;
+
+ -enable-* | --enable-*)
+ ac_useropt=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'`
+ # Reject names that are not valid shell variable names.
+ expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
+ as_fn_error $? "invalid feature name: $ac_useropt"
+ ac_useropt_orig=$ac_useropt
+ ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
+ case $ac_user_opts in
+ *"
+"enable_$ac_useropt"
+"*) ;;
+ *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--enable-$ac_useropt_orig"
+ ac_unrecognized_sep=', ';;
+ esac
+ eval enable_$ac_useropt=\$ac_optarg ;;
+
+ -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \
+ | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \
+ | --exec | --exe | --ex)
+ ac_prev=exec_prefix ;;
+ -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \
+ | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \
+ | --exec=* | --exe=* | --ex=*)
+ exec_prefix=$ac_optarg ;;
+
+ -gas | --gas | --ga | --g)
+ # Obsolete; use --with-gas.
+ with_gas=yes ;;
+
+ -help | --help | --hel | --he | -h)
+ ac_init_help=long ;;
+ -help=r* | --help=r* | --hel=r* | --he=r* | -hr*)
+ ac_init_help=recursive ;;
+ -help=s* | --help=s* | --hel=s* | --he=s* | -hs*)
+ ac_init_help=short ;;
+
+ -host | --host | --hos | --ho)
+ ac_prev=host_alias ;;
+ -host=* | --host=* | --hos=* | --ho=*)
+ host_alias=$ac_optarg ;;
+
+ -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht)
+ ac_prev=htmldir ;;
+ -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \
+ | --ht=*)
+ htmldir=$ac_optarg ;;
+
+ -includedir | --includedir | --includedi | --included | --include \
+ | --includ | --inclu | --incl | --inc)
+ ac_prev=includedir ;;
+ -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \
+ | --includ=* | --inclu=* | --incl=* | --inc=*)
+ includedir=$ac_optarg ;;
+
+ -infodir | --infodir | --infodi | --infod | --info | --inf)
+ ac_prev=infodir ;;
+ -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*)
+ infodir=$ac_optarg ;;
+
+ -libdir | --libdir | --libdi | --libd)
+ ac_prev=libdir ;;
+ -libdir=* | --libdir=* | --libdi=* | --libd=*)
+ libdir=$ac_optarg ;;
+
+ -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \
+ | --libexe | --libex | --libe)
+ ac_prev=libexecdir ;;
+ -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \
+ | --libexe=* | --libex=* | --libe=*)
+ libexecdir=$ac_optarg ;;
+
+ -localedir | --localedir | --localedi | --localed | --locale)
+ ac_prev=localedir ;;
+ -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*)
+ localedir=$ac_optarg ;;
+
+ -localstatedir | --localstatedir | --localstatedi | --localstated \
+ | --localstate | --localstat | --localsta | --localst | --locals)
+ ac_prev=localstatedir ;;
+ -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \
+ | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*)
+ localstatedir=$ac_optarg ;;
+
+ -mandir | --mandir | --mandi | --mand | --man | --ma | --m)
+ ac_prev=mandir ;;
+ -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*)
+ mandir=$ac_optarg ;;
+
+ -nfp | --nfp | --nf)
+ # Obsolete; use --without-fp.
+ with_fp=no ;;
+
+ -no-create | --no-create | --no-creat | --no-crea | --no-cre \
+ | --no-cr | --no-c | -n)
+ no_create=yes ;;
+
+ -no-recursion | --no-recursion | --no-recursio | --no-recursi \
+ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r)
+ no_recursion=yes ;;
+
+ -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \
+ | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \
+ | --oldin | --oldi | --old | --ol | --o)
+ ac_prev=oldincludedir ;;
+ -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \
+ | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \
+ | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*)
+ oldincludedir=$ac_optarg ;;
+
+ -prefix | --prefix | --prefi | --pref | --pre | --pr | --p)
+ ac_prev=prefix ;;
+ -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*)
+ prefix=$ac_optarg ;;
+
+ -program-prefix | --program-prefix | --program-prefi | --program-pref \
+ | --program-pre | --program-pr | --program-p)
+ ac_prev=program_prefix ;;
+ -program-prefix=* | --program-prefix=* | --program-prefi=* \
+ | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*)
+ program_prefix=$ac_optarg ;;
+
+ -program-suffix | --program-suffix | --program-suffi | --program-suff \
+ | --program-suf | --program-su | --program-s)
+ ac_prev=program_suffix ;;
+ -program-suffix=* | --program-suffix=* | --program-suffi=* \
+ | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*)
+ program_suffix=$ac_optarg ;;
+
+ -program-transform-name | --program-transform-name \
+ | --program-transform-nam | --program-transform-na \
+ | --program-transform-n | --program-transform- \
+ | --program-transform | --program-transfor \
+ | --program-transfo | --program-transf \
+ | --program-trans | --program-tran \
+ | --progr-tra | --program-tr | --program-t)
+ ac_prev=program_transform_name ;;
+ -program-transform-name=* | --program-transform-name=* \
+ | --program-transform-nam=* | --program-transform-na=* \
+ | --program-transform-n=* | --program-transform-=* \
+ | --program-transform=* | --program-transfor=* \
+ | --program-transfo=* | --program-transf=* \
+ | --program-trans=* | --program-tran=* \
+ | --progr-tra=* | --program-tr=* | --program-t=*)
+ program_transform_name=$ac_optarg ;;
+
+ -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd)
+ ac_prev=pdfdir ;;
+ -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*)
+ pdfdir=$ac_optarg ;;
+
+ -psdir | --psdir | --psdi | --psd | --ps)
+ ac_prev=psdir ;;
+ -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*)
+ psdir=$ac_optarg ;;
+
+ -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+ | -silent | --silent | --silen | --sile | --sil)
+ silent=yes ;;
+
+ -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)
+ ac_prev=sbindir ;;
+ -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \
+ | --sbi=* | --sb=*)
+ sbindir=$ac_optarg ;;
+
+ -sharedstatedir | --sharedstatedir | --sharedstatedi \
+ | --sharedstated | --sharedstate | --sharedstat | --sharedsta \
+ | --sharedst | --shareds | --shared | --share | --shar \
+ | --sha | --sh)
+ ac_prev=sharedstatedir ;;
+ -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \
+ | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \
+ | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \
+ | --sha=* | --sh=*)
+ sharedstatedir=$ac_optarg ;;
+
+ -site | --site | --sit)
+ ac_prev=site ;;
+ -site=* | --site=* | --sit=*)
+ site=$ac_optarg ;;
+
+ -srcdir | --srcdir | --srcdi | --srcd | --src | --sr)
+ ac_prev=srcdir ;;
+ -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*)
+ srcdir=$ac_optarg ;;
+
+ -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \
+ | --syscon | --sysco | --sysc | --sys | --sy)
+ ac_prev=sysconfdir ;;
+ -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \
+ | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*)
+ sysconfdir=$ac_optarg ;;
+
+ -target | --target | --targe | --targ | --tar | --ta | --t)
+ ac_prev=target_alias ;;
+ -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*)
+ target_alias=$ac_optarg ;;
+
+ -v | -verbose | --verbose | --verbos | --verbo | --verb)
+ verbose=yes ;;
+
+ -version | --version | --versio | --versi | --vers | -V)
+ ac_init_version=: ;;
+
+ -with-* | --with-*)
+ ac_useropt=`expr "x$ac_option" : 'x-*with-\([^=]*\)'`
+ # Reject names that are not valid shell variable names.
+ expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
+ as_fn_error $? "invalid package name: $ac_useropt"
+ ac_useropt_orig=$ac_useropt
+ ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
+ case $ac_user_opts in
+ *"
+"with_$ac_useropt"
+"*) ;;
+ *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--with-$ac_useropt_orig"
+ ac_unrecognized_sep=', ';;
+ esac
+ eval with_$ac_useropt=\$ac_optarg ;;
+
+ -without-* | --without-*)
+ ac_useropt=`expr "x$ac_option" : 'x-*without-\(.*\)'`
+ # Reject names that are not valid shell variable names.
+ expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
+ as_fn_error $? "invalid package name: $ac_useropt"
+ ac_useropt_orig=$ac_useropt
+ ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
+ case $ac_user_opts in
+ *"
+"with_$ac_useropt"
+"*) ;;
+ *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--without-$ac_useropt_orig"
+ ac_unrecognized_sep=', ';;
+ esac
+ eval with_$ac_useropt=no ;;
+
+ --x)
+ # Obsolete; use --with-x.
+ with_x=yes ;;
+
+ -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \
+ | --x-incl | --x-inc | --x-in | --x-i)
+ ac_prev=x_includes ;;
+ -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \
+ | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*)
+ x_includes=$ac_optarg ;;
+
+ -x-libraries | --x-libraries | --x-librarie | --x-librari \
+ | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l)
+ ac_prev=x_libraries ;;
+ -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \
+ | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*)
+ x_libraries=$ac_optarg ;;
+
+ -*) as_fn_error $? "unrecognized option: \`$ac_option'
+Try \`$0 --help' for more information"
+ ;;
+
+ *=*)
+ ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='`
+ # Reject names that are not valid shell variable names.
+ case $ac_envvar in #(
+ '' | [0-9]* | *[!_$as_cr_alnum]* )
+ as_fn_error $? "invalid variable name: \`$ac_envvar'" ;;
+ esac
+ eval $ac_envvar=\$ac_optarg
+ export $ac_envvar ;;
+
+ *)
+ # FIXME: should be removed in autoconf 3.0.
+ $as_echo "$as_me: WARNING: you should use --build, --host, --target" >&2
+ expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null &&
+ $as_echo "$as_me: WARNING: invalid host type: $ac_option" >&2
+ : "${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}"
+ ;;
+
+ esac
+done
+
+if test -n "$ac_prev"; then
+ ac_option=--`echo $ac_prev | sed 's/_/-/g'`
+ as_fn_error $? "missing argument to $ac_option"
+fi
+
+if test -n "$ac_unrecognized_opts"; then
+ case $enable_option_checking in
+ no) ;;
+ fatal) as_fn_error $? "unrecognized options: $ac_unrecognized_opts" ;;
+ *) $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;;
+ esac
+fi
+
+# Check all directory arguments for consistency.
+for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \
+ datadir sysconfdir sharedstatedir localstatedir includedir \
+ oldincludedir docdir infodir htmldir dvidir pdfdir psdir \
+ libdir localedir mandir
+do
+ eval ac_val=\$$ac_var
+ # Remove trailing slashes.
+ case $ac_val in
+ */ )
+ ac_val=`expr "X$ac_val" : 'X\(.*[^/]\)' \| "X$ac_val" : 'X\(.*\)'`
+ eval $ac_var=\$ac_val;;
+ esac
+ # Be sure to have absolute directory names.
+ case $ac_val in
+ [\\/$]* | ?:[\\/]* ) continue;;
+ NONE | '' ) case $ac_var in *prefix ) continue;; esac;;
+ esac
+ as_fn_error $? "expected an absolute directory name for --$ac_var: $ac_val"
+done
+
+# There might be people who depend on the old broken behavior: `$host'
+# used to hold the argument of --host etc.
+# FIXME: To remove some day.
+build=$build_alias
+host=$host_alias
+target=$target_alias
+
+# FIXME: To remove some day.
+if test "x$host_alias" != x; then
+ if test "x$build_alias" = x; then
+ cross_compiling=maybe
+ $as_echo "$as_me: WARNING: if you wanted to set the --build type, don't use --host.
+ If a cross compiler is detected then cross compile mode will be used" >&2
+ elif test "x$build_alias" != "x$host_alias"; then
+ cross_compiling=yes
+ fi
+fi
+
+ac_tool_prefix=
+test -n "$host_alias" && ac_tool_prefix=$host_alias-
+
+test "$silent" = yes && exec 6>/dev/null
+
+
+ac_pwd=`pwd` && test -n "$ac_pwd" &&
+ac_ls_di=`ls -di .` &&
+ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` ||
+ as_fn_error $? "working directory cannot be determined"
+test "X$ac_ls_di" = "X$ac_pwd_ls_di" ||
+ as_fn_error $? "pwd does not report name of working directory"
+
+
+# Find the source files, if location was not specified.
+if test -z "$srcdir"; then
+ ac_srcdir_defaulted=yes
+ # Try the directory containing this script, then the parent directory.
+ ac_confdir=`$as_dirname -- "$as_myself" ||
+$as_expr X"$as_myself" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$as_myself" : 'X\(//\)[^/]' \| \
+ X"$as_myself" : 'X\(//\)$' \| \
+ X"$as_myself" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$as_myself" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)[^/].*/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\).*/{
+ s//\1/
+ q
+ }
+ s/.*/./; q'`
+ srcdir=$ac_confdir
+ if test ! -r "$srcdir/$ac_unique_file"; then
+ srcdir=..
+ fi
+else
+ ac_srcdir_defaulted=no
+fi
+if test ! -r "$srcdir/$ac_unique_file"; then
+ test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .."
+ as_fn_error $? "cannot find sources ($ac_unique_file) in $srcdir"
+fi
+ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work"
+ac_abs_confdir=`(
+ cd "$srcdir" && test -r "./$ac_unique_file" || as_fn_error $? "$ac_msg"
+ pwd)`
+# When building in place, set srcdir=.
+if test "$ac_abs_confdir" = "$ac_pwd"; then
+ srcdir=.
+fi
+# Remove unnecessary trailing slashes from srcdir.
+# Double slashes in file names in object file debugging info
+# mess up M-x gdb in Emacs.
+case $srcdir in
+*/) srcdir=`expr "X$srcdir" : 'X\(.*[^/]\)' \| "X$srcdir" : 'X\(.*\)'`;;
+esac
+for ac_var in $ac_precious_vars; do
+ eval ac_env_${ac_var}_set=\${${ac_var}+set}
+ eval ac_env_${ac_var}_value=\$${ac_var}
+ eval ac_cv_env_${ac_var}_set=\${${ac_var}+set}
+ eval ac_cv_env_${ac_var}_value=\$${ac_var}
+done
+
+#
+# Report the --help message.
+#
+if test "$ac_init_help" = "long"; then
+ # Omit some internal or obsolete options to make the list less imposing.
+ # This message is too long to be a string in the A/UX 3.1 sh.
+ cat <<_ACEOF
+\`configure' configures this package to adapt to many kinds of systems.
+
+Usage: $0 [OPTION]... [VAR=VALUE]...
+
+To assign environment variables (e.g., CC, CFLAGS...), specify them as
+VAR=VALUE. See below for descriptions of some of the useful variables.
+
+Defaults for the options are specified in brackets.
+
+Configuration:
+ -h, --help display this help and exit
+ --help=short display options specific to this package
+ --help=recursive display the short help of all the included packages
+ -V, --version display version information and exit
+ -q, --quiet, --silent do not print \`checking ...' messages
+ --cache-file=FILE cache test results in FILE [disabled]
+ -C, --config-cache alias for \`--cache-file=config.cache'
+ -n, --no-create do not create output files
+ --srcdir=DIR find the sources in DIR [configure dir or \`..']
+
+Installation directories:
+ --prefix=PREFIX install architecture-independent files in PREFIX
+ [$ac_default_prefix]
+ --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX
+ [PREFIX]
+
+By default, \`make install' will install all the files in
+\`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify
+an installation prefix other than \`$ac_default_prefix' using \`--prefix',
+for instance \`--prefix=\$HOME'.
+
+For better control, use the options below.
+
+Fine tuning of the installation directories:
+ --bindir=DIR user executables [EPREFIX/bin]
+ --sbindir=DIR system admin executables [EPREFIX/sbin]
+ --libexecdir=DIR program executables [EPREFIX/libexec]
+ --sysconfdir=DIR read-only single-machine data [PREFIX/etc]
+ --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com]
+ --localstatedir=DIR modifiable single-machine data [PREFIX/var]
+ --libdir=DIR object code libraries [EPREFIX/lib]
+ --includedir=DIR C header files [PREFIX/include]
+ --oldincludedir=DIR C header files for non-gcc [/usr/include]
+ --datarootdir=DIR read-only arch.-independent data root [PREFIX/share]
+ --datadir=DIR read-only architecture-independent data [DATAROOTDIR]
+ --infodir=DIR info documentation [DATAROOTDIR/info]
+ --localedir=DIR locale-dependent data [DATAROOTDIR/locale]
+ --mandir=DIR man documentation [DATAROOTDIR/man]
+ --docdir=DIR documentation root [DATAROOTDIR/doc/PACKAGE]
+ --htmldir=DIR html documentation [DOCDIR]
+ --dvidir=DIR dvi documentation [DOCDIR]
+ --pdfdir=DIR pdf documentation [DOCDIR]
+ --psdir=DIR ps documentation [DOCDIR]
+_ACEOF
+
+ cat <<\_ACEOF
+_ACEOF
+fi
+
+if test -n "$ac_init_help"; then
+
+ cat <<\_ACEOF
+
+Optional Features:
+ --disable-option-checking ignore unrecognized --enable/--with options
+ --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no)
+ --enable-FEATURE[=ARG] include FEATURE [ARG=yes]
+ --enable-nonstandardprintf
+ Use a special printf format for 64bit (default is
+ NO)
+
+Some influential environment variables:
+ CC C compiler command
+ CFLAGS C compiler flags
+ LDFLAGS linker flags, e.g. -L<lib dir> if you have libraries in a
+ nonstandard directory <lib dir>
+ LIBS libraries to pass to the linker, e.g. -l<library>
+ CPPFLAGS (Objective) C/C++ preprocessor flags, e.g. -I<include dir> if
+ you have headers in a nonstandard directory <include dir>
+ CPP C preprocessor
+
+Use these variables to override the choices made by `configure' or to help
+it to find libraries and programs with nonstandard names/locations.
+
+Report bugs to the package provider.
+_ACEOF
+ac_status=$?
+fi
+
+if test "$ac_init_help" = "recursive"; then
+ # If there are subdirs, report their specific --help.
+ for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue
+ test -d "$ac_dir" ||
+ { cd "$srcdir" && ac_pwd=`pwd` && srcdir=. && test -d "$ac_dir"; } ||
+ continue
+ ac_builddir=.
+
+case "$ac_dir" in
+.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;;
+*)
+ ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'`
+ # A ".." for each directory in $ac_dir_suffix.
+ ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'`
+ case $ac_top_builddir_sub in
+ "") ac_top_builddir_sub=. ac_top_build_prefix= ;;
+ *) ac_top_build_prefix=$ac_top_builddir_sub/ ;;
+ esac ;;
+esac
+ac_abs_top_builddir=$ac_pwd
+ac_abs_builddir=$ac_pwd$ac_dir_suffix
+# for backward compatibility:
+ac_top_builddir=$ac_top_build_prefix
+
+case $srcdir in
+ .) # We are building in place.
+ ac_srcdir=.
+ ac_top_srcdir=$ac_top_builddir_sub
+ ac_abs_top_srcdir=$ac_pwd ;;
+ [\\/]* | ?:[\\/]* ) # Absolute name.
+ ac_srcdir=$srcdir$ac_dir_suffix;
+ ac_top_srcdir=$srcdir
+ ac_abs_top_srcdir=$srcdir ;;
+ *) # Relative name.
+ ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix
+ ac_top_srcdir=$ac_top_build_prefix$srcdir
+ ac_abs_top_srcdir=$ac_pwd/$srcdir ;;
+esac
+ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix
+
+ cd "$ac_dir" || { ac_status=$?; continue; }
+ # Check for guested configure.
+ if test -f "$ac_srcdir/configure.gnu"; then
+ echo &&
+ $SHELL "$ac_srcdir/configure.gnu" --help=recursive
+ elif test -f "$ac_srcdir/configure"; then
+ echo &&
+ $SHELL "$ac_srcdir/configure" --help=recursive
+ else
+ $as_echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2
+ fi || ac_status=$?
+ cd "$ac_pwd" || { ac_status=$?; break; }
+ done
+fi
+
+test -n "$ac_init_help" && exit $ac_status
+if $ac_init_version; then
+ cat <<\_ACEOF
+configure
+generated by GNU Autoconf 2.68
+
+Copyright (C) 2010 Free Software Foundation, Inc.
+This configure script is free software; the Free Software Foundation
+gives unlimited permission to copy, distribute and modify it.
+_ACEOF
+ exit
+fi
+
+## ------------------------ ##
+## Autoconf initialization. ##
+## ------------------------ ##
+
+# ac_fn_c_try_compile LINENO
+# --------------------------
+# Try to compile conftest.$ac_ext, and return whether this succeeded.
+ac_fn_c_try_compile ()
+{
+ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ rm -f conftest.$ac_objext
+ if { { ac_try="$ac_compile"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_compile") 2>conftest.err
+ ac_status=$?
+ if test -s conftest.err; then
+ grep -v '^ *+' conftest.err >conftest.er1
+ cat conftest.er1 >&5
+ mv -f conftest.er1 conftest.err
+ fi
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; } && {
+ test -z "$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest.$ac_objext; then :
+ ac_retval=0
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_retval=1
+fi
+ eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+ as_fn_set_status $ac_retval
+
+} # ac_fn_c_try_compile
+
+# ac_fn_c_try_cpp LINENO
+# ----------------------
+# Try to preprocess conftest.$ac_ext, and return whether this succeeded.
+ac_fn_c_try_cpp ()
+{
+ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ if { { ac_try="$ac_cpp conftest.$ac_ext"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_cpp conftest.$ac_ext") 2>conftest.err
+ ac_status=$?
+ if test -s conftest.err; then
+ grep -v '^ *+' conftest.err >conftest.er1
+ cat conftest.er1 >&5
+ mv -f conftest.er1 conftest.err
+ fi
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; } > conftest.i && {
+ test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ }; then :
+ ac_retval=0
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_retval=1
+fi
+ eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+ as_fn_set_status $ac_retval
+
+} # ac_fn_c_try_cpp
+
+# ac_fn_c_check_header_mongrel LINENO HEADER VAR INCLUDES
+# -------------------------------------------------------
+# Tests whether HEADER exists, giving a warning if it cannot be compiled using
+# the include files in INCLUDES and setting the cache variable VAR
+# accordingly.
+ac_fn_c_check_header_mongrel ()
+{
+ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ if eval \${$3+:} false; then :
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
+$as_echo_n "checking for $2... " >&6; }
+if eval \${$3+:} false; then :
+ $as_echo_n "(cached) " >&6
+fi
+eval ac_res=\$$3
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+else
+ # Is the header compilable?
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 usability" >&5
+$as_echo_n "checking $2 usability... " >&6; }
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+$4
+#include <$2>
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_header_compiler=yes
+else
+ ac_header_compiler=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_compiler" >&5
+$as_echo "$ac_header_compiler" >&6; }
+
+# Is the header present?
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 presence" >&5
+$as_echo_n "checking $2 presence... " >&6; }
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <$2>
+_ACEOF
+if ac_fn_c_try_cpp "$LINENO"; then :
+ ac_header_preproc=yes
+else
+ ac_header_preproc=no
+fi
+rm -f conftest.err conftest.i conftest.$ac_ext
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_preproc" >&5
+$as_echo "$ac_header_preproc" >&6; }
+
+# So? What about this header?
+case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in #((
+ yes:no: )
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&5
+$as_echo "$as_me: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&2;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5
+$as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;}
+ ;;
+ no:yes:* )
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: present but cannot be compiled" >&5
+$as_echo "$as_me: WARNING: $2: present but cannot be compiled" >&2;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: check for missing prerequisite headers?" >&5
+$as_echo "$as_me: WARNING: $2: check for missing prerequisite headers?" >&2;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: see the Autoconf documentation" >&5
+$as_echo "$as_me: WARNING: $2: see the Autoconf documentation" >&2;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&5
+$as_echo "$as_me: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&2;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5
+$as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;}
+ ;;
+esac
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
+$as_echo_n "checking for $2... " >&6; }
+if eval \${$3+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ eval "$3=\$ac_header_compiler"
+fi
+eval ac_res=\$$3
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+fi
+ eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+
+} # ac_fn_c_check_header_mongrel
+
+# ac_fn_c_try_run LINENO
+# ----------------------
+# Try to link conftest.$ac_ext, and return whether this succeeded. Assumes
+# that executables *can* be run.
+ac_fn_c_try_run ()
+{
+ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ if { { ac_try="$ac_link"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_link") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; } && { ac_try='./conftest$ac_exeext'
+ { { case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_try") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; }; then :
+ ac_retval=0
+else
+ $as_echo "$as_me: program exited with status $ac_status" >&5
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_retval=$ac_status
+fi
+ rm -rf conftest.dSYM conftest_ipa8_conftest.oo
+ eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+ as_fn_set_status $ac_retval
+
+} # ac_fn_c_try_run
+
+# ac_fn_c_check_header_compile LINENO HEADER VAR INCLUDES
+# -------------------------------------------------------
+# Tests whether HEADER exists and can be compiled using the include files in
+# INCLUDES, setting the cache variable VAR accordingly.
+ac_fn_c_check_header_compile ()
+{
+ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
+$as_echo_n "checking for $2... " >&6; }
+if eval \${$3+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+$4
+#include <$2>
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ eval "$3=yes"
+else
+ eval "$3=no"
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+eval ac_res=\$$3
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+ eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+
+} # ac_fn_c_check_header_compile
+
+# ac_fn_c_try_link LINENO
+# -----------------------
+# Try to link conftest.$ac_ext, and return whether this succeeded.
+ac_fn_c_try_link ()
+{
+ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ rm -f conftest.$ac_objext conftest$ac_exeext
+ if { { ac_try="$ac_link"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_link") 2>conftest.err
+ ac_status=$?
+ if test -s conftest.err; then
+ grep -v '^ *+' conftest.err >conftest.er1
+ cat conftest.er1 >&5
+ mv -f conftest.er1 conftest.err
+ fi
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; } && {
+ test -z "$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest$ac_exeext && {
+ test "$cross_compiling" = yes ||
+ $as_test_x conftest$ac_exeext
+ }; then :
+ ac_retval=0
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_retval=1
+fi
+ # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information
+ # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would
+ # interfere with the next link command; also delete a directory that is
+ # left behind by Apple's compiler. We do this before executing the actions.
+ rm -rf conftest.dSYM conftest_ipa8_conftest.oo
+ eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+ as_fn_set_status $ac_retval
+
+} # ac_fn_c_try_link
+cat >config.log <<_ACEOF
+This file contains any messages produced by compilers while
+running configure, to aid debugging if configure makes a mistake.
+
+It was created by $as_me, which was
+generated by GNU Autoconf 2.68. Invocation command line was
+
+ $ $0 $@
+
+_ACEOF
+exec 5>>config.log
+{
+cat <<_ASUNAME
+## --------- ##
+## Platform. ##
+## --------- ##
+
+hostname = `(hostname || uname -n) 2>/dev/null | sed 1q`
+uname -m = `(uname -m) 2>/dev/null || echo unknown`
+uname -r = `(uname -r) 2>/dev/null || echo unknown`
+uname -s = `(uname -s) 2>/dev/null || echo unknown`
+uname -v = `(uname -v) 2>/dev/null || echo unknown`
+
+/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown`
+/bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown`
+
+/bin/arch = `(/bin/arch) 2>/dev/null || echo unknown`
+/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown`
+/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown`
+/usr/bin/hostinfo = `(/usr/bin/hostinfo) 2>/dev/null || echo unknown`
+/bin/machine = `(/bin/machine) 2>/dev/null || echo unknown`
+/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown`
+/bin/universe = `(/bin/universe) 2>/dev/null || echo unknown`
+
+_ASUNAME
+
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ $as_echo "PATH: $as_dir"
+ done
+IFS=$as_save_IFS
+
+} >&5
+
+cat >&5 <<_ACEOF
+
+
+## ----------- ##
+## Core tests. ##
+## ----------- ##
+
+_ACEOF
+
+
+# Keep a trace of the command line.
+# Strip out --no-create and --no-recursion so they do not pile up.
+# Strip out --silent because we don't want to record it for future runs.
+# Also quote any args containing shell meta-characters.
+# Make two passes to allow for proper duplicate-argument suppression.
+ac_configure_args=
+ac_configure_args0=
+ac_configure_args1=
+ac_must_keep_next=false
+for ac_pass in 1 2
+do
+ for ac_arg
+ do
+ case $ac_arg in
+ -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;;
+ -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+ | -silent | --silent | --silen | --sile | --sil)
+ continue ;;
+ *\'*)
+ ac_arg=`$as_echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;;
+ esac
+ case $ac_pass in
+ 1) as_fn_append ac_configure_args0 " '$ac_arg'" ;;
+ 2)
+ as_fn_append ac_configure_args1 " '$ac_arg'"
+ if test $ac_must_keep_next = true; then
+ ac_must_keep_next=false # Got value, back to normal.
+ else
+ case $ac_arg in
+ *=* | --config-cache | -C | -disable-* | --disable-* \
+ | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \
+ | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \
+ | -with-* | --with-* | -without-* | --without-* | --x)
+ case "$ac_configure_args0 " in
+ "$ac_configure_args1"*" '$ac_arg' "* ) continue ;;
+ esac
+ ;;
+ -* ) ac_must_keep_next=true ;;
+ esac
+ fi
+ as_fn_append ac_configure_args " '$ac_arg'"
+ ;;
+ esac
+ done
+done
+{ ac_configure_args0=; unset ac_configure_args0;}
+{ ac_configure_args1=; unset ac_configure_args1;}
+
+# When interrupted or exit'd, cleanup temporary files, and complete
+# config.log. We remove comments because anyway the quotes in there
+# would cause problems or look ugly.
+# WARNING: Use '\'' to represent an apostrophe within the trap.
+# WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug.
+trap 'exit_status=$?
+ # Save into config.log some information that might help in debugging.
+ {
+ echo
+
+ $as_echo "## ---------------- ##
+## Cache variables. ##
+## ---------------- ##"
+ echo
+ # The following way of writing the cache mishandles newlines in values,
+(
+ for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do
+ eval ac_val=\$$ac_var
+ case $ac_val in #(
+ *${as_nl}*)
+ case $ac_var in #(
+ *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5
+$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;;
+ esac
+ case $ac_var in #(
+ _ | IFS | as_nl) ;; #(
+ BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #(
+ *) { eval $ac_var=; unset $ac_var;} ;;
+ esac ;;
+ esac
+ done
+ (set) 2>&1 |
+ case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #(
+ *${as_nl}ac_space=\ *)
+ sed -n \
+ "s/'\''/'\''\\\\'\'''\''/g;
+ s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\''\\2'\''/p"
+ ;; #(
+ *)
+ sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p"
+ ;;
+ esac |
+ sort
+)
+ echo
+
+ $as_echo "## ----------------- ##
+## Output variables. ##
+## ----------------- ##"
+ echo
+ for ac_var in $ac_subst_vars
+ do
+ eval ac_val=\$$ac_var
+ case $ac_val in
+ *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;;
+ esac
+ $as_echo "$ac_var='\''$ac_val'\''"
+ done | sort
+ echo
+
+ if test -n "$ac_subst_files"; then
+ $as_echo "## ------------------- ##
+## File substitutions. ##
+## ------------------- ##"
+ echo
+ for ac_var in $ac_subst_files
+ do
+ eval ac_val=\$$ac_var
+ case $ac_val in
+ *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;;
+ esac
+ $as_echo "$ac_var='\''$ac_val'\''"
+ done | sort
+ echo
+ fi
+
+ if test -s confdefs.h; then
+ $as_echo "## ----------- ##
+## confdefs.h. ##
+## ----------- ##"
+ echo
+ cat confdefs.h
+ echo
+ fi
+ test "$ac_signal" != 0 &&
+ $as_echo "$as_me: caught signal $ac_signal"
+ $as_echo "$as_me: exit $exit_status"
+ } >&5
+ rm -f core *.core core.conftest.* &&
+ rm -f -r conftest* confdefs* conf$$* $ac_clean_files &&
+ exit $exit_status
+' 0
+for ac_signal in 1 2 13 15; do
+ trap 'ac_signal='$ac_signal'; as_fn_exit 1' $ac_signal
+done
+ac_signal=0
+
+# confdefs.h avoids OS command line length limits that DEFS can exceed.
+rm -f -r conftest* confdefs.h
+
+$as_echo "/* confdefs.h */" > confdefs.h
+
+# Predefined preprocessor variables.
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_NAME "$PACKAGE_NAME"
+_ACEOF
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_TARNAME "$PACKAGE_TARNAME"
+_ACEOF
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_VERSION "$PACKAGE_VERSION"
+_ACEOF
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_STRING "$PACKAGE_STRING"
+_ACEOF
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT"
+_ACEOF
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_URL "$PACKAGE_URL"
+_ACEOF
+
+
+# Let the site file select an alternate cache file if it wants to.
+# Prefer an explicitly selected file to automatically selected ones.
+ac_site_file1=NONE
+ac_site_file2=NONE
+if test -n "$CONFIG_SITE"; then
+ # We do not want a PATH search for config.site.
+ case $CONFIG_SITE in #((
+ -*) ac_site_file1=./$CONFIG_SITE;;
+ */*) ac_site_file1=$CONFIG_SITE;;
+ *) ac_site_file1=./$CONFIG_SITE;;
+ esac
+elif test "x$prefix" != xNONE; then
+ ac_site_file1=$prefix/share/config.site
+ ac_site_file2=$prefix/etc/config.site
+else
+ ac_site_file1=$ac_default_prefix/share/config.site
+ ac_site_file2=$ac_default_prefix/etc/config.site
+fi
+for ac_site_file in "$ac_site_file1" "$ac_site_file2"
+do
+ test "x$ac_site_file" = xNONE && continue
+ if test /dev/null != "$ac_site_file" && test -r "$ac_site_file"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: loading site script $ac_site_file" >&5
+$as_echo "$as_me: loading site script $ac_site_file" >&6;}
+ sed 's/^/| /' "$ac_site_file" >&5
+ . "$ac_site_file" \
+ || { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "failed to load site script $ac_site_file
+See \`config.log' for more details" "$LINENO" 5; }
+ fi
+done
+
+if test -r "$cache_file"; then
+ # Some versions of bash will fail to source /dev/null (special files
+ # actually), so we avoid doing that. DJGPP emulates it as a regular file.
+ if test /dev/null != "$cache_file" && test -f "$cache_file"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: loading cache $cache_file" >&5
+$as_echo "$as_me: loading cache $cache_file" >&6;}
+ case $cache_file in
+ [\\/]* | ?:[\\/]* ) . "$cache_file";;
+ *) . "./$cache_file";;
+ esac
+ fi
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: creating cache $cache_file" >&5
+$as_echo "$as_me: creating cache $cache_file" >&6;}
+ >$cache_file
+fi
+
+# Check that the precious variables saved in the cache have kept the same
+# value.
+ac_cache_corrupted=false
+for ac_var in $ac_precious_vars; do
+ eval ac_old_set=\$ac_cv_env_${ac_var}_set
+ eval ac_new_set=\$ac_env_${ac_var}_set
+ eval ac_old_val=\$ac_cv_env_${ac_var}_value
+ eval ac_new_val=\$ac_env_${ac_var}_value
+ case $ac_old_set,$ac_new_set in
+ set,)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5
+$as_echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;}
+ ac_cache_corrupted=: ;;
+ ,set)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was not set in the previous run" >&5
+$as_echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;}
+ ac_cache_corrupted=: ;;
+ ,);;
+ *)
+ if test "x$ac_old_val" != "x$ac_new_val"; then
+ # differences in whitespace do not lead to failure.
+ ac_old_val_w=`echo x $ac_old_val`
+ ac_new_val_w=`echo x $ac_new_val`
+ if test "$ac_old_val_w" != "$ac_new_val_w"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' has changed since the previous run:" >&5
+$as_echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;}
+ ac_cache_corrupted=:
+ else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&5
+$as_echo "$as_me: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&2;}
+ eval $ac_var=\$ac_old_val
+ fi
+ { $as_echo "$as_me:${as_lineno-$LINENO}: former value: \`$ac_old_val'" >&5
+$as_echo "$as_me: former value: \`$ac_old_val'" >&2;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: current value: \`$ac_new_val'" >&5
+$as_echo "$as_me: current value: \`$ac_new_val'" >&2;}
+ fi;;
+ esac
+ # Pass precious variables to config.status.
+ if test "$ac_new_set" = set; then
+ case $ac_new_val in
+ *\'*) ac_arg=$ac_var=`$as_echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;;
+ *) ac_arg=$ac_var=$ac_new_val ;;
+ esac
+ case " $ac_configure_args " in
+ *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy.
+ *) as_fn_append ac_configure_args " '$ac_arg'" ;;
+ esac
+ fi
+done
+if $ac_cache_corrupted; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: error: changes in the environment can compromise the build" >&5
+$as_echo "$as_me: error: changes in the environment can compromise the build" >&2;}
+ as_fn_error $? "run \`make distclean' and/or \`rm $cache_file' and start over" "$LINENO" 5
+fi
+## -------------------- ##
+## Main body of script. ##
+## -------------------- ##
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+ac_config_headers="$ac_config_headers config.h"
+
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args.
+set dummy ${ac_tool_prefix}gcc; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_CC+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ ac_cv_prog_CC="${ac_tool_prefix}gcc"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+$as_echo "$CC" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_CC"; then
+ ac_ct_CC=$CC
+ # Extract the first word of "gcc", so it can be a program name with args.
+set dummy gcc; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_CC+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_CC"; then
+ ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ ac_cv_prog_ac_ct_CC="gcc"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_CC=$ac_cv_prog_ac_ct_CC
+if test -n "$ac_ct_CC"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5
+$as_echo "$ac_ct_CC" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ if test "x$ac_ct_CC" = x; then
+ CC=""
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ CC=$ac_ct_CC
+ fi
+else
+ CC="$ac_cv_prog_CC"
+fi
+
+if test -z "$CC"; then
+ if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args.
+set dummy ${ac_tool_prefix}cc; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_CC+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ ac_cv_prog_CC="${ac_tool_prefix}cc"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+$as_echo "$CC" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ fi
+fi
+if test -z "$CC"; then
+ # Extract the first word of "cc", so it can be a program name with args.
+set dummy cc; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_CC+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+ ac_prog_rejected=no
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then
+ ac_prog_rejected=yes
+ continue
+ fi
+ ac_cv_prog_CC="cc"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+if test $ac_prog_rejected = yes; then
+ # We found a bogon in the path, so make sure we never use it.
+ set dummy $ac_cv_prog_CC
+ shift
+ if test $# != 0; then
+ # We chose a different compiler from the bogus one.
+ # However, it has the same basename, so the bogon will be chosen
+ # first if we set CC to just the basename; use the full file name.
+ shift
+ ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@"
+ fi
+fi
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+$as_echo "$CC" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$CC"; then
+ if test -n "$ac_tool_prefix"; then
+ for ac_prog in cl.exe
+ do
+ # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
+set dummy $ac_tool_prefix$ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_CC+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ ac_cv_prog_CC="$ac_tool_prefix$ac_prog"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+$as_echo "$CC" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ test -n "$CC" && break
+ done
+fi
+if test -z "$CC"; then
+ ac_ct_CC=$CC
+ for ac_prog in cl.exe
+do
+ # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_CC+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_CC"; then
+ ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ ac_cv_prog_ac_ct_CC="$ac_prog"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_CC=$ac_cv_prog_ac_ct_CC
+if test -n "$ac_ct_CC"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5
+$as_echo "$ac_ct_CC" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ test -n "$ac_ct_CC" && break
+done
+
+ if test "x$ac_ct_CC" = x; then
+ CC=""
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ CC=$ac_ct_CC
+ fi
+fi
+
+fi
+
+
+test -z "$CC" && { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "no acceptable C compiler found in \$PATH
+See \`config.log' for more details" "$LINENO" 5; }
+
+# Provide some information about the compiler.
+$as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5
+set X $ac_compile
+ac_compiler=$2
+for ac_option in --version -v -V -qversion; do
+ { { ac_try="$ac_compiler $ac_option >&5"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_compiler $ac_option >&5") 2>conftest.err
+ ac_status=$?
+ if test -s conftest.err; then
+ sed '10a\
+... rest of stderr output deleted ...
+ 10q' conftest.err >conftest.er1
+ cat conftest.er1 >&5
+ fi
+ rm -f conftest.er1 conftest.err
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }
+done
+
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+ac_clean_files_save=$ac_clean_files
+ac_clean_files="$ac_clean_files a.out a.out.dSYM a.exe b.out"
+# Try to create an executable without -o first, disregard a.out.
+# It will help us diagnose broken compilers, and finding out an intuition
+# of exeext.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler works" >&5
+$as_echo_n "checking whether the C compiler works... " >&6; }
+ac_link_default=`$as_echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'`
+
+# The possible output files:
+ac_files="a.out conftest.exe conftest a.exe a_out.exe b.out conftest.*"
+
+ac_rmfiles=
+for ac_file in $ac_files
+do
+ case $ac_file in
+ *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;;
+ * ) ac_rmfiles="$ac_rmfiles $ac_file";;
+ esac
+done
+rm -f $ac_rmfiles
+
+if { { ac_try="$ac_link_default"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_link_default") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then :
+ # Autoconf-2.13 could set the ac_cv_exeext variable to `no'.
+# So ignore a value of `no', otherwise this would lead to `EXEEXT = no'
+# in a Makefile. We should not override ac_cv_exeext if it was cached,
+# so that the user can short-circuit this test for compilers unknown to
+# Autoconf.
+for ac_file in $ac_files ''
+do
+ test -f "$ac_file" || continue
+ case $ac_file in
+ *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj )
+ ;;
+ [ab].out )
+ # We found the default executable, but exeext='' is most
+ # certainly right.
+ break;;
+ *.* )
+ if test "${ac_cv_exeext+set}" = set && test "$ac_cv_exeext" != no;
+ then :; else
+ ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
+ fi
+ # We set ac_cv_exeext here because the later test for it is not
+ # safe: cross compilers may not add the suffix if given an `-o'
+ # argument, so we may need to know it at that point already.
+ # Even if this section looks crufty: it has the advantage of
+ # actually working.
+ break;;
+ * )
+ break;;
+ esac
+done
+test "$ac_cv_exeext" = no && ac_cv_exeext=
+
+else
+ ac_file=''
+fi
+if test -z "$ac_file"; then :
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+$as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error 77 "C compiler cannot create executables
+See \`config.log' for more details" "$LINENO" 5; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler default output file name" >&5
+$as_echo_n "checking for C compiler default output file name... " >&6; }
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_file" >&5
+$as_echo "$ac_file" >&6; }
+ac_exeext=$ac_cv_exeext
+
+rm -f -r a.out a.out.dSYM a.exe conftest$ac_cv_exeext b.out
+ac_clean_files=$ac_clean_files_save
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of executables" >&5
+$as_echo_n "checking for suffix of executables... " >&6; }
+if { { ac_try="$ac_link"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_link") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then :
+ # If both `conftest.exe' and `conftest' are `present' (well, observable)
+# catch `conftest.exe'. For instance with Cygwin, `ls conftest' will
+# work properly (i.e., refer to `conftest.exe'), while it won't with
+# `rm'.
+for ac_file in conftest.exe conftest conftest.*; do
+ test -f "$ac_file" || continue
+ case $ac_file in
+ *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;;
+ *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
+ break;;
+ * ) break;;
+ esac
+done
+else
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "cannot compute suffix of executables: cannot compile and link
+See \`config.log' for more details" "$LINENO" 5; }
+fi
+rm -f conftest conftest$ac_cv_exeext
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_exeext" >&5
+$as_echo "$ac_cv_exeext" >&6; }
+
+rm -f conftest.$ac_ext
+EXEEXT=$ac_cv_exeext
+ac_exeext=$EXEEXT
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <stdio.h>
+int
+main ()
+{
+FILE *f = fopen ("conftest.out", "w");
+ return ferror (f) || fclose (f) != 0;
+
+ ;
+ return 0;
+}
+_ACEOF
+ac_clean_files="$ac_clean_files conftest.out"
+# Check that the compiler produces executables we can run. If not, either
+# the compiler is broken, or we cross compile.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are cross compiling" >&5
+$as_echo_n "checking whether we are cross compiling... " >&6; }
+if test "$cross_compiling" != yes; then
+ { { ac_try="$ac_link"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_link") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }
+ if { ac_try='./conftest$ac_cv_exeext'
+ { { case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_try") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; }; then
+ cross_compiling=no
+ else
+ if test "$cross_compiling" = maybe; then
+ cross_compiling=yes
+ else
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "cannot run C compiled programs.
+If you meant to cross compile, use \`--host'.
+See \`config.log' for more details" "$LINENO" 5; }
+ fi
+ fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $cross_compiling" >&5
+$as_echo "$cross_compiling" >&6; }
+
+rm -f conftest.$ac_ext conftest$ac_cv_exeext conftest.out
+ac_clean_files=$ac_clean_files_save
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of object files" >&5
+$as_echo_n "checking for suffix of object files... " >&6; }
+if ${ac_cv_objext+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.o conftest.obj
+if { { ac_try="$ac_compile"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_compile") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then :
+ for ac_file in conftest.o conftest.obj conftest.*; do
+ test -f "$ac_file" || continue;
+ case $ac_file in
+ *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM ) ;;
+ *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'`
+ break;;
+ esac
+done
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "cannot compute suffix of object files: cannot compile
+See \`config.log' for more details" "$LINENO" 5; }
+fi
+rm -f conftest.$ac_cv_objext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_objext" >&5
+$as_echo "$ac_cv_objext" >&6; }
+OBJEXT=$ac_cv_objext
+ac_objext=$OBJEXT
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C compiler" >&5
+$as_echo_n "checking whether we are using the GNU C compiler... " >&6; }
+if ${ac_cv_c_compiler_gnu+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+#ifndef __GNUC__
+ choke me
+#endif
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_compiler_gnu=yes
+else
+ ac_compiler_gnu=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ac_cv_c_compiler_gnu=$ac_compiler_gnu
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5
+$as_echo "$ac_cv_c_compiler_gnu" >&6; }
+if test $ac_compiler_gnu = yes; then
+ GCC=yes
+else
+ GCC=
+fi
+ac_test_CFLAGS=${CFLAGS+set}
+ac_save_CFLAGS=$CFLAGS
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5
+$as_echo_n "checking whether $CC accepts -g... " >&6; }
+if ${ac_cv_prog_cc_g+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_save_c_werror_flag=$ac_c_werror_flag
+ ac_c_werror_flag=yes
+ ac_cv_prog_cc_g=no
+ CFLAGS="-g"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_cv_prog_cc_g=yes
+else
+ CFLAGS=""
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+
+else
+ ac_c_werror_flag=$ac_save_c_werror_flag
+ CFLAGS="-g"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_cv_prog_cc_g=yes
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ ac_c_werror_flag=$ac_save_c_werror_flag
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5
+$as_echo "$ac_cv_prog_cc_g" >&6; }
+if test "$ac_test_CFLAGS" = set; then
+ CFLAGS=$ac_save_CFLAGS
+elif test $ac_cv_prog_cc_g = yes; then
+ if test "$GCC" = yes; then
+ CFLAGS="-g -O2"
+ else
+ CFLAGS="-g"
+ fi
+else
+ if test "$GCC" = yes; then
+ CFLAGS="-O2"
+ else
+ CFLAGS=
+ fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C89" >&5
+$as_echo_n "checking for $CC option to accept ISO C89... " >&6; }
+if ${ac_cv_prog_cc_c89+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_cv_prog_cc_c89=no
+ac_save_CC=$CC
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <stdarg.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+/* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */
+struct buf { int x; };
+FILE * (*rcsopen) (struct buf *, struct stat *, int);
+static char *e (p, i)
+ char **p;
+ int i;
+{
+ return p[i];
+}
+static char *f (char * (*g) (char **, int), char **p, ...)
+{
+ char *s;
+ va_list v;
+ va_start (v,p);
+ s = g (p, va_arg (v,int));
+ va_end (v);
+ return s;
+}
+
+/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has
+ function prototypes and stuff, but not '\xHH' hex character constants.
+ These don't provoke an error unfortunately, instead are silently treated
+ as 'x'. The following induces an error, until -std is added to get
+ proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an
+ array size at least. It's necessary to write '\x00'==0 to get something
+ that's true only with -std. */
+int osf4_cc_array ['\x00' == 0 ? 1 : -1];
+
+/* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters
+ inside strings and character constants. */
+#define FOO(x) 'x'
+int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1];
+
+int test (int i, double x);
+struct s1 {int (*f) (int a);};
+struct s2 {int (*f) (double a);};
+int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int);
+int argc;
+char **argv;
+int
+main ()
+{
+return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1];
+ ;
+ return 0;
+}
+_ACEOF
+for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \
+ -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__"
+do
+ CC="$ac_save_CC $ac_arg"
+ if ac_fn_c_try_compile "$LINENO"; then :
+ ac_cv_prog_cc_c89=$ac_arg
+fi
+rm -f core conftest.err conftest.$ac_objext
+ test "x$ac_cv_prog_cc_c89" != "xno" && break
+done
+rm -f conftest.$ac_ext
+CC=$ac_save_CC
+
+fi
+# AC_CACHE_VAL
+case "x$ac_cv_prog_cc_c89" in
+ x)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5
+$as_echo "none needed" >&6; } ;;
+ xno)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5
+$as_echo "unsupported" >&6; } ;;
+ *)
+ CC="$CC $ac_cv_prog_cc_c89"
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5
+$as_echo "$ac_cv_prog_cc_c89" >&6; } ;;
+esac
+if test "x$ac_cv_prog_cc_c89" != xno; then :
+
+fi
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C preprocessor" >&5
+$as_echo_n "checking how to run the C preprocessor... " >&6; }
+# On Suns, sometimes $CPP names a directory.
+if test -n "$CPP" && test -d "$CPP"; then
+ CPP=
+fi
+if test -z "$CPP"; then
+ if ${ac_cv_prog_CPP+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ # Double quotes because CPP needs to be expanded
+ for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp"
+ do
+ ac_preproc_ok=false
+for ac_c_preproc_warn_flag in '' yes
+do
+ # Use a header file that comes with gcc, so configuring glibc
+ # with a fresh cross-compiler works.
+ # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ # <limits.h> exists even on freestanding compilers.
+ # On the NeXT, cc -E runs the code through the compiler's parser,
+ # not just through cpp. "Syntax error" is here to catch this case.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+ Syntax error
+_ACEOF
+if ac_fn_c_try_cpp "$LINENO"; then :
+
+else
+ # Broken: fails on valid input.
+continue
+fi
+rm -f conftest.err conftest.i conftest.$ac_ext
+
+ # OK, works on sane cases. Now check whether nonexistent headers
+ # can be detected and how.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <ac_nonexistent.h>
+_ACEOF
+if ac_fn_c_try_cpp "$LINENO"; then :
+ # Broken: success on invalid input.
+continue
+else
+ # Passes both tests.
+ac_preproc_ok=:
+break
+fi
+rm -f conftest.err conftest.i conftest.$ac_ext
+
+done
+# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
+rm -f conftest.i conftest.err conftest.$ac_ext
+if $ac_preproc_ok; then :
+ break
+fi
+
+ done
+ ac_cv_prog_CPP=$CPP
+
+fi
+ CPP=$ac_cv_prog_CPP
+else
+ ac_cv_prog_CPP=$CPP
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $CPP" >&5
+$as_echo "$CPP" >&6; }
+ac_preproc_ok=false
+for ac_c_preproc_warn_flag in '' yes
+do
+ # Use a header file that comes with gcc, so configuring glibc
+ # with a fresh cross-compiler works.
+ # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ # <limits.h> exists even on freestanding compilers.
+ # On the NeXT, cc -E runs the code through the compiler's parser,
+ # not just through cpp. "Syntax error" is here to catch this case.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+ Syntax error
+_ACEOF
+if ac_fn_c_try_cpp "$LINENO"; then :
+
+else
+ # Broken: fails on valid input.
+continue
+fi
+rm -f conftest.err conftest.i conftest.$ac_ext
+
+ # OK, works on sane cases. Now check whether nonexistent headers
+ # can be detected and how.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <ac_nonexistent.h>
+_ACEOF
+if ac_fn_c_try_cpp "$LINENO"; then :
+ # Broken: success on invalid input.
+continue
+else
+ # Passes both tests.
+ac_preproc_ok=:
+break
+fi
+rm -f conftest.err conftest.i conftest.$ac_ext
+
+done
+# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
+rm -f conftest.i conftest.err conftest.$ac_ext
+if $ac_preproc_ok; then :
+
+else
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "C preprocessor \"$CPP\" fails sanity check
+See \`config.log' for more details" "$LINENO" 5; }
+fi
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for grep that handles long lines and -e" >&5
+$as_echo_n "checking for grep that handles long lines and -e... " >&6; }
+if ${ac_cv_path_GREP+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -z "$GREP"; then
+ ac_path_GREP_found=false
+ # Loop through the user's path and test for each of PROGNAME-LIST
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_prog in grep ggrep; do
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext"
+ { test -f "$ac_path_GREP" && $as_test_x "$ac_path_GREP"; } || continue
+# Check for GNU ac_path_GREP and select it if it is found.
+ # Check for GNU $ac_path_GREP
+case `"$ac_path_GREP" --version 2>&1` in
+*GNU*)
+ ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;;
+*)
+ ac_count=0
+ $as_echo_n 0123456789 >"conftest.in"
+ while :
+ do
+ cat "conftest.in" "conftest.in" >"conftest.tmp"
+ mv "conftest.tmp" "conftest.in"
+ cp "conftest.in" "conftest.nl"
+ $as_echo 'GREP' >> "conftest.nl"
+ "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break
+ diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break
+ as_fn_arith $ac_count + 1 && ac_count=$as_val
+ if test $ac_count -gt ${ac_path_GREP_max-0}; then
+ # Best one so far, save it but keep looking for a better one
+ ac_cv_path_GREP="$ac_path_GREP"
+ ac_path_GREP_max=$ac_count
+ fi
+ # 10*(2^10) chars as input seems more than enough
+ test $ac_count -gt 10 && break
+ done
+ rm -f conftest.in conftest.tmp conftest.nl conftest.out;;
+esac
+
+ $ac_path_GREP_found && break 3
+ done
+ done
+ done
+IFS=$as_save_IFS
+ if test -z "$ac_cv_path_GREP"; then
+ as_fn_error $? "no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5
+ fi
+else
+ ac_cv_path_GREP=$GREP
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_GREP" >&5
+$as_echo "$ac_cv_path_GREP" >&6; }
+ GREP="$ac_cv_path_GREP"
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for egrep" >&5
+$as_echo_n "checking for egrep... " >&6; }
+if ${ac_cv_path_EGREP+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if echo a | $GREP -E '(a|b)' >/dev/null 2>&1
+ then ac_cv_path_EGREP="$GREP -E"
+ else
+ if test -z "$EGREP"; then
+ ac_path_EGREP_found=false
+ # Loop through the user's path and test for each of PROGNAME-LIST
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_prog in egrep; do
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext"
+ { test -f "$ac_path_EGREP" && $as_test_x "$ac_path_EGREP"; } || continue
+# Check for GNU ac_path_EGREP and select it if it is found.
+ # Check for GNU $ac_path_EGREP
+case `"$ac_path_EGREP" --version 2>&1` in
+*GNU*)
+ ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;;
+*)
+ ac_count=0
+ $as_echo_n 0123456789 >"conftest.in"
+ while :
+ do
+ cat "conftest.in" "conftest.in" >"conftest.tmp"
+ mv "conftest.tmp" "conftest.in"
+ cp "conftest.in" "conftest.nl"
+ $as_echo 'EGREP' >> "conftest.nl"
+ "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break
+ diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break
+ as_fn_arith $ac_count + 1 && ac_count=$as_val
+ if test $ac_count -gt ${ac_path_EGREP_max-0}; then
+ # Best one so far, save it but keep looking for a better one
+ ac_cv_path_EGREP="$ac_path_EGREP"
+ ac_path_EGREP_max=$ac_count
+ fi
+ # 10*(2^10) chars as input seems more than enough
+ test $ac_count -gt 10 && break
+ done
+ rm -f conftest.in conftest.tmp conftest.nl conftest.out;;
+esac
+
+ $ac_path_EGREP_found && break 3
+ done
+ done
+ done
+IFS=$as_save_IFS
+ if test -z "$ac_cv_path_EGREP"; then
+ as_fn_error $? "no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5
+ fi
+else
+ ac_cv_path_EGREP=$EGREP
+fi
+
+ fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_EGREP" >&5
+$as_echo "$ac_cv_path_EGREP" >&6; }
+ EGREP="$ac_cv_path_EGREP"
+
+
+if test $ac_cv_c_compiler_gnu = yes; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC needs -traditional" >&5
+$as_echo_n "checking whether $CC needs -traditional... " >&6; }
+if ${ac_cv_prog_gcc_traditional+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_pattern="Autoconf.*'x'"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <sgtty.h>
+Autoconf TIOCGETP
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ $EGREP "$ac_pattern" >/dev/null 2>&1; then :
+ ac_cv_prog_gcc_traditional=yes
+else
+ ac_cv_prog_gcc_traditional=no
+fi
+rm -f conftest*
+
+
+ if test $ac_cv_prog_gcc_traditional = no; then
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <termio.h>
+Autoconf TCGETA
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ $EGREP "$ac_pattern" >/dev/null 2>&1; then :
+ ac_cv_prog_gcc_traditional=yes
+fi
+rm -f conftest*
+
+ fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_gcc_traditional" >&5
+$as_echo "$ac_cv_prog_gcc_traditional" >&6; }
+ if test $ac_cv_prog_gcc_traditional = yes; then
+ CC="$CC -traditional"
+ fi
+fi
+
+ac_aux_dir=
+for ac_dir in "$srcdir" "$srcdir/.." "$srcdir/../.."; do
+ if test -f "$ac_dir/install-sh"; then
+ ac_aux_dir=$ac_dir
+ ac_install_sh="$ac_aux_dir/install-sh -c"
+ break
+ elif test -f "$ac_dir/install.sh"; then
+ ac_aux_dir=$ac_dir
+ ac_install_sh="$ac_aux_dir/install.sh -c"
+ break
+ elif test -f "$ac_dir/shtool"; then
+ ac_aux_dir=$ac_dir
+ ac_install_sh="$ac_aux_dir/shtool install -c"
+ break
+ fi
+done
+if test -z "$ac_aux_dir"; then
+ as_fn_error $? "cannot find install-sh, install.sh, or shtool in \"$srcdir\" \"$srcdir/..\" \"$srcdir/../..\"" "$LINENO" 5
+fi
+
+# These three variables are undocumented and unsupported,
+# and are intended to be withdrawn in a future Autoconf release.
+# They can cause serious problems if a builder's source tree is in a directory
+# whose full name contains unusual characters.
+ac_config_guess="$SHELL $ac_aux_dir/config.guess" # Please don't use this var.
+ac_config_sub="$SHELL $ac_aux_dir/config.sub" # Please don't use this var.
+ac_configure="$SHELL $ac_aux_dir/configure" # Please don't use this var.
+
+
+# Find a good install program. We prefer a C program (faster),
+# so one script is as good as another. But avoid the broken or
+# incompatible versions:
+# SysV /etc/install, /usr/sbin/install
+# SunOS /usr/etc/install
+# IRIX /sbin/install
+# AIX /bin/install
+# AmigaOS /C/install, which installs bootblocks on floppy discs
+# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag
+# AFS /usr/afsws/bin/install, which mishandles nonexistent args
+# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff"
+# OS/2's system install, which has a completely different semantic
+# ./install, which can be erroneously created by make from ./install.sh.
+# Reject install programs that cannot install multiple files.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a BSD-compatible install" >&5
+$as_echo_n "checking for a BSD-compatible install... " >&6; }
+if test -z "$INSTALL"; then
+if ${ac_cv_path_install+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ # Account for people who put trailing slashes in PATH elements.
+case $as_dir/ in #((
+ ./ | .// | /[cC]/* | \
+ /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \
+ ?:[\\/]os2[\\/]install[\\/]* | ?:[\\/]OS2[\\/]INSTALL[\\/]* | \
+ /usr/ucb/* ) ;;
+ *)
+ # OSF1 and SCO ODT 3.0 have their own names for install.
+ # Don't use installbsd from OSF since it installs stuff as root
+ # by default.
+ for ac_prog in ginstall scoinst install; do
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_prog$ac_exec_ext" && $as_test_x "$as_dir/$ac_prog$ac_exec_ext"; }; then
+ if test $ac_prog = install &&
+ grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then
+ # AIX install. It has an incompatible calling convention.
+ :
+ elif test $ac_prog = install &&
+ grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then
+ # program-specific install script used by HP pwplus--don't use.
+ :
+ else
+ rm -rf conftest.one conftest.two conftest.dir
+ echo one > conftest.one
+ echo two > conftest.two
+ mkdir conftest.dir
+ if "$as_dir/$ac_prog$ac_exec_ext" -c conftest.one conftest.two "`pwd`/conftest.dir" &&
+ test -s conftest.one && test -s conftest.two &&
+ test -s conftest.dir/conftest.one &&
+ test -s conftest.dir/conftest.two
+ then
+ ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c"
+ break 3
+ fi
+ fi
+ fi
+ done
+ done
+ ;;
+esac
+
+ done
+IFS=$as_save_IFS
+
+rm -rf conftest.one conftest.two conftest.dir
+
+fi
+ if test "${ac_cv_path_install+set}" = set; then
+ INSTALL=$ac_cv_path_install
+ else
+ # As a last resort, use the slow shell script. Don't cache a
+ # value for INSTALL within a source directory, because that will
+ # break other packages using the cache if that directory is
+ # removed, or if the value is a relative name.
+ INSTALL=$ac_install_sh
+ fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $INSTALL" >&5
+$as_echo "$INSTALL" >&6; }
+
+# Use test -z because SunOS4 sh mishandles braces in ${var-val}.
+# It thinks the first close brace ends the variable substitution.
+test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}'
+
+test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}'
+
+test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644'
+
+if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args.
+set dummy ${ac_tool_prefix}ranlib; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_RANLIB+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$RANLIB"; then
+ ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+RANLIB=$ac_cv_prog_RANLIB
+if test -n "$RANLIB"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $RANLIB" >&5
+$as_echo "$RANLIB" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_RANLIB"; then
+ ac_ct_RANLIB=$RANLIB
+ # Extract the first word of "ranlib", so it can be a program name with args.
+set dummy ranlib; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_RANLIB+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_RANLIB"; then
+ ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ ac_cv_prog_ac_ct_RANLIB="ranlib"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB
+if test -n "$ac_ct_RANLIB"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_RANLIB" >&5
+$as_echo "$ac_ct_RANLIB" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ if test "x$ac_ct_RANLIB" = x; then
+ RANLIB=":"
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ RANLIB=$ac_ct_RANLIB
+ fi
+else
+ RANLIB="$ac_cv_prog_RANLIB"
+fi
+
+if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}ar", so it can be a program name with args.
+set dummy ${ac_tool_prefix}ar; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_AR+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$AR"; then
+ ac_cv_prog_AR="$AR" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ ac_cv_prog_AR="${ac_tool_prefix}ar"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+AR=$ac_cv_prog_AR
+if test -n "$AR"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AR" >&5
+$as_echo "$AR" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_AR"; then
+ ac_ct_AR=$AR
+ # Extract the first word of "ar", so it can be a program name with args.
+set dummy ar; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_AR+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_AR"; then
+ ac_cv_prog_ac_ct_AR="$ac_ct_AR" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ ac_cv_prog_ac_ct_AR="ar"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_AR=$ac_cv_prog_ac_ct_AR
+if test -n "$ac_ct_AR"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_AR" >&5
+$as_echo "$ac_ct_AR" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ if test "x$ac_ct_AR" = x; then
+ AR=""
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ AR=$ac_ct_AR
+ fi
+else
+ AR="$ac_cv_prog_AR"
+fi
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5
+$as_echo_n "checking for ANSI C header files... " >&6; }
+if ${ac_cv_header_stdc+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <float.h>
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_cv_header_stdc=yes
+else
+ ac_cv_header_stdc=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+if test $ac_cv_header_stdc = yes; then
+ # SunOS 4.x string.h does not declare mem*, contrary to ANSI.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <string.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ $EGREP "memchr" >/dev/null 2>&1; then :
+
+else
+ ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+ # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <stdlib.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ $EGREP "free" >/dev/null 2>&1; then :
+
+else
+ ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+ # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi.
+ if test "$cross_compiling" = yes; then :
+ :
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <ctype.h>
+#include <stdlib.h>
+#if ((' ' & 0x0FF) == 0x020)
+# define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
+# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c))
+#else
+# define ISLOWER(c) \
+ (('a' <= (c) && (c) <= 'i') \
+ || ('j' <= (c) && (c) <= 'r') \
+ || ('s' <= (c) && (c) <= 'z'))
+# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c))
+#endif
+
+#define XOR(e, f) (((e) && !(f)) || (!(e) && (f)))
+int
+main ()
+{
+ int i;
+ for (i = 0; i < 256; i++)
+ if (XOR (islower (i), ISLOWER (i))
+ || toupper (i) != TOUPPER (i))
+ return 2;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_run "$LINENO"; then :
+
+else
+ ac_cv_header_stdc=no
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+ conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+
+fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdc" >&5
+$as_echo "$ac_cv_header_stdc" >&6; }
+if test $ac_cv_header_stdc = yes; then
+
+$as_echo "#define STDC_HEADERS 1" >>confdefs.h
+
+fi
+
+# On IRIX 5.3, sys/types and inttypes.h are conflicting.
+for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \
+ inttypes.h stdint.h unistd.h
+do :
+ as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
+ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default
+"
+if eval test \"x\$"$as_ac_Header"\" = x"yes"; then :
+ cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+
+done
+
+
+for ac_header in elf.h getopt.h libelf.h libelf/libelf.h sgidefs.h sys/types.h
+do :
+ as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
+ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default"
+if eval test \"x\$"$as_ac_Header"\" = x"yes"; then :
+ cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+
+done
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for elf64_getehdr in -lelf" >&5
+$as_echo_n "checking for elf64_getehdr in -lelf... " >&6; }
+if ${ac_cv_lib_elf_elf64_getehdr+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lelf $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char elf64_getehdr ();
+int
+main ()
+{
+return elf64_getehdr ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_elf_elf64_getehdr=yes
+else
+ ac_cv_lib_elf_elf64_getehdr=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_elf_elf64_getehdr" >&5
+$as_echo "$ac_cv_lib_elf_elf64_getehdr" >&6; }
+if test "x$ac_cv_lib_elf_elf64_getehdr" = xyes; then :
+
+$as_echo "#define HAVE_ELF64_GETEHDR 1" >>confdefs.h
+
+fi
+
+
+if test "$ac_cv_header_elf_h" = yes; then
+
+$as_echo "#define LOCATION_OF_LIBELFHEADER <elf.h>" >>confdefs.h
+
+elif test "$ac_cv_header_libelf_h" = yes; then
+
+$as_echo "#define LOCATION_OF_LIBELFHEADER <libelf.h>" >>confdefs.h
+
+elif test "$ac_cv_header_libelf_libelf_h" = yes; then
+
+$as_echo "#define LOCATION_OF_LIBELFHEADER <libelf/libelf.h>" >>confdefs.h
+
+fi
+
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include "stdafx.h"
+int
+main ()
+{
+ int p; p = 27;
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+
+$as_echo "#define HAVE_STDAFX_H 1" >>confdefs.h
+
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include LOCATION_OF_LIBELFHEADER
+int
+main ()
+{
+Elf64_Rel *p; int i; i = p->r_info;
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+
+$as_echo "#define HAVE_ELF64_R_INFO 1" >>confdefs.h
+
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+__uint32_t p; p = 3;
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+
+$as_echo "#define HAVE___UINT32_T 1" >>confdefs.h
+
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+__uint64_t p; p = 3;
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+
+$as_echo "#define HAVE___UINT64_T 1" >>confdefs.h
+
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <sys/types.h>
+int
+main ()
+{
+ __uint32_t p; p = 3;
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+
+$as_echo "#define HAVE___UINT32_T_IN_SYS_TYPES_H 1" >>confdefs.h
+
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <sys/types.h>
+ #include <regex.h>
+int
+main ()
+{
+ int i;
+ regex_t r;
+ int cflags = REG_EXTENDED;
+ const char *s = "abc";
+ i = regcomp(&r,s,cflags);
+ regfree(&r);
+ ;
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+
+$as_echo "#define HAVE_REGEX 1" >>confdefs.h
+
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <stdio.h>
+#include <stdlib.h>
+/* On Ubuntu 10.x, tsearch is in package libc6-dev. */
+/* The tdestroy function is GNU, not POSIX. */
+#define __USE_GNU 1
+#include <search.h>
+struct my_tentry {
+ long mt_key;
+ char * mt_name;
+};
+struct my_tentry * make_my_tentry(long k,char *name) { return 0; }
+void mt_free_func(void *mt_data) { return; }
+int mt_compare_func(const void *l, const void *r) { return 0; }
+int
+main ()
+{
+
+ long i = 1;
+ void *tree1 = 0;
+ char *dbuf = 0;
+ struct my_tentry *mt = 0;
+ struct my_tentry *retval = 0;
+ mt = make_my_tentry(i,dbuf);
+ retval = tsearch(mt,&tree1, mt_compare_func );
+ tdestroy(tree1,mt_free_func);
+ exit(0);
+;
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+
+$as_echo "#define HAVE_TSEARCH 1" >>confdefs.h
+
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+
+
+# Check whether --enable-nonstandardprintf was given.
+if test "${enable_nonstandardprintf+set}" = set; then :
+ enableval=$enable_nonstandardprintf;
+$as_echo "#define HAVE_NONSTANDARD_PRINTF_64_FORMAT 1" >>confdefs.h
+
+fi
+
+
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+#include <libelf.h>
+
+int
+main ()
+{
+ int p; p = 0;
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+
+$as_echo "#define HAVE_RAW_LIBELF_OK 1" >>confdefs.h
+
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+#define _GNU_SOURCE
+#include <libelf.h>
+
+int
+main ()
+{
+ off64_t p; p = 0;
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+
+$as_echo "#define HAVE_LIBELF_OFF64_OK 1" >>confdefs.h
+
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+
+
+ac_config_files="$ac_config_files Makefile"
+
+cat >confcache <<\_ACEOF
+# This file is a shell script that caches the results of configure
+# tests run on this system so they can be shared between configure
+# scripts and configure runs, see configure's option --config-cache.
+# It is not useful on other systems. If it contains results you don't
+# want to keep, you may remove or edit it.
+#
+# config.status only pays attention to the cache file if you give it
+# the --recheck option to rerun configure.
+#
+# `ac_cv_env_foo' variables (set or unset) will be overridden when
+# loading this file, other *unset* `ac_cv_foo' will be assigned the
+# following values.
+
+_ACEOF
+
+# The following way of writing the cache mishandles newlines in values,
+# but we know of no workaround that is simple, portable, and efficient.
+# So, we kill variables containing newlines.
+# Ultrix sh set writes to stderr and can't be redirected directly,
+# and sets the high bit in the cache file unless we assign to the vars.
+(
+ for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do
+ eval ac_val=\$$ac_var
+ case $ac_val in #(
+ *${as_nl}*)
+ case $ac_var in #(
+ *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5
+$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;;
+ esac
+ case $ac_var in #(
+ _ | IFS | as_nl) ;; #(
+ BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #(
+ *) { eval $ac_var=; unset $ac_var;} ;;
+ esac ;;
+ esac
+ done
+
+ (set) 2>&1 |
+ case $as_nl`(ac_space=' '; set) 2>&1` in #(
+ *${as_nl}ac_space=\ *)
+ # `set' does not quote correctly, so add quotes: double-quote
+ # substitution turns \\\\ into \\, and sed turns \\ into \.
+ sed -n \
+ "s/'/'\\\\''/g;
+ s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p"
+ ;; #(
+ *)
+ # `set' quotes correctly as required by POSIX, so do not add quotes.
+ sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p"
+ ;;
+ esac |
+ sort
+) |
+ sed '
+ /^ac_cv_env_/b end
+ t clear
+ :clear
+ s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/
+ t end
+ s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/
+ :end' >>confcache
+if diff "$cache_file" confcache >/dev/null 2>&1; then :; else
+ if test -w "$cache_file"; then
+ if test "x$cache_file" != "x/dev/null"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5
+$as_echo "$as_me: updating cache $cache_file" >&6;}
+ if test ! -f "$cache_file" || test -h "$cache_file"; then
+ cat confcache >"$cache_file"
+ else
+ case $cache_file in #(
+ */* | ?:*)
+ mv -f confcache "$cache_file"$$ &&
+ mv -f "$cache_file"$$ "$cache_file" ;; #(
+ *)
+ mv -f confcache "$cache_file" ;;
+ esac
+ fi
+ fi
+ else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file" >&5
+$as_echo "$as_me: not updating unwritable cache $cache_file" >&6;}
+ fi
+fi
+rm -f confcache
+
+test "x$prefix" = xNONE && prefix=$ac_default_prefix
+# Let make expand exec_prefix.
+test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'
+
+DEFS=-DHAVE_CONFIG_H
+
+ac_libobjs=
+ac_ltlibobjs=
+U=
+for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue
+ # 1. Remove the extension, and $U if already installed.
+ ac_script='s/\$U\././;s/\.o$//;s/\.obj$//'
+ ac_i=`$as_echo "$ac_i" | sed "$ac_script"`
+ # 2. Prepend LIBOBJDIR. When used with automake>=1.10 LIBOBJDIR
+ # will be set to the directory where LIBOBJS objects are built.
+ as_fn_append ac_libobjs " \${LIBOBJDIR}$ac_i\$U.$ac_objext"
+ as_fn_append ac_ltlibobjs " \${LIBOBJDIR}$ac_i"'$U.lo'
+done
+LIBOBJS=$ac_libobjs
+
+LTLIBOBJS=$ac_ltlibobjs
+
+
+
+: "${CONFIG_STATUS=./config.status}"
+ac_write_fail=0
+ac_clean_files_save=$ac_clean_files
+ac_clean_files="$ac_clean_files $CONFIG_STATUS"
+{ $as_echo "$as_me:${as_lineno-$LINENO}: creating $CONFIG_STATUS" >&5
+$as_echo "$as_me: creating $CONFIG_STATUS" >&6;}
+as_write_fail=0
+cat >$CONFIG_STATUS <<_ASEOF || as_write_fail=1
+#! $SHELL
+# Generated by $as_me.
+# Run this file to recreate the current configuration.
+# Compiler output produced by configure, useful for debugging
+# configure, is in config.log if it exists.
+
+debug=false
+ac_cs_recheck=false
+ac_cs_silent=false
+
+SHELL=\${CONFIG_SHELL-$SHELL}
+export SHELL
+_ASEOF
+cat >>$CONFIG_STATUS <<\_ASEOF || as_write_fail=1
+## -------------------- ##
+## M4sh Initialization. ##
+## -------------------- ##
+
+# Be more Bourne compatible
+DUALCASE=1; export DUALCASE # for MKS sh
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then :
+ emulate sh
+ NULLCMD=:
+ # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which
+ # is contrary to our usage. Disable this feature.
+ alias -g '${1+"$@"}'='"$@"'
+ setopt NO_GLOB_SUBST
+else
+ case `(set -o) 2>/dev/null` in #(
+ *posix*) :
+ set -o posix ;; #(
+ *) :
+ ;;
+esac
+fi
+
+
+as_nl='
+'
+export as_nl
+# Printing a long string crashes Solaris 7 /usr/bin/printf.
+as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'
+as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo
+as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo
+# Prefer a ksh shell builtin over an external printf program on Solaris,
+# but without wasting forks for bash or zsh.
+if test -z "$BASH_VERSION$ZSH_VERSION" \
+ && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then
+ as_echo='print -r --'
+ as_echo_n='print -rn --'
+elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then
+ as_echo='printf %s\n'
+ as_echo_n='printf %s'
+else
+ if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then
+ as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"'
+ as_echo_n='/usr/ucb/echo -n'
+ else
+ as_echo_body='eval expr "X$1" : "X\\(.*\\)"'
+ as_echo_n_body='eval
+ arg=$1;
+ case $arg in #(
+ *"$as_nl"*)
+ expr "X$arg" : "X\\(.*\\)$as_nl";
+ arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;;
+ esac;
+ expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl"
+ '
+ export as_echo_n_body
+ as_echo_n='sh -c $as_echo_n_body as_echo'
+ fi
+ export as_echo_body
+ as_echo='sh -c $as_echo_body as_echo'
+fi
+
+# The user is always right.
+if test "${PATH_SEPARATOR+set}" != set; then
+ PATH_SEPARATOR=:
+ (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && {
+ (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 ||
+ PATH_SEPARATOR=';'
+ }
+fi
+
+
+# IFS
+# We need space, tab and new line, in precisely that order. Quoting is
+# there to prevent editors from complaining about space-tab.
+# (If _AS_PATH_WALK were called with IFS unset, it would disable word
+# splitting by setting IFS to empty value.)
+IFS=" "" $as_nl"
+
+# Find who we are. Look in the path if we contain no directory separator.
+as_myself=
+case $0 in #((
+ *[\\/]* ) as_myself=$0 ;;
+ *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
+ done
+IFS=$as_save_IFS
+
+ ;;
+esac
+# We did not find ourselves, most probably we were run as `sh COMMAND'
+# in which case we are not to be found in the path.
+if test "x$as_myself" = x; then
+ as_myself=$0
+fi
+if test ! -f "$as_myself"; then
+ $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2
+ exit 1
+fi
+
+# Unset variables that we do not need and which cause bugs (e.g. in
+# pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1"
+# suppresses any "Segmentation fault" message there. '((' could
+# trigger a bug in pdksh 5.2.14.
+for as_var in BASH_ENV ENV MAIL MAILPATH
+do eval test x\${$as_var+set} = xset \
+ && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || :
+done
+PS1='$ '
+PS2='> '
+PS4='+ '
+
+# NLS nuisances.
+LC_ALL=C
+export LC_ALL
+LANGUAGE=C
+export LANGUAGE
+
+# CDPATH.
+(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
+
+
+# as_fn_error STATUS ERROR [LINENO LOG_FD]
+# ----------------------------------------
+# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are
+# provided, also output the error to LOG_FD, referencing LINENO. Then exit the
+# script with STATUS, using 1 if that was 0.
+as_fn_error ()
+{
+ as_status=$1; test $as_status -eq 0 && as_status=1
+ if test "$4"; then
+ as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4
+ fi
+ $as_echo "$as_me: error: $2" >&2
+ as_fn_exit $as_status
+} # as_fn_error
+
+
+# as_fn_set_status STATUS
+# -----------------------
+# Set $? to STATUS, without forking.
+as_fn_set_status ()
+{
+ return $1
+} # as_fn_set_status
+
+# as_fn_exit STATUS
+# -----------------
+# Exit the shell with STATUS, even in a "trap 0" or "set -e" context.
+as_fn_exit ()
+{
+ set +e
+ as_fn_set_status $1
+ exit $1
+} # as_fn_exit
+
+# as_fn_unset VAR
+# ---------------
+# Portably unset VAR.
+as_fn_unset ()
+{
+ { eval $1=; unset $1;}
+}
+as_unset=as_fn_unset
+# as_fn_append VAR VALUE
+# ----------------------
+# Append the text in VALUE to the end of the definition contained in VAR. Take
+# advantage of any shell optimizations that allow amortized linear growth over
+# repeated appends, instead of the typical quadratic growth present in naive
+# implementations.
+if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then :
+ eval 'as_fn_append ()
+ {
+ eval $1+=\$2
+ }'
+else
+ as_fn_append ()
+ {
+ eval $1=\$$1\$2
+ }
+fi # as_fn_append
+
+# as_fn_arith ARG...
+# ------------------
+# Perform arithmetic evaluation on the ARGs, and store the result in the
+# global $as_val. Take advantage of shells that can avoid forks. The arguments
+# must be portable across $(()) and expr.
+if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then :
+ eval 'as_fn_arith ()
+ {
+ as_val=$(( $* ))
+ }'
+else
+ as_fn_arith ()
+ {
+ as_val=`expr "$@" || test $? -eq 1`
+ }
+fi # as_fn_arith
+
+
+if expr a : '\(a\)' >/dev/null 2>&1 &&
+ test "X`expr 00001 : '.*\(...\)'`" = X001; then
+ as_expr=expr
+else
+ as_expr=false
+fi
+
+if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then
+ as_basename=basename
+else
+ as_basename=false
+fi
+
+if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then
+ as_dirname=dirname
+else
+ as_dirname=false
+fi
+
+as_me=`$as_basename -- "$0" ||
+$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
+ X"$0" : 'X\(//\)$' \| \
+ X"$0" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X/"$0" |
+ sed '/^.*\/\([^/][^/]*\)\/*$/{
+ s//\1/
+ q
+ }
+ /^X\/\(\/\/\)$/{
+ s//\1/
+ q
+ }
+ /^X\/\(\/\).*/{
+ s//\1/
+ q
+ }
+ s/.*/./; q'`
+
+# Avoid depending upon Character Ranges.
+as_cr_letters='abcdefghijklmnopqrstuvwxyz'
+as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
+as_cr_Letters=$as_cr_letters$as_cr_LETTERS
+as_cr_digits='0123456789'
+as_cr_alnum=$as_cr_Letters$as_cr_digits
+
+ECHO_C= ECHO_N= ECHO_T=
+case `echo -n x` in #(((((
+-n*)
+ case `echo 'xy\c'` in
+ *c*) ECHO_T=' ';; # ECHO_T is single tab character.
+ xy) ECHO_C='\c';;
+ *) echo `echo ksh88 bug on AIX 6.1` > /dev/null
+ ECHO_T=' ';;
+ esac;;
+*)
+ ECHO_N='-n';;
+esac
+
+rm -f conf$$ conf$$.exe conf$$.file
+if test -d conf$$.dir; then
+ rm -f conf$$.dir/conf$$.file
+else
+ rm -f conf$$.dir
+ mkdir conf$$.dir 2>/dev/null
+fi
+if (echo >conf$$.file) 2>/dev/null; then
+ if ln -s conf$$.file conf$$ 2>/dev/null; then
+ as_ln_s='ln -s'
+ # ... but there are two gotchas:
+ # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail.
+ # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable.
+ # In both cases, we have to default to `cp -p'.
+ ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe ||
+ as_ln_s='cp -p'
+ elif ln conf$$.file conf$$ 2>/dev/null; then
+ as_ln_s=ln
+ else
+ as_ln_s='cp -p'
+ fi
+else
+ as_ln_s='cp -p'
+fi
+rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file
+rmdir conf$$.dir 2>/dev/null
+
+
+# as_fn_mkdir_p
+# -------------
+# Create "$as_dir" as a directory, including parents if necessary.
+as_fn_mkdir_p ()
+{
+
+ case $as_dir in #(
+ -*) as_dir=./$as_dir;;
+ esac
+ test -d "$as_dir" || eval $as_mkdir_p || {
+ as_dirs=
+ while :; do
+ case $as_dir in #(
+ *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'(
+ *) as_qdir=$as_dir;;
+ esac
+ as_dirs="'$as_qdir' $as_dirs"
+ as_dir=`$as_dirname -- "$as_dir" ||
+$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$as_dir" : 'X\(//\)[^/]' \| \
+ X"$as_dir" : 'X\(//\)$' \| \
+ X"$as_dir" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$as_dir" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)[^/].*/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\).*/{
+ s//\1/
+ q
+ }
+ s/.*/./; q'`
+ test -d "$as_dir" && break
+ done
+ test -z "$as_dirs" || eval "mkdir $as_dirs"
+ } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir"
+
+
+} # as_fn_mkdir_p
+if mkdir -p . 2>/dev/null; then
+ as_mkdir_p='mkdir -p "$as_dir"'
+else
+ test -d ./-p && rmdir ./-p
+ as_mkdir_p=false
+fi
+
+if test -x / >/dev/null 2>&1; then
+ as_test_x='test -x'
+else
+ if ls -dL / >/dev/null 2>&1; then
+ as_ls_L_option=L
+ else
+ as_ls_L_option=
+ fi
+ as_test_x='
+ eval sh -c '\''
+ if test -d "$1"; then
+ test -d "$1/.";
+ else
+ case $1 in #(
+ -*)set "./$1";;
+ esac;
+ case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in #((
+ ???[sx]*):;;*)false;;esac;fi
+ '\'' sh
+ '
+fi
+as_executable_p=$as_test_x
+
+# Sed expression to map a string onto a valid CPP name.
+as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"
+
+# Sed expression to map a string onto a valid variable name.
+as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'"
+
+
+exec 6>&1
+## ----------------------------------- ##
+## Main body of $CONFIG_STATUS script. ##
+## ----------------------------------- ##
+_ASEOF
+test $as_write_fail = 0 && chmod +x $CONFIG_STATUS || ac_write_fail=1
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+# Save the log message, to keep $0 and so on meaningful, and to
+# report actual input values of CONFIG_FILES etc. instead of their
+# values after options handling.
+ac_log="
+This file was extended by $as_me, which was
+generated by GNU Autoconf 2.68. Invocation command line was
+
+ CONFIG_FILES = $CONFIG_FILES
+ CONFIG_HEADERS = $CONFIG_HEADERS
+ CONFIG_LINKS = $CONFIG_LINKS
+ CONFIG_COMMANDS = $CONFIG_COMMANDS
+ $ $0 $@
+
+on `(hostname || uname -n) 2>/dev/null | sed 1q`
+"
+
+_ACEOF
+
+case $ac_config_files in *"
+"*) set x $ac_config_files; shift; ac_config_files=$*;;
+esac
+
+case $ac_config_headers in *"
+"*) set x $ac_config_headers; shift; ac_config_headers=$*;;
+esac
+
+
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+# Files that config.status was made for.
+config_files="$ac_config_files"
+config_headers="$ac_config_headers"
+
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+ac_cs_usage="\
+\`$as_me' instantiates files and other configuration actions
+from templates according to the current configuration. Unless the files
+and actions are specified as TAGs, all are instantiated by default.
+
+Usage: $0 [OPTION]... [TAG]...
+
+ -h, --help print this help, then exit
+ -V, --version print version number and configuration settings, then exit
+ --config print configuration, then exit
+ -q, --quiet, --silent
+ do not print progress messages
+ -d, --debug don't remove temporary files
+ --recheck update $as_me by reconfiguring in the same conditions
+ --file=FILE[:TEMPLATE]
+ instantiate the configuration file FILE
+ --header=FILE[:TEMPLATE]
+ instantiate the configuration header FILE
+
+Configuration files:
+$config_files
+
+Configuration headers:
+$config_headers
+
+Report bugs to the package provider."
+
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
+ac_cs_version="\\
+config.status
+configured by $0, generated by GNU Autoconf 2.68,
+ with options \\"\$ac_cs_config\\"
+
+Copyright (C) 2010 Free Software Foundation, Inc.
+This config.status script is free software; the Free Software Foundation
+gives unlimited permission to copy, distribute and modify it."
+
+ac_pwd='$ac_pwd'
+srcdir='$srcdir'
+INSTALL='$INSTALL'
+test -n "\$AWK" || AWK=awk
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+# The default lists apply if the user does not specify any file.
+ac_need_defaults=:
+while test $# != 0
+do
+ case $1 in
+ --*=?*)
+ ac_option=`expr "X$1" : 'X\([^=]*\)='`
+ ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'`
+ ac_shift=:
+ ;;
+ --*=)
+ ac_option=`expr "X$1" : 'X\([^=]*\)='`
+ ac_optarg=
+ ac_shift=:
+ ;;
+ *)
+ ac_option=$1
+ ac_optarg=$2
+ ac_shift=shift
+ ;;
+ esac
+
+ case $ac_option in
+ # Handling of the options.
+ -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)
+ ac_cs_recheck=: ;;
+ --version | --versio | --versi | --vers | --ver | --ve | --v | -V )
+ $as_echo "$ac_cs_version"; exit ;;
+ --config | --confi | --conf | --con | --co | --c )
+ $as_echo "$ac_cs_config"; exit ;;
+ --debug | --debu | --deb | --de | --d | -d )
+ debug=: ;;
+ --file | --fil | --fi | --f )
+ $ac_shift
+ case $ac_optarg in
+ *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;;
+ '') as_fn_error $? "missing file argument" ;;
+ esac
+ as_fn_append CONFIG_FILES " '$ac_optarg'"
+ ac_need_defaults=false;;
+ --header | --heade | --head | --hea )
+ $ac_shift
+ case $ac_optarg in
+ *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;;
+ esac
+ as_fn_append CONFIG_HEADERS " '$ac_optarg'"
+ ac_need_defaults=false;;
+ --he | --h)
+ # Conflict between --help and --header
+ as_fn_error $? "ambiguous option: \`$1'
+Try \`$0 --help' for more information.";;
+ --help | --hel | -h )
+ $as_echo "$ac_cs_usage"; exit ;;
+ -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+ | -silent | --silent | --silen | --sile | --sil | --si | --s)
+ ac_cs_silent=: ;;
+
+ # This is an error.
+ -*) as_fn_error $? "unrecognized option: \`$1'
+Try \`$0 --help' for more information." ;;
+
+ *) as_fn_append ac_config_targets " $1"
+ ac_need_defaults=false ;;
+
+ esac
+ shift
+done
+
+ac_configure_extra_args=
+
+if $ac_cs_silent; then
+ exec 6>/dev/null
+ ac_configure_extra_args="$ac_configure_extra_args --silent"
+fi
+
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+if \$ac_cs_recheck; then
+ set X '$SHELL' '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion
+ shift
+ \$as_echo "running CONFIG_SHELL=$SHELL \$*" >&6
+ CONFIG_SHELL='$SHELL'
+ export CONFIG_SHELL
+ exec "\$@"
+fi
+
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+exec 5>>config.log
+{
+ echo
+ sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX
+## Running $as_me. ##
+_ASBOX
+ $as_echo "$ac_log"
+} >&5
+
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+
+# Handling of arguments.
+for ac_config_target in $ac_config_targets
+do
+ case $ac_config_target in
+ "config.h") CONFIG_HEADERS="$CONFIG_HEADERS config.h" ;;
+ "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;;
+
+ *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;;
+ esac
+done
+
+
+# If the user did not use the arguments to specify the items to instantiate,
+# then the envvar interface is used. Set only those that are not.
+# We use the long form for the default assignment because of an extremely
+# bizarre bug on SunOS 4.1.3.
+if $ac_need_defaults; then
+ test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files
+ test "${CONFIG_HEADERS+set}" = set || CONFIG_HEADERS=$config_headers
+fi
+
+# Have a temporary directory for convenience. Make it in the build tree
+# simply because there is no reason against having it here, and in addition,
+# creating and moving files from /tmp can sometimes cause problems.
+# Hook for its removal unless debugging.
+# Note that there is a small window in which the directory will not be cleaned:
+# after its creation but before its name has been assigned to `$tmp'.
+$debug ||
+{
+ tmp= ac_tmp=
+ trap 'exit_status=$?
+ : "${ac_tmp:=$tmp}"
+ { test ! -d "$ac_tmp" || rm -fr "$ac_tmp"; } && exit $exit_status
+' 0
+ trap 'as_fn_exit 1' 1 2 13 15
+}
+# Create a (secure) tmp directory for tmp files.
+
+{
+ tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` &&
+ test -d "$tmp"
+} ||
+{
+ tmp=./conf$$-$RANDOM
+ (umask 077 && mkdir "$tmp")
+} || as_fn_error $? "cannot create a temporary directory in ." "$LINENO" 5
+ac_tmp=$tmp
+
+# Set up the scripts for CONFIG_FILES section.
+# No need to generate them if there are no CONFIG_FILES.
+# This happens for instance with `./config.status config.h'.
+if test -n "$CONFIG_FILES"; then
+
+
+ac_cr=`echo X | tr X '\015'`
+# On cygwin, bash can eat \r inside `` if the user requested igncr.
+# But we know of no other shell where ac_cr would be empty at this
+# point, so we can use a bashism as a fallback.
+if test "x$ac_cr" = x; then
+ eval ac_cr=\$\'\\r\'
+fi
+ac_cs_awk_cr=`$AWK 'BEGIN { print "a\rb" }' </dev/null 2>/dev/null`
+if test "$ac_cs_awk_cr" = "a${ac_cr}b"; then
+ ac_cs_awk_cr='\\r'
+else
+ ac_cs_awk_cr=$ac_cr
+fi
+
+echo 'BEGIN {' >"$ac_tmp/subs1.awk" &&
+_ACEOF
+
+
+{
+ echo "cat >conf$$subs.awk <<_ACEOF" &&
+ echo "$ac_subst_vars" | sed 's/.*/&!$&$ac_delim/' &&
+ echo "_ACEOF"
+} >conf$$subs.sh ||
+ as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5
+ac_delim_num=`echo "$ac_subst_vars" | grep -c '^'`
+ac_delim='%!_!# '
+for ac_last_try in false false false false false :; do
+ . ./conf$$subs.sh ||
+ as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5
+
+ ac_delim_n=`sed -n "s/.*$ac_delim\$/X/p" conf$$subs.awk | grep -c X`
+ if test $ac_delim_n = $ac_delim_num; then
+ break
+ elif $ac_last_try; then
+ as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5
+ else
+ ac_delim="$ac_delim!$ac_delim _$ac_delim!! "
+ fi
+done
+rm -f conf$$subs.sh
+
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+cat >>"\$ac_tmp/subs1.awk" <<\\_ACAWK &&
+_ACEOF
+sed -n '
+h
+s/^/S["/; s/!.*/"]=/
+p
+g
+s/^[^!]*!//
+:repl
+t repl
+s/'"$ac_delim"'$//
+t delim
+:nl
+h
+s/\(.\{148\}\)..*/\1/
+t more1
+s/["\\]/\\&/g; s/^/"/; s/$/\\n"\\/
+p
+n
+b repl
+:more1
+s/["\\]/\\&/g; s/^/"/; s/$/"\\/
+p
+g
+s/.\{148\}//
+t nl
+:delim
+h
+s/\(.\{148\}\)..*/\1/
+t more2
+s/["\\]/\\&/g; s/^/"/; s/$/"/
+p
+b
+:more2
+s/["\\]/\\&/g; s/^/"/; s/$/"\\/
+p
+g
+s/.\{148\}//
+t delim
+' <conf$$subs.awk | sed '
+/^[^""]/{
+ N
+ s/\n//
+}
+' >>$CONFIG_STATUS || ac_write_fail=1
+rm -f conf$$subs.awk
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+_ACAWK
+cat >>"\$ac_tmp/subs1.awk" <<_ACAWK &&
+ for (key in S) S_is_set[key] = 1
+ FS = ""
+
+}
+{
+ line = $ 0
+ nfields = split(line, field, "@")
+ substed = 0
+ len = length(field[1])
+ for (i = 2; i < nfields; i++) {
+ key = field[i]
+ keylen = length(key)
+ if (S_is_set[key]) {
+ value = S[key]
+ line = substr(line, 1, len) "" value "" substr(line, len + keylen + 3)
+ len += length(value) + length(field[++i])
+ substed = 1
+ } else
+ len += 1 + keylen
+ }
+
+ print line
+}
+
+_ACAWK
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+if sed "s/$ac_cr//" < /dev/null > /dev/null 2>&1; then
+ sed "s/$ac_cr\$//; s/$ac_cr/$ac_cs_awk_cr/g"
+else
+ cat
+fi < "$ac_tmp/subs1.awk" > "$ac_tmp/subs.awk" \
+ || as_fn_error $? "could not setup config files machinery" "$LINENO" 5
+_ACEOF
+
+# VPATH may cause trouble with some makes, so we remove sole $(srcdir),
+# ${srcdir} and @srcdir@ entries from VPATH if srcdir is ".", strip leading and
+# trailing colons and then remove the whole line if VPATH becomes empty
+# (actually we leave an empty line to preserve line numbers).
+if test "x$srcdir" = x.; then
+ ac_vpsub='/^[ ]*VPATH[ ]*=[ ]*/{
+h
+s///
+s/^/:/
+s/[ ]*$/:/
+s/:\$(srcdir):/:/g
+s/:\${srcdir}:/:/g
+s/:@srcdir@:/:/g
+s/^:*//
+s/:*$//
+x
+s/\(=[ ]*\).*/\1/
+G
+s/\n//
+s/^[^=]*=[ ]*$//
+}'
+fi
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+fi # test -n "$CONFIG_FILES"
+
+# Set up the scripts for CONFIG_HEADERS section.
+# No need to generate them if there are no CONFIG_HEADERS.
+# This happens for instance with `./config.status Makefile'.
+if test -n "$CONFIG_HEADERS"; then
+cat >"$ac_tmp/defines.awk" <<\_ACAWK ||
+BEGIN {
+_ACEOF
+
+# Transform confdefs.h into an awk script `defines.awk', embedded as
+# here-document in config.status, that substitutes the proper values into
+# config.h.in to produce config.h.
+
+# Create a delimiter string that does not exist in confdefs.h, to ease
+# handling of long lines.
+ac_delim='%!_!# '
+for ac_last_try in false false :; do
+ ac_tt=`sed -n "/$ac_delim/p" confdefs.h`
+ if test -z "$ac_tt"; then
+ break
+ elif $ac_last_try; then
+ as_fn_error $? "could not make $CONFIG_HEADERS" "$LINENO" 5
+ else
+ ac_delim="$ac_delim!$ac_delim _$ac_delim!! "
+ fi
+done
+
+# For the awk script, D is an array of macro values keyed by name,
+# likewise P contains macro parameters if any. Preserve backslash
+# newline sequences.
+
+ac_word_re=[_$as_cr_Letters][_$as_cr_alnum]*
+sed -n '
+s/.\{148\}/&'"$ac_delim"'/g
+t rset
+:rset
+s/^[ ]*#[ ]*define[ ][ ]*/ /
+t def
+d
+:def
+s/\\$//
+t bsnl
+s/["\\]/\\&/g
+s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\
+D["\1"]=" \3"/p
+s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2"/p
+d
+:bsnl
+s/["\\]/\\&/g
+s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\
+D["\1"]=" \3\\\\\\n"\\/p
+t cont
+s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2\\\\\\n"\\/p
+t cont
+d
+:cont
+n
+s/.\{148\}/&'"$ac_delim"'/g
+t clear
+:clear
+s/\\$//
+t bsnlc
+s/["\\]/\\&/g; s/^/"/; s/$/"/p
+d
+:bsnlc
+s/["\\]/\\&/g; s/^/"/; s/$/\\\\\\n"\\/p
+b cont
+' <confdefs.h | sed '
+s/'"$ac_delim"'/"\\\
+"/g' >>$CONFIG_STATUS || ac_write_fail=1
+
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+ for (key in D) D_is_set[key] = 1
+ FS = ""
+}
+/^[\t ]*#[\t ]*(define|undef)[\t ]+$ac_word_re([\t (]|\$)/ {
+ line = \$ 0
+ split(line, arg, " ")
+ if (arg[1] == "#") {
+ defundef = arg[2]
+ mac1 = arg[3]
+ } else {
+ defundef = substr(arg[1], 2)
+ mac1 = arg[2]
+ }
+ split(mac1, mac2, "(") #)
+ macro = mac2[1]
+ prefix = substr(line, 1, index(line, defundef) - 1)
+ if (D_is_set[macro]) {
+ # Preserve the white space surrounding the "#".
+ print prefix "define", macro P[macro] D[macro]
+ next
+ } else {
+ # Replace #undef with comments. This is necessary, for example,
+ # in the case of _POSIX_SOURCE, which is predefined and required
+ # on some systems where configure will not decide to define it.
+ if (defundef == "undef") {
+ print "/*", prefix defundef, macro, "*/"
+ next
+ }
+ }
+}
+{ print }
+_ACAWK
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+ as_fn_error $? "could not setup config headers machinery" "$LINENO" 5
+fi # test -n "$CONFIG_HEADERS"
+
+
+eval set X " :F $CONFIG_FILES :H $CONFIG_HEADERS "
+shift
+for ac_tag
+do
+ case $ac_tag in
+ :[FHLC]) ac_mode=$ac_tag; continue;;
+ esac
+ case $ac_mode$ac_tag in
+ :[FHL]*:*);;
+ :L* | :C*:*) as_fn_error $? "invalid tag \`$ac_tag'" "$LINENO" 5;;
+ :[FH]-) ac_tag=-:-;;
+ :[FH]*) ac_tag=$ac_tag:$ac_tag.in;;
+ esac
+ ac_save_IFS=$IFS
+ IFS=:
+ set x $ac_tag
+ IFS=$ac_save_IFS
+ shift
+ ac_file=$1
+ shift
+
+ case $ac_mode in
+ :L) ac_source=$1;;
+ :[FH])
+ ac_file_inputs=
+ for ac_f
+ do
+ case $ac_f in
+ -) ac_f="$ac_tmp/stdin";;
+ *) # Look for the file first in the build tree, then in the source tree
+ # (if the path is not absolute). The absolute path cannot be DOS-style,
+ # because $ac_f cannot contain `:'.
+ test -f "$ac_f" ||
+ case $ac_f in
+ [\\/$]*) false;;
+ *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";;
+ esac ||
+ as_fn_error 1 "cannot find input file: \`$ac_f'" "$LINENO" 5;;
+ esac
+ case $ac_f in *\'*) ac_f=`$as_echo "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac
+ as_fn_append ac_file_inputs " '$ac_f'"
+ done
+
+ # Let's still pretend it is `configure' which instantiates (i.e., don't
+ # use $as_me), people would be surprised to read:
+ # /* config.h. Generated by config.status. */
+ configure_input='Generated from '`
+ $as_echo "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g'
+ `' by configure.'
+ if test x"$ac_file" != x-; then
+ configure_input="$ac_file. $configure_input"
+ { $as_echo "$as_me:${as_lineno-$LINENO}: creating $ac_file" >&5
+$as_echo "$as_me: creating $ac_file" >&6;}
+ fi
+ # Neutralize special characters interpreted by sed in replacement strings.
+ case $configure_input in #(
+ *\&* | *\|* | *\\* )
+ ac_sed_conf_input=`$as_echo "$configure_input" |
+ sed 's/[\\\\&|]/\\\\&/g'`;; #(
+ *) ac_sed_conf_input=$configure_input;;
+ esac
+
+ case $ac_tag in
+ *:-:* | *:-) cat >"$ac_tmp/stdin" \
+ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;;
+ esac
+ ;;
+ esac
+
+ ac_dir=`$as_dirname -- "$ac_file" ||
+$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$ac_file" : 'X\(//\)[^/]' \| \
+ X"$ac_file" : 'X\(//\)$' \| \
+ X"$ac_file" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$ac_file" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)[^/].*/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\).*/{
+ s//\1/
+ q
+ }
+ s/.*/./; q'`
+ as_dir="$ac_dir"; as_fn_mkdir_p
+ ac_builddir=.
+
+case "$ac_dir" in
+.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;;
+*)
+ ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'`
+ # A ".." for each directory in $ac_dir_suffix.
+ ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'`
+ case $ac_top_builddir_sub in
+ "") ac_top_builddir_sub=. ac_top_build_prefix= ;;
+ *) ac_top_build_prefix=$ac_top_builddir_sub/ ;;
+ esac ;;
+esac
+ac_abs_top_builddir=$ac_pwd
+ac_abs_builddir=$ac_pwd$ac_dir_suffix
+# for backward compatibility:
+ac_top_builddir=$ac_top_build_prefix
+
+case $srcdir in
+ .) # We are building in place.
+ ac_srcdir=.
+ ac_top_srcdir=$ac_top_builddir_sub
+ ac_abs_top_srcdir=$ac_pwd ;;
+ [\\/]* | ?:[\\/]* ) # Absolute name.
+ ac_srcdir=$srcdir$ac_dir_suffix;
+ ac_top_srcdir=$srcdir
+ ac_abs_top_srcdir=$srcdir ;;
+ *) # Relative name.
+ ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix
+ ac_top_srcdir=$ac_top_build_prefix$srcdir
+ ac_abs_top_srcdir=$ac_pwd/$srcdir ;;
+esac
+ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix
+
+
+ case $ac_mode in
+ :F)
+ #
+ # CONFIG_FILE
+ #
+
+ case $INSTALL in
+ [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;;
+ *) ac_INSTALL=$ac_top_build_prefix$INSTALL ;;
+ esac
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+# If the template does not know about datarootdir, expand it.
+# FIXME: This hack should be removed a few years after 2.60.
+ac_datarootdir_hack=; ac_datarootdir_seen=
+ac_sed_dataroot='
+/datarootdir/ {
+ p
+ q
+}
+/@datadir@/p
+/@docdir@/p
+/@infodir@/p
+/@localedir@/p
+/@mandir@/p'
+case `eval "sed -n \"\$ac_sed_dataroot\" $ac_file_inputs"` in
+*datarootdir*) ac_datarootdir_seen=yes;;
+*@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5
+$as_echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;}
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+ ac_datarootdir_hack='
+ s&@datadir@&$datadir&g
+ s&@docdir@&$docdir&g
+ s&@infodir@&$infodir&g
+ s&@localedir@&$localedir&g
+ s&@mandir@&$mandir&g
+ s&\\\${datarootdir}&$datarootdir&g' ;;
+esac
+_ACEOF
+
+# Neutralize VPATH when `$srcdir' = `.'.
+# Shell code in configure.ac might set extrasub.
+# FIXME: do we really want to maintain this feature?
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+ac_sed_extra="$ac_vpsub
+$extrasub
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+:t
+/@[a-zA-Z_][a-zA-Z_0-9]*@/!b
+s|@configure_input@|$ac_sed_conf_input|;t t
+s&@top_builddir@&$ac_top_builddir_sub&;t t
+s&@top_build_prefix@&$ac_top_build_prefix&;t t
+s&@srcdir@&$ac_srcdir&;t t
+s&@abs_srcdir@&$ac_abs_srcdir&;t t
+s&@top_srcdir@&$ac_top_srcdir&;t t
+s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t
+s&@builddir@&$ac_builddir&;t t
+s&@abs_builddir@&$ac_abs_builddir&;t t
+s&@abs_top_builddir@&$ac_abs_top_builddir&;t t
+s&@INSTALL@&$ac_INSTALL&;t t
+$ac_datarootdir_hack
+"
+eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$ac_tmp/subs.awk" \
+ >$ac_tmp/out || as_fn_error $? "could not create $ac_file" "$LINENO" 5
+
+test -z "$ac_datarootdir_hack$ac_datarootdir_seen" &&
+ { ac_out=`sed -n '/\${datarootdir}/p' "$ac_tmp/out"`; test -n "$ac_out"; } &&
+ { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' \
+ "$ac_tmp/out"`; test -z "$ac_out"; } &&
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable \`datarootdir'
+which seems to be undefined. Please make sure it is defined" >&5
+$as_echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir'
+which seems to be undefined. Please make sure it is defined" >&2;}
+
+ rm -f "$ac_tmp/stdin"
+ case $ac_file in
+ -) cat "$ac_tmp/out" && rm -f "$ac_tmp/out";;
+ *) rm -f "$ac_file" && mv "$ac_tmp/out" "$ac_file";;
+ esac \
+ || as_fn_error $? "could not create $ac_file" "$LINENO" 5
+ ;;
+ :H)
+ #
+ # CONFIG_HEADER
+ #
+ if test x"$ac_file" != x-; then
+ {
+ $as_echo "/* $configure_input */" \
+ && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs"
+ } >"$ac_tmp/config.h" \
+ || as_fn_error $? "could not create $ac_file" "$LINENO" 5
+ if diff "$ac_file" "$ac_tmp/config.h" >/dev/null 2>&1; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: $ac_file is unchanged" >&5
+$as_echo "$as_me: $ac_file is unchanged" >&6;}
+ else
+ rm -f "$ac_file"
+ mv "$ac_tmp/config.h" "$ac_file" \
+ || as_fn_error $? "could not create $ac_file" "$LINENO" 5
+ fi
+ else
+ $as_echo "/* $configure_input */" \
+ && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" \
+ || as_fn_error $? "could not create -" "$LINENO" 5
+ fi
+ ;;
+
+
+ esac
+
+done # for ac_tag
+
+
+as_fn_exit 0
+_ACEOF
+ac_clean_files=$ac_clean_files_save
+
+test $ac_write_fail = 0 ||
+ as_fn_error $? "write failure creating $CONFIG_STATUS" "$LINENO" 5
+
+
+# configure is writing to config.log, and then calls config.status.
+# config.status does its own redirection, appending to config.log.
+# Unfortunately, on DOS this fails, as config.log is still kept open
+# by configure, so config.status won't be able to write to it; its
+# output is simply discarded. So we exec the FD to /dev/null,
+# effectively closing config.log, so it can be properly (re)opened and
+# appended to by config.status. When coming back to configure, we
+# need to make the FD available again.
+if test "$no_create" != yes; then
+ ac_cs_success=:
+ ac_config_status_args=
+ test "$silent" = yes &&
+ ac_config_status_args="$ac_config_status_args --quiet"
+ exec 5>/dev/null
+ $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false
+ exec 5>>config.log
+ # Use ||, not &&, to avoid exiting from the if with $? = 1, which
+ # would make configure fail if this is the last instruction.
+ $ac_cs_success || as_fn_exit 1
+fi
+if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5
+$as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;}
+fi
+
diff --git a/dwarfdump/configure.in b/dwarfdump/configure.in
new file mode 100644
index 0000000..753a1b4
--- /dev/null
+++ b/dwarfdump/configure.in
@@ -0,0 +1,98 @@
+dnl Process this file with autoconf to produce a configure script.
+AC_INIT(dwarfdump.c)
+AC_CONFIG_HEADER(config.h)
+
+AC_PROG_CC
+AC_GCC_TRADITIONAL
+AC_PROG_INSTALL
+AC_CHECK_TOOL(RANLIB, ranlib, :)
+AC_CHECK_TOOL(AR, ar)
+dnl AC_ARFLAGS
+
+AC_CHECK_HEADERS(elf.h getopt.h libelf.h libelf/libelf.h sgidefs.h sys/types.h)
+AC_CHECK_LIB(elf,elf64_getehdr,
+ AC_DEFINE(HAVE_ELF64_GETEHDR,1,
+ [Define to 1 if the elf64_getehdr function is in libelf.a.]))
+
+dnl Find out where the elf header is.
+if test "$ac_cv_header_elf_h" = yes; then
+ AC_DEFINE(LOCATION_OF_LIBELFHEADER,[<elf.h>], [Define to header that first defines elf])
+elif test "$ac_cv_header_libelf_h" = yes; then
+ AC_DEFINE(LOCATION_OF_LIBELFHEADER, [<libelf.h>],
+ [Define to header that first defines elf.])
+elif test "$ac_cv_header_libelf_libelf_h" = yes; then
+ AC_DEFINE(LOCATION_OF_LIBELFHEADER,[<libelf/libelf.h>],
+ [Define to header that first defines elf.])
+fi
+
+AC_TRY_COMPILE([#include "stdafx.h"],[ int p; p = 27;] ,
+ AC_DEFINE(HAVE_STDAFX_H,1,
+ [Define 1 if we have the Windows specific header stdafx.h]))
+
+AC_TRY_COMPILE([#include LOCATION_OF_LIBELFHEADER], Elf64_Rel *p; int i; i = p->r_info; ,AC_DEFINE(HAVE_ELF64_R_INFO,1,
+ [Define to 1 if the Elf64_Rel structure has r_info field.]))
+AC_TRY_COMPILE([], __uint32_t p; p = 3; ,AC_DEFINE(HAVE___UINT32_T,
+ 1,[See if __uint32_t is predefined in the compiler. ]))
+AC_TRY_COMPILE([], __uint64_t p; p = 3; ,AC_DEFINE(HAVE___UINT64_T,
+ 1,[See if __uint64_t is predefined in the compiler. ]))
+AC_TRY_COMPILE([#include <sys/types.h>],[ __uint32_t p; p = 3]; ,
+ AC_DEFINE(HAVE___UINT32_T_IN_SYS_TYPES_H,1,
+ [Define 1 if sys/types.h defines __uint32_t.]))
+AC_TRY_COMPILE([#include <sys/types.h>
+ #include <regex.h>],[ int i;
+ regex_t r;
+ int cflags = REG_EXTENDED;
+ const char *s = "abc";
+ i = regcomp(&r,s,cflags);
+ regfree(&r);
+ ]; ,
+ AC_DEFINE(HAVE_REGEX,1,
+ [Define 1 if regex seems to be defined]))
+AC_TRY_LINK([#include <stdio.h>
+#include <stdlib.h>
+/* On Ubuntu 10.x, tsearch is in package libc6-dev. */
+/* The tdestroy function is GNU, not POSIX. */
+#define __USE_GNU 1
+#include <search.h>
+struct my_tentry {
+ long mt_key;
+ char * mt_name;
+};
+struct my_tentry * make_my_tentry(long k,char *name) { return 0; }
+void mt_free_func(void *mt_data) { return; }
+int mt_compare_func(const void *l, const void *r) { return 0; }],[
+ long i = 1;
+ void *tree1 = 0;
+ char *dbuf = 0;
+ struct my_tentry *mt = 0;
+ struct my_tentry *retval = 0;
+ mt = make_my_tentry(i,dbuf);
+ retval = tsearch(mt,&tree1, mt_compare_func );
+ tdestroy(tree1,mt_free_func);
+ exit(0);
+];,
+ AC_DEFINE(HAVE_TSEARCH,1,
+ [Define 1 if the tsearch functions seem to be defined]))
+
+
+AC_ARG_ENABLE(nonstandardprintf,AC_HELP_STRING([--enable-nonstandardprintf],
+ [Use a special printf format for 64bit (default is NO)]),
+ [ AC_DEFINE([HAVE_NONSTANDARD_PRINTF_64_FORMAT],[1],
+ [Define 1 if need nonstandard printf format for 64bit] )],
+ [])
+
+AC_TRY_COMPILE([
+#include <libelf.h>
+],[ int p; p = 0; ] ,
+ AC_DEFINE(HAVE_RAW_LIBELF_OK,1,
+ [Define 1 if plain libelf builds.]))
+AC_TRY_COMPILE([
+#define _GNU_SOURCE
+#include <libelf.h>
+],[ off64_t p; p = 0;] ,
+ AC_DEFINE(HAVE_LIBELF_OFF64_OK,1,
+ [Define 1 if off64 is defined via libelf with GNU_SOURCE.]))
+
+
+
+AC_OUTPUT(Makefile)
diff --git a/dwarfdump/dwarfdump.1 b/dwarfdump/dwarfdump.1
new file mode 100644
index 0000000..bb7ee37
--- /dev/null
+++ b/dwarfdump/dwarfdump.1
@@ -0,0 +1,523 @@
+.TH DWARFDUMP
+.SH NAME
+dwarfdump \- dumps DWARF debug information of an ELF object
+.SH SYNOPSIS
+.B dwarfdump [options] \f2objectfilename\fP
+.SH DESCRIPTION
+The
+.B dwarfdump
+command prints or checks DWARF sections as requested by specific options.
+With no options (but with the required \f2objectfilename\fP )
+all sections print (but some sections cannot be printed independently
+safely, so those are only printed at offsets where the .debug_info section
+refers to those sections).
+.PP
+As of June 2011 the printing options and the checking options
+are mutually exclusive (if checking options are selected
+the section details are not printed). When errors are encountered
+dwarfdump does attempt to print sufficient context so that
+one can understand exactly where the error is in the DWARF.
+This change makes checking really large object files
+much easier.
+.PP
+The format is intended to be human readable.
+If a script is to parse the output, the
+.B \-d
+option is useful.
+.PP
+Not all sections actually exist in any given object file.
+.PP
+The format may change from release to release, so it is
+unwise to depend too heavily on the format.
+.PP
+Frame information (.debug_frame and .eh_frame) is heavily
+dependent on the ABI/ISA of the object file.
+By default we use a generic set of register names
+handling up to 100 registers named r0-100.
+The '-R' option uses a built-in generic register name set
+handling up to 1200 registers named r0-r1199.
+The '-x abi=<abi>'
+description below shows how to name an abi and use that to guide
+the -f or -F processing.
+Unless the cpu for the object file being dumped has many registers,
+do not use -R or -x abi=generic as those can be needlessly
+slow dumping frame sections. Instead, use the correct
+abi (if it exists in dwarfdump.conf) or a generic such
+as -x abi=generic100 or -x abi=generic500.
+To get MIPS/IRIX register names names and call the old version 2 libdwarf
+frame interface use the option '-x abi=mips'.
+Without '-R' or '-x abi=<abi>' dwarfdump ignores
+the dwarfdump.conf file and uses compiled-in generic set of
+register names.
+If no '-x name=<path>' is given, dwarfdump
+looks for "./dwarfdump.conf", "$HOME/.dwarfdump.conf", "<install-prefix>/lib/dwarfdump.conf" and takes the first it finds.
+If one or more '-x name=<path>' is given the last of these is
+used and all other such files are ignored.
+.PP
+Some -k (checking) options print so-called harmless errors.
+These are compiler errors that do not cause any
+known problem and are only detected inside libdwarf itself.
+These are difficult to properly report in dwarfdump and
+any error strings may not appear close to the time the
+error was encountered.
+.SH URI STYLE INPUT STRINGS
+.PP
+The <objectfilename> and the options taking name strings look for URIs and
+translate the URI strings to characters by default
+(see -x, -c<compiler name>, -S, -u).
+So any single % character is treated as if the following two
+characters are hex digits representing the underlying true character.
+Various characters are meaningful to shells (such as bash or sh)
+and to getopt (such as the space character)
+If the URI translation does anything it prints the before and after
+of the URI translation on standard output, so inspection of the first
+lines of output will show if URI did anything.
+The actual options themselves are assumed to be non-URI.
+So in the option '-cS&T' the -c portion must be non-URI, but the
+& character might cause input issues so '-cS%26T' could be used instead.
+To actually input a single % character (in a name, for example),
+double it to %% on the command line.
+.PP
+Options -U (turning off URI interpretation) and -q (making finding
+URI sequences silent) give finer control of URI interpretation.
+PP
+As an example, to get a string'a b' make the string 'a%20b'
+(here the quote (') is for exposition not part of the string, though
+quote is certainly problematic in a name).
+Instead of escaping " quotes in the string, type %25, as in
+ 'a "b' should be typed 'a%20%25b'
+Any characters can be typed in URI style, not just characters
+which are problematic to the shell or getopt.
+We strongly suggest you not type URI-style characters where
+such are not needed or use
+the % character itself in command line strings unless you must.
+.SH PRINTING OPTIONS
+.TP
+.B \-a
+Print each section as independently as possible. Sections that
+can safely be printed independently (like .debug_abbrev)
+have relevant info printed in the report (sometimes dependent
+on -v).
+
+.TP
+.B \-b
+Print the .debug_abbrev section. Because the DWARF specfications
+do not rule out garbage data areas in .debug_abbrev (if they are not
+referenced from .debug_info) any garbage bytes can result in
+this print failing.
+
+.TP
+.B \-c
+Print locations lists.
+
+.TP
+.B \-f
+Print the .debug_frame section.
+.TP
+.B \-F
+Print the .eh_frame section.
+
+.TP
+.B \-i
+Print the .debug_info section.
+
+.TP
+.B \-l
+Print the .debug_info section and the associated line section data.
+
+.TP
+.B \-m
+Print the .debug_macinfo section.
+
+.TP
+.B \-N
+Print .debug_ranges section. Because the DWARF specfications
+do not rule out garbage data areas in .debug_ranges (if they are not
+referenced from .debug_info) any garbage bytes can result in
+this print failing.
+
+.TP
+.B \-p
+Print the .debug_pubnames section.
+
+.TP
+.B \-r
+Print the .debug_aranges section.
+.TP
+.B \-s
+Print .debug_string section.
+
+.TP
+.B \-ta
+Print the IRIX only sections .debug_static_funcs and .debug_static_vars.
+
+.TP
+.B \-tf
+Print the IRIX only section .debug_static_funcs.
+.TP
+.B \-tv
+Print the IRIX only section .debug_static_vars.
+
+.TP
+.B \-w
+Print the IRIX-only .debug_weaknames section.
+
+.TP
+.B \-y
+Print the .debug_pubtypes section (and .debug_typenames,
+an SGI IRIX-only section).
+
+.PP
+Having dwarfdump print relocations may help establish whether
+dwarfdump understands any relocations that might exist.
+
+.TP
+.B \-o
+Print all relocation records as well as we can manage.
+.TP
+.B \-oi
+Print .rel*debug_info relocations.
+.TP
+.B \-ol
+Print .rel*debug_line relocation.
+.TP
+.B \-op
+Print .rel*debug_pubnames relocation.
+.TP
+.B \-oa
+Has no effect.
+.TP
+.B \-or
+Print .rel*debug_aranges relocations.
+.TP
+.B \-of
+Print .rel*debug_frame relocations.
+.TP
+.B \-oo
+Print .rel*debug_loc relocations.
+.TP
+.B \-oR
+Print .rel*debug_ranges relocations.
+
+.TP
+.B \-g
+Normally used only for testing libdwarf, this tells dwarfdump to
+print .debug_info and use an older dwarf_loclist() interface
+function (a function that cannot handle all current
+location lists).
+.TP
+.B \-V
+Print a dwarfdump date/version string and stop.
+
+.SH CHECKING OPTIONS
+.TP
+.B \-cg
+Restricts checking to compilers whose
+producer string starts with 'GNU'
+and turns off -cs .
+
+.TP
+.B \-cs
+Restricts checking to compilers whose
+producer string starts with 'SN'
+and turns off -cg .
+.TP
+.B \-cname
+Restricts checking to compilers whose
+producer string contains 'name' (not case sensitive).
+The 'name' is read as a URI string.
+
+.TP
+.B \
+-ka : Turns on all checking options except -kxe (-kxe might
+ be slow enough one mignt not want to use it routinely.)
+
+.TP
+.B \
+-kb : Checks for certain abbreviations section errors when reading
+ DIEs.
+.TP
+.B \-kc
+Checks for errors in constants in debug_info.
+.TP
+.B \-kd
+Turns on full reporting of error totals per producer.
+(the default shows less detail).
+.TP
+.B \-ke
+Turns on reading pubnames and checking for fde errors.
+.TP
+.B \-kf
+Turns on checking for FDE errors.
+.TP
+.B \-kF
+Turns on checking for line table errors.
+.TP
+.B \-kg
+Turns on checking for unused gaps in .debug_info (these
+gaps are not an error, just a waste of space).
+
+.TP
+.B \-ki
+Causes a summary of checking results per compiler (producer)
+to be printed at the end.
+.TP
+.B \-kl
+Turns on locations list checking.
+.TP
+.B \-km
+Turns on checking of ranges.
+.TP
+.B \-kM
+Turns on checking of aranges.
+.TP
+.B \-kr
+Turns on DIE tag-attr combinations checking.
+.TP
+.B \-kR
+Turns on reading DIEs and checking for forward declarations
+rom DW_AT_specification attributes.
+(which are not an error but can be a source of inefficiency
+for debuggers).
+.TP
+.B \-ks
+Turns on extra reporting for some DIE errors checking detects .
+.TP
+.B \-kS
+Turns on checking DIE references for circular references.
+.TP
+.B \-kt
+Turns on tag-tag combinations checking.
+.TP
+.B \-kx
+Turns on check_frames.
+.TP
+.B \-kxe
+Turns off basic check_frames and turns on extended frame checking.
+.TP
+.B \-ky
+Turns on type_offset, decl_file checking,
+
+.SH OPTION MODIFIERS
+
+.TP
+.B \-C
+Normally when checking for tag-tag or tag-attribute combinations
+both the standard combinations and some common extensions are allowed.
+With -C the extensions are taken out of the allowed class of combinations.
+
+.TP
+.B \-d
+When printing DIEs, put all the attributes for each DIE on the same (long)
+line as the TAG. This makes searching for DIE information
+(as with grep) much simpler as the entire DIE is on one line.
+
+.TP
+.B \-D
+Turns off the display of section offsets and attribute values in printed output.
+So the .debug_info output isjust TAGs and Attributes.
+For pubnames (and the like) it removes offsets from the output.
+For locations lists it removes offsets from the output, but that
+is useless since the attribute values don't show so neither does
+the location data.
+
+.TP
+.B \-e
+Turns on truncation of attribute and tag names. For example
+DW_TAG_foo becomes foo . Not compatible with
+checking, only useful for printing DIEs.
+
+.TP
+.B \-G
+When printing, add global offsets to the offsets printed.
+
+.TP
+.B \-H number
+When printing or checking .debug_info, this terminates
+the search after 'number' compilation units. When printing
+frame information this terminates the FDE reporting
+after 'number' FDEs and the CIE reporting (which occurs if one adds -v)
+after 'number' CIEs. Example '-H 1'
+
+.TP
+.B \-M
+When printing, this means one want to have the FORM show for each attribute.
+If a -v is also added (or more than one) then details of any form indirection
+are also shown.
+
+.TP
+.B \-n
+When printing frames, this turns off the search for function names.
+In a really large object the search can take more time than
+one wants to wait, so this avoids the search.
+
+.TP
+.B \-Q
+Suppresses section data printing (set automatically with a checking option).
+
+.TP
+.B \-R
+When printing frames for ABIs with lots of registers, this allows
+up to 1200 registers to be named (like R999) without choosing an ABI
+with, for example '-x abi=ppc'
+
+.TP
+.B \-v
+Increases the detail shown when printing.
+In some sections, using more -v options
+will increase the detail (one to three are useful) or may
+change the report to show, for example, the actual
+line-data-commands instead of the resultant line-table.
+
+.SH SELECTIVE ENTRY PRINTING
+
+.PP
+These -S options stand alone and basic print information about the compilation
+unit and DIE where the string(s) appear.
+At most one of each of the following is effective (so for example
+one can only have one 'match', but one can
+have a 'match', an 'any', and a 'regex').
+Any -S causes the .debug_info section to be inspected.
+No checking options or printing options should be supplied with -S.
+
+.TP
+.B \-S match=string
+When printing DIEs
+for each tag value or attribute name that matches 'string' exactly
+print the compilation unit information and its section offset.
+Any CU with no match is not printed.
+The 'string' is read as a URI string.
+.TP
+.B \-S any=string
+When printing DIEs
+for each tag value or attribute name that contains 'string'
+somewhere in the tag or attribute (case insensitive)
+print the compilation unit information and its section offset.
+Any CU with no match is not printed.
+The 'string' is read as a URI string.
+.TP
+.B \-S regex=string
+When printing DIEs
+for each tag value or attribute name where the 'string' reqular
+expression matches print the compilation unit information
+and its section offset.
+Any CU with no match is not printed.
+The 'string' is read as a URI string.
+
+.PP
+The string cannot have spaces or other characters which are
+meaningful to getopt(3) and the shell will strip off quotes and
+other characters.
+So the string is assumed to be in URI style and is translated.
+In other words, to match 'a b' make the -S string 'a%20b'
+Instead of escaping " quotes in the string, type %25, as in
+ 'a "b' should be typed 'a%20%25b'
+(the ' are for exposition here, not part of the strings).
+Any characters can be typed in URI style, not just characters
+which are problematic to the shell or getopt.
+.PP
+The -S any= and -S regex= options are only usable
+if the library functions required are found at configure time.
+.PP
+The -W option is a modifier to the -S option, and
+increases the amount of output -W prints.
+Now we show the -W in context with a -S option.
+
+.TP
+.B \-S match=string1 -W
+Prints the parent tree and the children tree for the
+DIEs that -S matches.
+
+.TP
+.B \-S match=string2 -Wp
+Prints the parent tree for the DIEs that -S matches.
+
+.TP
+.B \-S match=string3 -Wc
+Prints the parent tree for the DIEs that -S matches.
+
+.SH OTHER OPTIONS
+
+.TP
+.B \-# number
+This option controls internal debugging output,
+higher numbers mean more debug actions. See the source code.
+
+
+.TP
+.B \-x name=/p/a/t/h.conf
+The file path given is the name of a file assumed to be
+a dwarfdump.conf-like file.
+The file path is read as a URI string.
+
+.TP
+.B \-x abi=ppc
+Selects the abi (from a dwarfdump.conf file) to be used in
+printing frame information (here using ppc as an example).
+The abi is read as a URI string.
+
+.TP
+.B \-P
+When checking this adds the list of compilation-unit names
+seen for each producer-compiler to the printed checking results.
+.TP
+.B \-q
+When a URI is found and translated while reading
+the command line, be quiet about
+the URI translation. That is, don't print the
+original and translated option strings.
+
+.TP
+.B \-E
+Turns on printing object-internal header data for some
+systems (for Unix/Linux does nothing).
+
+.TP
+.B \-u cuname
+Turns on selective printing of DIEs (printing like -i).
+Only the DIEs for a compilation unit that match the
+name provided are printed.
+If the compilation unit is ./a/b/c.c
+the 'cuname' you provide should be c.c as the characters
+through the final path-separating / are ignored.
+If 'cuname' begins with a / then the entire name string
+of a compilation unit must match 'cuname'.
+The 'cuname' is read as a URI string.
+
+.TP
+.B \-U
+Turn off the URI interpretation of the command line
+strings entirely. Must be be on the command line before
+any URI strings encountered to be fully effective.
+
+.TP
+.B \-z
+No longer suported.
+
+
+.SH FILES
+dwarfdump
+
+dwarfdump.conf
+
+./dwarfdump.conf
+
+$(HOME)/.dwarfdump.conf
+
+$(HOME)/dwarfdump.conf
+
+<install-prefix>/lib/dwarfdump.conf
+.SH NOTES
+In some cases compilers use DW_FORM_data1 (for example)
+and in such cases the signedness of the value must be taken
+from context. Rather than attempt to determine the
+context, dwarfdump prints the value with both signednesses
+whenever there is ambiguity about the correct interpretation.
+For example,
+"DW_AT_const_value 176(as signed = -80)".
+For normal DWARF consumers that correctly and fully
+evaluate all attributes there is no ambiguity of signedness:
+the ambiguity for dwarfdump is due to dwarfdump evaluating
+DIEs in a simple order and not keeping track of much context.
+.SH BUGS
+Support for DWARF3 is being completed but may not be complete.
diff --git a/dwarfdump/dwarfdump.c b/dwarfdump/dwarfdump.c
new file mode 100644
index 0000000..f8bc309
--- /dev/null
+++ b/dwarfdump/dwarfdump.c
@@ -0,0 +1,2357 @@
+/*
+ Copyright (C) 2000,2002,2004,2005 Silicon Graphics, Inc. All Rights Reserved.
+ Portions Copyright (C) 2007-2010 David Anderson. All Rights Reserved.
+ Portions Copyright 2007-2010 Sun Microsystems, Inc. All rights reserved.
+
+
+ This program is free software; you can redistribute it and/or modify it
+ under the terms of version 2 of the GNU General Public License as
+ published by the Free Software Foundation.
+
+ This program is distributed in the hope that it would be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+ Further, this software is distributed without any warranty that it is
+ free of the rightful claim of any third person regarding infringement
+ or the like. Any license provided herein, whether implied or
+ otherwise, applies only to this software file. Patent licenses, if
+ any, provided herein do not apply to combinations of this program with
+ other software, or any other product whatsoever.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write the Free Software Foundation, Inc., 51
+ Franklin Street - Fifth Floor, Boston MA 02110-1301, USA.
+
+ Contact information: Silicon Graphics, Inc., 1500 Crittenden Lane,
+ Mountain View, CA 94043, or:
+
+ http://www.sgi.com
+
+ For further information regarding this notice, see:
+
+ http://oss.sgi.com/projects/GenInfo/NoticeExplan
+
+
+$Header: /plroot/cmplrs.src/v7.4.5m/.RCS/PL/dwarfdump/RCS/dwarfdump.c,v 1.48 2006/04/18 18:05:57 davea Exp $ */
+
+/* The address of the Free Software Foundation is
+ Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+ SGI has moved from the Crittenden Lane address.
+*/
+
+#include "globals.h"
+/* for 'open' */
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <limits.h>
+#include <unistd.h> /* For getopt */
+#include "makename.h"
+#include "dwconf.h"
+#include "common.h"
+#include "esb.h" /* For flexible string buffer. */
+
+#ifdef WIN32
+extern int elf_open(char *name,int mode);
+#endif
+
+#define DWARFDUMP_VERSION " Tue Apr 10 11:43:32 PDT 2012 "
+
+extern char *optarg;
+
+
+#define OKAY 0
+#define BYTES_PER_INSTRUCTION 4
+
+static const char* process_args(int argc, char *argv[]);
+
+char * program_name;
+static int check_error = 0;
+
+/* The type of Bucket. */
+#define KIND_RANGES_INFO 1
+#define KIND_SECTIONS_INFO 2
+#define KIND_VISITED_INFO 3
+
+/* pRangesInfo records the DW_AT_high_pc and DW_AT_low_pc
+ and is used to check that line range info falls inside
+ the known valid ranges. The data is per CU, and is
+ reset per CU in tag_specific_checks_setup(). */
+Bucket_Group *pRangesInfo = NULL;
+
+/* pLinkonceInfo records data about the link once sections.
+ If a line range is not valid in the current CU it might
+ be valid in a linkonce section, this data records the
+ linkonce sections. So it is filled in when an
+ object file is read and remains unchanged for an entire
+ object file. */
+Bucket_Group *pLinkonceInfo = NULL;
+/* pVisitedInfo records a recursive traversal of DIE attributes
+ DW_AT_specification DW_AT_abstract_origin DW_AT_type
+ that let DWARF refer (as in a general graph) to
+ arbitrary other DIEs.
+ These traversals use pVisitedInfo to
+ detect any compiler errors that introduce circular references.
+ Printing of the traversals is also done on request.
+ Entries are added and deleted as they are visited in
+ a depth-first traversal. */
+Bucket_Group *pVisitedInfo = NULL;
+
+/* Options to enable debug tracing */
+int nTrace[MAX_TRACE_LEVEL + 1];
+
+/* Build section information */
+void build_linkonce_info(Dwarf_Debug dbg);
+static const char * do_uri_translation(const char *s,
+ const char *context);
+static void reset_overall_CU_error_data();
+
+boolean info_flag = FALSE;
+boolean use_old_dwarf_loclist = FALSE; /* This so both dwarf_loclist()
+ and dwarf_loclist_n() can be
+ tested. Defaults to new
+ dwarf_loclist_n() */
+
+boolean line_flag = FALSE;
+static boolean abbrev_flag = FALSE;
+static boolean frame_flag = FALSE; /* .debug_frame section. */
+static boolean eh_frame_flag = FALSE; /* GNU .eh_frame section. */
+static boolean pubnames_flag = FALSE;
+static boolean macinfo_flag = FALSE;
+static boolean loc_flag = FALSE;
+static boolean aranges_flag = FALSE; /* .debug_aranges section. */
+static boolean ranges_flag = FALSE; /* .debug_ranges section. */
+static boolean string_flag = FALSE;
+static boolean reloc_flag = FALSE;
+static boolean static_func_flag = FALSE;
+static boolean static_var_flag = FALSE;
+static boolean type_flag = FALSE;
+static boolean weakname_flag = FALSE;
+static boolean header_flag = FALSE; /* Control printing of Elf header. */
+boolean producer_children_flag = FALSE; /* List of CUs per compiler */
+
+/* Bitmap for relocations. See globals.h for DW_SECTION_REL_DEBUG_RANGES etc.*/
+static unsigned reloc_map = 0;
+
+/* Start verbose at zero. verbose can
+ be incremented with -v but not decremented. */
+int verbose = 0;
+
+boolean dense = FALSE;
+boolean ellipsis = FALSE;
+boolean show_global_offsets = FALSE; /* Show global and relative offsets */
+boolean show_form_used = FALSE;
+boolean display_offsets = TRUE; /* Emit offsets */
+
+boolean check_abbrev_code = FALSE;
+boolean check_pubname_attr = FALSE;
+boolean check_reloc_offset = FALSE;
+boolean check_attr_tag = FALSE;
+boolean check_tag_tree = FALSE;
+boolean check_type_offset = FALSE;
+boolean check_decl_file = FALSE;
+boolean check_lines = FALSE;
+boolean check_fdes = FALSE;
+boolean check_ranges = FALSE;
+boolean check_aranges = FALSE;
+boolean check_harmless = FALSE;
+boolean check_abbreviations = FALSE;
+boolean check_dwarf_constants = FALSE;
+boolean check_di_gaps = FALSE;
+boolean check_forward_decl = FALSE;
+boolean check_self_references = FALSE;
+boolean generic_1200_regs = FALSE;
+boolean suppress_check_extensions_tables = FALSE;
+
+/* suppress_nested_name_search is a band-aid.
+ A workaround. A real fix for N**2 behavior is needed.
+*/
+boolean suppress_nested_name_search = FALSE;
+static boolean uri_options_translation = TRUE;
+static boolean do_print_uri_in_input = TRUE;
+
+
+/* break_after_n_units is mainly for testing.
+ It enables easy limiting of output size/running time
+ when one wants the output limited.
+ For example,
+ -H 2
+ limits the -i output to 2 compilation units and
+ the -f or -F output to 2 FDEs and 2 CIEs.
+*/
+int break_after_n_units = INT_MAX;
+
+boolean check_names = FALSE;
+boolean check_verbose_mode = TRUE; /* During '-k' mode, display errors */
+boolean check_frames = FALSE;
+boolean check_frames_extended = FALSE; /* Extensive frames check */
+boolean check_locations = FALSE; /* Location list check */
+
+static boolean check_all_compilers = TRUE;
+static boolean check_snc_compiler = FALSE; /* Check SNC compiler */
+static boolean check_gcc_compiler = FALSE;
+static boolean print_summary_all = FALSE;
+
+#define COMPILER_TABLE_MAX 100
+typedef struct anc {
+ struct anc *next;
+ char *item;
+} a_name_chain;
+
+/* Records information about compilers (producers) found in the
+ debug information, including the check results for several
+ categories (see -k option). */
+typedef struct {
+ const char *name;
+ boolean verified;
+ a_name_chain *cu_list;
+ a_name_chain *cu_last;
+ Dwarf_Check_Result results[LAST_CATEGORY];
+} Compiler;
+
+/* Record compilers whose CU names have been seen.
+ Full CU names recorded here, though only a portion
+ of the name may have been checked to cause the
+ compiler data to be entered here.
+ The +1 guarantees we do not overstep the array.
+*/
+static Compiler compilers_detected[COMPILER_TABLE_MAX];
+static int compilers_detected_count = 0;
+
+/* compilers_targeted is a list of indications of compilers
+ on which we wish error checking (and the counts
+ of checks made and errors found). We do substring
+ comparisons, so the compilers_targeted name might be simply a
+ compiler version number or a short substring of a
+ CU producer name.
+ The +1 guarantees we do not overstep the array.
+*/
+static Compiler compilers_targeted[COMPILER_TABLE_MAX];
+static int compilers_targeted_count = 0;
+static int current_compiler = -1;
+
+static void reset_compiler_entry(Compiler *compiler);
+static void PRINT_CHECK_RESULT(char *str,
+ Compiler *pCompiler, Dwarf_Check_Categories category);
+
+
+/* The check and print flags here make it easy to
+ allow check-only or print-only. We no longer support
+ check-and-print in a single run. */
+boolean do_check_dwarf = FALSE;
+boolean do_print_dwarf = FALSE;
+boolean check_show_results = FALSE; /* Display checks results. */
+boolean record_dwarf_error = FALSE; /* A test has failed, this
+ is normally set FALSE shortly after being set TRUE, it is
+ a short-range hint we should print something we might not
+ otherwise print (under the circumstances). */
+
+
+/* These names make diagnostic messages more complete, the
+ fixed length is safe, though ultra long names will get
+ truncated. */
+char PU_name[COMPILE_UNIT_NAME_LEN];
+char CU_name[COMPILE_UNIT_NAME_LEN];
+char CU_producer[COMPILE_UNIT_NAME_LEN];
+
+boolean seen_PU = FALSE; /* Detected a PU */
+boolean seen_CU = FALSE; /* Detected a CU */
+boolean need_CU_name = TRUE; /* Need CU name */
+boolean need_CU_base_address = TRUE; /* Need CU Base address */
+boolean need_CU_high_address = TRUE; /* Need CU High address */
+boolean need_PU_valid_code = TRUE; /* Need PU valid code */
+
+boolean seen_PU_base_address = FALSE; /* Detected a Base address for PU */
+boolean seen_PU_high_address = FALSE; /* Detected a High address for PU */
+Dwarf_Addr PU_base_address = 0; /* PU Base address */
+Dwarf_Addr PU_high_address = 0; /* PU High address */
+
+Dwarf_Off DIE_offset = 0; /* DIE offset in compile unit */
+Dwarf_Off DIE_overall_offset = 0; /* DIE offset in .debug_info */
+
+/* These globals enable better error reporting. */
+Dwarf_Off DIE_CU_offset = 0; /* CU DIE offset in compile unit */
+Dwarf_Off DIE_CU_overall_offset = 0; /* CU DIE offset in .debug_info */
+int current_section_id = 0; /* Section being process */
+
+Dwarf_Addr CU_base_address = 0; /* CU Base address */
+Dwarf_Addr CU_high_address = 0; /* CU High address */
+
+Dwarf_Addr elf_max_address = 0; /* Largest representable address offset */
+Dwarf_Half elf_address_size = 0; /* Target pointer size */
+
+/* Display parent/children when in wide format? */
+boolean display_parent_tree = FALSE;
+boolean display_children_tree = FALSE;
+int stop_indent_level = 0;
+
+/* Print search results in wide format? */
+boolean search_wide_format = FALSE;
+/* -S option: strings for 'any' and 'match' */
+boolean search_is_on = FALSE;
+const char *search_any_text = 0;
+const char *search_match_text = 0;
+const char *search_regex_text = 0;
+#ifdef HAVE_REGEX
+/* -S option: the compiled_regex */
+regex_t search_re;
+#endif
+
+
+/* These configure items are for the
+ frame data. We're pretty flexible in
+ the path to dwarfdump.conf .
+*/
+static const char *config_file_path = 0;
+static const char *config_file_abi = 0;
+static char *config_file_defaults[] = {
+ "dwarfdump.conf",
+ "./dwarfdump.conf",
+ "HOME/.dwarfdump.conf",
+ "HOME/dwarfdump.conf",
+#ifdef CONFPREFIX
+/* See Makefile.in "libdir" and CFLAGS */
+/* We need 2 levels of macro to get the name turned into
+ the string we want. */
+#define STR2(s) # s
+#define STR(s) STR2(s)
+ STR(CONFPREFIX)
+ "/dwarfdump.conf",
+#else
+ "/usr/lib/dwarfdump.conf",
+#endif
+ 0
+};
+static struct dwconf_s config_file_data;
+
+char cu_name[BUFSIZ];
+boolean cu_name_flag = FALSE;
+Dwarf_Unsigned cu_offset = 0;
+
+Dwarf_Error err;
+
+static void suppress_check_dwarf()
+{
+ do_print_dwarf = TRUE;
+ if(do_check_dwarf) {
+ fprintf(stderr,"Warning: check flag turned off, "
+ "checking and printing are separate.\n");
+ }
+ do_check_dwarf = FALSE;
+}
+static void suppress_print_dwarf()
+{
+ do_print_dwarf = FALSE;
+ do_check_dwarf = TRUE;
+}
+
+static int process_one_file(Elf * elf, const char * file_name, int archive,
+ struct dwconf_s *conf);
+static int
+open_a_file(const char * name)
+{
+ /* Set to a file number that cannot be legal. */
+ int f = -1;
+
+#if defined(__CYGWIN__) || defined(WIN32)
+ /* It is not possible to share file handles
+ between applications or DLLs. Each application has its own
+ file-handle table. For two applications to use the same file
+ using a DLL, they must both open the file individually.
+ Let the 'libelf' dll to open and close the file. */
+
+ /* For WIN32 open the file as binary */
+ f = elf_open(name, O_RDONLY | O_BINARY);
+#else
+ f = open(name, O_RDONLY);
+#endif
+ return f;
+
+}
+static void
+close_a_file(int f)
+{
+ close(f);
+}
+
+/*
+ Iterate through dwarf and print all info.
+*/
+int
+main(int argc, char *argv[])
+{
+ const char * file_name = 0;
+ int f = 0;
+ Elf_Cmd cmd = 0;
+ Elf *arf = 0;
+ Elf *elf = 0;
+ int archive = 0;
+
+#ifdef WIN32
+ /* Windows specific. */
+ /* Redirect stderr to stdout. */
+ /* Tried to use SetStdHandle, but it does not work properly. */
+ //BOOL bbb = SetStdHandle(STD_ERROR_HANDLE,GetStdHandle(STD_OUTPUT_HANDLE));
+ //_iob[2]._file = _iob[1]._file;
+ stderr->_file = stdout->_file;
+#endif /* WIN32 */
+
+ print_version_details(argv[0],FALSE);
+
+ (void) elf_version(EV_NONE);
+ if (elf_version(EV_CURRENT) == EV_NONE) {
+ (void) fprintf(stderr, "dwarfdump: libelf.a out of date.\n");
+ exit(1);
+ }
+
+ file_name = process_args(argc, argv);
+
+ /* Because LibDwarf now generates some new warnings,
+ allow the user to hide them by using command line options */
+ {
+ Dwarf_Cmdline_Options cmd;
+ cmd.check_verbose_mode = check_verbose_mode;
+ dwarf_record_cmdline_options(cmd);
+ }
+ print_args(argc,argv);
+ f = open_a_file(file_name);
+ if (f == -1) {
+ fprintf(stderr, "%s ERROR: can't open %s\n", program_name,
+ file_name);
+ return (FAILED);
+ }
+
+ cmd = ELF_C_READ;
+ arf = elf_begin(f, cmd, (Elf *) 0);
+ if (elf_kind(arf) == ELF_K_AR) {
+ archive = 1;
+ }
+
+ /* If we are checking .debug_line, .debug_ranges, .debug_aranges,
+ or .debug_loc build the tables containing
+ the pairs LowPC and HighPC. It is safer (and not
+ expensive) to build all
+ of these at once so mistakes in options do not lead
+ to coredumps (like -ka -p did once). */
+ if (check_decl_file || check_ranges || check_locations ||
+ do_check_dwarf || check_self_references) {
+ pRangesInfo = AllocateBucketGroup(KIND_RANGES_INFO);
+ pLinkonceInfo = AllocateBucketGroup(KIND_SECTIONS_INFO);
+ pVisitedInfo = AllocateBucketGroup(KIND_VISITED_INFO);
+ }
+
+ while ((elf = elf_begin(f, cmd, arf)) != 0) {
+ Elf32_Ehdr *eh32;
+
+#ifdef HAVE_ELF64_GETEHDR
+ Elf64_Ehdr *eh64;
+#endif /* HAVE_ELF64_GETEHDR */
+ eh32 = elf32_getehdr(elf);
+ if (!eh32) {
+#ifdef HAVE_ELF64_GETEHDR
+ /* not a 32-bit obj */
+ eh64 = elf64_getehdr(elf);
+ if (!eh64) {
+ /* not a 64-bit obj either! */
+ /* dwarfdump is almost-quiet when not an object */
+ fprintf(stderr, "Can't process %s: unknown format\n",file_name);
+ check_error = 1;
+ } else {
+ process_one_file(elf, file_name, archive,
+ &config_file_data);
+ }
+#endif /* HAVE_ELF64_GETEHDR */
+ } else {
+ process_one_file(elf, file_name, archive,
+ &config_file_data);
+ }
+ cmd = elf_next(elf);
+ elf_end(elf);
+ }
+ elf_end(arf);
+ /* Trivial malloc space cleanup. */
+ clean_up_die_esb();
+ clean_up_syms_malloc_data();
+
+ if(pRangesInfo) {
+ ReleaseBucketGroup(pRangesInfo);
+ pRangesInfo = 0;
+ }
+
+ if(pLinkonceInfo) {
+ ReleaseBucketGroup(pLinkonceInfo);
+ pLinkonceInfo = 0;
+ }
+
+ if(pVisitedInfo) {
+ ReleaseBucketGroup(pVisitedInfo);
+ pVisitedInfo = 0;
+ }
+
+#ifdef HAVE_REGEX
+ if(search_regex_text) {
+ regfree(&search_re);
+ }
+#endif
+ close_a_file(f);
+ if (check_error)
+ return FAILED;
+ else
+ return OKAY;
+}
+
+void
+print_any_harmless_errors(Dwarf_Debug dbg)
+{
+#define LOCAL_PTR_ARY_COUNT 50
+ /* We do not need to initialize the local array,
+ libdwarf does it. */
+ const char *buf[LOCAL_PTR_ARY_COUNT];
+ unsigned totalcount = 0;
+ unsigned i = 0;
+ unsigned printcount = 0;
+ int res = dwarf_get_harmless_error_list(dbg,LOCAL_PTR_ARY_COUNT,buf,
+ &totalcount);
+ if(res == DW_DLV_NO_ENTRY) {
+ return;
+ }
+ if(totalcount > 0) {
+ printf("\n*** HARMLESS ERROR COUNT: %u ***\n",totalcount);
+ }
+ for(i = 0 ; buf[i]; ++i) {
+ ++printcount;
+ DWARF_CHECK_COUNT(harmless_result,1);
+ DWARF_CHECK_ERROR(harmless_result,buf[i]);
+ }
+ if(totalcount > printcount) {
+ //harmless_result.checks += (totalcount - printcount);
+ DWARF_CHECK_COUNT(harmless_result,(totalcount - printcount));
+ //harmless_result.errors += (totalcount - printcount);
+ DWARF_ERROR_COUNT(harmless_result,(totalcount - printcount));
+ }
+}
+
+static void
+print_object_header(Elf *elf,Dwarf_Debug dbg)
+{
+#ifdef WIN32
+ /* Standard libelf has no function generating the names of the
+ encodings, but this libelf apparently does. */
+ Elf_Ehdr_Literal eh_literals;
+ Elf32_Ehdr *eh32;
+#ifdef HAVE_ELF64_GETEHDR
+ Elf64_Ehdr *eh64;
+#endif /* HAVE_ELF64_GETEHDR */
+
+ eh32 = elf32_getehdr(elf);
+ if (eh32) {
+ /* Get literal strings for header fields */
+ elf32_gethdr_literals(eh32,&eh_literals);
+ /* Print 32-bit obj header */
+ printf("\nObject Header:\ne_ident:\n");
+ printf(" File ID = %s\n",eh_literals.e_ident_file_id);
+ printf(" File class = %02x (%s)\n",
+ eh32->e_ident[EI_CLASS], eh_literals.e_ident_file_class);
+ printf(" Data encoding = %02x (%s)\n",
+ eh32->e_ident[EI_DATA], eh_literals.e_ident_data_encoding);
+ printf(" File version = %02x (%s)\n",
+ eh32->e_ident[EI_VERSION], eh_literals.e_ident_file_version);
+ printf(" OS ABI = %02x (%s) (%s)\n", eh32->e_ident[EI_OSABI],
+ eh_literals.e_ident_os_abi_s, eh_literals.e_ident_os_abi_l);
+ //printf(" ABI version = %02x (%s)\n",
+ // eh32->e_ident[EI_ABIVERSION], eh_literals.e_ident_abi_version);
+ printf("e_type : 0x%x (%s)\n",
+ eh32->e_type, eh_literals.e_type);
+ printf("e_machine: 0x%x (%s) (%s)\n", eh32->e_machine,
+ eh_literals.e_machine_s, eh_literals.e_machine_l);
+ printf("e_version: 0x%x\n", eh32->e_version);
+ //printf("e_entry = 0x%I64x\n", eh32->e_entry);
+ printf("e_flags : 0x%x\n", eh32->e_flags);
+ printf("e_phnum : 0x%x\n", eh32->e_phnum);
+ printf("e_shnum : 0x%x\n", eh32->e_shnum);
+ }
+ else {
+#ifdef HAVE_ELF64_GETEHDR
+ /* not a 32-bit obj */
+ eh64 = elf64_getehdr(elf);
+ if (eh64) {
+ /* Get literal strings for header fields */
+ elf64_gethdr_literals(eh64,&eh_literals);
+ /* Print 64-bit obj header */
+ printf("\nObject Header:\ne_ident:\n");
+ printf(" File ID = %s\n",eh_literals.e_ident_file_id);
+ printf(" File class = %02x (%s)\n",
+ eh64->e_ident[EI_CLASS], eh_literals.e_ident_file_class);
+ printf(" Data encoding = %02x (%s)\n",
+ eh64->e_ident[EI_DATA], eh_literals.e_ident_data_encoding);
+ printf(" File version = %02x (%s)\n",
+ eh64->e_ident[EI_VERSION], eh_literals.e_ident_file_version);
+ printf(" OS ABI = %02x (%s) (%s)\n", eh64->e_ident[EI_OSABI],
+ eh_literals.e_ident_os_abi_s, eh_literals.e_ident_os_abi_l);
+ //printf(" ABI version = %02x (%s)\n",
+ // eh64->e_ident[EI_ABIVERSION], eh_literals.e_ident_abi_version);
+ printf("e_type : 0x%x (%s)\n",
+ eh64->e_type, eh_literals.e_type);
+ printf("e_machine: 0x%x (%s) (%s)\n", eh64->e_machine,
+ eh_literals.e_machine_s, eh_literals.e_machine_l);
+ printf("e_version: 0x%x\n", eh64->e_version);
+ //printf("e_entry = 0x%I64x\n", eh64->e_entry);
+ printf("e_flags : 0x%x\n", eh64->e_flags);
+ printf("e_phnum : 0x%x\n", eh64->e_phnum);
+ printf("e_shnum : 0x%x\n", eh64->e_shnum);
+ }
+#endif /* HAVE_ELF64_GETEHDR */
+ }
+#endif /* WIN32 */
+}
+
+/* Print checks and errors for a specific compiler */
+static void
+print_specific_checks_results(Compiler *pCompiler)
+{
+ fprintf(stderr, "\nDWARF CHECK RESULT\n");
+ fprintf(stderr, "<item> <checks> <errors>\n");
+ if (check_pubname_attr) {
+ PRINT_CHECK_RESULT("pubname_attr", pCompiler, pubname_attr_result);
+ }
+ if (check_attr_tag) {
+ PRINT_CHECK_RESULT("attr_tag", pCompiler, attr_tag_result);
+ }
+ if (check_tag_tree) {
+ PRINT_CHECK_RESULT("tag_tree", pCompiler, tag_tree_result);
+ }
+ if (check_type_offset) {
+ PRINT_CHECK_RESULT("type_offset", pCompiler, type_offset_result);
+ }
+ if (check_decl_file) {
+ PRINT_CHECK_RESULT("decl_file", pCompiler, decl_file_result);
+ }
+ if (check_ranges) {
+ PRINT_CHECK_RESULT("ranges", pCompiler, ranges_result);
+ }
+ if (check_lines) {
+ PRINT_CHECK_RESULT("line_table", pCompiler, lines_result);
+ }
+ if (check_fdes) {
+ PRINT_CHECK_RESULT("fde table", pCompiler, fde_duplication);
+ }
+ if (check_aranges) {
+ PRINT_CHECK_RESULT("aranges", pCompiler, aranges_result);
+ }
+
+ if (check_names) {
+ PRINT_CHECK_RESULT("names",pCompiler, names_result);
+ }
+ if (check_frames) {
+ PRINT_CHECK_RESULT("frames",pCompiler, frames_result);
+ }
+ if (check_locations) {
+ PRINT_CHECK_RESULT("locations",pCompiler, locations_result);
+ }
+
+ if(check_harmless) {
+ PRINT_CHECK_RESULT("harmless_errors", pCompiler, harmless_result);
+ }
+
+ if (check_abbreviations) {
+ PRINT_CHECK_RESULT("abbreviations", pCompiler, abbreviations_result);
+ }
+
+ if (check_dwarf_constants) {
+ PRINT_CHECK_RESULT("dwarf_constants",
+ pCompiler, dwarf_constants_result);
+ }
+
+ if (check_di_gaps) {
+ PRINT_CHECK_RESULT("debug_info_gaps", pCompiler, di_gaps_result);
+ }
+
+ if (check_forward_decl) {
+ PRINT_CHECK_RESULT("forward_declarations",
+ pCompiler, forward_decl_result);
+ }
+
+ if (check_self_references) {
+ PRINT_CHECK_RESULT("self_references",
+ pCompiler, self_references_result);
+ }
+
+ PRINT_CHECK_RESULT("** Summarize **",pCompiler, total_check_result);
+}
+
+static int
+qsort_compare_compiler(const void *elem1,const void *elem2)
+{
+ Compiler cmp1 = *(Compiler *)elem1;
+ Compiler cmp2 = *(Compiler *)elem2;
+ int cnt1 = cmp1.results[total_check_result].errors;
+ int cnt2 = cmp2.results[total_check_result].errors;
+ int sc = 0;
+
+ if (cnt1 < cnt2) {
+ return 1;
+ } else if (cnt1 > cnt2) {
+ return -1;
+ }
+ /* When error counts match, sort on name. */
+ sc = strcmp(cmp2.name,cmp1.name);
+ return sc;
+}
+
+/* Print a summary of checks and errors */
+static void
+print_checks_results()
+{
+ int index = 0;
+ Compiler *pCompilers;
+ Compiler *pCompiler;
+
+ fflush(stdout);
+
+ /* Sort based on errors detected; the first entry is reserved */
+ pCompilers = &compilers_detected[1];
+ qsort((void *)pCompilers, compilers_detected_count,
+ sizeof(Compiler),qsort_compare_compiler);
+
+ /* Print list of CUs for each compiler detected */
+ if (producer_children_flag) {
+
+ a_name_chain *nc = 0;
+ a_name_chain *nc_next = 0;
+ int count = 0;
+ int total = 0;
+
+ fprintf(stderr,"\n*** CU NAMES PER COMPILER ***\n");
+ for (index = 1; index <= compilers_detected_count; ++index) {
+ pCompiler = &compilers_detected[index];
+ fprintf(stderr,"\n%02d: %s\n",index,pCompiler->name);
+ count = 0;
+ for (nc = pCompiler->cu_list; nc; nc = nc_next) {
+ fprintf(stderr,"\n %02d: '%s'",++count,nc->item);
+ nc_next = nc->next;
+ free(nc);
+ }
+ total += count;
+ fprintf(stderr,"\n");
+ }
+ fprintf(stderr,"\nDetected %d CU names\n",total);
+ }
+
+ /* Print error report only if errors have been detected */
+ /* Print error report if the -kd option */
+ if ((do_check_dwarf && check_error) || check_show_results) {
+ int count = 0;
+ int compilers_not_detected = 0;
+ int compilers_verified = 0;
+
+ /* Find out how many compilers have been verified. */
+ for (index = 1; index <= compilers_detected_count; ++index) {
+ if (compilers_detected[index].verified) {
+ ++compilers_verified;
+ }
+ }
+ /* Find out how many compilers have been not detected. */
+ for (index = 1; index <= compilers_targeted_count; ++index) {
+ if (!compilers_targeted[index].verified) {
+ ++compilers_not_detected;
+ }
+ }
+
+ /* Print compilers detected list */
+ fprintf(stderr,
+ "\n%d Compilers detected:\n",compilers_detected_count);
+ for (index = 1; index <= compilers_detected_count; ++index) {
+ pCompiler = &compilers_detected[index];
+ fprintf(stderr,"%02d: %s\n",index,pCompiler->name);
+ }
+
+ /* Print compiler list specified by the user with the
+ '-c<str>', that were not detected. */
+ if (compilers_not_detected) {
+ count = 0;
+ fprintf(stderr,
+ "\n%d Compilers not detected:\n",compilers_not_detected);
+ for (index = 1; index <= compilers_targeted_count; ++index) {
+ if (!compilers_targeted[index].verified) {
+ fprintf(stderr,
+ "%02d: '%s'\n",
+ ++count,compilers_targeted[index].name);
+ }
+ }
+ }
+
+ count = 0;
+ fprintf(stderr,"\n%d Compilers verified:\n",compilers_verified);
+ for (index = 1; index <= compilers_detected_count; ++index) {
+ pCompiler = &compilers_detected[index];
+ if (pCompiler->verified) {
+ fprintf(stderr,"%02d: errors = %5d, %s\n",
+ ++count,
+ pCompiler->results[total_check_result].errors,
+ pCompiler->name);
+ }
+ }
+
+ /* Print summary if we have verified compilers or
+ if the -kd option used. */
+ if (compilers_verified || check_show_results) {
+ /* Print compilers detected summary*/
+ if (print_summary_all) {
+ count = 0;
+ fprintf(stderr,"\n*** ERRORS PER COMPILER ***\n");
+ for (index = 1; index <= compilers_detected_count; ++index) {
+ pCompiler = &compilers_detected[index];
+ if (pCompiler->verified) {
+ fprintf(stderr,"%02d: %s\n",
+ ++count,pCompiler->name);
+ print_specific_checks_results(pCompiler);
+ }
+ }
+ }
+
+ /* Print general summary (all compilers checked) */
+ fprintf(stderr,"\n*** TOTAL ERRORS FOR ALL COMPILERS ***\n");
+ print_specific_checks_results(&compilers_detected[0]);
+ }
+ }
+}
+
+/*
+ Given a file which we know is an elf file, process
+ the dwarf data.
+
+*/
+static int
+process_one_file(Elf * elf, const char * file_name, int archive,
+ struct dwconf_s *config_file_data)
+{
+ Dwarf_Debug dbg;
+ int dres;
+
+ dres = dwarf_elf_init(elf, DW_DLC_READ, NULL, NULL, &dbg, &err);
+ if (dres == DW_DLV_NO_ENTRY) {
+ printf("No DWARF information present in %s\n", file_name);
+ return 0;
+ }
+ if (dres != DW_DLV_OK) {
+ print_error(dbg, "dwarf_elf_init", dres, err);
+ }
+
+ if (archive) {
+ Elf_Arhdr *mem_header = elf_getarhdr(elf);
+
+ printf("\narchive member \t%s\n",
+ mem_header ? mem_header->ar_name : "");
+ }
+ dwarf_set_frame_rule_initial_value(dbg,
+ config_file_data->cf_initial_rule_value);
+ dwarf_set_frame_rule_table_size(dbg,
+ config_file_data->cf_table_entry_count);
+ dwarf_set_frame_cfa_value(dbg,
+ config_file_data->cf_cfa_reg);
+ dwarf_set_frame_same_value(dbg,
+ config_file_data->cf_same_val);
+ dwarf_set_frame_undefined_value(dbg,
+ config_file_data->cf_undefined_val);
+ if(config_file_data->cf_address_size) {
+ dwarf_set_default_address_size(dbg, config_file_data->cf_address_size);
+ }
+ dwarf_set_harmless_error_list_size(dbg,50);
+
+
+ /* Get address size and largest representable address */
+ dres = dwarf_get_address_size(dbg,&elf_address_size,&err);
+ if (dres != DW_DLV_OK) {
+ print_error(dbg, "get_location_list", dres, err);
+ }
+
+ elf_max_address = (elf_address_size == 8 ) ?
+ 0xffffffffffffffffULL : 0xffffffff;
+
+ /* Get .text and .debug_ranges info if in check mode */
+ if (do_check_dwarf) {
+ Dwarf_Addr lower = 0;
+ Dwarf_Addr upper = 0;
+ Dwarf_Unsigned size = 0;
+ int res = 0;
+ res = dwarf_get_section_info_by_name(dbg,".text",&lower,&size,&err);
+ if (DW_DLV_OK == res) {
+ upper = lower + size;
+ }
+
+ /* Set limits for Ranges Information */
+ if (pRangesInfo) {
+ SetLimitsBucketGroup(pRangesInfo,lower,upper);
+ }
+
+ /* Build section information */
+ build_linkonce_info(dbg);
+ }
+
+ if (header_flag) {
+ print_object_header(elf,dbg);
+ }
+ reset_overall_CU_error_data();
+ if (info_flag || line_flag || cu_name_flag || search_is_on ||
+ producer_children_flag) {
+ print_infos(dbg,TRUE);
+ reset_overall_CU_error_data();
+ print_infos(dbg,FALSE);
+ }
+ if (pubnames_flag) {
+ reset_overall_CU_error_data();
+ print_pubnames(dbg);
+ }
+ if (macinfo_flag) {
+ reset_overall_CU_error_data();
+ print_macinfo(dbg);
+ }
+ if (loc_flag) {
+ reset_overall_CU_error_data();
+ print_locs(dbg);
+ }
+ if (abbrev_flag) {
+ reset_overall_CU_error_data();
+ print_abbrevs(dbg);
+ }
+ if (string_flag) {
+ reset_overall_CU_error_data();
+ print_strings(dbg);
+ }
+ if (aranges_flag) {
+ reset_overall_CU_error_data();
+ print_aranges(dbg);
+ }
+ if (ranges_flag) {
+ reset_overall_CU_error_data();
+ print_ranges(dbg);
+ }
+ if (frame_flag || eh_frame_flag) {
+ reset_overall_CU_error_data();
+ current_cu_die_for_print_frames = 0;
+ print_frames(dbg, frame_flag, eh_frame_flag, config_file_data);
+ }
+ if (static_func_flag) {
+ reset_overall_CU_error_data();
+ print_static_funcs(dbg);
+ }
+ if (static_var_flag) {
+ reset_overall_CU_error_data();
+ print_static_vars(dbg);
+ }
+ /* DWARF_PUBTYPES is the standard typenames dwarf section.
+ SGI_TYPENAME is the same concept but is SGI specific ( it was
+ defined 10 years before dwarf pubtypes). */
+
+ if (type_flag) {
+ reset_overall_CU_error_data();
+ print_types(dbg, DWARF_PUBTYPES);
+ reset_overall_CU_error_data();
+ print_types(dbg, SGI_TYPENAME);
+ }
+ if (weakname_flag) {
+ reset_overall_CU_error_data();
+ print_weaknames(dbg);
+ }
+ if (reloc_flag) {
+ reset_overall_CU_error_data();
+ print_relocinfo(dbg, reloc_map);
+ }
+ /* The right time to do this is unclear. But we need to do it. */
+ print_any_harmless_errors(dbg);
+
+ /* Print error report only if errors have been detected */
+ /* Print error report if the -kd option */
+ print_checks_results();
+
+ dres = dwarf_finish(dbg, &err);
+ if (dres != DW_DLV_OK) {
+ print_error(dbg, "dwarf_finish", dres, err);
+ }
+
+ printf("\n");
+ fflush(stderr);
+ return 0;
+
+}
+
+/* Do printing of most sections.
+ Do not do detailed checking.
+*/
+static void
+do_all()
+{
+ info_flag = line_flag = frame_flag = TRUE;
+ pubnames_flag = macinfo_flag = TRUE;
+ aranges_flag = TRUE;
+ /* Do not do
+ loc_flag = TRUE
+ abbrev_flag = TRUE;
+ ranges_flag = TRUE;
+ because nothing in
+ the DWARF spec guarantees the sections are free of random bytes
+ in areas not referenced by .debug_info */
+ string_flag = TRUE;
+ /* Do not do
+ reloc_flag = TRUE;
+ as print_relocs makes no sense for non-elf dwarfdump users. */
+ static_func_flag = static_var_flag = TRUE;
+ type_flag = weakname_flag = TRUE;
+ header_flag = TRUE; /* Dump header info */
+}
+
+
+static const char *usage_text[] = {
+"options:\t-a\tprint all .debug_* sections",
+"\t\t-b\tprint abbrev section",
+"\t\t-c\tprint loc section",
+"\t\t-c<str>\tcheck only specific compiler objects",
+"\t\t \t <str> is described by 'DW_AT_producer'. Examples:",
+"\t\t \t -cg check only GCC compiler objects",
+"\t\t \t -cs check only SNC compiler objects",
+"\t\t \t -c'350.1' check only compiler objects with 350.1 in the CU name",
+"\t\t-C\tactivate printing (with -i) of warnings about",
+"\t\t\tcertain common extensions of DWARF.",
+"\t\t-d\tdense: one line per entry (info section only)",
+"\t\t-D\tdo not show offsets", /* Do not show any offsets */
+"\t\t-e\tellipsis: short names for tags, attrs etc.",
+"\t\t-E\tprint object Header information",
+"\t\t-f\tprint dwarf frame section",
+"\t\t-F\tprint gnu .eh_frame section",
+"\t\t-g\t(use incomplete loclist support)",
+"\t\t-G\tshow global die offsets",
+"\t\t-h\tprint IRIX exception tables (unsupported)",
+"\t\t-H <num>\tlimit output to the first <num> major units",
+"\t\t\t example: to stop after <num> compilation units",
+"\t\t-i\tprint info section",
+"\t\t-k[abcdeEfFgilmMnrRsStx[e]y] check dwarf information",
+"\t\t a\tdo all checks",
+"\t\t b\tcheck abbreviations", /* Check abbreviations */
+"\t\t c\texamine DWARF constants", /* Check for valid DWARF constants */
+"\t\t d\tshow check results", /* Show check results */
+"\t\t e\texamine attributes of pubnames",
+"\t\t E\tignore DWARF extensions", /* Ignore DWARF extensions */
+"\t\t f\texamine frame information (use with -f or -F)",
+"\t\t F\texamine integrity of files-lines attributes", /* Files-Lines integrity */
+"\t\t g\tcheck debug info gaps", /* Check for debug info gaps */
+"\t\t i\tdisplay summary for all compilers", /* Summary all compilers */
+"\t\t l\tcheck location list (.debug_loc)", /* Location list integrity */
+"\t\t m\tcheck ranges list (.debug_ranges)", /* Ranges list integrity */
+"\t\t M\tcheck ranges list (.debug_aranges)",/* Aranges list integrity */
+"\t\t n\texamine names in attributes", /* Check for valid names */
+"\t\t r\texamine tag-attr relation",
+"\t\t R\tcheck forward references to DIEs (declarations)", /* Check DW_AT_specification references */
+"\t\t s\tperform checks in silent mode",
+"\t\t S\tcheck self references to DIEs",
+"\t\t t\texamine tag-tag relations",
+"\t\t x\tbasic frames check (.eh_frame, .debug_frame)",
+"\t\t xe\textensive frames check (.eh_frame, .debug_frame)",
+"\t\t y\texamine type info",
+"\t\t\tUnless -C option given certain common tag-attr and tag-tag",
+"\t\t\textensions are assumed to be ok (not reported).",
+"\t\t-l\tprint line section",
+"\t\t-m\tprint macinfo section",
+"\t\t-M\tprint the form name for each attribute",
+"\t\t-n\tsuppress frame information function name lookup",
+"\t\t \t(when printing frame information from multi-gigabyte",
+"\t\t \tobject files this option may save significant time).",
+"\t\t-N\tprint ranges section",
+"\t\t-o[liaprfoR]\tprint relocation info",
+"\t\t \tl=line,i=info,a=abbrev,p=pubnames,r=aranges,f=frames,o=loc,R=Ranges",
+"\t\t-p\tprint pubnames section",
+"\t\t-P\tprint list of compile units per producer", /* List of CUs per compiler */
+"\t\t-Q\tsuppress printing section data",
+"\t\t-r\tprint aranges section",
+"\t\t-R\tPrint frame register names as r33 etc",
+"\t\t \t and allow up to 1200 registers.",
+"\t\t \t Print using a 'generic' register set.",
+"\t\t-s\tprint string section",
+"\t\t-S <option>=<text>\tsearch for <text> in attributes",
+"\t\t \twith <option>:",
+"\t\t \t-S any=<text>\tany <text>",
+"\t\t \t-S match=<text>\tmatching <text>",
+#ifdef HAVE_REGEX
+"\t\t \t-S regex=<text>\tuse regular expression matching",
+#endif
+"\t\t \t (only one -S option allowed, any= and regex= ",
+"\t\t \t only usable if the functions required are ",
+"\t\t \t found at configure time)",
+"\t\t-t[afv] static: ",
+"\t\t a\tprint both sections",
+"\t\t f\tprint static func section",
+"\t\t v\tprint static var section",
+"\t\t-u<file> print sections only for specified file",
+"\t\t-v\tverbose: show more information",
+"\t\t-vv verbose: show even more information",
+"\t\t-V print version information",
+"\t\t-x name=<path>\tname dwarfdump.conf",
+"\t\t-x abi=<abi>\tname abi in dwarfdump.conf",
+"\t\t-w\tprint weakname section",
+"\t\t-W\tprint parent and children tree (wide format) with the -S option",
+"\t\t-Wp\tprint parent tree (wide format) with the -S option",
+"\t\t-Wc\tprint children tree (wide format) with the -S option",
+"\t\t-y\tprint type section",
+"",
+
+0
+};
+
+
+/* Remove matching leading/trailing quotes.
+ Does not alter the passed in string.
+ If quotes removed does a makename on a modified string. */
+static const char *
+remove_quotes_pair(const char *text)
+{
+ static char single_quote = '\'';
+ static char double_quote = '\"';
+ char quote = 0;
+ const char *p = text;
+ int len = strlen(text);
+
+ if (len < 2) {
+ return p;
+ }
+
+ /* Compare first character with ' or " */
+ if (p[0] == single_quote) {
+ quote = single_quote;
+ } else {
+ if (p[0] == double_quote) {
+ quote = double_quote;
+ }
+ else {
+ return p;
+ }
+ }
+ {
+ if (p[len - 1] == quote) {
+ char *altered = calloc(1,len+1);
+ const char *str2 = 0;
+ strcpy(altered,p+1);
+ altered[len - 2] = '\0';
+ str2 = makename(altered);
+ free(altered);
+ return str2;
+ }
+ }
+ return p;
+}
+
+/* process arguments and return object filename */
+static const char *
+process_args(int argc, char *argv[])
+{
+ extern int optind;
+ int c = 0;
+ boolean usage_error = FALSE;
+ int oarg = 0;
+
+ program_name = argv[0];
+
+ suppress_check_dwarf();
+ if (argv[1] != NULL && argv[1][0] != '-') {
+ do_all();
+ }
+
+ /* j unused */
+ while ((c = getopt(argc, argv,
+ "#:abc::CdDeEfFgGhH:ik:lmMnNo::pPqQrRsS:t:u:UvVwW::x:yz")) != EOF) {
+
+ switch (c) {
+ /* Internal debug level setting. */
+ case '#':
+ {
+ int nTraceLevel = atoi(optarg);
+ if (nTraceLevel > 0 && nTraceLevel <= MAX_TRACE_LEVEL) {
+ nTrace[nTraceLevel] = 1;
+ }
+ break;
+ }
+ case 'M':
+ show_form_used = TRUE;
+ break;
+ case 'x': /* Select abi/path to use */
+ {
+ const char *path = 0;
+ const char *abi = 0;
+ /* -x name=<path> meaning name dwarfdump.conf file -x
+ abi=<abi> meaning select abi from dwarfdump.conf
+ file. Must always select abi to use dwarfdump.conf */
+ if (strncmp(optarg, "name=", 5) == 0) {
+ path = do_uri_translation(&optarg[5],"-x name=");
+ if (strlen(path) < 1) {
+ goto badopt;
+ }
+ config_file_path = path;
+ } else if (strncmp(optarg, "abi=", 4) == 0) {
+ abi = do_uri_translation(&optarg[4],"-x abi=");
+ if (strlen(abi) < 1) {
+ goto badopt;
+ }
+ config_file_abi = abi;
+ break;
+ } else {
+ badopt:
+ fprintf(stderr, "-x name=<path-to-conf> \n");
+ fprintf(stderr, " and \n");
+ fprintf(stderr, "-x abi=<abi-in-conf> \n");
+ fprintf(stderr, "are legal, not -x %s\n", optarg);
+ usage_error = TRUE;
+ break;
+ }
+ }
+ break;
+ case 'C':
+ suppress_check_extensions_tables = TRUE;
+ break;
+ case 'g':
+ use_old_dwarf_loclist = TRUE;
+ info_flag = TRUE;
+ suppress_check_dwarf();
+ break;
+ case 'i':
+ info_flag = TRUE;
+ suppress_check_dwarf();
+ break;
+ case 'n':
+ suppress_nested_name_search = TRUE;
+ break;
+ case 'l':
+ line_flag = TRUE;
+ suppress_check_dwarf();
+ break;
+ case 'f':
+ frame_flag = TRUE;
+ suppress_check_dwarf();
+ break;
+ case 'H':
+ {
+ int break_val = atoi(optarg);
+ if(break_val > 0) {
+ break_after_n_units = break_val;
+ }
+ }
+ break;
+ case 'F':
+ eh_frame_flag = TRUE;
+ suppress_check_dwarf();
+ break;
+ case 'b':
+ abbrev_flag = TRUE;
+ suppress_check_dwarf();
+ break;
+ case 'p':
+ pubnames_flag = TRUE;
+ suppress_check_dwarf();
+ break;
+ case 'P':
+ /* List of CUs per compiler */
+ producer_children_flag = TRUE;
+ break;
+ case 'r':
+ aranges_flag = TRUE;
+ suppress_check_dwarf();
+ break;
+ case 'N':
+ ranges_flag = TRUE;
+ suppress_check_dwarf();
+ break;
+ case 'R':
+ generic_1200_regs = TRUE;
+ break;
+ case 'm':
+ macinfo_flag = TRUE;
+ suppress_check_dwarf();
+ break;
+ case 'c':
+ /* Specify compiler name. */
+ if (optarg) {
+ if ('s' == optarg[0]) {
+ /* -cs : Check SNC compiler */
+ check_snc_compiler = TRUE;
+ check_all_compilers = FALSE;
+ }
+ else {
+ if ('g' == optarg[0]) {
+ /* -cg : Check GCC compiler */
+ check_gcc_compiler = TRUE;
+ check_all_compilers = FALSE;
+ }
+ else {
+ /* Assume a compiler version to check,
+ most likely a substring of a compiler name. */
+ if ((compilers_targeted_count+1) < COMPILER_TABLE_MAX) {
+ Compiler *pCompiler = 0;
+ const char *cmp = 0;
+ cmp = do_uri_translation(optarg,"-c<compiler name>");
+ /* First compiler at position [1] */
+ compilers_targeted_count++;
+ pCompiler = &compilers_targeted[compilers_targeted_count];
+ reset_compiler_entry(pCompiler);
+ pCompiler->name = cmp;
+ check_all_compilers = FALSE;
+ } else {
+ fprintf(stderr, "Compiler table max %d exceeded, "
+ "limiting the tracked compilers to %d\n",
+ COMPILER_TABLE_MAX,COMPILER_TABLE_MAX);
+ }
+ }
+ }
+ } else {
+ loc_flag = TRUE;
+ suppress_check_dwarf();
+ }
+ break;
+ case 'Q':
+ /* Q suppresses section data printing. */
+ do_print_dwarf = FALSE;
+ break;
+ case 'q':
+ /* Suppress uri-did-transate notification */
+ do_print_uri_in_input = FALSE;
+ break;
+ case 's':
+ string_flag = TRUE;
+ suppress_check_dwarf();
+ break;
+ case 'S':
+ /* -S option: strings for 'any' and 'match' */
+ {
+ boolean err = TRUE;
+ search_is_on = TRUE;
+ const char *tempstr = 0;
+ /* -S text */
+ if (strncmp(optarg,"match=",6) == 0) {
+
+ search_match_text = makename(&optarg[6]);
+ tempstr = remove_quotes_pair(search_match_text);
+ search_match_text = do_uri_translation(tempstr,"-S match=");
+ if (strlen(search_match_text) > 0) {
+ err = FALSE;
+ }
+ }
+ else {
+ if (strncmp(optarg,"any=",4) == 0) {
+ search_any_text = makename(&optarg[4]);
+ tempstr = remove_quotes_pair(search_any_text);
+ search_any_text = do_uri_translation(tempstr,"-S any=");
+ if (strlen(search_any_text) > 0) {
+ err = FALSE;
+ }
+ }
+#ifdef HAVE_REGEX
+ else {
+ if (strncmp(optarg,"regex=",6) == 0) {
+ search_regex_text = makename(&optarg[6]);
+ tempstr = remove_quotes_pair(
+ search_regex_text);
+ search_regex_text = do_uri_translation(tempstr,
+ "-S regex=");
+ if (strlen(search_regex_text) > 0) {
+ if (regcomp(&search_re,search_regex_text,
+ REG_EXTENDED)) {
+ fprintf(stderr,
+ "regcomp: unable to compile %s\n",
+ search_regex_text);
+ }
+ else {
+ err = FALSE;
+ }
+ }
+ }
+ }
+#endif /* HAVE_REGEX */
+ }
+ if (err) {
+ fprintf(stderr,"-S any=<text> or -S match=<text> or -S regex=<text>\n");
+ fprintf(stderr, "is allowed, not -S %s\n",optarg);
+ usage_error = TRUE;
+ }
+ }
+ break;
+
+ case 'a':
+ suppress_check_dwarf();
+ do_all();
+ break;
+ case 'v':
+ verbose++;
+ break;
+ case 'V':
+ /* Display dwarfdump compilation date and time */
+ print_version_details(argv[0],TRUE);
+ exit(OKAY);
+ break;
+ case 'd':
+ /* This is sort of useless unless printing,
+ but harmless, so we do not insist we
+ are printing with suppress_check_dwarf(). */
+ dense = TRUE;
+ break;
+ case 'D':
+ /* Do not emit offset in output */
+ display_offsets = FALSE;
+ break;
+ case 'e':
+ suppress_check_dwarf();
+ ellipsis = TRUE;
+ break;
+ case 'E':
+ /* Object Header information (but maybe really print) */
+ header_flag = TRUE;
+ break;
+ case 'o':
+ reloc_flag = TRUE;
+ if (optarg) {
+ switch (optarg[0]) {
+ case 'i':
+ reloc_map |= (1 << DW_SECTION_REL_DEBUG_INFO); break;
+ reloc_map |= (1 << DW_SECTION_REL_DEBUG_TYPES); break;
+ case 'l': reloc_map |= (1 << DW_SECTION_REL_DEBUG_LINE); break;
+ case 'p': reloc_map |= (1 << DW_SECTION_REL_DEBUG_PUBNAMES); break;
+ /* Case a has no effect, no relocations can point out
+ of the abbrev section. */
+ case 'a': reloc_map |= (1 << DW_SECTION_REL_DEBUG_ABBREV); break;
+ case 'r': reloc_map |= (1 << DW_SECTION_REL_DEBUG_ARANGES); break;
+ case 'f': reloc_map |= (1 << DW_SECTION_REL_DEBUG_FRAME); break;
+ case 'o': reloc_map |= (1 << DW_SECTION_REL_DEBUG_LOC); break;
+ case 'R': reloc_map |= (1 << DW_SECTION_REL_DEBUG_RANGES); break;
+ default: usage_error = TRUE; break;
+ }
+ } else {
+ /* Display all relocs */
+ reloc_map = 0x00ff;
+ }
+ break;
+ case 'k':
+ suppress_print_dwarf();
+ oarg = optarg[0];
+ switch (oarg) {
+ case 'a':
+ check_pubname_attr = TRUE;
+ check_attr_tag = TRUE;
+ check_tag_tree = check_type_offset = TRUE;
+ check_names = TRUE;
+ pubnames_flag = info_flag = TRUE;
+ check_decl_file = TRUE;
+ check_frames = TRUE;
+ /*check_frames_extended = FALSE; */
+ check_locations = TRUE;
+ frame_flag = eh_frame_flag = TRUE;
+ check_ranges = TRUE;
+ check_lines = TRUE;
+ check_fdes = TRUE;
+ check_harmless = TRUE;
+ check_aranges = TRUE;
+ aranges_flag = TRUE; /* Aranges section */
+ check_abbreviations = TRUE;
+ check_dwarf_constants = TRUE;
+ check_di_gaps = TRUE; /* Check debug info gaps */
+ check_forward_decl = TRUE; /* Check forward declarations */
+ check_self_references = TRUE; /* Check self references */
+ break;
+ /* Abbreviations */
+ case 'b':
+ check_abbreviations = TRUE;
+ info_flag = TRUE;
+ break;
+ /* DWARF constants */
+ case 'c':
+ check_dwarf_constants = TRUE;
+ info_flag = TRUE;
+ break;
+ /* Display check results */
+ case 'd':
+ check_show_results = TRUE;
+ break;
+ case 'e':
+ check_pubname_attr = TRUE;
+ pubnames_flag = TRUE;
+ check_harmless = TRUE;
+ check_fdes = TRUE;
+ break;
+ case 'f':
+ check_harmless = TRUE;
+ check_fdes = TRUE;
+ break;
+ /* files-lines */
+ case 'F':
+ check_decl_file = TRUE;
+ check_lines = TRUE;
+ info_flag = TRUE;
+ break;
+ /* Check debug info gaps */
+ case 'g':
+ check_di_gaps = TRUE;
+ info_flag = TRUE;
+ break;
+ /* Locations list */
+ case 'l':
+ check_locations = TRUE;
+ info_flag = TRUE;
+ loc_flag = TRUE;
+ break;
+ /* Ranges */
+ case 'm':
+ check_ranges = TRUE;
+ info_flag = TRUE;
+ break;
+ /* Aranges */
+ case 'M':
+ check_aranges = TRUE;
+ aranges_flag = TRUE;
+ break;
+ /* invalid names */
+ case 'n':
+ check_names = TRUE;
+ info_flag = TRUE;
+ break;
+ case 'r':
+ check_attr_tag = TRUE;
+ info_flag = TRUE;
+ check_harmless = TRUE;
+ break;
+ /* forward declarations in DW_AT_specification */
+ case 'R':
+ check_forward_decl = TRUE;
+ info_flag = TRUE;
+ break;
+ /* Check verbose mode */
+ case 's':
+ check_verbose_mode = FALSE;
+ break;
+ /* self references in:
+ DW_AT_specification, DW_AT_type, DW_AT_abstract_origin */
+ case 'S':
+ check_self_references = TRUE;
+ info_flag = TRUE;
+ break;
+ case 't':
+ check_tag_tree = TRUE;
+ check_harmless = TRUE;
+ info_flag = TRUE;
+ break;
+ case 'y':
+ check_type_offset = TRUE;
+ check_harmless = TRUE;
+ check_decl_file = TRUE;
+ info_flag = TRUE;
+ check_ranges = TRUE;
+ check_aranges = TRUE;
+ break;
+ /* Summary for each compiler */
+ case 'i':
+ print_summary_all = TRUE;
+ break;
+ /* Frames check */
+ case 'x':
+ check_frames = TRUE;
+ frame_flag = TRUE;
+ eh_frame_flag = TRUE;
+ if (optarg[1]) {
+ if ('e' == optarg[1]) {
+ /* -xe : Extended frames check */
+ check_frames = FALSE;
+ check_frames_extended = TRUE;
+ } else {
+ usage_error = TRUE;
+ }
+ }
+ break;
+ default:
+ usage_error = TRUE;
+ break;
+ }
+ break;
+ case 'u': { /* compile unit */
+ const char *tstr = 0;
+ cu_name_flag = TRUE;
+ tstr = do_uri_translation(optarg,"-u<cu name>");
+ safe_strcpy(cu_name,sizeof(cu_name), tstr,strlen(tstr));
+ }
+ break;
+ case 'U':
+ uri_options_translation = FALSE;
+ break;
+ case 't':
+ oarg = optarg[0];
+ switch (oarg) {
+ case 'a':
+ /* all */
+ static_func_flag = static_var_flag = TRUE;
+ suppress_check_dwarf();
+ break;
+ case 'f':
+ /* .debug_static_func */
+ static_func_flag = TRUE;
+ suppress_check_dwarf();
+ break;
+ case 'v':
+ /* .debug_static_var */
+ static_var_flag = TRUE;
+ suppress_check_dwarf();
+ break;
+ default:
+ usage_error = TRUE;
+ break;
+ }
+ break;
+ case 'y': /* .debug_types */
+ suppress_check_dwarf();
+ type_flag = TRUE;
+ break;
+ case 'w': /* .debug_weaknames */
+ weakname_flag = TRUE;
+ suppress_check_dwarf();
+ break;
+ case 'z':
+ fprintf(stderr, "-z is no longer supported:ignored\n");
+ break;
+ case 'G':
+ show_global_offsets = TRUE;
+ break;
+ case 'W':
+ /* Search results in wide format */
+ search_wide_format = TRUE;
+ if (optarg) {
+ if ('c' == optarg[0]) {
+ /* -Wc : Display children tree */
+ display_children_tree = TRUE;
+ } else {
+ if ('p' == optarg[0]) {
+ /* -Wp : Display parent tree */
+ display_parent_tree = TRUE;
+ } else {
+ usage_error = TRUE;
+ }
+ }
+ }
+ else {
+ /* -W : Display parent and children tree */
+ display_children_tree = TRUE;
+ display_parent_tree = TRUE;
+ }
+ break;
+ default:
+ usage_error = TRUE;
+ break;
+ }
+ }
+
+ init_conf_file_data(&config_file_data);
+ if (config_file_abi && generic_1200_regs) {
+ printf("Specifying both -R and -x abi= is not allowed. Use one "
+ "or the other. -x abi= ignored.\n");
+ config_file_abi = FALSE;
+ }
+ if(generic_1200_regs) {
+ init_generic_config_1200_regs(&config_file_data);
+ }
+ if (config_file_abi && (frame_flag || eh_frame_flag)) {
+ int res = find_conf_file_and_read_config(config_file_path,
+ config_file_abi,
+ config_file_defaults,
+ &config_file_data);
+
+ if (res > 0) {
+ printf
+ ("Frame not configured due to error(s). Giving up.\n");
+ eh_frame_flag = FALSE;
+ frame_flag = FALSE;
+ }
+ }
+ if (usage_error || (optind != (argc - 1))) {
+ print_usage_message(program_name,usage_text);
+ exit(FAILED);
+ }
+
+ if (do_check_dwarf) {
+ /* Reduce verbosity when checking (checking means checking-only). */
+ verbose = 1;
+ }
+ return do_uri_translation(argv[optind],"file-to-process");
+}
+
+
+void
+print_error(Dwarf_Debug dbg, string msg, int dwarf_code,
+ Dwarf_Error err)
+{
+ print_error_and_continue(dbg,msg,dwarf_code,err);
+ dwarf_finish(dbg, &err);
+ exit(FAILED);
+}
+/* ARGSUSED */
+void
+print_error_and_continue(Dwarf_Debug dbg, string msg, int dwarf_code,
+ Dwarf_Error err)
+{
+ fflush(stdout);
+ fflush(stderr);
+
+ fprintf(stderr,"\n");
+
+ if (dwarf_code == DW_DLV_ERROR) {
+ string errmsg = dwarf_errmsg(err);
+ Dwarf_Unsigned myerr = dwarf_errno(err);
+
+ fprintf(stderr, "%s ERROR: %s: %s (%lu)\n",
+ program_name, msg, errmsg, (unsigned long) myerr);
+ } else if (dwarf_code == DW_DLV_NO_ENTRY) {
+ fprintf(stderr, "%s NO ENTRY: %s: \n", program_name, msg);
+ } else if (dwarf_code == DW_DLV_OK) {
+ fprintf(stderr, "%s: %s \n", program_name, msg);
+ } else {
+ fprintf(stderr, "%s InternalError: %s: code %d\n",
+ program_name, msg, dwarf_code);
+ }
+ fflush(stderr);
+
+ /* Display compile unit name */
+ PRINT_CU_INFO();
+}
+
+/* Predicate function. Returns 'true' if the CU should
+ be skipped as the DW_AT_name of the CU
+ does not match the command-line-supplied
+ cu name. Else returns false.*/
+boolean
+should_skip_this_cu(Dwarf_Debug dbg, Dwarf_Die cu_die, Dwarf_Error err)
+{
+ Dwarf_Half tag = 0;
+ Dwarf_Attribute attrib = 0;
+ Dwarf_Half theform = 0;
+ int dares = 0;
+ int tres = 0;
+ int fres = 0;
+
+ tres = dwarf_tag(cu_die, &tag, &err);
+ if (tres != DW_DLV_OK) {
+ print_error(dbg, "dwarf_tag in aranges",
+ tres, err);
+ }
+ dares = dwarf_attr(cu_die, DW_AT_name, &attrib,
+ &err);
+ if (dares != DW_DLV_OK) {
+ print_error(dbg, "dwarf_attr arange"
+ " derived die has no name",
+ dares, err);
+ }
+ fres = dwarf_whatform(attrib, &theform, &err);
+ if (fres == DW_DLV_OK) {
+ if (theform == DW_FORM_string
+ || theform == DW_FORM_strp) {
+ char * temps = 0;
+ int sres = dwarf_formstring(attrib, &temps,
+ &err);
+ if (sres == DW_DLV_OK) {
+ char *p = temps;
+ if (cu_name[0] != '/') {
+ p = strrchr(temps, '/');
+ if (p == NULL) {
+ p = temps;
+ } else {
+ p++;
+ }
+ }
+ /* Ignore case if Windows */
+#if WIN32
+ if (stricmp(cu_name, p)) {
+ // skip this cu.
+ return TRUE;
+ }
+#else
+ if (strcmp(cu_name, p)) {
+ // skip this cu.
+ return TRUE;
+ }
+#endif /* WIN32 */
+
+ } else {
+ print_error(dbg,
+ "arange: string missing",
+ sres, err);
+ }
+ }
+ } else {
+ print_error(dbg,
+ "dwarf_whatform unexpected value",
+ fres, err);
+ }
+ dwarf_dealloc(dbg, attrib, DW_DLA_ATTR);
+ return FALSE;
+}
+
+/* Returns the DW_AT_name of the CU */
+string
+old_get_cu_name(Dwarf_Debug dbg, Dwarf_Die cu_die, Dwarf_Error err)
+{
+ static struct esb_s esb_attr_name;
+ Dwarf_Half tag;
+ Dwarf_Attribute attrib;
+ Dwarf_Half theform;
+ int dares;
+ int tres;
+ int fres;
+
+ /* Initialize flexible string buffer */
+ esb_empty_string(&esb_attr_name);
+
+ tres = dwarf_tag(cu_die, &tag, &err);
+ if (tres != DW_DLV_OK) {
+ print_error(dbg, "dwarf_tag in aranges",
+ tres, err);
+ }
+ dares = dwarf_attr(cu_die, DW_AT_name, &attrib,
+ &err);
+ if (dares != DW_DLV_OK) {
+ print_error(dbg, "dwarf_attr arange"
+ " derived die has no name",
+ dares, err);
+ }
+ fres = dwarf_whatform(attrib, &theform, &err);
+ if (fres == DW_DLV_OK) {
+ if (theform == DW_FORM_string
+ || theform == DW_FORM_strp) {
+ char * temps = 0;
+ int sres = dwarf_formstring(attrib, &temps,
+ &err);
+ if (sres == DW_DLV_OK) {
+ char *p = temps;
+ if (cu_name[0] != '/') {
+ p = strrchr(temps, '/');
+ if (p == NULL) {
+ p = temps;
+ } else {
+ p++;
+ }
+ }
+ esb_append(&esb_attr_name,p);
+ } else {
+ print_error(dbg,
+ "arange: string missing",
+ sres, err);
+ }
+ }
+ } else {
+ print_error(dbg,
+ "dwarf_whatform unexpected value",
+ fres, err);
+ }
+ dwarf_dealloc(dbg, attrib, DW_DLA_ATTR);
+
+ /* Return the esb internal string */
+ return esb_get_string(&esb_attr_name);
+}
+
+/* Returns the cu of the CU */
+int get_cu_name(Dwarf_Debug dbg, Dwarf_Die cu_die,
+ Dwarf_Error err, string *short_name, string *long_name)
+{
+ Dwarf_Attribute name_attr = 0;
+ int ares;
+
+ ares = dwarf_attr(cu_die, DW_AT_name, &name_attr, &err);
+ if (ares == DW_DLV_ERROR) {
+ print_error(dbg, "hassattr on DW_AT_name", ares, err);
+ } else {
+ if (ares == DW_DLV_NO_ENTRY) {
+ *short_name = "<unknown name>";
+ *long_name = "<unknown name>";
+ } else {
+ /* DW_DLV_OK */
+ /* The string return is valid until the next call to this
+ function; so if the caller needs to keep the returned
+ string, the string must be copied (makename()). */
+ static struct esb_s esb_short_name;
+ static struct esb_s esb_long_name;
+ char *filename;
+ esb_empty_string(&esb_long_name);
+ get_attr_value(dbg, DW_TAG_compile_unit,
+ cu_die, name_attr, NULL, 0, &esb_long_name,
+ 0 /*show_form_used*/,0 /* verbose */);
+ *long_name = esb_get_string(&esb_long_name);
+ /* Generate the short name (filename) */
+ filename = strrchr(*long_name,'/');
+ if (!filename) {
+ filename = strrchr(*long_name,'\\');
+ }
+ if (filename) {
+ ++filename;
+ } else {
+ filename = *long_name;
+ }
+ esb_empty_string(&esb_short_name);
+ esb_append(&esb_short_name,filename);
+ *short_name = esb_get_string(&esb_short_name);
+ }
+ }
+
+ dwarf_dealloc(dbg, name_attr, DW_DLA_ATTR);
+ return ares;
+}
+
+/* Returns the producer of the CU */
+int get_producer_name(Dwarf_Debug dbg, Dwarf_Die cu_die,
+ Dwarf_Error err, string *producer_name)
+{
+ Dwarf_Attribute producer_attr = 0;
+ int ares;
+
+ ares = dwarf_attr(cu_die, DW_AT_producer, &producer_attr, &err);
+ if (ares == DW_DLV_ERROR) {
+ print_error(dbg, "hassattr on DW_AT_producer", ares, err);
+ } else {
+ if (ares == DW_DLV_NO_ENTRY) {
+ /* We add extra quotes so it looks more like
+ the names for real producers that get_attr_value
+ produces. */
+ *producer_name = "\"<CU-missing-DW_AT_producer>\"";
+ } else {
+ /* DW_DLV_OK */
+ /* The string return is valid until the next call to this
+ function; so if the caller needs to keep the returned
+ string, the string must be copied (makename()). */
+ static struct esb_s esb_producer;
+ esb_empty_string(&esb_producer);
+ get_attr_value(dbg, DW_TAG_compile_unit,
+ cu_die, producer_attr, NULL, 0, &esb_producer,
+ 0 /*show_form_used*/,0 /* verbose */);
+ *producer_name = esb_get_string(&esb_producer);
+ }
+ }
+
+ dwarf_dealloc(dbg, producer_attr, DW_DLA_ATTR);
+ return ares;
+}
+
+/* GCC linkonce names */
+char *lo_text = ".text."; /*".gnu.linkonce.t.";*/
+char *lo_debug_abbr = ".gnu.linkonce.wa.";
+char *lo_debug_aranges = ".gnu.linkonce.wr.";
+char *lo_debug_frame_1 = ".gnu.linkonce.wf.";
+char *lo_debug_frame_2 = ".gnu.linkonce.wF.";
+char *lo_debug_info = ".gnu.linkonce.wi.";
+char *lo_debug_line = ".gnu.linkonce.wl.";
+char *lo_debug_macinfo = ".gnu.linkonce.wm.";
+char *lo_debug_loc = ".gnu.linkonce.wo.";
+char *lo_debug_pubnames = ".gnu.linkonce.wp.";
+char *lo_debug_ranges = ".gnu.linkonce.wR.";
+char *lo_debug_str = ".gnu.linkonce.ws.";
+
+/* SNC compiler/linker linkonce names */
+char *nlo_text = ".text.";
+char *nlo_debug_abbr = ".debug.wa.";
+char *nlo_debug_aranges = ".debug.wr.";
+char *nlo_debug_frame_1 = ".debug.wf.";
+char *nlo_debug_frame_2 = ".debug.wF.";
+char *nlo_debug_info = ".debug.wi.";
+char *nlo_debug_line = ".debug.wl.";
+char *nlo_debug_macinfo = ".debug.wm.";
+char *nlo_debug_loc = ".debug.wo.";
+char *nlo_debug_pubnames = ".debug.wp.";
+char *nlo_debug_ranges = ".debug.wR.";
+char *nlo_debug_str = ".debug.ws.";
+
+/* Build linkonce section information */
+void
+build_linkonce_info(Dwarf_Debug dbg)
+{
+ int nCount = 0;
+ int section_index = 0;
+ int res = 0;
+
+ static char **linkonce_names[] = {
+ &lo_text, /* .text */
+ &nlo_text, /* .text */
+ &lo_debug_abbr, /* .debug_abbr */
+ &nlo_debug_abbr, /* .debug_abbr */
+ &lo_debug_aranges, /* .debug_aranges */
+ &nlo_debug_aranges, /* .debug_aranges */
+ &lo_debug_frame_1, /* .debug_frame */
+ &nlo_debug_frame_1, /* .debug_frame */
+ &lo_debug_frame_2, /* .debug_frame */
+ &nlo_debug_frame_2, /* .debug_frame */
+ &lo_debug_info, /* .debug_info */
+ &nlo_debug_info, /* .debug_info */
+ &lo_debug_line, /* .debug_line */
+ &nlo_debug_line, /* .debug_line */
+ &lo_debug_macinfo, /* .debug_macinfo */
+ &nlo_debug_macinfo, /* .debug_macinfo */
+ &lo_debug_loc, /* .debug_loc */
+ &nlo_debug_loc, /* .debug_loc */
+ &lo_debug_pubnames, /* .debug_pubnames */
+ &nlo_debug_pubnames, /* .debug_pubnames */
+ &lo_debug_ranges, /* .debug_ranges */
+ &nlo_debug_ranges, /* .debug_ranges */
+ &lo_debug_str, /* .debug_str */
+ &nlo_debug_str, /* .debug_str */
+ NULL
+ };
+
+ const char *section_name = NULL;
+ Dwarf_Addr section_addr = 0;
+ Dwarf_Unsigned section_size = 0;
+ Dwarf_Error error = 0;
+ int nIndex = 0;
+
+ nCount = dwarf_get_section_count(dbg);
+
+ /* Ignore section with index=0 */
+ for (section_index = 1; section_index < nCount; ++section_index) {
+ res = dwarf_get_section_info_by_index(dbg,section_index,
+ &section_name,
+ &section_addr,
+ &section_size,
+ &error);
+
+ if (res == DW_DLV_OK) {
+ for (nIndex = 0; linkonce_names[nIndex]; ++nIndex) {
+ if (section_name == strstr(section_name,
+ *linkonce_names[nIndex])) {
+
+ /* Insert only linkonce sections */
+ AddEntryIntoBucketGroup(pLinkonceInfo,
+ section_index,
+ section_addr,section_addr,
+ section_addr + section_size,
+ section_name,
+ TRUE);
+ break;
+ }
+ }
+ }
+ }
+
+ if (dump_linkonce_info) {
+ PrintBucketGroup(pLinkonceInfo,TRUE);
+ }
+}
+
+/* Check for specific TAGs and initialize some
+ information used by '-k' options */
+void
+tag_specific_checks_setup(Dwarf_Half val,int die_indent_level)
+{
+ switch (val) {
+ case DW_TAG_compile_unit:
+ /* To help getting the compile unit name */
+ seen_CU = TRUE;
+ /* If we are checking line information, build
+ the table containing the pairs LowPC and HighPC */
+ if (check_decl_file || check_ranges || check_locations) {
+ ResetBucketGroup(pRangesInfo);
+ }
+ /* The following flag indicate that only low_pc and high_pc
+ values found in DW_TAG_subprograms are going to be considered when
+ building the address table used to check ranges, lines, etc */
+ need_PU_valid_code = TRUE;
+ break;
+
+ case DW_TAG_subprogram:
+ /* Keep track of a PU */
+ if (die_indent_level == 1) {
+ /* A DW_TAG_subprogram can be nested, when is used to
+ declare a member function for a local class; process the DIE
+ only if we are at level zero in the DIEs tree */
+ seen_PU = TRUE;
+ seen_PU_base_address = FALSE;
+ seen_PU_high_address = FALSE;
+ PU_name[0] = 0;
+ need_PU_valid_code = TRUE;
+ }
+ break;
+ }
+}
+
+/* Indicates if the current CU is a target */
+static boolean current_cu_is_checked_compiler = TRUE;
+
+/* Are we checking for errors from the
+ compiler of the current compilation unit?
+*/
+boolean
+checking_this_compiler()
+{
+ /* This flag has been update by 'update_compiler_target()'
+ and indicates if the current CU is in a targeted compiler
+ specified by the user. Default value is TRUE, which
+ means test all compilers until a CU is detected. */
+ return current_cu_is_checked_compiler || check_all_compilers;
+}
+
+static int
+hasprefix(const char *sample, const char *prefix)
+{
+ unsigned prelen = strlen(prefix);
+ if ( strncmp(sample,prefix,prelen) == 0) {
+ return TRUE;
+ }
+ return FALSE;
+}
+
+/* Record which compiler was used (or notice we saw
+ it before) and set a couple variables as
+ a side effect (which are used all over):
+ current_cu_is_checked_compiler (used in checking_this_compiler() )
+ current_compiler
+ The compiler name is from DW_AT_producer.
+*/
+void
+update_compiler_target(const char *producer_name)
+{
+ Dwarf_Bool cFound = FALSE;
+ int index = 0;
+
+ safe_strcpy(CU_producer,sizeof(CU_producer),producer_name,
+ strlen(producer_name));
+ current_cu_is_checked_compiler = FALSE;
+
+ /* This list of compilers is just a start:
+ GCC id : "GNU"
+ SNC id : "SN Systems" */
+
+ /* Find a compiler version to check */
+ if (compilers_targeted_count) {
+ for (index = 1; index <= compilers_targeted_count; ++index) {
+ if (is_strstrnocase(CU_producer,compilers_targeted[index].name)) {
+ compilers_targeted[index].verified = TRUE;
+ current_cu_is_checked_compiler = TRUE;
+ break;
+ }
+ }
+ } else {
+ /* Take into account that internally all strings are double quoted */
+ boolean snc_compiler = hasprefix(CU_producer,"\"SN")? TRUE : FALSE;
+ boolean gcc_compiler = hasprefix(CU_producer,"\"GNU")?TRUE : FALSE;
+ current_cu_is_checked_compiler = check_all_compilers ||
+ (snc_compiler && check_snc_compiler) ||
+ (gcc_compiler && check_gcc_compiler) ;
+ }
+
+ /* Check for already detected compiler */
+ for (index = 1; index <= compilers_detected_count; ++index) {
+ if (
+#if WIN32
+ !stricmp(compilers_detected[index].name,CU_producer)
+#else
+ !strcmp(compilers_detected[index].name,CU_producer)
+#endif
+ ) {
+ /* Set current compiler index */
+ current_compiler = index;
+ cFound = TRUE;
+ break;
+ }
+ }
+ if (!cFound) {
+ /* Record a new detected compiler name. */
+ if (compilers_detected_count + 1 < COMPILER_TABLE_MAX) {
+ Compiler *pCompiler = 0;
+ char *cmp = makename(CU_producer);
+ /* Set current compiler index, first compiler at position [1] */
+ current_compiler = ++compilers_detected_count;
+ pCompiler = &compilers_detected[current_compiler];
+ reset_compiler_entry(pCompiler);
+ pCompiler->name = cmp;
+ }
+ }
+}
+
+/* Add a CU name to the current compiler entry, specified by the
+ 'current_compiler'; the name is added to the 'compilers_detected'
+ table and is printed if the '-P' option is specified in the
+ command line. */
+void
+add_cu_name_compiler_target(char *name)
+{
+ a_name_chain *cu_last = 0;
+ a_name_chain *nc = 0;
+ Compiler *pCompiler = 0;
+
+ if (current_compiler < 1) {
+ fprintf(stderr,"Current compiler set to %d, cannot add "
+ "Compilation unit name. Giving up.",current_compiler);
+ exit(1);
+ }
+ pCompiler = &compilers_detected[current_compiler];
+ cu_last = pCompiler->cu_last;
+ /* Record current cu name */
+ nc = (a_name_chain *)malloc(sizeof(a_name_chain));
+ nc->item = makename(name);
+ nc->next = NULL;
+ if (cu_last) {
+ cu_last->next = nc;
+ } else {
+ pCompiler->cu_list = nc;
+ }
+ pCompiler->cu_last = nc;
+}
+
+/* Reset a compiler entry, so all fields are properly set */
+static void
+reset_compiler_entry(Compiler *compiler)
+{
+ memset(compiler,0,sizeof(Compiler));
+}
+
+/* Making this a named string makes it simpler to change
+ what the reset,or 'I do not know' value is for
+ CU name or producer name for PRINT_CU_INFO. */
+static const char * default_cu_producer = "<unknown>";
+static void
+reset_overall_CU_error_data()
+{
+ strcpy(CU_name,default_cu_producer);
+ strcpy(CU_producer,default_cu_producer);
+ DIE_offset = 0;
+ DIE_overall_offset = 0;
+ DIE_CU_offset = 0;
+ DIE_CU_overall_offset = 0;
+ CU_base_address = 0;
+ CU_high_address = 0;
+}
+
+
+static boolean
+cu_data_is_set()
+{
+ if(strcmp(CU_name,default_cu_producer) ||
+ strcmp(CU_producer,default_cu_producer)) {
+ return 1;
+ }
+ if(DIE_offset || DIE_overall_offset) {
+ return 1;
+ }
+ if(CU_base_address || CU_high_address) {
+ return 1;
+ }
+ return 0;
+}
+/* Print CU basic information */
+void PRINT_CU_INFO()
+{
+ if (current_section_id == DEBUG_LINE ||
+ current_section_id == DEBUG_ARANGES) {
+ /* Only in the DEBUG_LINE/ARANGES case is DIE_CU_offset or
+ DIE_CU_overall_offset what we want to print here.
+ In other cases DIE_CU_offset is not really a CU
+ offset at all. */
+ DIE_offset = DIE_CU_offset;
+ DIE_overall_offset = DIE_CU_overall_offset;
+ }
+ if(!cu_data_is_set()) {
+ return;
+ }
+ printf("\n");
+ printf("CU Name = %s\n",CU_name);
+ printf("CU Producer = %s\n",CU_producer);
+ printf("DIE OFF = 0x%08" DW_PR_DUx
+ " GOFF = 0x%08" DW_PR_DUx ,DIE_offset,DIE_overall_offset);
+ printf(", Low PC = 0x%08" DW_PR_DUx ", High PC = 0x%08" DW_PR_DUx ,
+ CU_base_address,CU_high_address);
+ printf("\n");
+ fflush(stdout);
+}
+
+void DWARF_CHECK_COUNT(Dwarf_Check_Categories category, int inc)
+{
+ compilers_detected[0].results[category].checks += inc;
+ compilers_detected[0].results[total_check_result].checks += inc;
+ if(current_compiler > 0 && current_compiler < COMPILER_TABLE_MAX) {
+ compilers_detected[current_compiler].results[category].checks += inc;
+ compilers_detected[current_compiler].results[total_check_result].checks
+ += inc;
+ compilers_detected[current_compiler].verified = TRUE;
+ }
+}
+
+void DWARF_ERROR_COUNT(Dwarf_Check_Categories category, int inc)
+{
+ compilers_detected[0].results[category].errors += inc;
+ compilers_detected[0].results[total_check_result].errors += inc;
+ if(current_compiler > 0 && current_compiler < COMPILER_TABLE_MAX) {
+ compilers_detected[current_compiler].results[category].errors += inc;
+ compilers_detected[current_compiler].results[total_check_result].errors
+ += inc;
+ }
+}
+
+void PRINT_CHECK_RESULT(char *str,
+ Compiler *pCompiler, Dwarf_Check_Categories category)
+{
+ Dwarf_Check_Result result = pCompiler->results[category];
+ fprintf(stderr, "%-24s%10d %10d\n", str, result.checks, result.errors);
+}
+
+void DWARF_CHECK_ERROR_PRINT_CU()
+{
+ if (check_verbose_mode) {
+ PRINT_CU_INFO();
+ }
+ check_error++;
+ record_dwarf_error = TRUE;
+}
+
+void DWARF_CHECK_ERROR(Dwarf_Check_Categories category,
+ const char *str)
+{
+ if (checking_this_compiler()) {
+ DWARF_ERROR_COUNT(category,1);
+ if (check_verbose_mode) {
+ printf("\n*** DWARF CHECK: %s ***\n", str);
+ }
+ DWARF_CHECK_ERROR_PRINT_CU();
+ }
+}
+
+void DWARF_CHECK_ERROR2(Dwarf_Check_Categories category,
+ const char *str1, const char *str2)
+{
+ if (checking_this_compiler()) {
+ DWARF_ERROR_COUNT(category,1);
+ if (check_verbose_mode) {
+ printf("\n*** DWARF CHECK: %s: %s ***\n", str1, str2);
+ }
+ DWARF_CHECK_ERROR_PRINT_CU();
+ }
+}
+
+void DWARF_CHECK_ERROR3(Dwarf_Check_Categories category,
+ const char *str1, const char *str2, const char *strexpl)
+{
+ if (checking_this_compiler()) {
+ DWARF_ERROR_COUNT(category,1);
+ if (check_verbose_mode) {
+ printf("\n*** DWARF CHECK: %s -> %s: %s ***\n",
+ str1, str2,strexpl);
+ }
+ DWARF_CHECK_ERROR_PRINT_CU();
+ }
+}
+
+/* Precondition: 'out' is already constructed and empty. */
+static const char *
+do_uri_translation(const char *s,const char *context)
+{
+ struct esb_s str;
+ char *finalstr = 0;
+ if (!uri_options_translation) {
+ return makename(s);
+ }
+ esb_constructor(&str);
+ translate_from_uri(s,&str);
+ if (do_print_uri_in_input) {
+ if(strcmp(s,esb_get_string(&str))) {
+ printf("Uri Translation on option %s\n",context);
+ printf(" \'%s\'\n",s);
+ printf(" \'%s\'\n",esb_get_string(&str));
+ }
+ }
+ finalstr = makename(esb_get_string(&str));
+ esb_destructor(&str);
+ return finalstr;
+}
diff --git a/dwarfdump/dwarfdump.conf b/dwarfdump/dwarfdump.conf
new file mode 100644
index 0000000..d70bab8
--- /dev/null
+++ b/dwarfdump/dwarfdump.conf
@@ -0,0 +1,810 @@
+# MIPS/IRIX ISA/ABI
+# Used to configure dwarfdump printing of .debug_frame and
+# .eh_frame.
+
+# Any number of abi's can be described. Only one can be selected
+# in a given dwarfdump run (see dwarfdump options)
+# Available commands are
+# beginabi: <abiname>
+# reg: <regname> <dwarf regnumber>
+# frame_interface: <integer value 2 or 3>
+# cfa_reg: <number>
+# initial_reg_value: <number: often 1034 or 1035 >
+# same_val_reg: 1035
+# undefined_val_reg: 1034
+# reg_table_size: <size of table>
+# address_size: <4 or 8, Rarely needed, see example below. >
+# includeabi: <abiname Inserts the referenced abi as if its text was
+# directly inserted at this point.>
+# endabi: <abiname>
+#
+# Symbolic names do not work here, use literal numbers
+# where applicable (in C standard decimal, octal (leading 0) or
+# hexadecimal <leading 0x>).
+#
+# Whitespace is required to separate command: from operands and
+# operands from each other on a line.
+#
+# There is no ordering required within a beginabi/endabi pair.
+# As many ABIs as required may be listed.
+# dwarfdump will choose exactly one abi to dump frame information.
+#
+
+
+# MIPS abi,the old IRIX form, not to be used on modern objects.
+# Begin with abi name (use here and on dwarfdump command line).
+beginabi: mips-irix
+
+# Instructs dwarfdump to default to the older frame interface.
+# Use value 3 to use the newer interface.
+# The '2' interface is supported but deprecated (deprecated
+# because it cannot work with all popular ABIs: mixing
+# the cfa-rule into the table column set was not a good idea
+# but it is part of the MIPS/IRIX standard usage).
+frame_interface: 2
+
+# If (and only if) using frame_interface: 2 tell dwarfdump
+# what table colum that DW_FRAME_CFA_COL is.
+# If using frame_interface: 3 cfa_reg: should be
+# DW_FRAME_CFA_COL3 (1436)
+cfa_reg: 0
+
+# For MIPS, the same as DW_FRAME_SAME_VAL (1035).
+# For other ISA/ABIs 1034 (DW_FRAME_UNDEFINED_VAL) might be better.
+# Depends on the ABI convention, if set wrong way too many
+# regs will be listed in the frame output.
+# This instructs dwarfdump to set libdwarf to this value,
+# overriding the libdwarf default.
+# If initial_reg_value not set the libdwarf default is used
+# (see libdwarf.h DW_FRAME_REG_INITIAL_VALUE).
+initial_reg_value: 1035 # DW_FRAME_SAME_VAL
+same_val_reg: 1035
+undefined_val_reg: 1034
+
+# Built in to frame_interface: 2 as 66.
+reg_table_size: 66
+
+
+# Only name registers for wich a r4 (for example) is not what you
+# want to see
+# No particular order of the reg: lines required.
+reg: cfa 0 # Used with MIPS/IRIX original DWARF2 interface
+reg: r1/at 1
+reg: r2/v0 2
+reg: r3/v1 3
+reg: r4/a0 4
+reg: r5/a1 5
+reg: r6/a2 6
+reg: r7/a3 7
+reg: r8/t0 8
+reg: r9/t1 9
+reg: r10/t2 10
+reg: r11/t3 11
+reg: r12/t4 12
+reg: r13/t5 13
+reg: r14/t6 14
+reg: r15/t7 15
+reg: r16/s0 16
+reg: r17/s1 17
+reg: r18/s2 18
+reg: r19/s3 19
+reg: r20/s4 20
+reg: r21/s5 21
+reg: r22/s6 22
+reg: r23/s7 23
+reg: r24/t8 24
+reg: r25/t9 25
+reg: r26/k0 26
+reg: r27/k1 27
+reg: r28/gp 28
+reg: r29/sp 29
+reg: r30/s8 30
+reg: r31 31
+
+reg: $f0 32
+reg: $f1 33
+reg: $f2 34
+reg: $f3 35
+reg: $f4 36
+reg: $f5 37
+reg: $f6 38
+reg: $f7 39
+reg: $f8 40
+reg: $f9 41
+reg: $f10 42
+reg: $f11 43
+reg: $f12 44
+reg: $f13 45
+reg: $f14 46
+reg: $f15 47
+reg: $f16 48
+reg: $f17 49
+reg: $f18 50
+reg: $f19 51
+reg: $f20 52
+reg: $f21 53
+reg: $f22 54
+reg: $f23 55
+reg: $f24 56
+reg: $f25 57
+reg: $f26 58
+reg: $f27 59
+reg: $f28 60
+reg: $f29 61
+reg: $f30 62
+reg: $f31 63
+reg: ra 64
+reg: slk 65
+
+
+# End of abi definition.
+endabi: mips-irix
+
+
+# Make 'mips' abi be a modern MIPS, not an old IRIX version.
+beginabi: mips
+includeabi: mips-simple3
+endabi: mips
+
+
+# MIPS/IRIX ISA/ABI for testing libdwarf.
+beginabi: mips-irix2
+frame_interface: 2
+reg_table_size: 66
+cfa_reg: 0
+same_val_reg: 1035
+undefined_val_reg: 1034
+initial_reg_value: 1035
+
+reg: cfa 0 # Used with MIPS/IRIX original DWARF2 interface
+reg: ra 64
+reg: slk 65
+
+# End of abi definition.
+endabi: mips-irix2
+
+# MIPS/IRIX ISA/ABI for testing the new frame interface
+# with libdwarf.
+beginabi: mips-simple3
+frame_interface: 3
+
+# When using frame_interface: 3 the size of the register table
+# is not fixed. It can be as large as needed.
+reg_table_size: 66
+cfa_reg: 1436 # DW_FRAME_CFA_COL3
+initial_reg_value: 1035
+same_val_reg: 1035
+undefined_val_reg: 1034
+
+# No cfa as a 'normal' register.
+# Rule 0 is just register 0, which is not used
+# in frame descriptions.
+# (so cfa does not have a number here, and dwarfdump gives
+# it the name 'cfa' automatically).
+reg: ra 64
+reg: slk 65
+# End of abi definition.
+endabi: mips-simple3
+
+
+beginabi: ia64
+frame_interface: 3
+initial_reg_value: 1034 # DW_FRAME_UNDEFINED_VAL
+cfa_reg: 1436 # DW_FRAME_CFA_COL3
+reg_table_size: 695
+same_val_reg: 1035
+undefined_val_reg: 1034
+
+# The following register names are not necessarily correct...
+# Register indexes r32-r127 not used.
+reg: f0 128
+# ...
+reg: f127 255
+reg: b0 321
+reg: b1 322
+reg: b2 323
+reg: b3 324
+reg: b4 325
+reg: b5 326
+reg: b6 327
+reg: b7 328
+reg: vfp 329
+reg: vrap 330
+reg: pr 331
+reg: ip 332
+reg: psr 333
+reg: cfm 334
+reg: k0 335
+reg: k1 336
+reg: k2 337
+reg: k3 338
+reg: k4 339
+reg: k5 340
+reg: k6 341
+reg: k7 342
+reg: rsc 350
+reg: bsp 351
+reg: bspstore 352
+reg: rnat 353
+reg: fcr 355
+reg: eflag 358
+reg: csd 359
+reg: ssd 360
+reg: cflg 361
+reg: fsr 362
+reg: fir 363
+reg: fdr 364
+reg: pfs 398
+reg: lc 399
+reg: ec 400
+
+endabi: ia64
+
+
+beginabi: x86
+frame_interface: 3
+initial_reg_value: 1035 # DW_FRAME_SAME_VAL
+reg_table_size: 66 # more than large enough, hopefully.
+cfa_reg: 1436 # DW_FRAME_CFA_COL3
+same_val_reg: 1035
+undefined_val_reg: 1034
+
+# The following register names are not necessarily correct...
+reg: eax 0
+reg: ecx 1
+reg: edx 2
+reg: ebx 3
+reg: esp 4
+reg: ebp 5
+reg: esi 6
+reg: edi 7
+reg: eip 8
+reg: eflags 9
+
+reg: trapno 10
+reg: st0 11
+reg: st1 12
+reg: st2 13
+reg: st3 14
+reg: st4 15
+reg: st5 16
+reg: st6 17
+reg: st7 18
+# 19 is ? 20 is ?
+reg: xmm0 21
+reg: xmm1 22
+reg: xmm2 23
+reg: xmm3 24
+reg: xmm4 25
+reg: xmm5 26
+reg: xmm6 27
+reg: xmm7 28
+
+reg: mm0 29
+reg: mm1 30
+reg: mm2 31
+reg: mm3 32
+reg: mm4 33
+reg: mm5 34
+reg: mm6 35
+reg: mm7 36
+
+reg: fcw 37
+reg: fsw 38
+reg: mxcsr 39
+
+reg: es 40
+reg: cs 41
+reg: ss 42
+reg: ds 43
+reg: fs 44
+reg: gs 45
+# 46 47 are ?
+reg: tr 48
+reg: ldtr 49
+
+
+endabi: x86
+
+
+beginabi: x86_64
+frame_interface: 3
+initial_reg_value: 1035 # DW_FRAME_SAME_VAL
+reg_table_size: 66 # more than large enough, hopefully.
+cfa_reg: 1436 # DW_FRAME_CFA_COL3
+same_val_reg: 1035
+undefined_val_reg: 1034
+
+# The following register names are not necessarily correct...
+reg: rax 0
+reg: rdx 1
+reg: rcx 2
+reg: rbx 3
+reg: rsi 4
+reg: rdi 5
+reg: rbp 6
+reg: rsp 7
+reg: r8 8
+reg: r9 9
+reg: r10 10
+reg: r11 11
+reg: r12 12
+reg: r13 13
+reg: r14 14
+reg: r15 15
+reg: rip 16
+reg: xmm0 17
+reg: xmm1 18
+reg: xmm2 19
+reg: xmm3 20
+reg: xmm4 21
+reg: xmm5 22
+reg: xmm6 23
+reg: xmm7 24
+reg: xmm8 25
+reg: xmm9 26
+reg: xmm10 27
+reg: xmm11 28
+reg: xmm12 29
+reg: xmm13 30
+reg: xmm14 31
+reg: xmm15 32
+
+reg: st0 33
+reg: st1 34
+reg: st2 35
+reg: st3 36
+reg: st4 37
+reg: st5 38
+reg: st6 39
+reg: st7 40
+
+reg: mm0 41
+reg: mm1 42
+reg: mm2 43
+reg: mm3 44
+reg: mm4 45
+reg: mm5 46
+reg: mm6 47
+reg: mm7 48
+
+reg: rflags 49
+reg: es 50
+reg: cs 51
+reg: ss 52
+reg: ds 53
+reg: fs 54
+reg: gs 55
+# 56, 57 are ?
+reg: fs.base 58
+reg: gs.base 59
+# 60 61 are ?
+reg: tr 62
+reg: ldtr 63
+
+endabi: x86_64
+
+beginabi: m68k
+frame_interface: 3
+initial_reg_value: 1035 # DW_FRAME_SAME_VAL
+reg_table_size: 66 # more than large enough, hopefully.
+cfa_reg: 1436 # DW_FRAME_CFA_COL3
+same_val_reg: 1035
+undefined_val_reg: 1034
+
+reg: d0 0
+reg: d1 1
+reg: d2 2
+reg: d3 3
+reg: d4 4
+reg: d5 5
+reg: d6 6
+reg: d7 7
+
+reg: a0 8
+reg: a1 9
+reg: a2 10
+reg: a3 11
+reg: a4 12
+reg: a5 13
+reg: a6 14
+reg: sp 15
+
+reg: fp0 16
+reg: fp1 17
+reg: fp2 18
+reg: fp3 19
+reg: fp4 20
+reg: fp5 21
+reg: fp6 22
+reg: pc 23
+
+endabi: m68k
+
+# Demonstrates use of address_size and includeabi keywords.
+# address_size is useful when an Elf64 object has DWARF2
+# 32bit (4 byte) address-size frame data (which has no address_size field)
+# and no .debug_info section to provide the 32bit address size.
+beginabi: ppc32bitaddress
+address_size: 4
+includeabi: ppc
+endabi: ppc32bitaddress
+
+beginabi: ppc
+# This abi defined Oct 2008 based on:
+# http://refspecs.linuxfoundation.org/ELF/ppc64/PPC-elf64abi-1.9.html
+frame_interface: 3
+# abi dwarf table uses up thru 1155.
+# As of Oct 2008, the only ABI requiring a higher
+# DW_FRAME_SAME_VAL and DW_FRAME_CFA_COL3.
+initial_reg_value: 1235 # DW_FRAME_SAME_VAL
+cfa_reg: 1436 # DW_FRAME_CFA_COL3
+same_val_reg: 1235
+undefined_val_reg: 1234
+reg_table_size: 1200
+
+reg: r0 0
+reg: f0 32
+reg: f1 33
+reg: f2 34
+reg: f3 35
+reg: f4 36
+reg: f5 37
+reg: f6 38
+reg: f7 39
+reg: f8 40
+reg: f9 41
+reg: f10 42
+reg: f11 43
+reg: f12 44
+reg: f13 45
+reg: f14 46
+reg: f16 47
+reg: f17 48
+reg: f18 49
+reg: f19 50
+reg: f20 51
+reg: f21 52
+reg: f22 53
+reg: f23 54
+reg: f24 55
+reg: f25 56
+reg: f26 57
+reg: f27 58
+reg: f28 59
+reg: f29 60
+reg: f30 62
+reg: f31 63
+reg: cr 64
+reg: fpcsr 65
+# spr0 is also called MQ
+reg: spr0 100
+# spr1 is also called XER
+reg: spr1 101
+# spr4 also called rtcu
+reg: spr4 104
+# spr5 also called rtcl
+reg: spr5 105
+#spr8 also called LR
+reg: spr8 108
+# spr9 also called ctr
+reg: spr9 109
+reg: msr 66
+reg: sr0 70
+reg: sr1 71
+reg: sr2 72
+reg: sr3 73
+reg: sr4 74
+reg: sr5 75
+reg: sr6 76
+reg: sr7 77
+reg: sr8 78
+reg: sr9 79
+
+#dsisr also called spr18
+reg: spr18 118
+# dar also called spr19
+reg: spr19 119
+#dec also called spr22
+reg: spr22 122
+#sdr1 also called spr25
+reg: spr25 125
+#srr0 also called spr26
+reg: spr26 126
+#srr1 also called spr27
+reg: spr27 127
+
+#vrsave also called spr256
+reg: spr256 356
+#sprg0 also called spr272
+reg: spr272 372
+#sprg1 also called spr273
+reg: spr273 373
+#sprg2 also called spr274
+reg: spr274 374
+#sprg3 also called spr275
+reg: spr275 375
+#asr also called spr280
+reg: spr280 380
+#ear also called spr282
+reg: spr282 382
+#tb also called spr284
+reg: spr284 384
+#tbu also called spr285
+reg: spr285 385
+#pvr also called spr287
+reg: spr287 387
+#ibat0u also called spr528
+reg: spr528 628
+#ibat0l also called spr529
+reg: spr529 629
+#ibat1u also called spr530
+reg: spr530 630
+#ibat1l also called spr531
+reg: spr531 631
+#ibat2u also called spr532
+reg: spr532 632
+#ibat2l also called spr533
+reg: spr533 633
+#ibat3u also called spr534
+reg: spr534 634
+#ibat3l also called spr535
+reg: spr535 635
+#dbat0u also called spr536
+reg: spr536 636
+#dbat0l also called spr537
+reg: spr537 637
+#dbat1u also called spr538
+reg: spr538 638
+#dbat1l also called spr539
+reg: spr539 639
+#dbat2u also called spr540
+reg: spr540 640
+#dbat2l also called spr541
+reg: spr541 641
+#dbat3u also called spr542
+reg: spr542 642
+#dbat3l also called spr543
+reg: spr543 643
+
+#hid0 also called spr1008
+reg: spr1008 1108
+#hid1 also called spr1009
+reg: spr1009 1109
+#hid2 also called iabr or spr1010
+reg: spr1010 1110
+#hid5 also called dabr or spr1013
+reg: spr1013 1113
+#hid15 also called pir or spr1023
+reg: spr1023 1123
+
+# vector registers 0-31
+reg: vr0 1124
+reg: vr1 1125
+reg: vr2 1126
+reg: vr3 1127
+reg: vr4 1128
+reg: vr5 1129
+reg: vr6 1130
+reg: vr7 1131
+reg: vr8 1132
+reg: vr9 1133
+reg: vr10 1134
+reg: vr11 1135
+reg: vr12 1136
+reg: vr13 1137
+reg: vr14 1138
+reg: vr15 1130
+reg: vr16 1140
+reg: vr17 1141
+reg: vr18 1142
+reg: vr19 1143
+reg: vr20 1144
+reg: vr21 1145
+reg: vr22 1146
+reg: vr23 1147
+reg: vr24 1148
+reg: vr25 1149
+reg: vr26 1150
+reg: vr27 1151
+reg: vr28 1152
+reg: vr29 1153
+reg: vr30 1154
+reg: vr31 1155
+endabi: ppc
+
+# 'Generic 1000 register abi'.
+# This is useful as a 'general' ABI settings for
+# cpus using up to 1000 registers. The register names
+# show as a number, like 'r991'.
+beginabi: generic
+frame_interface: 3
+initial_reg_value: 1035 # DW_FRAME_SAME_VAL
+cfa_reg: 1436 # DW_FRAME_CFA_COL3
+reg_table_size: 1000
+same_val_reg: 1035
+undefined_val_reg: 1034
+reg: r0 0
+endabi: generic
+
+# 'Generic 500 register abi'.
+# This is useful as a 'general' ABI settings for
+# cpus using up to 500 registers. The register names
+# show as a number, like 'r91'.
+beginabi: generic500
+frame_interface: 3
+initial_reg_value: 1035 # DW_FRAME_SAME_VAL
+cfa_reg: 1436 # DW_FRAME_CFA_COL3
+reg_table_size: 500
+same_val_reg: 1035
+undefined_val_reg: 1034
+reg: r0 0
+endabi: generic500
+
+# 'Generic 100 register abi'.
+# This is useful as a 'general' ABI settings for
+# cpus using up to 100 registers. The register names
+# show as a number, like 'r91'.
+beginabi: generic100
+frame_interface: 3
+initial_reg_value: 1035 # DW_FRAME_SAME_VAL
+cfa_reg: 1436 # DW_FRAME_CFA_COL3
+reg_table_size: 100
+same_val_reg: 1035
+undefined_val_reg: 1034
+reg: r0 0
+endabi: generic100
+
+
+beginabi: arm
+frame_interface: 3
+# When using frame_interface: 3 the size of the register
+# table is not fixed. It can be as large as needed.
+reg_table_size: 288
+cfa_reg: 1436 # DW_FRAME_CFA_COL3
+initial_reg_value: 1034
+same_val_reg: 1035
+undefined_val_reg: 1034
+# If the vendor co-processor registers are allowed
+# or other numbers above 287 used then
+# the reg_table_size must be increased and (possibly)
+# the cfa, same_value, undefined_value reg values changed
+# here.
+# r0-r15 are 0 through 15.
+# Numbers 16 through 63 had meaning
+# in some ARM DWARF register mappings.
+reg: s0 64
+reg: s1 65
+reg: s2 66
+reg: s3 67
+reg: s4 68
+reg: s5 69
+reg: s6 70
+reg: s7 71
+reg: s8 72
+reg: s9 73
+reg: s10 74
+reg: s11 75
+reg: s12 76
+reg: s13 77
+reg: s14 78
+reg: s15 79
+reg: s16 80
+reg: s17 81
+reg: s18 82
+reg: s19 83
+reg: s20 84
+reg: s21 85
+reg: s22 86
+reg: s23 87
+reg: s24 88
+reg: s25 89
+reg: s26 90
+reg: s27 91
+reg: s28 92
+reg: s29 93
+reg: s30 94
+reg: s31 95
+reg: f0 96
+reg: f1 97
+reg: f2 98
+reg: f3 99
+reg: f4 100
+reg: f5 101
+reg: f6 102
+reg: f7 103
+reg: wcgr0 104
+reg: wcgr0 105
+reg: wcgr0 106
+reg: wcgr0 107
+reg: wcgr0 108
+reg: wcgr0 109
+reg: wcgr0 110
+reg: wcgr0 111
+reg: wr0 112
+reg: wr1 113
+reg: wr2 114
+reg: wr3 115
+reg: wr4 116
+reg: wr5 117
+reg: wr6 118
+reg: wr7 119
+reg: wr8 120
+reg: wr9 121
+reg: wr10 122
+reg: wr11 123
+reg: wr12 124
+reg: wr13 125
+reg: wr14 126
+reg: wr15 127
+reg: spsr 128
+reg: spsr_fiq 129
+reg: spsr_irq 130
+reg: spsr_abt 131
+reg: spsr_und 132
+reg: spsr_svc 133
+reg: r8_usr 144
+reg: r9_usr 145
+reg: r10_usr 146
+reg: r11_usr 147
+reg: r12_usr 148
+reg: r13_usr 149
+reg: r14_usr 150
+reg: r8_fiq 151
+reg: r9_fiq 152
+reg: r10_fiq 153
+reg: r11_fiq 154
+reg: r12_fiq 155
+reg: r13_fiq 156
+reg: r14_fiq 157
+reg: r13_riq 158
+reg: r14_riq 159
+reg: r14_abt 160
+reg: r13_abt 161
+reg: r14_und 162
+reg: r13_und 163
+reg: r14_svc 164
+reg: r13_svc 165
+reg: wc0 192
+reg: wc1 193
+reg: wc2 192
+reg: wc3 192
+reg: wc4 192
+reg: wc5 197
+reg: wc6 198
+reg: wc7 199
+reg: d0 256
+reg: d1 257
+reg: d2 258
+reg: d3 259
+reg: d4 260
+reg: d5 261
+reg: d6 262
+reg: d7 263
+reg: d8 264
+reg: d9 265
+reg: d10 266
+reg: d11 267
+reg: d12 268
+reg: d13 269
+reg: d14 270
+reg: d15 271
+reg: d16 272
+reg: d17 273
+reg: d18 274
+reg: d19 275
+reg: d20 266
+reg: d21 277
+reg: d22 278
+reg: d23 279
+reg: d24 280
+reg: d25 281
+reg: d26 282
+reg: d27 283
+reg: d28 284
+reg: d29 285
+reg: d30 286
+reg: d31 287
+# End of abi definition.
+endabi: arm
+
diff --git a/dwarfdump/dwconf.c b/dwarfdump/dwconf.c
new file mode 100644
index 0000000..1b59053
--- /dev/null
+++ b/dwarfdump/dwconf.c
@@ -0,0 +1,1424 @@
+/*
+ Copyright (C) 2006 Silicon Graphics, Inc. All Rights Reserved.
+ Portions Copyright 2011 David Anderson. All Rights Reserved.
+
+ This program is free software; you can redistribute it and/or modify it
+ under the terms of version 2 of the GNU General Public License as
+ published by the Free Software Foundation.
+
+ This program is distributed in the hope that it would be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+ Further, this software is distributed without any warranty that it is
+ free of the rightful claim of any third person regarding infringement
+ or the like. Any license provided herein, whether implied or
+ otherwise, applies only to this software file. Patent licenses, if
+ any, provided herein do not apply to combinations of this program with
+ other software, or any other product whatsoever.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write the Free Software Foundation, Inc., 51
+ Franklin Street - Fifth Floor, Boston MA 02110-1301, USA.
+
+ Contact information: Silicon Graphics, Inc., 1500 Crittenden Lane,
+ Mountain View, CA 94043, or:
+
+ http://www.sgi.com
+
+ For further information regarding this notice, see:
+
+ http://oss.sgi.com/projects/GenInfo/NoticeExplan
+
+
+ $Header: /plroot/cmplrs.src/v7.4.5m/.RCS/PL/dwarfdump/RCS/dwconf.c,v 1.4 2006/04/18 18:05:57 davea Exp $ */
+
+
+/* Windows specific */
+#ifdef HAVE_STDAFX_H
+#include "stdafx.h"
+#endif /* HAVE_STDAFX_H */
+
+#include "globals.h"
+#include "dwarf.h"
+#include "libdwarf.h"
+
+#include <ctype.h>
+#include "dwconf.h"
+#include "makename.h"
+
+extern int verbose;
+
+/* The nesting level is arbitrary, 2 should suffice.
+ But at least this prevents an infinite loop.
+*/
+#define MAX_NEST_LEVEL 3
+
+struct token_s {
+ unsigned tk_len;
+ char *tk_data;
+};
+enum linetype_e {
+ LT_ERROR,
+ LT_COMMENT,
+ LT_BLANK,
+ LT_BEGINABI,
+ LT_REG,
+ LT_FRAME_INTERFACE,
+ LT_CFA_REG,
+ LT_INITIAL_REG_VALUE,
+ LT_SAME_VAL_REG,
+ LT_UNDEFINED_VAL_REG,
+ LT_REG_TABLE_SIZE,
+ LT_ADDRESS_SIZE,
+ LT_INCLUDEABI,
+ LT_ENDABI
+};
+
+struct comtable_s {
+ enum linetype_e type;
+ char *name;
+ size_t namelen;
+};
+
+static int errcount = 0; /* Count errors found in this scan of
+ the configuration file. */
+
+static char name_begin_abi[] = "beginabi:";
+static char name_reg[] = "reg:";
+static char name_frame_interface[] = "frame_interface:";
+static char name_cfa_reg[] = "cfa_reg:";
+static char name_initial_reg_value[] = "initial_reg_value:";
+static char name_same_val_reg[] = "same_val_reg:";
+static char name_undefined_val_reg[] = "undefined_val_reg:";
+static char name_reg_table_size[] = "reg_table_size:";
+static char name_address_size[] = "address_size:";
+static char name_includeabi[] = "includeabi:";
+static char name_endabi[] = "endabi:";
+
+static struct comtable_s comtable[] = {
+ {LT_BEGINABI, name_begin_abi},
+ {LT_REG, name_reg},
+ {LT_FRAME_INTERFACE, name_frame_interface},
+ {LT_CFA_REG, name_cfa_reg},
+ {LT_INITIAL_REG_VALUE, name_initial_reg_value},
+ {LT_SAME_VAL_REG, name_same_val_reg},
+ {LT_UNDEFINED_VAL_REG, name_undefined_val_reg},
+ {LT_REG_TABLE_SIZE, name_reg_table_size},
+ {LT_ADDRESS_SIZE, name_address_size},
+ {LT_INCLUDEABI, name_includeabi},
+ {LT_ENDABI, name_endabi},
+};
+
+struct conf_internal_s {
+ unsigned long beginabi_lineno;
+ unsigned long frame_interface_lineno;
+ unsigned long initial_reg_value_lineno;
+ unsigned long reg_table_size_lineno;
+ unsigned long address_size_lineno;
+ unsigned long same_val_reg_lineno;
+ unsigned long undefined_val_reg_lineno;
+ unsigned long cfa_reg_lineno;
+ unsigned long regcount;
+ struct dwconf_s * conf_out;
+ const char * conf_name_used;
+ char ** conf_defaults;
+};
+static void
+init_conf_internal(struct conf_internal_s *s,
+ struct dwconf_s * conf_out)
+{
+ s->beginabi_lineno = 0;
+ s->frame_interface_lineno = 0;
+ s->initial_reg_value_lineno = 0;
+ s->reg_table_size_lineno = 0;
+ s->address_size_lineno = 0;
+ s->same_val_reg_lineno = 0;
+ s->undefined_val_reg_lineno = 0;
+ s->cfa_reg_lineno = 0;
+ s->cfa_reg_lineno = 0;
+ s->conf_name_used = 0;
+ s->conf_defaults = 0;
+ s->regcount = 0;
+ s->conf_out = conf_out;
+}
+
+static int size_of_comtable = sizeof(comtable) / sizeof(comtable[0]);
+
+static FILE *find_a_file(const char *named_file, char **defaults,
+ const char** name_used);
+static int find_abi_start(FILE * stream, const char *abi_name, long *offset,
+ unsigned long *lineno_out);
+static int parse_abi(FILE * stream, const char *fname, const char *abiname,
+ struct conf_internal_s *out, unsigned long lineno, unsigned nest_level);
+static char *get_token(char *cp, struct token_s *outtok);
+
+/* This finds a dwarfdump.conf file and
+ then parses it. It updates
+ conf_out as appropriate.
+
+ This finds the first file (looking in a set of places)
+ with that name. It then looks for the right ABI entry.
+ If the first file it finds does not have that ABI entry it
+ gives up.
+
+ It would also be reasonable to search every 'dwarfdump.conf'
+ it finds for the abi. But we stop at the first dwarfdump.conf
+ we find.
+ This is the internal call to get the conf data to implement
+ a crude 'includeabi' feature.
+
+ Returns 0 if no errors found, else returns > 0.
+*/
+static int
+find_conf_file_and_read_config_inner(const char *named_file,
+ const char *named_abi,
+ struct conf_internal_s *conf_internal,
+ unsigned nest_level)
+{
+
+ FILE *conf_stream = 0;
+ const char *name_used = 0;
+ long offset = 0;
+ int res = FALSE;
+ unsigned long lineno = 0;
+
+ errcount = 0;
+
+ conf_stream = find_a_file(named_file, conf_internal->conf_defaults,
+ &name_used);
+ if (!conf_stream) {
+ ++errcount;
+ printf("dwarfdump found no file %s!\n",
+ named_file ? named_file : "readable for configuration. "
+ "(add options -v -v to see what file names tried)\n");
+ return errcount;
+ }
+ if (verbose > 1) {
+ printf("dwarfdump using configuration file %s\n", name_used);
+ }
+ conf_internal->conf_name_used = name_used;
+
+ res = find_abi_start(conf_stream, named_abi, &offset, &lineno);
+ if (errcount > 0) {
+ ++errcount;
+ printf("dwarfdump found no ABI %s in file %s.\n",
+ named_abi, name_used);
+ return errcount;
+ }
+ res = fseek(conf_stream, offset, SEEK_SET);
+ if (res != 0) {
+ ++errcount;
+ printf("dwarfdump seek to %ld offset in %s failed!\n",
+ offset, name_used);
+ return errcount;
+ }
+ parse_abi(conf_stream, name_used, named_abi, conf_internal, lineno,
+ nest_level);
+ fclose(conf_stream);
+ return errcount;
+}
+
+/* This is the external-facing call to get the conf data. */
+int
+find_conf_file_and_read_config(const char *named_file,
+ const char *named_abi, char **defaults,
+ struct dwconf_s *conf_out)
+{
+ int res = 0;
+ struct conf_internal_s conf_internal;
+ init_conf_file_data(conf_out);
+ init_conf_internal(&conf_internal,conf_out);
+ conf_internal.conf_defaults = defaults;
+ res = find_conf_file_and_read_config_inner(named_file,
+ named_abi,
+ &conf_internal,0);
+ return res;
+}
+
+/* Given path strings, attempt to make a canonical file name:
+ that is, avoid superfluous '/' so that no
+ '//' (or worse) is created in the output. The path components
+ are to be separated so at least one '/'
+ is to appear between the two 'input strings' when
+ creating the output.
+*/
+static char *
+canonical_append(char *target, unsigned int target_size,
+ const char *first_string, const char *second_string)
+{
+ size_t firstlen = strlen(first_string);
+
+ /* +1 +1: Leave room for added "/" and final NUL, though that is
+ overkill, as we drop a NUL byte too. */
+ if ((firstlen + strlen(second_string) + 1 + 1) >= target_size) {
+ /* Not enough space. */
+ return NULL;
+ }
+ for (; *second_string == '/'; ++second_string) {
+ }
+ for (; firstlen > 0 && first_string[firstlen - 1] == '/';
+ --firstlen) {
+ }
+ target[0] = 0;
+ if (firstlen > 0) {
+ strncpy(target, first_string, firstlen);
+ target[firstlen + 1] = 0;
+ }
+ target[firstlen] = '/';
+ firstlen++;
+ target[firstlen] = 0;
+ strcat(target, second_string);
+ return target;
+}
+
+#ifdef BUILD_FOR_TEST
+#define CANBUF 25
+struct canap_s {
+ char *res_exp;
+ char *first;
+ char *second;
+} canap[] = {
+ {
+ "ab/c", "ab", "c"}, {
+ "ab/c", "ab/", "c"}, {
+ "ab/c", "ab", "/c"}, {
+ "ab/c", "ab////", "/////c"}, {
+ "ab/", "ab", ""}, {
+ "ab/", "ab////", ""}, {
+ "ab/", "ab////", ""}, {
+ "/a", "", "a"}, {
+ 0, "/abcdefgbijkl", "pqrstuvwxyzabcd"}, {
+ 0, 0, 0}
+};
+static void
+test_canonical_append(void)
+{
+ /* Make buf big, this is test code, so be safe. */
+ char lbuf[1000];
+ unsigned i;
+ unsigned failcount = 0;
+
+ printf("Entry test_canonical_append\n");
+ for (i = 0;; ++i) {
+ char *res = 0;
+
+ if (canap[i].first == 0 && canap[i].second == 0)
+ break;
+
+ res = canonical_append(lbuf, CANBUF, canap[i].first,
+ canap[i].second);
+ if (res == 0) {
+ if (canap[i].res_exp == 0) {
+ /* GOOD */
+ printf("PASS %u\n", i);
+ } else {
+ ++failcount;
+ printf("FAIL: entry %u wrong, expected %s, got NULL\n",
+ i, canap[i].res_exp);
+ }
+ } else {
+ if (canap[i].res_exp == 0) {
+ ++failcount;
+ printf("FAIL: entry %u wrong, got %s expected NULL\n",
+ i, res);
+ } else {
+ if (strcmp(res, canap[i].res_exp) == 0) {
+ printf("PASS %u\n", i);
+ /* GOOD */
+ } else {
+ ++failcount;
+ printf("FAIL: entry %u wrong, expected %s got %s\n",
+ i, canap[i].res_exp, res);
+ }
+ }
+ }
+ }
+ printf("FAIL count %u\n", failcount);
+
+}
+#endif /* BUILD_FOR_TEST */
+/* Try to find a file as named and open for read.
+ We treat each name as a full name, we are not
+ combining separate name and path components.
+ This is an arbitrary choice...
+
+ The defaults are listed in dwarfdump.c in the array
+ config_file_defaults[].
+*/
+static FILE *
+find_a_file(const char *named_file, char **defaults, const char ** name_used)
+{
+ FILE *fin = 0;
+ const char *lname = named_file;
+ const char *type = "rw";
+ int i = 0;
+
+#ifdef BUILD_FOR_TEST
+ test_canonical_append();
+#endif /* BUILD_FOR_TEST */
+
+ if (lname) {
+ /* Name given, just assume it is fully correct, try no other. */
+ if (verbose > 1) {
+ printf("dwarfdump looking for configuration as %s\n",
+ lname);
+ }
+ fin = fopen(lname, type);
+ if (fin) {
+ *name_used = lname;
+ return fin;
+ }
+ return 0;
+ }
+ /* No name given, find a default, if we can. */
+ for (i = 0; defaults[i]; ++i) {
+ lname = defaults[i];
+#ifdef WIN32
+ /* Open the configuration file, located
+ in the directory where the tool is loaded from */
+ {
+ static char szPath[MAX_PATH];
+ if (GetModuleFileName(NULL,szPath,MAX_PATH)) {
+ char *pDir = strrchr(szPath,'/');
+ if (!pDir) {
+ pDir = strrchr(szPath,'\\');
+ if (!pDir) {
+ /* No file was found */
+ return 0;
+ }
+ }
+ /* Add the configuration name to the pathname */
+ ++pDir;
+ strcpy(pDir,"dwarfdump.conf");
+ lname = szPath;
+ }
+ }
+#else /* non-Win */
+ if (strncmp(lname, "HOME/", 5) == 0) {
+ /* arbitrary size */
+ char buf[2000];
+ char *homedir = getenv("HOME");
+ if (homedir) {
+ char *cp = canonical_append(buf, sizeof(buf),
+ homedir, lname + 5);
+ if (!cp) {
+ /* OOps, ignore this one. */
+ continue;
+ }
+ lname = makename(buf);
+ }
+ }
+#endif /* WIN32 */
+ if (verbose > 1) {
+ printf("dwarfdump looking for configuration as %s\n",
+ lname);
+ }
+ fin = fopen(lname, type);
+ if (fin) {
+ *name_used = lname;
+ return fin;
+ }
+ }
+ return 0;
+}
+
+/* Start at a token begin, see how long it is,
+ return length. */
+unsigned
+find_token_len(char *cp)
+{
+ unsigned len = 0;
+
+ for (; *cp; ++cp) {
+ if (isspace(*cp)) {
+ return len;
+ }
+ if (*cp == '#') {
+ return len; /* begins comment */
+ }
+ ++len;
+ }
+ return len;
+}
+
+/*
+ Skip past all whitespace: the only code that even knows
+ what whitespace is.
+*/
+static char *
+skipwhite(char *cp)
+{
+ for (; *cp; ++cp) {
+ if (!isspace(*cp)) {
+ return cp;
+ }
+ }
+ return cp;
+}
+
+/* Return TRUE if ok. FALSE if find more tokens.
+ Emit error message if error.
+*/
+static int
+ensure_has_no_more_tokens(char *cp, const char *fname, unsigned long lineno)
+{
+ struct token_s tok;
+
+ cp = get_token(cp, &tok);
+ if (tok.tk_len > 0) {
+ printf("dwarfdump.conf error: "
+ "extra characters after command operands, found "
+ "\"%s\" in %s line %lu\n", tok.tk_data, fname, lineno);
+ ++errcount;
+ return FALSE;
+ }
+ return TRUE;
+}
+
+
+/* There may be many beginabi: lines in a dwarfdump.conf file,
+ find the one we want and return its file offset.
+*/
+static int
+find_abi_start(FILE * stream, const char *abi_name,
+ long *offset, unsigned long *lineno_out)
+{
+ char buf[100];
+ unsigned long lineno = 0;
+
+ for (; !feof(stream);) {
+
+ struct token_s tok;
+ char *line = 0;
+ long loffset = ftell(stream);
+
+ line = fgets(buf, sizeof(buf), stream);
+ ++lineno;
+ if (!line) {
+ ++errcount;
+ return FALSE;
+ }
+
+ line = get_token(buf, &tok);
+
+ if (strcmp(tok.tk_data, name_begin_abi) != 0) {
+ continue;
+ }
+ get_token(line, &tok);
+ if (strcmp(tok.tk_data, abi_name) != 0) {
+ continue;
+ }
+
+ *offset = loffset;
+ *lineno_out = lineno;
+ return TRUE;
+ }
+
+ ++errcount;
+ return FALSE;
+}
+
+static char *tempstr = 0;
+static unsigned tempstr_len = 0;
+
+/* Use a global buffer (tempstr) to turn a non-delimited
+ input char array into a NUL-terminated C string
+ (with the help of makename() to get a permanent
+ address for the result ing string).
+*/
+static char *
+build_string(unsigned tlen, char *cp)
+{
+ if (tlen >= tempstr_len) {
+ free(tempstr);
+ tempstr = malloc(tlen + 100);
+ }
+ strncpy(tempstr, cp, tlen);
+ tempstr[tlen] = 0;
+ return makename(tempstr);
+}
+
+/* The tokenizer for our simple parser.
+*/
+static char *
+get_token(char *cp, struct token_s *outtok)
+{
+ char *lcp = skipwhite(cp);
+ unsigned tlen = find_token_len(lcp);
+
+ outtok->tk_len = tlen;
+ if (tlen > 0) {
+ outtok->tk_data = build_string(tlen, lcp);
+ } else {
+ outtok->tk_data = "";
+ }
+ return lcp + tlen;
+
+}
+
+/*
+ We can't get all the field set up statically very easily,
+ so we get the command string length set here.
+*/
+static void
+finish_comtable_setup(void)
+{
+ unsigned i;
+
+ for (i = 0; i < size_of_comtable; ++i) {
+ comtable[i].namelen = strlen(comtable[i].name);
+ }
+}
+
+/*
+ Given a line of the table, determine if it is a command
+ or not, and if a command, which one is it.
+ Return LT_ERROR if it's not recognized.
+*/
+static enum linetype_e
+which_command(char *cp, struct comtable_s **tableentry)
+{
+ int i;
+ struct token_s tok;
+
+ if (*cp == '#')
+ return LT_COMMENT;
+ if (!*cp)
+ return LT_BLANK;
+
+ get_token(cp, &tok);
+
+ for (i = 0; i < size_of_comtable; ++i) {
+ if (tok.tk_len == comtable[i].namelen &&
+ strcmp(comtable[i].name, tok.tk_data) == 0) {
+
+ *tableentry = &comtable[i];
+ return comtable[i].type;
+ }
+ }
+
+ return LT_ERROR;
+}
+
+/* We are promised it's an abiname: command
+ find the name on the line.
+*/
+static int
+parsebeginabi(char *cp, const char *fname, const char *abiname,
+ unsigned long lineno, struct comtable_s *comtab)
+{
+ size_t clen = comtab->namelen;
+ size_t abinamelen = strlen(abiname);
+ struct token_s tok;
+
+
+ cp = cp + clen + 1;
+ cp = skipwhite(cp);
+ get_token(cp, &tok);
+ if (tok.tk_len != abinamelen ||
+ strncmp(cp, abiname, abinamelen) != 0) {
+ printf("dwarfdump internal error: "
+ "mismatch %s with %s %s line %lu\n",
+ cp, tok.tk_data, fname, lineno);
+ ++errcount;
+ return FALSE;
+ }
+ ensure_has_no_more_tokens(cp + tok.tk_len, fname, lineno);
+ return TRUE;
+}
+
+/* This expands register names as required, but does not
+ ensure no names duplicated.
+*/
+#define CONF_TABLE_OVERSIZE 100
+static void
+add_to_reg_table(struct dwconf_s *conf,
+ char *rname, unsigned long rval, const char *fname,
+ unsigned long lineno)
+{
+ if (conf->cf_regs_malloced == 0) {
+ conf->cf_regs = 0;
+ conf->cf_named_regs_table_size = 0;
+ }
+ if (rval >= conf->cf_named_regs_table_size) {
+ char **newregs = 0;
+ unsigned long newtablen = rval + CONF_TABLE_OVERSIZE;
+ unsigned long newtabsize = newtablen * sizeof(char *);
+ unsigned long oldtabsize =
+ conf->cf_named_regs_table_size * sizeof(char *);
+ newregs = realloc(conf->cf_regs, newtabsize);
+ if (!newregs) {
+ printf("dwarfdump: unable to malloc table %lu bytes. "
+ " %s line %lu\n", newtabsize, fname, lineno);
+ exit(1);
+ }
+ /* Zero out the new entries. */
+ memset((char *) newregs + (oldtabsize), 0,
+ (newtabsize - oldtabsize));
+ conf->cf_named_regs_table_size = (unsigned long) newtablen;
+ conf->cf_regs = newregs;
+ conf->cf_regs_malloced = 1;
+ }
+ conf->cf_regs[rval] = rname;
+ return;
+}
+
+/* Our input is supposed to be a number.
+ Determine the value (and return it) or generate an error message.
+*/
+static int
+make_a_number(char *cmd, const char *filename, unsigned long
+ lineno, struct token_s *tok, unsigned long *val_out)
+{
+ char *endnum = 0;
+ unsigned long val = 0;
+
+ val = strtoul(tok->tk_data, &endnum, 0);
+ if (val == 0 && endnum == (tok->tk_data)) {
+ printf("dwarfdump.conf error: "
+ "%s missing register number (\"%s\" not valid) %s line %lu\n",
+ cmd, tok->tk_data, filename, lineno);
+ ++errcount;
+ return FALSE;
+ }
+ if (endnum != (tok->tk_data + tok->tk_len)) {
+ printf("dwarfdump.conf error: "
+ "%s Missing register number (\"%s\" not valid) %s line %lu\n",
+ cmd, tok->tk_data, filename, lineno);
+ ++errcount;
+ return FALSE;
+ }
+ *val_out = val;
+ return TRUE;
+
+
+
+}
+
+/* We are guaranteed it's a reg: command, so parse that command
+ and record the interesting data.
+*/
+static int
+parsereg(char *cp, const char *fname, unsigned long lineno,
+ struct conf_internal_s *conf, struct comtable_s *comtab)
+{
+ size_t clen = comtab->namelen;
+ struct token_s regnum;
+ struct token_s tokreg;
+ unsigned long val = 0;
+ int ok = FALSE;
+ int res = FALSE;
+
+ cp = cp + clen + 1;
+ cp = get_token(cp, &tokreg);
+ cp = get_token(cp, &regnum);
+ if (tokreg.tk_len == 0) {
+ printf("dwarfdump.conf error: "
+ "reg: missing register name %s line %lu",
+ fname, lineno);
+ ++errcount;
+ return FALSE;
+
+ }
+ if (regnum.tk_len == 0) {
+ printf("dwarfdump.conf error: "
+ "reg: missing register number %s line %lu",
+ fname, lineno);
+ ++errcount;
+ return FALSE;
+ }
+
+ ok = make_a_number(comtab->name, fname, lineno, &regnum, &val);
+
+ if (!ok) {
+ ++errcount;
+ return FALSE;
+ }
+
+ add_to_reg_table(conf->conf_out, tokreg.tk_data, val, fname, lineno);
+
+ res = ensure_has_no_more_tokens(cp, fname, lineno);
+ return res;
+}
+
+/*
+ We are guaranteed it's an frame_interface: command.
+ Parse it and record the value data.
+*/
+static int
+parseframe_interface(char *cp, const char *fname, unsigned long lineno,
+ struct conf_internal_s *conf, struct comtable_s *comtab)
+{
+ size_t clen = comtab->namelen;
+ struct token_s tok;
+ unsigned long val = 0;
+ int ok = FALSE;
+ int res = FALSE;
+
+ cp = cp + clen + 1;
+ cp = get_token(cp, &tok);
+ if (tok.tk_len == 0) {
+ printf("dwarfdump.conf error: "
+ "%s missing interface number %s line %lu",
+ comtab->name, fname, lineno);
+ ++errcount;
+ return FALSE;
+ }
+
+ ok = make_a_number(comtab->name, fname, lineno, &tok, &val);
+
+ if (!ok) {
+ ++errcount;
+ return FALSE;
+ }
+ if (val != 2 && val != 3) {
+ printf("dwarfdump.conf error: "
+ "%s only interface numbers 2 or 3 are allowed, "
+ " not %lu. %s line %lu",
+ comtab->name, val, fname, lineno);
+ ++errcount;
+ return FALSE;
+ }
+
+ conf->conf_out->cf_interface_number = (int) val;
+ res = ensure_has_no_more_tokens(cp, fname, lineno);
+ return res;
+}
+
+/*
+ We are guaranteed it's a cfa_reg: command. Parse it
+ and record the important data.
+*/
+static int
+parsecfa_reg(char *cp, const char *fname, unsigned long lineno,
+ struct conf_internal_s *conf, struct comtable_s *comtab)
+{
+ size_t clen = comtab->namelen;
+ struct token_s tok;
+ unsigned long val = 0;
+ int ok = FALSE;
+ int res = FALSE;
+
+ cp = cp + clen + 1;
+ cp = get_token(cp, &tok);
+ if (tok.tk_len == 0) {
+ printf("dwarfdump.conf error: "
+ "%s missing cfa_reg number %s line %lu",
+ comtab->name, fname, lineno);
+ ++errcount;
+ return FALSE;
+ }
+
+ ok = make_a_number(comtab->name, fname, lineno, &tok, &val);
+
+ if (!ok) {
+ ++errcount;
+ return FALSE;
+ }
+ conf->conf_out->cf_cfa_reg = (int) val;
+ res = ensure_has_no_more_tokens(cp, fname, lineno);
+ return res;
+}
+
+
+/* We are guaranteed it's an initial_reg_value: command,
+ parse it and put the reg value where it will be remembered.
+*/
+static int
+parseinitial_reg_value(char *cp, const char *fname,
+ unsigned long lineno,
+ struct conf_internal_s *conf, struct comtable_s *comtab)
+{
+ size_t clen = comtab->namelen;
+ struct token_s tok;
+ unsigned long val = 0;
+ int ok = FALSE;
+ int res = FALSE;
+
+ cp = cp + clen + 1;
+ cp = get_token(cp, &tok);
+ if (tok.tk_len == 0) {
+ printf("dwarfdump.conf error: "
+ "%s missing initial reg value %s line %lu",
+ comtab->name, fname, lineno);
+ ++errcount;
+ return FALSE;
+ }
+
+ ok = make_a_number(comtab->name, fname, lineno, &tok, &val);
+
+ if (!ok) {
+
+ ++errcount;
+ return FALSE;
+ }
+ conf->conf_out->cf_initial_rule_value = (int) val;
+ res = ensure_has_no_more_tokens(cp, fname, lineno);
+ return res;
+}
+
+static int
+parsesame_val_reg(char *cp, const char *fname,
+ unsigned long lineno,
+ struct conf_internal_s *conf, struct comtable_s *comtab)
+{
+ size_t clen = comtab->namelen;
+ struct token_s tok;
+ unsigned long val = 0;
+ int ok = FALSE;
+ int res = FALSE;
+
+ cp = cp + clen + 1;
+ cp = get_token(cp, &tok);
+ if (tok.tk_len == 0) {
+ printf("dwarfdump.conf error: "
+ "%s missing same_reg value %s line %lu",
+ comtab->name, fname, lineno);
+ ++errcount;
+ return FALSE;
+ }
+
+ ok = make_a_number(comtab->name, fname, lineno, &tok, &val);
+
+ if (!ok) {
+
+ ++errcount;
+ return FALSE;
+ }
+ conf->conf_out->cf_same_val = (int) val;
+ res = ensure_has_no_more_tokens(cp, fname, lineno);
+ return res;
+}
+
+static int
+parseundefined_val_reg(char *cp, const char *fname,
+ unsigned long lineno,
+ struct conf_internal_s *conf, struct comtable_s *comtab)
+{
+ size_t clen = comtab->namelen;
+ struct token_s tok;
+ unsigned long val = 0;
+ int ok = FALSE;
+ int res = FALSE;
+
+ cp = cp + clen + 1;
+ cp = get_token(cp, &tok);
+ if (tok.tk_len == 0) {
+ printf("dwarfdump.conf error: "
+ "%s missing undefined_reg value %s line %lu",
+ comtab->name, fname, lineno);
+ ++errcount;
+ return FALSE;
+ }
+
+ ok = make_a_number(comtab->name, fname, lineno, &tok, &val);
+
+ if (!ok) {
+
+ ++errcount;
+ return FALSE;
+ }
+ conf->conf_out->cf_undefined_val = (int) val;
+ res = ensure_has_no_more_tokens(cp, fname, lineno);
+ return res;
+}
+
+
+
+/* We are guaranteed it's a table size command, parse it
+ and record the table size.
+*/
+static int
+parsereg_table_size(char *cp, const char *fname, unsigned long lineno,
+ struct conf_internal_s *conf, struct comtable_s *comtab)
+{
+ size_t clen = comtab->namelen;
+ struct token_s tok;
+ unsigned long val = 0;
+ int ok = FALSE;
+ int res = FALSE;
+
+ cp = cp + clen + 1;
+ cp = get_token(cp, &tok);
+ if (tok.tk_len == 0) {
+ printf("dwarfdump.conf error: "
+ "%s missing reg table size value %s line %lu",
+ comtab->name, fname, lineno);
+ ++errcount;
+ return FALSE;
+ }
+
+ ok = make_a_number(comtab->name, fname, lineno, &tok, &val);
+
+ if (!ok) {
+ ++errcount;
+ return FALSE;
+ }
+ conf->conf_out->cf_table_entry_count = (unsigned long) val;
+ res = ensure_has_no_more_tokens(cp, fname, lineno);
+ return res;
+}
+
+/* We are guaranteed it's a table size command, parse it
+ and record the table size.
+*/
+static int
+parseaddress_size(char *cp, const char *fname, unsigned long lineno,
+ struct conf_internal_s *conf, struct comtable_s *comtab)
+{
+ size_t clen = comtab->namelen;
+ struct token_s tok;
+ unsigned long val = 0;
+ int ok = FALSE;
+ int res = FALSE;
+
+ cp = cp + clen + 1;
+ cp = get_token(cp, &tok);
+ if (tok.tk_len == 0) {
+ printf("dwarfdump.conf error: "
+ "%s missing address size value %s line %lu",
+ comtab->name, fname, lineno);
+ ++errcount;
+ return FALSE;
+ }
+
+ ok = make_a_number(comtab->name, fname, lineno, &tok, &val);
+
+ if (!ok) {
+ ++errcount;
+ return FALSE;
+ }
+ conf->conf_out->cf_address_size = (unsigned long) val;
+ res = ensure_has_no_more_tokens(cp, fname, lineno);
+ return res;
+}
+
+
+/* We are guaranteed it's an endabi: command, parse it and
+ check we have the right abi.
+*/
+static int
+parseendabi(char *cp, const char *fname,
+ const char *abiname, unsigned long lineno,
+ struct comtable_s *comtab)
+{
+ size_t clen = comtab->namelen;
+ struct token_s tok;
+ int res = 0;
+
+
+ cp = cp + clen + 1;
+ cp = get_token(cp, &tok);
+ if (strcmp(abiname, tok.tk_data) != 0) {
+ printf("%s error: "
+ "mismatch abi name %s (here) vs. %s (beginabi:) %s line %lu\n",
+ comtab->name, tok.tk_data, abiname, fname, lineno);
+ ++errcount;
+ return FALSE;
+ }
+ res = ensure_has_no_more_tokens(cp, fname, lineno);
+ return res;
+}
+static int
+parseincludeabi(char *cp, const char *fname, unsigned long lineno,
+ char **abiname_out,
+ struct comtable_s *comtab)
+{
+ size_t clen = comtab->namelen;
+ struct token_s tok;
+ char *name = 0;
+ int res = FALSE;
+
+ cp = cp + clen + 1;
+ cp = get_token(cp, &tok);
+ name = makename(tok.tk_data);
+
+ *abiname_out = name;
+ res = ensure_has_no_more_tokens(cp, fname, lineno);
+ return res;
+}
+
+
+
+
+/* Return TRUE if we succeeded and filed in *out.
+ Return FALSE if we failed (and fill in nothing).
+ beginabi: <abiname>
+ reg: <regname> <dwarf regnumber>
+ frame_interface: <integer value 2 or 3>
+ cfa_reg: <number>
+ initial_reg_value: <number: normally 1034 or 1035 >
+ reg_table_size: <size of table>
+ endabi: <abiname>
+
+ We are positioned at the start of a beginabi: line when
+ called.
+
+*/
+static int
+parse_abi(FILE * stream, const char *fname, const char *abiname,
+ struct conf_internal_s *conf_internal,
+ unsigned long lineno,
+ unsigned int nest_level)
+{
+ struct dwconf_s *localconf = conf_internal->conf_out;
+ char buf[1000];
+ int comtype = 0;
+
+ static int first_time_done = 0;
+ struct comtable_s *comtabp = 0;
+
+ if( nest_level > MAX_NEST_LEVEL) {
+ ++errcount;
+ printf("dwarfdump.conf: includeabi nest too deep in %s at line %lu\n",
+ fname, lineno);
+ return FALSE;
+ }
+
+
+ if (first_time_done == 0) {
+ finish_comtable_setup();
+ first_time_done = 1;
+ }
+
+ for (; !feof(stream);) {
+ char *line = 0;
+
+ /* long loffset = ftell(stream); */
+ line = fgets(buf, sizeof(buf), stream);
+ if (!line) {
+ ++errcount;
+ printf
+ ("dwarfdump: end of file or error before endabi: in %s, line %lu\n",
+ fname, lineno);
+ return FALSE;
+ }
+ ++lineno;
+ line = skipwhite(line);
+ comtype = which_command(line, &comtabp);
+ switch (comtype) {
+ case LT_ERROR:
+ ++errcount;
+ printf
+ ("dwarfdump: Unknown text in %s is \"%s\" at line %lu\n",
+ fname, line, lineno);
+ break;
+ case LT_COMMENT:
+ break;
+ case LT_BLANK:
+ break;
+ case LT_BEGINABI:
+ if (conf_internal->beginabi_lineno > 0) {
+ ++errcount;
+ printf
+ ("dwarfdump: Encountered beginabi: when not expected. "
+ "%s line %lu previous beginabi line %lu\n", fname,
+ lineno, conf_internal->beginabi_lineno);
+ }
+ conf_internal->beginabi_lineno = lineno;
+ parsebeginabi(line, fname, abiname, lineno, comtabp);
+ break;
+
+ case LT_REG:
+ parsereg(line, fname, lineno, conf_internal, comtabp);
+ conf_internal->regcount++;
+ break;
+ case LT_FRAME_INTERFACE:
+ if (conf_internal->frame_interface_lineno > 0) {
+ ++errcount;
+ printf
+ ("dwarfdump: Encountered duplicate frame_interface: "
+ "%s line %lu previous frame_interface: line %lu\n",
+ fname, lineno, conf_internal->frame_interface_lineno);
+ }
+ conf_internal->frame_interface_lineno = lineno;
+ parseframe_interface(line, fname,
+ lineno, conf_internal, comtabp);
+ break;
+ case LT_CFA_REG:
+ if (conf_internal->cfa_reg_lineno > 0) {
+ printf("dwarfdump: Encountered duplicate cfa_reg: "
+ "%s line %lu previous cfa_reg line %lu\n",
+ fname, lineno, conf_internal->cfa_reg_lineno);
+ ++errcount;
+ }
+ conf_internal->cfa_reg_lineno = lineno;
+ parsecfa_reg(line, fname, lineno, conf_internal, comtabp);
+ break;
+ case LT_INITIAL_REG_VALUE:
+ if (conf_internal->initial_reg_value_lineno > 0) {
+ printf
+ ("dwarfdump: Encountered duplicate initial_reg_value: "
+ "%s line %lu previous initial_reg_value: line %lu\n",
+ fname, lineno, conf_internal->initial_reg_value_lineno);
+ ++errcount;
+ }
+ conf_internal->initial_reg_value_lineno = lineno;
+ parseinitial_reg_value(line, fname,
+ lineno, conf_internal, comtabp);
+ break;
+ case LT_SAME_VAL_REG:
+ if (conf_internal->same_val_reg_lineno > 0) {
+ ++errcount;
+ printf
+ ("dwarfdump: Encountered duplicate same_val_reg: "
+ "%s line %lu previous initial_reg_value: line %lu\n",
+ fname, lineno, conf_internal->initial_reg_value_lineno);
+ }
+ conf_internal->same_val_reg_lineno = lineno;
+ parsesame_val_reg(line, fname,
+ lineno, conf_internal, comtabp);
+ break;
+ case LT_UNDEFINED_VAL_REG:
+ if (conf_internal->undefined_val_reg_lineno > 0) {
+ ++errcount;
+ printf
+ ("dwarfdump: Encountered duplicate undefined_val_reg: "
+ "%s line %lu previous initial_reg_value: line %lu\n",
+ fname, lineno, conf_internal->initial_reg_value_lineno);
+ }
+ conf_internal->undefined_val_reg_lineno = lineno;
+ parseundefined_val_reg(line, fname,
+ lineno, conf_internal, comtabp);
+ break;
+ case LT_REG_TABLE_SIZE:
+ if (conf_internal->reg_table_size_lineno > 0) {
+ printf("dwarfdump: duplicate reg_table_size: "
+ "%s line %lu previous reg_table_size: line %lu\n",
+ fname, lineno, conf_internal->reg_table_size_lineno);
+ ++errcount;
+ }
+ conf_internal->reg_table_size_lineno = lineno;
+ parsereg_table_size(line, fname,
+ lineno, conf_internal, comtabp);
+ break;
+ case LT_ENDABI:
+ parseendabi(line, fname, abiname, lineno, comtabp);
+
+ if (conf_internal->regcount > localconf->cf_table_entry_count) {
+ printf("dwarfdump: more registers named than "
+ " in %s ( %lu named vs %s %lu) %s line %lu\n",
+ abiname, (unsigned long) conf_internal->regcount,
+ name_reg_table_size,
+ (unsigned long) localconf->cf_table_entry_count,
+ fname, (unsigned long) lineno);
+ ++errcount;
+ }
+ return TRUE;
+ case LT_ADDRESS_SIZE:
+ if (conf_internal->address_size_lineno > 0) {
+ printf("dwarfdump: duplicate address_size: "
+ "%s line %lu previous address_size: line %lu\n",
+ fname, lineno, conf_internal->address_size_lineno);
+ ++errcount;
+ }
+ conf_internal->address_size_lineno = lineno;
+ parseaddress_size(line, fname,
+ lineno, conf_internal, comtabp);
+ break;
+ case LT_INCLUDEABI: {
+ char *abiname_inner = 0;
+ unsigned long abilno = conf_internal->beginabi_lineno;
+ int ires = 0;
+ ires = parseincludeabi(line,fname,lineno, &abiname_inner,comtabp);
+ if(ires == FALSE) {
+ return FALSE;
+ }
+ /* For the nested abi read, the abi line number must be
+ set as if not-yet-read, and then restored. */
+ conf_internal->beginabi_lineno = 0;
+ find_conf_file_and_read_config_inner(
+ conf_internal->conf_name_used,
+ abiname_inner, conf_internal,nest_level+1);
+ conf_internal->beginabi_lineno = abilno;
+ }
+ break;
+ default:
+ printf
+ ("dwarfdump internal error, impossible line type %d %s %lu \n",
+ (int) comtype, fname, lineno);
+ exit(1);
+
+ }
+ }
+ ++errcount;
+ printf("End of file, no endabi: found. %s, line %lu\n",
+ fname, lineno);
+ return FALSE;
+}
+
+/* MIPS/IRIX frame register names.
+ For alternate name sets, use dwarfdump.conf or
+ revise dwarf.h and libdwarf.h and this table.
+*/
+static char *regnames[] = {
+ "cfa",
+ "r1/at", "r2/v0", "r3/v1",
+ "r4/a0", "r5/a1", "r6/a2", "r7/a3",
+ "r8/t0", "r9/t1", "r10/t2", "r11/t3",
+ "r12/t4", "r13/t5", "r14/t6", "r15/t7",
+ "r16/s0", "r17/s1", "r18/s2", "r19/s3",
+ "r20/s4", "r21/s5", "r22/s6", "r23/s7",
+ "r24/t8", "r25/t9", "r26/k0", "r27/k1",
+ "r28/gp", "r29/sp", "r30/s8", "r31",
+
+ "$f0", "$f1",
+ "$f2", "$f3",
+ "$f4", "$f5",
+ "$f6", "$f7",
+ "$f8", "$f9",
+ "$f10", "$f11",
+ "$f12", "$f13",
+ "$f14", "$f15",
+ "$f16", "$f17",
+ "$f18", "$f19",
+ "$f20", "$f21",
+ "$f22", "$f23",
+ "$f24", "$f25",
+ "$f26", "$f27",
+ "$f28", "$f29",
+ "$f30", "$f31",
+ "ra", "slk",
+};
+
+
+/* Naming a few registers makes printing these just
+ a little bit faster.
+*/
+static char *genericregnames[] = {
+ "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9",
+ "r10", "r11", "r12", "r13", "r14", "r15", "r16", "r17", "r18", "r19",
+ "r20"
+};
+
+/* This is a simple generic set of registers. The
+ table entry count is pretty arbitrary.
+*/
+void
+init_conf_file_data(struct dwconf_s *config_file_data)
+{
+ unsigned generic_table_count;
+ config_file_data->cf_abi_name = "";
+ config_file_data->cf_config_file_path = "";
+ config_file_data->cf_interface_number = 3;
+ config_file_data->cf_table_entry_count = 100;
+ config_file_data->cf_initial_rule_value = DW_FRAME_UNDEFINED_VAL;
+ config_file_data->cf_cfa_reg = DW_FRAME_CFA_COL3;
+ config_file_data->cf_address_size = 0;
+ config_file_data->cf_same_val = DW_FRAME_SAME_VAL;
+ config_file_data->cf_undefined_val = DW_FRAME_UNDEFINED_VAL;
+ config_file_data->cf_regs = genericregnames;
+ generic_table_count =
+ sizeof(genericregnames) / sizeof(genericregnames[0]);
+ config_file_data->cf_named_regs_table_size = generic_table_count;
+ config_file_data->cf_regs_malloced = 0;
+}
+
+/* These defaults match MIPS/IRIX ABI defaults, but this
+ function is not actually used.
+ For a 'generic' ABI, see -R or init_conf_file_data().
+ To really get the old MIPS, use '-x abi=mips'.
+ For other ABIs, see -x abi=<whatever>
+ to configure dwarfdump (and libdwarf) frame
+ data reporting at runtime.
+*/
+void
+init_mips_conf_file_data(struct dwconf_s *config_file_data)
+{
+ unsigned long base_table_count =
+ sizeof(regnames) / sizeof(regnames[0]);
+
+ memset(config_file_data, 0, sizeof(*config_file_data));
+ /* Interface 2 is deprecated, but for testing purposes
+ is acceptable. */
+ config_file_data->cf_interface_number = 2;
+ config_file_data->cf_table_entry_count = DW_REG_TABLE_SIZE;
+ config_file_data->cf_initial_rule_value =
+ DW_FRAME_REG_INITIAL_VALUE;
+ config_file_data->cf_cfa_reg = DW_FRAME_CFA_COL;
+ config_file_data->cf_address_size = 0;
+ config_file_data->cf_same_val = DW_FRAME_SAME_VAL;
+ config_file_data->cf_undefined_val = DW_FRAME_UNDEFINED_VAL;
+ config_file_data->cf_regs = regnames;
+ config_file_data->cf_named_regs_table_size = base_table_count;
+ config_file_data->cf_regs_malloced = 0;
+ if (config_file_data->cf_table_entry_count != base_table_count) {
+ printf("dwarfdump: improper base table initization, "
+ "header files wrong: "
+ "DW_REG_TABLE_SIZE %u != string table size %lu\n",
+ (unsigned) DW_REG_TABLE_SIZE,
+ (unsigned long) base_table_count);
+ exit(1);
+ }
+ return;
+}
+
+/* A 'generic' ABI. For up to 1200 registers.
+ Perhaps cf_initial_rule_value should be d
+ UNDEFINED VALUE (1034) instead, but for the purposes of
+ getting the dwarfdump output correct
+ either will work.
+*/
+void
+init_generic_config_1200_regs(struct dwconf_s *config_file_data)
+{
+ unsigned long generic_table_count =
+ sizeof(genericregnames) / sizeof(genericregnames[0]);
+ config_file_data->cf_interface_number = 3;
+ config_file_data->cf_table_entry_count = 1200;
+ /* There is no defined name for cf_initial_rule_value,
+ cf_same_val, or cf_undefined_val in libdwarf.h,
+ these must just be high enough to be higher than
+ any real register number.
+ DW_FRAME_CFA_COL3 must also be higher than any
+ real register number. */
+ config_file_data->cf_initial_rule_value = 1235; /* SAME VALUE */
+ config_file_data->cf_cfa_reg = DW_FRAME_CFA_COL3;
+ config_file_data->cf_address_size = 0;
+ config_file_data->cf_same_val = 1235;
+ config_file_data->cf_undefined_val = 1234;
+ config_file_data->cf_regs = genericregnames;
+ config_file_data->cf_named_regs_table_size = generic_table_count;
+ config_file_data->cf_regs_malloced = 0;
+}
+
+/* Print the 'right' string for the register we are given.
+ Deal sensibly with the special regs as well as numbers
+ we know and those we have not been told about.
+
+*/
+void
+print_reg_from_config_data(Dwarf_Signed reg,
+ struct dwconf_s *config_data)
+{
+ char *name = 0;
+
+ if (reg == config_data->cf_cfa_reg) {
+ fputs("cfa",stdout);
+ return;
+ }
+ if (reg == config_data->cf_undefined_val) {
+ fputs("u",stdout);
+ return;
+ }
+ if (reg == config_data->cf_same_val) {
+ fputs("s",stdout);
+ return;
+ }
+
+ if (config_data->cf_regs == 0 ||
+ reg < 0 ||
+ reg >= config_data->cf_named_regs_table_size) {
+ printf("r%" DW_PR_DSd "", (Dwarf_Signed) reg);
+ return;
+ }
+ name = config_data->cf_regs[reg];
+ if (!name) {
+ /* Can happen, the reg names table can be sparse. */
+ printf("r%" DW_PR_DSd "", (Dwarf_Signed) reg);
+ return;
+ }
+ fputs(name,stdout);
+ return;
+}
diff --git a/dwarfdump/dwconf.h b/dwarfdump/dwconf.h
new file mode 100644
index 0000000..471a3d4
--- /dev/null
+++ b/dwarfdump/dwconf.h
@@ -0,0 +1,106 @@
+/*
+ Copyright (C) 2006 Silicon Graphics, Inc. All Rights Reserved.
+ Portions Copyright 2011 David Anderson. All Rights Reserved.
+
+ This program is free software; you can redistribute it and/or modify it
+ under the terms of version 2 of the GNU General Public License as
+ published by the Free Software Foundation.
+
+ This program is distributed in the hope that it would be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+ Further, this software is distributed without any warranty that it is
+ free of the rightful claim of any third person regarding infringement
+ or the like. Any license provided herein, whether implied or
+ otherwise, applies only to this software file. Patent licenses, if
+ any, provided herein do not apply to combinations of this program with
+ other software, or any other product whatsoever.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write the Free Software Foundation, Inc., 51
+ Franklin Street - Fifth Floor, Boston MA 02110-1301, USA.
+
+ Contact information: Silicon Graphics, Inc., 1500 Crittenden Lane,
+ Mountain View, CA 94043, or:
+
+ http://www.sgi.com
+
+ For further information regarding this notice, see:
+
+ http://oss.sgi.com/projects/GenInfo/NoticeExplan
+
+
+ $Header: /plroot/cmplrs.src/v7.4.5m/.RCS/PL/dwarfdump/RCS/dwconf.h,v 1.2 2006/04/18 04:29:39 davea Exp $ */
+
+
+/* declarations helping configure the frame reader. */
+struct dwconf_s {
+ char *cf_config_file_path;
+ char *cf_abi_name;
+
+ /* 2 for old, 3 for frame interface 3. 2 means use the old
+ mips-abi-oriented frame interface. 3 means use the new
+ DWARF3-capable and configureable-abi interface.
+
+ Now, anyone who revises dwarf.h and libdwarf.h to match their
+ abi-of-interest will still be able to use cf_interface_number 2
+ as before. But most folks don't update those header files and
+ instead of making *them* configurable we make dwarfdump (and
+ libdwarf) configurable sufficiently to print frame information
+ sensibly. */
+ int cf_interface_number;
+
+ /* The number of table rules , aka columns. For MIPS/IRIX is 66. */
+ unsigned long cf_table_entry_count;
+
+ /* Array of cf_table_entry_count reg names. Names not filled in
+ from dwarfdump.conf have NULL (0) pointer value.
+ cf_named_regs_table_size must match size of cf_regs array.
+ Set cf_regs_malloced 1 if table was malloced. Set 0
+ if static.
+ */
+ char **cf_regs;
+ unsigned long cf_named_regs_table_size;
+ int cf_regs_malloced;
+
+ /* The 'default initial value' when intializing a table. for MIPS
+ is DW_FRAME_SAME_VAL(1035). For other ISA/ABIs may be
+ DW_FRAME_UNDEFINED_VAL(1034). */
+ int cf_initial_rule_value;
+ int cf_same_val;
+ int cf_undefined_val;
+
+ /* The number of the cfa 'register'. For cf_interface_number 2 of
+ MIPS this is 0. For other architectures (and anytime using
+ cf_interface_number 3) this should be outside the table, a
+ special value such as 1436, not a table column at all). */
+ int cf_cfa_reg;
+
+ /* If non-zero it is the number of bytes in an address
+ for the frame data. Normally it will be zero because
+ there are usually other sources for the correct address size.
+ However, with DWARF2 frame data there is no explicit address
+ size in the frame data and the object file might not have
+ other .debug_ sections to work with.
+ If zero, no address size was supplied, and that is normal and
+ the already-set (or defaulted) address size is to be used.
+ Only an exceptional frame configure will specify address
+ size here. This won't work at all if the object needing
+ this setting has different address size in different CUs. */
+ int cf_address_size;
+};
+
+
+/* Returns DW_DLV_OK if works. DW_DLV_ERROR if cannot do what is asked. */
+int find_conf_file_and_read_config(const char *named_file,
+ const char *named_abi, char **defaults,
+ struct dwconf_s *conf_out);
+void init_conf_file_data(struct dwconf_s *config_file_data);
+void init_mips_conf_file_data(struct dwconf_s *config_file_data);
+
+void print_reg_from_config_data(Dwarf_Signed reg,
+ struct dwconf_s *config_data);
+
+
+void init_generic_config_1200_regs(struct dwconf_s *conf);
diff --git a/dwarfdump/esb.c b/dwarfdump/esb.c
new file mode 100644
index 0000000..8c806c8
--- /dev/null
+++ b/dwarfdump/esb.c
@@ -0,0 +1,242 @@
+/*
+ Copyright (C) 2005 Silicon Graphics, Inc. All Rights Reserved.
+ This program is free software; you can redistribute it and/or modify it
+ under the terms of version 2 of the GNU General Public License as
+ published by the Free Software Foundation.
+
+ This program is distributed in the hope that it would be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+ Further, this software is distributed without any warranty that it is
+ free of the rightful claim of any third person regarding infringement
+ or the like. Any license provided herein, whether implied or
+ otherwise, applies only to this software file. Patent licenses, if
+ any, provided herein do not apply to combinations of this program with
+ other software, or any other product whatsoever.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write the Free Software Foundation, Inc., 51
+ Franklin Street - Fifth Floor, Boston MA 02110-1301, USA.
+
+ Contact information: Silicon Graphics, Inc., 1500 Crittenden Lane,
+ Mountain View, CA 94043, or:
+
+ http://www.sgi.com
+
+ For further information regarding this notice, see:
+
+ http://oss.sgi.com/projects/GenInfo/NoticeExplan
+
+
+$Header: /plroot/cmplrs.src/v7.4.5m/.RCS/PL/dwarfdump/RCS/esb.c,v 1.1 2005/08/04 05:09:37 davea Exp $ */
+
+/* esb.c
+ extensible string buffer.
+
+ A simple means (vaguely like a C++ class) that
+ enables safely saving strings of arbitrary length built up
+ in small pieces.
+
+*/
+
+#include "globals.h"
+#include <stdarg.h> /* For va_start etc. */
+#include "esb.h"
+
+#define INITIAL_ALLOC 1024
+static size_t alloc_size = INITIAL_ALLOC;
+
+
+static void
+init_esb_string(struct esb_s *data, size_t min_len)
+{
+ string d;
+
+ if (data->esb_allocated_size > 0) {
+ return;
+ }
+ if (min_len < alloc_size) {
+ min_len = alloc_size;
+ }
+ d = malloc(min_len);
+ if (!d) {
+ fprintf(stderr,
+ "dwarfdump is out of memory allocating %lu bytes\n",
+ (unsigned long) min_len);
+ exit(5);
+ }
+ data->esb_string = d;
+ data->esb_allocated_size = min_len;
+ data->esb_string[0] = 0;
+ data->esb_used_bytes = 0;
+}
+
+/* Make more room. Leaving contents unchanged, effectively.
+*/
+static void
+allocate_more(struct esb_s *data, size_t len)
+{
+ size_t new_size = data->esb_allocated_size + len;
+ string newd = 0;
+
+ if (new_size < alloc_size)
+ new_size = alloc_size;
+ newd = realloc(data->esb_string, new_size);
+ if (!newd) {
+ fprintf(stderr, "dwarfdump is out of memory re-allocating "
+ "%lu bytes\n", (unsigned long) new_size);
+ exit(5);
+ }
+ data->esb_string = newd;
+ data->esb_allocated_size = new_size;
+}
+
+static void
+esb_appendn_internal(struct esb_s *data, const char * in_string, size_t len);
+
+void
+esb_appendn(struct esb_s *data, const char * in_string, size_t len)
+{
+ size_t full_len = strlen(in_string);
+
+ if (full_len < len) {
+ fprintf(stderr, "dwarfdump internal error, bad string length "
+ " %lu < %lu \n",
+ (unsigned long) full_len, (unsigned long) len);
+ len = full_len;
+ }
+
+ esb_appendn_internal(data, in_string, len);
+}
+
+/* The length is gotten from the in_string itself. */
+void
+esb_append(struct esb_s *data, const char * in_string)
+{
+ size_t len = strlen(in_string);
+
+ esb_appendn_internal(data, in_string, len);
+}
+
+/* The 'len' is believed. Do not pass in strings < len bytes long. */
+static void
+esb_appendn_internal(struct esb_s *data, const char * in_string, size_t len)
+{
+ size_t remaining = 0;
+ size_t needed = len + 1;
+
+ if (data->esb_allocated_size == 0) {
+ size_t maxlen = (len > alloc_size) ? len : alloc_size;
+
+ init_esb_string(data, maxlen);
+ }
+ remaining = data->esb_allocated_size - data->esb_used_bytes;
+ if (remaining < needed) {
+ allocate_more(data, needed);
+ }
+ strncpy(&data->esb_string[data->esb_used_bytes], in_string, len);
+ data->esb_used_bytes += len;
+ /* Insist on explicit NUL terminator */
+ data->esb_string[data->esb_used_bytes] = 0;
+}
+
+/* Always returns an empty string or a non-empty string. Never 0. */
+string
+esb_get_string(struct esb_s *data)
+{
+ if (data->esb_allocated_size == 0) {
+ init_esb_string(data, alloc_size);
+ }
+ return data->esb_string;
+}
+
+
+/* Sets esb_used_bytes to zero. The string is not freed and
+ esb_allocated_size is unchanged. */
+void
+esb_empty_string(struct esb_s *data)
+{
+ if (data->esb_allocated_size == 0) {
+ init_esb_string(data, alloc_size);
+ }
+ data->esb_used_bytes = 0;
+ data->esb_string[0] = 0;
+
+}
+
+
+/* Return esb_used_bytes. */
+size_t
+esb_string_len(struct esb_s *data)
+{
+ return data->esb_used_bytes;
+}
+
+
+/* The following are for testing esb, not use by dwarfdump. */
+
+/* *data is presumed to contain garbage, not values, and
+ is properly initialized. */
+void
+esb_constructor(struct esb_s *data)
+{
+ memset(data, 0, sizeof(*data));
+}
+
+/* The string is freed, contents of *data set to zeroes. */
+void
+esb_destructor(struct esb_s *data)
+{
+ if (data->esb_string) {
+ free(data->esb_string);
+ }
+ esb_constructor(data);
+}
+
+
+/* To get all paths in the code tested, this sets the
+ allocation/reallocation to the given value, which can be quite small
+ but must not be zero. */
+void
+esb_alloc_size(size_t size)
+{
+ alloc_size = size;
+}
+
+size_t
+esb_get_allocated_size(struct esb_s *data)
+{
+ return data->esb_allocated_size;
+}
+
+/* Append a formatted string */
+void
+esb_append_printf(struct esb_s *data,const char *in_string, ...)
+{
+#if WIN32
+ #define NULL_DEVICE_FILE "NUL"
+#else
+ #define NULL_DEVICE_FILE "/dev/null"
+#endif /* WIN32 */
+
+ static FILE *null_file = NULL;
+
+ int needed_size = 0;
+ int length = 0;
+ va_list ap;
+ va_start(ap,in_string);
+ if (null_file == NULL) {
+ null_file = fopen(NULL_DEVICE_FILE,"w");
+ }
+ length = vfprintf(null_file,in_string,ap);
+
+ /* Check if we require allocate more space */
+ needed_size = data->esb_used_bytes + length;
+ if (needed_size > data->esb_allocated_size) {
+ allocate_more(data,length);
+ }
+ vsprintf(&data->esb_string[data->esb_used_bytes],in_string,ap);
+ data->esb_used_bytes += length;
+ va_end(ap);
+}
diff --git a/dwarfdump/esb.h b/dwarfdump/esb.h
new file mode 100644
index 0000000..260db07
--- /dev/null
+++ b/dwarfdump/esb.h
@@ -0,0 +1,86 @@
+/*
+ Copyright (C) 2005 Silicon Graphics, Inc. All Rights Reserved.
+ Portions Copyright 2011 David Anderson. All Rights Reserved.
+ This program is free software; you can redistribute it and/or modify it
+ under the terms of version 2 of the GNU General Public License as
+ published by the Free Software Foundation.
+
+ This program is distributed in the hope that it would be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+ Further, this software is distributed without any warranty that it is
+ free of the rightful claim of any third person regarding infringement
+ or the like. Any license provided herein, whether implied or
+ otherwise, applies only to this software file. Patent licenses, if
+ any, provided herein do not apply to combinations of this program with
+ other software, or any other product whatsoever.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write the Free Software Foundation, Inc., 51
+ Franklin Street - Fifth Floor, Boston MA 02110-1301, USA.
+
+ Contact information: Silicon Graphics, Inc., 1500 Crittenden Lane,
+ Mountain View, CA 94043, or:
+
+ http://www.sgi.com
+
+ For further information regarding this notice, see:
+
+ http://oss.sgi.com/projects/GenInfo/NoticeExplan
+
+
+ $Header: /plroot/cmplrs.src/v7.4.5m/.RCS/PL/dwarfdump/RCS/esb.h,v 1.1 2005/08/04 05:09:37 davea Exp $ */
+
+
+/* esb.h
+ Extensible string buffer.
+ A simple vaguely object oriented extensible string buffer.
+
+ The struct could be opaque here, but it seems ok to expose
+ the contents: simplifies debugging.
+*/
+
+
+struct esb_s {
+ string esb_string; /* pointer to the data itself, or NULL. */
+ size_t esb_allocated_size; /* Size of allocated data or 0 */
+ size_t esb_used_bytes; /* Amount of space used or 0 */
+};
+
+/* string length taken from string itself. */
+void esb_append(struct esb_s *data, const char * in_string);
+
+/* The 'len' is believed. Do not pass in strings < len bytes long. */
+void esb_appendn(struct esb_s *data, const char * in_string, size_t len);
+
+/* Always returns an empty string or a non-empty string. Never 0. */
+string esb_get_string(struct esb_s *data);
+
+
+/* Sets esb_used_bytes to zero. The string is not freed and
+ esb_allocated_size is unchanged. */
+void esb_empty_string(struct esb_s *data);
+
+
+/* Return esb_used_bytes. */
+size_t esb_string_len(struct esb_s *data);
+
+/* The following are for testing esb, not use by dwarfdump. */
+
+/* *data is presumed to contain garbage, not values, and
+ is properly initialized. */
+void esb_constructor(struct esb_s *data);
+
+/* The string is freed, contents of *data set to zeroes. */
+void esb_destructor(struct esb_s *data);
+
+
+/* To get all paths in the code tested, this sets the
+ allocation/reallocation to the given value, which can be quite small
+ but must not be zero. */
+void esb_alloc_size(size_t size);
+size_t esb_get_allocated_size(struct esb_s *data);
+
+/* Append a formatted string */
+void esb_append_printf(struct esb_s *data,const char *in_string, ...);
diff --git a/dwarfdump/globals.h b/dwarfdump/globals.h
new file mode 100644
index 0000000..46cbc11
--- /dev/null
+++ b/dwarfdump/globals.h
@@ -0,0 +1,459 @@
+/*
+ Copyright (C) 2000,2004,2005 Silicon Graphics, Inc. All Rights Reserved.
+ Portions Copyright (C) 2007-2010 David Anderson. All Rights Reserved.
+
+ This program is free software; you can redistribute it and/or modify it
+ under the terms of version 2 of the GNU General Public License as
+ published by the Free Software Foundation.
+
+ This program is distributed in the hope that it would be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+ Further, this software is distributed without any warranty that it is
+ free of the rightful claim of any third person regarding infringement
+ or the like. Any license provided herein, whether implied or
+ otherwise, applies only to this software file. Patent licenses, if
+ any, provided herein do not apply to combinations of this program with
+ other software, or any other product whatsoever.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write the Free Software Foundation, Inc., 51
+ Franklin Street - Fifth Floor, Boston MA 02110-1301, USA.
+
+ Contact information: Silicon Graphics, Inc., 1500 Crittenden Lane,
+ Mountain View, CA 94043, or:
+
+ http://www.sgi.com
+
+ For further information regarding this notice, see:
+
+ http://oss.sgi.com/projects/GenInfo/NoticeExplan
+
+
+
+$Header: /plroot/cmplrs.src/v7.4.5m/.RCS/PL/dwarfdump/RCS/globals.h,v 1.25 2006/04/17 00:09:56 davea Exp $ */
+
+#ifndef globals_INCLUDED
+#define globals_INCLUDED
+
+#include "config.h"
+#if (!defined(HAVE_RAW_LIBELF_OK) && defined(HAVE_LIBELF_OFF64_OK) )
+/* At a certain point libelf.h requires _GNU_SOURCE.
+ here we assume the criteria in configure determine that
+ usefully.
+*/
+#define _GNU_SOURCE 1
+#endif
+
+/* We want __uint32_t and __uint64_t and __int32_t __int64_t
+ properly defined but not duplicated, since duplicate typedefs
+ are not legal C.
+ HAVE___UINT32_T
+ HAVE___UINT64_T will be set by configure if
+ our 4 types are predefined in compiler
+*/
+
+
+#if (!defined(HAVE___UINT32_T)) && defined(HAVE_SGIDEFS_H)
+#include <sgidefs.h> /* sgidefs.h defines them */
+#define HAVE___UINT32_T 1
+#define HAVE___UINT64_T 1
+#endif
+
+
+
+#if (!defined(HAVE___UINT32_T)) && defined(HAVE_SYS_TYPES_H) && defined(HAVE___UINT32_T_IN_SYS_TYPES_H)
+# include <sys/types.h>
+/* we assume __[u]int32_t and __[u]int64_t defined
+ since __uint32_t defined in the sys/types.h in use */
+#define HAVE___UINT32_T 1
+#define HAVE___UINT64_T 1
+#endif
+
+#ifndef HAVE___UINT32_T
+typedef int __int32_t;
+typedef unsigned __uint32_t;
+#define HAVE___UINT32_T 1
+#endif
+#ifndef HAVE___UINT64_T
+typedef long long __int64_t;
+typedef unsigned long long __uint64_t;
+#define HAVE___UINT64_T 1
+#endif
+
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+/* Windows specific */
+#ifdef HAVE_STDAFX_H
+#include "stdafx.h"
+#endif /* HAVE_STDAFX_H */
+
+#ifdef HAVE_ELF_H
+#include <elf.h>
+#endif
+#ifdef HAVE_LIBELF_H
+#include <libelf.h>
+#else
+#ifdef HAVE_LIBELF_LIBELF_H
+#include <libelf/libelf.h>
+#endif
+#endif
+#include <dwarf.h>
+#include <libdwarf.h>
+#ifdef HAVE_REGEX
+#include <regex.h>
+#endif
+typedef char * string;
+
+#include "checkutil.h"
+#ifndef BOOLEAN_TYPEDEFED
+#define BOOLEAN_TYPEDEFED
+typedef int boolean;
+#endif /* BOOLEAN_TYPEDEFED */
+#ifndef FALSE
+#define FALSE 0
+#endif
+#ifndef TRUE
+#define TRUE 1
+#endif
+#ifndef FAILED
+#define FAILED 1
+#endif
+
+/* size of attrib_buffer, defined in print_die.c */
+#define ATTRIB_BUFSIZ 999
+
+typedef struct {
+ int checks;
+ int errors;
+} Dwarf_Check_Result;
+
+extern boolean do_check_dwarf;
+extern boolean do_print_dwarf;
+
+extern boolean record_dwarf_error; /* A test has failed, this
+ is normally set FALSE shortly after being set TRUE, it is
+ a short-range hint we should print something we might not
+ otherwise print (under the circumstances). */
+
+/* Compilation Unit information for improved error messages.
+ If the strings are too short we just truncate so fixed length
+ here is fine. */
+#define COMPILE_UNIT_NAME_LEN 512
+extern char PU_name[COMPILE_UNIT_NAME_LEN]; /* PU Name */
+extern char CU_name[COMPILE_UNIT_NAME_LEN]; /* CU Name */
+extern char CU_producer[COMPILE_UNIT_NAME_LEN]; /* CU Producer Name */
+
+extern boolean seen_PU; /* Detected a PU. */
+extern boolean seen_CU; /* Detected a CU. */
+extern boolean need_CU_name; /* Need CU name. */
+extern boolean need_CU_base_address; /* Need CU Base address. */
+extern boolean need_CU_high_address; /* Need CU High address. */
+extern boolean need_PU_valid_code; /* Need PU valid code. */
+
+extern boolean seen_PU_base_address; /* Detected a Base address for PU */
+extern boolean seen_PU_high_address; /* Detected a High address for PU */
+extern Dwarf_Addr PU_base_address; /* PU Base address */
+extern Dwarf_Addr PU_high_address; /* PU High address */
+
+extern Dwarf_Off DIE_offset; /* DIE offset in compile unit. */
+extern Dwarf_Off DIE_overall_offset; /* DIE offset in .debug_info. */
+
+/* Current CU information for better error reporting. */
+extern Dwarf_Off DIE_CU_offset; /* CU DIE offset in compile unit */
+extern Dwarf_Off DIE_CU_overall_offset; /* CU DIE offset in .debug_info */
+extern int current_section_id; /* Section being process. */
+
+extern Dwarf_Addr CU_base_address; /* CU Base address. */
+extern Dwarf_Addr CU_high_address; /* CU High address. */
+
+extern Dwarf_Addr elf_max_address; /* Largest representable
+ address offset. */
+extern Dwarf_Half elf_address_size; /* Target pointer size. */
+
+/* Ranges and Location tables for better error checking: see
+ dwarfdump.c comments for more information. */
+extern Bucket_Group *pRangesInfo;
+extern Bucket_Group *pLinkonceInfo;
+extern Bucket_Group *pVisitedInfo;
+
+/* Display parent/children when in wide format. */
+extern boolean display_parent_tree;
+extern boolean display_children_tree;
+extern int stop_indent_level;
+
+/* Print search results when in wide format. */
+extern boolean search_wide_format;
+extern boolean search_is_on;
+
+const extern char *search_any_text;
+const extern char *search_match_text;
+const extern char *search_regex_text;
+#ifdef HAVE_REGEX
+extern regex_t search_re;
+#endif
+extern boolean is_strstrnocase(const char *data, const char *pattern);
+
+/* Options to enable debug tracing. */
+#define MAX_TRACE_LEVEL 10
+extern int nTrace[MAX_TRACE_LEVEL + 1];
+
+#define DUMP_RANGES_INFO 1 /* Dump RangesInfo Table. */
+#define DUMP_LOCATION_SECTION_INFO 2 /* Dump Location (.debug_loc) Info. */
+#define DUMP_RANGES_SECTION_INFO 3 /* Dump Ranges (.debug_ranges) Info. */
+#define DUMP_LINKONCE_INFO 4 /* Dump Linkonce Table. */
+#define DUMP_VISITED_INFO 5 /* Dump Visited Info. */
+
+#define dump_ranges_info nTrace[DUMP_RANGES_INFO]
+#define dump_location_section_info nTrace[DUMP_LOCATION_SECTION_INFO]
+#define dump_ranges_section_info nTrace[DUMP_RANGES_SECTION_INFO]
+#define dump_linkonce_info nTrace[DUMP_LINKONCE_INFO]
+#define dump_visited_info nTrace[DUMP_VISITED_INFO]
+
+/* Section IDs */
+#define DEBUG_ABBREV 1
+#define DEBUG_ARANGES 2
+#define DEBUG_FRAME 3
+#define DEBUG_INFO 4
+#define DEBUG_LINE 5
+#define DEBUG_LOC 6
+#define DEBUG_MACINFO 7
+#define DEBUG_PUBNAMES 8
+#define DEBUG_RANGES 9
+#define DEBUG_STATIC_VARS 10
+#define DEBUG_STATIC_FUNC 11
+#define DEBUG_STR 12
+#define DEBUG_WEAKNAMES 13
+#define DEBUG_TYPES 14
+
+extern int verbose;
+extern boolean dense;
+extern boolean ellipsis;
+extern boolean use_mips_regnames;
+extern boolean show_global_offsets;
+extern boolean show_form_used;
+extern boolean display_offsets;
+
+extern boolean check_pubname_attr;
+extern boolean check_attr_tag;
+extern boolean check_tag_tree;
+extern boolean check_type_offset;
+extern boolean check_decl_file;
+extern boolean check_lines;
+extern boolean check_ranges; /* Ranges (aranges & ranges) check */
+extern boolean check_fdes;
+extern boolean check_aranges;
+extern boolean check_harmless;
+extern boolean check_abbreviations;
+extern boolean check_dwarf_constants;
+extern boolean check_di_gaps;
+extern boolean check_forward_decl;
+extern boolean check_self_references;
+extern boolean suppress_nested_name_search;
+extern boolean suppress_check_extensions_tables;
+
+extern int break_after_n_units;
+
+extern boolean check_names; /* Check for invalid names */
+extern boolean check_verbose_mode; /* During '-k' mode, display errors */
+extern boolean check_frames; /* Frames check */
+extern boolean check_frames_extended;/* Extensive frames check */
+extern boolean check_locations; /* Location list check */
+
+/* Check categories corresponding to the -k option */
+typedef enum /* Dwarf_Check_Categories */ {
+ abbrev_code_result,
+ pubname_attr_result,
+ reloc_offset_result,
+ attr_tag_result,
+ tag_tree_result,
+ type_offset_result,
+ decl_file_result,
+ ranges_result,
+ lines_result,
+ aranges_result,
+ /* Harmless errors are errors detected inside libdwarf but
+ not reported via DW_DLE_ERROR returns because the errors
+ won't really affect client code. The 'harmless' errors
+ are reported and otherwise ignored. It is difficult to report
+ the error when the error is noticed by libdwarf, the error
+ is reported at a later time.
+ The other errors dwarfdump reports are also generally harmless
+ but are detected by dwarfdump so it's possble to report the
+ error as soon as the error is discovered. */
+ harmless_result,
+ fde_duplication,
+ frames_result,
+ locations_result,
+ names_result,
+ abbreviations_result,
+ dwarf_constants_result,
+ di_gaps_result,
+ forward_decl_result,
+ self_references_result,
+ total_check_result,
+ LAST_CATEGORY /* Must be last */
+} Dwarf_Check_Categories;
+
+extern boolean info_flag;
+extern boolean line_flag;
+extern boolean use_old_dwarf_loclist;
+extern boolean producer_children_flag; /* List of CUs per compiler */
+
+extern char cu_name[ ];
+extern boolean cu_name_flag;
+extern Dwarf_Unsigned cu_offset;
+extern Dwarf_Off fde_offset_for_cu_low;
+extern Dwarf_Off fde_offset_for_cu_high;
+
+/* Process TAGs for checking mode and reset pRangesInfo table
+ if appropriate. */
+extern void tag_specific_checks_setup(Dwarf_Half val,int die_indent_level);
+
+extern char *program_name;
+extern Dwarf_Error err;
+extern void print_error_and_continue (Dwarf_Debug dbg, string msg,int res, Dwarf_Error err);
+extern void print_error (Dwarf_Debug dbg, string msg,int res, Dwarf_Error err);
+
+extern void print_line_numbers_this_cu (Dwarf_Debug dbg, Dwarf_Die in_die);
+
+struct dwconf_s;
+extern void print_frames (Dwarf_Debug dbg, int print_debug_frame,
+ int print_eh_frame,struct dwconf_s *);
+extern void print_ranges (Dwarf_Debug dbg);
+extern void print_pubnames (Dwarf_Debug dbg);
+extern void print_macinfo (Dwarf_Debug dbg);
+extern void print_infos (Dwarf_Debug dbg,Dwarf_Bool is_info);
+extern void print_locs (Dwarf_Debug dbg);
+extern void print_abbrevs (Dwarf_Debug dbg);
+extern void print_strings (Dwarf_Debug dbg);
+extern void print_aranges (Dwarf_Debug dbg);
+extern void print_relocinfo (Dwarf_Debug dbg,unsigned reloc_map);
+extern void print_static_funcs(Dwarf_Debug dbg);
+extern void print_static_vars(Dwarf_Debug dbg);
+enum type_type_e {SGI_TYPENAME, DWARF_PUBTYPES} ;
+extern void print_types(Dwarf_Debug dbg,enum type_type_e type_type);
+extern void print_weaknames(Dwarf_Debug dbg);
+extern void print_exception_tables(Dwarf_Debug dbg);
+
+struct esb_s;
+extern void print_ranges_list_to_extra(Dwarf_Debug dbg,
+ Dwarf_Unsigned off,
+ Dwarf_Ranges *rangeset,
+ Dwarf_Signed rangecount,
+ Dwarf_Unsigned bytecount,
+ struct esb_s *stringbuf);
+boolean should_skip_this_cu(Dwarf_Debug dbg, Dwarf_Die cu_die, Dwarf_Error err);
+
+/* Returns the DW_AT_name of the CU */
+string old_get_cu_name(Dwarf_Debug dbg,Dwarf_Die cu_die,Dwarf_Error err);
+
+/* Returns the producer of the CU */
+int get_cu_name(Dwarf_Debug dbg,Dwarf_Die cu_die,
+ Dwarf_Error err,char **short_name,char **long_name);
+int get_producer_name(Dwarf_Debug dbg,Dwarf_Die cu_die,
+ Dwarf_Error err,char **producer_name);
+
+/* Get number of abbreviations for a CU */
+extern void get_abbrev_array_info(Dwarf_Debug dbg,Dwarf_Unsigned offset);
+/* Validate an abbreviation */
+extern void validate_abbrev_code(Dwarf_Debug dbg,Dwarf_Unsigned abbrev_code);
+
+extern void print_die_and_children(
+ Dwarf_Debug dbg,
+ Dwarf_Die in_die,
+ Dwarf_Bool is_info,
+ char **srcfiles,
+ Dwarf_Signed cnt);
+extern boolean print_one_die(
+ Dwarf_Debug dbg,
+ Dwarf_Die die,
+ boolean print_information,
+ int die_indent_level,
+ char **srcfiles,
+ Dwarf_Signed cnt,
+ boolean ignore_die_stack);
+
+/* Check for specific compiler */
+extern boolean checking_this_compiler();
+extern void update_compiler_target(const char *producer_name);
+extern void add_cu_name_compiler_target(char *name);
+
+/* General error reporting routines. These were
+ macros for a short time and when changed into functions
+ they kept (for now) their capitalization.
+ The capitalization will likely change. */
+extern void PRINT_CU_INFO();
+extern void DWARF_CHECK_COUNT(Dwarf_Check_Categories category, int inc);
+extern void DWARF_ERROR_COUNT(Dwarf_Check_Categories category, int inc);
+extern void DWARF_CHECK_ERROR_PRINT_CU();
+extern void DWARF_CHECK_ERROR(Dwarf_Check_Categories category,
+ const char *str);
+extern void DWARF_CHECK_ERROR2(Dwarf_Check_Categories category,
+ const char *str1, const char *str2);
+extern void DWARF_CHECK_ERROR3(Dwarf_Check_Categories category,
+ const char *str1, const char *str2, const char *strexpl);
+
+struct esb_s;
+
+extern Dwarf_Die current_cu_die_for_print_frames; /* This is
+ an awful hack, making current_cu_die_for_print_frames public.
+ But it enables cleaning up (doing all dealloc needed). */
+
+extern void printreg(Dwarf_Signed reg,struct dwconf_s *config_data);
+extern void print_frame_inst_bytes(Dwarf_Debug dbg,
+ Dwarf_Ptr cie_init_inst, Dwarf_Signed len,
+ Dwarf_Signed data_alignment_factor,
+ int code_alignment_factor, Dwarf_Half addr_size,
+ struct dwconf_s *config_data);
+
+int
+get_proc_name(Dwarf_Debug dbg, Dwarf_Die die, Dwarf_Addr low_pc,
+ char *proc_name_buf, int proc_name_buf_len, void **pcMap);
+
+void get_attr_value(Dwarf_Debug dbg, Dwarf_Half tag,
+ Dwarf_Die die,
+ Dwarf_Attribute attrib,
+ char **srcfiles,
+ Dwarf_Signed cnt, struct esb_s *esbp,
+ int show_form,int local_verbose);
+
+
+extern Dwarf_Unsigned local_dwarf_decode_u_leb128(unsigned char *leb128,
+ unsigned int *leb128_length);
+
+extern Dwarf_Signed local_dwarf_decode_s_leb128(unsigned char *leb128,
+ unsigned int *leb128_length);
+
+extern void dump_block(char *prefix, char *data, Dwarf_Signed len);
+
+extern void format_sig8_string(Dwarf_Sig8 *data,struct esb_s *out);
+
+int
+dwarfdump_print_one_locdesc(Dwarf_Debug dbg,
+ Dwarf_Locdesc * llbuf,
+ int skip_locdesc_header,
+ struct esb_s *string_out);
+void clean_up_die_esb();
+void clean_up_syms_malloc_data();
+void safe_strcpy(char *out, long outlen, const char *in, long inlen);
+
+
+void print_any_harmless_errors(Dwarf_Debug dbg);
+
+/* Definitions for printing relocations. */
+#define DW_SECTION_REL_DEBUG_INFO 0
+#define DW_SECTION_REL_DEBUG_LINE 1
+#define DW_SECTION_REL_DEBUG_PUBNAMES 2
+#define DW_SECTION_REL_DEBUG_ABBREV 3
+#define DW_SECTION_REL_DEBUG_ARANGES 4
+#define DW_SECTION_REL_DEBUG_FRAME 5
+#define DW_SECTION_REL_DEBUG_LOC 6
+#define DW_SECTION_REL_DEBUG_RANGES 7
+#define DW_SECTION_REL_DEBUG_TYPES 8
+
+#endif /* globals_INCLUDED */
diff --git a/dwarfdump/install.sh b/dwarfdump/install.sh
new file mode 100755
index 0000000..0ff4b6a
--- /dev/null
+++ b/dwarfdump/install.sh
@@ -0,0 +1,119 @@
+#!/bin/sh
+
+#
+# install - install a program, script, or datafile
+# This comes from X11R5; it is not part of GNU.
+#
+# $XConsortium: install.sh,v 1.2 89/12/18 14:47:22 jim Exp $
+#
+# This script is compatible with the BSD install script, but was written
+# from scratch.
+#
+
+
+# set DOITPROG to echo to test this script
+
+# Don't use :- since 4.3BSD and earlier shells don't like it.
+doit="${DOITPROG-}"
+
+
+# put in absolute paths if you don't have them in your path; or use env. vars.
+
+mvprog="${MVPROG-mv}"
+cpprog="${CPPROG-cp}"
+chmodprog="${CHMODPROG-chmod}"
+chownprog="${CHOWNPROG-chown}"
+chgrpprog="${CHGRPPROG-chgrp}"
+stripprog="${STRIPPROG-strip}"
+rmprog="${RMPROG-rm}"
+
+instcmd="$mvprog"
+chmodcmd=""
+chowncmd=""
+chgrpcmd=""
+stripcmd=""
+rmcmd="$rmprog -f"
+mvcmd="$mvprog"
+src=""
+dst=""
+
+while [ x"$1" != x ]; do
+ case $1 in
+ -c) instcmd="$cpprog"
+ shift
+ continue;;
+
+ -m) chmodcmd="$chmodprog $2"
+ shift
+ shift
+ continue;;
+
+ -o) chowncmd="$chownprog $2"
+ shift
+ shift
+ continue;;
+
+ -g) chgrpcmd="$chgrpprog $2"
+ shift
+ shift
+ continue;;
+
+ -s) stripcmd="$stripprog"
+ shift
+ continue;;
+
+ *) if [ x"$src" = x ]
+ then
+ src=$1
+ else
+ dst=$1
+ fi
+ shift
+ continue;;
+ esac
+done
+
+if [ x"$src" = x ]
+then
+ echo "install: no input file specified"
+ exit 1
+fi
+
+if [ x"$dst" = x ]
+then
+ echo "install: no destination specified"
+ exit 1
+fi
+
+
+# If destination is a directory, append the input filename; if your system
+# does not like double slashes in filenames, you may need to add some logic
+
+if [ -d $dst ]
+then
+ dst="$dst"/`basename $src`
+fi
+
+# Make a temp file name in the proper directory.
+
+dstdir=`dirname $dst`
+dsttmp=$dstdir/#inst.$$#
+
+# Move or copy the file name to the temp name
+
+$doit $instcmd $src $dsttmp
+
+# and set any options; do chmod last to preserve setuid bits
+
+if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; fi
+if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; fi
+if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; fi
+if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; fi
+
+# Now rename the file to the real destination.
+
+$doit $rmcmd $dst
+$doit $mvcmd $dsttmp $dst
+
+
+exit 0
diff --git a/dwarfdump/makename.c b/dwarfdump/makename.c
new file mode 100644
index 0000000..e97e1d0
--- /dev/null
+++ b/dwarfdump/makename.c
@@ -0,0 +1,68 @@
+
+/*
+ Copyright (C) 2000,2004 Silicon Graphics, Inc. All Rights Reserved.
+
+ This program is free software; you can redistribute it and/or modify it
+ under the terms of version 2 of the GNU General Public License as
+ published by the Free Software Foundation.
+
+ This program is distributed in the hope that it would be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+ Further, this software is distributed without any warranty that it is
+ free of the rightful claim of any third person regarding infringement
+ or the like. Any license provided herein, whether implied or
+ otherwise, applies only to this software file. Patent licenses, if
+ any, provided herein do not apply to combinations of this program with
+ other software, or any other product whatsoever.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write the Free Software Foundation, Inc., 51
+ Franklin Street - Fifth Floor, Boston MA 02110-1301, USA.
+
+ Contact information: Silicon Graphics, Inc., 1500 Crittenden Lane,
+ Mountain View, CA 94043, or:
+
+ http://www.sgi.com
+
+ For further information regarding this notice, see:
+
+ http://oss.sgi.com/projects/GenInfo/NoticeExplan
+
+ makename.c
+ $Revision: 1.4 $
+ $Date: 2005/11/08 21:48:42 $
+
+ This used to be elaborate stuff.
+ Now it is trivial, as duplicating names is
+ unimportant in dwarfdump (in general).
+
+ And in fact, this is only called for attributes and
+ tags etc whose true name is unknown. Not for
+ any normal case.
+
+*/
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include "makename.h"
+
+char *
+makename(const char *s)
+{
+ char *newstr;
+
+ if (!s) {
+ return "";
+ }
+
+ newstr = strdup(s);
+ if (newstr == 0) {
+ fprintf(stderr, "Out of memory mallocing %d bytes\n",
+ (int) strlen(s));
+ exit(1);
+ }
+ return newstr;
+}
diff --git a/dwarfdump/makename.h b/dwarfdump/makename.h
new file mode 100644
index 0000000..da1f798
--- /dev/null
+++ b/dwarfdump/makename.h
@@ -0,0 +1,53 @@
+#ifndef names_h
+#define names_h
+/*
+ Copyright (C) 2000,2004 Silicon Graphics, Inc. All Rights Reserved.
+ Portions Copyright 2011 David Anderson. All Rights Reserved.
+
+ This program is free software; you can redistribute it and/or modify it
+ under the terms of version 2 of the GNU General Public License as
+ published by the Free Software Foundation.
+
+ This program is distributed in the hope that it would be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+ Further, this software is distributed without any warranty that it is
+ free of the rightful claim of any third person regarding infringement
+ or the like. Any license provided herein, whether implied or
+ otherwise, applies only to this software file. Patent licenses, if
+ any, provided herein do not apply to combinations of this program with
+ other software, or any other product whatsoever.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write the Free Software Foundation, Inc., 51
+ Franklin Street - Fifth Floor, Boston MA 02110-1301, USA.
+
+ Contact information: Silicon Graphics, Inc., 1500 Crittenden Lane,
+ Mountain View, CA 94043, or:
+
+ http://www.sgi.com
+
+ For further information regarding this notice, see:
+
+ http://oss.sgi.com/projects/GenInfo/NoticeExplan
+*/
+
+/* makename.h
+ $Revision: 1.3 $
+ $Date: 2004/10/28 22:26:58 $
+
+ This is for putting strings into stable storage.
+
+ Effectively an strdup() wrapper.
+
+ Rarely called.
+
+ It leaks memory, (the memory
+ is never freed) but that seems unimportant since
+ use of this is very rare.
+*/
+
+char * makename(const char *); /* Makes a copy of the string in
+ a malloc area. Can never return 0. */
+#endif
diff --git a/dwarfdump/naming.c b/dwarfdump/naming.c
new file mode 100644
index 0000000..115fd09
--- /dev/null
+++ b/dwarfdump/naming.c
@@ -0,0 +1,261 @@
+/*
+ Copyright (C) 2000-2005 Silicon Graphics, Inc. All Rights Reserved.
+ Portions Copyright (C) 2007-2011 David Anderson. All Rights Reserved.
+ Portions Copyright (C) 2010-2011 SN Systems Ltd. All Rights Reserved.
+
+ This program is free software; you can redistribute it and/or modify it
+ under the terms of version 2 of the GNU General Public License as
+ published by the Free Software Foundation.
+
+ This program is distributed in the hope that it would be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+ Further, this software is distributed without any warranty that it is
+ free of the rightful claim of any third person regarding infringement
+ or the like. Any license provided herein, whether implied or
+ otherwise, applies only to this software file. Patent licenses, if
+ any, provided herein do not apply to combinations of this program with
+ other software, or any other product whatsoever.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write the Free Software Foundation, Inc., 51
+ Franklin Street - Fifth Floor, Boston MA 02110-1301, USA.
+
+ Contact information: Silicon Graphics, Inc., 1500 Crittenden Lane,
+ Mountain View, CA 94043, or:
+
+ http://www.sgi.com
+
+ For further information regarding this notice, see:
+
+ http://oss.sgi.com/projects/GenInfo/NoticeExplan
+
+*/
+
+/* The address of the Free Software Foundation is
+ Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+ SGI has moved from the Crittenden Lane address.
+*/
+
+
+
+/* naming.c */
+#include "globals.h"
+#include "dwarf.h"
+#include "libdwarf.h"
+#include "makename.h"
+
+static const char *
+skipunder(const char *v)
+{
+ const char *cp = v;
+ int undercount = 0;
+ for( ; *cp ; ++cp) {
+ if( *cp == '_') {
+ ++undercount;
+ if(undercount == 2) {
+ return cp+1;
+ }
+ }
+ }
+ return "";
+}
+
+static const char *
+ellipname(int res, int val_in, const char *v,const char *ty,int printonerr)
+{
+#ifndef TRIVIAL_NAMING
+ if (check_dwarf_constants && checking_this_compiler()) {
+ DWARF_CHECK_COUNT(dwarf_constants_result,1);
+ }
+#endif
+ if(res != DW_DLV_OK) {
+ char buf[100];
+ char *n;
+ snprintf(buf,sizeof(buf),"<Unknown %s value 0x%x>",ty,val_in);
+ /* Capture any name error in DWARF constants */
+#ifndef TRIVIAL_NAMING
+ if(printonerr && check_dwarf_constants && checking_this_compiler()) {
+ if (check_verbose_mode) {
+ fprintf(stderr,"%s of %d (0x%x) is unknown to dwarfdump. "
+ "Continuing. \n",ty,val_in,val_in );
+ }
+ DWARF_ERROR_COUNT(dwarf_constants_result,1);
+ DWARF_CHECK_ERROR_PRINT_CU();
+ }
+#else
+ /* This is for the tree-generation, not dwarfdump itself. */
+ if(printonerr) {
+ fprintf(stderr,"%s of %d (0x%x) is unknown to dwarfdump. "
+ "Continuing. \n",ty,val_in,val_in );
+ }
+#endif
+ n = makename(buf);
+ return n;
+ }
+ if(ellipsis) {
+ return skipunder(v);
+ }
+ return v;
+}
+
+const char * get_TAG_name(unsigned int val_in,int printonerr)
+{
+ const char *v = 0;
+ int res = dwarf_get_TAG_name(val_in,&v);
+ return ellipname(res,val_in,v,"TAG",printonerr);
+}
+const char * get_children_name(unsigned int val_in,int printonerr)
+{
+ const char *v = 0;
+ int res = dwarf_get_children_name(val_in,&v);
+ return ellipname(res,val_in,v,"children",printonerr);
+}
+const char * get_FORM_name(unsigned int val_in,int printonerr)
+{
+ const char *v = 0;
+ int res = dwarf_get_FORM_name(val_in,&v);
+ return ellipname(res,val_in,v,"FORM",printonerr);
+}
+const char * get_AT_name(unsigned int val_in,int printonerr)
+{
+ const char *v = 0;
+ int res = dwarf_get_AT_name(val_in,&v);
+ return ellipname(res,val_in,v,"AT",printonerr);
+}
+const char * get_OP_name(unsigned int val_in,int printonerr)
+{
+ const char *v = 0;
+ int res = dwarf_get_OP_name(val_in,&v);
+ return ellipname(res,val_in,v,"OP",printonerr);
+}
+const char * get_ATE_name(unsigned int val_in,int printonerr)
+{
+ const char *v = 0;
+ int res = dwarf_get_ATE_name(val_in,&v);
+ return ellipname(res,val_in,v,"ATE",printonerr);
+}
+const char * get_DS_name(unsigned int val_in,int printonerr)
+{
+ const char *v = 0;
+ int res = dwarf_get_DS_name(val_in,&v);
+ return ellipname(res,val_in,v,"DS",printonerr);
+}
+const char * get_END_name(unsigned int val_in,int printonerr)
+{
+ const char *v = 0;
+ int res = dwarf_get_END_name(val_in,&v);
+ return ellipname(res,val_in,v,"END",printonerr);
+}
+const char * get_ATCF_name(unsigned int val_in,int printonerr)
+{
+ const char *v = 0;
+ int res = dwarf_get_ATCF_name(val_in,&v);
+ return ellipname(res,val_in,v,"ATCF",printonerr);
+}
+const char * get_ACCESS_name(unsigned int val_in,int printonerr)
+{
+ const char *v = 0;
+ int res = dwarf_get_ACCESS_name(val_in,&v);
+ return ellipname(res,val_in,v,"ACCESS",printonerr);
+}
+const char * get_VIS_name(unsigned int val_in,int printonerr)
+{
+ const char *v = 0;
+ int res = dwarf_get_VIS_name(val_in,&v);
+ return ellipname(res,val_in,v,"VIS",printonerr);
+}
+const char * get_VIRTUALITY_name(unsigned int val_in,int printonerr)
+{
+ const char *v = 0;
+ int res = dwarf_get_VIRTUALITY_name(val_in,&v);
+ return ellipname(res,val_in,v,"VIRTUALITY",printonerr);
+}
+const char * get_LANG_name(unsigned int val_in,int printonerr)
+{
+ const char *v = 0;
+ int res = dwarf_get_LANG_name(val_in,&v);
+ return ellipname(res,val_in,v,"LANG",printonerr);
+}
+const char * get_ID_name(unsigned int val_in,int printonerr)
+{
+ const char *v = 0;
+ int res = dwarf_get_ID_name(val_in,&v);
+ return ellipname(res,val_in,v,"ID",printonerr);
+}
+const char * get_CC_name(unsigned int val_in,int printonerr)
+{
+ const char *v = 0;
+ int res = dwarf_get_CC_name(val_in,&v);
+ return ellipname(res,val_in,v,"CC",printonerr);
+}
+const char * get_INL_name(unsigned int val_in,int printonerr)
+{
+ const char *v = 0;
+ int res = dwarf_get_INL_name(val_in,&v);
+ return ellipname(res,val_in,v,"INL",printonerr);
+}
+const char * get_ORD_name(unsigned int val_in,int printonerr)
+{
+ const char *v = 0;
+ int res = dwarf_get_ORD_name(val_in,&v);
+ return ellipname(res,val_in,v,"ORD",printonerr);
+}
+const char * get_DSC_name(unsigned int val_in,int printonerr)
+{
+ const char *v = 0;
+ int res = dwarf_get_DSC_name(val_in,&v);
+ return ellipname(res,val_in,v,"DSC",printonerr);
+}
+const char * get_LNS_name(unsigned int val_in,int printonerr)
+{
+ const char *v = 0;
+ int res = dwarf_get_LNS_name(val_in,&v);
+ return ellipname(res,val_in,v,"LNS",printonerr);
+}
+const char * get_LNE_name(unsigned int val_in,int printonerr)
+{
+ const char *v = 0;
+ int res = dwarf_get_LNE_name(val_in,&v);
+ return ellipname(res,val_in,v,"LNE",printonerr);
+}
+const char * get_MACINFO_name(unsigned int val_in,int printonerr)
+{
+ const char *v = 0;
+ int res = dwarf_get_MACINFO_name(val_in,&v);
+ return ellipname(res,val_in,v,"MACINFO",printonerr);
+}
+const char * get_CFA_name(unsigned int val_in,int printonerr)
+{
+ const char *v = 0;
+ int res = dwarf_get_CFA_name(val_in,&v);
+ return ellipname(res,val_in,v,"CFA",printonerr);
+}
+const char * get_EH_name(unsigned int val_in,int printonerr)
+{
+ const char *v = 0;
+ int res = dwarf_get_EH_name(val_in,&v);
+ return ellipname(res,val_in,v,"EH",printonerr);
+}
+const char * get_FRAME_name(unsigned int val_in,int printonerr)
+{
+ const char *v = 0;
+ int res = dwarf_get_FRAME_name(val_in,&v);
+ return ellipname(res,val_in,v,"FRAME",printonerr);
+}
+const char * get_CHILDREN_name(unsigned int val_in,int printonerr)
+{
+ const char *v = 0;
+ int res = dwarf_get_CHILDREN_name(val_in,&v);
+ return ellipname(res,val_in,v,"CHILDREN",printonerr);
+}
+const char * get_ADDR_name(unsigned int val_in,int printonerr)
+{
+ const char *v = 0;
+ int res = dwarf_get_ADDR_name(val_in,&v);
+ return ellipname(res,val_in,v,"ADDR",printonerr);
+}
+
+
diff --git a/dwarfdump/naming.h b/dwarfdump/naming.h
new file mode 100644
index 0000000..89a1594
--- /dev/null
+++ b/dwarfdump/naming.h
@@ -0,0 +1,73 @@
+
+/*
+ Copyright (C) 2000-2005 Silicon Graphics, Inc. All Rights Reserved.
+ Portions Copyright (C) 2007-2011 David Anderson. All Rights Reserved.
+
+
+ This program is free software; you can redistribute it and/or modify it
+ under the terms of version 2 of the GNU General Public License as
+ published by the Free Software Foundation.
+
+ This program is distributed in the hope that it would be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+ Further, this software is distributed without any warranty that it is
+ free of the rightful claim of any third person regarding infringement
+ or the like. Any license provided herein, whether implied or
+ otherwise, applies only to this software file. Patent licenses, if
+ any, provided herein do not apply to combinations of this program with
+ other software, or any other product whatsoever.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write the Free Software Foundation, Inc., 51
+ Franklin Street - Fifth Floor, Boston MA 02110-1301, USA.
+
+ Contact information: Silicon Graphics, Inc., 1500 Crittenden Lane,
+ Mountain View, CA 94043, or:
+
+ http://www.sgi.com
+
+ For further information regarding this notice, see:
+
+ http://oss.sgi.com/projects/GenInfo/NoticeExplan
+
+*/
+
+/* The address of the Free Software Foundation is
+ Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+ SGI has moved from the Crittenden Lane address.
+*/
+
+
+/* naming.h */
+
+extern const char * get_TAG_name(unsigned int val_in,int printonerr);
+extern const char * get_children_name(unsigned int val_in,int printonerr);
+extern const char * get_FORM_name(unsigned int val_in,int printonerr);
+extern const char * get_AT_name(unsigned int val_in,int printonerr);
+extern const char * get_OP_name(unsigned int val_in,int printonerr);
+extern const char * get_ATE_name(unsigned int val_in,int printonerr);
+extern const char * get_DS_name(unsigned int val_in,int printonerr);
+extern const char * get_END_name(unsigned int val_in,int printonerr);
+extern const char * get_ATCF_name(unsigned int val_in,int printonerr);
+extern const char * get_ACCESS_name(unsigned int val_in,int printonerr);
+extern const char * get_VIS_name(unsigned int val_in,int printonerr);
+extern const char * get_VIRTUALITY_name(unsigned int val_in,int printonerr);
+extern const char * get_LANG_name(unsigned int val_in,int printonerr);
+extern const char * get_ID_name(unsigned int val_in,int printonerr);
+extern const char * get_CC_name(unsigned int val_in,int printonerr);
+extern const char * get_INL_name(unsigned int val_in,int printonerr);
+extern const char * get_ORD_name(unsigned int val_in,int printonerr);
+extern const char * get_DSC_name(unsigned int val_in,int printonerr);
+extern const char * get_LNS_name(unsigned int val_in,int printonerr);
+extern const char * get_LNE_name(unsigned int val_in,int printonerr);
+extern const char * get_MACINFO_name(unsigned int val_in,int printonerr);
+extern const char * get_CFA_name(unsigned int val_in,int printonerr);
+extern const char * get_EH_name(unsigned int val_in,int printonerr);
+extern const char * get_FRAME_name(unsigned int val_in,int printonerr);
+extern const char * get_CHILDREN_name(unsigned int val_in,int printonerr);
+extern const char * get_ADDR_name(unsigned int val_in,int printonerr);
+
+
diff --git a/dwarfdump/print_abbrevs.c b/dwarfdump/print_abbrevs.c
new file mode 100644
index 0000000..76a08f5
--- /dev/null
+++ b/dwarfdump/print_abbrevs.c
@@ -0,0 +1,304 @@
+/*
+ Copyright (C) 2000-2006 Silicon Graphics, Inc. All Rights Reserved.
+ Portions Copyright 2007-2010 Sun Microsystems, Inc. All rights reserved.
+ Portions Copyright 2009-2011 SN Systems Ltd. All rights reserved.
+ Portions Copyright 2008-2011 David Anderson. All rights reserved.
+
+ This program is free software; you can redistribute it and/or modify it
+ under the terms of version 2 of the GNU General Public License as
+ published by the Free Software Foundation.
+
+ This program is distributed in the hope that it would be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+ Further, this software is distributed without any warranty that it is
+ free of the rightful claim of any third person regarding infringement
+ or the like. Any license provided herein, whether implied or
+ otherwise, applies only to this software file. Patent licenses, if
+ any, provided herein do not apply to combinations of this program with
+ other software, or any other product whatsoever.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write the Free Software Foundation, Inc., 51
+ Franklin Street - Fifth Floor, Boston MA 02110-1301, USA.
+
+ Contact information: Silicon Graphics, Inc., 1500 Crittenden Lane,
+ Mountain View, CA 94043, or:
+
+ http://www.sgi.com
+
+ For further information regarding this notice, see:
+
+ http://oss.sgi.com/projects/GenInfo/NoticeExplan
+
+
+
+$Header: /plroot/cmplrs.src/v7.4.5m/.RCS/PL/dwarfdump/RCS/print_sections.c,v 1.69 2006/04/17 00:09:56 davea Exp $ */
+/* The address of the Free Software Foundation is
+ Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+ SGI has moved from the Crittenden Lane address.
+*/
+
+#include "globals.h"
+#include "naming.h"
+#include "dwconf.h"
+#include "esb.h"
+
+#include "print_sections.h"
+
+
+/* The following relevent for one specific Linker. */
+#define SNLINKER_MAX_ATTRIB_COUNT 16
+
+/* Print data in .debug_abbrev
+ This is inherently unsafe as it assumes there
+ are no byte sequences in .debug_abbrev other than
+ legal abbrev sequences. But the Dwarf spec
+ does not promise that. The spec only promises
+ that any bytes at an offset referred to from
+ .debug_info are legal sequences.
+*/
+extern void
+print_abbrevs(Dwarf_Debug dbg)
+{
+ Dwarf_Abbrev ab;
+ Dwarf_Unsigned offset = 0;
+ Dwarf_Unsigned length = 0;
+ Dwarf_Unsigned abbrev_entry_count = 0;
+ /* Maximum defined tag is 0xffff, DW_TAG_hi_user. */
+ Dwarf_Half tag = 0;
+ Dwarf_Half attr = 0;
+ Dwarf_Signed form = 0;
+ Dwarf_Off off = 0;
+ Dwarf_Unsigned i = 0;
+ const char * child_name = 0;
+ Dwarf_Unsigned abbrev_num = 1;
+ Dwarf_Signed child_flag = 0;
+ int abres = 0;
+ int tres = 0;
+ int acres = 0;
+ Dwarf_Unsigned abbrev_code = 0;
+
+ current_section_id = DEBUG_ABBREV;
+
+ if (do_print_dwarf) {
+ printf("\n.debug_abbrev\n");
+ }
+ while ((abres = dwarf_get_abbrev(dbg, offset, &ab,
+ &length, &abbrev_entry_count,
+ &err)) == DW_DLV_OK) {
+
+ if (abbrev_entry_count == 0) {
+ /* Simple innocuous zero : null abbrev entry */
+ if (dense) {
+ printf("<%" DW_PR_DUu "><0x%" DW_PR_XZEROS DW_PR_DUx "><%"
+ DW_PR_DSd "><%s>\n",
+ abbrev_num,
+ offset,
+ (Dwarf_Signed) /* abbrev_code */ 0,
+ "null .debug_abbrev entry");
+ } else {
+ printf("<%5" DW_PR_DUu "><0x%" DW_PR_XZEROS DW_PR_DUx
+ "><code: %3" DW_PR_DSd "> %-20s\n",
+ abbrev_num,
+ offset,
+ (Dwarf_Signed) /* abbrev_code */ 0,
+ "null .debug_abbrev entry");
+ }
+
+ offset += length;
+ ++abbrev_num;
+ dwarf_dealloc(dbg, ab, DW_DLA_ABBREV);
+ continue;
+ }
+ tres = dwarf_get_abbrev_tag(ab, &tag, &err);
+ if (tres != DW_DLV_OK) {
+ dwarf_dealloc(dbg, ab, DW_DLA_ABBREV);
+ print_error(dbg, "dwarf_get_abbrev_tag", tres, err);
+ }
+ tres = dwarf_get_abbrev_code(ab, &abbrev_code, &err);
+ if (tres != DW_DLV_OK) {
+ dwarf_dealloc(dbg, ab, DW_DLA_ABBREV);
+ print_error(dbg, "dwarf_get_abbrev_code", tres, err);
+ }
+ if (dense) {
+ printf("<%" DW_PR_DUu "><0x%" DW_PR_XZEROS DW_PR_DUx
+ "><%" DW_PR_DSd "><%s>",
+ abbrev_num,
+ offset, abbrev_code,
+ get_TAG_name(tag,dwarf_names_print_on_error));
+ }
+ else {
+ printf("<%5" DW_PR_DUu "><0x%" DW_PR_XZEROS DW_PR_DUx "><code: %3"
+ DW_PR_DSd "> %-20s",
+ abbrev_num,
+ offset, abbrev_code,
+ get_TAG_name(tag,dwarf_names_print_on_error));
+ }
+ /* Process specific TAGs specially. */
+ tag_specific_checks_setup(tag,0);
+ ++abbrev_num;
+ acres = dwarf_get_abbrev_children_flag(ab, &child_flag, &err);
+ if (acres == DW_DLV_ERROR) {
+ dwarf_dealloc(dbg, ab, DW_DLA_ABBREV);
+ print_error(dbg, "dwarf_get_abbrev_children_flag", acres,
+ err);
+ }
+ if (acres == DW_DLV_NO_ENTRY) {
+ child_flag = 0;
+ }
+ child_name = get_children_name(child_flag,
+ dwarf_names_print_on_error);
+ if (dense)
+ printf(" %s", child_name);
+ else
+ printf(" %s\n", child_name);
+ /* Abbrev just contains the format of a die, which debug_info
+ then points to with the real data. So here we just print the
+ given format. */
+ for (i = 0; i < abbrev_entry_count; i++) {
+ int aeres = 0;
+
+ aeres =
+ dwarf_get_abbrev_entry(ab, i, &attr, &form, &off, &err);
+ if (aeres == DW_DLV_ERROR) {
+ dwarf_dealloc(dbg, ab, DW_DLA_ABBREV);
+ print_error(dbg, "dwarf_get_abbrev_entry", aeres, err);
+ }
+ if (aeres == DW_DLV_NO_ENTRY) {
+ attr = -1LL;
+ form = -1LL;
+ }
+ if (dense) {
+ printf(" <%ld>%s<%s>", (unsigned long) off,
+ get_AT_name(attr,dwarf_names_print_on_error),
+ get_FORM_name((Dwarf_Half) form,
+ dwarf_names_print_on_error));
+ } else {
+ printf(" <0x%08lx> %-28s%s\n",
+ (unsigned long) off,
+ get_AT_name(attr,
+ dwarf_names_print_on_error),
+ get_FORM_name((Dwarf_Half) form,
+ dwarf_names_print_on_error));
+ }
+ }
+ dwarf_dealloc(dbg, ab, DW_DLA_ABBREV);
+ offset += length;
+ if (dense) {
+ printf("\n");
+ }
+ }
+ if (abres == DW_DLV_ERROR) {
+ print_error(dbg, "dwarf_get_abbrev", abres, err);
+ }
+}
+
+/* Number of abbreviations for current CU */
+static Dwarf_Unsigned CU_abbrev_count = 0;
+
+/* Abbreviations array info for checking abbrev tags.
+ The [zero] entry is not used.
+ We never shrink the array, but it never grows beyond
+ the largest abbreviation count of all the CUs.
+*/
+
+static Dwarf_Signed *abbrev_array = NULL;
+/* Size of the array, the same as the abbrev tag
+ count of the CU with the most of them. */
+static Dwarf_Unsigned abbrev_array_size = 0;
+#define ABBREV_ARRAY_INITIAL_SIZE 64
+
+/* Calculate the number of abbreviations for the
+ current CU and set up a basic abbreviations array info,
+ storing the number of attributes per abbreviation.
+*/
+void
+get_abbrev_array_info(Dwarf_Debug dbg, Dwarf_Unsigned offset_in)
+{
+ Dwarf_Unsigned offset = offset_in;
+ if (check_abbreviations) {
+ Dwarf_Abbrev ab;
+ Dwarf_Unsigned length = 0;
+ Dwarf_Unsigned abbrev_entry_count = 0;
+ Dwarf_Unsigned abbrev_code;
+ int abres = DW_DLV_OK;
+ Dwarf_Error err;
+
+ Dwarf_Bool bMore = TRUE;
+ CU_abbrev_count = 0;
+
+ if (abbrev_array == NULL) {
+ /* Allocate initial abbreviation array info */
+ abbrev_array = (Dwarf_Signed *)
+ calloc(ABBREV_ARRAY_INITIAL_SIZE+1,sizeof(Dwarf_Signed));
+ abbrev_array_size = ABBREV_ARRAY_INITIAL_SIZE;
+ } else {
+ /* Clear out values from previous CU */
+ memset((void *)abbrev_array,0,
+ (abbrev_array_size+1) * sizeof(Dwarf_Signed));
+ }
+
+ while (bMore && (abres = dwarf_get_abbrev(dbg, offset, &ab,
+ &length, &abbrev_entry_count,
+ &err)) == DW_DLV_OK) {
+ dwarf_get_abbrev_code(ab,&abbrev_code,&err);
+ if (abbrev_code == 0) {
+ /* End of abbreviation table for this CU */
+ ++offset; /* Skip abbreviation code */
+ bMore = FALSE;
+ } else {
+ /* Valid abbreviation code */
+ if (abbrev_code > 0) {
+ if (abbrev_code > abbrev_array_size) {
+ /* Resize abbreviation array */
+ abbrev_array_size *= 2;
+ abbrev_array = (Dwarf_Signed *)
+ realloc(abbrev_array,
+ (abbrev_array_size+1) * sizeof(Dwarf_Signed));
+ }
+ abbrev_array[abbrev_code] = abbrev_entry_count;
+ ++CU_abbrev_count;
+ offset += length;
+ } else {
+ /* Invalid abbreviation code */
+ print_error(dbg, "get_abbrev_array_info", abres, err);
+ }
+ }
+ dwarf_dealloc(dbg, ab, DW_DLA_ABBREV);
+ }
+ }
+}
+
+/* Validate an abbreviation for the current CU. */
+void
+validate_abbrev_code(Dwarf_Debug dbg,Dwarf_Unsigned abbrev_code)
+{
+ char buf[128];
+
+ DWARF_CHECK_COUNT(abbreviations_result,1);
+ if (abbrev_code < 0 || (abbrev_code && abbrev_code > CU_abbrev_count)) {
+ snprintf(buf, sizeof(buf),
+ "Abbrev code %" DW_PR_DUu
+ " outside valid range of [0-%" DW_PR_DUu "]",
+ abbrev_code,CU_abbrev_count);
+ DWARF_CHECK_ERROR2(abbreviations_result,buf,
+ "Invalid abbreviation code.");
+ } else {
+ Dwarf_Signed abbrev_entry_count =
+ abbrev_array[abbrev_code];
+ if (abbrev_entry_count < 0 ||
+ abbrev_entry_count > SNLINKER_MAX_ATTRIB_COUNT) {
+ snprintf(buf, sizeof(buf),
+ "Abbrev code %" DW_PR_DUu
+ ", with %" DW_PR_DUu " attributes: "
+ "outside valid range.",
+ abbrev_code,
+ abbrev_entry_count);
+ DWARF_CHECK_ERROR2(abbreviations_result,buf,
+ "Invalid number of attributes.");
+ }
+ }
+}
diff --git a/dwarfdump/print_aranges.c b/dwarfdump/print_aranges.c
new file mode 100644
index 0000000..f3e076c
--- /dev/null
+++ b/dwarfdump/print_aranges.c
@@ -0,0 +1,267 @@
+/*
+ Copyright (C) 2000-2006 Silicon Graphics, Inc. All Rights Reserved.
+ Portions Copyright 2007-2010 Sun Microsystems, Inc. All rights reserved.
+ Portions Copyright 2009-2011 SN Systems Ltd. All rights reserved.
+ Portions Copyright 2008-2011 David Anderson. All rights reserved.
+
+ This program is free software; you can redistribute it and/or modify it
+ under the terms of version 2 of the GNU General Public License as
+ published by the Free Software Foundation.
+
+ This program is distributed in the hope that it would be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+ Further, this software is distributed without any warranty that it is
+ free of the rightful claim of any third person regarding infringement
+ or the like. Any license provided herein, whether implied or
+ otherwise, applies only to this software file. Patent licenses, if
+ any, provided herein do not apply to combinations of this program with
+ other software, or any other product whatsoever.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write the Free Software Foundation, Inc., 51
+ Franklin Street - Fifth Floor, Boston MA 02110-1301, USA.
+
+ Contact information: Silicon Graphics, Inc., 1500 Crittenden Lane,
+ Mountain View, CA 94043, or:
+
+ http://www.sgi.com
+
+ For further information regarding this notice, see:
+
+ http://oss.sgi.com/projects/GenInfo/NoticeExplan
+
+
+
+$Header: /plroot/cmplrs.src/v7.4.5m/.RCS/PL/dwarfdump/RCS/print_sections.c,v 1.69 2006/04/17 00:09:56 davea Exp $ */
+/* The address of the Free Software Foundation is
+ Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+ SGI has moved from the Crittenden Lane address.
+*/
+
+#include "globals.h"
+#include "naming.h"
+#include "dwconf.h"
+#include "esb.h"
+
+#include "print_sections.h"
+
+
+static void
+do_checking(Dwarf_Debug dbg, Dwarf_Arange *arange_buf,Dwarf_Signed i,
+ Dwarf_Off cu_die_offset,Dwarf_Bool first_cu,
+ Dwarf_Off cu_die_offset_prev, Dwarf_Die cu_die )
+{
+ int dres = 0;
+ Dwarf_Off cuhdroff = 0;
+ Dwarf_Off cudieoff3 = 0;
+ dres = dwarf_get_arange_cu_header_offset(
+ arange_buf[i],&cuhdroff,&err);
+ if(dres == DW_DLV_OK) {
+ Dwarf_Off cudieoff2 = 0;
+
+ /* Get the CU offset for easy error reporting */
+ if (first_cu || cu_die_offset != cu_die_offset_prev) {
+ cu_die_offset_prev = cu_die_offset;
+ dres = dwarf_die_offsets(cu_die,&DIE_overall_offset,&DIE_offset,&err);
+ if (dres != DW_DLV_OK) {
+ print_error(dbg, "dwarf_die_offsets", dres, err);
+ }
+ }
+ dres = dwarf_get_cu_die_offset_given_cu_header_offset(
+ dbg,cuhdroff,&cudieoff2,&err);
+ if(dres == DW_DLV_OK) {
+ /* Get the CU offset for easy error reporting */
+ dwarf_die_offsets(cu_die,&DIE_overall_offset,&DIE_offset,&err);
+ DWARF_CHECK_COUNT(aranges_result,1);
+ if(cudieoff2 != cu_die_offset) {
+ printf("Error, cu_die offsets mismatch, 0x%"
+ DW_PR_DUx
+ " != 0x%" DW_PR_DUx " from arange data",
+ cu_die_offset,cudieoff2);
+ DWARF_CHECK_ERROR(aranges_result,
+ " dwarf_get_cu_die_offset_given_cu..."
+ " gets wrong offset");
+ }
+ } else {
+ print_error(dbg, "dwarf_get_cu_die_offset_given...", dres, err);
+ }
+ } else {
+ print_error(dbg, "dwarf_get_arange_cu_header_offset", dres, err);
+ }
+ dres = dwarf_get_cu_die_offset(arange_buf[i],&cudieoff3,
+ &err);
+ if(dres == DW_DLV_OK) {
+ DWARF_CHECK_COUNT(aranges_result,1);
+ if(cudieoff3 != cu_die_offset) {
+ printf(
+ "Error, cu_die offsets (b) mismatch , 0x%"
+ DW_PR_DUx
+ " != 0x%" DW_PR_DUx " from arange data",
+ cu_die_offset,cudieoff3);
+ DWARF_CHECK_ERROR(aranges_result,
+ " dwarf_get_cu_die_offset "
+ " gets wrong offset");
+ }
+ } else {
+ print_error(dbg, "dwarf_get_cu_die_offset failed ",
+ dres,err);
+ }
+}
+
+/* get all the data in .debug_aranges */
+extern void
+print_aranges(Dwarf_Debug dbg)
+{
+ Dwarf_Signed count = 0;
+ Dwarf_Signed i = 0;
+ Dwarf_Arange *arange_buf = NULL;
+ int ares = 0;
+ int aires = 0;
+ Dwarf_Off prev_off = 0; /* Holds previous CU offset */
+ Dwarf_Bool first_cu = TRUE;
+ Dwarf_Off cu_die_offset_prev = 0;
+
+ /* Reset the global state, so we can traverse the debug_info */
+ seen_CU = FALSE;
+ need_CU_name = TRUE;
+ need_CU_base_address = TRUE;
+ need_CU_high_address = TRUE;
+
+ current_section_id = DEBUG_ARANGES;
+ if (do_print_dwarf) {
+ printf("\n.debug_aranges\n");
+ }
+ ares = dwarf_get_aranges(dbg, &arange_buf, &count, &err);
+ if (ares == DW_DLV_ERROR) {
+ print_error(dbg, "dwarf_get_aranges", ares, err);
+ } else if (ares == DW_DLV_NO_ENTRY) {
+ /* no arange is included */
+ } else {
+ for (i = 0; i < count; i++) {
+ Dwarf_Unsigned segment = 0;
+ Dwarf_Unsigned segment_entry_size = 0;
+ Dwarf_Addr start = 0;
+ Dwarf_Unsigned length = 0;
+ Dwarf_Off cu_die_offset = 0;
+ Dwarf_Die cu_die = NULL;
+ aires = dwarf_get_arange_info_b(arange_buf[i],
+ &segment,
+ &segment_entry_size,
+ &start, &length,
+ &cu_die_offset, &err);
+ if (aires != DW_DLV_OK) {
+ print_error(dbg, "dwarf_get_arange_info", aires, err);
+ } else {
+ int dres;
+ char *producer_name = 0;
+
+ /* Get basic locations for error reporting */
+ dres = dwarf_offdie(dbg, cu_die_offset, &cu_die, &err);
+ if (dres != DW_DLV_OK) {
+ print_error(dbg, "dwarf_offdie", dres, err);
+ }
+
+ if (cu_name_flag) {
+ if(should_skip_this_cu(dbg,cu_die,err)) {
+ continue;
+ }
+ }
+ /* Get producer name for this CU and update compiler list */
+ get_producer_name(dbg,cu_die,err,&producer_name);
+ update_compiler_target(producer_name);
+ if (!checking_this_compiler()) {
+ continue;
+ }
+
+ if (check_aranges) {
+ do_checking(dbg,arange_buf,i,cu_die_offset,first_cu,
+ cu_die_offset_prev,cu_die);
+ }
+ /* Get the offset of the cu header itself in the
+ section, but not for end-entries. */
+ if(start || length) {
+ Dwarf_Off off = 0;
+ int cures3 = dwarf_get_arange_cu_header_offset(
+ arange_buf[i], &off, &err);
+ if (cures3 != DW_DLV_OK) {
+ print_error(dbg, "dwarf_get_cu_hdr_offset",
+ cures3, err);
+ }
+
+ /* Print the CU information if different. */
+ if (prev_off != off || first_cu) {
+ first_cu = FALSE;
+ prev_off = off;
+ /* We are faking the indent level. We do not know
+ what level it is, really.
+
+ If do_check_dwarf we do not want to do
+ the die print call as it will do
+ check/print we may not have asked for.
+ And if we did ask for debug_info checks
+ this will do the checks a second time!
+ So only call print_one_die if printing.
+ */
+ if(do_print_dwarf){
+ /* There is no die if its a set-end entry */
+ print_one_die(dbg, cu_die,
+ /* print_information= */ (boolean) TRUE,
+ /* indent_level = */0,
+ /* srcfiles= */ 0,
+ /* cnt= */ 0,
+ /* ignore_die_stack= */TRUE);
+ }
+ /* Reset the state, so we can traverse the debug_info */
+ seen_CU = FALSE;
+ need_CU_name = TRUE;
+ if (do_print_dwarf) {
+ printf("\n");
+ }
+ }
+
+ if (do_print_dwarf) {
+ /* Print current aranges record */
+ if(segment_entry_size) {
+ printf(
+ "\narange starts at seg,off 0x%"
+ DW_PR_XZEROS DW_PR_DUx
+ ",0x%" DW_PR_XZEROS DW_PR_DUx
+ ", ",
+ segment,
+ (Dwarf_Unsigned)start);
+ } else {
+ printf("\narange starts at 0x%"
+ DW_PR_XZEROS DW_PR_DUx ", ",
+ (Dwarf_Unsigned)start);
+ }
+ printf("length of 0x%" DW_PR_XZEROS DW_PR_DUx
+ ", cu_die_offset = 0x%" DW_PR_XZEROS DW_PR_DUx,
+ length,
+ (Dwarf_Unsigned)cu_die_offset);
+
+ }
+ if (verbose && do_print_dwarf) {
+ printf(" cuhdr 0x%" DW_PR_XZEROS DW_PR_DUx "\n",
+ (Dwarf_Unsigned)off);
+ }
+ dwarf_dealloc(dbg, cu_die, DW_DLA_DIE);
+ cu_die = 0;
+ } else {
+ /* Must be a range end. We really do want to print
+ this as there is a real record here, an
+ 'arange end' record. */
+ if (do_print_dwarf) {
+ printf("\narange end");
+ }
+ }/* end start||length test */
+ } /* end aires DW_DLV_OK test */
+
+ /* print associated die too? */
+ dwarf_dealloc(dbg, arange_buf[i], DW_DLA_ARANGE);
+ }
+ dwarf_dealloc(dbg, arange_buf, DW_DLA_LIST);
+ }
+}
diff --git a/dwarfdump/print_die.c b/dwarfdump/print_die.c
new file mode 100644
index 0000000..5951385
--- /dev/null
+++ b/dwarfdump/print_die.c
@@ -0,0 +1,3540 @@
+/*
+
+ Copyright (C) 2000-2006 Silicon Graphics, Inc. All Rights Reserved.
+ Portions Copyright 2007-2010 Sun Microsystems, Inc. All rights reserved.
+ Portions Copyright 2009-2011 SN Systems Ltd. All rights reserved.
+ Portions Copyright 2007-2011 David Anderson. All rights reserved.
+
+ This program is free software; you can redistribute it and/or modify it
+ under the terms of version 2 of the GNU General Public License as
+ published by the Free Software Foundation.
+
+ This program is distributed in the hope that it would be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+ Further, this software is distributed without any warranty that it is
+ free of the rightful claim of any third person regarding infringement
+ or the like. Any license provided herein, whether implied or
+ otherwise, applies only to this software file. Patent licenses, if
+ any, provided herein do not apply to combinations of this program with
+ other software, or any other product whatsoever.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write the Free Software Foundation, Inc., 51
+ Franklin Street - Fifth Floor, Boston MA 02110-1301, USA.
+
+ Contact information: Silicon Graphics, Inc., 1500 Crittenden Lane,
+ Mountain View, CA 94043, or:
+
+ http://www.sgi.com
+
+ For further information regarding this notice, see:
+
+ http://oss.sgi.com/projects/GenInfo/NoticeExplan
+
+
+$ Header: /plroot/cmplrs.src/v7.4.5m/.RCS/PL/dwarfdump/RCS/print_die.c,v 1.51 2006/04/01 16:20:21 davea Exp $ */
+/* The address of the Free Software Foundation is
+ Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+ SGI has moved from the Crittenden Lane address. */
+
+
+#include "globals.h"
+#include "naming.h"
+#include "esb.h" /* For flexible string buffer. */
+#include "makename.h" /* Non-duplicating string table. */
+#include "print_frames.h" /* for get_string_from_locs() . */
+#include "tag_common.h"
+
+/* Traverse a DIE and attributes to check self references */
+static boolean traverse_one_die(Dwarf_Debug dbg, Dwarf_Attribute attrib,
+ Dwarf_Die die, char **srcfiles,
+ Dwarf_Signed cnt, int die_indent_level);
+static boolean traverse_attribute(Dwarf_Debug dbg, Dwarf_Die die,
+ Dwarf_Half attr, Dwarf_Attribute attr_in,
+ boolean print_information,
+ char **srcfiles, Dwarf_Signed cnt,
+ int die_indent_level);
+static void print_die_and_children_internal(Dwarf_Debug dbg,
+ Dwarf_Die in_die_in,
+ Dwarf_Bool is_info,
+ char **srcfiles, Dwarf_Signed cnt);
+static int print_one_die_section(Dwarf_Debug dbg,Dwarf_Bool is_info);
+
+/* Is this a PU has been invalidated by the SN Systems linker? */
+#define IsInvalidCode(low,high) ((low == elf_max_address) || (low == 0 && high == 0))
+
+
+static int get_form_values(Dwarf_Attribute attrib,
+ Dwarf_Half * theform, Dwarf_Half * directform);
+static void show_form_itself(int show_form,int verbose,
+ int theform, int directform, struct esb_s * str_out);
+static void print_exprloc_content(Dwarf_Debug dbg,Dwarf_Die die, Dwarf_Attribute attrib,
+ int showhextoo, struct esb_s *esbp);
+static boolean print_attribute(Dwarf_Debug dbg, Dwarf_Die die,
+ Dwarf_Half attr,
+ Dwarf_Attribute actual_addr,
+ boolean print_information,
+ int die_indent_level, char **srcfiles,
+ Dwarf_Signed cnt);
+static void get_location_list(Dwarf_Debug dbg, Dwarf_Die die,
+ Dwarf_Attribute attr, struct esb_s *esbp);
+static int legal_tag_attr_combination(Dwarf_Half tag, Dwarf_Half attr);
+static int legal_tag_tree_combination(Dwarf_Half parent_tag,
+ Dwarf_Half child_tag);
+static int _dwarf_print_one_expr_op(Dwarf_Debug dbg,Dwarf_Loc* expr,
+ int index, struct esb_s *string_out);
+static int formxdata_print_value(Dwarf_Debug dbg,Dwarf_Attribute attrib,
+ struct esb_s *esbp, Dwarf_Error * err, Dwarf_Bool hex_format);
+
+/* esb_base is static so gets initialized to zeros.
+ It is not thread-safe or
+ safe for multiple open producer instances for
+ but that does not matter here in dwarfdump.
+
+ The memory used by esb_base and esb_extra is never freed.
+*/
+static struct esb_s esb_base;
+static struct esb_s esb_extra;
+
+static int dwarf_names_print_on_error = 1;
+
+static int die_stack_indent_level = 0;
+static boolean local_symbols_already_began = FALSE;
+
+typedef const char *(*encoding_type_func) (unsigned,int doprintingonerr);
+
+Dwarf_Off fde_offset_for_cu_low = DW_DLV_BADOFFSET;
+Dwarf_Off fde_offset_for_cu_high = DW_DLV_BADOFFSET;
+
+/* Indicators to record a pair [low,high], these
+ are used in printing DIEs to accumulate the high
+ and low pc across attributes and to record the pair
+ as soon as both are known. Probably would be better to
+ use variables as arguments to
+ print_attribute(). */
+static Dwarf_Addr lowAddr = 0;
+static Dwarf_Addr highAddr = 0;
+static Dwarf_Bool bSawLow = FALSE;
+static Dwarf_Bool bSawHigh = FALSE;
+
+/* The following too is related to high and low pc
+attributes of a function. It's misnamed, it really means
+'yes, we have high and low pc' if it is TRUE. Defaulting to TRUE
+seems bogus. */
+static Dwarf_Bool in_valid_code = TRUE;
+
+struct operation_descr_s {
+ int op_code;
+ int op_count;
+ const char * op_1type;
+};
+struct operation_descr_s opdesc[]= {
+ {DW_OP_addr,1,"addr" },
+ {DW_OP_deref,0 },
+ {DW_OP_const1u,1,"1u" },
+ {DW_OP_const1s,1,"1s" },
+ {DW_OP_const2u,1,"2u" },
+ {DW_OP_const2s,1,"2s" },
+ {DW_OP_const4u,1,"4u" },
+ {DW_OP_const4s,1,"4s" },
+ {DW_OP_const8u,1,"8u" },
+ {DW_OP_const8s,1,"8s" },
+ {DW_OP_constu,1,"uleb" },
+ {DW_OP_consts,1,"sleb" },
+ {DW_OP_dup,0,""},
+ {DW_OP_drop,0,""},
+ {DW_OP_over,0,""},
+ {DW_OP_pick,1,"1u"},
+ {DW_OP_swap,0,""},
+ {DW_OP_rot,0,""},
+ {DW_OP_xderef,0,""},
+ {DW_OP_abs,0,""},
+ {DW_OP_and,0,""},
+ {DW_OP_div,0,""},
+ {DW_OP_minus,0,""},
+ {DW_OP_mod,0,""},
+ {DW_OP_mul,0,""},
+ {DW_OP_neg,0,""},
+ {DW_OP_not,0,""},
+ {DW_OP_or,0,""},
+ {DW_OP_plus,0,""},
+ {DW_OP_plus_uconst,1,"uleb"},
+ {DW_OP_shl,0,""},
+ {DW_OP_shr,0,""},
+ {DW_OP_shra,0,""},
+ {DW_OP_xor,0,""},
+ {DW_OP_skip,1,"2s"},
+ {DW_OP_bra,1,"2s"},
+ {DW_OP_eq,0,""},
+ {DW_OP_ge,0,""},
+ {DW_OP_gt,0,""},
+ {DW_OP_le,0,""},
+ {DW_OP_lt,0,""},
+ {DW_OP_ne,0,""},
+ /* lit0 thru reg31 handled specially, no operands */
+ /* breg0 thru breg31 handled specially, 1 operand */
+ {DW_OP_regx,1,"uleb"},
+ {DW_OP_fbreg,1,"sleb"},
+ {DW_OP_bregx,2,"uleb"},
+ {DW_OP_piece,1,"uleb"},
+ {DW_OP_deref_size,1,"1u"},
+ {DW_OP_xderef_size,1,"1u"},
+ {DW_OP_nop,0,""},
+ {DW_OP_push_object_address,0,""},
+ {DW_OP_call2,1,"2u"},
+ {DW_OP_call4,1,"4u"},
+ {DW_OP_call_ref,1,"off"},
+ {DW_OP_form_tls_address,0,""},
+ {DW_OP_call_frame_cfa,0,""},
+ {DW_OP_bit_piece,2,"uleb"},
+ {DW_OP_implicit_value,2,"uleb"},
+ {DW_OP_stack_value,0,""},
+ {DW_OP_GNU_uninit,0,""},
+ {DW_OP_GNU_encoded_addr,1,"addr"},
+ {DW_OP_GNU_implicit_pointer,1,"addr" },
+ {DW_OP_GNU_entry_value,1,"val" },
+ /* terminator */
+ {0,0,""}
+};
+
+struct die_stack_data_s {
+ Dwarf_Die die_;
+ boolean already_printed_;
+};
+struct die_stack_data_s empty_stack_entry;
+
+#define DIE_STACK_SIZE 800
+static struct die_stack_data_s die_stack[DIE_STACK_SIZE];
+
+#define SET_DIE_STACK_ENTRY(i,x) { die_stack[i].die_ = x; \
+ die_stack[die_stack_indent_level].already_printed_ = FALSE; }
+#define EMPTY_DIE_STACK_ENTRY(i) { die_stack[i] = empty_stack_entry; }
+
+static int
+print_as_info_or_cu()
+{
+ return (info_flag || cu_name_flag);
+}
+
+
+/* process each compilation unit in .debug_info */
+void
+print_infos(Dwarf_Debug dbg,Dwarf_Bool is_info)
+{
+ int nres = 0;
+ if(is_info) {
+ nres = print_one_die_section(dbg,TRUE);
+ if (nres == DW_DLV_ERROR) {
+ char * errmsg = dwarf_errmsg(err);
+ Dwarf_Unsigned myerr = dwarf_errno(err);
+
+ fprintf(stderr, "%s ERROR: %s: %s (%lu)\n",
+ program_name, "attempting to print .debug_info",
+ errmsg, (unsigned long) myerr);
+ fprintf(stderr, "attempting to continue.\n");
+ }
+ return;
+ }
+ nres = print_one_die_section(dbg,FALSE);
+ if (nres == DW_DLV_ERROR) {
+ char * errmsg = dwarf_errmsg(err);
+ Dwarf_Unsigned myerr = dwarf_errno(err);
+
+ fprintf(stderr, "%s ERROR: %s: %s (%lu)\n",
+ program_name, "attempting to print .debug_types",
+ errmsg, (unsigned long) myerr);
+ fprintf(stderr, "attempting to continue.\n");
+ }
+}
+static void
+print_std_cu_hdr(Dwarf_Unsigned cu_header_length,
+ Dwarf_Unsigned abbrev_offset,
+ Dwarf_Half version_stamp,
+ Dwarf_Half address_size)
+{
+ if(dense) {
+ printf(" %s<0x%" DW_PR_XZEROS DW_PR_DUx
+ ">", "cu_header_length",
+ cu_header_length);
+ printf(" %s<0x%04x>", "version_stamp",
+ version_stamp);
+ printf(" %s<0x%" DW_PR_XZEROS DW_PR_DUx
+ ">", "abbrev_offset", abbrev_offset);
+ printf(" %s<0x%02x>", "address_size",
+ address_size);
+ } else {
+ printf(" %-16s = 0x%" DW_PR_XZEROS DW_PR_DUx
+ " %" DW_PR_DUu
+ "\n", "cu_header_length",
+ cu_header_length,
+ cu_header_length);
+ printf(" %-16s = 0x%04x %u\n", "version_stamp",
+ version_stamp,version_stamp);
+ printf(" %-16s = 0x%" DW_PR_XZEROS DW_PR_DUx
+ " %" DW_PR_DUu
+ "\n", "abbrev_offset",
+ abbrev_offset,
+ abbrev_offset);
+ printf(" %-16s = 0x%02x %u\n", "address_size",
+ address_size,address_size);
+ }
+}
+static void
+print_std_cu_signature(Dwarf_Sig8 *signature,Dwarf_Unsigned typeoffset)
+{
+ if(dense) {
+ struct esb_s sig8str;
+ esb_constructor(&sig8str);
+ format_sig8_string(signature,&sig8str);
+ printf(" %s<%s>", "signature",esb_get_string(&sig8str));
+ printf(" %s<0x%" DW_PR_XZEROS DW_PR_DUx ">",
+ "typeoffset", typeoffset);
+ esb_destructor(&sig8str);
+ } else {
+ struct esb_s sig8str;
+ esb_constructor(&sig8str);
+ format_sig8_string(signature,&sig8str);
+ printf(" %-16s = %s\n", "signature",esb_get_string(&sig8str));
+ printf(" %-16s = 0x%" DW_PR_XZEROS DW_PR_DUx " %" DW_PR_DUu "\n",
+ "typeoffset",
+ typeoffset,typeoffset);
+ esb_destructor(&sig8str);
+ }
+}
+
+static int
+print_one_die_section(Dwarf_Debug dbg,Dwarf_Bool is_info)
+{
+ Dwarf_Unsigned cu_header_length = 0;
+ Dwarf_Unsigned abbrev_offset = 0;
+ Dwarf_Half version_stamp = 0;
+ Dwarf_Half address_size = 0;
+ Dwarf_Half extension_size = 0;
+ Dwarf_Half length_size = 0;
+ Dwarf_Sig8 signature;
+ Dwarf_Unsigned typeoffset = 0;
+ Dwarf_Unsigned next_cu_offset = 0;
+ unsigned loop_count = 0;
+ int nres = DW_DLV_OK;
+ int cu_count = 0;
+ char * cu_short_name = NULL;
+ char * cu_long_name = NULL;
+ char * producer_name = NULL;
+
+ current_section_id = DEBUG_INFO;
+
+ if (print_as_info_or_cu() && do_print_dwarf) {
+ if(is_info) {
+ printf("\n.debug_info\n");
+ }
+ }
+
+ /* Loop until it fails. */
+ for(;;++loop_count) {
+ int sres = DW_DLV_OK;
+ Dwarf_Die cu_die = 0;
+
+ nres = dwarf_next_cu_header_c(dbg,
+ is_info,
+ &cu_header_length, &version_stamp,
+ &abbrev_offset, &address_size,
+ &length_size,&extension_size,
+ &signature, &typeoffset,
+ &next_cu_offset, &err);
+ if (nres == DW_DLV_NO_ENTRY) {
+ return nres;
+ }
+ if( loop_count == 0 &&!is_info &&
+ print_as_info_or_cu() && do_print_dwarf) {
+ printf("\n.debug_types\n");
+ }
+ if (nres != DW_DLV_OK) {
+ return nres;
+ }
+ if(cu_count >= break_after_n_units) {
+ printf("Break at %d\n",cu_count);
+ break;
+ }
+ /* Regardless of any options used, get basic
+ information about the current CU: producer, name */
+ sres = dwarf_siblingof_b(dbg, NULL,is_info, &cu_die, &err);
+ if (sres != DW_DLV_OK) {
+ print_error(dbg, "siblingof cu header", sres, err);
+ }
+ /* Get the CU offset for easy error reporting */
+ dwarf_die_offsets(cu_die,&DIE_overall_offset,&DIE_offset,&err);
+
+ if (cu_name_flag) {
+ if(should_skip_this_cu(dbg,cu_die,err)) {
+ dwarf_dealloc(dbg, cu_die, DW_DLA_DIE);
+ cu_die = 0;
+ ++cu_count;
+ cu_offset = next_cu_offset;
+ continue;
+ }
+ }
+
+ /* Get producer name for this CU and update compiler list */
+ get_producer_name(dbg,cu_die,err,&producer_name);
+ update_compiler_target(producer_name);
+
+ /* Once the compiler table has been updated, see
+ if we need to generate the list of CU compiled
+ by all the producers contained in the elf file */
+ if (producer_children_flag) {
+ get_cu_name(dbg,cu_die,err,&cu_short_name,&cu_long_name);
+ /* Add CU name to current compiler entry */
+ add_cu_name_compiler_target(cu_long_name);
+ }
+
+ /* If the current compiler is not requested by the
+ user, then move to the next CU */
+ if (!checking_this_compiler()) {
+ dwarf_dealloc(dbg, cu_die, DW_DLA_DIE);
+ ++cu_count;
+ cu_offset = next_cu_offset;
+ cu_die = 0;
+ continue;
+ }
+
+ /* We have not seen the compile unit yet, reset these
+ error-reporting globals. */
+ seen_CU = FALSE;
+ need_CU_name = TRUE;
+ need_CU_base_address = TRUE;
+ need_CU_high_address = TRUE;
+ seen_PU_base_address = FALSE;
+ seen_PU_high_address = FALSE;
+
+ /* Release the 'cu_die' created by the call
+ to 'dwarf_siblingof' at the top of the main loop. */
+ dwarf_dealloc(dbg, cu_die, DW_DLA_DIE);
+ cu_die = 0; /* For debugging, stale die should be NULL. */
+
+ if (info_flag && do_print_dwarf) {
+ if(verbose) {
+ if (dense) {
+ printf("<%s>", "cu_header");
+ } else {
+ printf("\nCU_HEADER:\n");
+ }
+ print_std_cu_hdr(cu_header_length,abbrev_offset,
+ version_stamp,address_size);
+ if(!is_info) {
+ print_std_cu_signature(&signature,typeoffset);
+ }
+ if(dense) {
+ printf("\n");
+ }
+ } else {
+ if(!is_info) {
+ if(dense) {
+ printf("<%s>", "cu_header");
+ } else {
+ printf("\nCU_HEADER:\n");
+ }
+ print_std_cu_signature(&signature,typeoffset);
+ if(dense) {
+ printf("\n");
+ }
+ }
+ }
+ }
+
+ /* Get abbreviation info for this CU */
+ get_abbrev_array_info(dbg,abbrev_offset);
+
+ /* process a single compilation unit in .debug_info. */
+ sres = dwarf_siblingof_b(dbg, NULL,is_info, &cu_die, &err);
+ if (sres == DW_DLV_OK) {
+ if (print_as_info_or_cu() || search_is_on) {
+ Dwarf_Signed cnt = 0;
+ char **srcfiles = 0;
+ int srcf = dwarf_srcfiles(cu_die,
+ &srcfiles, &cnt, &err);
+ if (srcf != DW_DLV_OK) {
+ srcfiles = 0;
+ cnt = 0;
+ }
+
+ /* Get the CU offset for easy error reporting */
+ dwarf_die_offsets(cu_die,&DIE_CU_overall_offset,
+ &DIE_CU_offset,&err);
+ print_die_and_children(dbg, cu_die,is_info, srcfiles, cnt);
+ if (srcf == DW_DLV_OK) {
+ int si = 0;
+ for (si = 0; si < cnt; ++si) {
+ dwarf_dealloc(dbg, srcfiles[si], DW_DLA_STRING);
+ }
+ dwarf_dealloc(dbg, srcfiles, DW_DLA_LIST);
+ }
+ }
+
+ /* Dump Ranges Information */
+ if (dump_ranges_info) {
+ PrintBucketGroup(pRangesInfo,TRUE);
+ }
+
+ /* Traverse the line section if in check mode */
+ if (line_flag || check_decl_file) {
+ print_line_numbers_this_cu(dbg, cu_die);
+ }
+ dwarf_dealloc(dbg, cu_die, DW_DLA_DIE);
+ cu_die = 0;
+ } else if (sres == DW_DLV_NO_ENTRY) {
+ /* Do nothing I guess. */
+ } else {
+ print_error(dbg, "Regetting cu_die", sres, err);
+ }
+ ++cu_count;
+ cu_offset = next_cu_offset;
+ }
+ return nres;
+}
+
+static void
+print_a_die_stack(Dwarf_Debug dbg,char **srcfiles,Dwarf_Signed cnt,int lev)
+{
+ boolean print_information = TRUE;
+ boolean ignore_die_stack = FALSE;
+ print_one_die(dbg,die_stack[lev].die_,print_information,lev,srcfiles,cnt,
+ ignore_die_stack);
+}
+extern void
+print_die_and_children(Dwarf_Debug dbg,
+ Dwarf_Die in_die_in,
+ Dwarf_Bool is_info,
+ char **srcfiles, Dwarf_Signed cnt)
+{
+ print_die_and_children_internal(dbg,
+ in_die_in,is_info,srcfiles,cnt);
+}
+
+static void
+print_die_stack(Dwarf_Debug dbg,char **srcfiles,Dwarf_Signed cnt)
+{
+ int lev = 0;
+ boolean print_information = TRUE;
+ boolean ignore_die_stack = FALSE;
+
+ for(lev = 0; lev <= die_stack_indent_level; ++lev)
+ {
+ print_one_die(dbg,die_stack[lev].die_,print_information,
+ lev,srcfiles,cnt,
+ ignore_die_stack);
+ }
+}
+
+/* recursively follow the die tree */
+static void
+print_die_and_children_internal(Dwarf_Debug dbg,
+ Dwarf_Die in_die_in,
+ Dwarf_Bool is_info,
+ char **srcfiles, Dwarf_Signed cnt)
+{
+ Dwarf_Die child = 0;
+ Dwarf_Die sibling = 0;
+ Dwarf_Error err = 0;
+ int tres = 0;
+ int cdres = 0;
+ Dwarf_Die in_die = in_die_in;
+
+ for (;;) {
+ SET_DIE_STACK_ENTRY(die_stack_indent_level,in_die);
+
+ /* Get the CU offset for easy error reporting */
+ dwarf_die_offsets(in_die,&DIE_overall_offset,&DIE_offset,&err);
+
+ if (check_tag_tree) {
+ DWARF_CHECK_COUNT(tag_tree_result,1);
+ if (die_stack_indent_level == 0) {
+ Dwarf_Half tag = 0;
+
+ tres = dwarf_tag(in_die, &tag, &err);
+ if (tres != DW_DLV_OK) {
+ DWARF_CHECK_ERROR(tag_tree_result,
+ "Tag-tree root is not DW_TAG_compile_unit");
+ } else if (tag == DW_TAG_compile_unit) {
+ /* OK */
+ } else {
+ DWARF_CHECK_ERROR(tag_tree_result,
+ "tag-tree root is not DW_TAG_compile_unit");
+ }
+ } else {
+ Dwarf_Half tag_parent = 0;
+ Dwarf_Half tag_child = 0;
+ int pres = 0;
+ int cres = 0;
+ const char *ctagname = "<child tag invalid>";
+ const char *ptagname = "<parent tag invalid>";
+
+ pres = dwarf_tag(die_stack[die_stack_indent_level - 1].die_,
+ &tag_parent, &err);
+ cres = dwarf_tag(in_die, &tag_child, &err);
+ if (pres != DW_DLV_OK)
+ tag_parent = 0;
+ if (cres != DW_DLV_OK)
+ tag_child = 0;
+
+ /* Check for specific compiler */
+ if (checking_this_compiler()) {
+ /* Process specific TAGs. */
+ tag_specific_checks_setup(tag_child,die_stack_indent_level);
+ if (cres != DW_DLV_OK || pres != DW_DLV_OK) {
+ if (cres == DW_DLV_OK) {
+ ctagname = get_TAG_name(tag_child,
+ dwarf_names_print_on_error);
+ }
+ if (pres == DW_DLV_OK) {
+ ptagname = get_TAG_name(tag_parent,
+ dwarf_names_print_on_error);
+ }
+ DWARF_CHECK_ERROR3(tag_tree_result,ptagname,
+ ctagname,
+ "Tag-tree relation is not standard..");
+ } else if (legal_tag_tree_combination(tag_parent,
+ tag_child)) {
+ /* OK */
+ } else {
+ DWARF_CHECK_ERROR3(tag_tree_result,
+ get_TAG_name(tag_parent,
+ dwarf_names_print_on_error),
+ get_TAG_name(tag_child,
+ dwarf_names_print_on_error),
+ "tag-tree relation is not standard.");
+ }
+ }
+ }
+ }
+
+ if (record_dwarf_error && check_verbose_mode) {
+ record_dwarf_error = FALSE;
+ }
+
+ /* Here do pre-descent processing of the die. */
+ {
+ boolean retry_print_on_match = FALSE;
+ boolean ignore_die_stack = FALSE;
+ retry_print_on_match = print_one_die(dbg, in_die,
+ print_as_info_or_cu(),
+ die_stack_indent_level, srcfiles, cnt,ignore_die_stack);
+ if(!print_as_info_or_cu() && retry_print_on_match) {
+ if (display_parent_tree) {
+ print_die_stack(dbg,srcfiles,cnt);
+ } else {
+ if (display_children_tree) {
+ print_a_die_stack(dbg,srcfiles,cnt,die_stack_indent_level);
+ }
+ }
+ if (display_children_tree) {
+ stop_indent_level = die_stack_indent_level;
+ info_flag = TRUE;
+ }
+ }
+ }
+
+ cdres = dwarf_child(in_die, &child, &err);
+
+ /* Check for specific compiler */
+ if (check_abbreviations && checking_this_compiler()) {
+ Dwarf_Half ab_has_child;
+ Dwarf_Bool bError = FALSE;
+ Dwarf_Half tag = 0;
+ tres = dwarf_die_abbrev_children_flag(in_die,&ab_has_child);
+ if (tres == DW_DLV_OK) {
+ DWARF_CHECK_COUNT(abbreviations_result,1);
+ tres = dwarf_tag(in_die, &tag, &err);
+ if (tres == DW_DLV_OK) {
+ switch (tag) {
+ case DW_TAG_array_type:
+ case DW_TAG_class_type:
+ case DW_TAG_compile_unit:
+ case DW_TAG_enumeration_type:
+ case DW_TAG_lexical_block:
+ case DW_TAG_namespace:
+ case DW_TAG_structure_type:
+ case DW_TAG_subprogram:
+ case DW_TAG_subroutine_type:
+ case DW_TAG_union_type:
+ case DW_TAG_entry_point:
+ case DW_TAG_inlined_subroutine:
+ break;
+ default:
+ bError = (cdres == DW_DLV_OK && !ab_has_child) ||
+ (cdres == DW_DLV_NO_ENTRY && ab_has_child);
+ if (bError) {
+ DWARF_CHECK_ERROR(abbreviations_result,
+ "check 'dw_children' flag combination.");
+ }
+ break;
+ }
+ }
+ }
+ }
+
+
+ /* child first: we are doing depth-first walk */
+ if (cdres == DW_DLV_OK) {
+ die_stack_indent_level++;
+ SET_DIE_STACK_ENTRY(die_stack_indent_level,0);
+ if(die_stack_indent_level >= DIE_STACK_SIZE ) {
+ print_error(dbg,
+ "compiled in DIE_STACK_SIZE limit exceeded",
+ DW_DLV_OK,err);
+ }
+ print_die_and_children_internal(dbg, child,is_info, srcfiles, cnt);
+ EMPTY_DIE_STACK_ENTRY(die_stack_indent_level);
+ die_stack_indent_level--;
+ if (die_stack_indent_level == 0)
+ local_symbols_already_began = FALSE;
+ dwarf_dealloc(dbg, child, DW_DLA_DIE);
+ child = 0;
+ } else if (cdres == DW_DLV_ERROR) {
+ print_error(dbg, "dwarf_child", cdres, err);
+ }
+
+ /* Stop the display of all children */
+ if (display_children_tree && info_flag &&
+ stop_indent_level == die_stack_indent_level) {
+
+ info_flag = FALSE;
+ }
+
+ cdres = dwarf_siblingof_b(dbg, in_die,is_info, &sibling, &err);
+ if (cdres == DW_DLV_OK) {
+ /* print_die_and_children(dbg, sibling, srcfiles, cnt); We
+ loop around to actually print this, rather than
+ recursing. Recursing is horribly wasteful of stack
+ space. */
+ } else if (cdres == DW_DLV_ERROR) {
+ print_error(dbg, "dwarf_siblingof", cdres, err);
+ }
+
+ /* If we have a sibling, verify that its offset
+ is next to the last processed DIE;
+ An incorrect sibling chain is a nasty bug. */
+ if (cdres == DW_DLV_OK && sibling && check_di_gaps &&
+ checking_this_compiler()) {
+
+ Dwarf_Off glb_off;
+ DWARF_CHECK_COUNT(di_gaps_result,1);
+ if (dwarf_validate_die_sibling(sibling,&glb_off) == DW_DLV_ERROR) {
+ static char msg[128];
+ Dwarf_Off sib_off;
+ dwarf_dieoffset(sibling,&sib_off,&err);
+ sprintf(msg,
+ "GSIB = 0x%" DW_PR_XZEROS DW_PR_DUx
+ " GOFF = 0x%" DW_PR_XZEROS DW_PR_DUx
+ " Gap = %" DW_PR_DUu " bytes",
+ sib_off,glb_off,sib_off-glb_off);
+ DWARF_CHECK_ERROR2(di_gaps_result,
+ "Incorrect sibling chain",msg);
+ }
+ }
+
+ /* Here do any post-descent (ie post-dwarf_child) processing of
+ the in_die. */
+
+ EMPTY_DIE_STACK_ENTRY(die_stack_indent_level);
+ if (in_die != in_die_in) {
+ /* Dealloc our in_die, but not the argument die, it belongs
+ to our caller. Whether the siblingof call worked or not. */
+ dwarf_dealloc(dbg, in_die, DW_DLA_DIE);
+ in_die = 0;
+ }
+ if (cdres == DW_DLV_OK) {
+ /* Set to process the sibling, loop again. */
+ in_die = sibling;
+ } else {
+ /* We are done, no more siblings at this level. */
+ break;
+ }
+ } /* end for loop on siblings */
+ return;
+}
+
+/* Print one die on error and verbose or non check mode */
+#define PRINTING_DIES (do_print_dwarf || (record_dwarf_error && check_verbose_mode))
+
+/* If print_information is FALSE, check the TAG and if it is a CU die
+ print the information anyway. */
+boolean
+print_one_die(Dwarf_Debug dbg, Dwarf_Die die,
+ boolean print_information,
+ int die_indent_level,
+ char **srcfiles, Dwarf_Signed cnt,
+ boolean ignore_die_stack)
+{
+ Dwarf_Signed i = 0;
+ Dwarf_Off offset = 0;
+ Dwarf_Off overall_offset = 0;
+ const char * tagname = 0;
+ Dwarf_Half tag = 0;
+ Dwarf_Signed atcnt = 0;
+ Dwarf_Attribute *atlist = 0;
+ int tres = 0;
+ int ores = 0;
+ int atres = 0;
+ int abbrev_code = dwarf_die_abbrev_code(die);
+ boolean attribute_matched = FALSE;
+
+ /* Print using indentation
+ < 1><0x000854ff GOFF=0x00546047> DW_TAG_pointer_type -> 34
+ < 1><0x000854ff> DW_TAG_pointer_type -> 18
+ DW_TAG_pointer_type -> 2
+ */
+ /* Attribute indent. */
+ int nColumn = show_global_offsets ? 34 : 18;
+
+ if (check_abbreviations && checking_this_compiler()) {
+ validate_abbrev_code(dbg,abbrev_code);
+ }
+
+ if(!ignore_die_stack && die_stack[die_indent_level].already_printed_) {
+ /* FALSE seems like a safe return. */
+ return FALSE;
+ }
+
+ /* Reset indentation column if no offsets */
+ if (!display_offsets) {
+ nColumn = 2;
+ }
+
+ tres = dwarf_tag(die, &tag, &err);
+ if (tres != DW_DLV_OK) {
+ print_error(dbg, "accessing tag of die!", tres, err);
+ }
+ tagname = get_TAG_name(tag,dwarf_names_print_on_error);
+
+ tag_specific_checks_setup(tag,die_indent_level);
+ ores = dwarf_dieoffset(die, &overall_offset, &err);
+ if (ores != DW_DLV_OK) {
+ print_error(dbg, "dwarf_dieoffset", ores, err);
+ }
+ ores = dwarf_die_CU_offset(die, &offset, &err);
+ if (ores != DW_DLV_OK) {
+ print_error(dbg, "dwarf_die_CU_offset", ores, err);
+ }
+
+ if (dump_visited_info && check_self_references) {
+ printf("<%2d><0x%" DW_PR_XZEROS DW_PR_DUx
+ " GOFF=0x%" DW_PR_XZEROS DW_PR_DUx "> ",
+ die_indent_level, (Dwarf_Unsigned)offset,
+ (Dwarf_Unsigned)overall_offset);
+ printf("%*s%s\n",die_indent_level * 2 + 2," ",tagname);
+ }
+
+ /* Print the die */
+ if (PRINTING_DIES && print_information) {
+ if (!ignore_die_stack) {
+ die_stack[die_indent_level].already_printed_ = TRUE;
+ }
+ if (die_indent_level == 0) {
+ if (dense) {
+ printf("\n");
+ } else {
+ printf("\nCOMPILE_UNIT<header overall offset = 0x%"
+ DW_PR_XZEROS DW_PR_DUx ">:\n",
+ (Dwarf_Unsigned)(overall_offset - offset));
+ }
+ } else if (local_symbols_already_began == FALSE &&
+ die_indent_level == 1 && !dense) {
+
+ printf("\nLOCAL_SYMBOLS:\n");
+ local_symbols_already_began = TRUE;
+ }
+
+ /* Print just the Tags and Attributes */
+ if (!display_offsets) {
+ /* Print using indentation */
+ printf("%*s%s\n",die_stack_indent_level * 2 + 2," ",tagname);
+ } else {
+ if (dense) {
+ if (show_global_offsets) {
+ if (die_indent_level == 0) {
+ printf("<%d><0x%" DW_PR_DUx "+0x%" DW_PR_DUx " GOFF=0x%"
+ DW_PR_DUx ">", die_indent_level,
+ (Dwarf_Unsigned)(overall_offset - offset),
+ (Dwarf_Unsigned)offset,
+ (Dwarf_Unsigned)overall_offset);
+ } else {
+ printf("<%d><0x%" DW_PR_DUx " GOFF=0x%" DW_PR_DUx ">",
+ die_indent_level,
+ (Dwarf_Unsigned)offset,
+ (Dwarf_Unsigned)overall_offset);
+ }
+ } else {
+ if (die_indent_level == 0) {
+ printf("<%d><0x%" DW_PR_DUx "+0x%" DW_PR_DUx ">",
+ die_indent_level,
+ (Dwarf_Unsigned)(overall_offset - offset),
+ (Dwarf_Unsigned)offset);
+ } else {
+ printf("<%d><0x%" DW_PR_DUx ">", die_indent_level,
+ (Dwarf_Unsigned)offset);
+ }
+ }
+ printf("<%s>",tagname);
+ if(verbose) {
+ printf(" <abbrev %d>",abbrev_code);
+ }
+ } else {
+ if (show_global_offsets) {
+ printf("<%2d><0x%" DW_PR_XZEROS DW_PR_DUx
+ " GOFF=0x%" DW_PR_XZEROS DW_PR_DUx ">",
+ die_indent_level, (Dwarf_Unsigned)offset,
+ (Dwarf_Unsigned)overall_offset);
+ } else {
+ printf("<%2d><0x%" DW_PR_XZEROS DW_PR_DUx ">",
+ die_indent_level,
+ (Dwarf_Unsigned)offset);
+ }
+
+ /* Print using indentation */
+ printf("%*s%s",die_indent_level * 2 + 2," ",tagname);
+ if(verbose) {
+ printf(" <abbrev %d>",abbrev_code);
+ }
+ fputs("\n",stdout);
+ }
+ }
+ }
+
+ atres = dwarf_attrlist(die, &atlist, &atcnt, &err);
+ if (atres == DW_DLV_ERROR) {
+ print_error(dbg, "dwarf_attrlist", atres, err);
+ } else if (atres == DW_DLV_NO_ENTRY) {
+ /* indicates there are no attrs. It is not an error. */
+ atcnt = 0;
+ }
+
+ /* Reset any loose references to low or high PC */
+ bSawLow = FALSE;
+ bSawHigh = FALSE;
+
+ /* Get the CU offset for easy error reporting */
+ dwarf_die_offsets(die,&DIE_CU_overall_offset,&DIE_CU_offset,&err);
+
+ for (i = 0; i < atcnt; i++) {
+ Dwarf_Half attr;
+ int ares;
+
+ ares = dwarf_whatattr(atlist[i], &attr, &err);
+ if (ares == DW_DLV_OK) {
+ /* Print using indentation */
+ if (!dense && PRINTING_DIES && print_information) {
+ printf("%*s",die_indent_level * 2 + 2 + nColumn," ");
+ }
+
+ {
+ boolean attr_match = print_attribute(dbg, die, attr,
+ atlist[i],
+ print_information, die_indent_level, srcfiles, cnt);
+ if(print_information == FALSE && attr_match) {
+ attribute_matched = TRUE;
+ }
+ }
+
+ if (record_dwarf_error && check_verbose_mode) {
+ record_dwarf_error = FALSE;
+ }
+ } else {
+ print_error(dbg, "dwarf_whatattr entry missing", ares, err);
+ }
+ }
+
+ for (i = 0; i < atcnt; i++) {
+ dwarf_dealloc(dbg, atlist[i], DW_DLA_ATTR);
+ }
+ if (atres == DW_DLV_OK) {
+ dwarf_dealloc(dbg, atlist, DW_DLA_LIST);
+ }
+
+ if (PRINTING_DIES && dense && print_information) {
+ printf("\n");
+ }
+ return attribute_matched;
+}
+
+/* Encodings have undefined signedness. Accept either
+ signedness. The values are integer-like (they are defined
+ in the DWARF specification), so the
+ form the compiler uses (as long as it is
+ a constant value) is a non-issue.
+
+ The numbers need not be small (in spite of the
+ function name), but the result should be an integer.
+
+ If string_out is non-NULL, construct a string output, either
+ an error message or the name of the encoding.
+ The function pointer passed in is to code generated
+ by a script at dwarfdump build time. The code for
+ the val_as_string function is generated
+ from dwarf.h. See <build dir>/dwarf_names.c
+
+ The known_signed bool is set true(nonzero) or false (zero)
+ and *both* uval_out and sval_out are set to the value,
+ though of course uval_out cannot represent a signed
+ value properly and sval_out cannot represent all unsigned
+ values properly.
+
+ If string_out is non-NULL then attr_name and val_as_string
+ must also be non-NULL. */
+static int
+get_small_encoding_integer_and_name(Dwarf_Debug dbg,
+ Dwarf_Attribute attrib,
+ Dwarf_Unsigned * uval_out,
+ char *attr_name,
+ const char ** string_out,
+ encoding_type_func val_as_string,
+ Dwarf_Error * err,
+ int show_form)
+{
+ Dwarf_Unsigned uval = 0;
+ char buf[100]; /* The strings are small. */
+ int vres = dwarf_formudata(attrib, &uval, err);
+
+ if (vres != DW_DLV_OK) {
+ Dwarf_Signed sval = 0;
+ vres = dwarf_formsdata(attrib, &sval, err);
+ if (vres != DW_DLV_OK) {
+ vres = dwarf_global_formref(attrib,&uval,err);
+ if (vres != DW_DLV_OK) {
+ if (string_out != 0) {
+ snprintf(buf, sizeof(buf),
+ "%s has a bad form.", attr_name);
+ *string_out = makename(buf);
+ }
+ return vres;
+ }
+ *uval_out = uval;
+ } else {
+ uval = (Dwarf_Unsigned) sval;
+ *uval_out = uval;
+ }
+ } else {
+ *uval_out = uval;
+ }
+ if (string_out) {
+ Dwarf_Half theform = 0;
+ Dwarf_Half directform = 0;
+ get_form_values(attrib,&theform,&directform);
+ esb_empty_string(&esb_base);
+ esb_append(&esb_base, val_as_string((Dwarf_Half) uval,
+ dwarf_names_print_on_error));
+ show_form_itself(show_form, verbose, theform, directform,&esb_base);
+ *string_out = makename(esb_get_string(&esb_base));
+ }
+ return DW_DLV_OK;
+}
+
+
+
+
+/* We need a 32-bit signed number here, but there's no portable
+ way of getting that. So use __uint32_t instead. It's supplied
+ in a reliable way by the autoconf infrastructure. */
+
+static void
+get_FLAG_BLOCK_string(Dwarf_Debug dbg, Dwarf_Attribute attrib,
+ struct esb_s*esbp)
+{
+ int fres = 0;
+ Dwarf_Block *tempb = 0;
+ __uint32_t * array = 0;
+ Dwarf_Unsigned array_len = 0;
+ __uint32_t * array_ptr;
+ Dwarf_Unsigned array_remain = 0;
+ char linebuf[100];
+
+ /* first get compressed block data */
+ fres = dwarf_formblock (attrib,&tempb, &err);
+ if (fres != DW_DLV_OK) {
+ print_error(dbg,"DW_FORM_blockn cannot get block\n",fres,err);
+ return;
+ }
+
+ /* uncompress block into int array */
+ array = dwarf_uncompress_integer_block(dbg,
+ 1, /* 'true' (meaning signed ints)*/
+ 32, /* bits per unit */
+ tempb->bl_data,
+ tempb->bl_len,
+ &array_len, /* len of out array */
+ &err);
+ if (array == (void*) DW_DLV_BADOFFSET) {
+ print_error(dbg,"DW_AT_SUN_func_offsets cannot uncompress data\n",0,err);
+ return;
+ }
+ if (array_len == 0) {
+ print_error(dbg,"DW_AT_SUN_func_offsets has no data\n",0,err);
+ return;
+ }
+
+ /* fill in string buffer */
+ array_remain = array_len;
+ array_ptr = array;
+ while (array_remain > 8) {
+ /* Print a full line */
+ /* If you touch this string, update the magic number 8 in
+ the += and -= below! */
+ snprintf(linebuf, sizeof(linebuf),
+ "\n 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x",
+ array_ptr[0], array_ptr[1],
+ array_ptr[2], array_ptr[3],
+ array_ptr[4], array_ptr[5],
+ array_ptr[6], array_ptr[7]);
+ array_ptr += 8;
+ array_remain -= 8;
+ esb_append(&esb_base, linebuf);
+ }
+
+ /* now do the last line */
+ if (array_remain > 0) {
+ esb_append(&esb_base, "\n ");
+ while (array_remain > 0) {
+ snprintf(linebuf, sizeof(linebuf), " 0x%08x", *array_ptr);
+ array_remain--;
+ array_ptr++;
+ esb_append(&esb_base, linebuf);
+ }
+ }
+
+ /* free array buffer */
+ dwarf_dealloc_uncompressed_block(dbg, array);
+
+}
+
+static const char *
+get_rangelist_type_descr(Dwarf_Ranges *r)
+{
+ switch(r->dwr_type) {
+ case DW_RANGES_ENTRY: return "range entry";
+ case DW_RANGES_ADDRESS_SELECTION: return "addr selection";
+ case DW_RANGES_END: return "range end";
+ }
+ /* Impossible. */
+ return "Unknown";
+}
+
+
+void
+print_ranges_list_to_extra(Dwarf_Debug dbg,
+ Dwarf_Unsigned off,
+ Dwarf_Ranges *rangeset,
+ Dwarf_Signed rangecount,
+ Dwarf_Unsigned bytecount,
+ struct esb_s *stringbuf)
+{
+ char tmp[200];
+ Dwarf_Signed i;
+ if(dense) {
+ snprintf(tmp,sizeof(tmp),
+ "< ranges: %" DW_PR_DSd " ranges at .debug_ranges offset %"
+ DW_PR_DUu " (0x%" DW_PR_XZEROS DW_PR_DUx ") "
+ "(%" DW_PR_DUu " bytes)>",
+ rangecount,
+ off,
+ off,
+ bytecount);
+ esb_append(stringbuf,tmp);
+ } else {
+ snprintf(tmp,sizeof(tmp),
+ "\t\tranges: %" DW_PR_DSd " at .debug_ranges offset %"
+ DW_PR_DUu " (0x%" DW_PR_XZEROS DW_PR_DUx ") "
+ "(%" DW_PR_DUu " bytes)\n",
+ rangecount,
+ off,
+ off,
+ bytecount);
+ esb_append(stringbuf,tmp);
+ }
+ for(i = 0; i < rangecount; ++i) {
+ Dwarf_Ranges * r = rangeset +i;
+ const char *type = get_rangelist_type_descr(r);
+ if(dense) {
+ snprintf(tmp,sizeof(tmp),
+ "<[%2" DW_PR_DSd
+ "] %s 0x%" DW_PR_XZEROS DW_PR_DUx
+ " 0x%" DW_PR_XZEROS DW_PR_DUx ">",
+ (Dwarf_Signed)i,
+ type,
+ (Dwarf_Unsigned)r->dwr_addr1,
+ (Dwarf_Unsigned)r->dwr_addr2);
+ } else {
+ snprintf(tmp,sizeof(tmp),
+ "\t\t\t[%2" DW_PR_DSd
+ "] %-14s 0x%" DW_PR_XZEROS DW_PR_DUx
+ " 0x%" DW_PR_XZEROS DW_PR_DUx "\n",
+ (Dwarf_Signed)i,
+ type,
+ (Dwarf_Unsigned)r->dwr_addr1,
+ (Dwarf_Unsigned)r->dwr_addr2);
+ }
+ esb_append(stringbuf,tmp);
+ }
+}
+
+
+static boolean
+is_location_form(int form)
+{
+ if(form == DW_FORM_block1 ||
+ form == DW_FORM_block2 ||
+ form == DW_FORM_block4 ||
+ form == DW_FORM_block ||
+ form == DW_FORM_data4 ||
+ form == DW_FORM_data8 ||
+ form == DW_FORM_sec_offset) {
+ return TRUE;
+ }
+ return FALSE;
+}
+
+static void
+show_attr_form_error(Dwarf_Debug dbg,unsigned attr,unsigned form,struct esb_s *out)
+{
+ const char *n = 0;
+ int res;
+ char buf[30];
+ esb_append(out,"ERROR: Attribute ");
+ snprintf(buf,sizeof(buf),"%u",attr);
+ esb_append(out,buf);
+ esb_append(out," (");
+ res = dwarf_get_AT_name(attr,&n);
+ if(res != DW_DLV_OK) {
+ n = "UknownAttribute";
+ }
+ esb_append(out,n);
+ esb_append(out,") ");
+ esb_append(out," has form ");
+ snprintf(buf,sizeof(buf),"%u",form);
+ esb_append(out,buf);
+ esb_append(out," (");
+ res = dwarf_get_FORM_name(form,&n);
+ if(res != DW_DLV_OK) {
+ n = "UknownForm";
+ }
+ esb_append(out,n);
+ esb_append(out,"), a form which is not appropriate");
+ print_error_and_continue(dbg,esb_get_string(out), DW_DLV_OK,err);
+}
+
+/* Traverse an attribute and following any reference
+ in order to detect self references to DIES (loop). */
+static boolean
+traverse_attribute(Dwarf_Debug dbg, Dwarf_Die die, Dwarf_Half attr,
+ Dwarf_Attribute attr_in,
+ boolean print_information,
+ char **srcfiles, Dwarf_Signed cnt,
+ int die_indent_level)
+{
+ Dwarf_Attribute attrib = 0;
+ const char * atname = 0;
+ const char * valname = 0;
+ int tres = 0;
+ Dwarf_Half tag = 0;
+ boolean circular_reference = FALSE;
+ Dwarf_Bool is_info = TRUE;
+
+ is_info = dwarf_get_die_infotypes_flag(die);
+ atname = get_AT_name(attr,dwarf_names_print_on_error);
+
+ /* The following gets the real attribute, even in the face of an
+ incorrect doubling, or worse, of attributes. */
+ attrib = attr_in;
+ /* Do not get attr via dwarf_attr: if there are (erroneously)
+ multiple of an attr in a DIE, dwarf_attr will not get the
+ second, erroneous one and dwarfdump will print the first one
+ multiple times. Oops. */
+
+ tres = dwarf_tag(die, &tag, &err);
+ if (tres == DW_DLV_ERROR) {
+ tag = 0;
+ } else if (tres == DW_DLV_NO_ENTRY) {
+ tag = 0;
+ } else {
+ /* ok */
+ }
+
+ switch (attr) {
+ case DW_AT_specification:
+ case DW_AT_abstract_origin:
+ case DW_AT_type: {
+ int res = 0;
+ Dwarf_Off die_off = 0;
+ Dwarf_Off ref_off = 0;
+ Dwarf_Die ref_die = 0;
+
+ ++die_indent_level;
+ esb_empty_string(&esb_base);
+ get_attr_value(dbg, tag, die, attrib, srcfiles, cnt,
+ &esb_base, show_form_used,verbose);
+ valname = esb_get_string(&esb_base);
+
+ /* Get the global offset for reference */
+ res = dwarf_global_formref(attrib, &ref_off, &err);
+ if (res != DW_DLV_OK) {
+ int errno = dwarf_errno(err);
+ if (errno == DW_DLE_REF_SIG8_NOT_HANDLED ) {
+ // No need to stop, ref_sig8 refers out of
+ // the current section.
+ break;
+ } else {
+ print_error(dbg, "dwarf_global_formref fails in traversal",
+ res, err);
+ }
+ }
+ res = dwarf_dieoffset(die, &die_off, &err);
+ if (res != DW_DLV_OK) {
+ int errno = dwarf_errno(err);
+ if (errno == DW_DLE_REF_SIG8_NOT_HANDLED ) {
+ // No need to stop, ref_sig8 refers out of
+ // the current section.
+ break;
+ } else {
+ print_error(dbg, "dwarf_dieoffset fails in traversal", res, err);
+ }
+ }
+
+ /* Follow reference chain, looking for self references */
+ res = dwarf_offdie_b(dbg,ref_off,is_info,&ref_die,&err);
+ if (res == DW_DLV_OK) {
+ ++die_indent_level;
+ /* Dump visited information */
+ if (dump_visited_info) {
+ Dwarf_Off off = 0;
+ dwarf_die_CU_offset(die, &off, &err);
+ /* Check above call return status? FIXME */
+
+ printf("<%2d><0x%" DW_PR_XZEROS DW_PR_DUx
+ " GOFF=0x%" DW_PR_XZEROS DW_PR_DUx "> ",
+ die_indent_level, (Dwarf_Unsigned)off,
+ (Dwarf_Unsigned)die_off);
+ printf("%*s%s -> %s\n",die_indent_level * 2 + 2,
+ " ",atname,valname);
+ }
+ circular_reference = traverse_one_die(dbg,attrib,ref_die,
+ srcfiles,cnt,die_indent_level);
+ DeleteKeyInBucketGroup(pVisitedInfo,ref_off);
+ dwarf_dealloc(dbg,ref_die,DW_DLA_DIE);
+ --die_indent_level;
+ ref_die = 0;
+ }
+ }
+ break;
+ } /* End switch. */
+ return circular_reference;
+}
+
+/* Traverse one DIE in order to detect self references to DIES. */
+static boolean
+traverse_one_die(Dwarf_Debug dbg, Dwarf_Attribute attrib, Dwarf_Die die,
+ char **srcfiles, Dwarf_Signed cnt, int die_indent_level)
+{
+ Dwarf_Half tag = 0;
+ Dwarf_Off overall_offset = 0;
+ Dwarf_Signed atcnt = 0;
+ int res = 0;
+ boolean circular_reference = FALSE;
+ boolean print_information = FALSE;
+
+ res = dwarf_tag(die, &tag, &err);
+ if (res != DW_DLV_OK) {
+ print_error(dbg, "accessing tag of die!", res, err);
+ }
+ res = dwarf_dieoffset(die, &overall_offset, &err);
+ if (res != DW_DLV_OK) {
+ print_error(dbg, "dwarf_dieoffset", res, err);
+ }
+
+ /* Print visited information */
+ if (dump_visited_info) {
+ Dwarf_Off offset = 0;
+ const char * tagname = 0;
+ res = dwarf_die_CU_offset(die, &offset, &err);
+ if (res != DW_DLV_OK) {
+ print_error(dbg, "dwarf_die_CU_offsetC", res, err);
+ }
+ tagname = get_TAG_name(tag,dwarf_names_print_on_error);
+ printf("<%2d><0x%" DW_PR_XZEROS DW_PR_DUx
+ " GOFF=0x%" DW_PR_XZEROS DW_PR_DUx "> ",
+ die_indent_level, (Dwarf_Unsigned)offset,
+ (Dwarf_Unsigned)overall_offset);
+ printf("%*s%s\n",die_indent_level * 2 + 2," ",tagname);
+ }
+
+ DWARF_CHECK_COUNT(self_references_result,1);
+ if (FindKeyInBucketGroup(pVisitedInfo,overall_offset)) {
+ char * valname = NULL;
+ Dwarf_Half attr = 0;
+ const char *atname = NULL;
+ esb_empty_string(&esb_base);
+ get_attr_value(dbg, tag, die, attrib, srcfiles,
+ cnt, &esb_base, show_form_used,verbose);
+ valname = esb_get_string(&esb_base);
+ dwarf_whatattr(attrib, &attr, &err);
+ atname = get_AT_name(attr,dwarf_names_print_on_error);
+
+ /* We have a self reference */
+ DWARF_CHECK_ERROR3(self_references_result,
+ "Invalid self reference to DIE: ",atname,valname);
+ circular_reference = TRUE;
+ } else {
+ Dwarf_Signed i = 0;
+ Dwarf_Attribute *atlist = 0;
+
+ /* Add current DIE */
+ AddEntryIntoBucketGroup(pVisitedInfo,overall_offset,
+ 0,0,0,NULL,FALSE);
+
+ res = dwarf_attrlist(die, &atlist, &atcnt, &err);
+ if (res == DW_DLV_ERROR) {
+ print_error(dbg, "dwarf_attrlist", res, err);
+ } else if (res == DW_DLV_NO_ENTRY) {
+ /* indicates there are no attrs. It is not an error. */
+ atcnt = 0;
+ }
+
+ for (i = 0; i < atcnt; i++) {
+ Dwarf_Half attr;
+ int ares;
+
+ ares = dwarf_whatattr(atlist[i], &attr, &err);
+ if (ares == DW_DLV_OK) {
+ circular_reference = traverse_attribute(dbg, die, attr,
+ atlist[i],
+ print_information, srcfiles, cnt,
+ die_indent_level);
+ } else {
+ print_error(dbg, "dwarf_whatattr entry missing",
+ ares, err);
+ }
+ }
+
+ for (i = 0; i < atcnt; i++) {
+ dwarf_dealloc(dbg, atlist[i], DW_DLA_ATTR);
+ }
+ if (res == DW_DLV_OK) {
+ dwarf_dealloc(dbg, atlist, DW_DLA_LIST);
+ }
+
+ /* Delete current DIE */
+ DeleteKeyInBucketGroup(pVisitedInfo,overall_offset);
+ }
+ return circular_reference;
+}
+
+
+/* Extracted this from print_attribute()
+ to get tolerable indents.
+ In other words to make it readable.
+ It uses global data fields excessively, but so does
+ print_attribute().
+ The majority of the code here is checking for
+ compiler errors. */
+static void
+print_range_attribute(Dwarf_Debug dbg,
+ Dwarf_Die die,
+ Dwarf_Half attr,
+ Dwarf_Attribute attr_in,
+ Dwarf_Half theform,
+ int dwarf_names_print_on_error,
+ boolean print_information,
+ int *append_extra_string)
+{
+ Dwarf_Error err = 0;
+ Dwarf_Unsigned original_off = 0;
+ int fres = 0;
+
+ fres = dwarf_global_formref(attr_in, &original_off, &err);
+ if( fres == DW_DLV_OK) {
+ Dwarf_Ranges *rangeset = 0;
+ Dwarf_Signed rangecount = 0;
+ Dwarf_Unsigned bytecount = 0;
+ int rres = dwarf_get_ranges_a(dbg,original_off,
+ die,
+ &rangeset,
+ &rangecount,&bytecount,&err);
+ if(rres == DW_DLV_OK) {
+ /* Ignore ranges inside a stripped function */
+ if (check_ranges &&
+ in_valid_code && checking_this_compiler()) {
+ Dwarf_Unsigned off = original_off;
+
+ Dwarf_Signed index = 0;
+ Dwarf_Addr base_address = CU_base_address;
+ Dwarf_Addr lopc = 0;
+ Dwarf_Addr hipc = 0;
+ Dwarf_Bool bError = FALSE;
+
+ /* Ignore last entry, is the end-of-list */
+ for (index = 0; index < rangecount - 1; index++) {
+ Dwarf_Ranges *r = rangeset + index;
+
+ if (r->dwr_addr1 == elf_max_address) {
+ /* (0xffffffff,addr), use specific address (current PU address) */
+ base_address = r->dwr_addr2;
+ } else {
+ /* (offset,offset), update using CU address */
+ lopc = r->dwr_addr1 + base_address;
+ hipc = r->dwr_addr2 + base_address;
+ DWARF_CHECK_COUNT(ranges_result,1);
+
+ /* Check the low_pc and high_pc
+ are within a valid range in
+ the .text section */
+ if (IsValidInBucketGroup(pRangesInfo,lopc) &&
+ IsValidInBucketGroup(pRangesInfo,hipc)) {
+ /* Valid values; do nothing */
+ } else {
+ /* At this point may be we
+ are dealing with a
+ linkonce symbol */
+ if (IsValidInLinkonce(pLinkonceInfo,
+ PU_name,lopc,hipc)) {
+ /* Valid values; do nothing */
+ } else {
+ bError = TRUE;
+ DWARF_CHECK_ERROR(ranges_result,
+ ".debug_ranges: Address outside a "
+ "valid .text range");
+ if (check_verbose_mode) {
+ printf(
+ "Offset = 0x%" DW_PR_XZEROS DW_PR_DUx
+ ", Base = 0x%" DW_PR_XZEROS DW_PR_DUx
+ ", "
+ "Low = 0x%" DW_PR_XZEROS DW_PR_DUx
+ " (0x%" DW_PR_XZEROS DW_PR_DUx
+ "), High = 0x%"
+ DW_PR_XZEROS DW_PR_DUx
+ " (0x%" DW_PR_XZEROS DW_PR_DUx
+ ")\n",
+ off,base_address,lopc,
+ r->dwr_addr1,hipc,
+ r->dwr_addr2);
+ }
+ }
+ }
+ }
+ /* Each entry holds 2 addresses (offsets) */
+ off += elf_address_size * 2;
+ }
+ if (bError && check_verbose_mode) {
+ printf("\n");
+ }
+ }
+ if(print_information) {
+ *append_extra_string = 1;
+ esb_empty_string(&esb_extra);
+ print_ranges_list_to_extra(dbg,original_off,
+ rangeset,rangecount,bytecount,
+ &esb_extra);
+ }
+ dwarf_ranges_dealloc(dbg,rangeset,rangecount);
+ } else if (rres == DW_DLV_ERROR) {
+ if (do_print_dwarf) {
+ printf("\ndwarf_get_ranges() "
+ "cannot find DW_AT_ranges at offset 0x%"
+ DW_PR_XZEROS DW_PR_DUx
+ " (0x%" DW_PR_XZEROS DW_PR_DUx ").",
+ original_off,
+ original_off);
+ } else {
+ DWARF_CHECK_COUNT(ranges_result,1);
+ DWARF_CHECK_ERROR2(ranges_result,
+ get_AT_name(attr,
+ dwarf_names_print_on_error),
+ " cannot find DW_AT_ranges at offset");
+ }
+ } else {
+ /* NO ENTRY */
+ if (do_print_dwarf) {
+ printf("\ndwarf_get_ranges() "
+ "finds no DW_AT_ranges at offset 0x%"
+ DW_PR_XZEROS DW_PR_DUx
+ " (0x%" DW_PR_XZEROS DW_PR_DUx ").",
+ original_off,
+ original_off);
+ } else {
+ DWARF_CHECK_COUNT(ranges_result,1);
+ DWARF_CHECK_ERROR2(ranges_result,
+ get_AT_name(attr,
+ dwarf_names_print_on_error),
+ " fails to find DW_AT_ranges at offset");
+ }
+ }
+ } else {
+ if (do_print_dwarf) {
+ struct esb_s local;
+ char tmp[100];
+
+ snprintf(tmp,sizeof(tmp)," attr 0x%x form 0x%x ",
+ (unsigned)attr,(unsigned)theform);
+ esb_constructor(&local);
+ esb_append(&local,
+ " fails to find DW_AT_ranges offset");
+ esb_append(&local,tmp);
+ printf(" %s ",esb_get_string(&local));
+ esb_destructor(&local);
+ } else {
+ DWARF_CHECK_COUNT(ranges_result,1);
+ DWARF_CHECK_ERROR2(ranges_result,
+ get_AT_name(attr,
+ dwarf_names_print_on_error),
+ " fails to find DW_AT_ranges offset");
+ }
+ }
+}
+
+/* A DW_AT_name in a CU DIE will likely have dots
+ and be entirely sensible. So lets
+ not call things a possible error when they are not.
+ Some assemblers allow '.' in an identifier too.
+ We should check for that, but we don't yet.
+
+ We should check the compiler before checking
+ for 'altabi.' too (FIXME).
+
+ This is a heuristic, not all that reliable.
+
+ Return 0 if it is a vaguely standard identifier.
+ Else return 1, meaning 'it might be a file name
+ or have '.' in it quite sensibly.'
+
+ If we don't do the TAG check we might report "t.c"
+ as a questionable DW_AT_name. Which would be silly.
+*/
+static int
+dot_ok_in_identifier(int tag,Dwarf_Die die, const char *val)
+{
+ if (strncmp(val,"altabi.",7)) {
+ /* Ignore the names of the form 'altabi.name',
+ which apply to one specific compiler. */
+ return 1;
+ }
+ if(tag == DW_TAG_compile_unit || tag == DW_TAG_partial_unit ||
+ tag == DW_TAG_imported_unit || tag == DW_TAG_type_unit) {
+ return 1;
+ }
+ return 0;
+}
+
+static void
+trim_quotes(const char *val,struct esb_s *es)
+{
+ if(val[0] == '"') {
+ size_t l = strlen(val);
+ if(l > 2 && val[l-1] == '"') {
+ esb_appendn(es,val+1,l-2);
+ return;
+ }
+ }
+ esb_append(es,val);
+}
+
+static int
+have_a_search_match(const char *valname,const char *atname)
+{
+ /* valname may have had quotes inserted, but search_match_text
+ will not. So we need to use a new copy, not valname here.
+ */
+ struct esb_s esb_match;
+ char *s2;
+ esb_constructor(&esb_match);
+
+ trim_quotes(valname,&esb_match);
+ s2 = esb_get_string(&esb_match);
+ if (search_match_text ) {
+ if(!strcmp(s2,search_match_text) ||
+ !strcmp(atname,search_match_text)) {
+
+ esb_destructor(&esb_match);
+ return TRUE;
+ }
+ }
+ if (search_any_text) {
+ if(is_strstrnocase(s2,search_any_text) ||
+ is_strstrnocase(atname,search_any_text)) {
+
+ esb_destructor(&esb_match);
+ return TRUE;
+ }
+ }
+#ifdef HAVE_REGEX
+ if (search_regex_text) {
+ if(!regexec(&search_re,s2,0,NULL,0) ||
+ !regexec(&search_re,atname,0,NULL,0)) {
+
+ esb_destructor(&esb_match);
+ return TRUE;
+ }
+ }
+#endif
+ esb_destructor(&esb_match);
+ return FALSE;
+}
+
+
+static boolean
+print_attribute(Dwarf_Debug dbg, Dwarf_Die die,
+ Dwarf_Half attr,
+ Dwarf_Attribute attr_in,
+ boolean print_information,
+ int die_indent_level,
+ char **srcfiles, Dwarf_Signed cnt)
+{
+ Dwarf_Attribute attrib = 0;
+ Dwarf_Unsigned uval = 0;
+ const char * atname = 0;
+ const char * valname = 0;
+ int tres = 0;
+ Dwarf_Half tag = 0;
+ int append_extra_string = 0;
+ boolean found_search_attr = FALSE;
+ boolean bTextFound = FALSE;
+ Dwarf_Bool is_info = FALSE;
+
+ is_info = dwarf_get_die_infotypes_flag(die);
+ esb_empty_string(&esb_extra);
+ atname = get_AT_name(attr,dwarf_names_print_on_error);
+
+ /* The following gets the real attribute, even in the face of an
+ incorrect doubling, or worse, of attributes. */
+ attrib = attr_in;
+ /* Do not get attr via dwarf_attr: if there are (erroneously)
+ multiple of an attr in a DIE, dwarf_attr will not get the
+ second, erroneous one and dwarfdump will print the first one
+ multiple times. Oops. */
+
+ tres = dwarf_tag(die, &tag, &err);
+ if (tres == DW_DLV_ERROR) {
+ tag = 0;
+ } else if (tres == DW_DLV_NO_ENTRY) {
+ tag = 0;
+ } else {
+ /* ok */
+ }
+ if (check_attr_tag && checking_this_compiler()) {
+ const char *tagname = "<tag invalid>";
+
+ DWARF_CHECK_COUNT(attr_tag_result,1);
+ if (tres == DW_DLV_ERROR) {
+ DWARF_CHECK_ERROR3(attr_tag_result,tagname,
+ get_AT_name(attr,dwarf_names_print_on_error),
+ "check the tag-attr combination, dwarf_tag failed.");
+ } else if (tres == DW_DLV_NO_ENTRY) {
+ DWARF_CHECK_ERROR3(attr_tag_result,tagname,
+ get_AT_name(attr,dwarf_names_print_on_error),
+ "check the tag-attr combination, dwarf_tag NO ENTRY?.");
+ } else if (legal_tag_attr_combination(tag, attr)) {
+ /* OK */
+ } else {
+ tagname = get_TAG_name(tag,dwarf_names_print_on_error);
+ tag_specific_checks_setup(tag,die_stack_indent_level);
+ DWARF_CHECK_ERROR3(attr_tag_result,tagname,
+ get_AT_name(attr,dwarf_names_print_on_error),
+ "check the tag-attr combination");
+ }
+ }
+
+ switch (attr) {
+ case DW_AT_language:
+ get_small_encoding_integer_and_name(dbg, attrib, &uval,
+ "DW_AT_language", &valname,
+ get_LANG_name, &err,
+ show_form_used);
+ break;
+ case DW_AT_accessibility:
+ get_small_encoding_integer_and_name(dbg, attrib, &uval,
+ "DW_AT_accessibility",
+ &valname, get_ACCESS_name,
+ &err,
+ show_form_used);
+ break;
+ case DW_AT_visibility:
+ get_small_encoding_integer_and_name(dbg, attrib, &uval,
+ "DW_AT_visibility",
+ &valname, get_VIS_name,
+ &err,
+ show_form_used);
+ break;
+ case DW_AT_virtuality:
+ get_small_encoding_integer_and_name(dbg, attrib, &uval,
+ "DW_AT_virtuality",
+ &valname,
+ get_VIRTUALITY_name, &err,
+ show_form_used);
+ break;
+ case DW_AT_identifier_case:
+ get_small_encoding_integer_and_name(dbg, attrib, &uval,
+ "DW_AT_identifier",
+ &valname, get_ID_name,
+ &err,
+ show_form_used);
+ break;
+ case DW_AT_inline:
+ get_small_encoding_integer_and_name(dbg, attrib, &uval,
+ "DW_AT_inline", &valname,
+ get_INL_name, &err,
+ show_form_used);
+ break;
+ case DW_AT_encoding:
+ get_small_encoding_integer_and_name(dbg, attrib, &uval,
+ "DW_AT_encoding", &valname,
+ get_ATE_name, &err,
+ show_form_used);
+ break;
+ case DW_AT_ordering:
+ get_small_encoding_integer_and_name(dbg, attrib, &uval,
+ "DW_AT_ordering", &valname,
+ get_ORD_name, &err,
+ show_form_used);
+ break;
+ case DW_AT_calling_convention:
+ get_small_encoding_integer_and_name(dbg, attrib, &uval,
+ "DW_AT_calling_convention",
+ &valname, get_CC_name,
+ &err,
+ show_form_used);
+ break;
+ case DW_AT_discr_list: /* DWARF3 */
+ get_small_encoding_integer_and_name(dbg, attrib, &uval,
+ "DW_AT_discr_list",
+ &valname, get_DSC_name,
+ &err,
+ show_form_used);
+ break;
+ case DW_AT_data_member_location:
+ {
+ /* Value is a constant or a location
+ description or location list.
+ If a constant, it could be signed or
+ unsigned. Telling whether a constant
+ or a reference is nontrivial
+ since DW_FORM_data{4,8}
+ could be either in DWARF{2,3} */
+ enum Dwarf_Form_Class fc = DW_FORM_CLASS_UNKNOWN;
+ Dwarf_Half theform = 0;
+ Dwarf_Half directform = 0;
+ Dwarf_Half version = 0;
+ Dwarf_Half offset_size = 0;
+ int wres = 0;
+
+ get_form_values(attrib,&theform,&directform);
+ wres = dwarf_get_version_of_die(die ,
+ &version,&offset_size);
+ if(wres != DW_DLV_OK) {
+ print_error(dbg,"Cannot get DIE context version number",wres,err);
+ break;
+ }
+ fc = dwarf_get_form_class(version,attr,offset_size,theform);
+ if(fc == DW_FORM_CLASS_CONSTANT) {
+ esb_empty_string(&esb_base);
+ wres = formxdata_print_value(dbg,attrib,&esb_base,
+ &err, FALSE);
+ show_form_itself(show_form_used,verbose, theform,
+ directform,&esb_base);
+ valname = esb_get_string(&esb_base);
+ if(wres == DW_DLV_OK){
+ /* String appended already. */
+ break;
+ } else if (wres == DW_DLV_NO_ENTRY) {
+ print_error(dbg,"Cannot get DW_AT_data_member_location, how can it be NO_ENTRY? ",wres,err);
+ break;
+ } else {
+ print_error(dbg,"Cannot get DW_AT_data_member_location ",wres,err);
+ break;
+ }
+ }
+ /* FALL THRU, this is a
+ a location description, or a reference
+ to one, or a mistake. */
+ }
+ /* FALL THRU to location description */
+ case DW_AT_location:
+ case DW_AT_vtable_elem_location:
+ case DW_AT_string_length:
+ case DW_AT_return_addr:
+ case DW_AT_use_location:
+ case DW_AT_static_link:
+ case DW_AT_frame_base:
+ {
+ /* The value is a location description
+ or location list. */
+
+ Dwarf_Half theform = 0;
+ Dwarf_Half directform = 0;
+ get_form_values(attrib,&theform,&directform);
+ esb_empty_string(&esb_base);
+ if(is_location_form(theform)) {
+ get_location_list(dbg, die, attrib, &esb_base);
+ show_form_itself(show_form_used,verbose,
+ theform, directform,&esb_base);
+ } else if (theform == DW_FORM_exprloc) {
+ int showhextoo = 1;
+ print_exprloc_content(dbg,die,attrib,showhextoo,&esb_base);
+ } else {
+ show_attr_form_error(dbg,attr,theform,&esb_base);
+ }
+ valname = esb_get_string(&esb_base);
+ }
+ break;
+ case DW_AT_SUN_func_offsets:
+ {
+ /* value is a location description or location list */
+ Dwarf_Half theform = 0;
+ Dwarf_Half directform = 0;
+ get_form_values(attrib,&theform,&directform);
+ esb_empty_string(&esb_base);
+ get_FLAG_BLOCK_string(dbg, attrib,&esb_base);
+ show_form_itself(show_form_used,verbose, theform,
+ directform,&esb_base);
+ valname = esb_get_string(&esb_base);
+ }
+ break;
+ case DW_AT_SUN_cf_kind:
+ {
+ Dwarf_Half kind = 0;
+ Dwarf_Unsigned tempud = 0;
+ Dwarf_Error err = 0;
+ int wres = 0;
+ Dwarf_Half theform = 0;
+ Dwarf_Half directform = 0;
+ get_form_values(attrib,&theform,&directform);
+ wres = dwarf_formudata (attrib,&tempud, &err);
+ esb_empty_string(&esb_base);
+ if(wres == DW_DLV_OK) {
+ kind = tempud;
+ esb_append(&esb_base,
+ get_ATCF_name(kind,dwarf_names_print_on_error));
+ } else if (wres == DW_DLV_NO_ENTRY) {
+ esb_append(&esb_base, "?");
+ } else {
+ print_error(dbg,"Cannot get formudata....",wres,err);
+ esb_append(&esb_base, "??");
+ }
+ show_form_itself(show_form_used,verbose, theform,
+ directform,&esb_base);
+ valname = esb_get_string(&esb_base);
+ }
+ break;
+ case DW_AT_upper_bound:
+ {
+ Dwarf_Half theform;
+ int rv;
+ rv = dwarf_whatform(attrib,&theform,&err);
+ /* depending on the form and the attribute, process the form */
+ if(rv == DW_DLV_ERROR) {
+ print_error(dbg, "dwarf_whatform Cannot find attr form",
+ rv, err);
+ } else if (rv == DW_DLV_NO_ENTRY) {
+ break;
+ }
+
+ esb_empty_string(&esb_base);
+ switch (theform) {
+ case DW_FORM_block1: {
+ Dwarf_Half theform = 0;
+ Dwarf_Half directform = 0;
+ get_form_values(attrib,&theform,&directform);
+ get_location_list(dbg, die, attrib, &esb_base);
+ show_form_itself(show_form_used,verbose, theform,
+ directform,&esb_base);
+ valname = esb_get_string(&esb_base);
+ }
+ break;
+ default:
+ get_attr_value(dbg, tag, die,
+ attrib, srcfiles, cnt, &esb_base, show_form_used,verbose);
+ valname = esb_get_string(&esb_base);
+ break;
+ }
+ break;
+ }
+ case DW_AT_low_pc:
+ case DW_AT_high_pc:
+ {
+ Dwarf_Half theform;
+ int rv;
+ rv = dwarf_whatform(attrib,&theform,&err);
+ /* Depending on the form and the attribute,
+ process the form. */
+ if(rv == DW_DLV_ERROR) {
+ print_error(dbg, "dwarf_whatform cannot Find attr form",
+ rv, err);
+ } else if (rv == DW_DLV_NO_ENTRY) {
+ break;
+ }
+ esb_empty_string(&esb_base);
+ if( theform != DW_FORM_addr) {
+ /* New in DWARF4: other forms are not an address
+ but are instead offset from pc.
+ One could test for DWARF4 here before adding
+ this string, but that seems unnecessary as this
+ could not happen with DWARF3 or earlier.
+ A normal consumer would have to add this value to
+ DW_AT_low_pc to get a true pc. */
+ esb_append(&esb_base,"<offset-from-lowpc>");
+ }
+ get_attr_value(dbg, tag, die, attrib, srcfiles, cnt,
+ &esb_base,show_form_used,verbose);
+ valname = esb_get_string(&esb_base);
+
+ /* Update base and high addresses for CU */
+ if (seen_CU && (need_CU_base_address ||
+ need_CU_high_address)) {
+
+ /* Update base address for CU */
+ if (need_CU_base_address && attr == DW_AT_low_pc) {
+ dwarf_formaddr(attrib, &CU_base_address, &err);
+ need_CU_base_address = FALSE;
+ }
+
+ /* Update high address for CU */
+ if (need_CU_high_address && attr == DW_AT_high_pc) {
+ dwarf_formaddr(attrib, &CU_high_address, &err);
+ need_CU_high_address = FALSE;
+ }
+ }
+
+ /* Record the low and high addresses as we have them */
+ if ((check_decl_file || check_ranges ||
+ check_locations) && theform == DW_FORM_addr) {
+ Dwarf_Addr addr = 0;
+ dwarf_formaddr(attrib, &addr, &err);
+ if (attr == DW_AT_low_pc) {
+ lowAddr = addr;
+ bSawLow = TRUE;
+ /* Record the base address of the last seen PU
+ to be used when checking line information */
+ if (seen_PU && !seen_PU_base_address) {
+ seen_PU_base_address = TRUE;
+ PU_base_address = addr;
+ }
+ } else {
+ highAddr = addr;
+ bSawHigh = TRUE;
+ /* Record the high address of the last seen PU
+ to be used when checking line information */
+ if (seen_PU && !seen_PU_high_address) {
+ seen_PU_high_address = TRUE;
+ PU_high_address = addr;
+ }
+ }
+
+ /* We have now both low_pc and high_pc values */
+ if (bSawLow && bSawHigh) {
+
+ /* We need to decide if this PU is
+ valid, as the SN Linker marks a stripped
+ function by setting lowpc to -1;
+ also for discarded comdat, both lowpc
+ and highpc are zero */
+ if (need_PU_valid_code) {
+ need_PU_valid_code = FALSE;
+
+ /* To ignore a PU as invalid code,
+ only consider the lowpc and
+ highpc values associated with the
+ DW_TAG_subprogram; other
+ instances of lowpc and highpc,
+ must be ignore (lexical blocks) */
+ in_valid_code = TRUE;
+ if (IsInvalidCode(lowAddr,highAddr) &&
+ tag == DW_TAG_subprogram) {
+ in_valid_code = FALSE;
+ }
+ }
+
+ /* We have a low_pc/high_pc pair;
+ check if they are valid */
+ if (in_valid_code) {
+ DWARF_CHECK_COUNT(ranges_result,1);
+ if (lowAddr != elf_max_address &&
+ lowAddr > highAddr) {
+ DWARF_CHECK_ERROR(ranges_result,
+ ".debug_info: Incorrect values "
+ "for low_pc/high_pc");
+ if (check_verbose_mode) {
+ printf("Low = 0x%" DW_PR_XZEROS DW_PR_DUx
+ ", High = 0x%" DW_PR_XZEROS DW_PR_DUx "\n",
+ lowAddr,highAddr);
+ }
+ }
+ if (check_decl_file || check_ranges ||
+ check_locations) {
+ AddEntryIntoBucketGroup(pRangesInfo,0,lowAddr,
+ lowAddr,highAddr,NULL,FALSE);
+ }
+ }
+ bSawLow = FALSE;
+ bSawHigh = FALSE;
+ }
+ }
+ }
+ break;
+ case DW_AT_ranges:
+ {
+ Dwarf_Half theform = 0;
+ int rv;
+
+ rv = dwarf_whatform(attrib,&theform,&err);
+ if(rv == DW_DLV_ERROR) {
+ print_error(dbg, "dwarf_whatform cannot find Attr Form",
+ rv, err);
+ } else if (rv == DW_DLV_NO_ENTRY) {
+ break;
+ }
+
+ esb_empty_string(&esb_base);
+ get_attr_value(dbg, tag,die, attrib, srcfiles, cnt, &esb_base,
+ show_form_used,verbose);
+ print_range_attribute(dbg, die, attr,attr_in, theform,
+ dwarf_names_print_on_error,print_information,
+ &append_extra_string);
+ valname = esb_get_string(&esb_base);
+ }
+ break;
+ case DW_AT_MIPS_linkage_name:
+ esb_empty_string(&esb_base);
+ get_attr_value(dbg, tag, die, attrib, srcfiles,
+ cnt, &esb_base, show_form_used,verbose);
+ valname = esb_get_string(&esb_base);
+
+ if (check_locations || check_ranges) {
+ int local_show_form = 0;
+ int local_verbose = 0;
+ struct esb_s lesb;
+ const char *name = 0;
+ esb_constructor(&lesb);
+ get_attr_value(dbg, tag, die, attrib, srcfiles, cnt,
+ &lesb, local_show_form,local_verbose);
+ /* Look for specific name forms, attempting to
+ notice and report 'odd' identifiers. */
+ name = esb_get_string(&lesb);
+ safe_strcpy(PU_name,sizeof(PU_name),name,strlen(name));
+ }
+ break;
+ case DW_AT_name:
+ case DW_AT_GNU_template_name:
+ esb_empty_string(&esb_base);
+ get_attr_value(dbg, tag, die, attrib, srcfiles, cnt,
+ &esb_base, show_form_used,verbose);
+ valname = esb_get_string(&esb_base);
+
+ if (check_names && checking_this_compiler()) {
+ int local_show_form = FALSE;
+ int local_verbose = 0;
+ struct esb_s lesb;
+ const char *name = 0;
+ esb_constructor(&lesb);
+ get_attr_value(dbg, tag, die, attrib, srcfiles, cnt,
+ &lesb, local_show_form,local_verbose);
+ /* Look for specific name forms, attempting to
+ notice and report 'odd' identifiers. */
+ name = esb_get_string(&lesb);
+ DWARF_CHECK_COUNT(names_result,1);
+ if (!strcmp("\"(null)\"",name)) {
+ DWARF_CHECK_ERROR(names_result,
+ "string attribute is \"(null)\".");
+ } else {
+ if (!dot_ok_in_identifier(tag,die,name)
+ && !need_CU_name && strchr(name,'.')) {
+ /* This is a suggestion there 'might' be
+ a surprising name, not a guarantee of an
+ error. */
+ DWARF_CHECK_ERROR(names_result,
+ "string attribute is invalid.");
+ }
+ }
+ esb_destructor(&lesb);
+ }
+
+ /* If we are in checking mode and we do not have a PU name */
+ if ((check_locations || check_ranges) && seen_PU && !PU_name[0]) {
+ int local_show_form = FALSE;
+ int local_verbose = 0;
+ const char *name = 0;
+ struct esb_s lesb;
+ esb_constructor(&lesb);
+ get_attr_value(dbg, tag, die, attrib, srcfiles, cnt,
+ &lesb, local_show_form,local_verbose);
+ name = esb_get_string(&lesb);
+
+ safe_strcpy(PU_name,sizeof(PU_name),name,strlen(name));
+ esb_destructor(&lesb);
+ }
+
+ /* If we are processing the compile unit, record the name */
+ if (seen_CU && need_CU_name) {
+ /* Lets not get the form name included. */
+ struct esb_s lesb;
+ int local_show_form_used = FALSE;
+ int local_verbose = 0;
+ char *localname = 0;
+ esb_constructor(&lesb);
+ get_attr_value(dbg, tag, die, attrib, srcfiles, cnt,
+ &lesb, local_show_form_used,local_verbose);
+ localname = esb_get_string(&lesb);
+ safe_strcpy(CU_name,sizeof(CU_name),localname,strlen(localname));
+ need_CU_name = FALSE;
+ esb_destructor(&lesb);
+ }
+ break;
+
+ case DW_AT_producer:
+ esb_empty_string(&esb_base);
+ get_attr_value(dbg, tag, die, attrib, srcfiles, cnt,
+ &esb_base, show_form_used,verbose);
+ valname = esb_get_string(&esb_base);
+ /* If we are in checking mode, identify the compiler */
+ if (do_check_dwarf || search_is_on) {
+ /* Do not use show-form here! We just want the producer name, not
+ the form name. */
+ int show_form_local = FALSE;
+ int local_verbose = 0;
+ struct esb_s local_e;
+ esb_constructor(&local_e);
+ get_attr_value(dbg, tag, die, attrib, srcfiles, cnt,
+ &local_e, show_form_local,local_verbose);
+ /* Check if this compiler version is a target */
+ update_compiler_target(esb_get_string(&local_e));
+ esb_destructor(&local_e);
+ }
+ break;
+
+
+ /* When dealing with linkonce symbols, the low_pc and high_pc
+ are associated with a specific symbol; SNC always generate a name in
+ the for of DW_AT_MIPS_linkage_name; GCC does not; instead it generates
+ DW_AT_abstract_origin or DW_AT_specification; in that case we have to
+ traverse this attribute in order to get the name for the linkonce */
+ case DW_AT_specification:
+ case DW_AT_abstract_origin:
+ case DW_AT_type:
+ esb_empty_string(&esb_base);
+ get_attr_value(dbg, tag, die, attrib, srcfiles, cnt, &esb_base,
+ show_form_used,verbose);
+ valname = esb_get_string(&esb_base);
+ if (check_forward_decl || check_self_references) {
+ Dwarf_Off die_off = 0;
+ Dwarf_Off ref_off = 0;
+ int res = 0;
+ int suppress_check = 0;
+
+ /* Get the global offset for reference */
+ res = dwarf_global_formref(attrib, &ref_off, &err);
+ if (res != DW_DLV_OK) {
+ int myerr = dwarf_errno(err);
+ if(myerr == DW_DLE_REF_SIG8_NOT_HANDLED) {
+ /* DW_DLE_REF_SIG8_NOT_HANDLED */
+ /* No offset available, it makes little sense
+ to delve into this sort of reference unless
+ we think a graph of self-refs *across*
+ type-units is possible. Hmm. FIXME? */
+ suppress_check = 1 ;
+ dwarf_dealloc(dbg,err,DW_DLA_ERROR);
+ err = 0;
+ } else {
+ print_error(dbg, "dwarf_die_CU_offsetD", res, err);
+ }
+ }
+ res = dwarf_dieoffset(die, &die_off, &err);
+ if (res != DW_DLV_OK) {
+ print_error(dbg, "ref formwith no ref?!", res, err);
+ }
+
+ if (!suppress_check && check_self_references) {
+ Dwarf_Die ref_die = 0;
+
+ ResetBucketGroup(pVisitedInfo);
+ AddEntryIntoBucketGroup(pVisitedInfo,die_off,0,0,0,NULL,FALSE);
+
+ /* Follow reference chain, looking for self references */
+ res = dwarf_offdie_b(dbg,ref_off,is_info,&ref_die,&err);
+ if (res == DW_DLV_OK) {
+ ++die_indent_level;
+ struct esb_s copy_base;
+ if (dump_visited_info) {
+ Dwarf_Off off;
+ dwarf_die_CU_offset(die, &off, &err);
+ printf("<%2d><0x%" DW_PR_XZEROS DW_PR_DUx
+ " GOFF=0x%" DW_PR_XZEROS DW_PR_DUx "> ",
+ die_indent_level, (Dwarf_Unsigned)off,
+ (Dwarf_Unsigned)die_off);
+ printf("%*s%s -> %s\n",die_indent_level * 2 + 2,
+ " ",atname,valname);
+ }
+ /* Because esb_base is global, lets not
+ let the traversal trash what we have here. */
+ esb_constructor(&copy_base);
+ esb_append(&copy_base,esb_get_string(&esb_base));
+ esb_empty_string(&esb_base);
+ traverse_one_die(dbg,attrib,ref_die,srcfiles,cnt,die_indent_level);
+ esb_empty_string(&esb_base);
+ esb_append(&esb_base,esb_get_string(&copy_base));
+ esb_destructor(&copy_base);
+ dwarf_dealloc(dbg,ref_die,DW_DLA_DIE);
+ ref_die = 0;
+ --die_indent_level;
+ }
+ DeleteKeyInBucketGroup(pVisitedInfo,die_off);
+ }
+
+ if (!suppress_check && check_forward_decl) {
+ if (attr == DW_AT_specification) {
+ /* Check the DW_AT_specification does not make forward
+ references to DIEs.
+ DWARF4 specifications, section 2.13.2,
+ but really they are legal,
+ this test is probably wrong. */
+ DWARF_CHECK_COUNT(forward_decl_result,1);
+ if (ref_off > die_off) {
+ DWARF_CHECK_ERROR2(forward_decl_result,
+ "Invalid forward reference to DIE: ",valname);
+ }
+ }
+ }
+ }
+ /* If we are in checking mode and we do not have a PU name */
+ if ((check_locations || check_ranges) && seen_PU && !PU_name[0]) {
+ if (tag == DW_TAG_subprogram) {
+ /* This gets the DW_AT_name if this DIE has one. */
+ Dwarf_Addr low_pc = 0;
+ static char proc_name[BUFSIZ];
+ proc_name[0] = 0;
+ get_proc_name(dbg,die,low_pc,proc_name,BUFSIZ,/*pcMap=*/0);
+ if (proc_name[0]) {
+ safe_strcpy(PU_name,sizeof(PU_name),proc_name,
+ strlen(proc_name));
+ }
+ }
+ }
+ break;
+ default:
+ esb_empty_string(&esb_base);
+ get_attr_value(dbg, tag,die, attrib, srcfiles, cnt, &esb_base,
+ show_form_used,verbose);
+ valname = esb_get_string(&esb_base);
+ break;
+ }
+ if (!print_information) {
+ if(have_a_search_match(valname,atname) )
+ {
+ if (search_wide_format) {
+ found_search_attr = TRUE;
+ } else {
+ PRINT_CU_INFO();
+ bTextFound = TRUE;
+ }
+ }
+ }
+ if ((PRINTING_DIES && print_information) || bTextFound) {
+ /* Print just the Tags and Attributes */
+ if (!display_offsets) {
+ printf("%-28s\n",atname);
+ } else {
+ if (dense) {
+ printf(" %s<%s>", atname, valname);
+ if(append_extra_string) {
+ char *v = esb_get_string(&esb_extra);
+ printf("%s", v);
+ }
+ } else {
+ printf("%-28s%s\n", atname, valname);
+ if( append_extra_string) {
+ char *v = esb_get_string(&esb_extra);
+ printf("%s", v);
+ }
+ }
+ }
+ /* Due to redirection of stderr */
+ fflush(stdout);
+ bTextFound = FALSE;
+ }
+ return found_search_attr;
+}
+
+
+int
+dwarfdump_print_one_locdesc(Dwarf_Debug dbg,
+ Dwarf_Locdesc * llbuf,
+ int skip_locdesc_header,
+ struct esb_s *string_out)
+{
+
+ Dwarf_Locdesc *locd = 0;
+ Dwarf_Half no_of_ops = 0;
+ int i = 0;
+ char small_buf[100];
+
+ if (!skip_locdesc_header && (verbose || llbuf->ld_from_loclist)) {
+ snprintf(small_buf, sizeof(small_buf),
+ "<lowpc=0x%" DW_PR_XZEROS DW_PR_DUx ">",
+ (Dwarf_Unsigned) llbuf->ld_lopc);
+ esb_append(string_out, small_buf);
+
+
+ snprintf(small_buf, sizeof(small_buf),
+ "<highpc=0x%" DW_PR_XZEROS DW_PR_DUx ">",
+ (Dwarf_Unsigned) llbuf->ld_hipc);
+ esb_append(string_out, small_buf);
+ if (display_offsets && verbose) {
+ snprintf(small_buf, sizeof(small_buf),
+ "<from %s offset 0x%" DW_PR_XZEROS DW_PR_DUx ">",
+ llbuf->ld_from_loclist ? ".debug_loc" : ".debug_info",
+ llbuf->ld_section_offset);
+ esb_append(string_out, small_buf);
+ }
+ }
+
+ locd = llbuf;
+ no_of_ops = llbuf->ld_cents;
+ for (i = 0; i < no_of_ops; i++) {
+ Dwarf_Loc * op = &locd->ld_s[i];
+
+ int res = _dwarf_print_one_expr_op(dbg,op,i,string_out);
+ if(res == DW_DLV_ERROR) {
+ return res;
+ }
+ }
+ return DW_DLV_OK;
+}
+
+
+
+static int
+op_has_no_operands(int op)
+{
+ unsigned i = 0;
+ if(op >= DW_OP_lit0 && op <= DW_OP_reg31) {
+ return TRUE;
+ }
+ for( ; ; ++i) {
+ struct operation_descr_s *odp = opdesc+i;
+ if(odp->op_code == 0) {
+ break;
+ }
+ if(odp->op_code != op) {
+ continue;
+ }
+ if (odp->op_count == 0) {
+ return TRUE;
+ }
+ return FALSE;
+ }
+ return FALSE;
+}
+
+int
+_dwarf_print_one_expr_op(Dwarf_Debug dbg,Dwarf_Loc* expr,int index,
+ struct esb_s *string_out)
+{
+ /* local_space_needed is intended to be 'more than big enough'
+ for a short group of loclist entries. */
+ char small_buf[100];
+ Dwarf_Small op;
+ Dwarf_Unsigned opd1;
+ Dwarf_Unsigned opd2;
+ const char * op_name;
+
+ if (index > 0) {
+ esb_append(string_out, " ");
+ }
+
+ op = expr->lr_atom;
+
+ /* We have valid operands whose values are bigger than the
+ DW_OP_nop = 0x96; for example: DW_OP_GNU_push_tls_address = 0xe0
+ Also, the function 'get_OP_name' handles this case, generating a
+ name 'Unknown OP value'. */
+ if (op > DW_OP_hi_user) {
+ print_error(dbg, "dwarf_op unexpected value!", DW_DLV_OK,
+ err);
+ return DW_DLV_ERROR;
+ }
+ op_name = get_OP_name(op,dwarf_names_print_on_error);
+ esb_append(string_out, op_name);
+
+ opd1 = expr->lr_number;
+ if(op_has_no_operands(op)) {
+ /* Nothing to add. */
+ } else if (op >= DW_OP_breg0 && op <= DW_OP_breg31) {
+ snprintf(small_buf, sizeof(small_buf),
+ "%+" DW_PR_DSd , (Dwarf_Signed) opd1);
+ esb_append(string_out, small_buf);
+ } else {
+ switch (op) {
+ case DW_OP_addr:
+ snprintf(small_buf, sizeof(small_buf),
+ " 0x%" DW_PR_XZEROS DW_PR_DUx , opd1);
+ esb_append(string_out, small_buf);
+ break;
+ case DW_OP_const1s:
+ case DW_OP_const2s:
+ case DW_OP_const4s:
+ case DW_OP_const8s:
+ case DW_OP_consts:
+ case DW_OP_skip:
+ case DW_OP_bra:
+ case DW_OP_fbreg:
+ snprintf(small_buf, sizeof(small_buf),
+ " %" DW_PR_DSd, (Dwarf_Signed) opd1);
+ esb_append(string_out, small_buf);
+ break;
+ case DW_OP_const1u:
+ case DW_OP_const2u:
+ case DW_OP_const4u:
+ case DW_OP_const8u:
+ case DW_OP_constu:
+ case DW_OP_pick:
+ case DW_OP_plus_uconst:
+ case DW_OP_regx:
+ case DW_OP_piece:
+ case DW_OP_deref_size:
+ case DW_OP_xderef_size:
+ snprintf(small_buf, sizeof(small_buf),
+ " %" DW_PR_DUu , opd1);
+ esb_append(string_out, small_buf);
+ break;
+ case DW_OP_bregx:
+ snprintf(small_buf, sizeof(small_buf),
+ "0x%08" DW_PR_DUx , opd1);
+ esb_append(string_out, small_buf);
+ opd2 = expr->lr_number2;
+ snprintf(small_buf, sizeof(small_buf),
+ "+%" DW_PR_DSd , (Dwarf_Signed) opd2);
+ esb_append(string_out, small_buf);
+ break;
+ case DW_OP_call2:
+ snprintf(small_buf, sizeof(small_buf),
+ " 0x%" DW_PR_XZEROS DW_PR_DUx , opd1);
+ esb_append(string_out, small_buf);
+ break;
+ case DW_OP_call4:
+ snprintf(small_buf, sizeof(small_buf),
+ " 0x%" DW_PR_XZEROS DW_PR_DUx , opd1);
+ esb_append(string_out, small_buf);
+ break;
+ case DW_OP_call_ref:
+ snprintf(small_buf, sizeof(small_buf),
+ " 0x%" DW_PR_XZEROS DW_PR_DUx , opd1);
+ esb_append(string_out, small_buf);
+ break;
+ case DW_OP_bit_piece:
+ snprintf(small_buf, sizeof(small_buf),
+ " 0x%" DW_PR_XZEROS DW_PR_DUx , opd1);
+ esb_append(string_out, small_buf);
+ opd2 = expr->lr_number2;
+ snprintf(small_buf, sizeof(small_buf),
+ " offset 0x%" DW_PR_DUx , (Dwarf_Signed) opd2);
+ esb_append(string_out, small_buf);
+ break;
+ case DW_OP_implicit_value:
+ {
+#define IMPLICIT_VALUE_PRINT_MAX 12
+ unsigned int print_len = 0;
+ snprintf(small_buf, sizeof(small_buf),
+ " 0x%" DW_PR_XZEROS DW_PR_DUx , opd1);
+ esb_append(string_out, small_buf);
+ /* The other operand is a block of opd1 bytes. */
+ /* FIXME */
+ print_len = opd1;
+ if(print_len > IMPLICIT_VALUE_PRINT_MAX) {
+ print_len = IMPLICIT_VALUE_PRINT_MAX;
+ }
+#undef IMPLICIT_VALUE_PRINT_MAX
+ if(print_len > 0) {
+ const unsigned char *bp = 0;
+ unsigned int i = 0;
+ opd2 = expr->lr_number2;
+ /* This is a really ugly cast, a way
+ to implement DW_OP_implicit value in
+ this libdwarf context. */
+ bp = (const unsigned char *) opd2;
+ esb_append(string_out," contents 0x");
+ for( ; i < print_len; ++i,++bp) {
+ /* Do not use DW_PR_DUx here,
+ the value *bp is a const unsigned char. */
+ snprintf(small_buf, sizeof(small_buf),
+ "%02x", *bp);
+ esb_append(string_out,small_buf);
+ }
+ }
+ }
+ break;
+
+ /* We do not know what the operands, if any, are. */
+ case DW_OP_HP_unknown:
+ case DW_OP_HP_is_value:
+ case DW_OP_HP_fltconst4:
+ case DW_OP_HP_fltconst8:
+ case DW_OP_HP_mod_range:
+ case DW_OP_HP_unmod_range:
+ case DW_OP_HP_tls:
+ case DW_OP_INTEL_bit_piece:
+ break;
+ case DW_OP_stack_value: /* DWARF4 */
+ break;
+ case DW_OP_GNU_uninit: /* DW_OP_APPLE_uninit */
+ /* No operands. */
+ break;
+ case DW_OP_GNU_encoded_addr:
+ snprintf(small_buf, sizeof(small_buf),
+ " 0x%" DW_PR_XZEROS DW_PR_DUx , opd1);
+ esb_append(string_out, small_buf);
+ break;
+ case DW_OP_GNU_implicit_pointer:
+ snprintf(small_buf, sizeof(small_buf),
+ " 0x%" DW_PR_XZEROS DW_PR_DUx , opd1);
+ esb_append(string_out, small_buf);
+ break;
+ case DW_OP_GNU_entry_value:
+ snprintf(small_buf, sizeof(small_buf),
+ " 0x%" DW_PR_XZEROS DW_PR_DUx , opd1);
+ esb_append(string_out, small_buf);
+ break;
+ default:
+ {
+ snprintf(small_buf, sizeof(small_buf),
+ " dwarf_op unknown 0x%x", (unsigned)op);
+ esb_append(string_out,small_buf);
+ }
+ break;
+ }
+ }
+ return DW_DLV_OK;
+}
+
+/* Fill buffer with location lists
+ Buffer esbp expands as needed.
+*/
+/*ARGSUSED*/ static void
+get_location_list(Dwarf_Debug dbg, Dwarf_Die die, Dwarf_Attribute attr,
+ struct esb_s *esbp)
+{
+ Dwarf_Locdesc *llbuf = 0;
+ Dwarf_Locdesc **llbufarray = 0;
+ Dwarf_Signed no_of_elements;
+ Dwarf_Error err;
+ int i;
+ int lres = 0;
+ int llent = 0;
+ int skip_locdesc_header = 0;
+
+ /* Base address used to update entries in .debug_loc */
+ Dwarf_Addr base_address = CU_base_address;
+ Dwarf_Addr lopc = 0;
+ Dwarf_Addr hipc = 0;
+ Dwarf_Bool bError = FALSE;
+
+ if (use_old_dwarf_loclist) {
+ lres = dwarf_loclist(attr, &llbuf, &no_of_elements, &err);
+ if (lres == DW_DLV_ERROR) {
+ print_error(dbg, "dwarf_loclist", lres, err);
+ } else if (lres == DW_DLV_NO_ENTRY) {
+ return;
+ }
+ dwarfdump_print_one_locdesc(dbg, llbuf,skip_locdesc_header,esbp);
+ dwarf_dealloc(dbg, llbuf->ld_s, DW_DLA_LOC_BLOCK);
+ dwarf_dealloc(dbg, llbuf, DW_DLA_LOCDESC);
+ return;
+ }
+
+ lres = dwarf_loclist_n(attr, &llbufarray, &no_of_elements, &err);
+ if (lres == DW_DLV_ERROR) {
+ print_error(dbg, "dwarf_loclist", lres, err);
+ } else if (lres == DW_DLV_NO_ENTRY) {
+ return;
+ }
+ for (llent = 0; llent < no_of_elements; ++llent) {
+ char small_buf[100];
+ Dwarf_Off offset = 0;
+
+ llbuf = llbufarray[llent];
+ /* If we have a location list refering to the .debug_loc
+ Check for specific compiler we are validating. */
+ if (check_locations && in_valid_code &&
+ llbuf->ld_from_loclist && checking_this_compiler()) {
+ /* To calculate the offset, we use:
+ sizeof(Dwarf_Half) -> number of expression list
+ 2 * address_size -> low_pc and high_pc */
+ offset = llbuf->ld_section_offset -
+ llbuf->ld_cents * sizeof(Dwarf_Half) -
+ 2 * elf_address_size;
+
+ if (llbuf->ld_lopc == elf_max_address) {
+ /* (0xffffffff,addr), use specific address
+ (current PU address) */
+ base_address = llbuf->ld_hipc;
+ } else {
+ /* (offset,offset), update using CU address */
+ lopc = llbuf->ld_lopc + base_address;
+ hipc = llbuf->ld_hipc + base_address;
+
+ DWARF_CHECK_COUNT(locations_result,1);
+
+ /* Check the low_pc and high_pc are within
+ a valid range in the .text section */
+ if (IsValidInBucketGroup(pRangesInfo,lopc) &&
+ IsValidInBucketGroup(pRangesInfo,hipc)) {
+ /* Valid values; do nothing */
+ } else {
+ /* At this point may be we are dealing with
+ a linkonce symbol */
+ if (IsValidInLinkonce(pLinkonceInfo,PU_name,
+ lopc,hipc)) {
+ /* Valid values; do nothing */
+ } else {
+ bError = TRUE;
+ DWARF_CHECK_ERROR(locations_result,
+ ".debug_loc: Address outside a "
+ "valid .text range");
+ if (check_verbose_mode) {
+ printf(
+ "Offset = 0x%" DW_PR_XZEROS DW_PR_DUx
+ ", Base = 0x%" DW_PR_XZEROS DW_PR_DUx ", "
+ "Low = 0x%" DW_PR_XZEROS DW_PR_DUx
+ " (0x%" DW_PR_XZEROS DW_PR_DUx
+ "), High = 0x%" DW_PR_XZEROS DW_PR_DUx
+ " (0x%" DW_PR_XZEROS DW_PR_DUx ")\n",
+ offset,base_address,lopc,
+ llbuf->ld_lopc,
+ hipc,
+ llbuf->ld_hipc);
+ }
+ }
+ }
+ }
+ }
+
+ if (!dense && llbuf->ld_from_loclist) {
+ if (llent == 0) {
+ snprintf(small_buf, sizeof(small_buf),
+ "<loclist with %ld entries follows>",
+ (long) no_of_elements);
+ esb_append(esbp, small_buf);
+ }
+ esb_append(esbp, "\n\t\t\t");
+ snprintf(small_buf, sizeof(small_buf), "[%2d]", llent);
+ esb_append(esbp, small_buf);
+ }
+ lres = dwarfdump_print_one_locdesc(dbg,
+ llbuf,
+ skip_locdesc_header,
+ esbp);
+ if (lres == DW_DLV_ERROR) {
+ return;
+ } else {
+ /* DW_DLV_OK so we add follow-on at end, else is
+ DW_DLV_NO_ENTRY (which is impossible, treat like
+ DW_DLV_OK). */
+ }
+ }
+
+ if (bError && check_verbose_mode) {
+ printf("\n");
+ }
+
+ for (i = 0; i < no_of_elements; ++i) {
+ dwarf_dealloc(dbg, llbufarray[i]->ld_s, DW_DLA_LOC_BLOCK);
+ dwarf_dealloc(dbg, llbufarray[i], DW_DLA_LOCDESC);
+ }
+ dwarf_dealloc(dbg, llbufarray, DW_DLA_LIST);
+}
+
+static void
+formx_unsigned(Dwarf_Unsigned u, struct esb_s *esbp, Dwarf_Bool hex_format)
+{
+ char small_buf[40];
+ if (hex_format) {
+ snprintf(small_buf, sizeof(small_buf),"0x%" DW_PR_XZEROS DW_PR_DUx , u);
+ } else {
+ snprintf(small_buf, sizeof(small_buf),
+ "%" DW_PR_DUu , u);
+ }
+ esb_append(esbp, small_buf);
+}
+static void
+formx_signed(Dwarf_Signed u, struct esb_s *esbp)
+{
+ char small_buf[40];
+ snprintf(small_buf, sizeof(small_buf),
+ "%" DW_PR_DSd , u);
+ esb_append(esbp, small_buf);
+}
+/* We think this is an integer. Figure out how to print it.
+ In case the signedness is ambiguous (such as on
+ DW_FORM_data1 (ie, unknown signedness) print two ways.
+*/
+static int
+formxdata_print_value(Dwarf_Debug dbg,Dwarf_Attribute attrib,
+ struct esb_s *esbp,
+ Dwarf_Error * err, Dwarf_Bool hex_format)
+{
+ Dwarf_Signed tempsd = 0;
+ Dwarf_Unsigned tempud = 0;
+ int sres = 0;
+ int ures = 0;
+ Dwarf_Error serr = 0;
+
+ ures = dwarf_formudata(attrib, &tempud, err);
+ sres = dwarf_formsdata(attrib, &tempsd, &serr);
+ if(ures == DW_DLV_OK) {
+ if(sres == DW_DLV_OK) {
+ if(tempud == tempsd && tempsd >= 0) {
+ /* Data is the same value and not negative,
+ so makes no difference which
+ we print. */
+ formx_unsigned(tempud,esbp,hex_format);
+ } else {
+ formx_unsigned(tempud,esbp,hex_format);
+ esb_append(esbp,"(as signed = ");
+ formx_signed(tempsd,esbp);
+ esb_append(esbp,")");
+ }
+ } else if (sres == DW_DLV_NO_ENTRY) {
+ formx_unsigned(tempud,esbp,hex_format);
+ } else /* DW_DLV_ERROR */{
+ formx_unsigned(tempud,esbp,hex_format);
+ }
+ goto cleanup;
+ } else {
+ /* ures == DW_DLV_ERROR or DW_DLV_NO_ENTRY*/
+ if(sres == DW_DLV_OK) {
+ formx_signed(tempsd,esbp);
+ } else {
+ /* Neither worked. */
+ }
+ }
+ /* Clean up any unused Dwarf_Error data.
+ DW_DLV_NO_ENTRY cannot really happen,
+ so a complete cleanup for that is
+ not necessary. */
+ cleanup:
+ if(sres == DW_DLV_OK || ures == DW_DLV_OK) {
+ if(sres == DW_DLV_ERROR) {
+ dwarf_dealloc(dbg,serr,DW_DLA_ERROR);
+ }
+ if(ures == DW_DLV_ERROR) {
+ dwarf_dealloc(dbg,*err,DW_DLA_ERROR);
+ *err = 0;
+ }
+ return DW_DLV_OK;
+ }
+ if(sres == DW_DLV_ERROR || ures == DW_DLV_ERROR) {
+ if(sres == DW_DLV_ERROR && ures == DW_DLV_ERROR) {
+ dwarf_dealloc(dbg,serr,DW_DLA_ERROR);
+ return DW_DLV_ERROR;
+ }
+ if(sres == DW_DLV_ERROR) {
+ *err = serr;
+ }
+ return DW_DLV_ERROR;
+ }
+ /* Both are DW_DLV_NO_ENTRY which is crazy, impossible. */
+ return DW_DLV_NO_ENTRY;
+}
+
+static char *
+get_form_number_as_string(int form, char *buf, unsigned bufsize)
+{
+ snprintf(buf,bufsize," %d",form);
+ return buf;
+}
+
+static void
+print_exprloc_content(Dwarf_Debug dbg,Dwarf_Die die, Dwarf_Attribute attrib,
+ int showhextoo, struct esb_s *esbp)
+{
+ Dwarf_Ptr x = 0;
+ Dwarf_Unsigned tempud = 0;
+ char small_buf[80];
+ Dwarf_Error err = 0;
+ int wres = 0;
+ wres = dwarf_formexprloc(attrib,&tempud,&x,&err);
+ if(wres == DW_DLV_NO_ENTRY) {
+ /* Show nothing? Impossible. */
+ } else if(wres == DW_DLV_ERROR) {
+ print_error(dbg, "Cannot get a DW_FORM_exprbloc....", wres, err);
+ } else {
+ Dwarf_Half address_size = 0;
+ int ares = 0;
+ unsigned u = 0;
+ snprintf(small_buf, sizeof(small_buf),
+ "len 0x%04" DW_PR_DUx ": ",tempud);
+ esb_append(esbp, small_buf);
+ if(showhextoo) {
+ for (u = 0; u < tempud; u++) {
+ snprintf(small_buf, sizeof(small_buf), "%02x",
+ *(u + (unsigned char *) x));
+ esb_append(esbp, small_buf);
+ }
+ esb_append(esbp,": ");
+ }
+ address_size = 0;
+ ares = dwarf_get_die_address_size(die,&address_size,&err);
+ if(wres == DW_DLV_NO_ENTRY) {
+ print_error(dbg,"Cannot get die address size for exprloc",
+ ares,err);
+ } else if(wres == DW_DLV_ERROR) {
+ print_error(dbg,"Cannot Get die address size for exprloc",
+ ares,err);
+ } else {
+ get_string_from_locs(dbg,x,tempud,address_size, esbp);
+ }
+ }
+}
+
+
+
+
+/* Fill buffer with attribute value.
+ We pass in tag so we can try to do the right thing with
+ broken compiler DW_TAG_enumerator
+
+ We append to esbp's buffer.
+*/
+void
+get_attr_value(Dwarf_Debug dbg, Dwarf_Half tag,
+ Dwarf_Die die, Dwarf_Attribute attrib,
+ char **srcfiles, Dwarf_Signed cnt, struct esb_s *esbp,
+ int show_form,
+ int local_verbose)
+{
+ Dwarf_Half theform = 0;
+ char * temps = 0;
+ Dwarf_Block *tempb = 0;
+ Dwarf_Signed tempsd = 0;
+ Dwarf_Unsigned tempud = 0;
+ int i = 0;
+ Dwarf_Half attr = 0;
+ Dwarf_Off off = 0;
+ Dwarf_Off goff = 0; /* Global offset */
+ Dwarf_Die die_for_check = 0;
+ Dwarf_Half tag_for_check = 0;
+ Dwarf_Bool tempbool = 0;
+ Dwarf_Addr addr = 0;
+ int fres = 0;
+ int bres = 0;
+ int wres = 0;
+ int dres = 0;
+ Dwarf_Half direct_form = 0;
+ char small_buf[COMPILE_UNIT_NAME_LEN]; /* Size to hold a filename */
+ Dwarf_Bool is_info = TRUE;
+
+
+ is_info = dwarf_get_die_infotypes_flag(die);
+ /* Dwarf_whatform gets the real form, DW_FORM_indir is
+ never returned: instead the real form following
+ DW_FORM_indir is returned. */
+ fres = dwarf_whatform(attrib, &theform, &err);
+ /* Depending on the form and the attribute, process the form. */
+ if (fres == DW_DLV_ERROR) {
+ print_error(dbg, "dwarf_whatform cannot Find Attr Form", fres,
+ err);
+ } else if (fres == DW_DLV_NO_ENTRY) {
+ return;
+ }
+
+ /* dwarf_whatform_direct gets the 'direct' form, so if
+ the form is DW_FORM_indir that is what is returned. */
+ dwarf_whatform_direct(attrib, &direct_form, &err);
+ /* Ignore errors in dwarf_whatform_direct() */
+
+
+ switch (theform) {
+ case DW_FORM_addr:
+ bres = dwarf_formaddr(attrib, &addr, &err);
+ if (bres == DW_DLV_OK) {
+ snprintf(small_buf, sizeof(small_buf),
+ "0x%" DW_PR_XZEROS DW_PR_DUx ,
+ (Dwarf_Unsigned) addr);
+ esb_append(esbp, small_buf);
+ } else {
+ print_error(dbg, "addr formwith no addr?!", bres, err);
+ }
+ break;
+ case DW_FORM_ref_addr:
+ /* DW_FORM_ref_addr is not accessed thru formref: ** it is an
+ address (global section offset) in ** the .debug_info
+ section. */
+ bres = dwarf_global_formref(attrib, &off, &err);
+ if (bres == DW_DLV_OK) {
+ snprintf(small_buf, sizeof(small_buf),
+ "<global die offset 0x%" DW_PR_XZEROS DW_PR_DUx
+ ">",
+ (Dwarf_Unsigned) off);
+ esb_append(esbp, small_buf);
+ } else {
+ print_error(dbg,
+ "DW_FORM_ref_addr form with no reference?!",
+ bres, err);
+ }
+ wres = dwarf_whatattr(attrib, &attr, &err);
+ if (wres == DW_DLV_ERROR) {
+ } else if (wres == DW_DLV_NO_ENTRY) {
+ } else {
+ if (attr == DW_AT_sibling) {
+ /* The value had better be inside the current CU
+ else there is a nasty error here, as a sibling
+ has to be in the same CU, it seems. */
+ Dwarf_Off cuoff = 0;
+ Dwarf_Off culen = 0;
+ int res = dwarf_die_CU_offset_range(die,&cuoff,
+ &culen,&err);
+ DWARF_CHECK_COUNT(tag_tree_result,1);
+ if(res != DW_DLV_OK) {
+ } else {
+ Dwarf_Off cuend = cuoff+culen;
+ if(off < cuoff || off >= cuend) {
+ DWARF_CHECK_ERROR(tag_tree_result,
+ "DW_AT_sibling DW_FORM_ref_addr offset points "
+ "outside of current CU");
+ }
+ }
+ }
+ }
+
+ break;
+ case DW_FORM_ref1:
+ case DW_FORM_ref2:
+ case DW_FORM_ref4:
+ case DW_FORM_ref8:
+ case DW_FORM_ref_udata:
+ bres = dwarf_formref(attrib, &off, &err);
+ if (bres != DW_DLV_OK) {
+ /* Report incorrect offset */
+ snprintf(small_buf,sizeof(small_buf),
+ "%s, offset=<0x%" DW_PR_XZEROS DW_PR_DUx
+ ">","reference form with no valid local ref?!",off);
+ print_error(dbg, small_buf, bres, err);
+ }
+
+ /* Convert the local offset into a relative section offset */
+ if (show_global_offsets) {
+ bres = dwarf_convert_to_global_offset(attrib,
+ off, &goff, &err);
+ if (bres != DW_DLV_OK) {
+ /* Report incorrect offset */
+ snprintf(small_buf,sizeof(small_buf),
+ "%s, global die offset=<0x%" DW_PR_XZEROS DW_PR_DUx
+ ">","invalid offset",goff);
+ print_error(dbg, small_buf, bres, err);
+ }
+ }
+
+ /* Do references inside <> to distinguish them ** from
+ constants. In dense form this results in <<>>. Ugly for
+ dense form, but better than ambiguous. davea 9/94 */
+ if (show_global_offsets) {
+ snprintf(small_buf, sizeof(small_buf),
+ "<0x%" DW_PR_XZEROS DW_PR_DUx " GOFF=0x%" DW_PR_XZEROS DW_PR_DUx ">",
+ (Dwarf_Unsigned)off, goff);
+ } else {
+ snprintf(small_buf, sizeof(small_buf),
+ "<0x%" DW_PR_XZEROS DW_PR_DUx ">", off);
+ }
+
+ esb_append(esbp, small_buf);
+ if (check_type_offset) {
+ attr = 0;
+ wres = dwarf_whatattr(attrib, &attr, &err);
+ if (wres == DW_DLV_ERROR) {
+
+ } else if (wres == DW_DLV_NO_ENTRY) {
+ }
+ if (attr == DW_AT_type) {
+ dres = dwarf_offdie_b(dbg, cu_offset + off,
+ is_info,
+ &die_for_check, &err);
+ DWARF_CHECK_COUNT(type_offset_result,1);
+ if (dres != DW_DLV_OK) {
+ snprintf(small_buf,sizeof(small_buf),
+ "DW_AT_type offset does not point to a DIE for global offset 0x%" DW_PR_DUx " cu off 0x%" DW_PR_DUx " local offset 0x%" DW_PR_DUx,
+ cu_offset + off,cu_offset,off);
+ DWARF_CHECK_ERROR(type_offset_result,small_buf);
+ } else {
+ int tres2 =
+ dwarf_tag(die_for_check, &tag_for_check, &err);
+ if (tres2 == DW_DLV_OK) {
+ switch (tag_for_check) {
+ case DW_TAG_array_type:
+ case DW_TAG_class_type:
+ case DW_TAG_enumeration_type:
+ case DW_TAG_pointer_type:
+ case DW_TAG_reference_type:
+ case DW_TAG_string_type:
+ case DW_TAG_structure_type:
+ case DW_TAG_subroutine_type:
+ case DW_TAG_typedef:
+ case DW_TAG_union_type:
+ case DW_TAG_ptr_to_member_type:
+ case DW_TAG_set_type:
+ case DW_TAG_subrange_type:
+ case DW_TAG_base_type:
+ case DW_TAG_const_type:
+ case DW_TAG_file_type:
+ case DW_TAG_packed_type:
+ case DW_TAG_thrown_type:
+ case DW_TAG_volatile_type:
+ case DW_TAG_template_type_parameter:
+ case DW_TAG_template_value_parameter:
+ case DW_TAG_unspecified_type:
+ /* OK */
+ break;
+ default:
+ {
+ snprintf(small_buf,sizeof(small_buf),
+ "DW_AT_type offset does not point to Type info we got tag 0x%x %s",
+ tag_for_check,
+ get_TAG_name(tag_for_check,
+ dwarf_names_print_on_error));
+ DWARF_CHECK_ERROR(type_offset_result,small_buf);
+ }
+ break;
+ }
+ dwarf_dealloc(dbg, die_for_check, DW_DLA_DIE);
+ die_for_check = 0;
+ } else {
+ DWARF_CHECK_ERROR(type_offset_result,
+ "DW_AT_type offset does not exist");
+ }
+ }
+ }
+ }
+ break;
+ case DW_FORM_block:
+ case DW_FORM_block1:
+ case DW_FORM_block2:
+ case DW_FORM_block4:
+ fres = dwarf_formblock(attrib, &tempb, &err);
+ if (fres == DW_DLV_OK) {
+ for (i = 0; i < tempb->bl_len; i++) {
+ snprintf(small_buf, sizeof(small_buf), "%02x",
+ *(i + (unsigned char *) tempb->bl_data));
+ esb_append(esbp, small_buf);
+ }
+ dwarf_dealloc(dbg, tempb, DW_DLA_BLOCK);
+ tempb = 0;
+ } else {
+ print_error(dbg, "DW_FORM_blockn cannot get block\n", fres,
+ err);
+ }
+ break;
+ case DW_FORM_data1:
+ case DW_FORM_data2:
+ case DW_FORM_data4:
+ case DW_FORM_data8:
+ fres = dwarf_whatattr(attrib, &attr, &err);
+ if (fres == DW_DLV_ERROR) {
+ print_error(dbg, "FORM_datan cannot get attr", fres, err);
+ } else if (fres == DW_DLV_NO_ENTRY) {
+ print_error(dbg, "FORM_datan cannot get attr", fres, err);
+ } else {
+ switch (attr) {
+ case DW_AT_ordering:
+ case DW_AT_byte_size:
+ case DW_AT_bit_offset:
+ case DW_AT_bit_size:
+ case DW_AT_inline:
+ case DW_AT_language:
+ case DW_AT_visibility:
+ case DW_AT_virtuality:
+ case DW_AT_accessibility:
+ case DW_AT_address_class:
+ case DW_AT_calling_convention:
+ case DW_AT_discr_list: /* DWARF3 */
+ case DW_AT_encoding:
+ case DW_AT_identifier_case:
+ case DW_AT_MIPS_loop_unroll_factor:
+ case DW_AT_MIPS_software_pipeline_depth:
+ case DW_AT_decl_column:
+ case DW_AT_decl_file:
+ case DW_AT_decl_line:
+ case DW_AT_call_column:
+ case DW_AT_call_file:
+ case DW_AT_call_line:
+ case DW_AT_start_scope:
+ case DW_AT_byte_stride:
+ case DW_AT_bit_stride:
+ case DW_AT_count:
+ case DW_AT_stmt_list:
+ case DW_AT_MIPS_fde:
+ { int show_form_here = 0;
+ wres = get_small_encoding_integer_and_name(dbg,
+ attrib,
+ &tempud,
+ /* attrname */ (char *) NULL,
+ /* err_string */ (const char **) NULL,
+ (encoding_type_func) 0,
+ &err,show_form_here);
+
+ if (wres == DW_DLV_OK) {
+ snprintf(small_buf, sizeof(small_buf),
+ "0x%08" DW_PR_DUx ,
+ tempud);
+ esb_append(esbp, small_buf);
+ if (attr == DW_AT_decl_file || attr == DW_AT_call_file) {
+ if (srcfiles && tempud > 0 && tempud <= cnt) {
+ /* added by user request */
+ /* srcfiles is indexed starting at 0, but
+ DW_AT_decl_file defines that 0 means no
+ file, so tempud 1 means the 0th entry in
+ srcfiles, thus tempud-1 is the correct
+ index into srcfiles. */
+ char *fname = srcfiles[tempud - 1];
+
+ esb_append(esbp, " ");
+ esb_append(esbp, fname);
+ }
+
+ /* Validate integrity of files
+ referenced in .debug_line */
+ if(check_decl_file) {
+ DWARF_CHECK_COUNT(decl_file_result,1);
+ /* Zero is always a legal index, it means
+ no source name provided. */
+ if(tempud != 0 && tempud > cnt) {
+ if(!srcfiles) {
+ snprintf(small_buf,sizeof(small_buf),
+ "There is a file number=%" DW_PR_DUu
+ " but no source files "
+ " are known.",tempud);
+ } else {
+ snprintf(small_buf, sizeof(small_buf),
+ "Does not point to valid file info "
+ " filenum=%" DW_PR_DUu
+ " filecount=%" DW_PR_DUu ".",
+ tempud,cnt);
+ }
+ DWARF_CHECK_ERROR2(decl_file_result,
+ get_AT_name(attr,
+ dwarf_names_print_on_error),
+ small_buf);
+ }
+ }
+ }
+ } else {
+ print_error(dbg, "Cannot get encoding attribute ..",
+ wres, err);
+ }
+ }
+ break;
+ case DW_AT_const_value:
+ /* Do not use hexadecimal format */
+ wres = formxdata_print_value(dbg,attrib,esbp, &err, FALSE);
+ if(wres == DW_DLV_OK){
+ /* String appended already. */
+ } else if (wres == DW_DLV_NO_ENTRY) {
+ /* nothing? */
+ } else {
+ print_error(dbg,"Cannot get DW_AT_const_value ",wres,err);
+ }
+
+
+ break;
+ case DW_AT_upper_bound:
+ case DW_AT_lower_bound:
+ default:
+ /* Do not use hexadecimal format except for
+ DW_AT_ranges. */
+ wres = formxdata_print_value(dbg,attrib,esbp, &err,
+ (DW_AT_ranges == attr));
+ if (wres == DW_DLV_OK) {
+ /* String appended already. */
+ } else if (wres == DW_DLV_NO_ENTRY) {
+ /* nothing? */
+ } else {
+ print_error(dbg, "Cannot get form data..", wres,
+ err);
+ }
+ break;
+ }
+ }
+ if (cu_name_flag) {
+ if (attr == DW_AT_MIPS_fde) {
+ if (fde_offset_for_cu_low == DW_DLV_BADOFFSET) {
+ fde_offset_for_cu_low
+ = fde_offset_for_cu_high = tempud;
+ } else if (tempud < fde_offset_for_cu_low) {
+ fde_offset_for_cu_low = tempud;
+ } else if (tempud > fde_offset_for_cu_high) {
+ fde_offset_for_cu_high = tempud;
+ }
+ }
+ }
+ break;
+ case DW_FORM_sdata:
+ wres = dwarf_formsdata(attrib, &tempsd, &err);
+ if (wres == DW_DLV_OK) {
+ snprintf(small_buf, sizeof(small_buf),
+ "0x%" DW_PR_XZEROS DW_PR_DUx , tempsd);
+ esb_append(esbp, small_buf);
+ } else if (wres == DW_DLV_NO_ENTRY) {
+ /* nothing? */
+ } else {
+ print_error(dbg, "Cannot get formsdata..", wres, err);
+ }
+ break;
+ case DW_FORM_udata:
+ wres = dwarf_formudata(attrib, &tempud, &err);
+ if (wres == DW_DLV_OK) {
+ snprintf(small_buf, sizeof(small_buf), "0x%" DW_PR_XZEROS DW_PR_DUx ,
+ tempud);
+ esb_append(esbp, small_buf);
+ } else if (wres == DW_DLV_NO_ENTRY) {
+ /* nothing? */
+ } else {
+ print_error(dbg, "Cannot get formudata....", wres, err);
+ }
+ break;
+ case DW_FORM_string:
+ case DW_FORM_strp:
+ wres = dwarf_formstring(attrib, &temps, &err);
+ if (wres == DW_DLV_OK) {
+ /* Print as quoted string for clarity. */
+ esb_append(esbp, "\"");
+ esb_append(esbp, temps);
+ esb_append(esbp, "\"");
+ } else if (wres == DW_DLV_NO_ENTRY) {
+ /* nothing? */
+ } else {
+ print_error(dbg, "Cannot get a formstr (or a formstrp)....",
+ wres, err);
+ }
+
+ break;
+ case DW_FORM_flag:
+ wres = dwarf_formflag(attrib, &tempbool, &err);
+ if (wres == DW_DLV_OK) {
+ if (tempbool) {
+ snprintf(small_buf, sizeof(small_buf), "yes(%d)",
+ tempbool);
+ esb_append(esbp, small_buf);
+ } else {
+ snprintf(small_buf, sizeof(small_buf), "no");
+ esb_append(esbp, small_buf);
+ }
+ } else if (wres == DW_DLV_NO_ENTRY) {
+ /* nothing? */
+ } else {
+ print_error(dbg, "Cannot get formflag/p....", wres, err);
+ }
+ break;
+ case DW_FORM_indirect:
+ /* We should not ever get here, since the true form was
+ determined and direct_form has the DW_FORM_indirect if it is
+ used here in this attr. */
+ esb_append(esbp, get_FORM_name(theform,
+ dwarf_names_print_on_error));
+ break;
+ case DW_FORM_exprloc: { /* DWARF4 */
+ int showhextoo = 1;
+ print_exprloc_content(dbg,die,attrib,showhextoo,esbp);
+ }
+ break;
+ case DW_FORM_sec_offset: { /* DWARF4 */
+ string emptyattrname = 0;
+ int show_form_here = 0;
+ wres = get_small_encoding_integer_and_name(dbg,
+ attrib,
+ &tempud,
+ emptyattrname,
+ /* err_string */ NULL,
+ (encoding_type_func) 0,
+ &err,show_form_here);
+ if(wres == DW_DLV_NO_ENTRY) {
+ /* Show nothing? */
+ } else if(wres == DW_DLV_ERROR) {
+ print_error(dbg,
+ "Cannot get a DW_FORM_sec_offset....",
+ wres, err);
+ } else {
+ snprintf(small_buf, sizeof(small_buf),
+ "0x%" DW_PR_XZEROS DW_PR_DUx,
+ tempud);
+ esb_append(esbp,small_buf);
+ }
+ }
+
+ break;
+ case DW_FORM_flag_present: /* DWARF4 */
+ esb_append(esbp,"yes(1)");
+ break;
+ case DW_FORM_ref_sig8: { /* DWARF4 */
+ Dwarf_Sig8 sig8data;
+ wres = dwarf_formsig8(attrib,&sig8data,&err);
+ if(wres != DW_DLV_OK) {
+ /* Show nothing? */
+ print_error(dbg,
+ "Cannot get a DW_FORM_ref_sig8 ....",
+ wres, err);
+ } else {
+ struct esb_s sig8str;
+ esb_constructor(&sig8str);
+ format_sig8_string(&sig8data,&sig8str);
+ esb_append(esbp,esb_get_string(&sig8str));
+ esb_destructor(&sig8str);
+ }
+ }
+ break;
+
+ default:
+ print_error(dbg, "dwarf_whatform unexpected value", DW_DLV_OK,
+ err);
+ }
+ show_form_itself(show_form,local_verbose,theform, direct_form,esbp);
+}
+
+void
+format_sig8_string(Dwarf_Sig8*data, struct esb_s *out)
+{
+ unsigned i = 0;
+ char small_buf[40];
+ esb_append(out,"0x");
+ for( ; i < sizeof(data->signature); ++i) {
+ if (i == 4) {
+ esb_append(out," 0x");
+ }
+ snprintf(small_buf,sizeof(small_buf), "%02x",
+ (unsigned char)(data->signature[i]));
+ esb_append(out,small_buf);
+ }
+}
+
+
+/* A cleanup so that when using a memory checker
+ we don't show irrelevant leftovers.
+*/
+void
+clean_up_die_esb()
+{
+ esb_destructor(&esb_base);
+}
+
+static int
+get_form_values(Dwarf_Attribute attrib,
+ Dwarf_Half * theform, Dwarf_Half * directform)
+{
+ Dwarf_Error err = 0;
+ int res = dwarf_whatform(attrib, theform, &err);
+ dwarf_whatform_direct(attrib, directform, &err);
+ return res;
+}
+static void
+show_form_itself(int local_show_form,
+ int local_verbose,
+ int theform,
+ int directform, struct esb_s *esbp)
+{
+ char small_buf[100];
+ if (local_show_form
+ && directform && directform == DW_FORM_indirect) {
+ char *form_indir = " (used DW_FORM_indirect";
+ char *form_indir2 = ") ";
+ esb_append(esbp, form_indir);
+ if(local_verbose) {
+ esb_append(esbp, get_form_number_as_string(DW_FORM_indirect,
+ small_buf,sizeof(small_buf)));
+ }
+ esb_append(esbp, form_indir2);
+ }
+ if(local_show_form) {
+ esb_append(esbp," <form ");
+ esb_append(esbp,get_FORM_name(theform,
+ dwarf_names_print_on_error));
+ if(local_verbose) {
+ esb_append(esbp, get_form_number_as_string(theform,
+ small_buf, sizeof(small_buf)));
+ }
+ esb_append(esbp,">");
+ }
+}
+
+
+#include "tmp-ta-table.c"
+#include "tmp-ta-ext-table.c"
+
+static int
+legal_tag_attr_combination(Dwarf_Half tag, Dwarf_Half attr)
+{
+ if(tag <= 0) {
+ return FALSE;
+ }
+ if(tag < ATTR_TREE_ROW_COUNT) {
+ int index = attr / BITS_PER_WORD;
+ if ( index < ATTR_TREE_COLUMN_COUNT) {
+ unsigned bitflag = 1 << (attr % BITS_PER_WORD);
+ int known = ((tag_attr_combination_table[tag][index]
+ & bitflag) > 0 ? TRUE : FALSE);
+ if(known) {
+ return TRUE;
+ }
+ }
+ }
+ /* DW_AT_MIPS_fde used to return TRUE as that was
+ convenient for SGI/MIPS users. */
+ if(!suppress_check_extensions_tables) {
+ int r = 0;
+ for ( ; r < ATTR_TREE_EXT_ROW_COUNT; ++r ) {
+ int c = 1;
+ if(tag != tag_attr_combination_ext_table[r][0]) {
+ continue;
+ }
+ for( ; c < ATTR_TREE_EXT_COLUMN_COUNT ; ++c) {
+ if (tag_attr_combination_ext_table[r][c] == attr) {
+ return TRUE;
+ }
+ }
+ }
+ }
+ return (FALSE);
+}
+
+#include "tmp-tt-table.c"
+#include "tmp-tt-ext-table.c"
+
+/* Look only at valid table entries
+ The check here must match the building-logic in
+ tag_tree.c
+ And must match the tags defined in dwarf.h
+ The tag_tree_combination_table is a table of bit flags. */
+static int
+legal_tag_tree_combination(Dwarf_Half tag_parent, Dwarf_Half tag_child)
+{
+ if(tag_parent <= 0) {
+ return FALSE;
+ }
+ if ( tag_parent < TAG_TREE_ROW_COUNT) {
+ int index = tag_child / BITS_PER_WORD;
+ if ( index < TAG_TREE_COLUMN_COUNT) {
+ unsigned bitflag = 1 << (tag_child % BITS_PER_WORD);
+ int known = ((tag_tree_combination_table[tag_parent]
+ [index] & bitflag) > 0 ? TRUE : FALSE);
+ if(known) {
+ return TRUE;
+ }
+ }
+ }
+ if(!suppress_check_extensions_tables) {
+ int r = 0;
+ for ( ; r < TAG_TREE_EXT_ROW_COUNT; ++r ) {
+ int c = 1;
+ if(tag_parent != tag_tree_combination_ext_table[r][0]) {
+ continue;
+ }
+ for( ; c < TAG_TREE_EXT_COLUMN_COUNT ; ++c) {
+ if (tag_tree_combination_ext_table[r][c] == tag_child) {
+ return TRUE;
+ }
+ }
+ }
+ }
+ return (FALSE);
+}
+
diff --git a/dwarfdump/print_frames.c b/dwarfdump/print_frames.c
new file mode 100644
index 0000000..01e4130
--- /dev/null
+++ b/dwarfdump/print_frames.c
@@ -0,0 +1,1823 @@
+/*
+ Copyright (C) 2006 Silicon Graphics, Inc. All Rights Reserved.
+ Portions Copyright (C) 2011 SN Systems Ltd. All Rights Reserved.
+ Portions Copyright (C) 2007-2011 David Anderson. All Rights Reserved.
+
+ This program is free software; you can redistribute it and/or modify it
+ under the terms of version 2 of the GNU General Public License as
+ published by the Free Software Foundation.
+
+ This program is distributed in the hope that it would be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+ Further, this software is distributed without any warranty that it is
+ free of the rightful claim of any third person regarding infringement
+ or the like. Any license provided herein, whether implied or
+ otherwise, applies only to this software file. Patent licenses, if
+ any, provided herein do not apply to combinations of this program with
+ other software, or any other product whatsoever.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write the Free Software Foundation, Inc., 51
+ Franklin Street - Fifth Floor, Boston MA 02110-1301, USA.
+
+ Contact information: Silicon Graphics, Inc., 1500 Crittenden Lane,
+ Mountain View, CA 94043, or:
+
+ http://www.sgi.com
+
+ For further information regarding this notice, see:
+
+ http://oss.sgi.com/projects/GenInfo/NoticeExplan
+
+
+
+ $Header: /plroot/cmplrs.src/v7.4.5m/.RCS/PL/dwarfdump/RCS/print_frames.c,v 1.5 2006/06/14 20:34:02 davea Exp $ */
+
+/* The address of the Free Software Foundation is
+ Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+ SGI has moved from the Crittenden Lane address.
+*/
+
+/* From 199x through 2010 print_frames relied on
+ the order of the fdes matching the order of the functions
+ in the CUs when it came to printing a function name with
+ an FDE. This sometimes worked for SGI/IRIX because of
+ the way the compiler often emitted things. It always worked poorly
+ for gcc and other compilers.
+
+ As of 2010 the addrmap.h addrmap.h code provides help
+ in doing a better job when the tsearch functions (part of
+ POSIX) are available. */
+
+#include "globals.h"
+
+#include "print_frames.h"
+#include "dwconf.h"
+#include "esb.h"
+#include "addrmap.h"
+
+static void
+print_one_frame_reg_col(Dwarf_Debug dbg,
+ Dwarf_Unsigned rule_id,
+ Dwarf_Small value_type,
+ Dwarf_Unsigned reg_used,
+ Dwarf_Half addr_size,
+ struct dwconf_s *config_data,
+ Dwarf_Signed offset_relevant,
+ Dwarf_Signed offset, Dwarf_Ptr block_ptr);
+
+/* A strcpy which ensures NUL terminated string
+ and never overruns the output.
+*/
+void
+safe_strcpy(char *out, long outlen, const char *in, long inlen)
+{
+ if (inlen >= (outlen - 1)) {
+ strncpy(out, in, outlen - 1);
+ out[outlen - 1] = 0;
+ } else {
+ strcpy(out, in);
+ }
+}
+
+/* For inlined functions, try to find name */
+static int
+get_abstract_origin_funcname(Dwarf_Debug dbg,Dwarf_Attribute attr,
+ char *name_out, unsigned maxlen)
+{
+ Dwarf_Off off = 0;
+ Dwarf_Die origin_die = 0;
+ Dwarf_Attribute *atlist = NULL;
+ Dwarf_Signed atcnt = 0;
+ Dwarf_Signed i = 0;
+ int dres = 0;
+ int atres;
+ int name_found = 0;
+ int res = dwarf_global_formref(attr,&off,&err);
+ if(res != DW_DLV_OK) {
+ return DW_DLV_NO_ENTRY;
+ }
+ dres = dwarf_offdie(dbg,off,&origin_die,&err);
+ if(dres != DW_DLV_OK) {
+ return DW_DLV_NO_ENTRY;
+ }
+ atres = dwarf_attrlist(origin_die, &atlist, &atcnt, &err);
+ if (atres != DW_DLV_OK) {
+ dwarf_dealloc(dbg,origin_die,DW_DLA_DIE);
+ return DW_DLV_NO_ENTRY;
+ }
+ for (i = 0; i < atcnt; i++) {
+ Dwarf_Half lattr;
+ int ares;
+ ares = dwarf_whatattr(atlist[i], &lattr, &err);
+ if (ares == DW_DLV_ERROR) {
+ break;
+ } else if (ares == DW_DLV_OK) {
+ if(lattr == DW_AT_name) {
+ int sres = 0;
+ char* temps = 0;
+ sres = dwarf_formstring(atlist[i], &temps, &err);
+ if (sres == DW_DLV_OK) {
+ long len = (long) strlen(temps);
+ safe_strcpy(name_out, maxlen, temps, len);
+ name_found = 1;
+ break;
+ }
+ }
+ }
+ }
+ for (i = 0; i < atcnt; i++) {
+ dwarf_dealloc(dbg, atlist[i], DW_DLA_ATTR);
+ }
+ dwarf_dealloc(dbg, atlist, DW_DLA_LIST);
+ dwarf_dealloc(dbg,origin_die,DW_DLA_DIE);
+ if(!name_found) {
+ return DW_DLV_NO_ENTRY;
+ }
+ return DW_DLV_OK;
+}
+/*
+ Returns 1 if a proc with this low_pc found.
+ Else returns 0.
+
+ From print_die.c this has no pcMap passed in,
+ we do not really have a sensible context, so this
+ really just looks at the current attributes for a name.
+*/
+int
+get_proc_name(Dwarf_Debug dbg, Dwarf_Die die, Dwarf_Addr low_pc,
+ char *proc_name_buf, int proc_name_buf_len, void **pcMap)
+{
+ Dwarf_Signed atcnt = 0;
+ Dwarf_Signed i = 0;
+ Dwarf_Attribute *atlist = NULL;
+ Dwarf_Addr low_pc_die = 0;
+ int atres = 0;
+ int funcres = 1;
+ int funcpcfound = 0;
+ int funcnamefound = 0;
+
+ proc_name_buf[0] = 0; /* always set to something */
+ if(pcMap) {
+ struct Addr_Map_Entry *ame = 0;
+ ame = addr_map_find(low_pc,pcMap);
+ if(ame && ame->mp_name) {
+ /* mp_name is NULL only if we ran out of heap space. */
+ safe_strcpy(proc_name_buf, proc_name_buf_len,
+ ame->mp_name,(long) strlen(ame->mp_name));
+ return 1;
+ }
+ }
+
+ atres = dwarf_attrlist(die, &atlist, &atcnt, &err);
+ if (atres == DW_DLV_ERROR) {
+ print_error(dbg, "dwarf_attrlist", atres, err);
+ return 0;
+ }
+ if (atres == DW_DLV_NO_ENTRY) {
+ return 0;
+ }
+ for (i = 0; i < atcnt; i++) {
+ Dwarf_Half attr = 0;
+ int ares = 0;
+ string temps = 0;
+ int sres = 0;
+ int dres = 0;
+
+ if (funcnamefound == 1 && funcpcfound == 1) {
+ /* stop as soon as both found */
+ break;
+ }
+ ares = dwarf_whatattr(atlist[i], &attr, &err);
+ if (ares == DW_DLV_ERROR) {
+ print_error(dbg, "get_proc_name whatattr error", ares, err);
+ } else if (ares == DW_DLV_OK) {
+ switch (attr) {
+ case DW_AT_specification:
+ case DW_AT_abstract_origin:
+ {
+ if(!funcnamefound) {
+ /* Only use this if we have not seen DW_AT_name
+ yet .*/
+ int aores = get_abstract_origin_funcname(dbg,
+ atlist[i], proc_name_buf,proc_name_buf_len);
+ if(aores == DW_DLV_OK) {
+ /* FOUND THE NAME */
+ funcnamefound = 1;
+ }
+ }
+ }
+ break;
+ case DW_AT_name:
+ /* Even if we saw DW_AT_abstract_origin, go ahead
+ and take DW_AT_name. */
+ sres = dwarf_formstring(atlist[i], &temps, &err);
+ if (sres == DW_DLV_ERROR) {
+ print_error(dbg,
+ "formstring in get_proc_name failed",
+ sres, err);
+ /* 50 is safe wrong length since is bigger than the
+ actual string */
+ safe_strcpy(proc_name_buf, proc_name_buf_len,
+ "ERROR in dwarf_formstring!", 50);
+ } else if (sres == DW_DLV_NO_ENTRY) {
+ /* 50 is safe wrong length since is bigger than the
+ actual string */
+ safe_strcpy(proc_name_buf, proc_name_buf_len,
+ "NO ENTRY on dwarf_formstring?!", 50);
+ } else {
+ long len = (long) strlen(temps);
+
+ safe_strcpy(proc_name_buf, proc_name_buf_len, temps,
+ len);
+ }
+ funcnamefound = 1; /* FOUND THE NAME */
+ break;
+ case DW_AT_low_pc:
+ dres = dwarf_formaddr(atlist[i], &low_pc_die, &err);
+ if (dres == DW_DLV_ERROR) {
+ print_error(dbg, "formaddr in get_proc_name failed",
+ dres, err);
+ low_pc_die = ~low_pc;
+ /* ensure no match */
+ }
+ funcpcfound = 1;
+
+ break;
+ default:
+ break;
+ }
+ }
+ }
+ for (i = 0; i < atcnt; i++) {
+ dwarf_dealloc(dbg, atlist[i], DW_DLA_ATTR);
+ }
+ dwarf_dealloc(dbg, atlist, DW_DLA_LIST);
+ if(funcnamefound && funcpcfound && pcMap ) {
+ /* Insert every name to map, not just the one
+ we are looking for.
+ This version does extra work in that
+ early symbols in a CU will be inserted
+ multiple times (the extra times have no
+ effect), the dwarfdump2
+ version of this does less work. */
+ addr_map_insert(low_pc_die,proc_name_buf,pcMap);
+ }
+ if (funcnamefound == 0 || funcpcfound == 0 || low_pc != low_pc_die) {
+ funcres = 0;
+ }
+ return (funcres);
+}
+
+/* Modified Depth First Search looking for the procedure:
+ a) only looks for children of subprogram.
+ b) With subprogram looks at current die *before* looking
+ for a child.
+
+ Needed since some languages, including SGI MP Fortran,
+ have nested functions.
+ Return 0 on failure, 1 on success.
+*/
+static int
+load_nested_proc_name(Dwarf_Debug dbg, Dwarf_Die die, Dwarf_Addr low_pc,
+ char *ret_name_buf, int ret_name_buf_len,
+ void **pcMap)
+{
+ char name_buf[BUFSIZ];
+ Dwarf_Die curdie = die;
+ int die_locally_gotten = 0;
+ Dwarf_Die prev_child = 0;
+ Dwarf_Die newchild = 0;
+ Dwarf_Die newsibling = 0;
+ Dwarf_Half tag;
+ Dwarf_Error err = 0;
+ int chres = DW_DLV_OK;
+
+ ret_name_buf[0] = 0;
+ name_buf[0] = 0;
+ while (chres == DW_DLV_OK) {
+ int tres;
+
+ tres = dwarf_tag(curdie, &tag, &err);
+ newchild = 0;
+ err = 0;
+ if (tres == DW_DLV_OK) {
+ int lchres;
+
+ if (tag == DW_TAG_subprogram) {
+ int proc_name_v = get_proc_name(dbg, curdie, low_pc,
+ name_buf, BUFSIZ,pcMap);
+ if (proc_name_v) {
+ safe_strcpy(ret_name_buf, ret_name_buf_len,
+ name_buf, (long) strlen(name_buf));
+ if (die_locally_gotten) {
+ /* If we got this die from the parent, we do
+ not want to dealloc here! */
+ dwarf_dealloc(dbg, curdie, DW_DLA_DIE);
+ }
+ return 1;
+ }
+ /* Check children of subprograms recursively should
+ this really be check children of anything,
+ or just children of subprograms? */
+
+ lchres = dwarf_child(curdie, &newchild, &err);
+ if (lchres == DW_DLV_OK) {
+ /* look for inner subprogram */
+ int newprog =
+ load_nested_proc_name(dbg, newchild, low_pc,
+ name_buf, BUFSIZ,
+ pcMap);
+
+ dwarf_dealloc(dbg, newchild, DW_DLA_DIE);
+ if (newprog) {
+ /* Found it. We could just take this name or
+ we could concatenate names together For now,
+ just take name */
+ if (die_locally_gotten) {
+ /* If we got this die from the parent, we
+ do not want to dealloc here! */
+ dwarf_dealloc(dbg, curdie, DW_DLA_DIE);
+ }
+ safe_strcpy(ret_name_buf, ret_name_buf_len,
+ name_buf, (long) strlen(name_buf));
+ return 1;
+ }
+ } else if (lchres == DW_DLV_NO_ENTRY) {
+ /* nothing to do */
+ } else {
+ print_error(dbg,
+ "load_nested_proc_name dwarf_child() failed ",
+ chres, err);
+ if (die_locally_gotten) {
+ /* If we got this die from the parent, we do
+ not want to dealloc here! */
+ dwarf_dealloc(dbg, curdie, DW_DLA_DIE);
+ }
+ return 0;
+ }
+ } /* end if TAG_subprogram */
+ } else {
+ print_error(dbg, "no tag on child read ", tres, err);
+ if (die_locally_gotten) {
+ /* If we got this die from the parent, we do not want
+ to dealloc here! */
+ dwarf_dealloc(dbg, curdie, DW_DLA_DIE);
+ }
+ return 0;
+ }
+ /* try next sibling */
+ prev_child = curdie;
+ chres = dwarf_siblingof(dbg, curdie, &newsibling, &err);
+ if (chres == DW_DLV_ERROR) {
+ print_error(dbg, "dwarf_cu_header On Child read ", chres,
+ err);
+ if (die_locally_gotten) {
+ /* If we got this die from the parent, we do not want
+ to dealloc here! */
+ dwarf_dealloc(dbg, curdie, DW_DLA_DIE);
+ }
+ return 0;
+ } else if (chres == DW_DLV_NO_ENTRY) {
+ if (die_locally_gotten) {
+ /* If we got this die from the parent, we do not want
+ to dealloc here! */
+ dwarf_dealloc(dbg, prev_child, DW_DLA_DIE);
+ }
+ return 0;/* proc name not at this level */
+ } else {
+ /* DW_DLV_OK */
+ curdie = newsibling;
+ if (die_locally_gotten) {
+ /* If we got this die from the parent, we do not want
+ to dealloc here! */
+ dwarf_dealloc(dbg, prev_child, DW_DLA_DIE);
+ }
+ prev_child = 0;
+ die_locally_gotten = 1;
+ }
+
+ }
+ if (die_locally_gotten) {
+ /* If we got this die from the parent, we do not want to
+ dealloc here! */
+ dwarf_dealloc(dbg, curdie, DW_DLA_DIE);
+ }
+ return 0;
+}
+
+/* For SGI MP Fortran and other languages, functions
+ nest! As a result, we must dig thru all functions,
+ not just the top level.
+ This remembers the CU die and restarts each search at the start
+ of the current cu.
+*/
+static string
+get_fde_proc_name(Dwarf_Debug dbg, Dwarf_Addr low_pc,
+ void **pcMap,
+ int *all_cus_seen)
+{
+ static char proc_name[BUFSIZ];
+ Dwarf_Unsigned cu_header_length = 0;
+ Dwarf_Unsigned abbrev_offset = 0;
+ Dwarf_Half version_stamp = 0;
+ Dwarf_Half address_size = 0;
+ Dwarf_Unsigned next_cu_offset = 0;
+ int cures = DW_DLV_OK;
+ int dres = DW_DLV_OK;
+ int chres = DW_DLV_OK;
+ int looping = 0;
+
+ proc_name[0] = 0;
+ {
+ struct Addr_Map_Entry *ame = 0;
+ ame = addr_map_find(low_pc,pcMap);
+ if(ame && ame->mp_name) {
+ /* mp_name is only NULL here if we just ran out of heap memory! */
+ safe_strcpy(proc_name, sizeof(proc_name),
+ ame->mp_name,(long) strlen(ame->mp_name));
+ return proc_name;
+ }
+ if (*all_cus_seen) {
+ return "";
+ }
+ }
+ if (current_cu_die_for_print_frames == NULL) {
+ /* Call depends on dbg->cu_context to know what to do. */
+ cures = dwarf_next_cu_header(dbg, &cu_header_length,
+ &version_stamp, &abbrev_offset,
+ &address_size, &next_cu_offset,
+ &err);
+ if (cures == DW_DLV_ERROR) {
+ return NULL;
+ } else if (cures == DW_DLV_NO_ENTRY) {
+ /* loop thru the list again */
+ current_cu_die_for_print_frames = 0;
+ ++looping;
+ } else { /* DW_DLV_OK */
+ dres = dwarf_siblingof(dbg, NULL,
+ &current_cu_die_for_print_frames,
+ &err);
+ if (dres == DW_DLV_ERROR) {
+ return NULL;
+ }
+ }
+ }
+ if (dres == DW_DLV_OK) {
+ Dwarf_Die child = 0;
+
+ if (current_cu_die_for_print_frames == 0) {
+ /* no information. Possibly a stripped file */
+ return NULL;
+ }
+ chres =
+ dwarf_child(current_cu_die_for_print_frames, &child, &err);
+ if (chres == DW_DLV_ERROR) {
+ print_error(dbg, "dwarf_cu_header on child read ", chres,
+ err);
+ } else if (chres == DW_DLV_NO_ENTRY) {
+ } else { /* DW_DLV_OK */
+ int gotname =
+ load_nested_proc_name(dbg, child, low_pc, proc_name,
+ BUFSIZ,pcMap);
+
+ dwarf_dealloc(dbg, child, DW_DLA_DIE);
+ if (gotname) {
+ return (proc_name);
+ }
+ child = 0;
+ }
+ }
+ for (;;) {
+ Dwarf_Die ldie = 0;
+
+ cures = dwarf_next_cu_header(dbg, &cu_header_length,
+ &version_stamp, &abbrev_offset,
+ &address_size, &next_cu_offset,
+ &err);
+ if (cures != DW_DLV_OK) {
+ *all_cus_seen = 1;
+ break;
+ }
+
+ dres = dwarf_siblingof(dbg, NULL, &ldie, &err);
+ if (current_cu_die_for_print_frames) {
+ dwarf_dealloc(dbg, current_cu_die_for_print_frames,
+ DW_DLA_DIE);
+ }
+ current_cu_die_for_print_frames = 0;
+ if (dres == DW_DLV_ERROR) {
+ print_error(dbg,
+ "dwarf_cu_header Child Read finding proc name for .debug_frame",
+ chres, err);
+ continue;
+ } else if (dres == DW_DLV_NO_ENTRY) {
+ ++looping;
+ if (looping > 1) {
+ print_error(dbg, "looping on cu headers!", dres, err);
+ return NULL;
+ }
+ continue;
+ }
+ /* DW_DLV_OK */
+ current_cu_die_for_print_frames = ldie;
+ {
+ int chres = 0;
+ Dwarf_Die child = 0;
+
+ chres =
+ dwarf_child(current_cu_die_for_print_frames, &child,
+ &err);
+ if (chres == DW_DLV_ERROR) {
+ print_error(dbg, "dwarf Child Read ", chres, err);
+ } else if (chres == DW_DLV_NO_ENTRY) {
+
+ ;/* do nothing, loop on cu */
+ } else {
+ /* DW_DLV_OK) */
+
+ int gotname =
+ load_nested_proc_name(dbg, child, low_pc, proc_name,
+ BUFSIZ,pcMap);
+
+ dwarf_dealloc(dbg, child, DW_DLA_DIE);
+ if (gotname) {
+ return (proc_name);
+ }
+ }
+ }
+ }
+ return (NULL);
+}
+
+/* Gather the fde print logic here so the control logic
+ determining what FDE to print is clearer. */
+static int
+print_one_fde(Dwarf_Debug dbg, Dwarf_Fde fde,
+ Dwarf_Unsigned fde_index,
+ Dwarf_Cie * cie_data,
+ Dwarf_Signed cie_element_count,
+ Dwarf_Half address_size, int is_eh,
+ struct dwconf_s *config_data,
+ void **pcMap,
+ void **lowpcSet,
+ int * all_cus_seen)
+{
+ Dwarf_Addr j = 0;
+ Dwarf_Addr low_pc = 0;
+ Dwarf_Unsigned func_length = 0;
+ Dwarf_Ptr fde_bytes = NULL;
+ Dwarf_Unsigned fde_bytes_length = 0;
+ Dwarf_Off cie_offset = 0;
+ Dwarf_Signed cie_index = 0;
+ Dwarf_Off fde_offset = 0;
+ Dwarf_Signed eh_table_offset = 0;
+ int fres = 0;
+ int offres = 0;
+ string temps = 0;
+ Dwarf_Error err = 0;
+ int printed_intro_addr = 0;
+
+ fres = dwarf_get_fde_range(fde,
+ &low_pc, &func_length,
+ &fde_bytes,
+ &fde_bytes_length,
+ &cie_offset, &cie_index,
+ &fde_offset, &err);
+ if (fres == DW_DLV_ERROR) {
+ print_error(dbg, "dwarf_get_fde_range", fres, err);
+ }
+ if (fres == DW_DLV_NO_ENTRY) {
+ return DW_DLV_NO_ENTRY;
+ }
+ if (cu_name_flag &&
+ fde_offset_for_cu_low != DW_DLV_BADOFFSET &&
+ (fde_offset < fde_offset_for_cu_low ||
+ fde_offset > fde_offset_for_cu_high)) {
+ return DW_DLV_NO_ENTRY;
+ }
+ /* eh_table_offset is IRIX ONLY. */
+ fres = dwarf_get_fde_exception_info(fde, &eh_table_offset, &err);
+ if (fres == DW_DLV_ERROR) {
+ print_error(dbg, "dwarf_get_fde_exception_info", fres, err);
+ }
+ if(suppress_nested_name_search) {
+ temps = 0;
+ } else {
+#ifdef HAVE_TSEARCH
+ struct Addr_Map_Entry *mp = 0;
+ temps = get_fde_proc_name(dbg, low_pc,pcMap,all_cus_seen);
+ mp = addr_map_find(low_pc,lowpcSet);
+ if (check_frames || check_frames_extended) {
+ DWARF_CHECK_COUNT(fde_duplication,1);
+ }
+ if (mp) {
+ if (check_frames || check_frames_extended) {
+ char msg[400];
+ if(temps && (strlen(temps) > 0)) {
+ snprintf(msg,sizeof(msg),"An fde low pc of 0x%"
+ DW_PR_DUx
+ " is not the first fde with that pc. "
+ "The first is named \"%s\"",
+ (Dwarf_Unsigned)low_pc,
+ temps);
+ } else {
+ snprintf(msg,sizeof(msg),"An fde low pc of 0x%"
+ DW_PR_DUx
+ " is not the first fde with that pc. "
+ "The first is not named.",
+ (Dwarf_Unsigned)low_pc);
+
+ }
+ DWARF_CHECK_ERROR(fde_duplication,msg);
+ }
+ } else {
+ addr_map_insert(low_pc,0,lowpcSet);
+ }
+#endif
+ }
+
+ /* Do not print if in check mode */
+ if (!check_frames_extended) {
+ printf("<%5" DW_PR_DSd "><0x%" DW_PR_XZEROS DW_PR_DUx
+ ":0x%" DW_PR_XZEROS DW_PR_DUx
+ "><%s><fde offset 0x%" DW_PR_XZEROS DW_PR_DUx
+ " length: 0x%" DW_PR_XZEROS DW_PR_DUx ">",
+ cie_index, (Dwarf_Unsigned)low_pc,
+ (Dwarf_Unsigned)(low_pc + func_length),
+ temps ? temps : "", (Dwarf_Unsigned)fde_offset, fde_bytes_length);
+ }
+
+
+
+ if (!is_eh) {
+ /* IRIX uses eh_table_offset. */
+ /* Do not print if in check mode */
+ if (!check_frames_extended) {
+ if (eh_table_offset == DW_DLX_NO_EH_OFFSET) {
+ printf("<eh offset %s>\n", "none");
+ } else if (eh_table_offset == DW_DLX_EH_OFFSET_UNAVAILABLE) {
+ printf("<eh offset %s>\n", "unknown");
+ } else {
+ printf("<eh offset 0x%" DW_PR_XZEROS DW_PR_DUx
+ ">\n", eh_table_offset);
+ }
+ }
+ } else {
+ int ares = 0;
+ Dwarf_Small *data = 0;
+ Dwarf_Unsigned len = 0;
+
+ ares = dwarf_get_fde_augmentation_data(fde, &data, &len, &err);
+ if (ares == DW_DLV_NO_ENTRY) {
+ /* do nothing. */
+ } else if (ares == DW_DLV_OK) {
+ /* Do not print if in check mode */
+ if (!check_frames_extended) {
+ int k2 = 0;
+
+ printf("<eh aug data len 0x%" DW_PR_DUx , len);
+ for (k2 = 0; k2 < len; ++k2) {
+ if (k2 == 0) {
+ printf(" bytes 0x");
+ }
+ printf("%02x ", (unsigned char) data[k2]);
+ }
+ printf(">");
+ }
+ } /* else DW_DLV_ERROR, do nothing */
+
+ /* Do not print if in check mode */
+ if (!check_frames_extended) {
+ printf("\n");
+
+ }
+ }
+
+ for (j = low_pc; j < low_pc + func_length; j++) {
+ Dwarf_Half k = 0;
+
+ if (config_data->cf_interface_number == 3) {
+ Dwarf_Signed reg = 0;
+ Dwarf_Signed offset_relevant = 0;
+ Dwarf_Small value_type = 0;
+ Dwarf_Signed offset_or_block_len = 0;
+ Dwarf_Signed offset = 0;
+ Dwarf_Ptr block_ptr = 0;
+ Dwarf_Addr row_pc = 0;
+
+ int fires = dwarf_get_fde_info_for_cfa_reg3(fde,
+ j,
+ &value_type,
+ &offset_relevant,
+ &reg,
+ &offset_or_block_len,
+ &block_ptr,
+ &row_pc,
+ &err);
+ offset = offset_or_block_len;
+ if (fires == DW_DLV_ERROR) {
+ print_error(dbg,
+ "dwarf_get_fde_info_for_reg", fires, err);
+ }
+ if (fires == DW_DLV_NO_ENTRY) {
+ continue;
+ }
+ if (row_pc != j) {
+ /* duplicate row */
+ continue;
+ }
+
+ /* Do not print if in check mode */
+ if (!printed_intro_addr && !check_frames_extended) {
+ printf(" 0x%" DW_PR_XZEROS DW_PR_DUx
+ ": ", (Dwarf_Unsigned)j);
+ printed_intro_addr = 1;
+ }
+ print_one_frame_reg_col(dbg, config_data->cf_cfa_reg,
+ value_type,
+ reg,
+ address_size,
+ config_data,
+ offset_relevant, offset, block_ptr);
+ }
+ for (k = 0; k < config_data->cf_table_entry_count; k++) {
+ Dwarf_Signed reg = 0;
+ Dwarf_Signed offset_relevant = 0;
+ int fires = 0;
+ Dwarf_Small value_type = 0;
+ Dwarf_Ptr block_ptr = 0;
+ Dwarf_Signed offset_or_block_len = 0;
+ Dwarf_Signed offset = 0;
+ Dwarf_Addr row_pc = 0;
+
+ if (config_data->cf_interface_number == 3) {
+ fires = dwarf_get_fde_info_for_reg3(fde,
+ k,
+ j,
+ &value_type,
+ &offset_relevant,
+ &reg,
+ &offset_or_block_len,
+ &block_ptr,
+ &row_pc, &err);
+ offset = offset_or_block_len;
+ } else {
+ /* This interface is deprecated. Is the old
+ MIPS/DWARF2 interface. */
+ /* ASSERT: config_data->cf_interface_number == 2 */
+ value_type = DW_EXPR_OFFSET;
+ fires = dwarf_get_fde_info_for_reg(fde,
+ k,
+ j,
+ &offset_relevant,
+ &reg,
+ &offset, &row_pc,
+ &err);
+ }
+ if (fires == DW_DLV_ERROR) {
+ printf("\n");
+ print_error(dbg,
+ "dwarf_get_fde_info_for_reg", fires, err);
+ }
+ if (fires == DW_DLV_NO_ENTRY) {
+ continue;
+ }
+ if (row_pc != j) {
+ /* duplicate row */
+ break;
+ }
+
+ /* Do not print if in check mode */
+ if (!printed_intro_addr && !check_frames_extended) {
+ printf(" 0x%" DW_PR_XZEROS DW_PR_DUx ": ",
+ (Dwarf_Unsigned)j);
+ printed_intro_addr = 1;
+ }
+ print_one_frame_reg_col(dbg,k,
+ value_type,
+ reg,
+ address_size,
+ config_data,
+ offset_relevant, offset, block_ptr);
+ }
+ if (printed_intro_addr) {
+ printf("\n");
+ printed_intro_addr = 0;
+ }
+ }
+ if (verbose > 1) {
+ Dwarf_Off fde_off = 0;
+ Dwarf_Off cie_off = 0;
+
+ /* Get the fde instructions and print them in raw form, just
+ like cie instructions */
+ Dwarf_Ptr instrs = 0;
+ Dwarf_Unsigned ilen = 0;
+ int res = 0;
+
+ res = dwarf_get_fde_instr_bytes(fde, &instrs, &ilen, &err);
+ offres =
+ dwarf_fde_section_offset(dbg, fde, &fde_off, &cie_off,
+ &err);
+ if (offres == DW_DLV_OK) {
+ /* Do not print if in check mode */
+ if (!check_frames_extended) {
+ printf(" fde section offset %" DW_PR_DUu
+ " 0x%" DW_PR_XZEROS DW_PR_DUx
+ " cie offset for fde: %" DW_PR_DUu
+ " 0x%" DW_PR_XZEROS DW_PR_DUx "\n",
+ (Dwarf_Unsigned) fde_off,
+ (Dwarf_Unsigned) fde_off,
+ (Dwarf_Unsigned) cie_off,
+ (Dwarf_Unsigned) cie_off);
+ }
+ }
+
+
+ if (res == DW_DLV_OK) {
+ int cires = 0;
+ Dwarf_Unsigned cie_length = 0;
+ Dwarf_Small version = 0;
+ string augmenter = 0;
+ Dwarf_Unsigned code_alignment_factor = 0;
+ Dwarf_Signed data_alignment_factor = 0;
+ Dwarf_Half return_address_register_rule = 0;
+ Dwarf_Ptr initial_instructions = 0;
+ Dwarf_Unsigned initial_instructions_length = 0;
+
+ if (cie_index >= cie_element_count) {
+ printf("Bad cie index %" DW_PR_DSd
+ " with fde index %" DW_PR_DUu "! "
+ "(table entry max %" DW_PR_DSd ")\n",
+ cie_index, fde_index,
+ cie_element_count);
+ exit(1);
+ }
+ cires = dwarf_get_cie_info(cie_data[cie_index],
+ &cie_length,
+ &version,
+ &augmenter,
+ &code_alignment_factor,
+ &data_alignment_factor,
+ &return_address_register_rule,
+ &initial_instructions,
+ &initial_instructions_length,
+ &err);
+ if (cires == DW_DLV_ERROR) {
+ printf
+ ("Bad cie index %" DW_PR_DSd
+ " with fde index %" DW_PR_DUu "!\n",
+ cie_index, fde_index);
+ print_error(dbg, "dwarf_get_cie_info", cires, err);
+ }
+ if (cires == DW_DLV_NO_ENTRY) {
+ ; /* ? */
+ } else {
+ /* Do not print if in check mode */
+ if (!check_frames_extended) {
+ print_frame_inst_bytes(dbg, instrs,
+ (Dwarf_Signed) ilen,
+ data_alignment_factor,
+ (int) code_alignment_factor,
+ address_size, config_data);
+ }
+ }
+ } else if (res == DW_DLV_NO_ENTRY) {
+ printf("Impossible: no instr bytes for fde index %"
+ DW_PR_DUu "?\n",
+ fde_index);
+ } else {
+ /* DW_DLV_ERROR */
+ printf("Error: on gettinginstr bytes for fde index %"
+ DW_PR_DUu "?\n",
+ fde_index);
+ print_error(dbg, "dwarf_get_fde_instr_bytes", res, err);
+ }
+
+ }
+ return DW_DLV_OK;
+}
+
+
+/* Print a cie. Gather the print logic here so the
+ control logic deciding what to print
+ is clearer.
+*/
+int
+print_one_cie(Dwarf_Debug dbg, Dwarf_Cie cie,
+ Dwarf_Unsigned cie_index, Dwarf_Half address_size,
+ struct dwconf_s *config_data)
+{
+
+ int cires = 0;
+ Dwarf_Unsigned cie_length = 0;
+ Dwarf_Small version = 0;
+ string augmenter = "";
+ Dwarf_Unsigned code_alignment_factor = 0;
+ Dwarf_Signed data_alignment_factor = 0;
+ Dwarf_Half return_address_register_rule = 0;
+ Dwarf_Ptr initial_instructions = 0;
+ Dwarf_Unsigned initial_instructions_length = 0;
+ Dwarf_Off cie_off = 0;
+ Dwarf_Error err = 0;
+
+ cires = dwarf_get_cie_info(cie,
+ &cie_length,
+ &version,
+ &augmenter,
+ &code_alignment_factor,
+ &data_alignment_factor,
+ &return_address_register_rule,
+ &initial_instructions,
+ &initial_instructions_length, &err);
+ if (cires == DW_DLV_ERROR) {
+ print_error(dbg, "dwarf_get_cie_info", cires, err);
+ }
+ if (cires == DW_DLV_NO_ENTRY) {
+ printf("Impossible DW_DLV_NO_ENTRY on cie %" DW_PR_DUu "\n",
+ cie_index);
+ return DW_DLV_NO_ENTRY;
+ }
+ {
+ /* Do not print if in check mode */
+ if (!check_frames_extended) {
+ printf("<%5" DW_PR_DUu ">\tversion\t\t\t\t%d\n",
+ cie_index, version);
+ cires = dwarf_cie_section_offset(dbg, cie, &cie_off, &err);
+ if (cires == DW_DLV_OK) {
+ printf("\tcie section offset\t\t%" DW_PR_DUu
+ " 0x%" DW_PR_XZEROS DW_PR_DUx "\n",
+ (Dwarf_Unsigned) cie_off,
+ (Dwarf_Unsigned) cie_off);
+ }
+ printf("\taugmentation\t\t\t%s\n", augmenter);
+ printf("\tcode_alignment_factor\t\t%" DW_PR_DUu "\n",
+ code_alignment_factor);
+ printf("\tdata_alignment_factor\t\t%" DW_PR_DSd "\n",
+ data_alignment_factor);
+ printf("\treturn_address_register\t\t%d\n",
+ return_address_register_rule);
+ }
+
+ {
+ int ares = 0;
+ Dwarf_Small *data = 0;
+ Dwarf_Unsigned len = 0;
+
+ ares =
+ dwarf_get_cie_augmentation_data(cie, &data, &len, &err);
+ if (ares == DW_DLV_NO_ENTRY) {
+ /* do nothing. */
+ } else if (ares == DW_DLV_OK && len > 0) {
+ /* Do not print if in check mode */
+ if (!check_frames_extended) {
+ int k2 = 0;
+
+ printf(" eh aug data len 0x%" DW_PR_DUx , len);
+ for (k2 = 0; data && k2 < len; ++k2) {
+ if (k2 == 0) {
+ printf(" bytes 0x");
+ }
+ printf("%02x ", (unsigned char) data[k2]);
+ }
+ printf("\n");
+ }
+ } /* else DW_DLV_ERROR or no data, do nothing */
+ }
+
+ /* Do not print if in check mode */
+ if (!check_frames_extended) {
+ printf("\tbytes of initial instructions\t%" DW_PR_DUu "\n",
+ initial_instructions_length);
+ printf("\tcie length\t\t\t%" DW_PR_DUu "\n", cie_length);
+ /* For better layout */
+ printf("\tinitial instructions\n");
+ print_frame_inst_bytes(dbg, initial_instructions,
+ (Dwarf_Signed) initial_instructions_length,
+ data_alignment_factor,
+ (int) code_alignment_factor,
+ address_size, config_data);
+ }
+ }
+ return DW_DLV_OK;
+}
+
+void
+get_string_from_locs(Dwarf_Debug dbg,
+ Dwarf_Ptr bytes_in,
+ Dwarf_Unsigned block_len,
+ Dwarf_Half addr_size,
+ struct esb_s *out_string)
+{
+
+ Dwarf_Locdesc *locdescarray = 0;
+ Dwarf_Signed listlen = 0;
+ Dwarf_Error err2 =0;
+ int skip_locdesc_header=1;
+ int res = 0;
+ int res2 = dwarf_loclist_from_expr_a(dbg,
+ bytes_in,block_len,
+ addr_size,
+ &locdescarray,
+ &listlen,&err2);
+ if (res2 == DW_DLV_ERROR) {
+ print_error(dbg, "dwarf_get_loclist_from_expr_a",
+ res2, err2);
+ }
+ if(res2==DW_DLV_NO_ENTRY) {
+ return;
+ }
+ /* lcnt is always 1 */
+
+ /* Use locdescarray here.*/
+ res = dwarfdump_print_one_locdesc(dbg,
+ locdescarray,
+ skip_locdesc_header,
+ out_string);
+ if(res != DW_DLV_OK) {
+ printf("Bad status from _dwarf_print_one_locdesc %d\n",res);
+ exit(1);
+ }
+
+ dwarf_dealloc(dbg, locdescarray->ld_s, DW_DLA_LOC_BLOCK);
+ dwarf_dealloc(dbg, locdescarray, DW_DLA_LOCDESC);
+ return ;
+}
+
+/* Print the frame instructions in detail for a glob of instructions.
+*/
+
+/*ARGSUSED*/ void
+print_frame_inst_bytes(Dwarf_Debug dbg,
+ Dwarf_Ptr cie_init_inst, Dwarf_Signed len,
+ Dwarf_Signed data_alignment_factor,
+ int code_alignment_factor, Dwarf_Half addr_size,
+ struct dwconf_s *config_data)
+{
+ unsigned char *instp = (unsigned char *) cie_init_inst;
+ Dwarf_Unsigned uval = 0;
+ Dwarf_Unsigned uval2 = 0;
+ unsigned int uleblen = 0;
+ unsigned int off = 0;
+ unsigned int loff = 0;
+ unsigned short u16 = 0;
+ unsigned int u32 = 0;
+ unsigned long long u64;
+
+ for (; len > 0;) {
+ unsigned char ibyte = *instp;
+ int top = ibyte & 0xc0;
+ int bottom = ibyte & 0x3f;
+ int delta = 0;
+ int reg = 0;
+
+ switch (top) {
+ case DW_CFA_advance_loc:
+ delta = ibyte & 0x3f;
+ printf("\t%2u DW_CFA_advance_loc %d", off,
+ (int) (delta * code_alignment_factor));
+ if (verbose) {
+ printf(" (%d * %d)", (int) delta,
+ (int) code_alignment_factor);
+ }
+ printf("\n");
+ break;
+ case DW_CFA_offset:
+ loff = off;
+ reg = ibyte & 0x3f;
+ uval = local_dwarf_decode_u_leb128(instp + 1, &uleblen);
+ instp += uleblen;
+ len -= uleblen;
+ off += uleblen;
+ printf("\t%2u DW_CFA_offset ", loff);
+ printreg((Dwarf_Signed) reg, config_data);
+ printf(" %" DW_PR_DSd , (Dwarf_Signed)
+ (((Dwarf_Signed) uval) * data_alignment_factor));
+ if (verbose) {
+ printf(" (%" DW_PR_DUu " * %" DW_PR_DSd ")", uval,
+ data_alignment_factor);
+ }
+ printf("\n");
+ break;
+
+ case DW_CFA_restore:
+ reg = ibyte & 0x3f;
+ printf("\t%2u DW_CFA_restore ", off);
+ printreg((Dwarf_Signed) reg, config_data);
+ printf("\n");
+ break;
+
+ default:
+ loff = off;
+ switch (bottom) {
+ case DW_CFA_set_loc:
+ /* operand is address, so need address size */
+ /* which will be 4 or 8. */
+ switch (addr_size) {
+ case 4:
+ {
+ __uint32_t v32 = 0;
+ memcpy(&v32, instp + 1, addr_size);
+ uval = v32;
+ }
+ break;
+ case 8:
+ {
+ __uint64_t v64 = 0;
+ memcpy(&v64, instp + 1, addr_size);
+ uval = v64;
+ }
+ break;
+ default:
+ printf
+ ("Error: Unexpected address size %d in DW_CFA_set_loc!\n",
+ addr_size);
+ uval = 0;
+ }
+
+ instp += addr_size;
+ len -= (Dwarf_Signed) addr_size;
+ off += addr_size;
+ printf("\t%2u DW_CFA_set_loc %" DW_PR_DUu "\n",
+ loff, uval);
+ break;
+ case DW_CFA_advance_loc1:
+ delta = (unsigned char) *(instp + 1);
+ uval2 = delta;
+ instp += 1;
+ len -= 1;
+ off += 1;
+ printf("\t%2u DW_CFA_advance_loc1 %" DW_PR_DUu "\n",
+ loff, uval2);
+ break;
+ case DW_CFA_advance_loc2:
+ memcpy(&u16, instp + 1, 2);
+ uval2 = u16;
+ instp += 2;
+ len -= 2;
+ off += 2;
+ printf("\t%2u DW_CFA_advance_loc2 %" DW_PR_DUu "\n",
+ loff, uval2);
+ break;
+ case DW_CFA_advance_loc4:
+ memcpy(&u32, instp + 1, 4);
+ uval2 = u32;
+ instp += 4;
+ len -= 4;
+ off += 4;
+ printf("\t%2u DW_CFA_advance_loc4 %" DW_PR_DUu "\n",
+ loff, uval2);
+ break;
+ case DW_CFA_MIPS_advance_loc8:
+ memcpy(&u64, instp + 1, 8);
+ uval2 = u64;
+ instp += 8;
+ len -= 8;
+ off += 8;
+ printf("\t%2u DW_CFA_MIPS_advance_loc8 %" DW_PR_DUu "\n",
+ loff, uval2);
+ break;
+ case DW_CFA_offset_extended:
+ uval = local_dwarf_decode_u_leb128(instp + 1, &uleblen);
+ instp += uleblen;
+ len -= uleblen;
+ off += uleblen;
+ uval2 =
+ local_dwarf_decode_u_leb128(instp + 1, &uleblen);
+ instp += uleblen;
+ len -= uleblen;
+ off += uleblen;
+ printf("\t%2u DW_CFA_offset_extended ", loff);
+ printreg((Dwarf_Signed) uval, config_data);
+ printf(" %" DW_PR_DSd ,
+ (Dwarf_Signed) (((Dwarf_Signed) uval2) *
+ data_alignment_factor));
+ if (verbose) {
+ printf(" (%" DW_PR_DUu " * %d)", uval2,
+ (int) data_alignment_factor);
+ }
+ printf("\n");
+ break;
+
+ case DW_CFA_restore_extended:
+ uval = local_dwarf_decode_u_leb128(instp + 1, &uleblen);
+ instp += uleblen;
+ len -= uleblen;
+ off += uleblen;
+ printf("\t%2u DW_CFA_restore_extended ", loff);
+ printreg((Dwarf_Signed) uval, config_data);
+ printf("\n");
+ break;
+ case DW_CFA_undefined:
+ uval = local_dwarf_decode_u_leb128(instp + 1, &uleblen);
+ instp += uleblen;
+ len -= uleblen;
+ off += uleblen;
+ printf("\t%2u DW_CFA_undefined ", loff);
+ printreg((Dwarf_Signed) uval, config_data);
+ printf("\n");
+ break;
+ case DW_CFA_same_value:
+ uval = local_dwarf_decode_u_leb128(instp + 1, &uleblen);
+ instp += uleblen;
+ len -= uleblen;
+ off += uleblen;
+ printf("\t%2u DW_CFA_same_value ", loff);
+ printreg((Dwarf_Signed) uval, config_data);
+ printf("\n");
+ break;
+ case DW_CFA_register:
+ uval = local_dwarf_decode_u_leb128(instp + 1, &uleblen);
+ instp += uleblen;
+ len -= uleblen;
+ off += uleblen;
+ uval2 =
+ local_dwarf_decode_u_leb128(instp + 1, &uleblen);
+ instp += uleblen;
+ len -= uleblen;
+ off += uleblen;
+ printf("\t%2u DW_CFA_register ", loff);
+ printreg((Dwarf_Signed) uval, config_data);
+ printf(" = ");
+ printreg((Dwarf_Signed) uval2, config_data);
+ printf("\n");
+ break;
+ case DW_CFA_remember_state:
+ printf("\t%2u DW_CFA_remember_state\n", loff);
+ break;
+ case DW_CFA_restore_state:
+ printf("\t%2u DW_CFA_restore_state\n", loff);
+ break;
+ case DW_CFA_def_cfa:
+ uval = local_dwarf_decode_u_leb128(instp + 1, &uleblen);
+ instp += uleblen;
+ len -= uleblen;
+ off += uleblen;
+ uval2 =
+ local_dwarf_decode_u_leb128(instp + 1, &uleblen);
+ instp += uleblen;
+ len -= uleblen;
+ off += uleblen;
+ printf("\t%2u DW_CFA_def_cfa ", loff);
+ printreg((Dwarf_Signed) uval, config_data);
+ printf(" %" DW_PR_DUu , (unsigned long long) uval2);
+ printf("\n");
+ break;
+ case DW_CFA_def_cfa_register:
+ uval = local_dwarf_decode_u_leb128(instp + 1, &uleblen);
+ instp += uleblen;
+ len -= uleblen;
+ off += uleblen;
+ printf("\t%2u DW_CFA_def_cfa_register ", loff);
+ printreg((Dwarf_Signed) uval, config_data);
+ printf("\n");
+ break;
+ case DW_CFA_def_cfa_offset:
+ uval = local_dwarf_decode_u_leb128(instp + 1, &uleblen);
+ instp += uleblen;
+ len -= uleblen;
+ off += uleblen;
+ printf("\t%2u DW_CFA_def_cfa_offset %" DW_PR_DUu "\n",
+ loff, uval);
+ break;
+
+ case DW_CFA_nop:
+ printf("\t%2u DW_CFA_nop\n", loff);
+ break;
+
+ case DW_CFA_def_cfa_expression: /* DWARF3 */
+ {
+ Dwarf_Unsigned block_len =
+ local_dwarf_decode_u_leb128(instp + 1,
+ &uleblen);
+
+ instp += uleblen;
+ len -= uleblen;
+ off += uleblen;
+ printf
+ ("\t%2u DW_CFA_def_cfa_expression expr block len %"
+ DW_PR_DUu "\n",
+ loff,
+ block_len);
+ dump_block("\t\t", (char *) instp+1,
+ (Dwarf_Signed) block_len);
+ printf("\n");
+ if(verbose) {
+ struct esb_s exprstring;
+ esb_constructor(&exprstring);
+ get_string_from_locs(dbg,
+ instp+1,block_len,addr_size,&exprstring);
+ printf("\t\t%s\n",esb_get_string(&exprstring));
+ esb_destructor(&exprstring);
+ }
+ instp += block_len;
+ len -= block_len;
+ off += block_len;
+ }
+ break;
+ case DW_CFA_expression: /* DWARF3 */
+ uval = local_dwarf_decode_u_leb128(instp + 1, &uleblen);
+ instp += uleblen;
+ len -= uleblen;
+ off += uleblen;
+ {
+ /* instp is always 1 byte back, so we need +1
+ when we use it. See the final increment
+ of this for loop. */
+ Dwarf_Unsigned block_len =
+ local_dwarf_decode_u_leb128(instp + 1,
+ &uleblen);
+
+ instp += uleblen;
+ len -= uleblen;
+ off += uleblen;
+ printf
+ ("\t%2u DW_CFA_expression %" DW_PR_DUu
+ " expr block len %" DW_PR_DUu "\n",
+ loff, uval,
+ block_len);
+ dump_block("\t\t", (char *) instp+1,
+ (Dwarf_Signed) block_len);
+ printf("\n");
+ if(verbose) {
+ struct esb_s exprstring;
+ esb_constructor(&exprstring);
+ get_string_from_locs(dbg,
+ instp+1,block_len,addr_size,&exprstring);
+ printf("\t\t%s\n",esb_get_string(&exprstring));
+ esb_destructor(&exprstring);
+ }
+ instp += block_len;
+ len -= block_len;
+ off += block_len;
+ }
+ break;
+ case DW_CFA_offset_extended_sf: /* DWARF3 */
+ uval = local_dwarf_decode_u_leb128(instp + 1, &uleblen);
+ instp += uleblen;
+ len -= uleblen;
+ off += uleblen;
+ {
+ /* instp is always 1 byte back, so we need +1
+ when we use it. See the final increment
+ of this for loop. */
+ Dwarf_Signed sval2 =
+ local_dwarf_decode_s_leb128(instp + 1,
+ &uleblen);
+
+ instp += uleblen;
+ len -= uleblen;
+ off += uleblen;
+ printf("\t%2u DW_CFA_offset_extended_sf ", loff);
+ printreg((Dwarf_Signed) uval, config_data);
+ printf(" %" DW_PR_DSd , (Dwarf_Signed)
+ ((sval2) * data_alignment_factor));
+ if (verbose) {
+ printf(" (%" DW_PR_DSd " * %d)", sval2,
+ (int) data_alignment_factor);
+ }
+ }
+ printf("\n");
+ break;
+ case DW_CFA_def_cfa_sf: /* DWARF3 */
+ /* instp is always 1 byte back, so we need +1
+ when we use it. See the final increment
+ of this for loop. */
+ uval = local_dwarf_decode_u_leb128(instp + 1, &uleblen);
+ instp += uleblen;
+ len -= uleblen;
+ off += uleblen;
+ {
+ Dwarf_Signed sval2 =
+ local_dwarf_decode_s_leb128(instp + 1,
+ &uleblen);
+
+ instp += uleblen;
+ len -= uleblen;
+ off += uleblen;
+ printf("\t%2u DW_CFA_def_cfa_sf ", loff);
+ printreg((Dwarf_Signed) uval, config_data);
+ printf(" %" DW_PR_DSd , (long long) sval2);
+ printf(" (*data alignment factor=>%" DW_PR_DSd ")",
+ (Dwarf_Signed)(sval2*data_alignment_factor));
+ }
+ printf("\n");
+ break;
+ case DW_CFA_def_cfa_offset_sf: /* DWARF3 */
+ {
+ /* instp is always 1 byte back, so we need +1
+ when we use it. See the final increment
+ of this for loop. */
+ Dwarf_Signed sval =
+ local_dwarf_decode_s_leb128(instp + 1,
+ &uleblen);
+
+ instp += uleblen;
+ len -= uleblen;
+ off += uleblen;
+ printf("\t%2u DW_CFA_def_cfa_offset_sf %"
+ DW_PR_DSd " (*data alignment factor=> %"
+ DW_PR_DSd ")\n",
+ loff, sval,
+ (Dwarf_Signed)(data_alignment_factor*sval));
+
+ }
+ break;
+ case DW_CFA_val_offset: /* DWARF3 */
+ /* instp is always 1 byte back, so we need +1
+ when we use it. See the final increment
+ of this for loop. */
+ uval = local_dwarf_decode_u_leb128(instp + 1, &uleblen);
+ instp += uleblen;
+ len -= uleblen;
+ off += uleblen;
+ {
+ Dwarf_Signed sval2 =
+ local_dwarf_decode_s_leb128(instp + 1,
+ &uleblen);
+ instp += uleblen;
+ len -= uleblen;
+ off += uleblen;
+ printf("\t%2u DW_CFA_val_offset ", loff);
+ printreg((Dwarf_Signed)uval, config_data);
+ printf(" %" DW_PR_DSd ,
+ (Dwarf_Signed) (sval2 *
+ data_alignment_factor));
+ if (verbose) {
+ printf(" (%" DW_PR_DSd " * %d)",
+ (Dwarf_Signed) sval2,
+ (int) data_alignment_factor);
+ }
+ }
+ printf("\n");
+
+ break;
+ case DW_CFA_val_offset_sf: /* DWARF3 */
+ /* instp is always 1 byte back, so we need +1
+ when we use it. See the final increment
+ of this for loop. */
+ uval = local_dwarf_decode_u_leb128(instp + 1, &uleblen);
+ instp += uleblen;
+ len -= uleblen;
+ off += uleblen;
+ {
+ Dwarf_Signed sval2 =
+ local_dwarf_decode_s_leb128(instp + 1,
+ &uleblen);
+
+ instp += uleblen;
+ len -= uleblen;
+ off += uleblen;
+ printf("\t%2u DW_CFA_val_offset_sf ", loff);
+ printreg((Dwarf_Signed) uval, config_data);
+ printf(" %" DW_PR_DSd , (signed long long)
+ ((sval2) * data_alignment_factor));
+ if (verbose) {
+ printf(" (%" DW_PR_DSd " * %d)", sval2,
+ (int) data_alignment_factor);
+ }
+ }
+ printf("\n");
+
+ break;
+ case DW_CFA_val_expression: /* DWARF3 */
+ /* instp is always 1 byte back, so we need +1
+ when we use it. See the final increment
+ of this for loop. */
+ uval = local_dwarf_decode_u_leb128(instp + 1, &uleblen);
+ instp += uleblen;
+ len -= uleblen;
+ off += uleblen;
+ {
+ Dwarf_Unsigned block_len =
+ local_dwarf_decode_u_leb128(instp + 1,
+ &uleblen);
+
+ instp += uleblen;
+ len -= uleblen;
+ off += uleblen;
+ printf
+ ("\t%2u DW_CFA_val_expression %" DW_PR_DUu
+ " expr block len %" DW_PR_DUu "\n",
+ loff, uval,
+ block_len);
+ dump_block("\t\t", (char *) instp+1,
+ (Dwarf_Signed) block_len);
+ printf("\n");
+ if(verbose) {
+ struct esb_s exprstring;
+ esb_constructor(&exprstring);
+ get_string_from_locs(dbg,
+ instp+1,block_len,addr_size,&exprstring);
+ printf("\t\t%s\n",esb_get_string(&exprstring));
+ esb_destructor(&exprstring);
+ }
+ instp += block_len;
+ len -= block_len;
+ off += block_len;
+ }
+
+
+ break;
+
+
+#ifdef DW_CFA_GNU_window_save
+ case DW_CFA_GNU_window_save:{
+ /* no information: this just tells unwinder to
+ restore the window registers from the previous
+ frame's window save area */
+ printf("\t%2u DW_CFA_GNU_window_save \n", loff);
+ }
+ break;
+#endif
+#ifdef DW_CFA_GNU_negative_offset_extended
+ case DW_CFA_GNU_negative_offset_extended:{
+ printf("\t%2u DW_CFA_GNU_negative_offset_extended \n",
+ loff);
+ }
+ break;
+#endif
+#ifdef DW_CFA_GNU_args_size
+ /* single uleb128 is the current arg area size in
+ bytes. no register exists yet to save this in */
+ case DW_CFA_GNU_args_size:{
+ Dwarf_Unsigned lreg = 0;
+
+ /* instp is always 1 byte back, so we need +1
+ when we use it. See the final increment
+ of this for loop. */
+ lreg = local_dwarf_decode_u_leb128(instp + 1,
+ &uleblen);
+ printf("\t%2u DW_CFA_GNU_args_size arg size: %"
+ DW_PR_DUu "\n",
+ loff, lreg);
+ instp += uleblen;
+ len -= uleblen;
+ off += uleblen;
+ }
+ break;
+#endif
+
+ default:
+ printf(" %u Unexpected op 0x%x: \n",
+ loff, (unsigned int) bottom);
+ len = 0;
+ break;
+ }
+ }
+ instp++;
+ len--;
+ off++;
+ }
+}
+
+/* Print our register names for the cases we have a name.
+ Delegate to the configure code to actually do the print.
+*/
+void
+printreg(Dwarf_Signed reg, struct dwconf_s *config_data)
+{
+ print_reg_from_config_data(reg, config_data);
+}
+
+/* Actually does the printing of a rule in the table.
+ This may print something or may print nothing! */
+static void
+print_one_frame_reg_col(Dwarf_Debug dbg,
+ Dwarf_Unsigned rule_id,
+ Dwarf_Small value_type,
+ Dwarf_Unsigned reg_used,
+ Dwarf_Half addr_size,
+ struct dwconf_s *config_data,
+ Dwarf_Signed offset_relevant,
+ Dwarf_Signed offset,
+ Dwarf_Ptr block_ptr)
+{
+ char *type_title = "";
+ int print_type_title = 1;
+
+ if (check_frames_extended) {
+ return;
+ }
+
+ if (config_data->cf_interface_number == 2)
+ print_type_title = 0;
+
+ switch (value_type) {
+ case DW_EXPR_OFFSET:
+ type_title = "off";
+ goto preg2;
+ case DW_EXPR_VAL_OFFSET:
+ type_title = "valoff";
+
+ preg2:
+ if (reg_used == config_data->cf_initial_rule_value) {
+ break;
+ }
+ if (print_type_title)
+ printf("<%s ", type_title);
+ printreg((Dwarf_Signed) rule_id, config_data);
+ printf("=");
+ if (offset_relevant == 0) {
+ printreg((Dwarf_Signed) reg_used, config_data);
+ printf(" ");
+ } else {
+ printf("%02" DW_PR_DSd , offset);
+ printf("(");
+ printreg((Dwarf_Signed) reg_used, config_data);
+ printf(") ");
+ }
+ if (print_type_title)
+ printf("%s", "> ");
+ break;
+ case DW_EXPR_EXPRESSION:
+ type_title = "expr";
+ goto pexp2;
+ case DW_EXPR_VAL_EXPRESSION:
+ type_title = "valexpr";
+
+ pexp2:
+ if (print_type_title)
+ printf("<%s ", type_title);
+ printreg((Dwarf_Signed) rule_id, config_data);
+ printf("=");
+ printf("expr-block-len=%" DW_PR_DSd , offset);
+ if (print_type_title)
+ printf("%s", "> ");
+ if (verbose) {
+ char pref[40];
+
+ strcpy(pref, "<");
+ strcat(pref, type_title);
+ strcat(pref, "bytes:");
+ dump_block(pref, block_ptr, offset);
+ printf("%s", "> ");
+ if(verbose) {
+ struct esb_s exprstring;
+ esb_constructor(&exprstring);
+ get_string_from_locs(dbg,
+ block_ptr,offset,addr_size,&exprstring);
+ printf("<expr:%s>",esb_get_string(&exprstring));
+ esb_destructor(&exprstring);
+ }
+ }
+ break;
+ default:
+ printf("Internal error in libdwarf, value type %d\n",
+ value_type);
+ exit(1);
+ }
+ return;
+}
+
+
+/* get all the data in .debug_frame (or .eh_frame).
+ The '3' versions mean print using the dwarf3 new interfaces.
+ The non-3 mean use the old interfaces.
+ All combinations of requests are possible. */
+extern void
+print_frames(Dwarf_Debug dbg, int print_debug_frame, int print_eh_frame,
+ struct dwconf_s *config_data)
+{
+ Dwarf_Signed i;
+ int fres = 0;
+ Dwarf_Half address_size = 0;
+ int framed = 0;
+ void * map_lowpc_to_name = 0;
+
+ current_section_id = DEBUG_FRAME;
+
+ /* The address size here will not be right for all frames.
+ Only in DWARF4 is there a real address size known
+ in the frame data itself. If any DIE
+ is known then a real address size can be gotten from
+ dwarf_get_die_address_size(). */
+ fres = dwarf_get_address_size(dbg, &address_size, &err);
+ if (fres != DW_DLV_OK) {
+ print_error(dbg, "dwarf_get_address_size", fres, err);
+ }
+ for (framed = 0; framed < 2; ++framed) {
+ Dwarf_Cie *cie_data = NULL;
+ Dwarf_Signed cie_element_count = 0;
+ Dwarf_Fde *fde_data = NULL;
+ Dwarf_Signed fde_element_count = 0;
+ int frame_count = 0;
+ int cie_count = 0;
+ int all_cus_seen = 0;
+ void * lowpcSet = 0;
+ char *framename = 0;
+ int silent_if_missing = 0;
+ int is_eh = 0;
+
+ if (framed == 0) {
+ if (!print_debug_frame) {
+ continue;
+ }
+ framename = ".debug_frame";
+ /* Big question here is how to print all the info?
+ Can print the logical matrix, but that is huge,
+ though could skip lines that don't change.
+ Either that, or print the instruction statement program
+ that describes the changes. */
+ fres = dwarf_get_fde_list(dbg, &cie_data, &cie_element_count,
+ &fde_data, &fde_element_count, &err);
+ if(check_harmless) {
+ print_any_harmless_errors(dbg);
+ }
+ } else {
+ if (!print_eh_frame) {
+ continue;
+ }
+ is_eh = 1;
+ /* This is gnu g++ exceptions in a .eh_frame section. Which
+ is just like .debug_frame except that the empty, or
+ 'special' CIE_id is 0, not -1 (to distinguish fde from
+ cie). And the augmentation is "eh". As of egcs-1.1.2
+ anyway. A non-zero cie_id is in a fde and is the
+ difference between the fde address and the beginning of
+ the cie it belongs to. This makes sense as this is
+ intended to be referenced at run time, and is part of
+ the running image. For more on augmentation strings, see
+ libdwarf/dwarf_frame.c. */
+
+ /* Big question here is how to print all the info?
+ Can print the logical matrix, but that is huge,
+ though could skip lines that don't change.
+ Either that, or print the instruction statement program
+ that describes the changes. */
+ silent_if_missing = 1;
+ framename = ".eh_frame";
+ fres = dwarf_get_fde_list_eh(dbg, &cie_data,
+ &cie_element_count, &fde_data,
+ &fde_element_count, &err);
+ if(check_harmless) {
+ print_any_harmless_errors(dbg);
+ }
+ }
+
+ /* Do not print any frame info if in check mode */
+ if (check_frames) {
+ addr_map_destroy(lowpcSet);
+ lowpcSet = 0;
+ continue;
+ }
+
+ if (fres == DW_DLV_ERROR) {
+ printf("\n%s\n", framename);
+ print_error(dbg, "dwarf_get_fde_list", fres, err);
+ } else if (fres == DW_DLV_NO_ENTRY) {
+ if (!silent_if_missing) {
+ printf("\n%s\n", framename);
+ }
+ /* no frame information */
+ } else { /* DW_DLV_OK */
+ /* Do not print if in check mode */
+ if (!check_frames_extended) {
+ printf("\n%s\n", framename);
+ printf("\nfde:\n");
+ }
+
+ for (i = 0; i < fde_element_count; i++) {
+ print_one_fde(dbg, fde_data[i],
+ i, cie_data, cie_element_count,
+ address_size, is_eh, config_data,
+ &map_lowpc_to_name,
+ &lowpcSet,
+ &all_cus_seen);
+ ++frame_count;
+ if(frame_count >= break_after_n_units) {
+ break;
+ }
+ }
+ /* Print the cie set. */
+ if (verbose) {
+ /* Do not print if in check mode */
+ if (!check_frames_extended) {
+ printf("\ncie:\n");
+ }
+ for (i = 0; i < cie_element_count; i++) {
+ print_one_cie(dbg, cie_data[i], i, address_size,
+ config_data);
+ ++cie_count;
+ if(cie_count >= break_after_n_units) {
+ break;
+ }
+ }
+ }
+ dwarf_fde_cie_list_dealloc(dbg, cie_data, cie_element_count,
+ fde_data, fde_element_count);
+ }
+ addr_map_destroy(lowpcSet);
+ lowpcSet = 0;
+ }
+ if (current_cu_die_for_print_frames) {
+ dwarf_dealloc(dbg, current_cu_die_for_print_frames, DW_DLA_DIE);
+ current_cu_die_for_print_frames = 0;
+ }
+ addr_map_destroy(map_lowpc_to_name);
+}
+
diff --git a/dwarfdump/print_frames.h b/dwarfdump/print_frames.h
new file mode 100644
index 0000000..2a133d8
--- /dev/null
+++ b/dwarfdump/print_frames.h
@@ -0,0 +1,47 @@
+/*
+ Copyright (C) 2006 Silicon Graphics, Inc. All Rights Reserved.
+ Portions Copyright (C) 2009-2011 David Anderson. All Rights Reserved.
+
+ This program is free software; you can redistribute it and/or modify it
+ under the terms of version 2 of the GNU General Public License as
+ published by the Free Software Foundation.
+
+ This program is distributed in the hope that it would be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+ Further, this software is distributed without any warranty that it is
+ free of the rightful claim of any third person regarding infringement
+ or the like. Any license provided herein, whether implied or
+ otherwise, applies only to this software file. Patent licenses, if
+ any, provided herein do not apply to combinations of this program with
+ other software, or any other product whatsoever.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write the Free Software Foundation, Inc., 51
+ Franklin Street - Fifth Floor, Boston MA 02110-1301, USA.
+
+ Contact information: Silicon Graphics, Inc., 1500 Crittenden Lane,
+ Mountain View, CA 94043, or:
+
+ http://www.sgi.com
+
+ For further information regarding this notice, see:
+
+ http://oss.sgi.com/projects/GenInfo/NoticeExplan
+
+
+
+ $Header: /plroot/cmplrs.src/v7.4.5m/.RCS/PL/dwarfdump/RCS/print_frames.h,v 1.2 2006/04/17 00:09:56 davea Exp $ */
+
+int print_one_cie(Dwarf_Debug dbg, Dwarf_Cie cie,
+ Dwarf_Unsigned cie_index,
+ Dwarf_Half address_size,
+ struct dwconf_s * config_data);
+
+void get_string_from_locs(Dwarf_Debug dbg,
+ Dwarf_Ptr bytes_in,
+ Dwarf_Unsigned block_len,
+ Dwarf_Half addr_size,
+ struct esb_s *out_string);
+
diff --git a/dwarfdump/print_lines.c b/dwarfdump/print_lines.c
new file mode 100644
index 0000000..4b33994
--- /dev/null
+++ b/dwarfdump/print_lines.c
@@ -0,0 +1,433 @@
+
+/*
+ Copyright (C) 2000-2006 Silicon Graphics, Inc. All Rights Reserved.
+ Portions Copyright 2007-2010 Sun Microsystems, Inc. All rights reserved.
+ Portions Copyright 2009-2011 SN Systems Ltd. All rights reserved.
+ Portions Copyright 2008-2011 David Anderson. All rights reserved.
+
+ This program is free software; you can redistribute it and/or modify it
+ under the terms of version 2 of the GNU General Public License as
+ published by the Free Software Foundation.
+
+ This program is distributed in the hope that it would be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+ Further, this software is distributed without any warranty that it is
+ free of the rightful claim of any third person regarding infringement
+ or the like. Any license provided herein, whether implied or
+ otherwise, applies only to this software file. Patent licenses, if
+ any, provided herein do not apply to combinations of this program with
+ other software, or any other product whatsoever.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write the Free Software Foundation, Inc., 51
+ Franklin Street - Fifth Floor, Boston MA 02110-1301, USA.
+
+ Contact information: Silicon Graphics, Inc., 1500 Crittenden Lane,
+ Mountain View, CA 94043, or:
+
+ http://www.sgi.com
+
+ For further information regarding this notice, see:
+
+ http://oss.sgi.com/projects/GenInfo/NoticeExplan
+
+
+
+$Header: /plroot/cmplrs.src/v7.4.5m/.RCS/PL/dwarfdump/RCS/print_sections.c,v 1.69 2006/04/17 00:09:56 davea Exp $ */
+/* The address of the Free Software Foundation is
+ Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+ SGI has moved from the Crittenden Lane address. */
+
+#include "globals.h"
+#include "naming.h"
+#include "dwconf.h"
+#include "esb.h"
+#include "uri.h"
+#include <ctype.h>
+
+#include "print_sections.h"
+
+/*
+ Print line number information:
+ [line] [address] <new statement>
+ new basic-block
+ filename
+*/
+
+
+static void
+print_source_intro(Dwarf_Die cu_die)
+{
+ Dwarf_Off off = 0;
+ int ores = dwarf_dieoffset(cu_die, &off, &err);
+
+ if (ores == DW_DLV_OK) {
+ printf("Source lines (from CU-DIE at .debug_info offset 0x%"
+ DW_PR_XZEROS DW_PR_DUx "):\n",
+ (Dwarf_Unsigned) off);
+ } else {
+ printf("Source lines (for the CU-DIE at unknown location):\n");
+ }
+}
+
+static void
+record_line_error(const char *where, Dwarf_Error err)
+{
+ char tmp_buff[500];
+ if(check_lines && checking_this_compiler()) {
+ snprintf(tmp_buff, sizeof(tmp_buff),
+ "Error getting line details calling %s dwarf error is %s",
+ where,dwarf_errmsg(err));
+ DWARF_CHECK_ERROR(lines_result,tmp_buff);
+ }
+}
+
+extern void
+print_line_numbers_this_cu(Dwarf_Debug dbg, Dwarf_Die cu_die)
+{
+ Dwarf_Signed linecount = 0;
+ Dwarf_Line *linebuf = NULL;
+ Dwarf_Signed i = 0;
+ Dwarf_Addr pc = 0;
+ Dwarf_Unsigned lineno = 0;
+ Dwarf_Unsigned column = 0;
+
+ Dwarf_Bool newstatement = 0;
+ Dwarf_Bool lineendsequence = 0;
+ Dwarf_Bool new_basic_block = 0;
+ int lres = 0;
+ int sres = 0;
+ int ares = 0;
+ int lires = 0;
+ int cores = 0;
+ int line_errs = 0;
+
+ Dwarf_Bool SkipRecord = FALSE;
+
+ current_section_id = DEBUG_LINE;
+
+ /* line_flag is TRUE */
+
+ if (do_print_dwarf) {
+ printf("\n.debug_line: line number info for a single cu\n");
+ }
+ if (verbose > 1) {
+ int errcount = 0;
+ print_source_intro(cu_die);
+ print_one_die(dbg, cu_die,
+ /* print_information= */ 1,
+ /* indent level */0,
+ /* srcfiles= */ 0, /* cnt= */ 0,
+ /* ignore_die_stack= */TRUE);
+ DWARF_CHECK_COUNT(lines_result,1);
+ lres = dwarf_print_lines(cu_die, &err,&errcount);
+ if(errcount > 0) {
+ DWARF_ERROR_COUNT(lines_result,errcount);
+ DWARF_CHECK_COUNT(lines_result,(errcount-1));
+ }
+ if (lres == DW_DLV_ERROR) {
+ print_error(dbg, "dwarf_srclines details", lres, err);
+ }
+ return;
+ }
+
+ if(check_lines && checking_this_compiler()) {
+ DWARF_CHECK_COUNT(lines_result,1);
+ dwarf_check_lineheader(cu_die,&line_errs);
+ if(line_errs > 0) {
+ DWARF_CHECK_ERROR_PRINT_CU();
+ DWARF_ERROR_COUNT(lines_result,line_errs);
+ DWARF_CHECK_COUNT(lines_result,(line_errs-1));
+ }
+ }
+ lres = dwarf_srclines(cu_die, &linebuf, &linecount, &err);
+ if (lres == DW_DLV_ERROR) {
+ /* Do not terminate processing */
+ if (check_decl_file) {
+ DWARF_CHECK_COUNT(decl_file_result,1);
+ DWARF_CHECK_ERROR2(decl_file_result,"dwarf_srclines",
+ dwarf_errmsg(err));
+ record_dwarf_error = FALSE; /* Clear error condition */
+ } else {
+ print_error(dbg, "dwarf_srclines", lres, err);
+ }
+ } else if (lres == DW_DLV_NO_ENTRY) {
+ /* no line information is included */
+ } else {
+ struct esb_s lastsrc;;
+ esb_constructor(&lastsrc);
+ if (do_print_dwarf) {
+ print_source_intro(cu_die);
+ if (verbose) {
+ print_one_die(dbg, cu_die,
+ /* print_information= */ TRUE,
+ /* indent_level= */ 0,
+ /* srcfiles= */ 0, /* cnt= */ 0,
+ /* ignore_die_stack= */TRUE);
+ }
+ printf("\n<pc> [row,col] "
+ "NS BB ET PE EB IS= DI= uri: \"filepath\"\n");
+ printf("NS new statement, BB new basic block, "
+ "ET end of text sequence\n");
+ printf("PE prologue end, EB epilogue begin\n");
+ printf("IA=val ISA number, DI=val discriminator value\n");
+ }
+ for (i = 0; i < linecount; i++) {
+ Dwarf_Line line = linebuf[i];
+ string filename = 0;
+ int nsres = 0;
+ Dwarf_Bool found_line_error = FALSE;
+ Dwarf_Bool has_is_addr_set = FALSE;
+ char *where = NULL;
+
+ if (check_decl_file && checking_this_compiler()) {
+ /* A line record with addr=0 was detected */
+ if (SkipRecord) {
+ /* Skip records that do not have ís_addr_set' */
+ ares = dwarf_line_is_addr_set(line, &has_is_addr_set, &err);
+ if (ares == DW_DLV_OK && has_is_addr_set) {
+ SkipRecord = FALSE;
+ }
+ else {
+ /* Keep ignoring records until we have
+ one with 'is_addr_set' */
+ continue;
+ }
+ }
+ }
+
+ if(check_lines && checking_this_compiler()) {
+ DWARF_CHECK_COUNT(lines_result,1);
+ }
+ filename = "<unknown>";
+ sres = dwarf_linesrc(line, &filename, &err);
+ if (sres == DW_DLV_ERROR) {
+ /* Do not terminate processing */
+ where = "dwarf_linesrc()";
+ record_line_error(where,err);
+ found_line_error = TRUE;
+ }
+
+ ares = dwarf_lineaddr(line, &pc, &err);
+
+ if (ares == DW_DLV_ERROR) {
+ /* Do not terminate processing */
+ where = "dwarf_lineaddr()";
+ record_line_error(where,err);
+ found_line_error = TRUE;
+ }
+ if (ares == DW_DLV_NO_ENTRY) {
+ pc = 0;
+ }
+ lires = dwarf_lineno(line, &lineno, &err);
+ if (lires == DW_DLV_ERROR) {
+ /* Do not terminate processing */
+ where = "dwarf_lineno()";
+ record_line_error(where,err);
+ found_line_error = TRUE;
+ }
+ if (lires == DW_DLV_NO_ENTRY) {
+ lineno = -1LL;
+ }
+ cores = dwarf_lineoff_b(line, &column, &err);
+ if (cores == DW_DLV_ERROR) {
+ /* Do not terminate processing */
+ where = "dwarf_lineoff()";
+ record_line_error(where,err);
+ found_line_error = TRUE;
+ }
+ if (cores == DW_DLV_NO_ENTRY) {
+ /* Zero was always the correct default, meaning
+ the left edge. DWARF2/3/4 spec sec 6.2.2 */
+ column = 0;
+ }
+
+ /* Process any possible error condition, though
+ we won't be at the first such error. */
+ if (check_decl_file && checking_this_compiler()) {
+ DWARF_CHECK_COUNT(decl_file_result,1);
+ if (found_line_error) {
+ DWARF_CHECK_ERROR2(decl_file_result,where,dwarf_errmsg(err));
+ } else if (do_check_dwarf) {
+ /* Check the address lies with a valid [lowPC:highPC]
+ in the .text section*/
+ if (IsValidInBucketGroup(pRangesInfo,pc)) {
+ /* Valid values; do nothing */
+ } else {
+ /* At this point may be we are dealing with
+ a linkonce symbol. The problem we have here
+ is we have consumed the deug_info section
+ and we are dealing just with the records
+ from the .debug_line, so no PU_name is
+ available and no high_pc. Traverse the linkonce
+ table if try to match the pc value with
+ one of those ranges.
+ */
+ if(check_lines && checking_this_compiler()) {
+ DWARF_CHECK_COUNT(lines_result,1);
+ }
+ if (FindAddressInBucketGroup(pLinkonceInfo,pc)){
+ /* Valid values; do nothing */
+ } else {
+ /* The SN Systems Linker generates
+ line records
+ with addr=0, when dealing with linkonce
+ symbols and no stripping */
+ if (pc) {
+ char addr_tmp[100];
+ if(check_lines && checking_this_compiler()) {
+ snprintf(addr_tmp,sizeof(addr_tmp),
+ ".debug_line: Address"
+ " 0x%" DW_PR_XZEROS DW_PR_DUx
+ " outside a valid .text range",pc);
+ DWARF_CHECK_ERROR(lines_result,
+ addr_tmp);
+ }
+ } else {
+ SkipRecord = TRUE;
+ }
+ }
+ }
+ /* Check the last record for the .debug_line,
+ the one created by DW_LNE_end_sequence,
+ is the same as the high_pc
+ address for the last known user program
+ unit (PU) */
+ if ((i + 1 == linecount) &&
+ seen_PU_high_address) {
+ /* Ignore those PU that have been stripped
+ by the linker; their low_pc values are
+ set to -1 (snc linker only) */
+ /* It is perfectly sensible for a compiler
+ to leave a few bytes of NOP or other stuff
+ after the last instruction in a subprogram,
+ for cache-alignment or other purposes, so
+ a mismatch here is not necessarily
+ an error. */
+
+ if (check_lines && checking_this_compiler()) {
+ DWARF_CHECK_COUNT(lines_result,1);
+ if ((pc != PU_high_address) &&
+ (PU_base_address != elf_max_address)) {
+ char addr_tmp[100];
+ snprintf(addr_tmp,sizeof(addr_tmp),
+ ".debug_line: Address"
+ " 0x%" DW_PR_XZEROS DW_PR_DUx
+ " may be incorrect"
+ " as DW_LNE_end_sequence address",pc);
+ DWARF_CHECK_ERROR(lines_result,
+ addr_tmp);
+ }
+ }
+ }
+ }
+ }
+
+ /* Display the error information */
+ if (found_line_error || record_dwarf_error) {
+ if (check_verbose_mode) {
+ /* Print the record number for better error description */
+ printf("Record = %" DW_PR_DUu
+ " Addr = 0x%" DW_PR_XZEROS DW_PR_DUx
+ " [%4" DW_PR_DUu ",%2" DW_PR_DUu "] '%s'\n",
+ i, pc,lineno,column,filename);
+ /* Flush due to the redirection of stderr */
+ fflush(stdout);
+ /* The compilation unit was already printed */
+ if (!check_decl_file) {
+ PRINT_CU_INFO();
+ }
+ }
+ record_dwarf_error = FALSE;
+ /* Due to a fatal error, skip current record */
+ if (found_line_error) {
+ continue;
+ }
+ }
+ if (do_print_dwarf) {
+ printf("0x%08" DW_PR_DUx
+ " [%4" DW_PR_DUu ",%2" DW_PR_DUu "]", pc, lineno,
+ column);
+ }
+
+ nsres = dwarf_linebeginstatement(line, &newstatement, &err);
+ if (nsres == DW_DLV_OK) {
+ if (newstatement && do_print_dwarf) {
+ printf(" %s","NS");
+ }
+ } else if (nsres == DW_DLV_ERROR) {
+ print_error(dbg, "linebeginstatment failed", nsres, err);
+ }
+ nsres = dwarf_lineblock(line, &new_basic_block, &err);
+ if (nsres == DW_DLV_OK) {
+ if (new_basic_block && do_print_dwarf) {
+ printf(" %s","BB");
+ }
+ } else if (nsres == DW_DLV_ERROR) {
+ print_error(dbg, "lineblock failed", nsres, err);
+ }
+ nsres = dwarf_lineendsequence(line, &lineendsequence, &err);
+ if (nsres == DW_DLV_OK) {
+ if (lineendsequence && do_print_dwarf) {
+ printf(" %s", "ET");
+ }
+ } else if (nsres == DW_DLV_ERROR) {
+ print_error(dbg, "lineblock failed", nsres, err);
+ }
+ if(do_print_dwarf) {
+ Dwarf_Bool prologue_end = 0;
+ Dwarf_Bool epilogue_begin = 0;
+ Dwarf_Unsigned isa = 0;
+ Dwarf_Unsigned discriminator = 0;
+ int disres = dwarf_prologue_end_etc(line,
+ &prologue_end,&epilogue_begin,
+ &isa,&discriminator,&err);
+ if (disres == DW_DLV_ERROR) {
+ print_error(dbg, "dwarf_prologue_end_etc() failed",
+ disres, err);
+ }
+ if(prologue_end) {
+ printf(" PE");
+ }
+ if(epilogue_begin) {
+ printf(" EB");
+ }
+ if(isa) {
+ printf(" IS=0x%" DW_PR_DUx, isa);
+ }
+ if(discriminator) {
+ printf(" DI=0x%" DW_PR_DUx, discriminator);
+ }
+ }
+
+
+ if (i > 0 && verbose < 3 &&
+ strcmp(filename,esb_get_string(&lastsrc)) == 0) {
+ /* Do not print name. */
+ } else {
+ struct esb_s urs;
+ esb_constructor(&urs);
+ esb_append(&urs, " uri: \"");
+ translate_to_uri(filename,&urs);
+ esb_append(&urs,"\"");
+ if(do_print_dwarf) {
+ printf("%s",esb_get_string(&urs));
+ }
+ esb_destructor(&urs);
+ esb_empty_string(&lastsrc);
+ esb_append(&lastsrc,filename);
+ }
+ if (sres == DW_DLV_OK) {
+ dwarf_dealloc(dbg, filename, DW_DLA_STRING);
+ }
+ if (do_print_dwarf) {
+ printf("\n");
+ }
+ }
+ esb_destructor(&lastsrc);
+ dwarf_srclines_dealloc(dbg, linebuf, linecount);
+ }
+}
diff --git a/dwarfdump/print_locs.c b/dwarfdump/print_locs.c
new file mode 100644
index 0000000..c7cf99f
--- /dev/null
+++ b/dwarfdump/print_locs.c
@@ -0,0 +1,128 @@
+/*
+ Copyright (C) 2000-2006 Silicon Graphics, Inc. All Rights Reserved.
+ Portions Copyright 2007-2010 Sun Microsystems, Inc. All rights reserved.
+ Portions Copyright 2009-2010 SN Systems Ltd. All rights reserved.
+ Portions Copyright 2008-2011 David Anderson. All rights reserved.
+
+ This program is free software; you can redistribute it and/or modify it
+ under the terms of version 2 of the GNU General Public License as
+ published by the Free Software Foundation.
+
+ This program is distributed in the hope that it would be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+ Further, this software is distributed without any warranty that it is
+ free of the rightful claim of any third person regarding infringement
+ or the like. Any license provided herein, whether implied or
+ otherwise, applies only to this software file. Patent licenses, if
+ any, provided herein do not apply to combinations of this program with
+ other software, or any other product whatsoever.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write the Free Software Foundation, Inc., 51
+ Franklin Street - Fifth Floor, Boston MA 02110-1301, USA.
+
+ Contact information: Silicon Graphics, Inc., 1500 Crittenden Lane,
+ Mountain View, CA 94043, or:
+
+ http://www.sgi.com
+
+ For further information regarding this notice, see:
+
+ http://oss.sgi.com/projects/GenInfo/NoticeExplan
+
+
+
+$Header: /plroot/cmplrs.src/v7.4.5m/.RCS/PL/dwarfdump/RCS/print_sections.c,v 1.69 2006/04/17 00:09:56 davea Exp $ */
+/* The address of the Free Software Foundation is
+ Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+ SGI has moved from the Crittenden Lane address.
+*/
+
+#include "globals.h"
+#include "naming.h"
+#include "dwconf.h"
+#include "esb.h"
+
+#include "print_sections.h"
+#include "print_frames.h"
+
+/* print data in .debug_loc
+ There is no guarantee this will work because we are assuming
+ that all bytes are valid loclist data, that there are no
+ odd padding or garbage bytes. In normal use one gets
+ into here via an offset from .debug_info, so it could be
+ that bytes not referenced from .debug_info are garbage
+ or even zero padding. So this can fail (error off) as such bytes
+ can lead dwarf_get_loclist_entry() astray.
+
+ It's also wrong because we don't know what CU or frame each
+ loclist is from, so we don't know the address_size for sure.
+*/
+extern void
+print_locs(Dwarf_Debug dbg)
+{
+ Dwarf_Unsigned offset = 0;
+ Dwarf_Addr hipc_offset = 0;
+ Dwarf_Addr lopc_offset = 0;
+ Dwarf_Ptr data = 0;
+ Dwarf_Unsigned entry_len = 0;
+ Dwarf_Unsigned next_entry = 0;
+ struct esb_s exprstring;
+ int index = 0;
+ int lres = 0;
+ int fres = 0;
+
+ /* This is sometimes wrong, we need a frame-specific size. */
+ Dwarf_Half address_size = 0;
+
+ current_section_id = DEBUG_LOC;
+
+ /* Do nothing if not printing. */
+ if (!do_print_dwarf) {
+ return;
+ }
+
+ fres = dwarf_get_address_size(dbg, &address_size, &err);
+ if (fres != DW_DLV_OK) {
+ print_error(dbg, "dwarf_get_address_size", fres, err);
+ }
+
+ printf("\n.debug_loc");
+
+ printf("\nFormat <i o b e l>: "
+ "index section-offset begin-addr end-addr length-of-block-entry\n");
+ esb_constructor(&exprstring);
+ while ((lres = dwarf_get_loclist_entry(dbg, offset,
+ &hipc_offset, &lopc_offset,
+ &data, &entry_len,
+ &next_entry,
+ &err)) == DW_DLV_OK) {
+ get_string_from_locs(dbg,data,entry_len,address_size,
+ &exprstring);
+ /* Display offsets */
+ if (display_offsets) {
+ ++index;
+ printf(" <iobel> [%8d] 0x%" DW_PR_XZEROS DW_PR_DUx,
+ index, offset);
+ if(verbose) {
+ printf(" <expr-off 0x%" DW_PR_XZEROS DW_PR_DUx ">",
+ next_entry - entry_len);
+ }
+ }
+ printf(" 0x%" DW_PR_XZEROS DW_PR_DUx
+ " 0x%" DW_PR_XZEROS DW_PR_DUx
+ " %8" DW_PR_DUu " %s\n",
+ (Dwarf_Unsigned) lopc_offset,
+ (Dwarf_Unsigned) hipc_offset, entry_len,
+ esb_get_string(&exprstring));
+ esb_empty_string(&exprstring);
+ offset = next_entry;
+ }
+ esb_destructor(&exprstring);
+ if (lres == DW_DLV_ERROR) {
+ print_error(dbg, "dwarf_get_loclist_entry", lres, err);
+ }
+}
diff --git a/dwarfdump/print_macros.c b/dwarfdump/print_macros.c
new file mode 100644
index 0000000..0a36fc9
--- /dev/null
+++ b/dwarfdump/print_macros.c
@@ -0,0 +1,216 @@
+/*
+ Copyright (C) 2000-2006 Silicon Graphics, Inc. All Rights Reserved.
+ Portions Copyright 2007-2010 Sun Microsystems, Inc. All rights reserved.
+ Portions Copyright 2009-2011 SN Systems Ltd. All rights reserved.
+ Portions Copyright 2008-2011 David Anderson. All rights reserved.
+
+ This program is free software; you can redistribute it and/or modify it
+ under the terms of version 2 of the GNU General Public License as
+ published by the Free Software Foundation.
+
+ This program is distributed in the hope that it would be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+ Further, this software is distributed without any warranty that it is
+ free of the rightful claim of any third person regarding infringement
+ or the like. Any license provided herein, whether implied or
+ otherwise, applies only to this software file. Patent licenses, if
+ any, provided herein do not apply to combinations of this program with
+ other software, or any other product whatsoever.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write the Free Software Foundation, Inc., 51
+ Franklin Street - Fifth Floor, Boston MA 02110-1301, USA.
+
+ Contact information: Silicon Graphics, Inc., 1500 Crittenden Lane,
+ Mountain View, CA 94043, or:
+
+ http://www.sgi.com
+
+ For further information regarding this notice, see:
+
+ http://oss.sgi.com/projects/GenInfo/NoticeExplan
+
+
+
+$Header: /plroot/cmplrs.src/v7.4.5m/.RCS/PL/dwarfdump/RCS/print_sections.c,v 1.69 2006/04/17 00:09:56 davea Exp $ */
+/* The address of the Free Software Foundation is
+ Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+ SGI has moved from the Crittenden Lane address.
+*/
+
+#include "globals.h"
+#include "naming.h"
+#include "dwconf.h"
+#include "esb.h"
+
+#include "print_sections.h"
+#include "print_frames.h"
+
+
+struct macro_counts_s {
+ long mc_start_file;
+ long mc_end_file;
+ long mc_define;
+ long mc_undef;
+ long mc_extension;
+ long mc_code_zero;
+ long mc_unknown;
+};
+
+static void
+print_one_macro_entry_detail(long i,
+ char *type,
+ struct Dwarf_Macro_Details_s *mdp)
+{
+ /* "DW_MACINFO_*: section-offset file-index [line] string\n" */
+ if (mdp->dmd_macro) {
+ printf("%3ld %s: %6" DW_PR_DUu " %2" DW_PR_DSd " [%4"
+ DW_PR_DSd "] \"%s\" \n",
+ i,
+ type,
+ (Dwarf_Unsigned)mdp->dmd_offset,
+ mdp->dmd_fileindex, mdp->dmd_lineno, mdp->dmd_macro);
+ } else {
+ printf("%3ld %s: %6" DW_PR_DUu " %2" DW_PR_DSd " [%4"
+ DW_PR_DSd "] 0\n",
+ i,
+ type,
+ (Dwarf_Unsigned)mdp->dmd_offset,
+ mdp->dmd_fileindex, mdp->dmd_lineno);
+ }
+
+}
+
+static void
+print_one_macro_entry(long i,
+ struct Dwarf_Macro_Details_s *mdp,
+ struct macro_counts_s *counts)
+{
+
+ switch (mdp->dmd_type) {
+ case 0:
+ counts->mc_code_zero++;
+ print_one_macro_entry_detail(i, "DW_MACINFO_type-code-0", mdp);
+ break;
+
+ case DW_MACINFO_start_file:
+ counts->mc_start_file++;
+ print_one_macro_entry_detail(i, "DW_MACINFO_start_file", mdp);
+ break;
+
+ case DW_MACINFO_end_file:
+ counts->mc_end_file++;
+ print_one_macro_entry_detail(i, "DW_MACINFO_end_file ", mdp);
+ break;
+
+ case DW_MACINFO_vendor_ext:
+ counts->mc_extension++;
+ print_one_macro_entry_detail(i, "DW_MACINFO_vendor_ext", mdp);
+ break;
+
+ case DW_MACINFO_define:
+ counts->mc_define++;
+ print_one_macro_entry_detail(i, "DW_MACINFO_define ", mdp);
+ break;
+
+ case DW_MACINFO_undef:
+ counts->mc_undef++;
+ print_one_macro_entry_detail(i, "DW_MACINFO_undef ", mdp);
+ break;
+
+ default:
+ {
+ char create_type[50]; /* More than large enough. */
+
+ counts->mc_unknown++;
+ snprintf(create_type, sizeof(create_type),
+ "DW_MACINFO_0x%x", mdp->dmd_type);
+ print_one_macro_entry_detail(i, create_type, mdp);
+ }
+ break;
+ }
+}
+
+/* print data in .debug_macinfo */
+/* FIXME: should print name of file whose index is in macro data
+ here -- somewhere. */
+/*ARGSUSED*/ extern void
+print_macinfo(Dwarf_Debug dbg)
+{
+ Dwarf_Off offset = 0;
+ Dwarf_Unsigned max = 0;
+ Dwarf_Signed count = 0;
+ long group = 0;
+ Dwarf_Macro_Details *maclist = NULL;
+ int lres = 0;
+
+ current_section_id = DEBUG_MACINFO;
+ if (!do_print_dwarf) {
+ return;
+ }
+
+ printf("\n.debug_macinfo\n");
+
+ while ((lres = dwarf_get_macro_details(dbg, offset,
+ max, &count, &maclist,
+ &err)) == DW_DLV_OK) {
+ long i = 0;
+ struct macro_counts_s counts;
+
+
+ memset(&counts, 0, sizeof(counts));
+
+ printf("\n");
+ printf("compilation-unit .debug_macinfo # %ld\n", group);
+ printf
+ ("num name section-offset file-index [line] \"string\"\n");
+ for (i = 0; i < count; i++) {
+ struct Dwarf_Macro_Details_s *mdp = &maclist[i];
+
+ print_one_macro_entry(i, mdp, &counts);
+ }
+
+ if (counts.mc_start_file == 0) {
+ printf
+ ("DW_MACINFO file count of zero is invalid DWARF2/3\n");
+ }
+ if (counts.mc_start_file != counts.mc_end_file) {
+ printf("Counts of DW_MACINFO file (%ld) end_file (%ld) "
+ "do not match!.\n",
+ counts.mc_start_file, counts.mc_end_file);
+ }
+ if (counts.mc_code_zero < 1) {
+ printf("Count of zeros in macro group should be non-zero "
+ "(1 preferred), count is %ld\n",
+ counts.mc_code_zero);
+ }
+ printf("Macro counts: start file %ld, "
+ "end file %ld, "
+ "define %ld, "
+ "undef %ld, "
+ "ext %ld, "
+ "code-zero %ld, "
+ "unknown %ld\n",
+ counts.mc_start_file,
+ counts.mc_end_file,
+ counts.mc_define,
+ counts.mc_undef,
+ counts.mc_extension,
+ counts.mc_code_zero, counts.mc_unknown);
+
+
+ /* int type= maclist[count - 1].dmd_type; */
+ /* ASSERT: type is zero */
+
+ offset = maclist[count - 1].dmd_offset + 1;
+ dwarf_dealloc(dbg, maclist, DW_DLA_STRING);
+ ++group;
+ }
+ if (lres == DW_DLV_ERROR) {
+ print_error(dbg, "dwarf_get_macro_details", lres, err);
+ }
+}
+
diff --git a/dwarfdump/print_pubnames.c b/dwarfdump/print_pubnames.c
new file mode 100644
index 0000000..8018152
--- /dev/null
+++ b/dwarfdump/print_pubnames.c
@@ -0,0 +1,300 @@
+/*
+ Copyright (C) 2000-2006 Silicon Graphics, Inc. All Rights Reserved.
+ Portions Copyright 2007-2010 Sun Microsystems, Inc. All rights reserved.
+v Portions Copyright 2009-2011 SN Systems Ltd. All rights reserved.
+ Portions Copyright 2008-2011 David Anderson. All rights reserved.
+
+ This program is free software; you can redistribute it and/or modify it
+ under the terms of version 2 of the GNU General Public License as
+ published by the Free Software Foundation.
+
+ This program is distributed in the hope that it would be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+ Further, this software is distributed without any warranty that it is
+ free of the rightful claim of any third person regarding infringement
+ or the like. Any license provided herein, whether implied or
+ otherwise, applies only to this software file. Patent licenses, if
+ any, provided herein do not apply to combinations of this program with
+ other software, or any other product whatsoever.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write the Free Software Foundation, Inc., 51
+ Franklin Street - Fifth Floor, Boston MA 02110-1301, USA.
+
+ Contact information: Silicon Graphics, Inc., 1500 Crittenden Lane,
+ Mountain View, CA 94043, or:
+
+ http://www.sgi.com
+
+ For further information regarding this notice, see:
+
+ http://oss.sgi.com/projects/GenInfo/NoticeExplan
+
+
+
+$Header: /plroot/cmplrs.src/v7.4.5m/.RCS/PL/dwarfdump/RCS/print_sections.c,v 1.69 2006/04/17 00:09:56 davea Exp $ */
+/* The address of the Free Software Foundation is
+ Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+ SGI has moved from the Crittenden Lane address.
+*/
+
+#include "globals.h"
+#include "naming.h"
+#include "dwconf.h"
+#include "esb.h"
+#include "print_sections.h"
+
+/* This unifies the code for some error checks to
+ avoid code duplication.
+*/
+static void
+check_info_offset_sanity(char *sec,
+ char *field,
+ char *global,
+ Dwarf_Unsigned offset, Dwarf_Unsigned maxoff)
+{
+ if (maxoff == 0) {
+ /* Lets make a heuristic check. */
+ if (offset > 0xffffffff) {
+ printf("Warning: section %s %s %s offset 0x%"
+ DW_PR_XZEROS DW_PR_DUx " "
+ "exceptionally large \n",
+ sec, field, global, offset);
+ }
+ return;
+ }
+ if (offset >= maxoff) {
+ printf("Warning: section %s %s %s offset 0x%"
+ DW_PR_XZEROS DW_PR_DUx " "
+ "larger than max of 0x%" DW_PR_DUx "\n",
+ sec, field, global, offset, maxoff);
+ }
+}
+
+/* Unified pubnames style output.
+ The error checking here against maxoff may be useless
+ (in that libdwarf may return an error if the offset is bad
+ and we will not get called here).
+ But we leave it in nonetheless as it looks sensible.
+ In at least one gigantic executable such offsets turned out wrong.
+*/
+void
+print_pubname_style_entry(Dwarf_Debug dbg,
+ char *line_title,
+ char *name,
+ Dwarf_Unsigned die_off,
+ Dwarf_Unsigned cu_off,
+ Dwarf_Unsigned global_cu_offset,
+ Dwarf_Unsigned maxoff)
+{
+ Dwarf_Die die = NULL;
+ Dwarf_Off die_CU_off = 0;
+ int dres = 0;
+ int ddres = 0;
+ int cudres = 0;
+ char tmp_buf[100];
+
+ /* get die at die_off */
+ dres = dwarf_offdie(dbg, die_off, &die, &err);
+ if (dres != DW_DLV_OK) {
+ struct esb_s details;
+ esb_constructor(&details);
+ esb_append(&details,line_title);
+ esb_append(&details," dwarf_offdie : "
+ "die offset does not reference valid DIE. ");
+ snprintf(tmp_buf,sizeof(tmp_buf),"0x%" DW_PR_DUx, die_off);
+ esb_append(&details,tmp_buf);
+ esb_append(&details,".");
+ print_error(dbg, esb_get_string(&details), dres, err);
+ esb_destructor(&details);
+ }
+
+ /* get offset of die from its cu-header */
+ ddres = dwarf_die_CU_offset(die, &die_CU_off, &err);
+ if (ddres != DW_DLV_OK) {
+ struct esb_s details;
+ esb_constructor(&details);
+ esb_append(&details,line_title);
+ esb_append(&details," cannot get CU die offset");
+ print_error(dbg, esb_get_string(&details), dres, err);
+ esb_destructor(&details);
+ die_CU_off = 0;
+ }
+
+ /* Get die at offset cu_off to check its existence. */
+ {
+ Dwarf_Die cu_die = NULL;
+ cudres = dwarf_offdie(dbg, cu_off, &cu_die, &err);
+ if (cudres != DW_DLV_OK) {
+ struct esb_s details;
+ esb_constructor(&details);
+ esb_append(&details,line_title);
+ esb_append(&details," dwarf_offdie: "
+ "cu die offset does not reference valid CU DIE. ");
+ snprintf(tmp_buf,sizeof(tmp_buf),"0x%" DW_PR_DUx, cu_off);
+ esb_append(&details,tmp_buf);
+ esb_append(&details,".");
+ print_error(dbg, esb_get_string(&details), dres, err);
+ esb_destructor(&details);
+ } else {
+ /* It exists, all is well. */
+ dwarf_dealloc(dbg, cu_die, DW_DLA_DIE);
+ }
+ }
+ /* Display offsets */
+ if (display_offsets) {
+ /* Print 'name'at the end for better layout */
+ printf("%s die-in-sect 0x%" DW_PR_XZEROS DW_PR_DUx
+ ", cu-in-sect 0x%" DW_PR_XZEROS DW_PR_DUx ","
+ " die-in-cu 0x%" DW_PR_XZEROS DW_PR_DUx
+ ", cu-header-in-sect 0x%" DW_PR_XZEROS DW_PR_DUx ,
+ line_title,
+ die_off, cu_off,
+ (Dwarf_Unsigned) die_CU_off,
+ /* Following is absolute offset of the ** beginning of the
+ cu */
+ (Dwarf_Signed) (die_off - die_CU_off));
+ }
+
+ if ((die_off - die_CU_off) != global_cu_offset) {
+ printf(" error: real cuhdr 0x%" DW_PR_XZEROS DW_PR_DUx,
+ global_cu_offset);
+ exit(1);
+ }
+
+ /* Display offsets */
+ if (display_offsets && verbose) {
+ printf(" cuhdr 0x%" DW_PR_XZEROS DW_PR_DUx , global_cu_offset);
+ }
+
+ /* Print 'name'at the end for better layout */
+ printf(" '%s'\n",name);
+
+ dwarf_dealloc(dbg, die, DW_DLA_DIE);
+
+ check_info_offset_sanity(line_title,
+ "die offset", name, die_off, maxoff);
+ check_info_offset_sanity(line_title,
+ "die cu offset", name, die_CU_off, maxoff);
+ check_info_offset_sanity(line_title,
+ "cu offset", name,
+ (die_off - die_CU_off), maxoff);
+
+}
+
+/* Get all the data in .debug_pubnames */
+void
+print_pubnames(Dwarf_Debug dbg)
+{
+ Dwarf_Global *globbuf = NULL;
+ Dwarf_Signed count = 0;
+ Dwarf_Signed i = 0;
+ Dwarf_Off die_off = 0;
+ Dwarf_Off cu_off = 0;
+
+ /* Offset to previous CU */
+ Dwarf_Off prev_cu_off = elf_max_address;
+
+ char *name = 0;
+ int res = 0;
+
+ current_section_id = DEBUG_PUBNAMES;
+ if (do_print_dwarf) {
+ printf("\n.debug_pubnames\n");
+ }
+ res = dwarf_get_globals(dbg, &globbuf, &count, &err);
+ if (res == DW_DLV_ERROR) {
+ print_error(dbg, "dwarf_get_globals", res, err);
+ } else if (res == DW_DLV_NO_ENTRY) {
+ /* (err == 0 && count == DW_DLV_NOCOUNT) means there are no
+ pubnames. */
+ } else {
+ Dwarf_Unsigned maxoff = get_info_max_offset(dbg);
+
+ for (i = 0; i < count; i++) {
+ int nres = 0;
+ int cures3 = 0;
+ Dwarf_Off global_cu_off = 0;
+
+ nres = dwarf_global_name_offsets(globbuf[i],
+ &name, &die_off, &cu_off,
+ &err);
+ deal_with_name_offset_err(dbg, "dwarf_global_name_offsets",
+ name, die_off, nres, err);
+ cures3 = dwarf_global_cu_offset(globbuf[i],
+ &global_cu_off, &err);
+ if (cures3 != DW_DLV_OK) {
+ print_error(dbg, "dwarf_global_cu_offset", cures3, err);
+ }
+
+ if (check_pubname_attr) {
+ Dwarf_Bool has_attr;
+ int ares;
+ int dres;
+ Dwarf_Die die;
+
+ /* We are processing a new set of pubnames
+ for a different CU; get the producer ID, at 'cu_off'
+ to see if we need to skip these pubnames */
+ if (cu_off != prev_cu_off) {
+ char *producer_name = 0;
+
+ /* Record offset for previous CU */
+ prev_cu_off = cu_off;
+
+ dres = dwarf_offdie(dbg, cu_off, &die, &err);
+ if (dres != DW_DLV_OK) {
+ print_error(dbg, "print pubnames: dwarf_offdie a", dres,err);
+ }
+
+ /* Get producer name for this CU and update compiler list */
+ get_producer_name(dbg,die,err,&producer_name);
+ update_compiler_target(producer_name);
+
+ dwarf_dealloc(dbg, die, DW_DLA_DIE);
+ }
+
+ /* get die at die_off */
+ dres = dwarf_offdie(dbg, die_off, &die, &err);
+ if (dres != DW_DLV_OK) {
+ print_error(dbg, "print pubnames: dwarf_offdie b", dres, err);
+ }
+
+
+ ares =
+ dwarf_hasattr(die, DW_AT_external, &has_attr, &err);
+ if (ares == DW_DLV_ERROR) {
+ print_error(dbg, "hassattr on DW_AT_external", ares,
+ err);
+ }
+
+ /* Check for specific compiler */
+ if (checking_this_compiler()) {
+ DWARF_CHECK_COUNT(pubname_attr_result,1);
+ if (ares == DW_DLV_OK && has_attr) {
+ /* Should the value of flag be examined? */
+ } else {
+ DWARF_CHECK_ERROR2(pubname_attr_result,name,
+ "pubname does not have DW_AT_external");
+ }
+ }
+ dwarf_dealloc(dbg, die, DW_DLA_DIE);
+ }
+
+ /* Now print pubname, after the test */
+ if (do_print_dwarf || (record_dwarf_error && check_verbose_mode)) {
+ print_pubname_style_entry(dbg,
+ "global",
+ name, die_off, cu_off,
+ global_cu_off, maxoff);
+ record_dwarf_error = FALSE; /* Clear error condition */
+ }
+
+ }
+ dwarf_globals_dealloc(dbg, globbuf, count);
+ }
+} /* print_pubnames() */
+
diff --git a/dwarfdump/print_ranges.c b/dwarfdump/print_ranges.c
new file mode 100644
index 0000000..aee55e0
--- /dev/null
+++ b/dwarfdump/print_ranges.c
@@ -0,0 +1,106 @@
+/*
+ Copyright (C) 2000-2006 Silicon Graphics, Inc. All Rights Reserved.
+ Portions Copyright 2007-2010 Sun Microsystems, Inc. All rights reserved.
+ Portions Copyright 2009-2011 SN Systems Ltd. All rights reserved.
+ Portions Copyright 2008-2011 David Anderson. All rights reserved.
+
+ This program is free software; you can redistribute it and/or modify it
+ under the terms of version 2 of the GNU General Public License as
+ published by the Free Software Foundation.
+
+ This program is distributed in the hope that it would be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+ Further, this software is distributed without any warranty that it is
+ free of the rightful claim of any third person regarding infringement
+ or the like. Any license provided herein, whether implied or
+ otherwise, applies only to this software file. Patent licenses, if
+ any, provided herein do not apply to combinations of this program with
+ other software, or any other product whatsoever.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write the Free Software Foundation, Inc., 51
+ Franklin Street - Fifth Floor, Boston MA 02110-1301, USA.
+
+ Contact information: Silicon Graphics, Inc., 1500 Crittenden Lane,
+ Mountain View, CA 94043, or:
+
+ http://www.sgi.com
+
+ For further information regarding this notice, see:
+
+ http://oss.sgi.com/projects/GenInfo/NoticeExplan
+
+
+
+$Header: /plroot/cmplrs.src/v7.4.5m/.RCS/PL/dwarfdump/RCS/print_sections.c,v 1.69 2006/04/17 00:09:56 davea Exp $ */
+/* The address of the Free Software Foundation is
+ Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+ SGI has moved from the Crittenden Lane address.
+*/
+
+#include "globals.h"
+#include "naming.h"
+#include "dwconf.h"
+#include "esb.h"
+#include "print_sections.h"
+
+static struct esb_s esb_string;
+
+/* Because we do not know what DIE is involved, if the
+ object being printed has different address sizes
+ in different compilation units this will not work
+ properly: anything could happen. */
+extern void
+print_ranges(Dwarf_Debug dbg)
+{
+ Dwarf_Unsigned off = 0;
+ int group_number = 0;
+ int wasdense = 0;
+
+ current_section_id = DEBUG_RANGES;
+ if (!do_print_dwarf) {
+ return;
+ }
+ printf("\n.debug_ranges\n");
+
+ /* Turn off dense, we do not want print_ranges_list_to_extra
+ to use dense form here. */
+ wasdense = dense;
+ dense = 0;
+ for(;;) {
+ Dwarf_Ranges *rangeset = 0;
+ Dwarf_Signed rangecount = 0;
+ Dwarf_Unsigned bytecount = 0;
+
+ /* We do not know what DIE is involved, we use
+ the older call here. */
+ int rres = dwarf_get_ranges(dbg,off,&rangeset,
+ &rangecount,&bytecount,&err);
+ if(rres == DW_DLV_OK) {
+ char *val = 0;
+ printf(" Ranges group %d:\n",group_number);
+ esb_empty_string(&esb_string);
+ print_ranges_list_to_extra(dbg,off,
+ rangeset,rangecount,bytecount,
+ &esb_string);
+ dwarf_ranges_dealloc(dbg,rangeset,rangecount);
+ val = esb_get_string(&esb_string);
+ printf("%s",val);
+ ++group_number;
+ } else if (rres == DW_DLV_NO_ENTRY) {
+ printf("End of .debug_ranges.\n");
+ break;
+ } else {
+ /* ERROR, which does not quite mean a real error,
+ as we might just be misaligned reading things without
+ a DW_AT_ranges offset.*/
+ printf("End of .debug_ranges..\n");
+ break;
+ }
+ off += bytecount;
+ }
+ dense = wasdense;
+}
diff --git a/dwarfdump/print_reloc.c b/dwarfdump/print_reloc.c
new file mode 100644
index 0000000..35a1574
--- /dev/null
+++ b/dwarfdump/print_reloc.c
@@ -0,0 +1,1150 @@
+/*
+ Copyright (C) 2000,2004,2005 Silicon Graphics, Inc. All Rights Reserved.
+ Portions Copyright (C) 2007-2011 David Anderson. All Rights Reserved.
+ Portions Copyright (C) 2011 SN Systems Ltd. All Rights Reserved
+
+ This program is free software; you can redistribute it and/or modify it
+ under the terms of version 2 of the GNU General Public License as
+ published by the Free Software Foundation.
+
+ This program is distributed in the hope that it would be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+ Further, this software is distributed without any warranty that it is
+ free of the rightful claim of any third person regarding infringement
+ or the like. Any license provided herein, whether implied or
+ otherwise, applies only to this software file. Patent licenses, if
+ any, provided herein do not apply to combinations of this program with
+ other software, or any other product whatsoever.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write the Free Software Foundation, Inc., 51
+ Franklin Street - Fifth Floor, Boston MA 02110-1301, USA.
+
+ Contact information: Silicon Graphics, Inc., 1500 Crittenden Lane,
+ Mountain View, CA 94043, or:
+
+ http://www.sgi.com
+
+ For further information regarding this notice, see:
+
+ http://oss.sgi.com/projects/GenInfo/NoticeExplan
+
+
+
+$Header: /plroot/cmplrs.src/v7.4.5m/.RCS/PL/dwarfdump/RCS/print_reloc.c,v 1.11 2005/08/04 05:09:37 davea Exp $ */
+
+/* The address of the Free Software Foundation is
+ Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+ SGI has moved from the Crittenden Lane address.
+*/
+
+
+
+
+#include "globals.h"
+#include "print_reloc.h"
+
+#define DW_SECTION_REL_DEBUG_NUM 9 /* Number of sections */
+/* .debug_abbrev should never have a relocation applied to it as it
+ never refers to another section! (other sections refer to
+ .debug_abbrev) */
+
+#define DW_SECTNAME_RELA_DEBUG ".rela.debug_"
+#define DW_SECTNAME_RELA_DEBUG_INFO ".rela.debug_info"
+#define DW_SECTNAME_RELA_DEBUG_LINE ".rela.debug_line"
+#define DW_SECTNAME_RELA_DEBUG_PUBNAMES ".rela.debug_pubnames"
+#define DW_SECTNAME_RELA_DEBUG_ABBREV ".rela.debug_abbrev"
+#define DW_SECTNAME_RELA_DEBUG_ARANGES ".rela.debug_aranges"
+#define DW_SECTNAME_RELA_DEBUG_FRAME ".rela.debug_frame"
+#define DW_SECTNAME_RELA_DEBUG_LOC ".rela.debug_loc"
+#define DW_SECTNAME_RELA_DEBUG_RANGES ".rela.debug_ranges"
+#define DW_SECTNAME_RELA_DEBUG_TYPES ".rela.debug_types"
+
+#define DW_SECTNAME_REL_DEBUG ".rel.debug_"
+#define DW_SECTNAME_REL_DEBUG_INFO ".rel.debug_info"
+#define DW_SECTNAME_REL_DEBUG_LINE ".rel.debug_line"
+#define DW_SECTNAME_REL_DEBUG_PUBNAMES ".rel.debug_pubnames"
+#define DW_SECTNAME_REL_DEBUG_ABBREV ".rel.debug_abbrev"
+#define DW_SECTNAME_REL_DEBUG_ARANGES ".rel.debug_aranges"
+#define DW_SECTNAME_REL_DEBUG_FRAME ".rel.debug_frame"
+#define DW_SECTNAME_REL_DEBUG_LOC ".rel.debug_loc"
+#define DW_SECTNAME_REL_DEBUG_RANGES ".rel.debug_ranges"
+#define DW_SECTNAME_REL_DEBUG_TYPES ".rel.debug_types"
+
+
+#define STRING_FOR_DUPLICATE " duplicate"
+#define STRING_FOR_NULL " null"
+
+static char *sectnames[] = {
+ DW_SECTNAME_REL_DEBUG_INFO,
+ DW_SECTNAME_REL_DEBUG_LINE,
+ DW_SECTNAME_REL_DEBUG_PUBNAMES,
+ DW_SECTNAME_REL_DEBUG_ABBREV,
+ DW_SECTNAME_REL_DEBUG_ARANGES,
+ DW_SECTNAME_REL_DEBUG_FRAME,
+ DW_SECTNAME_REL_DEBUG_LOC,
+ DW_SECTNAME_REL_DEBUG_RANGES,
+ DW_SECTNAME_REL_DEBUG_TYPES,
+};
+static char *sectnamesa[] = {
+ DW_SECTNAME_RELA_DEBUG_INFO,
+ DW_SECTNAME_RELA_DEBUG_LINE,
+ DW_SECTNAME_RELA_DEBUG_PUBNAMES,
+ DW_SECTNAME_RELA_DEBUG_ABBREV,
+ DW_SECTNAME_RELA_DEBUG_ARANGES,
+ DW_SECTNAME_RELA_DEBUG_FRAME,
+ DW_SECTNAME_RELA_DEBUG_LOC,
+ DW_SECTNAME_RELA_DEBUG_RANGES,
+ DW_SECTNAME_RELA_DEBUG_TYPES,
+};
+
+static char *error_msg_duplicate[] = {
+ DW_SECTNAME_REL_DEBUG_INFO STRING_FOR_DUPLICATE,
+ DW_SECTNAME_REL_DEBUG_LINE STRING_FOR_DUPLICATE,
+ DW_SECTNAME_REL_DEBUG_PUBNAMES STRING_FOR_DUPLICATE,
+ DW_SECTNAME_REL_DEBUG_ABBREV STRING_FOR_DUPLICATE,
+ DW_SECTNAME_REL_DEBUG_ARANGES STRING_FOR_DUPLICATE,
+ DW_SECTNAME_REL_DEBUG_FRAME STRING_FOR_DUPLICATE,
+ DW_SECTNAME_REL_DEBUG_LOC STRING_FOR_DUPLICATE,
+ DW_SECTNAME_REL_DEBUG_RANGES STRING_FOR_DUPLICATE,
+ DW_SECTNAME_REL_DEBUG_TYPES STRING_FOR_DUPLICATE,
+};
+
+static char *error_msg_null[] = {
+ DW_SECTNAME_REL_DEBUG_INFO STRING_FOR_NULL,
+ DW_SECTNAME_REL_DEBUG_LINE STRING_FOR_NULL,
+ DW_SECTNAME_REL_DEBUG_PUBNAMES STRING_FOR_NULL,
+ DW_SECTNAME_REL_DEBUG_ABBREV STRING_FOR_NULL,
+ DW_SECTNAME_REL_DEBUG_ARANGES STRING_FOR_NULL,
+ DW_SECTNAME_REL_DEBUG_FRAME STRING_FOR_NULL,
+ DW_SECTNAME_REL_DEBUG_LOC STRING_FOR_NULL,
+ DW_SECTNAME_REL_DEBUG_RANGES STRING_FOR_NULL,
+ DW_SECTNAME_REL_DEBUG_TYPES STRING_FOR_NULL,
+};
+
+/* Include Section type, to be able to deal with all the
+ Elf32_Rel, Elf32_Rela, Elf64_Rel, Elf64_Rela relocation types */
+#define SECT_DATA_SET(x,t,n) { \
+ if (sect_data[(x)].buf != NULL) { \
+ print_error(dbg, error_msg_duplicate[(x)], DW_DLV_OK, err); \
+ } \
+ if ((data = elf_getdata(scn, 0)) == NULL || data->d_size == 0) {\
+ print_error(dbg, error_msg_null[(x)],DW_DLV_OK, err); \
+ } \
+ sect_data[(x)].buf = data -> d_buf; \
+ sect_data[(x)].size = data -> d_size; \
+ sect_data[(x)].type = t; \
+ sect_data[(x)].name = n; \
+ }
+
+/* PowerPC relocations defined by the ABIs */
+static char *reloc_type_names_PPC[] = {
+ "R_PPC_NONE", /* 00 */
+ "R_PPC_ADDR32", /* 01 */
+ "R_PPC_ADDR24", /* 02 */
+ "R_PPC_ADDR16", /* 03 */
+ "R_PPC_ADDR16_LO", /* 04 */
+ "R_PPC_ADDR16_HI", /* 05 */
+ "R_PPC_ADDR16_HA", /* 06 */
+ "R_PPC_ADDR14", /* 07 */
+ "R_PPC_ADDR14_BRTAKEN", /* 08 */
+ "R_PPC_ADDR14_BRNTAKEN", /* 09 */
+ "R_PPC_REL24", /* 10 */
+ "R_PPC_REL14", /* 11 */
+ "R_PPC_REL14_BRTAKEN", /* 12 */
+ "R_PPC_REL14_BRNTAKEN", /* 13 */
+ "R_PPC_GOT16", /* 14 */
+ "R_PPC_GOT16_LO", /* 15 */
+ "R_PPC_GOT16_HI", /* 16 */
+ "R_PPC_GOT16_HA", /* 17 */
+ "R_PPC_PLTREL24", /* 18 */
+ "R_PPC_COPY", /* 19 */
+ "R_PPC_GLOB_DAT", /* 20 */
+ "R_PPC_JMP_SLOT", /* 21 */
+ "R_PPC_RELATIVE", /* 22 */
+ "R_PPC_LOCAL24PC", /* 23 */
+ "R_PPC_UADDR32", /* 24 */
+ "R_PPC_UADDR16", /* 25 */
+ "R_PPC_REL32", /* 26 */
+ "R_PPC_PLT32", /* 27 */
+ "R_PPC_PLTREL32", /* 28 */
+ "R_PPC_PLT16_LO", /* 29 */
+ "R_PPC_PLT16_HI", /* 30 */
+ "R_PPC_PLT16_HA", /* 31 */
+ "R_PPC_SDAREL16", /* 32 */
+ "R_PPC_SECTOFF", /* 33 */
+ "R_PPC_SECTOFF_LO", /* 34 */
+ "R_PPC_SECTOFF_HI", /* 35 */
+ "R_PPC_SECTOFF_HA", /* 36 */
+ "R_PPC_37", /* 37 */
+ "R_PPC_38", /* 38 */
+ "R_PPC_39", /* 39 */
+ "R_PPC_40", /* 40 */
+ "R_PPC_41", /* 41 */
+ "R_PPC_42", /* 42 */
+ "R_PPC_43", /* 43 */
+ "R_PPC_44", /* 44 */
+ "R_PPC_45", /* 45 */
+ "R_PPC_46", /* 46 */
+ "R_PPC_47", /* 47 */
+ "R_PPC_48", /* 48 */
+ "R_PPC_49", /* 49 */
+ "R_PPC_50", /* 50 */
+ "R_PPC_51", /* 51 */
+ "R_PPC_52", /* 52 */
+ "R_PPC_53", /* 53 */
+ "R_PPC_54", /* 54 */
+ "R_PPC_55", /* 55 */
+ "R_PPC_56", /* 56 */
+ "R_PPC_57", /* 57 */
+ "R_PPC_58", /* 58 */
+ "R_PPC_59", /* 59 */
+ "R_PPC_60", /* 60 */
+ "R_PPC_61", /* 61 */
+ "R_PPC_62", /* 62 */
+ "R_PPC_63", /* 63 */
+ "R_PPC_64", /* 64 */
+ "R_PPC_65", /* 65 */
+ "R_PPC_66", /* 66 */
+ "R_PPC_TLS", /* 67 */
+ "R_PPC_DTPMOD32", /* 68 */
+ "R_PPC_TPREL16", /* 69 */
+ "R_PPC_TPREL16_LO", /* 70 */
+ "R_PPC_TPREL16_HI", /* 71 */
+ "R_PPC_TPREL16_HA", /* 72 */
+ "R_PPC_TPREL32", /* 73 */
+ "R_PPC_DTPREL16", /* 74 */
+ "R_PPC_DTPREL16_LO", /* 75 */
+ "R_PPC_DTPREL16_HI", /* 76 */
+ "R_PPC_DTPREL16_HA", /* 77 */
+ "R_PPC_DTPREL64", /* 78 */
+ "R_PPC_GOT_TLSGD16", /* 79 */
+ "R_PPC_GOT_TLSGD16_LO", /* 80 */
+ "R_PPC_GOT_TLSGD16_HI", /* 81 */
+ "R_PPC_GOT_TLSGD16_HA", /* 82 */
+ "R_PPC_GOT_TLSLD16", /* 83 */
+ "R_PPC_GOT_TLSLD16_LO", /* 84 */
+ "R_PPC_GOT_TLSLD16_HI", /* 85 */
+ "R_PPC_GOT_TLSLD16_HA", /* 86 */
+ "R_PPC_GOT_TPREL16_DS", /* 87 */
+ "R_PPC_GOT_TPREL16_LO", /* 88 */
+ "R_PPC_GOT_TPREL16_HI", /* 89 */
+ "R_PPC_GOT_TPREL16_HA", /* 90 */
+ "R_PPC_GOT_DTPREL16", /* 91 */
+ "R_PPC_GOT_DTPREL16_LO", /* 92 */
+ "R_PPC_GOT_DTPREL16_HI", /* 93 */
+ "R_PPC_GOT_DTPREL16_HA", /* 94 */
+};
+
+/* PowerPC64 relocations defined by the ABIs */
+static char *reloc_type_names_PPC64[] = {
+ "R_PPC64_NONE", /* 00 */
+ "R_PPC64_ADDR32", /* 01 */
+ "R_PPC64_ADDR24", /* 02 */
+ "R_PPC64_ADDR16", /* 03 */
+ "R_PPC64_ADDR16_LO", /* 04 */
+ "R_PPC64_ADDR16_HI", /* 05 */
+ "R_PPC64_ADDR16_HA", /* 06 */
+ "R_PPC64_ADDR14", /* 07 */
+ "R_PPC64_ADDR14_BRTAKEN", /* 08 */
+ "R_PPC64_ADDR14_BRNTAKEN", /* 09 */
+ "R_PPC64_REL24", /* 10 */
+ "R_PPC64_REL14", /* 11 */
+ "R_PPC64_REL14_BRTAKEN", /* 12 */
+ "R_PPC64_REL14_BRNTAKEN", /* 13 */
+ "R_PPC64_GOT16", /* 14 */
+ "R_PPC64_GOT16_LO", /* 15 */
+ "R_PPC64_GOT16_HI", /* 16 */
+ "R_PPC64_GOT16_HA", /* 17 */
+ "R_PPC64_PLTREL24", /* 18 */
+ "R_PPC64_COPY", /* 19 */
+ "R_PPC64_GLOB_DAT", /* 20 */
+ "R_PPC64_JMP_SLOT", /* 21 */
+ "R_PPC64_RELATIVE", /* 22 */
+ "R_PPC64_LOCAL24PC", /* 23 */
+ "R_PPC64_UADDR32", /* 24 */
+ "R_PPC64_UADDR16", /* 25 */
+ "R_PPC64_REL32", /* 26 */
+ "R_PPC64_PLT32", /* 27 */
+ "R_PPC64_PLTREL32", /* 28 */
+ "R_PPC64_PLT16_LO", /* 29 */
+ "R_PPC64_PLT16_HI", /* 30 */
+ "R_PPC64_PLT16_HA", /* 31 */
+ "R_PPC64_SDAREL16", /* 32 */
+ "R_PPC64_SECTOFF", /* 33 */
+ "R_PPC64_SECTOFF_LO", /* 34 */
+ "R_PPC64_SECTOFF_HI", /* 35 */
+ "R_PPC64_SECTOFF_HA", /* 36 */
+ "R_PPC64_REL30", /* 37 */
+ "R_PPC64_ADDR64", /* 38 */
+ "R_PPC64_ADDR16_HIGHER", /* 39 */
+ "R_PPC64_ADDR16_HIGHERA", /* 40 */
+ "R_PPC64_ADDR16_HIGHEST", /* 41 */
+ "R_PPC64_ADDR16_HIGHESTA", /* 42 */
+ "R_PPC64_UADDR64", /* 43 */
+ "R_PPC64_REL64", /* 44 */
+ "R_PPC64_PLT64", /* 45 */
+ "R_PPC64_PLTREL64", /* 46 */
+ "R_PPC64_TOC16", /* 47 */
+ "R_PPC64_TOC16_LO", /* 48 */
+ "R_PPC64_TOC16_HI", /* 49 */
+ "R_PPC64_TOC16_HA", /* 50 */
+ "R_PPC64_TOC", /* 51 */
+ "R_PPC64_PLTGOT16", /* 52 */
+ "R_PPC64_PLTGOT16_LO", /* 53 */
+ "R_PPC64_PLTGOT16_HI", /* 54 */
+ "R_PPC64_PLTGOT16_HA", /* 55 */
+ "R_PPC64_ADDR16_DS", /* 56 */
+ "R_PPC64_ADDR16_LO_DS", /* 57 */
+ "R_PPC64_GOT16_DS", /* 58 */
+ "R_PPC64_GOT16_LO_DS", /* 59 */
+ "R_PPC64_PLT16_LO_DS", /* 60 */
+ "R_PPC64_SECTOFF_DS", /* 61 */
+ "R_PPC64_SECTOFF_LO_DS", /* 62 */
+ "R_PPC64_TOC16_DS", /* 63 */
+ "R_PPC64_TOC16_LO_DS", /* 64 */
+ "R_PPC64_PLTGOT16_DS", /* 65 */
+ "R_PPC64_PLTGOT16_LO_DS", /* 66 */
+ "R_PPC64_TLS", /* 67 */
+ "R_PPC64_DTPMOD32", /* 68 */
+ "R_PPC64_TPREL16", /* 69 */
+ "R_PPC64_TPREL16_LO", /* 70 */
+ "R_PPC64_TPREL16_HI", /* 71 */
+ "R_PPC64_TPREL16_HA", /* 72 */
+ "R_PPC64_TPREL32", /* 73 */
+ "R_PPC64_DTPREL16", /* 74 */
+ "R_PPC64_DTPREL16_LO", /* 75 */
+ "R_PPC64_DTPREL16_HI", /* 76 */
+ "R_PPC64_DTPREL16_HA", /* 77 */
+ "R_PPC64_DTPREL64", /* 78 */
+ "R_PPC64_GOT_TLSGD16", /* 79 */
+ "R_PPC64_GOT_TLSGD16_LO", /* 80 */
+ "R_PPC64_GOT_TLSGD16_HI", /* 81 */
+ "R_PPC64_GOT_TLSGD16_HA", /* 82 */
+ "R_PPC64_GOT_TLSLD16", /* 83 */
+ "R_PPC64_GOT_TLSLD16_LO", /* 84 */
+ "R_PPC64_GOT_TLSLD16_HI", /* 85 */
+ "R_PPC64_GOT_TLSLD16_HA", /* 86 */
+ "R_PPC64_GOT_TPREL16_DS", /* 87 */
+ "R_PPC64_GOT_TPREL16_LO", /* 88 */
+ "R_PPC64_GOT_TPREL16_HI", /* 89 */
+ "R_PPC64_GOT_TPREL16_HA", /* 90 */
+ "R_PPC64_GOT_DTPREL16", /* 91 */
+ "R_PPC64_GOT_DTPREL16_LO", /* 92 */
+ "R_PPC64_GOT_DTPREL16_HI", /* 93 */
+ "R_PPC64_GOT_DTPREL16_HA", /* 94 */
+ "R_PPC64_TPREL16_DS", /* 95 */
+ "R_PPC64_TPREL16_LO_DS", /* 96 */
+ "R_PPC64_TPREL16_HIGHER", /* 97 */
+ "R_PPC64_TPREL16_HIGHERA", /* 98 */
+ "R_PPC64_TPREL16_HIGHEST", /* 99 */
+ "R_PPC64_TPREL16_HIGHESTA", /* 100 */
+ "R_PPC64_DTPREL16_DS", /* 101 */
+ "R_PPC64_DTPREL16_LO_DS", /* 102 */
+ "R_PPC64_DTPREL16_HIGHER", /* 103 */
+ "R_PPC64_DTPREL16_HIGHERA", /* 104 */
+ "R_PPC64_DTPREL16_HIGHEST", /* 105 */
+ "R_PPC64_DTPREL16_HIGHESTA", /* 106 */
+ "R_PPC64_TOC32", /* 107 */
+ "R_PPC64_DTPMOD32", /* 108 */
+ "R_PPC64_TPREL32", /* 109 */
+ "R_PPC64_DTPREL32", /* 110 */
+};
+
+/* Relocation types for MIPS */
+static char *reloc_type_names_MIPS[] = {
+ "R_MIPS_NONE", "R_MIPS_16", "R_MIPS_32", "R_MIPS_REL32",
+ "R_MIPS_26", "R_MIPS_HI16", "R_MIPS_LO16", "R_MIPS_GPREL16",
+ "R_MIPS_LITERAL", "R_MIPS_GOT16", "R_MIPS_PC16", "R_MIPS_CALL16",
+ "R_MIPS_GPREL32", /* 12 */
+ "reloc type 13?", "reloc type 14?", "reloc type 15?",
+ "R_MIPS_SHIFT5", /* 16 */
+ "R_MIPS_SHIFT6", /* 17 */
+ "R_MIPS_64", /* 18 */
+ "R_MIPS_GOT_DISP", /* 19 */
+ "R_MIPS_GOT_PAGE", /* 20 */
+ "R_MIPS_GOT_OFST", /* 21 */
+ "R_MIPS_GOT_HI16", /* 22 */
+ "R_MIPS_GOT_LO16", /* 23 */
+ "R_MIPS_SUB", /* 24 */
+ "R_MIPS_INSERT_A", /* 25 */
+ "R_MIPS_INSERT_B", /* 26 */
+ "R_MIPS_DELETE", /* 27 */
+ "R_MIPS_HIGHER", /* 28 */
+ "R_MIPS_HIGHEST", /* 29 */
+ "R_MIPS_CALL_HI16", /* 30 */
+ "R_MIPS_CALL_LO16", /* 31 */
+ "R_MIPS_SCN_DISP", /* 32 */
+ "R_MIPS_REL16", /* 33 */
+ "R_MIPS_ADD_IMMEDIATE", /* 34 */
+};
+
+/* ARM relocations defined by the ABIs */
+static char *reloc_type_names_ARM[] = {
+ "R_ARM_NONE", /* 00 */
+ "R_ARM_PC24", /* 01 */
+ "R_ARM_ABS32", /* 02 */
+ "R_ARM_REL32", /* 03 */
+ "R_ARM_LDR_PC_G0", /* 04 */
+ "R_ARM_ABS16", /* 05 */
+ "R_ARM_ABS12", /* 06 */
+ "R_ARM_THM_ABS5", /* 07 */
+ "R_ARM_ABS8", /* 08 */
+ "R_ARM_SBREL32", /* 09 */
+ "R_ARM_THM_CALL", /* 10 */
+ "R_ARM_THM_PC8", /* 11 */
+ "R_ARM_BREL_ADJ", /* 12 */
+ "R_ARM_TLS_DESC", /* 13 */
+ "R_ARM_THM_SWI8", /* 14 */
+ "R_ARM_XPC25", /* 15 */
+ "R_ARM_THM_XPC22", /* 16 */
+ "R_ARM_TLS_DTPMOD32", /* 17 */
+ "R_ARM_TLS_DTPOFF32", /* 18 */
+ "R_ARM_TLS_TPOFF32", /* 19 */
+ "R_ARM_COPY", /* 20 */
+ "R_ARM_GLOB_DAT", /* 21 */
+ "R_ARM_JUMP_SLOT", /* 22 */
+ "R_ARM_RELATIVE", /* 23 */
+ "R_ARM_GOTOFF32", /* 24 */
+ "R_ARM_BASE_PREL", /* 25 */
+ "R_ARM_GOT_BREL", /* 26 */
+ "R_ARM_PLT32", /* 27 */
+ "R_ARM_CALL", /* 28 */
+ "R_ARM_JUMP24", /* 29 */
+ "R_ARM_THM_JUMP24", /* 30 */
+ "R_ARM_BASE_ABS", /* 31 */
+ "R_ARM_ALU_PCREL_7_0", /* 32 */
+ "R_ARM_ALU_PCREL_15_8", /* 33 */
+ "R_ARM_ALU_PCREL_23_15", /* 34 */
+ "R_ARM_LDR_SBREL_11_0_NC", /* 35 */
+ "R_ARM_ALU_SBREL_19_12_NC", /* 36 */
+ "R_ARM_ALU_SBREL_27_20_CK", /* 37 */
+ "R_ARM_TARGET1", /* 38 */
+ "R_ARM_SBREL31", /* 39 */
+ "R_ARM_V4BX", /* 40 */
+ "R_ARM_TARGET2", /* 41 */
+ "R_ARM_PREL31", /* 42 */
+ "R_ARM_MOVW_ABS_NC", /* 43 */
+ "R_ARM_MOVT_ABS", /* 44 */
+ "R_ARM_MOVW_PREL_NC", /* 45 */
+ "R_ARM_MOVT_PREL", /* 46 */
+ "R_ARM_THM_MOVW_ABS_NC", /* 47 */
+ "R_ARM_THM_MOVT_ABS", /* 48 */
+ "R_ARM_THM_MOVW_PREL_NC", /* 49 */
+ "R_ARM_THM_MOVT_PREL", /* 50 */
+ "R_ARM_THM_JUMP19", /* 51 */
+ "R_ARM_THM_JUMP6", /* 52 */
+ "R_ARM_THM_ALU_PREL_11_0", /* 53 */
+ "R_ARM_THM_PC12", /* 54 */
+ "R_ARM_ABS32_NOI", /* 55 */
+ "R_ARM_REL32_NOI", /* 56 */
+ "R_ARM_ALU_PC_G0_NC", /* 57 */
+ "R_ARM_ALU_PC_G0", /* 58 */
+ "R_ARM_ALU_PC_G1_NC", /* 59 */
+ "R_ARM_ALU_PC_G1", /* 60 */
+ "R_ARM_ALU_PC_G2", /* 61 */
+ "R_ARM_LDR_PC_G1", /* 62 */
+ "R_ARM_LDR_PC_G2", /* 63 */
+ "R_ARM_LDRS_PC_G0", /* 64 */
+ "R_ARM_LDRS_PC_G1", /* 65 */
+ "R_ARM_LDRS_PC_G2", /* 66 */
+ "R_ARM_LDC_PC_G0", /* 67 */
+ "R_ARM_LDC_PC_G1", /* 68 */
+ "R_ARM_LDC_PC_G2", /* 69 */
+ "R_ARM_ALU_SB_G0_NC", /* 70 */
+ "R_ARM_ALU_SB_G0", /* 71 */
+ "R_ARM_ALU_SB_G1_NC", /* 72 */
+ "R_ARM_ALU_SB_G1", /* 73 */
+ "R_ARM_ALU_SB_G2", /* 74 */
+ "R_ARM_LDR_SB_G0", /* 75 */
+ "R_ARM_LDR_SB_G1", /* 76 */
+ "R_ARM_LDR_SB_G2", /* 77 */
+ "R_ARM_LDRS_SB_G0", /* 78 */
+ "R_ARM_LDRS_SB_G1", /* 79 */
+ "R_ARM_LDRS_SB_G2", /* 80 */
+ "R_ARM_LDC_SB_G0", /* 81 */
+ "R_ARM_LDC_SB_G1", /* 82 */
+ "R_ARM_LDC_SB_G2", /* 83 */
+ "R_ARM_MOVW_BREL_NC", /* 84 */
+ "R_ARM_MOVT_BREL", /* 85 */
+ "R_ARM_MOVW_BREL", /* 86 */
+ "R_ARM_THM_MOVW_BREL_NC", /* 87 */
+ "R_ARM_THM_MOVT_BREL", /* 88 */
+ "R_ARM_THM_MOVW_BREL", /* 89 */
+ "R_ARM_TLS_GOTDESC", /* 90 */
+ "R_ARM_TLS_CALL", /* 91 */
+ "R_ARM_TLS_DESCSEQ", /* 92 */
+ "R_ARM_THM_TLS_CALL", /* 93 */
+ "R_ARM_PLT32_ABS", /* 94 */
+ "R_ARM_GOT_ABS", /* 95 */
+ "R_ARM_GOT_PREL", /* 96 */
+ "R_ARM_GOT_BREL12", /* 97 */
+ "R_ARM_GOTOFF12", /* 98 */
+ "R_ARM_GOTRELAX", /* 99 */
+ "R_ARM_GNU_VTENTRY", /* 100 */
+ "R_ARM_GNU_VTINHERIT", /* 101 */
+ "R_ARM_THM_JUMP11", /* 102 */
+ "R_ARM_THM_JUMP8", /* 103 */
+ "R_ARM_TLS_GD32", /* 104 */
+ "R_ARM_TLS_LDM32", /* 105 */
+ "R_ARM_TLS_LDO32", /* 106 */
+ "R_ARM_TLS_IE32", /* 107 */
+ "R_ARM_TLS_LE32", /* 108 */
+ "R_ARM_TLS_LDO12", /* 109 */
+ "R_ARM_TLS_LE12", /* 110 */
+ "R_ARM_TLS_IE12GP", /* 111 */
+ "R_ARM_TLS_MOVT_TPOFF32", /* 112 */ /* "R_ARM_PRIVATE_0" */
+ "R_ARM_TLS_MOVW_TPOFF32", /* 113 */ /* "R_ARM_PRIVATE_1" */
+ "R_ARM_THM_TLS_MOVT_TPOFF32", /* 114 */ /* "R_ARM_PRIVATE_2" */
+ "R_ARM_THM_TLS_MOVT_TPOFF32", /* 115 */ /* "R_ARM_PRIVATE_3" */
+ "R_ARM_PRIVATE_4", /* 116 */
+ "R_ARM_PRIVATE_5", /* 117 */
+ "R_ARM_PRIVATE_6", /* 118 */
+ "R_ARM_PRIVATE_7", /* 119 */
+ "R_ARM_PRIVATE_8", /* 120 */
+ "R_ARM_PRIVATE_9", /* 121 */
+ "R_ARM_PRIVATE_10", /* 122 */
+ "R_ARM_PRIVATE_11", /* 123 */
+ "R_ARM_PRIVATE_12", /* 124 */
+ "R_ARM_PRIVATE_13", /* 125 */
+ "R_ARM_PRIVATE_14", /* 126 */
+ "R_ARM_PRIVATE_15", /* 127 */
+ "R_ARM_ME_TOO", /* 128 */
+ "R_ARM_THM_TLS_DESCSEQ16", /* 129 */
+ "R_ARM_THM_TLS_DESCSEQ32", /* 130 */
+};
+
+/* Record the relocation table name information */
+static char **reloc_type_names = NULL;
+static Dwarf_Small number_of_reloc_type_names = 0;
+
+/* Set the relocation names based on the machine type */
+static void
+set_relocation_table_names(Dwarf_Small machine_type)
+{
+ switch (machine_type) {
+ case EM_MIPS:
+ reloc_type_names = reloc_type_names_MIPS;
+ number_of_reloc_type_names =
+ sizeof(reloc_type_names_MIPS) / sizeof(char *);
+ break;
+ case EM_PPC:
+ reloc_type_names = reloc_type_names_PPC;
+ number_of_reloc_type_names =
+ sizeof(reloc_type_names_PPC) / sizeof(char *);
+ break;
+ case EM_PPC64:
+ reloc_type_names = reloc_type_names_PPC64;
+ number_of_reloc_type_names =
+ sizeof(reloc_type_names_PPC64) / sizeof(char *);
+ break;
+ case EM_ARM:
+ reloc_type_names = reloc_type_names_ARM;
+ number_of_reloc_type_names =
+ sizeof(reloc_type_names_ARM) / sizeof(char *);
+ break;
+ default:
+ /* We don't have others covered. */
+ reloc_type_names = 0;
+ number_of_reloc_type_names = 0;
+ break;
+ }
+}
+
+/*
+ Return valid reloc type names.
+ If buf is used, it is static, so beware: it
+ will be overwritten by the next call.
+*/
+static char *
+get_reloc_type_names(int index)
+{
+ static char buf[100];
+ char *retval = 0;
+
+ if (index < 0 || index >= number_of_reloc_type_names) {
+ sprintf(buf, "reloc type %d unknown", (int) index);
+ retval = buf;
+ } else {
+ retval = reloc_type_names[index];
+ }
+ return retval;
+}
+
+#ifndef HAVE_ELF64_GETEHDR
+#define Elf64_Addr long
+#define Elf64_Word unsigned long
+#define Elf64_Xword unsigned long
+#define Elf64_Sym long
+#endif
+
+static struct {
+ Dwarf_Small *buf;
+ Dwarf_Unsigned size;
+ Dwarf_Bool display; /* Display reloc if TRUE */
+ const char *name; /* Section name */
+ Elf64_Xword type; /* To cover 32 and 64 records types */
+} sect_data[DW_SECTION_REL_DEBUG_NUM];
+
+
+typedef size_t indx_type;
+
+typedef struct {
+ indx_type indx;
+ char *name;
+ Elf32_Addr value;
+ Elf32_Word size;
+ int type;
+ int bind;
+ unsigned char other;
+ Elf32_Half shndx;
+} SYM;
+
+
+typedef struct {
+ indx_type indx;
+ char *name;
+ Elf64_Addr value;
+ Elf64_Xword size;
+ int type;
+ int bind;
+ unsigned char other;
+ unsigned short shndx;
+} SYM64;
+
+static void print_reloc_information_64(int section_no,
+ Dwarf_Small * buf,
+ Dwarf_Unsigned size,
+ Elf64_Xword type,
+ char **scn_names,int scn_names_count);
+static void print_reloc_information_32(int section_no,
+ Dwarf_Small * buf,
+ Dwarf_Unsigned size,
+ Elf64_Xword type,
+ char **scn_names,int scn_names_count);
+static SYM *readsyms(Elf32_Sym * data, size_t num, Elf * elf,
+ Elf32_Word link);
+static SYM64 *read_64_syms(Elf64_Sym * data, size_t num, Elf * elf,
+ Elf64_Word link);
+static void *get_scndata(Elf_Scn * fd_scn, size_t * scn_size);
+static void print_relocinfo_64(Dwarf_Debug dbg, Elf * elf);
+static void print_relocinfo_32(Dwarf_Debug dbg, Elf * elf);
+
+static SYM *sym_data;
+static SYM64 *sym_data_64;
+static long sym_data_entry_count;
+static long sym_data_64_entry_count;
+
+typedef struct {
+ indx_type index;
+ char *name_rel; /* .rel.debug_* names */
+ char *name_rela; /* .rela.debug_* names */
+} REL_INFO;
+
+/* If the incoming scn_name is known, record the name
+ in our reloc section names table.
+ For a given (debug) section there can be a .rel or a .rela,
+ not both.
+ The name-to-index in this table is fixed, invariant.
+ It has to match other tables like
+*/
+static int
+get_reloc_section(Dwarf_Debug dbg,
+ Elf_Scn *scn,
+ char *scn_name,
+ Elf64_Word sh_type)
+{
+ static REL_INFO rel_info[DW_SECTION_REL_DEBUG_NUM] = {
+ {/*0*/ DW_SECTION_REL_DEBUG_INFO,
+ DW_SECTNAME_REL_DEBUG_INFO,
+ DW_SECTNAME_RELA_DEBUG_INFO},
+
+ {/*1*/ DW_SECTION_REL_DEBUG_LINE,
+ DW_SECTNAME_REL_DEBUG_LINE,
+ DW_SECTNAME_RELA_DEBUG_LINE},
+
+ {/*2*/ DW_SECTION_REL_DEBUG_PUBNAMES,
+ DW_SECTNAME_REL_DEBUG_PUBNAMES,
+ DW_SECTNAME_RELA_DEBUG_PUBNAMES},
+
+ {/*3*/ DW_SECTION_REL_DEBUG_ABBREV,
+ DW_SECTNAME_REL_DEBUG_ABBREV,
+ DW_SECTNAME_RELA_DEBUG_ABBREV},
+
+ {/*4*/ DW_SECTION_REL_DEBUG_ARANGES,
+ DW_SECTNAME_REL_DEBUG_ARANGES,
+ DW_SECTNAME_RELA_DEBUG_ARANGES},
+
+ {/*5*/ DW_SECTION_REL_DEBUG_FRAME,
+ DW_SECTNAME_REL_DEBUG_FRAME,
+ DW_SECTNAME_RELA_DEBUG_FRAME},
+
+ {/*6*/ DW_SECTION_REL_DEBUG_LOC,
+ DW_SECTNAME_REL_DEBUG_LOC,
+ DW_SECTNAME_RELA_DEBUG_LOC},
+
+ {/*7*/ DW_SECTION_REL_DEBUG_RANGES,
+ DW_SECTNAME_REL_DEBUG_RANGES,
+ DW_SECTNAME_RELA_DEBUG_RANGES},
+
+ {/*8*/ DW_SECTION_REL_DEBUG_TYPES,
+ DW_SECTNAME_REL_DEBUG_TYPES,
+ DW_SECTNAME_RELA_DEBUG_TYPES},
+ };
+
+ Elf_Data *data;
+ int index;
+ for (index = 0; index < DW_SECTION_REL_DEBUG_NUM; ++index) {
+ const char *n = rel_info[index].name_rel;
+ const char *na = rel_info[index].name_rela;
+ if (strcmp(scn_name, n) == 0) {
+ SECT_DATA_SET(rel_info[index].index,sh_type,n)
+ return TRUE;
+ }
+ if (strcmp(scn_name, na) == 0) {
+ SECT_DATA_SET(rel_info[index].index,sh_type,na)
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
+void
+print_relocinfo(Dwarf_Debug dbg, unsigned reloc_map)
+{
+ Elf *elf;
+ char *endr_ident;
+ int is_64bit;
+ int res;
+ int i;
+
+ for (i = 0; i < DW_SECTION_REL_DEBUG_NUM; i++) {
+ sect_data[i].display = reloc_map & (1 << i);
+ sect_data[i].buf = 0;
+ sect_data[i].size = 0;
+ sect_data[i].type = SHT_NULL;
+ }
+ res = dwarf_get_elf(dbg, &elf, &err);
+ if (res != DW_DLV_OK) {
+ print_error(dbg, "dwarf_get_elf error", res, err);
+ }
+ if ((endr_ident = elf_getident(elf, NULL)) == NULL) {
+ print_error(dbg, "DW_ELF_GETIDENT_ERROR", res, err);
+ }
+ is_64bit = (endr_ident[EI_CLASS] == ELFCLASS64);
+ if (is_64bit) {
+ print_relocinfo_64(dbg, elf);
+ } else {
+ print_relocinfo_32(dbg, elf);
+ }
+}
+
+static void
+print_relocinfo_64(Dwarf_Debug dbg, Elf * elf)
+{
+#ifdef HAVE_ELF64_GETEHDR
+ Elf_Scn *scn = NULL;
+ Elf64_Ehdr *ehdr64 = 0;
+ Elf64_Shdr *shdr64 = 0;
+ char *scn_name = 0;
+ int i = 0;
+ Elf64_Sym *sym_64 = 0;
+ char **scn_names = 0;
+ int scn_names_cnt = 0;
+
+ ehdr64 = elf64_getehdr(elf);
+ if (ehdr64 == NULL) {
+ print_error(dbg, "DW_ELF_GETEHDR_ERROR", DW_DLV_OK, err);
+ }
+
+ /* Make the section name array big enough
+ that we don't need to check for overrun in the loop. */
+ scn_names = (char **)calloc(ehdr64->e_shnum + 1, sizeof(char *));
+
+ while ((scn = elf_nextscn(elf, scn)) != NULL) {
+
+ shdr64 = elf64_getshdr(scn);
+ if (shdr64 == NULL) {
+ print_error(dbg, "DW_ELF_GETSHDR_ERROR", DW_DLV_OK, err);
+ }
+ scn_name = elf_strptr(elf, ehdr64->e_shstrndx, shdr64->sh_name);
+ if (scn_name == NULL) {
+ print_error(dbg, "DW_ELF_STRPTR_ERROR", DW_DLV_OK, err);
+ }
+
+ if (scn_names) {
+ /* elf_nextscn() skips section with index '0' */
+ scn_names[++scn_names_cnt] = scn_name;
+ }
+ if (shdr64->sh_type == SHT_SYMTAB) {
+ size_t sym_size = 0;
+ size_t count = 0;
+
+ sym_64 = (Elf64_Sym *) get_scndata(scn, &sym_size);
+ if (sym_64 == NULL) {
+ print_error(dbg, "no symbol table data", DW_DLV_OK,
+ err);
+ }
+ count = sym_size / sizeof(Elf64_Sym);
+ sym_64++;
+ free(sym_data_64);
+ sym_data_64 = read_64_syms(sym_64, count, elf, shdr64->sh_link);
+ sym_data_64_entry_count = count;
+ if (sym_data_64 == NULL) {
+ print_error(dbg, "problem reading symbol table data",
+ DW_DLV_OK, err);
+ }
+ } else if (!get_reloc_section(dbg,scn,scn_name,shdr64->sh_type)) {
+ continue;
+ }
+ } /* while */
+
+ /* Set the relocation names based on the machine type */
+ set_relocation_table_names(ehdr64->e_machine);
+
+ for (i = 0; i < DW_SECTION_REL_DEBUG_NUM; i++) {
+ if (sect_data[i].display &&
+ sect_data[i].buf != NULL &&
+ sect_data[i].size > 0) {
+ print_reloc_information_64(i, sect_data[i].buf,
+ sect_data[i].size, sect_data[i].type,scn_names,
+ scn_names_cnt);
+ }
+ }
+
+ if (scn_names) {
+ free(scn_names);
+ scn_names = 0;
+ scn_names_cnt = 0;
+ }
+#endif
+}
+
+static void
+print_relocinfo_32(Dwarf_Debug dbg, Elf * elf)
+{
+ Elf_Scn *scn = NULL;
+ Elf32_Ehdr *ehdr32 = 0;
+ Elf32_Shdr *shdr32 = 0;
+ char *scn_name = 0;
+ int i = 0;
+ Elf32_Sym *sym = 0;
+ char **scn_names = 0;
+ int scn_names_cnt = 0;
+
+ ehdr32 = elf32_getehdr(elf);
+ if (ehdr32 == NULL) {
+ print_error(dbg, "DW_ELF_GETEHDR_ERROR", DW_DLV_OK, err);
+ }
+
+ /* Make the section name array big enough
+ that we don't need to check for overrun in the loop. */
+ scn_names = (char **)calloc(ehdr32->e_shnum + 1, sizeof(char *));
+
+ while ((scn = elf_nextscn(elf, scn)) != NULL) {
+ shdr32 = elf32_getshdr(scn);
+ if (shdr32 == NULL) {
+ print_error(dbg, "DW_ELF_GETSHDR_ERROR", DW_DLV_OK, err);
+ }
+ scn_name = elf_strptr(elf, ehdr32->e_shstrndx, shdr32->sh_name);
+ if (scn_name == NULL) {
+ print_error(dbg, "DW_ELF_STRPTR_ERROR", DW_DLV_OK, err);
+ }
+
+ if (scn_names) {
+ /* elf_nextscn() skips section with index '0' */
+ scn_names[++scn_names_cnt] = scn_name;
+ }
+
+ if (shdr32->sh_type == SHT_SYMTAB) {
+ size_t sym_size = 0;
+ size_t count = 0;
+
+ sym = (Elf32_Sym *) get_scndata(scn, &sym_size);
+ if (sym == NULL) {
+ print_error(dbg, "no symbol table data", DW_DLV_OK,
+ err);
+ }
+ sym = (Elf32_Sym *) get_scndata(scn, &sym_size);
+ count = sym_size / sizeof(Elf32_Sym);
+ sym++;
+ free(sym_data);
+ sym_data = readsyms(sym, count, elf, shdr32->sh_link);
+ sym_data_entry_count = count;
+ if (sym_data == NULL) {
+ print_error(dbg, "problem reading symbol table data",
+ DW_DLV_OK, err);
+ }
+ } else if (!get_reloc_section(dbg,scn,scn_name,shdr32->sh_type)) {
+ continue;
+ }
+ } /* End while. */
+
+ /* Set the relocation names based on the machine type */
+ set_relocation_table_names(ehdr32->e_machine);
+
+ for (i = 0; i < DW_SECTION_REL_DEBUG_NUM; i++) {
+ if (sect_data[i].display &&
+ sect_data[i].buf != NULL &&
+ sect_data[i].size > 0) {
+ print_reloc_information_32(i, sect_data[i].buf,
+ sect_data[i].size,sect_data[i].type,scn_names,
+ scn_names_cnt);
+ }
+ }
+
+ if (scn_names) {
+ free(scn_names);
+ scn_names = 0;
+ scn_names_cnt = 0;
+ }
+}
+
+#if HAVE_ELF64_R_INFO
+#ifndef ELF64_R_TYPE
+#define ELF64_R_TYPE(x) 0 /* FIXME */
+#endif
+#ifndef ELF64_R_SYM
+#define ELF64_R_SYM(x) 0 /* FIXME */
+#endif
+#ifndef ELF64_ST_TYPE
+#define ELF64_ST_TYPE(x) 0 /* FIXME */
+#endif
+#ifndef ELF64_ST_BIND
+#define ELF64_ST_BIND(x) 0 /* FIXME */
+#endif
+#endif /* HAVE_ELF64_R_INFO */
+
+
+static void
+print_reloc_information_64(int section_no, Dwarf_Small * buf,
+ Dwarf_Unsigned size, Elf64_Xword type,
+ char **scn_names, int scn_names_count)
+{
+ /* Include support for Elf64_Rel and Elf64_Rela */
+ Dwarf_Unsigned add = 0;
+ Dwarf_Half rel_size = SHT_RELA == type ?
+ sizeof(Elf64_Rela) : sizeof(Elf64_Rel);
+ Dwarf_Unsigned off = 0;
+
+ printf("\n%s:\n", type== SHT_RELA?sectnamesa[section_no]:
+ sectnames[section_no]);
+
+ /* Print some headers and change the order for better reading */
+ printf("Offset Addend %-26s Index Symbol Name\n","Reloc Type");
+
+#if HAVE_ELF64_GETEHDR
+ for (off = 0; off < size; off += rel_size) {
+#if HAVE_ELF64_R_INFO
+ /* This works for the Elf64_Rel in linux */
+ Elf64_Rel *p = (Elf64_Rel *) (buf + off);
+ char *name = 0;
+ if(sym_data ) {
+ size_t index = ELF64_R_SYM(p->r_info) - 1;
+ if(index < sym_data_entry_count) {
+ name = sym_data[index].name;
+ }
+ } else if (sym_data_64) {
+ size_t index = ELF64_R_SYM(p->r_info) - 1;
+ if(index < sym_data_64_entry_count) {
+ name = sym_data_64[index].name;
+ }
+ }
+
+ /* When the name is not available, use the
+ section name as a reference for the name.*/
+ if (!name || !name[0]) {
+ size_t index = ELF64_R_SYM(p->r_info) - 1;
+ if(index < sym_data_64_entry_count) {
+ SYM64 *sym_64 = &sym_data_64[index];
+ if (sym_64->type == STT_SECTION &&
+ sym_64->shndx < scn_names_count) {
+ name = scn_names[sym_64->shndx];
+ }
+ }
+ }
+ if(!name || !name[0]) {
+ name = "<no name>";
+ }
+
+ if (SHT_RELA == type) {
+ Elf64_Rela *pa = (Elf64_Rela *)p;
+ add = pa->r_addend;
+ }
+
+ printf("0x%08lx 0x%08lx %-26s <%5ld> %s\n",
+ (unsigned long int) (p->r_offset),
+ (unsigned long int) (add),
+ get_reloc_type_names(ELF64_R_TYPE(p->r_info)),
+ (long)ELF64_R_SYM(p->r_info),
+ name);
+#else
+ /* sgi/mips -64 does not have r_info in the 64bit relocations,
+ but seperate fields, with 3 types, actually. Only one of
+ which prints here, as only one really used with dwarf */
+ Elf64_Rel *p = (Elf64_Rel *) (buf + off);
+ char *name = 0;
+ if(sym_data ) {
+ size_t index = p->r_sym - 1;
+ if(index < sym_data_entry_count) {
+ name = sym_data[index].name;
+ }
+ } else if (sym_data_64) {
+ size_t index = p->r_sym - 1;
+ if(index < sym_data_64_entry_count) {
+ name = sym_data_64[index].name;
+ }
+ }
+ if(!name || !name[0]) {
+ name = "<no name>";
+ }
+ printf("%5" DW_PR_DUu " %-26s <%3ld> %s\n",
+ (Dwarf_Unsigned) (p->r_offset),
+ get_reloc_type_names(p->r_type),
+ (long)p->r_sym,
+ name);
+#endif
+ }
+#endif /* HAVE_ELF64_GETEHDR */
+}
+
+static void
+print_reloc_information_32(int section_no, Dwarf_Small * buf,
+ Dwarf_Unsigned size, Elf64_Xword type, char **scn_names,
+ int scn_names_count)
+{
+ /* Include support for Elf32_Rel and Elf32_Rela */
+ Dwarf_Unsigned add = 0;
+ Dwarf_Half rel_size = SHT_RELA == type ?
+ sizeof(Elf32_Rela) : sizeof(Elf32_Rel);
+ Dwarf_Unsigned off = 0;
+
+ printf("\n%s:\n", type== SHT_RELA?sectnamesa[section_no]:
+ sectnames[section_no]);
+
+
+ /* Print some headers and change the order for better reading. */
+ printf("Offset Addend %-26s Index Symbol Name\n","Reloc Type");
+
+ for (off = 0; off < size; off += rel_size) {
+ Elf32_Rel *p = (Elf32_Rel *) (buf + off);
+ char *name = 0;
+
+ if(sym_data) {
+ size_t index = ELF32_R_SYM(p->r_info) - 1;
+ if(index < sym_data_entry_count) {
+ name = sym_data[index].name;
+ }
+ }
+
+ /* When the name is not available, use the
+ section name as a reference for the name. */
+ if (!name || !name[0]) {
+ size_t index = ELF32_R_SYM(p->r_info) - 1;
+ if(index < sym_data_entry_count) {
+ SYM *sym = &sym_data[index];
+ if (sym->type == STT_SECTION&&
+ sym->shndx < scn_names_count) {
+ name = scn_names[sym->shndx];
+ }
+ }
+ }
+ if(!name || !name[0]) {
+ name = "<no name>";
+ }
+ if (SHT_RELA == type) {
+ Elf32_Rela *pa = (Elf32_Rela *)p;
+ add = pa->r_addend;
+ }
+ printf("0x%08lx 0x%08lx %-26s <%5ld> %s\n",
+ (unsigned long int) (p->r_offset),
+ (unsigned long int) (add),
+ get_reloc_type_names(ELF32_R_TYPE(p->r_info)),
+ (long)ELF32_R_SYM(p->r_info),
+ name);
+ }
+}
+
+static SYM *
+readsyms(Elf32_Sym * data, size_t num, Elf * elf, Elf32_Word link)
+{
+ SYM *s, *buf;
+ indx_type i;
+
+ buf = (SYM *) calloc(num, sizeof(SYM));
+ if (buf == NULL) {
+ return NULL;
+ }
+ s = buf; /* save pointer to head of array */
+ for (i = 1; i < num; i++, data++, buf++) {
+ buf->indx = i;
+ buf->name = (char *) elf_strptr(elf, link, data->st_name);
+ buf->value = data->st_value;
+ buf->size = data->st_size;
+ buf->type = ELF32_ST_TYPE(data->st_info);
+ buf->bind = ELF32_ST_BIND(data->st_info);
+ buf->other = data->st_other;
+ buf->shndx = data->st_shndx;
+ } /* end for loop */
+ return (s);
+}
+
+static SYM64 *
+read_64_syms(Elf64_Sym * data, size_t num, Elf * elf, Elf64_Word link)
+{
+#ifdef HAVE_ELF64_GETEHDR
+
+ SYM64 *s, *buf;
+ indx_type i;
+
+ buf = (SYM64 *) calloc(num, sizeof(SYM64));
+ if (buf == NULL) {
+ return NULL;
+ }
+ s = buf; /* save pointer to head of array */
+ for (i = 1; i < num; i++, data++, buf++) {
+ buf->indx = i;
+ buf->name = (char *) elf_strptr(elf, link, data->st_name);
+ buf->value = data->st_value;
+ buf->size = data->st_size;
+ buf->type = ELF64_ST_TYPE(data->st_info);
+ buf->bind = ELF64_ST_BIND(data->st_info);
+ buf->other = data->st_other;
+ buf->shndx = data->st_shndx;
+ } /* end for loop */
+ return (s);
+#else
+ return 0;
+#endif /* HAVE_ELF64_GETEHDR */
+}
+
+static void *
+get_scndata(Elf_Scn * fd_scn, size_t * scn_size)
+{
+ Elf_Data *p_data;
+
+ p_data = 0;
+ if ((p_data = elf_getdata(fd_scn, p_data)) == 0 ||
+ p_data->d_size == 0) {
+ return NULL;
+ }
+ *scn_size = p_data->d_size;
+ return (p_data->d_buf);
+}
+
+/* Cleanup of malloc space (some of the pointers will be 0 here)
+ so dwarfdump looks 'clean' to a malloc checker.
+*/
+void
+clean_up_syms_malloc_data()
+{
+ free(sym_data);
+ sym_data = 0;
+ free(sym_data_64);
+ sym_data_64 = 0;
+ sym_data_64_entry_count = 0;
+ sym_data_entry_count = 0;
+}
diff --git a/dwarfdump/print_reloc.h b/dwarfdump/print_reloc.h
new file mode 100644
index 0000000..d511b71
--- /dev/null
+++ b/dwarfdump/print_reloc.h
@@ -0,0 +1,307 @@
+/*
+ Copyright (C) 2000,2004,2005 Silicon Graphics, Inc. All Rights Reserved.
+ Portions Copyright (C) 2007-2011 David Anderson. All Rights Reserved.
+ Portions Copyright (C) 2011 SN Systems Ltd. All rights reserved.
+
+ This program is free software; you can redistribute it and/or modify it
+ under the terms of version 2 of the GNU General Public License as
+ published by the Free Software Foundation.
+
+ This program is distributed in the hope that it would be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+ Further, this software is distributed without any warranty that it is
+ free of the rightful claim of any third person regarding infringement
+ or the like. Any license provided herein, whether implied or
+ otherwise, applies only to this software file. Patent licenses, if
+ any, provided herein do not apply to combinations of this program with
+ other software, or any other product whatsoever.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write the Free Software Foundation, Inc., 51
+ Franklin Street - Fifth Floor, Boston MA 02110-1301, USA.
+
+ Contact information: Silicon Graphics, Inc., 1500 Crittenden Lane,
+ Mountain View, CA 94043, or:
+
+ http://www.sgi.com
+
+ For further information regarding this notice, see:
+
+ http://oss.sgi.com/projects/GenInfo/NoticeExplan
+
+$Header: /plroot/cmplrs.src/v7.4.5m/.RCS/PL/dwarfdump/RCS/print_reloc.c,v 1.11 2005/08/04 05:09:37 davea Exp $ */
+
+/* The address of the Free Software Foundation is
+ Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+ SGI has moved from the Crittenden Lane address.
+*/
+
+/* PowerPC relocations defined by the ABIs */
+#define R_PPC_NONE 0
+#define R_PPC_ADDR32 1 /* 32bit absolute address */
+#define R_PPC_ADDR24 2 /* 26bit address, 2 bits ignored. */
+#define R_PPC_ADDR16 3 /* 16bit absolute address */
+#define R_PPC_ADDR16_LO 4 /* lower 16bit of absolute address */
+#define R_PPC_ADDR16_HI 5 /* high 16bit of absolute address */
+#define R_PPC_ADDR16_HA 6 /* adjusted high 16bit */
+#define R_PPC_ADDR14 7 /* 16bit address, 2 bits ignored */
+#define R_PPC_ADDR14_BRTAKEN 8
+#define R_PPC_ADDR14_BRNTAKEN 9
+#define R_PPC_REL24 10 /* PC relative 26 bit */
+#define R_PPC_REL14 11 /* PC relative 16 bit */
+#define R_PPC_REL14_BRTAKEN 12
+#define R_PPC_REL14_BRNTAKEN 13
+#define R_PPC_GOT16 14
+#define R_PPC_GOT16_LO 15
+#define R_PPC_GOT16_HI 16
+#define R_PPC_GOT16_HA 17
+#define R_PPC_PLTREL24 18
+#define R_PPC_COPY 19
+#define R_PPC_GLOB_DAT 20
+#define R_PPC_JMP_SLOT 21
+#define R_PPC_RELATIVE 22
+#define R_PPC_LOCAL24PC 23
+#define R_PPC_UADDR32 24
+#define R_PPC_UADDR16 25
+#define R_PPC_REL32 26
+#define R_PPC_PLT32 27
+#define R_PPC_PLTREL32 28
+#define R_PPC_PLT16_LO 29
+#define R_PPC_PLT16_HI 30
+#define R_PPC_PLT16_HA 31
+#define R_PPC_SDAREL16 32
+#define R_PPC_SECTOFF 33
+#define R_PPC_SECTOFF_LO 34
+#define R_PPC_SECTOFF_HI 35
+#define R_PPC_SECTOFF_HA 36
+
+/* Unused types */
+#define R_PPC_37 37
+#define R_PPC_38 38
+#define R_PPC_39 39
+#define R_PPC_40 40
+#define R_PPC_41 41
+#define R_PPC_42 42
+#define R_PPC_43 43
+#define R_PPC_44 44
+#define R_PPC_45 45
+#define R_PPC_46 46
+#define R_PPC_47 47
+#define R_PPC_48 48
+#define R_PPC_49 49
+#define R_PPC_50 50
+#define R_PPC_51 51
+#define R_PPC_52 52
+#define R_PPC_53 53
+#define R_PPC_54 54
+#define R_PPC_55 55
+
+/* Unused types */
+#define R_PPC_56 56
+#define R_PPC_57 57
+#define R_PPC_58 58
+#define R_PPC_59 59
+#define R_PPC_60 60
+#define R_PPC_61 61
+#define R_PPC_62 62
+#define R_PPC_63 63
+#define R_PPC_64 64
+#define R_PPC_65 65
+#define R_PPC_66 66
+
+/* PowerPC relocations defined for the TLS access ABI. */
+#define R_PPC_TLS 67 /* none (sym+add)@tls */
+#define R_PPC_DTPMOD32 68 /* word32 (sym+add)@dtpmod */
+#define R_PPC_TPREL16 69 /* half16* (sym+add)@tprel */
+#define R_PPC_TPREL16_LO 70 /* half16 (sym+add)@tprel@l */
+#define R_PPC_TPREL16_HI 71 /* half16 (sym+add)@tprel@h */
+#define R_PPC_TPREL16_HA 72 /* half16 (sym+add)@tprel@ha */
+#define R_PPC_TPREL32 73 /* word32 (sym+add)@tprel */
+#define R_PPC_DTPREL16 74 /* half16* (sym+add)@dtprel */
+#define R_PPC_DTPREL16_LO 75 /* half16 (sym+add)@dtprel@l */
+#define R_PPC_DTPREL16_HI 76 /* half16 (sym+add)@dtprel@h */
+#define R_PPC_DTPREL16_HA 77 /* half16 (sym+add)@dtprel@ha */
+#define R_PPC_DTPREL32 78 /* word32 (sym+add)@dtprel */
+#define R_PPC_GOT_TLSGD16 79 /* half16* (sym+add)@got@tlsgd */
+#define R_PPC_GOT_TLSGD16_LO 80 /* half16 (sym+add)@got@tlsgd@l */
+#define R_PPC_GOT_TLSGD16_HI 81 /* half16 (sym+add)@got@tlsgd@h */
+#define R_PPC_GOT_TLSGD16_HA 82 /* half16 (sym+add)@got@tlsgd@ha */
+#define R_PPC_GOT_TLSLD16 83 /* half16* (sym+add)@got@tlsld */
+#define R_PPC_GOT_TLSLD16_LO 84 /* half16 (sym+add)@got@tlsld@l */
+#define R_PPC_GOT_TLSLD16_HI 85 /* half16 (sym+add)@got@tlsld@h */
+#define R_PPC_GOT_TLSLD16_HA 86 /* half16 (sym+add)@got@tlsld@ha */
+#define R_PPC_GOT_TPREL16 87 /* half16* (sym+add)@got@tprel */
+#define R_PPC_GOT_TPREL16_LO 88 /* half16 (sym+add)@got@tprel@l */
+#define R_PPC_GOT_TPREL16_HI 89 /* half16 (sym+add)@got@tprel@h */
+#define R_PPC_GOT_TPREL16_HA 90 /* half16 (sym+add)@got@tprel@ha */
+#define R_PPC_GOT_DTPREL16 91 /* half16* (sym+add)@got@dtprel */
+#define R_PPC_GOT_DTPREL16_LO 92 /* half16* (sym+add)@got@dtprel@l */
+#define R_PPC_GOT_DTPREL16_HI 93 /* half16* (sym+add)@got@dtprel@h */
+#define R_PPC_GOT_DTPREL16_HA 94 /* half16* (sym+add)@got@dtprel@ha */
+
+/* Keep this the last entry. */
+#define R_PPC_NUM 95
+
+/* PowerPC64 relocations defined by the ABIs */
+#define R_PPC64_NONE R_PPC_NONE
+#define R_PPC64_ADDR32 R_PPC_ADDR32 /* 32bit absolute address. */
+#define R_PPC64_ADDR24 R_PPC_ADDR24 /* 26bit address, word aligned. */
+#define R_PPC64_ADDR16 R_PPC_ADDR16 /* 16bit absolute address. */
+#define R_PPC64_ADDR16_LO R_PPC_ADDR16_LO /* lower 16bits of abs. address. */
+#define R_PPC64_ADDR16_HI R_PPC_ADDR16_HI /* high 16bits of abs. address. */
+#define R_PPC64_ADDR16_HA R_PPC_ADDR16_HA /* adjusted high 16bits. */
+#define R_PPC64_ADDR14 R_PPC_ADDR14 /* 16bit address, word aligned. */
+#define R_PPC64_ADDR14_BRTAKEN R_PPC_ADDR14_BRTAKEN
+#define R_PPC64_ADDR14_BRNTAKEN R_PPC_ADDR14_BRNTAKEN
+#define R_PPC64_REL24 R_PPC_REL24 /* PC relative 26 bit, word aligned. */
+#define R_PPC64_REL14 R_PPC_REL14 /* PC relative 16 bit. */
+#define R_PPC64_REL14_BRTAKEN R_PPC_REL14_BRTAKEN
+#define R_PPC64_REL14_BRNTAKEN R_PPC_REL14_BRNTAKEN
+#define R_PPC64_GOT16 R_PPC_GOT16
+#define R_PPC64_GOT16_LO R_PPC_GOT16_LO
+#define R_PPC64_GOT16_HI R_PPC_GOT16_HI
+#define R_PPC64_GOT16_HA R_PPC_GOT16_HA
+
+#define R_PPC64_COPY R_PPC_COPY
+#define R_PPC64_GLOB_DAT R_PPC_GLOB_DAT
+#define R_PPC64_JMP_SLOT R_PPC_JMP_SLOT
+#define R_PPC64_RELATIVE R_PPC_RELATIVE
+
+#define R_PPC64_UADDR32 R_PPC_UADDR32
+#define R_PPC64_UADDR16 R_PPC_UADDR16
+#define R_PPC64_REL32 R_PPC_REL32
+#define R_PPC64_PLT32 R_PPC_PLT32
+#define R_PPC64_PLTREL32 R_PPC_PLTREL32
+#define R_PPC64_PLT16_LO R_PPC_PLT16_LO
+#define R_PPC64_PLT16_HI R_PPC_PLT16_HI
+#define R_PPC64_PLT16_HA R_PPC_PLT16_HA
+
+#define R_PPC64_SECTOFF R_PPC_SECTOFF
+#define R_PPC64_SECTOFF_LO R_PPC_SECTOFF_LO
+#define R_PPC64_SECTOFF_HI R_PPC_SECTOFF_HI
+#define R_PPC64_SECTOFF_HA R_PPC_SECTOFF_HA
+#define R_PPC64_ADDR30 37 /* word30 (S + A - P) >> 2. */
+#define R_PPC64_ADDR64 38 /* doubleword64 S + A. */
+#define R_PPC64_ADDR16_HIGHER 39 /* half16 #higher(S + A). */
+#define R_PPC64_ADDR16_HIGHERA 40 /* half16 #highera(S + A). */
+#define R_PPC64_ADDR16_HIGHEST 41 /* half16 #highest(S + A). */
+#define R_PPC64_ADDR16_HIGHESTA 42 /* half16 #highesta(S + A). */
+#define R_PPC64_UADDR64 43 /* doubleword64 S + A. */
+#define R_PPC64_REL64 44 /* doubleword64 S + A - P. */
+#define R_PPC64_PLT64 45 /* doubleword64 L + A. */
+#define R_PPC64_PLTREL64 46 /* doubleword64 L + A - P. */
+#define R_PPC64_TOC16 47 /* half16* S + A - .TOC. */
+#define R_PPC64_TOC16_LO 48 /* half16 #lo(S + A - .TOC.). */
+#define R_PPC64_TOC16_HI 49 /* half16 #hi(S + A - .TOC.). */
+#define R_PPC64_TOC16_HA 50 /* half16 #ha(S + A - .TOC.). */
+#define R_PPC64_TOC 51 /* doubleword64 .TOC. */
+#define R_PPC64_PLTGOT16 52 /* half16* M + A. */
+#define R_PPC64_PLTGOT16_LO 53 /* half16 #lo(M + A). */
+#define R_PPC64_PLTGOT16_HI 54 /* half16 #hi(M + A). */
+#define R_PPC64_PLTGOT16_HA 55 /* half16 #ha(M + A). */
+
+#define R_PPC64_ADDR16_DS 56 /* half16ds* (S + A) >> 2. */
+#define R_PPC64_ADDR16_LO_DS 57 /* half16ds #lo(S + A) >> 2. */
+#define R_PPC64_GOT16_DS 58 /* half16ds* (G + A) >> 2. */
+#define R_PPC64_GOT16_LO_DS 59 /* half16ds #lo(G + A) >> 2. */
+#define R_PPC64_PLT16_LO_DS 60 /* half16ds #lo(L + A) >> 2. */
+#define R_PPC64_SECTOFF_DS 61 /* half16ds* (R + A) >> 2. */
+#define R_PPC64_SECTOFF_LO_DS 62 /* half16ds #lo(R + A) >> 2. */
+#define R_PPC64_TOC16_DS 63 /* half16ds* (S + A - .TOC.) >> 2. */
+#define R_PPC64_TOC16_LO_DS 64 /* half16ds #lo(S + A - .TOC.) >> 2. */
+#define R_PPC64_PLTGOT16_DS 65 /* half16ds* (M + A) >> 2. */
+#define R_PPC64_PLTGOT16_LO_DS 66 /* half16ds #lo(M + A) >> 2. */
+
+/* PowerPC64 relocations defined for the TLS access ABI. */
+#define R_PPC64_TLS 67 /* none (sym+add)@tls */
+#define R_PPC64_DTPMOD64 68 /* doubleword64 (sym+add)@dtpmod */
+#define R_PPC64_TPREL16 69 /* half16* (sym+add)@tprel */
+#define R_PPC64_TPREL16_LO 70 /* half16 (sym+add)@tprel@l */
+#define R_PPC64_TPREL16_HI 71 /* half16 (sym+add)@tprel@h */
+#define R_PPC64_TPREL16_HA 72 /* half16 (sym+add)@tprel@ha */
+#define R_PPC64_TPREL64 73 /* doubleword64 (sym+add)@tprel */
+#define R_PPC64_DTPREL16 74 /* half16* (sym+add)@dtprel */
+#define R_PPC64_DTPREL16_LO 75 /* half16 (sym+add)@dtprel@l */
+#define R_PPC64_DTPREL16_HI 76 /* half16 (sym+add)@dtprel@h */
+#define R_PPC64_DTPREL16_HA 77 /* half16 (sym+add)@dtprel@ha */
+#define R_PPC64_DTPREL64 78 /* doubleword64 (sym+add)@dtprel */
+#define R_PPC64_GOT_TLSGD16 79 /* half16* (sym+add)@got@tlsgd */
+#define R_PPC64_GOT_TLSGD16_LO 80 /* half16 (sym+add)@got@tlsgd@l */
+#define R_PPC64_GOT_TLSGD16_HI 81 /* half16 (sym+add)@got@tlsgd@h */
+#define R_PPC64_GOT_TLSGD16_HA 82 /* half16 (sym+add)@got@tlsgd@ha */
+#define R_PPC64_GOT_TLSLD16 83 /* half16* (sym+add)@got@tlsld */
+#define R_PPC64_GOT_TLSLD16_LO 84 /* half16 (sym+add)@got@tlsld@l */
+#define R_PPC64_GOT_TLSLD16_HI 85 /* half16 (sym+add)@got@tlsld@h */
+#define R_PPC64_GOT_TLSLD16_HA 86 /* half16 (sym+add)@got@tlsld@ha */
+#define R_PPC64_GOT_TPREL16_DS 87 /* half16ds* (sym+add)@got@tprel */
+#define R_PPC64_GOT_TPREL16_LO_DS 88 /* half16ds (sym+add)@got@tprel@l */
+#define R_PPC64_GOT_TPREL16_HI 89 /* half16 (sym+add)@got@tprel@h */
+#define R_PPC64_GOT_TPREL16_HA 90 /* half16 (sym+add)@got@tprel@ha */
+#define R_PPC64_GOT_DTPREL16_DS 91 /* half16ds* (sym+add)@got@dtprel */
+#define R_PPC64_GOT_DTPREL16_LO_DS 92 /* half16ds (sym+add)@got@dtprel@l */
+#define R_PPC64_GOT_DTPREL16_HI 93 /* half16 (sym+add)@got@dtprel@h */
+#define R_PPC64_GOT_DTPREL16_HA 94 /* half16 (sym+add)@got@dtprel@ha */
+#define R_PPC64_TPREL16_DS 95 /* half16ds* (sym+add)@tprel */
+#define R_PPC64_TPREL16_LO_DS 96 /* half16ds (sym+add)@tprel@l */
+#define R_PPC64_TPREL16_HIGHER 97 /* half16 (sym+add)@tprel@higher */
+#define R_PPC64_TPREL16_HIGHERA 98 /* half16 (sym+add)@tprel@highera */
+#define R_PPC64_TPREL16_HIGHEST 99 /* half16 (sym+add)@tprel@highest */
+#define R_PPC64_TPREL16_HIGHESTA 100 /* half16 (sym+add)@tprel@highesta */
+#define R_PPC64_DTPREL16_DS 101 /* half16ds* (sym+add)@dtprel */
+#define R_PPC64_DTPREL16_LO_DS 102 /* half16ds (sym+add)@dtprel@l */
+#define R_PPC64_DTPREL16_HIGHER 103 /* half16 (sym+add)@dtprel@higher */
+#define R_PPC64_DTPREL16_HIGHERA 104 /* half16 (sym+add)@dtprel@highera */
+#define R_PPC64_DTPREL16_HIGHEST 105 /* half16 (sym+add)@dtprel@highest */
+#define R_PPC64_DTPREL16_HIGHESTA 106 /* half16 (sym+add)@dtprel@highesta */
+
+/* Additional relocation types */
+#define R_PPC64_TOC32 107
+#define R_PPC64_DTPMOD32 108
+#define R_PPC64_TPREL32 109
+#define R_PPC64_DTPREL32 110
+
+/* Keep this the last entry. */
+#define R_PPC64_NUM 111
+
+/* Relocation types for MIPS */
+#define R_MIPS_NONE 0
+#define R_MIPS_16 1
+#define R_MIPS_32 2
+#define R_MIPS_ADD 2
+#define R_MIPS_REL 3
+#define R_MIPS_REL32 3
+#define R_MIPS_26 4
+#define R_MIPS_HI16 5
+#define R_MIPS_LO16 6
+#define R_MIPS_GPREL 7
+#define R_MIPS_GPREL16 7
+#define R_MIPS_LITERAL 8
+#define R_MIPS_GOT 9
+#define R_MIPS_GOT16 9
+#define R_MIPS_PC16 10
+#define R_MIPS_CALL 11
+#define R_MIPS_CALL16 11
+#define R_MIPS_GPREL32 12
+
+#define R_MIPS_SHIFT5 16
+#define R_MIPS_SHIFT6 17
+#define R_MIPS_64 18
+#define R_MIPS_GOT_DISP 19
+#define R_MIPS_GOT_PAGE 20
+#define R_MIPS_GOT_OFST 21
+#define R_MIPS_GOT_HI16 22
+#define R_MIPS_GOT_LO16 23
+#define R_MIPS_SUB 24
+#define R_MIPS_INSERT_A 25
+#define R_MIPS_INSERT_B 26
+#define R_MIPS_DELETE 27
+#define R_MIPS_HIGHER 28
+#define R_MIPS_HIGHEST 29
+#define R_MIPS_CALL_HI16 30
+#define R_MIPS_CALL_LO16 31
+#define R_MIPS_SCN_DISP 32
+#define R_MIPS_REL16 33
+#define R_MIPS_ADD_IMMEDIATE 34
diff --git a/dwarfdump/print_sections.c b/dwarfdump/print_sections.c
new file mode 100644
index 0000000..a5e6ef1
--- /dev/null
+++ b/dwarfdump/print_sections.c
@@ -0,0 +1,206 @@
+/*
+ Copyright (C) 2000-2006 Silicon Graphics, Inc. All Rights Reserved.
+ Portions Copyright 2007-2010 Sun Microsystems, Inc. All rights reserved.
+ Portions Copyright 2009-2010 SN Systems Ltd. All rights reserved.
+ Portions Copyright 2008-2011 David Anderson. All rights reserved.
+
+ This program is free software; you can redistribute it and/or modify it
+ under the terms of version 2 of the GNU General Public License as
+ published by the Free Software Foundation.
+
+ This program is distributed in the hope that it would be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+ Further, this software is distributed without any warranty that it is
+ free of the rightful claim of any third person regarding infringement
+ or the like. Any license provided herein, whether implied or
+ otherwise, applies only to this software file. Patent licenses, if
+ any, provided herein do not apply to combinations of this program with
+ other software, or any other product whatsoever.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write the Free Software Foundation, Inc., 51
+ Franklin Street - Fifth Floor, Boston MA 02110-1301, USA.
+
+ Contact information: Silicon Graphics, Inc., 1500 Crittenden Lane,
+ Mountain View, CA 94043, or:
+
+ http://www.sgi.com
+
+ For further information regarding this notice, see:
+
+ http://oss.sgi.com/projects/GenInfo/NoticeExplan
+
+
+
+$Header: /plroot/cmplrs.src/v7.4.5m/.RCS/PL/dwarfdump/RCS/print_sections.c,v 1.69 2006/04/17 00:09:56 davea Exp $ */
+/* The address of the Free Software Foundation is
+ Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+ SGI has moved from the Crittenden Lane address.
+*/
+
+#include "globals.h"
+#include "naming.h"
+#include "dwconf.h"
+#include "esb.h"
+
+#include "print_sections.h"
+#include "print_frames.h"
+
+/*
+ Print line number information:
+ filename
+ new basic-block
+ [line] [address] <new statement>
+*/
+
+int dwarf_names_print_on_error = 1;
+
+/* referred in dwarfdump.c */
+Dwarf_Die current_cu_die_for_print_frames;
+
+void
+deal_with_name_offset_err(Dwarf_Debug dbg,
+ char *err_loc,
+ char *name, Dwarf_Unsigned die_off,
+ int nres, Dwarf_Error err)
+{
+ if (nres == DW_DLV_ERROR) {
+ Dwarf_Unsigned myerr = dwarf_errno(err);
+
+ if (myerr == DW_DLE_OFFSET_BAD) {
+ printf("Error: bad offset %s, %s %" DW_PR_DUu
+ " (0x%08" DW_PR_DUx ")\n",
+ err_loc,
+ name,
+ die_off,
+ die_off);
+ }
+ print_error(dbg, err_loc, nres, err);
+ }
+}
+
+
+
+/* The April 2005 dwarf_get_section_max_offsets()
+ in libdwarf returns all max-offsets, but we only
+ want one of those offsets. This function returns
+ the one we want from that set,
+ making functions needing this offset as readable as possible.
+ (avoiding code duplication).
+*/
+Dwarf_Unsigned
+get_info_max_offset(Dwarf_Debug dbg)
+{
+ Dwarf_Unsigned debug_info_size = 0;
+ Dwarf_Unsigned debug_abbrev_size = 0;
+ Dwarf_Unsigned debug_line_size = 0;
+ Dwarf_Unsigned debug_loc_size = 0;
+ Dwarf_Unsigned debug_aranges_size = 0;
+ Dwarf_Unsigned debug_macinfo_size = 0;
+ Dwarf_Unsigned debug_pubnames_size = 0;
+ Dwarf_Unsigned debug_str_size = 0;
+ Dwarf_Unsigned debug_frame_size = 0;
+ Dwarf_Unsigned debug_ranges_size = 0;
+ Dwarf_Unsigned debug_pubtypes_size = 0;
+
+ dwarf_get_section_max_offsets(dbg,
+ &debug_info_size,
+ &debug_abbrev_size,
+ &debug_line_size,
+ &debug_loc_size,
+ &debug_aranges_size,
+ &debug_macinfo_size,
+ &debug_pubnames_size,
+ &debug_str_size,
+ &debug_frame_size,
+ &debug_ranges_size,
+ &debug_pubtypes_size);
+
+ return debug_info_size;
+}
+
+/*
+ decode ULEB
+*/
+Dwarf_Unsigned
+local_dwarf_decode_u_leb128(unsigned char *leb128,
+ unsigned int *leb128_length)
+{
+ unsigned char byte = 0;
+ Dwarf_Unsigned number = 0;
+ unsigned int shift = 0;
+ unsigned int byte_length = 1;
+
+ byte = *leb128;
+ for (;;) {
+ number |= (byte & 0x7f) << shift;
+ shift += 7;
+
+ if ((byte & 0x80) == 0) {
+ if (leb128_length != NULL)
+ *leb128_length = byte_length;
+ return (number);
+ }
+
+ byte_length++;
+ byte = *(++leb128);
+ }
+}
+
+#define BITSINBYTE 8
+Dwarf_Signed
+local_dwarf_decode_s_leb128(unsigned char *leb128,
+ unsigned int *leb128_length)
+{
+ Dwarf_Signed number = 0;
+ Dwarf_Bool sign = 0;
+ Dwarf_Signed shift = 0;
+ unsigned char byte = *leb128;
+ Dwarf_Signed byte_length = 1;
+
+ /* byte_length being the number of bytes of data absorbed so far in
+ turning the leb into a Dwarf_Signed. */
+
+ for (;;) {
+ sign = byte & 0x40;
+ number |= ((Dwarf_Signed) ((byte & 0x7f))) << shift;
+ shift += 7;
+
+ if ((byte & 0x80) == 0) {
+ break;
+ }
+ ++leb128;
+ byte = *leb128;
+ byte_length++;
+ }
+
+ if ((shift < sizeof(Dwarf_Signed) * BITSINBYTE) && sign) {
+ number |= -((Dwarf_Signed) 1 << shift);
+ }
+
+ if (leb128_length != NULL)
+ *leb128_length = byte_length;
+ return (number);
+}
+
+
+/* Dumping a dwarf-expression as a byte stream. */
+void
+dump_block(char *prefix, char *data, Dwarf_Signed len)
+{
+ char *end_data = data + len;
+ char *cur = data;
+ int i = 0;
+
+ printf("%s", prefix);
+ for (; cur < end_data; ++cur, ++i) {
+ if (i > 0 && i % 4 == 0)
+ printf(" ");
+ printf("%02x", 0xff & *cur);
+
+ }
+}
+
diff --git a/dwarfdump/print_sections.h b/dwarfdump/print_sections.h
new file mode 100644
index 0000000..63015cd
--- /dev/null
+++ b/dwarfdump/print_sections.h
@@ -0,0 +1,54 @@
+/*
+ Copyright (C) 2006 Silicon Graphics, Inc. All Rights Reserved.
+ Portions Copyright (C) 2009-2011 David Anderson. All Rights Reserved.
+
+ This program is free software; you can redistribute it and/or modify it
+ under the terms of version 2 of the GNU General Public License as
+ published by the Free Software Foundation.
+
+ This program is distributed in the hope that it would be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+ Further, this software is distributed without any warranty that it is
+ free of the rightful claim of any third person regarding infringement
+ or the like. Any license provided herein, whether implied or
+ otherwise, applies only to this software file. Patent licenses, if
+ any, provided herein do not apply to combinations of this program with
+ other software, or any other product whatsoever.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write the Free Software Foundation, Inc., 51
+ Franklin Street - Fifth Floor, Boston MA 02110-1301, USA.
+
+ Contact information: Silicon Graphics, Inc., 1500 Crittenden Lane,
+ Mountain View, CA 94043, or:
+
+ http://www.sgi.com
+
+ For further information regarding this notice, see:
+
+ http://oss.sgi.com/projects/GenInfo/NoticeExplan
+
+
+*/
+
+
+extern int dwarf_names_print_on_error;
+
+void deal_with_name_offset_err(Dwarf_Debug dbg,
+ char *err_loc,
+ char *name,
+ Dwarf_Unsigned die_off,
+ int nres,
+ Dwarf_Error err);
+
+Dwarf_Unsigned get_info_max_offset(Dwarf_Debug dbg);
+
+void print_pubname_style_entry(Dwarf_Debug dbg,
+ char *line_title,
+ char *name,
+ Dwarf_Unsigned die_off,
+ Dwarf_Unsigned cu_off,
+ Dwarf_Unsigned global_cu_off,
+ Dwarf_Unsigned maxoff);
diff --git a/dwarfdump/print_static_funcs.c b/dwarfdump/print_static_funcs.c
new file mode 100644
index 0000000..c3dc59d
--- /dev/null
+++ b/dwarfdump/print_static_funcs.c
@@ -0,0 +1,137 @@
+/*
+ Copyright (C) 2000-2006 Silicon Graphics, Inc. All Rights Reserved.
+ Portions Copyright 2007-2010 Sun Microsystems, Inc. All rights reserved.
+ Portions Copyright 2009-2011 SN Systems Ltd. All rights reserved.
+ Portions Copyright 2008-2011 David Anderson. All rights reserved.
+
+ This program is free software; you can redistribute it and/or modify it
+ under the terms of version 2 of the GNU General Public License as
+ published by the Free Software Foundation.
+
+ This program is distributed in the hope that it would be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+ Further, this software is distributed without any warranty that it is
+ free of the rightful claim of any third person regarding infringement
+ or the like. Any license provided herein, whether implied or
+ otherwise, applies only to this software file. Patent licenses, if
+ any, provided herein do not apply to combinations of this program with
+ other software, or any other product whatsoever.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write the Free Software Foundation, Inc., 51
+ Franklin Street - Fifth Floor, Boston MA 02110-1301, USA.
+
+ Contact information: Silicon Graphics, Inc., 1500 Crittenden Lane,
+ Mountain View, CA 94043, or:
+
+ http://www.sgi.com
+
+ For further information regarding this notice, see:
+
+ http://oss.sgi.com/projects/GenInfo/NoticeExplan
+
+
+
+$Header: /plroot/cmplrs.src/v7.4.5m/.RCS/PL/dwarfdump/RCS/print_sections.c,v 1.69 2006/04/17 00:09:56 davea Exp $ */
+/* The address of the Free Software Foundation is
+ Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+ SGI has moved from the Crittenden Lane address.
+*/
+
+#include "globals.h"
+#include "naming.h"
+#include "dwconf.h"
+#include "esb.h"
+
+#include "print_sections.h"
+#include "print_frames.h"
+
+
+/* Get all the data in .debug_static_funcs
+ On error, this allows some dwarf memory leaks.
+*/
+extern void
+print_static_funcs(Dwarf_Debug dbg)
+{
+ Dwarf_Func *funcbuf = NULL;
+ Dwarf_Signed count = 0;
+ Dwarf_Signed i = 0;
+ Dwarf_Off die_off = 0;
+ Dwarf_Off cu_off = 0;
+ int gfres = 0;
+
+ current_section_id = DEBUG_STATIC_FUNC;
+
+ if (!do_print_dwarf) {
+ return;
+ }
+
+ printf("\n.debug_static_func\n");
+ gfres = dwarf_get_funcs(dbg, &funcbuf, &count, &err);
+ if (gfres == DW_DLV_ERROR) {
+ print_error(dbg, "dwarf_get_funcs", gfres, err);
+ } else if (gfres == DW_DLV_NO_ENTRY) {
+ /* no static funcs */
+ } else {
+ Dwarf_Unsigned maxoff = get_info_max_offset(dbg);
+
+ for (i = 0; i < count; i++) {
+ int fnres = 0;
+ int cures3 = 0;
+ Dwarf_Unsigned global_cu_off = 0;
+ char *name = 0;
+
+ fnres = dwarf_func_name_offsets(funcbuf[i], &name, &die_off,
+ &cu_off, &err);
+ deal_with_name_offset_err(dbg, "dwarf_func_name_offsets",
+ name, die_off, fnres, err);
+ cures3 = dwarf_func_cu_offset(funcbuf[i],
+ &global_cu_off, &err);
+ if (cures3 != DW_DLV_OK) {
+ print_error(dbg, "dwarf_global_cu_offset", cures3, err);
+ }
+
+ if (check_pubname_attr) {
+ Dwarf_Bool has_attr;
+ int ares;
+ int dres;
+ Dwarf_Die die;
+
+ /* get die at die_off */
+ dres = dwarf_offdie(dbg, die_off, &die, &err);
+ if (dres != DW_DLV_OK) {
+ print_error(dbg, "dwarf_offdie", dres, err);
+ }
+
+
+ ares =
+ dwarf_hasattr(die, DW_AT_external, &has_attr, &err);
+ if (ares == DW_DLV_ERROR) {
+ print_error(dbg, "hassattr on DW_AT_external", ares,
+ err);
+ }
+ if (checking_this_compiler()) {
+ DWARF_CHECK_COUNT(pubname_attr_result,1);
+ if (ares == DW_DLV_OK && has_attr) {
+ /* Should the value of flag be examined? */
+ } else {
+ DWARF_CHECK_ERROR2(pubname_attr_result,name,
+ "pubname (in static funcs section) does not have DW_AT_external");
+ }
+ }
+ dwarf_dealloc(dbg, die, DW_DLA_DIE);
+ }
+
+ if (do_print_dwarf || record_dwarf_error) {
+ print_pubname_style_entry(dbg,
+ "static-func", name, die_off,
+ cu_off, global_cu_off, maxoff);
+ record_dwarf_error = FALSE; /* Clear error condition */
+ }
+ }
+ dwarf_funcs_dealloc(dbg, funcbuf, count);
+ }
+} /* print_static_funcs() */
diff --git a/dwarfdump/print_static_vars.c b/dwarfdump/print_static_vars.c
new file mode 100644
index 0000000..5e42b67
--- /dev/null
+++ b/dwarfdump/print_static_vars.c
@@ -0,0 +1,104 @@
+/*
+ Copyright (C) 2000-2006 Silicon Graphics, Inc. All Rights Reserved.
+ Portions Copyright 2007-2010 Sun Microsystems, Inc. All rights reserved.
+ Portions Copyright 2009-2010 SN Systems Ltd. All rights reserved.
+ Portions Copyright 2008-2011 David Anderson. All rights reserved.
+
+ This program is free software; you can redistribute it and/or modify it
+ under the terms of version 2 of the GNU General Public License as
+ published by the Free Software Foundation.
+
+ This program is distributed in the hope that it would be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+ Further, this software is distributed without any warranty that it is
+ free of the rightful claim of any third person regarding infringement
+ or the like. Any license provided herein, whether implied or
+ otherwise, applies only to this software file. Patent licenses, if
+ any, provided herein do not apply to combinations of this program with
+ other software, or any other product whatsoever.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write the Free Software Foundation, Inc., 51
+ Franklin Street - Fifth Floor, Boston MA 02110-1301, USA.
+
+ Contact information: Silicon Graphics, Inc., 1500 Crittenden Lane,
+ Mountain View, CA 94043, or:
+
+ http://www.sgi.com
+
+ For further information regarding this notice, see:
+
+ http://oss.sgi.com/projects/GenInfo/NoticeExplan
+
+ $Header: /plroot/cmplrs.src/v7.4.5m/.RCS/PL/dwarfdump/RCS/print_sections.c,v 1.69 2006/04/17 00:09:56 davea Exp $ */
+
+/* The address of the Free Software Foundation is
+ Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+ SGI has moved from the Crittenden Lane address.
+*/
+
+#include "globals.h"
+#include "naming.h"
+#include "dwconf.h"
+#include "esb.h"
+
+#include "print_sections.h"
+#include "print_frames.h"
+
+/* Get all the data in .debug_static_vars */
+extern void
+print_static_vars(Dwarf_Debug dbg)
+{
+ Dwarf_Var *varbuf = NULL;
+ Dwarf_Signed count = 0;
+ Dwarf_Signed i = 0;
+ Dwarf_Off die_off = 0;
+ Dwarf_Off cu_off = 0;
+ char *name = 0;
+ int gvres = 0;
+
+ current_section_id = DEBUG_STATIC_VARS;
+
+ if (!do_print_dwarf) {
+ return;
+ }
+
+ printf("\n.debug_static_vars\n");
+ gvres = dwarf_get_vars(dbg, &varbuf, &count, &err);
+ if (gvres == DW_DLV_ERROR) {
+ print_error(dbg, "dwarf_get_vars", gvres, err);
+ } else if (gvres == DW_DLV_NO_ENTRY) {
+ /* no static vars */
+ } else {
+ Dwarf_Unsigned maxoff = get_info_max_offset(dbg);
+
+ for (i = 0; i < count; i++) {
+ int vnres = 0;
+ int cures3 = 0;
+ Dwarf_Off global_cu_off = 0;
+
+ vnres = dwarf_var_name_offsets(varbuf[i], &name, &die_off,
+ &cu_off, &err);
+ deal_with_name_offset_err(dbg,
+ "dwarf_var_name_offsets",
+ name, die_off, vnres, err);
+ cures3 = dwarf_var_cu_offset(varbuf[i],
+ &global_cu_off, &err);
+ if (cures3 != DW_DLV_OK) {
+ print_error(dbg, "dwarf_global_cu_offset", cures3, err);
+ }
+
+ print_pubname_style_entry(dbg,
+ "static-var",
+ name, die_off, cu_off,
+ global_cu_off, maxoff);
+
+ /* print associated die too? */
+ }
+ dwarf_vars_dealloc(dbg, varbuf, count);
+ }
+} /* print_static_vars */
+
diff --git a/dwarfdump/print_strings.c b/dwarfdump/print_strings.c
new file mode 100644
index 0000000..0cd67b3
--- /dev/null
+++ b/dwarfdump/print_strings.c
@@ -0,0 +1,80 @@
+/*
+ Copyright (C) 2000-2006 Silicon Graphics, Inc. All Rights Reserved.
+ Portions Copyright 2007-2010 Sun Microsystems, Inc. All rights reserved.
+ Portions Copyright 2009-2010 SN Systems Ltd. All rights reserved.
+ Portions Copyright 2008-2011 David Anderson. All rights reserved.
+
+ This program is free software; you can redistribute it and/or modify it
+ under the terms of version 2 of the GNU General Public License as
+ published by the Free Software Foundation.
+
+ This program is distributed in the hope that it would be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+ Further, this software is distributed without any warranty that it is
+ free of the rightful claim of any third person regarding infringement
+ or the like. Any license provided herein, whether implied or
+ otherwise, applies only to this software file. Patent licenses, if
+ any, provided herein do not apply to combinations of this program with
+ other software, or any other product whatsoever.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write the Free Software Foundation, Inc., 51
+ Franklin Street - Fifth Floor, Boston MA 02110-1301, USA.
+
+ Contact information: Silicon Graphics, Inc., 1500 Crittenden Lane,
+ Mountain View, CA 94043, or:
+
+ http://www.sgi.com
+
+ For further information regarding this notice, see:
+
+ http://oss.sgi.com/projects/GenInfo/NoticeExplan
+
+
+
+$Header: /plroot/cmplrs.src/v7.4.5m/.RCS/PL/dwarfdump/RCS/print_sections.c,v 1.69 2006/04/17 00:09:56 davea Exp $ */
+/* The address of the Free Software Foundation is
+ Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+ SGI has moved from the Crittenden Lane address.
+*/
+
+#include "globals.h"
+#include "naming.h"
+#include "dwconf.h"
+#include "esb.h"
+
+#include "print_sections.h"
+
+/* print data in .debug_string */
+extern void
+print_strings(Dwarf_Debug dbg)
+{
+ Dwarf_Signed length = 0;
+ string name;
+ Dwarf_Off offset = 0;
+ int sres = 0;
+
+ current_section_id = DEBUG_STR;
+ printf("\n.debug_string\n");
+ while ((sres = dwarf_get_str(dbg, offset, &name, &length, &err))
+ == DW_DLV_OK) {
+ if (display_offsets) {
+ printf("name at offset 0x%" DW_PR_XZEROS DW_PR_DUx
+ ", length %4" DW_PR_DSd " is '%s'\n",
+ (Dwarf_Unsigned)offset, length, name);
+ } else {
+ printf("name: length %4" DW_PR_DSd " is '%s'\n",
+ length, name);
+ }
+ offset += length + 1;
+ }
+ /* An inability to find the section is not necessarily
+ a real error, so do not report error unless we've
+ seen a real record. */
+ if(sres == DW_DLV_ERROR && offset != 0) {
+ print_error(dbg, "dwarf_get_str failure", sres, err);
+ }
+}
diff --git a/dwarfdump/print_types.c b/dwarfdump/print_types.c
new file mode 100644
index 0000000..f3fddba
--- /dev/null
+++ b/dwarfdump/print_types.c
@@ -0,0 +1,141 @@
+/*
+ Copyright (C) 2000-2006 Silicon Graphics, Inc. All Rights Reserved.
+ Portions Copyright 2007-2010 Sun Microsystems, Inc. All rights reserved.
+ Portions Copyright 2009-2010 SN Systems Ltd. All rights reserved.
+ Portions Copyright 2008-2011 David Anderson. All rights reserved.
+
+ This program is free software; you can redistribute it and/or modify it
+ under the terms of version 2 of the GNU General Public License as
+ published by the Free Software Foundation.
+
+ This program is distributed in the hope that it would be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+ Further, this software is distributed without any warranty that it is
+ free of the rightful claim of any third person regarding infringement
+ or the like. Any license provided herein, whether implied or
+ otherwise, applies only to this software file. Patent licenses, if
+ any, provided herein do not apply to combinations of this program with
+ other software, or any other product whatsoever.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write the Free Software Foundation, Inc., 51
+ Franklin Street - Fifth Floor, Boston MA 02110-1301, USA.
+
+ Contact information: Silicon Graphics, Inc., 1500 Crittenden Lane,
+ Mountain View, CA 94043, or:
+
+ http://www.sgi.com
+
+ For further information regarding this notice, see:
+
+ http://oss.sgi.com/projects/GenInfo/NoticeExplan
+
+
+
+$Header: /plroot/cmplrs.src/v7.4.5m/.RCS/PL/dwarfdump/RCS/print_sections.c,v 1.69 2006/04/17 00:09:56 davea Exp $ */
+/* The address of the Free Software Foundation is
+ Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+ SGI has moved from the Crittenden Lane address.
+*/
+
+#include "globals.h"
+#include "naming.h"
+#include "dwconf.h"
+#include "esb.h"
+
+#include "print_sections.h"
+#include "print_frames.h"
+
+/* get all the data in .debug_types */
+extern void
+print_types(Dwarf_Debug dbg, enum type_type_e type_type)
+{
+ Dwarf_Type *typebuf = NULL;
+ Dwarf_Signed count = 0;
+ Dwarf_Signed i = 0;
+ char *name = NULL;
+ int gtres = 0;
+
+ char *section_name = NULL;
+ char *offset_err_name = NULL;
+ char *section_open_name = NULL;
+ char *print_name_prefix = NULL;
+ int (*get_types) (Dwarf_Debug, Dwarf_Type **, Dwarf_Signed *,
+ Dwarf_Error *) = 0;
+ int (*get_offset) (Dwarf_Type, char **, Dwarf_Off *, Dwarf_Off *,
+ Dwarf_Error *) = NULL;
+ int (*get_cu_offset) (Dwarf_Type, Dwarf_Off *, Dwarf_Error *) =
+ NULL;
+ void (*dealloctype) (Dwarf_Debug, Dwarf_Type *, Dwarf_Signed) =
+ NULL;
+
+ /* Do nothing if in check mode */
+ if (!do_print_dwarf) {
+ return;
+ }
+
+
+ if (type_type == DWARF_PUBTYPES) {
+ section_name = ".debug_pubtypes";
+ offset_err_name = "dwarf_pubtype_name_offsets";
+ section_open_name = "dwarf_get_pubtypes";
+ print_name_prefix = "pubtype";
+ get_types = dwarf_get_pubtypes;
+ get_offset = dwarf_pubtype_name_offsets;
+ get_cu_offset = dwarf_pubtype_cu_offset;
+ dealloctype = dwarf_pubtypes_dealloc;
+ } else {
+ /* SGI_TYPENAME */
+ section_name = ".debug_typenames";
+ offset_err_name = "dwarf_type_name_offsets";
+ section_open_name = "dwarf_get_types";
+ print_name_prefix = "type";
+ get_types = dwarf_get_types;
+ get_offset = dwarf_type_name_offsets;
+ get_cu_offset = dwarf_type_cu_offset;
+ dealloctype = dwarf_types_dealloc;
+ }
+
+
+
+ gtres = get_types(dbg, &typebuf, &count, &err);
+ if (gtres == DW_DLV_ERROR) {
+ print_error(dbg, section_open_name, gtres, err);
+ } else if (gtres == DW_DLV_NO_ENTRY) {
+ /* no types */
+ } else {
+ Dwarf_Unsigned maxoff = get_info_max_offset(dbg);
+
+ /* Before July 2005, the section name was printed
+ unconditionally, now only prints if non-empty section really
+ exists. */
+ printf("\n%s\n", section_name);
+
+ for (i = 0; i < count; i++) {
+ int tnres = 0;
+ int cures3 = 0;
+ Dwarf_Off die_off = 0;
+ Dwarf_Off cu_off = 0;
+ Dwarf_Off global_cu_off = 0;
+
+ tnres =
+ get_offset(typebuf[i], &name, &die_off, &cu_off, &err);
+ deal_with_name_offset_err(dbg, offset_err_name, name,
+ die_off, tnres, err);
+ cures3 = get_cu_offset(typebuf[i], &global_cu_off, &err);
+ if (cures3 != DW_DLV_OK) {
+ print_error(dbg, "dwarf_var_cu_offset", cures3, err);
+ }
+ print_pubname_style_entry(dbg,
+ print_name_prefix,
+ name, die_off, cu_off,
+ global_cu_off, maxoff);
+
+ /* print associated die too? */
+ }
+ dealloctype(dbg, typebuf, count);
+ }
+} /* print_types() */
diff --git a/dwarfdump/print_weaknames.c b/dwarfdump/print_weaknames.c
new file mode 100644
index 0000000..fd60ea8
--- /dev/null
+++ b/dwarfdump/print_weaknames.c
@@ -0,0 +1,104 @@
+/*
+ Copyright (C) 2000-2006 Silicon Graphics, Inc. All Rights Reserved.
+ Portions Copyright 2007-2010 Sun Microsystems, Inc. All rights reserved.
+ Portions Copyright 2009-2011 SN Systems Ltd. All rights reserved.
+ Portions Copyright 2008-2011 David Anderson. All rights reserved.
+
+ This program is free software; you can redistribute it and/or modify it
+ under the terms of version 2 of the GNU General Public License as
+ published by the Free Software Foundation.
+
+ This program is distributed in the hope that it would be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+ Further, this software is distributed without any warranty that it is
+ free of the rightful claim of any third person regarding infringement
+ or the like. Any license provided herein, whether implied or
+ otherwise, applies only to this software file. Patent licenses, if
+ any, provided herein do not apply to combinations of this program with
+ other software, or any other product whatsoever.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write the Free Software Foundation, Inc., 51
+ Franklin Street - Fifth Floor, Boston MA 02110-1301, USA.
+
+ Contact information: Silicon Graphics, Inc., 1500 Crittenden Lane,
+ Mountain View, CA 94043, or:
+
+ http://www.sgi.com
+
+ For further information regarding this notice, see:
+
+ http://oss.sgi.com/projects/GenInfo/NoticeExplan
+
+
+
+ $Header: /plroot/cmplrs.src/v7.4.5m/.RCS/PL/dwarfdump/RCS/print_sections.c,v 1.69 2006/04/17 00:09:56 davea Exp $ */
+
+/* The address of the Free Software Foundation is
+ Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+ SGI has moved from the Crittenden Lane address.
+*/
+
+#include "globals.h"
+#include "naming.h"
+#include "dwconf.h"
+#include "esb.h"
+
+#include "print_sections.h"
+
+/* Get all the data in .debug_weaknames */
+extern void
+print_weaknames(Dwarf_Debug dbg)
+{
+ Dwarf_Weak *weaknamebuf = NULL;
+ Dwarf_Signed count = 0;
+ Dwarf_Signed i = 0;
+ Dwarf_Off die_off = 0;
+ Dwarf_Off cu_off = 0;
+ char *name = NULL;
+ int wkres = 0;
+
+ current_section_id = DEBUG_WEAKNAMES;
+
+ if (!do_print_dwarf) {
+ return;
+ }
+ printf("\n.debug_weaknames\n");
+ wkres = dwarf_get_weaks(dbg, &weaknamebuf, &count, &err);
+ if (wkres == DW_DLV_ERROR) {
+ print_error(dbg, "dwarf_get_weaks", wkres, err);
+ } else if (wkres == DW_DLV_NO_ENTRY) {
+ /* no weaknames */
+ } else {
+ Dwarf_Unsigned maxoff = get_info_max_offset(dbg);
+
+ for (i = 0; i < count; i++) {
+ int tnres = 0;
+ int cures3 = 0;
+ Dwarf_Unsigned global_cu_off = 0;
+
+ tnres = dwarf_weak_name_offsets(weaknamebuf[i],
+ &name, &die_off, &cu_off,
+ &err);
+ deal_with_name_offset_err(dbg,
+ "dwarf_weak_name_offsets",
+ name, die_off, tnres, err);
+ cures3 = dwarf_weak_cu_offset(weaknamebuf[i],
+ &global_cu_off, &err);
+ if (cures3 != DW_DLV_OK) {
+ print_error(dbg, "dwarf_weakname_cu_offset",
+ cures3, err);
+ }
+ print_pubname_style_entry(dbg,
+ "weakname",
+ name, die_off, cu_off,
+ global_cu_off, maxoff);
+
+ /* print associated die too? */
+ }
+ dwarf_weaks_dealloc(dbg, weaknamebuf, count);
+ }
+} /* print_weaknames() */
diff --git a/dwarfdump/strstrnocase.c b/dwarfdump/strstrnocase.c
new file mode 100755
index 0000000..082af66
--- /dev/null
+++ b/dwarfdump/strstrnocase.c
@@ -0,0 +1,118 @@
+/*
+ Copyright (C) 2009-2010 David Anderson. All Rights Reserved.
+
+ This program is free software; you can redistribute it and/or modify it
+ under the terms of version 2 of the GNU General Public License as
+ published by the Free Software Foundation.
+
+ This program is distributed in the hope that it would be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+ Further, this software is distributed without any warranty that it is
+ free of the rightful claim of any third person regarding infringement
+ or the like. Any license provided herein, whether implied or
+ otherwise, applies only to this software file. Patent licenses, if
+ any, provided herein do not apply to combinations of this program with
+ other software, or any other product whatsoever.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write the Free Software Foundation, Inc., 51
+ Franklin Street - Fifth Floor, Boston MA 02110-1301, USA.
+
+ Contact information: Silicon Graphics, Inc., 1500 Crittenden Lane,
+ Mountain View, CA 94043, or:
+
+ http://www.sgi.com
+
+ For further information regarding this notice, see:
+
+ http://oss.sgi.com/projects/GenInfo/NoticeExplan
+
+*/
+/* The address of the Free Software Foundation is
+ Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+ Boston, MA 02110-1301, USA. */
+
+
+
+/*
+This tries to find the string 'contained' in the
+string 'container'. it returns true if found, else false.
+The comparisons are independent of case.
+
+Regrettably there is no generally accepted version that
+does this job, though GNU Linux has strcasestr() which
+does what we need. Our code here do not behave like
+strstr or strcasestr in the case of
+an empty 'contained' argument: we return FALSE (this
+case is not interesting for dwarfdump).
+
+There is a public domain stristr(). But given that dwarfdump is GPL,
+it would seem (IANAL) that we cannot mix public domain code
+into the release.
+
+The software here is independently written and indeed trivial.
+
+The POSIX function tolower() is only properly defined on unsigned char, hence
+the ugly casts.
+
+strstrnocase.c
+
+*/
+#include <ctype.h>
+#include <stdio.h>
+#include <globals.h>
+
+boolean
+is_strstrnocase(const char * container, const char * contained)
+{
+ const unsigned char *ct = (const unsigned char *)container;
+ for( ; *ct; ++ct )
+ {
+ const unsigned char * cntnd = (const unsigned char *)contained;
+ boolean innerwrong = TRUE;
+ for( ; *cntnd; ++cntnd,++ct)
+ {
+ char lct = tolower(*ct);
+ char tlc = tolower(*cntnd);
+ if(lct != tlc) {
+ innerwrong=TRUE;
+ break; /* Go to outer loop */
+ }
+ innerwrong=FALSE;
+ }
+ if(!innerwrong) {
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
+#ifdef TEST
+static void
+test(const char *t1, const char *t2,int resexp)
+{
+ boolean res = is_strstrnocase(t1,t2);
+ if (res == resexp) {
+ return;
+ }
+ printf("Error,mismatch %s and %s. Expected %d got %d\n",
+ t1,t2,resexp,res);
+}
+
+int main()
+{
+ test("aaaaa","a",1);
+ test("aaaaa","b",0);
+ test("abaaba","ba",1);
+ test("abaaxa","x",1);
+ test("abaabA","Ba",1);
+ test("a","ab",0);
+ test("b","c",0);
+ test("b","",0);
+ test("","c",0);
+ test("","",0);
+ test("aaaaa","aaaaaaaa",0);
+}
+#endif
diff --git a/dwarfdump/tag_attr.c b/dwarfdump/tag_attr.c
new file mode 100644
index 0000000..899a357
--- /dev/null
+++ b/dwarfdump/tag_attr.c
@@ -0,0 +1,286 @@
+/*
+ Copyright (C) 2000-2005 Silicon Graphics, Inc. All Rights Reserved.
+ Portions Copyright (C) 2009-2010 SN Systems Ltd. All Rights Reserved.
+ Portions Copyright (C) 2009-2011 David Anderson. All Rights Reserved.
+
+ This program is free software; you can redistribute it and/or modify it
+ under the terms of version 2 of the GNU General Public License as
+ published by the Free Software Foundation.
+
+ This program is distributed in the hope that it would be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+ Further, this software is distributed without any warranty that it is
+ free of the rightful claim of any third person regarding infringement
+ or the like. Any license provided herein, whether implied or
+ otherwise, applies only to this software file. Patent licenses, if
+ any, provided herein do not apply to combinations of this program with
+ other software, or any other product whatsoever.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write the Free Software Foundation, Inc., 51
+ Franklin Street - Fifth Floor, Boston MA 02110-1301, USA.
+
+ Contact information: Silicon Graphics, Inc., 1500 Crittenden Lane,
+ Mountain View, CA 94043, or:
+
+ http://www.sgi.com
+
+ For further information regarding this notice, see:
+
+ http://oss.sgi.com/projects/GenInfo/NoticeExplan
+
+
+
+$Header: /plroot/cmplrs.src/v7.4.5m/.RCS/PL/dwarfdump/RCS/tag_attr.c,v 1.8 2005/12/01 17:34:59 davea Exp $ */
+#include <dwarf.h>
+#include <stdio.h>
+#include <stdlib.h> /* For exit() declaration etc. */
+#include <errno.h> /* For errno declaration. */
+#include <unistd.h> /* For getopt. */
+
+#include "globals.h"
+#include "libdwarf.h"
+#include "common.h"
+#include "tag_common.h"
+
+boolean ellipsis = FALSE; /* So we can use dwarf_names.c */
+
+/* Expected input format
+
+0xffffffff
+value of a tag
+value of a standard attribute that follows that tag
+...
+0xffffffff
+value of a tag
+value of a standard attribute that follows that tag
+...
+0xffffffff
+...
+
+No blank lines or commentary allowed, no symbols, just numbers.
+
+
+*/
+
+unsigned int tag_attr_combination_table[ATTR_TABLE_ROW_MAXIMUM][ATTR_TABLE_COLUMN_MAXIMUM];
+
+
+static const char *usage[] = {
+ "Usage: tag_attr_build <options>",
+ " -i input-table-path",
+ " -o output-table-path",
+ " -s (Generate standard attribute table)",
+ " -e (Generate extended attribute table (common extensions))",
+ ""
+};
+
+char *program_name = 0;
+char *input_name = 0;
+char *output_name = 0;
+int standard_flag = FALSE;
+int extended_flag = FALSE;
+
+/* process arguments */
+void
+process_args(int argc, char *argv[])
+{
+ int c = 0;
+ boolean usage_error = FALSE;
+
+ program_name = argv[0];
+
+ while ((c = getopt(argc, argv, "i:o:se")) != EOF) {
+ switch (c) {
+ case 'i':
+ input_name = optarg;
+ break;
+ case 'o':
+ output_name = optarg;
+ break;
+ case 'e':
+ extended_flag = TRUE;
+ break;
+ case 's':
+ standard_flag = TRUE;
+ break;
+ default:
+ usage_error = TRUE;
+ break;
+ }
+ }
+
+ if (usage_error || 1 == optind || optind != argc) {
+ print_usage_message(argv[0],usage);
+ exit(FAILED);
+ }
+}
+
+
+
+int
+main(int argc, char **argv)
+{
+ int i = 0;
+ unsigned int num = 0;
+ int input_eof = 0;
+ int table_rows = 0;
+ int table_columns = 0;
+ int current_row = 0;
+ FILE * fileInp = 0;
+ FILE * fileOut = 0;
+
+ print_version_details(argv[0],FALSE);
+ process_args(argc,argv);
+ print_args(argc,argv);
+
+ if (!input_name ) {
+ fprintf(stderr,"Input name required, not supplied.\n");
+ print_usage_message(argv[0],usage);
+ exit(FAILED);
+ }
+ fileInp = fopen(input_name,"r");
+ if (!fileInp) {
+ fprintf(stderr,"Invalid input filename, could not open '%s'\n",
+ input_name);
+ print_usage_message(argv[0],usage);
+ exit(FAILED);
+ }
+
+
+ if (!output_name ) {
+ fprintf(stderr,"Output name required, not supplied.\n");
+ print_usage_message(argv[0],usage);
+ exit(FAILED);
+ }
+ fileOut = fopen(output_name,"w");
+ if (!fileOut) {
+ fprintf(stderr,"Invalid output filename, could not open: '%s'\n",
+ output_name);
+ print_usage_message(argv[0],usage);
+ exit(FAILED);
+ }
+ if ((standard_flag && extended_flag) ||
+ (!standard_flag && !extended_flag)) {
+ fprintf(stderr,"Invalid table type\n");
+ fprintf(stderr,"Choose -e or -s .\n");
+ print_usage_message(argv[0],usage);
+ exit(FAILED);
+ }
+
+
+ if(standard_flag) {
+ table_rows = STD_ATTR_TABLE_ROWS;
+ table_columns = STD_ATTR_TABLE_COLUMNS;
+ } else {
+ table_rows = EXT_ATTR_TABLE_ROWS;
+ table_columns = EXT_ATTR_TABLE_COLS;
+ }
+
+ input_eof = read_value(&num,fileInp); /* 0xffffffff */
+ if (IS_EOF == input_eof) {
+ bad_line_input("Empty input file");
+ }
+ if (num != MAGIC_TOKEN_VALUE) {
+ bad_line_input("Expected 0xffffffff");
+ }
+ while (!feof(stdin)) {
+ unsigned int tag;
+ int curcol = 0;
+
+ input_eof = read_value(&tag,fileInp);
+ if (IS_EOF == input_eof) {
+ /* Reached normal eof */
+ break;
+ }
+ if(standard_flag) {
+ if (tag >= table_rows ) {
+ bad_line_input("tag value exceeds standard table size");
+ }
+ } else {
+ if(current_row >= table_rows) {
+ bad_line_input("too many extended table rows.");
+ }
+ tag_attr_combination_table[current_row][0] = tag;
+ }
+
+ input_eof = read_value(&num,fileInp);
+ if (IS_EOF == input_eof) {
+ bad_line_input("Not terminated correctly..");
+ }
+ curcol = 1;
+ while (num != MAGIC_TOKEN_VALUE) {
+ if(standard_flag) {
+ unsigned idx = num / BITS_PER_WORD;
+ unsigned bit = num % BITS_PER_WORD;
+
+ if (idx >= table_columns) {
+ bad_line_input
+ ("too many attributes: table incomplete.");
+ }
+ tag_attr_combination_table[tag][idx] |= (1 << bit);
+ } else {
+ if (curcol >= table_columns) {
+ bad_line_input("too many attributes: table incomplete.");
+ }
+ tag_attr_combination_table[current_row][curcol] = num;
+ curcol++;
+
+ }
+ input_eof = read_value(&num,fileInp);
+ if (IS_EOF == input_eof) {
+ bad_line_input("Not terminated correctly.");
+ }
+ }
+ ++current_row;
+ }
+ fprintf(fileOut,"/* Generated code, do not edit. */\n");
+ fprintf(fileOut,"/* Generated on %s %s */\n",__DATE__,__TIME__);
+ fprintf(fileOut,"\n/* BEGIN FILE */\n\n");
+ if (standard_flag) {
+ fprintf(fileOut,"#define ATTR_TREE_ROW_COUNT %d\n\n",table_rows);
+ fprintf(fileOut,"#define ATTR_TREE_COLUMN_COUNT %d\n\n",table_columns);
+ fprintf(fileOut,
+ "static unsigned int tag_attr_combination_table"
+ "[ATTR_TREE_ROW_COUNT][ATTR_TREE_COLUMN_COUNT] = {\n");
+ }
+ else {
+ fprintf(fileOut,"/* Common extensions */\n");
+ fprintf(fileOut,"#define ATTR_TREE_EXT_ROW_COUNT %d\n\n",table_rows);
+ fprintf(fileOut,"#define ATTR_TREE_EXT_COLUMN_COUNT %d\n\n",
+ table_columns);
+ fprintf(fileOut,
+ "static unsigned int tag_attr_combination_ext_table"
+ "[ATTR_TREE_EXT_ROW_COUNT][ATTR_TREE_EXT_COLUMN_COUNT] = {\n");
+ }
+
+ for (i = 0; i < table_rows; i++) {
+ int j = 0;
+ const char *name = 0;
+ if(standard_flag) {
+ dwarf_get_TAG_name(i,&name);
+ fprintf(fileOut,"/* %d %-37s*/\n",i,name);
+ } else {
+ int k = tag_attr_combination_table[i][0];
+ dwarf_get_TAG_name(k,&name);
+ fprintf(fileOut,"/* %u %-37s*/\n",k,name);
+ }
+ fprintf(fileOut," { ");
+ for(j = 0; j < table_columns; ++j ) {
+ fprintf(fileOut,"0x%08x,",tag_attr_combination_table[i][j]);
+ }
+ fprintf(fileOut,"},\n");
+ }
+ fprintf(fileOut,"};\n");
+ fprintf(fileOut,"\n/* END FILE */\n");
+ fclose(fileInp);
+ fclose(fileOut);
+ return (0);
+}
+/* A fake so we can use dwarf_names.c */
+void print_error (Dwarf_Debug dbg, string msg,int res, Dwarf_Error err)
+{
+}
+
diff --git a/dwarfdump/tag_attr.list b/dwarfdump/tag_attr.list
new file mode 100644
index 0000000..813ae18
--- /dev/null
+++ b/dwarfdump/tag_attr.list
@@ -0,0 +1,880 @@
+/*
+ Copyright (C) 2000-2010 Silicon Graphics, Inc. All Rights Reserved.
+ Portions Copyright (C) 2009-2011 David Anderson. All Rights Reserved.
+
+ This program is free software; you can redistribute it and/or modify it
+ under the terms of version 2.1 of the GNU Lesser General Public License
+ as published by the Free Software Foundation.
+
+ This program is distributed in the hope that it would be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+ Further, this software is distributed without any warranty that it is
+ free of the rightful claim of any third person regarding infringement
+ or the like. Any license provided herein, whether implied or
+ otherwise, applies only to this software file. Patent licenses, if
+ any, provided herein do not apply to combinations of this program with
+ other software, or any other product whatsoever.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this program; if not, write the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307,
+ USA.
+
+ Contact information: Silicon Graphics, Inc., 1500 Crittenden Lane,
+ Mountain View, CA 94043, or:
+
+ http://www.sgi.com
+
+ For further information regarding this notice, see:
+
+ http://oss.sgi.com/projects/GenInfo/NoticeExplan
+
+
+ $Header: /plroot/cmplrs.src/v7.4.5m/.RCS/PL/dwarfdump/RCS/tag_attr.list,v 1.7 2005/12/01 17:34:59 davea Exp $
+*/
+#include <dwarf.h>
+
+/*
+ list for semantic check of tag-attr relation.
+
+ 0xffffffff is a "punctuation." The final line of this file
+ must be 0xffffffff. The next line after each 0xffffffff
+ (except the final line) is a tag. The lines after this line
+ before the next 0xffffffff are the attributes that can be given
+ to the tag."
+
+ For example,
+
+ 0xffffffff
+ DW_TAG_access_declaration
+ DW_AT_decl_column
+ DW_AT_decl_file
+ DW_AT_decl_line
+ DW_AT_accessibility
+ DW_AT_name
+ DW_AT_sibling
+ 0xffffffff
+
+ means "only DW_AT_decl_column, DW_AT_decl_file, DW_AT_decl_line,
+ DW_AT_accessibility, DW_AT_name and DW_AT_sibling can be given to
+ DW_TAG_access_declaration."
+
+ This file is applied to the preprocessor, thus any C comment and
+ preprocessor control line is available.
+*/
+
+0xffffffff
+DW_TAG_access_declaration
+DW_AT_decl_column
+DW_AT_decl_file
+DW_AT_decl_line
+DW_AT_accessibility
+DW_AT_name
+DW_AT_sibling
+0xffffffff
+DW_TAG_array_type
+DW_AT_decl_column
+DW_AT_decl_file
+DW_AT_decl_line
+DW_AT_abstract_origin
+DW_AT_accessibility
+DW_AT_allocated
+DW_AT_associated
+DW_AT_bit_stride
+DW_AT_byte_size
+DW_AT_bit_size /* Allowed in DWARF4 */
+DW_AT_data_location
+DW_AT_declaration
+DW_AT_description
+DW_AT_name
+DW_AT_ordering
+DW_AT_sibling
+DW_AT_specification
+DW_AT_start_scope
+DW_AT_type
+DW_AT_visibility
+0xffffffff
+DW_TAG_base_type
+DW_AT_allocated
+DW_AT_associated
+DW_AT_binary_scale
+DW_AT_bit_offset
+DW_AT_bit_size
+DW_AT_byte_size
+DW_AT_bit_size /* Allowed in DWARF4 */
+DW_AT_data_bit_offset
+DW_AT_data_location
+DW_AT_decimal_scale
+DW_AT_decimal_sign
+DW_AT_description
+DW_AT_digit_count
+DW_AT_encoding
+DW_AT_endianity
+DW_AT_name
+DW_AT_name
+DW_AT_picture_string
+DW_AT_sibling
+DW_AT_small
+0xffffffff
+DW_TAG_catch_block
+DW_AT_abstract_origin
+DW_AT_high_pc
+DW_AT_low_pc
+DW_AT_ranges
+DW_AT_segment
+DW_AT_sibling
+0xffffffff
+DW_TAG_class_type
+DW_AT_decl_column
+DW_AT_decl_file
+DW_AT_decl_line
+DW_AT_abstract_origin
+DW_AT_accessibility
+DW_AT_allocated
+DW_AT_associated
+DW_AT_byte_size
+DW_AT_bit_size /* Allowed in DWARF4 */
+DW_AT_data_location
+DW_AT_declaration
+DW_AT_description
+DW_AT_name
+DW_AT_sibling
+DW_AT_signature
+DW_AT_specification
+DW_AT_start_scope
+DW_AT_visibility
+0xffffffff
+DW_TAG_common_block
+DW_AT_decl_column
+DW_AT_decl_file
+DW_AT_decl_line
+DW_AT_declaration
+DW_AT_location
+DW_AT_name
+DW_AT_segment
+DW_AT_sibling
+DW_AT_visibility
+0xffffffff
+DW_TAG_common_inclusion
+DW_AT_decl_column
+DW_AT_decl_file
+DW_AT_decl_line
+DW_AT_common_reference
+DW_AT_declaration
+DW_AT_sibling
+DW_AT_visibility
+0xffffffff
+DW_TAG_compile_unit
+DW_AT_base_types
+DW_AT_comp_dir
+DW_AT_identifier_case
+DW_AT_high_pc
+DW_AT_language
+DW_AT_low_pc
+DW_AT_macro_info
+DW_AT_main_subprogram
+DW_AT_name
+DW_AT_producer
+DW_AT_ranges
+DW_AT_segment
+DW_AT_sibling
+DW_AT_stmt_list
+DW_AT_use_UTF8
+DW_AT_entry_pc
+0xffffffff
+DW_TAG_condition
+DW_AT_decl_column
+DW_AT_decl_file
+DW_AT_decl_line
+DW_AT_name
+DW_AT_sibling
+0xffffffff
+DW_TAG_const_type
+DW_AT_allocated
+DW_AT_associated
+DW_AT_data_location
+DW_AT_name
+DW_AT_sibling
+DW_AT_type
+0xffffffff
+DW_TAG_constant
+DW_AT_decl_column
+DW_AT_decl_file
+DW_AT_decl_line
+DW_AT_accessibility
+DW_AT_const_value
+DW_AT_declaration
+DW_AT_description
+DW_AT_endianity
+DW_AT_external
+DW_AT_linkage_name
+DW_AT_name
+DW_AT_sibling
+DW_AT_start_scope
+DW_AT_type
+DW_AT_visibility
+0xffffffff
+DW_TAG_dwarf_procedure
+DW_AT_location
+0xffffffff
+DW_TAG_entry_point
+DW_AT_address_class
+DW_AT_description
+DW_AT_linkage_name
+DW_AT_low_pc
+DW_AT_name
+DW_AT_return_addr
+DW_AT_segment
+DW_AT_sibling
+DW_AT_static_link
+DW_AT_type
+0xffffffff
+DW_TAG_enumeration_type
+DW_AT_decl_column
+DW_AT_decl_file
+DW_AT_decl_line
+DW_AT_abstract_origin
+DW_AT_accessibility
+DW_AT_allocated
+DW_AT_associated
+DW_AT_bit_stride
+DW_AT_byte_size
+DW_AT_bit_size /* Allowed in DWARF4 */
+DW_AT_byte_stride
+DW_AT_data_location
+DW_AT_declaration
+DW_AT_description
+DW_AT_enum_class
+DW_AT_name
+DW_AT_sibling
+DW_AT_signature
+DW_AT_specification
+DW_AT_start_scope
+DW_AT_type
+DW_AT_visibility
+0xffffffff
+DW_TAG_enumerator
+DW_AT_decl_column
+DW_AT_decl_file
+DW_AT_decl_line
+DW_AT_const_value
+DW_AT_description
+DW_AT_name
+DW_AT_sibling
+0xffffffff
+DW_TAG_file_type
+DW_AT_decl_column
+DW_AT_decl_file
+DW_AT_decl_line
+DW_AT_abstract_origin
+DW_AT_allocated
+DW_AT_associated
+DW_AT_byte_size
+DW_AT_bit_size /* Allowed in DWARF4 */
+DW_AT_data_location
+DW_AT_description
+DW_AT_name
+DW_AT_sibling
+DW_AT_start_scope
+DW_AT_type
+DW_AT_visibility
+0xffffffff
+DW_TAG_formal_parameter
+DW_AT_decl_column
+DW_AT_decl_file
+DW_AT_decl_line
+DW_AT_abstract_origin
+DW_AT_artificial
+DW_AT_const_value
+DW_AT_default_value
+DW_AT_description
+DW_AT_endianity
+DW_AT_is_optional
+DW_AT_location
+DW_AT_name
+DW_AT_segment
+DW_AT_sibling
+DW_AT_type
+DW_AT_variable_parameter
+0xffffffff
+DW_TAG_friend
+DW_AT_decl_column
+DW_AT_decl_file
+DW_AT_decl_line
+DW_AT_abstract_origin
+DW_AT_friend
+DW_AT_sibling
+0xffffffff
+DW_TAG_imported_declaration
+DW_AT_decl_column
+DW_AT_decl_file
+DW_AT_decl_line
+DW_AT_accessibility
+DW_AT_description
+DW_AT_import
+DW_AT_name
+DW_AT_sibling
+DW_AT_start_scope
+0xffffffff
+DW_TAG_imported_module
+DW_AT_decl_column
+DW_AT_decl_file
+DW_AT_decl_line
+DW_AT_import
+DW_AT_sibling
+DW_AT_start_scope
+0xffffffff
+DW_TAG_imported_unit
+DW_AT_import
+0xffffffff
+DW_TAG_inheritance
+DW_AT_decl_column
+DW_AT_decl_file
+DW_AT_decl_line
+DW_AT_accessibility
+DW_AT_data_member_location
+DW_AT_sibling
+DW_AT_type
+DW_AT_virtuality
+0xffffffff
+DW_TAG_inlined_subroutine
+DW_AT_abstract_origin
+DW_AT_call_column
+DW_AT_call_file
+DW_AT_call_line
+DW_AT_const_expr
+DW_AT_entry_pc
+DW_AT_high_pc
+DW_AT_low_pc
+DW_AT_ranges
+DW_AT_return_addr
+DW_AT_segment
+DW_AT_sibling
+DW_AT_start_scope
+DW_AT_trampoline
+0xffffffff
+DW_TAG_interface_type
+DW_AT_decl_column
+DW_AT_decl_file
+DW_AT_decl_line
+DW_AT_accessibility
+DW_AT_description
+DW_AT_name
+DW_AT_sibling
+DW_AT_start_scope
+0xffffffff
+DW_TAG_label
+DW_AT_decl_column
+DW_AT_decl_file
+DW_AT_decl_line
+DW_AT_abstract_origin
+DW_AT_description
+DW_AT_low_pc
+DW_AT_name
+DW_AT_segment
+DW_AT_start_scope
+DW_AT_sibling
+0xffffffff
+DW_TAG_lexical_block
+DW_AT_abstract_origin
+DW_AT_description
+DW_AT_high_pc
+DW_AT_low_pc
+DW_AT_name
+DW_AT_ranges
+DW_AT_segment
+DW_AT_sibling
+0xffffffff
+DW_TAG_member
+DW_AT_decl_column
+DW_AT_decl_file
+DW_AT_decl_line
+DW_AT_accessibility
+DW_AT_bit_offset
+DW_AT_bit_size
+DW_AT_byte_size
+DW_AT_bit_size /* Allowed in DWARF4 */
+DW_AT_data_bit_offset
+DW_AT_data_member_location
+DW_AT_declaration
+DW_AT_description
+DW_AT_mutable
+DW_AT_name
+DW_AT_sibling
+DW_AT_type
+DW_AT_visibility
+DW_AT_artificial
+0xffffffff
+DW_TAG_module
+DW_AT_decl_column
+DW_AT_decl_file
+DW_AT_decl_line
+DW_AT_accessibility
+DW_AT_declaration
+DW_AT_description
+DW_AT_entry_pc
+DW_AT_high_pc
+DW_AT_low_pc
+DW_AT_name
+DW_AT_priority
+DW_AT_segment
+DW_AT_sibling
+DW_AT_specification
+DW_AT_visibility
+0xffffffff
+DW_TAG_namelist
+DW_AT_decl_column
+DW_AT_decl_file
+DW_AT_decl_line
+DW_AT_accessibility
+DW_AT_abstract_origin
+DW_AT_declaration
+DW_AT_name
+DW_AT_sibling
+DW_AT_visibility
+0xffffffff
+DW_TAG_namelist_item
+DW_AT_decl_column
+DW_AT_decl_file
+DW_AT_decl_line
+DW_AT_namelist_item
+DW_AT_sibling
+0xffffffff
+DW_TAG_namespace
+DW_AT_decl_column
+DW_AT_decl_file
+DW_AT_decl_line
+DW_AT_description
+DW_AT_extension
+DW_AT_name
+DW_AT_sibling
+DW_AT_start_scope
+0xffffffff
+DW_TAG_packed_type
+DW_AT_allocated
+DW_AT_associated
+DW_AT_data_location
+DW_AT_name
+DW_AT_sibling
+DW_AT_type
+0xffffffff
+DW_TAG_partial_unit
+DW_AT_base_types
+DW_AT_comp_dir
+DW_AT_description
+DW_AT_identifier_case
+DW_AT_high_pc
+DW_AT_language
+DW_AT_low_pc
+DW_AT_macro_info
+DW_AT_main_subprogram
+DW_AT_name
+DW_AT_producer
+DW_AT_ranges
+DW_AT_segment
+DW_AT_sibling
+DW_AT_stmt_list
+DW_AT_use_UTF8
+0xffffffff
+DW_TAG_pointer_type
+DW_AT_address_class
+DW_AT_allocated
+DW_AT_associated
+DW_AT_data_location
+DW_AT_name
+DW_AT_sibling
+DW_AT_specification
+DW_AT_type
+/* Comment from 1993:
+ "Though DWARF spec doesn't refer to DW_AT_byte_size, it may well be
+ given to DW_TAG_pointer_type."
+ Comment 31 January 2009:
+ Discussed in the dwarf-workgroup mailing list Jan 5 2009, that
+ DW_AT_byte_size is allowed.
+*/
+DW_AT_byte_size
+DW_AT_bit_size /* Allowed in DWARF4 (if DW_AT_byte_size allowed) */
+0xffffffff
+DW_TAG_ptr_to_member_type
+DW_AT_decl_column
+DW_AT_decl_file
+DW_AT_decl_line
+DW_AT_abstract_origin
+DW_AT_address_class
+DW_AT_allocated
+DW_AT_associated
+DW_AT_containing_type
+DW_AT_data_location
+DW_AT_declaration
+DW_AT_description
+DW_AT_name
+DW_AT_sibling
+DW_AT_type
+DW_AT_use_location
+DW_AT_visibility
+0xffffffff
+DW_TAG_rvalue_reference_type
+DW_AT_address_class
+DW_AT_allocated
+DW_AT_associated
+DW_AT_data_location
+DW_AT_name
+DW_AT_sibling
+DW_AT_type
+0xffffffff
+DW_TAG_reference_type
+DW_AT_address_class
+DW_AT_allocated
+DW_AT_associated
+DW_AT_data_location
+DW_AT_name
+DW_AT_sibling
+DW_AT_type
+/* Comment from 1993:
+ "Though DWARF spec doesn't refer to DW_AT_byte_size, it may well be
+ given to DW_TAG_pointer_type."
+ Comment 31 January 2009:
+ Discussed in the dwarf-workgroup mailing list Jan 5 2009, that
+ DW_AT_byte_size is allowed.
+*/
+DW_AT_byte_size
+DW_AT_bit_size /* Allowed in DWARF4 */
+0xffffffff
+DW_TAG_template_alias
+DW_AT_abstract_origin
+DW_AT_accessibility
+DW_AT_allocated
+DW_AT_associated
+DW_AT_data_location
+DW_AT_declaration
+DW_AT_description
+DW_AT_name
+DW_AT_sibling
+DW_AT_signature
+DW_AT_start_scope
+DW_AT_type
+DW_AT_visibility
+0xffffffff
+DW_TAG_restrict_type
+DW_AT_allocated
+DW_AT_associated
+DW_AT_data_location
+DW_AT_name
+DW_AT_sibling
+DW_AT_type
+0xffffffff
+DW_TAG_set_type
+DW_AT_decl_column
+DW_AT_decl_file
+DW_AT_decl_line
+DW_AT_abstract_origin
+DW_AT_accessibility
+DW_AT_allocated
+DW_AT_associated
+DW_AT_byte_size
+DW_AT_bit_size /* Allowed in DWARF4 */
+DW_AT_data_location
+DW_AT_declaration
+DW_AT_description
+DW_AT_name
+DW_AT_start_scope
+DW_AT_sibling
+DW_AT_type
+DW_AT_visibility
+0xffffffff
+DW_TAG_shared_type
+DW_AT_decl_column
+DW_AT_decl_file
+DW_AT_decl_line
+DW_AT_count
+DW_AT_name
+DW_AT_sibling
+DW_AT_type
+0xffffffff
+DW_TAG_string_type
+DW_AT_decl_column
+DW_AT_decl_file
+DW_AT_decl_line
+DW_AT_abstract_origin
+DW_AT_accessibility
+DW_AT_allocated
+DW_AT_associated
+DW_AT_byte_size
+DW_AT_bit_size /* Allowed in DWARF4 */
+DW_AT_data_location
+DW_AT_declaration
+DW_AT_description
+DW_AT_name
+DW_AT_segment
+DW_AT_sibling
+DW_AT_start_scope
+DW_AT_string_length
+DW_AT_visibility
+0xffffffff
+DW_TAG_structure_type
+DW_AT_decl_column
+DW_AT_decl_file
+DW_AT_decl_line
+DW_AT_abstract_origin
+DW_AT_accessibility
+DW_AT_allocated
+DW_AT_associated
+DW_AT_byte_size
+DW_AT_bit_size /* Allowed in DWARF4 */
+DW_AT_containing_type
+DW_AT_data_location
+DW_AT_declaration
+DW_AT_description
+DW_AT_name
+DW_AT_sibling
+DW_AT_signature
+DW_AT_specification
+DW_AT_start_scope
+DW_AT_visibility
+0xffffffff
+DW_TAG_subprogram
+DW_AT_decl_column
+DW_AT_decl_file
+DW_AT_decl_line
+DW_AT_abstract_origin
+DW_AT_accessibility
+DW_AT_address_class
+DW_AT_artificial
+DW_AT_calling_convention
+DW_AT_containing_type
+DW_AT_declaration
+DW_AT_description
+DW_AT_elemental
+DW_AT_entry_pc
+DW_AT_explicit
+DW_AT_external
+DW_AT_frame_base
+DW_AT_high_pc
+DW_AT_inline
+DW_AT_linkage_name
+DW_AT_low_pc
+DW_AT_main_subprogram
+DW_AT_name
+DW_AT_object_pointer
+DW_AT_prototyped
+DW_AT_pure
+DW_AT_ranges
+DW_AT_recursive
+DW_AT_return_addr
+DW_AT_segment
+DW_AT_sibling
+DW_AT_specification
+DW_AT_start_scope
+DW_AT_static_link
+DW_AT_trampoline
+DW_AT_type
+DW_AT_visibility
+DW_AT_virtuality
+DW_AT_vtable_elem_location
+0xffffffff
+DW_TAG_subrange_type
+DW_AT_decl_column
+DW_AT_decl_file
+DW_AT_decl_line
+DW_AT_abstract_origin
+DW_AT_accessibility
+DW_AT_allocated
+DW_AT_associated
+DW_AT_bit_stride
+DW_AT_byte_size
+DW_AT_bit_size /* Allowed in DWARF4 */
+DW_AT_byte_stride
+DW_AT_count
+DW_AT_data_location
+DW_AT_declaration
+DW_AT_description
+DW_AT_lower_bound
+DW_AT_name
+DW_AT_sibling
+DW_AT_threads_scaled
+DW_AT_type
+DW_AT_upper_bound
+DW_AT_visibility
+0xffffffff
+DW_TAG_subroutine_type
+DW_AT_decl_column
+DW_AT_decl_file
+DW_AT_decl_line
+DW_AT_abstract_origin
+DW_AT_accessibility
+DW_AT_address_class
+DW_AT_allocated
+DW_AT_associated
+DW_AT_data_location
+DW_AT_declaration
+DW_AT_description
+DW_AT_name
+DW_AT_prototyped
+DW_AT_sibling
+DW_AT_start_scope
+DW_AT_type
+DW_AT_visibility
+0xffffffff
+DW_TAG_template_type_parameter
+DW_AT_decl_column
+DW_AT_decl_file
+DW_AT_decl_line
+DW_AT_description
+DW_AT_name
+DW_AT_sibling
+DW_AT_type
+0xffffffff
+DW_TAG_template_value_parameter
+DW_AT_decl_column
+DW_AT_decl_file
+DW_AT_decl_line
+DW_AT_const_value
+DW_AT_description
+DW_AT_name
+DW_AT_sibling
+DW_AT_type
+0xffffffff
+DW_TAG_thrown_type
+DW_AT_decl_column
+DW_AT_decl_file
+DW_AT_decl_line
+DW_AT_allocated
+DW_AT_associated
+DW_AT_data_location
+DW_AT_sibling
+DW_AT_type
+0xffffffff
+DW_TAG_try_block
+DW_AT_abstract_origin
+DW_AT_high_pc
+DW_AT_low_pc
+DW_AT_ranges
+DW_AT_segment
+DW_AT_sibling
+0xffffffff
+DW_TAG_typedef
+DW_AT_decl_column
+DW_AT_decl_file
+DW_AT_decl_line
+DW_AT_abstract_origin
+DW_AT_accessibility
+DW_AT_allocated
+DW_AT_associated
+DW_AT_data_location
+DW_AT_declaration
+DW_AT_description
+DW_AT_name
+DW_AT_sibling
+DW_AT_start_scope
+DW_AT_type
+DW_AT_visibility
+0xffffffff
+DW_TAG_union_type
+DW_AT_decl_column
+DW_AT_decl_file
+DW_AT_decl_line
+DW_AT_abstract_origin
+DW_AT_accessibility
+DW_AT_allocated
+DW_AT_associated
+DW_AT_byte_size
+DW_AT_bit_size /* Allowed in DWARF4 */
+DW_AT_data_location
+DW_AT_declaration
+DW_AT_description
+DW_AT_name
+DW_AT_sibling
+DW_AT_signature
+DW_AT_specification
+DW_AT_start_scope
+DW_AT_visibility
+0xffffffff
+DW_TAG_unspecified_parameters
+DW_AT_decl_column
+DW_AT_decl_file
+DW_AT_decl_line
+DW_AT_abstract_origin
+DW_AT_artificial
+DW_AT_sibling
+0xffffffff
+DW_TAG_unspecified_type
+DW_AT_decl_column
+DW_AT_decl_file
+DW_AT_decl_line
+DW_AT_description
+DW_AT_sibling
+0xffffffff
+DW_TAG_variable
+DW_AT_decl_column
+DW_AT_decl_file
+DW_AT_decl_line
+DW_AT_abstract_origin
+DW_AT_accessibility
+DW_AT_byte_size
+DW_AT_bit_size /* Allowed in DWARF4 */
+DW_AT_const_expr
+DW_AT_const_value
+DW_AT_declaration
+DW_AT_description
+DW_AT_endianity
+DW_AT_external
+DW_AT_linkage_name
+DW_AT_location
+DW_AT_name
+DW_AT_segment
+DW_AT_sibling
+DW_AT_specification
+DW_AT_start_scope
+DW_AT_type
+DW_AT_visibility
+DW_AT_artificial
+0xffffffff
+DW_TAG_variant
+DW_AT_decl_column
+DW_AT_decl_file
+DW_AT_decl_line
+DW_AT_accessibility
+DW_AT_abstract_origin
+DW_AT_declaration
+DW_AT_discr_list
+DW_AT_discr_value
+DW_AT_sibling
+0xffffffff
+DW_TAG_variant_part
+DW_AT_decl_column
+DW_AT_decl_file
+DW_AT_decl_line
+DW_AT_accessibility
+DW_AT_abstract_origin
+DW_AT_declaration
+DW_AT_discr
+DW_AT_sibling
+DW_AT_type
+0xffffffff
+DW_TAG_volatile_type
+DW_AT_allocated
+DW_AT_associated
+DW_AT_data_location
+DW_AT_name
+DW_AT_sibling
+DW_AT_type
+0xffffffff
+DW_TAG_with_stmt
+DW_AT_accessibility
+DW_AT_address_class
+DW_AT_declaration
+DW_AT_high_pc
+DW_AT_location
+DW_AT_low_pc
+DW_AT_ranges
+DW_AT_segment
+DW_AT_sibling
+DW_AT_type
+DW_AT_visibility
+0xffffffff
+DW_TAG_type_unit
+DW_AT_language
+0xffffffff
+
diff --git a/dwarfdump/tag_attr_ext.list b/dwarfdump/tag_attr_ext.list
new file mode 100644
index 0000000..ce6d8b0
--- /dev/null
+++ b/dwarfdump/tag_attr_ext.list
@@ -0,0 +1,78 @@
+/*
+ Copyright (C) 2000-2010 Silicon Graphics, Inc. All Rights Reserved.
+ Portions Copyright (C) 2008-2010 SN Systems Ltd. All Rights Reserved.
+ Portions Copyright (C) 2009-2011 David Anderson. All Rights Reserved.
+
+ This program is free software; you can redistribute it and/or modify it
+ under the terms of version 2.1 of the GNU Lesser General Public License
+ as published by the Free Software Foundation.
+
+ This program is distributed in the hope that it would be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+ Further, this software is distributed without any warranty that it is
+ free of the rightful claim of any third person regarding infringement
+ or the like. Any license provided herein, whether implied or
+ otherwise, applies only to this software file. Patent licenses, if
+ any, provided herein do not apply to combinations of this program with
+ other software, or any other product whatsoever.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this program; if not, write the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307,
+ USA.
+
+ Contact information: Silicon Graphics, Inc., 1500 Crittenden Lane,
+ Mountain View, CA 94043, or:
+
+ http://www.sgi.com
+
+ For further information regarding this notice, see:
+
+ http://oss.sgi.com/projects/GenInfo/NoticeExplan
+
+
+ $Header: /plroot/cmplrs.src/v7.4.5m/.RCS/PL/dwarfdump/RCS/tag_attr.list,v 1.7 2005/12/01 17:34:59 davea Exp $
+*/
+#include <dwarf.h>
+
+/* list for semantic check of tag-attr relation.
+ See tag_attr.list for details.
+*/
+
+/* Common DWARF extensions */
+
+0xffffffff
+DW_TAG_member
+DW_AT_GNU_guarded_by /* gcc.gnu.org/wiki/ThreadSafetyAnnotationsInDWARF */
+DW_AT_GNU_pt_guarded_by /* gcc.gnu.org/wiki/ThreadSafetyAnnotationsInDWARF */
+DW_AT_GNU_guarded /* gcc.gnu.org/wiki/ThreadSafetyAnnotationsInDWARF */
+DW_AT_GNU_pt_guarded /* gcc.gnu.org/wiki/ThreadSafetyAnnotationsInDWARF */
+0xffffffff
+DW_TAG_array_type
+DW_AT_GNU_vector
+0xffffffff
+DW_TAG_subprogram
+DW_AT_MIPS_linkage_name /* Used by GNU, SGI-IRIX, and others. */
+DW_AT_MIPS_fde /* SGI-IRIX uses this */
+DW_AT_GNU_locks_excluded /* gcc.gnu.org/wiki/ThreadSafetyAnnotationsInDWARF */
+DW_AT_GNU_exclusive_locks_required
+DW_AT_GNU_shared_locks_required
+0xffffffff
+DW_TAG_variable
+DW_AT_MIPS_linkage_name /* Used by GNU, SGI-IRIX, and others. */
+DW_AT_GNU_guarded_by
+DW_AT_GNU_pt_guarded_by
+DW_AT_GNU_guarded
+DW_AT_GNU_pt_guarded
+0xffffffff
+DW_TAG_GNU_template_template_parameter
+DW_AT_decl_column
+DW_AT_decl_file
+DW_AT_decl_line
+DW_AT_name
+DW_AT_GNU_template_name
+DW_AT_GNU_guarded_by /* GNU changed the name of 0x2108! */
+0xffffffff
+
diff --git a/dwarfdump/tag_common.c b/dwarfdump/tag_common.c
new file mode 100644
index 0000000..28b2d2c
--- /dev/null
+++ b/dwarfdump/tag_common.c
@@ -0,0 +1,145 @@
+/*
+ Copyright (C) 2000-2005 Silicon Graphics, Inc. All Rights Reserved.
+ Portions Copyright (C) 2009-2010 SN Systems Ltd. All Rights Reserved.
+ Portions Copyright (C) 2009-2011 David Anderson. All Rights Reserved.
+
+ This program is free software; you can redistribute it and/or modify it
+ under the terms of version 2 of the GNU General Public License as
+ published by the Free Software Foundation.
+
+ This program is distributed in the hope that it would be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+ Further, this software is distributed without any warranty that it is
+ free of the rightful claim of any third person regarding infringement
+ or the like. Any license provided herein, whether implied or
+ otherwise, applies only to this software file. Patent licenses, if
+ any, provided herein do not apply to combinations of this program with
+ other software, or any other product whatsoever.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write the Free Software Foundation, Inc., 51
+ Franklin Street - Fifth Floor, Boston MA 02110-1301, USA.
+
+ Contact information: Silicon Graphics, Inc., 1500 Crittenden Lane,
+ Mountain View, CA 94043, or:
+
+ http://www.sgi.com
+
+ For further information regarding this notice, see:
+
+ http://oss.sgi.com/projects/GenInfo/NoticeExplan
+
+$Header: /plroot/cmplrs.src/v7.4.5m/.RCS/PL/dwarfdump/RCS/tag_common.c,v 1.8 2008/01/23 09:47:59 davea Exp $ */
+
+#include <dwarf.h>
+#include <stdio.h>
+#include <stdlib.h>/* For exit() declaration etc. */
+#include <errno.h>/* For errno declaration. */
+#include <ctype.h> /* For isspace() declaration */
+
+#include "globals.h"
+#include "naming.h"
+#include "tag_common.h"
+
+static int linecount = 0;
+static char line_in[MAX_LINE_SIZE];
+
+void
+bad_line_input(char *msg)
+{
+ fprintf(stderr,
+ "tag_(tree,attr) table build failed %s, line %d: \"%s\" \n",
+ msg, linecount, line_in);
+ exit(FAILED);
+}
+
+void
+trim_newline(char *line, int max)
+{
+ char *end = line + max - 1;
+
+ for (; *line && (line < end); ++line) {
+ if (*line == '\n') {
+ /* Found newline, drop it */
+ *line = 0;
+ return;
+ }
+ }
+ return;
+}
+
+/* Detect empty lines (and other lines we do not want to read) */
+boolean
+is_skippable_line(char *pLine)
+{
+ boolean empty = TRUE;
+
+ if(pLine[0] == '#') {
+ /* Preprocessor lines are of no interest. */
+ return TRUE;
+ }
+ for (; *pLine && empty; ++pLine) {
+ empty = isspace(*pLine);
+ }
+ return empty;
+}
+
+/* Reads a value from the text table.
+ Exits with non-zero status
+ if the table is erroneous in some way.
+*/
+int
+read_value(unsigned int *outval, FILE*file)
+{
+ char *res = 0;
+ unsigned long lval;
+ char *strout = 0;
+ boolean bBlankLine = TRUE;
+
+ ++linecount;
+ *outval = 0;
+
+ while (bBlankLine) {
+ res = fgets(line_in, sizeof(line_in), file);
+ if (res == 0) {
+ if (ferror(file)) {
+ fprintf(stderr,
+ "tag_attr: Error reading table, %d lines read\n",
+ linecount);
+ exit(FAILED);
+ }
+
+ if (feof(file)) {
+ return IS_EOF;
+ }
+
+ /* Impossible */
+ fprintf(stderr, "tag_attr: Impossible error reading table, "
+ "%d lines read\n", linecount);
+ exit(FAILED);
+ }
+
+ bBlankLine = is_skippable_line(line_in);
+ }
+
+ trim_newline(line_in, sizeof(line_in));
+ errno = 0;
+ lval = strtoul(line_in, &strout, 0);
+
+ if (strout == line_in) {
+ bad_line_input("bad number input!");
+ }
+
+ if (errno != 0) {
+ int myerr = errno;
+
+ fprintf(stderr, "tag_attr errno %d\n", myerr);
+ bad_line_input("invalid number on line");
+ }
+
+ *outval = (int) lval;
+
+ return NOT_EOF;
+}
diff --git a/dwarfdump/tag_common.h b/dwarfdump/tag_common.h
new file mode 100644
index 0000000..f06d9bd
--- /dev/null
+++ b/dwarfdump/tag_common.h
@@ -0,0 +1,123 @@
+/*
+ Copyright (C) 2000-2010 Silicon Graphics, Inc. All Rights Reserved.
+ Portions Copyright (C) 2009-2010 SN Systems Ltd. All Rights Reserved.
+ Portions Copyright (C) 2009-2011 David Anderson. All Rights Reserved.
+
+ This program is free software; you can redistribute it and/or modify it
+ under the terms of version 2 of the GNU General Public License as
+ published by the Free Software Foundation.
+
+ This program is distributed in the hope that it would be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+ Further, this software is distributed without any warranty that it is
+ free of the rightful claim of any third person regarding infringement
+ or the like. Any license provided herein, whether implied or
+ otherwise, applies only to this software file. Patent licenses, if
+ any, provided herein do not apply to combinations of this program with
+ other software, or any other product whatsoever.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write the Free Software Foundation, Inc., 51
+ Franklin Street - Fifth Floor, Boston MA 02110-1301, USA.
+
+ Contact information: Silicon Graphics, Inc., 1500 Crittenden Lane,
+ Mountain View, CA 94043, or:
+
+ http://www.sgi.com
+
+ For further information regarding this notice, see:
+
+ http://oss.sgi.com/projects/GenInfo/NoticeExplan
+
+$Header: /plroot/cmplrs.src/v7.4.5m/.RCS/PL/dwarfdump/RCS/tag_common.h,v 1.8 2008/01/23 09:47:59 davea Exp $ */
+
+#ifndef tag_common_INCLUDED
+#define tag_common_INCLUDED
+
+
+
+/* The following is the magic token used to
+ distinguish real tags/attrs from group-delimiters.
+ Blank lines have been eliminated by an awk script.
+*/
+#define MAGIC_TOKEN_VALUE 0xffffffff
+
+/* TAG_TREE.LIST Expected input format
+
+0xffffffff
+value of a tag
+value of a standard tag that may be a child of that tag
+...
+0xffffffff
+value of a tag
+value of a standard tag that may be a child of that tag
+...
+0xffffffff
+...
+
+No blank lines or commentary allowed, no symbols, just numbers.
+
+*/
+
+/* TAG_ATTR.LIST Expected input format
+
+0xffffffff
+value of a tag
+value of a standard attribute that follows that tag
+...
+0xffffffff
+value of a tag
+value of a standard attribute that follows that tag
+...
+0xffffffff
+...
+
+No blank lines or commentary allowed, no symbols, just numbers.
+
+*/
+
+/* We don't need really long lines: the input file is simple. */
+#define MAX_LINE_SIZE 1000
+
+/* 1 more than the highest number in the DW_TAG defines,
+ this is for standard TAGs. Number of rows. */
+#define STD_TAG_TABLE_ROWS 0x44
+/* Enough entries to have a bit for each standard legal tag. */
+#define STD_TAG_TABLE_COLUMNS 7
+
+/* TAG tree common extension maximums. */
+#define EXT_TAG_TABLE_ROWS 7
+#define EXT_TAG_TABLE_COLS 7
+
+/* The following 2 used in tag_tree.c only. */
+#define TAG_TABLE_ROW_MAXIMUM STD_TAG_TABLE_ROWS
+#define TAG_TABLE_COLUMN_MAXIMUM EXT_TAG_TABLE_COLS
+
+/* Number of attributes columns per tag. The array is bit fields,
+ BITS_PER_WORD fields per word. Dense and quick to inspect */
+#define COUNT_ATTRIBUTE_STD 7
+
+#define STD_ATTR_TABLE_ROWS STD_TAG_TABLE_ROWS
+#define STD_ATTR_TABLE_COLUMNS 7
+/* tag/attr tree common extension maximums. */
+#define EXT_ATTR_TABLE_ROWS 7
+#define EXT_ATTR_TABLE_COLS 7
+
+/* The following 2 used in tag_attr.c only. */
+#define ATTR_TABLE_ROW_MAXIMUM STD_ATTR_TABLE_ROWS
+#define ATTR_TABLE_COLUMN_MAXIMUM EXT_ATTR_TABLE_COLS
+
+/* Bits per 'int' to mark legal attrs. */
+#define BITS_PER_WORD 32
+
+#define IS_EOF 1
+#define NOT_EOF 0
+
+extern void bad_line_input(char *msg);
+extern void trim_newline(char *line, int max);
+extern boolean is_blank_line(char *pLine);
+extern int read_value(unsigned int *outval,FILE *f);
+
+#endif /* tag_common_INCLUDED */
diff --git a/dwarfdump/tag_tree.c b/dwarfdump/tag_tree.c
new file mode 100644
index 0000000..b508d06
--- /dev/null
+++ b/dwarfdump/tag_tree.c
@@ -0,0 +1,290 @@
+/*
+ Copyright (C) 2000-2005 Silicon Graphics, Inc. All Rights Reserved.
+ Portions Copyright 2009-2010 SN Systems Ltd. All rights reserved.
+ Portions Copyright 2009-2011 David Anderson. All rights reserved.
+
+ This program is free software; you can redistribute it and/or modify it
+ under the terms of version 2 of the GNU General Public License as
+ published by the Free Software Foundation.
+
+ This program is distributed in the hope that it would be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+ Further, this software is distributed without any warranty that it is
+ free of the rightful claim of any third person regarding infringement
+ or the like. Any license provided herein, whether implied or
+ otherwise, applies only to this software file. Patent licenses, if
+ any, provided herein do not apply to combinations of this program with
+ other software, or any other product whatsoever.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write the Free Software Foundation, Inc., 51
+ Franklin Street - Fifth Floor, Boston MA 02110-1301, USA.
+
+ Contact information: Silicon Graphics, Inc., 1500 Crittenden Lane,
+ Mountain View, CA 94043, or:
+
+ http://www.sgi.com
+
+ For further information regarding this notice, see:
+
+ http://oss.sgi.com/projects/GenInfo/NoticeExplan
+
+
+
+$Header: /plroot/cmplrs.src/v7.4.5m/.RCS/PL/dwarfdump/RCS/tag_tree.c,v 1.8 2005/12/01 17:34:59 davea Exp $ */
+#include <dwarf.h>
+#include <stdio.h>
+#include <stdlib.h> /* For exit() declaration etc. */
+#include <errno.h> /* For errno declaration. */
+#include <unistd.h> /* For getopt. */
+
+#include "globals.h"
+#include "libdwarf.h"
+#include "common.h"
+#include "tag_common.h"
+
+unsigned int tag_tree_combination_table[TAG_TABLE_ROW_MAXIMUM][TAG_TABLE_COLUMN_MAXIMUM];
+
+string program_name;
+
+boolean ellipsis = FALSE; /* So we can use dwarf_names.c */
+
+/* Expected input format
+
+0xffffffff
+value of a tag
+value of a standard tag that may be a child ofthat tag
+...
+0xffffffff
+value of a tag
+value of a standard tag that may be a child ofthat tag
+...
+0xffffffff
+...
+
+No commentary allowed, no symbols, just numbers.
+Blank lines are allowed and are dropped.
+
+*/
+
+static const char *usage[] = {
+ "Usage: tag_tree_build <options>",
+ "options:\t-t\tGenerate Tags table",
+ " -i Input-file-path",
+ " -o Output-table-path",
+ " -e (Want Extended table (common extensions))",
+ " -s (Want Standard table)",
+ ""
+};
+
+static char *input_name = 0;
+static char *output_name = 0;
+int extended_flag = FALSE;
+int standard_flag = FALSE;
+
+static void
+process_args(int argc, char *argv[])
+{
+ int c = 0;
+ boolean usage_error = FALSE;
+
+ program_name = argv[0];
+
+ while ((c = getopt(argc, argv, "i:o:es")) != EOF) {
+ switch (c) {
+ case 'i':
+ input_name = strdup(optarg);
+ break;
+ case 'o':
+ output_name = strdup(optarg);
+ break;
+ case 'e':
+ extended_flag = TRUE;
+ break;
+ case 's':
+ standard_flag = TRUE;
+ break;
+
+ default:
+ usage_error = TRUE;
+ break;
+ }
+ }
+
+ if (usage_error || 1 == optind || optind != argc) {
+ print_usage_message(argv[0],usage);
+ exit(FAILED);
+ }
+}
+
+
+
+int
+main(int argc, char **argv)
+{
+ int i = 0;
+ unsigned int num = 0;
+ int input_eof = 0;
+ int table_rows = 0;
+ int table_columns = 0;
+ int current_row = 0;
+ FILE *fileInp = 0;
+ FILE *fileOut = 0;
+
+
+ print_version_details(argv[0],FALSE);
+ process_args(argc,argv);
+ print_args(argc,argv);
+
+ if (!input_name ) {
+ fprintf(stderr,"Input name required, not supplied.\n");
+ print_usage_message(argv[0],usage);
+ exit(FAILED);
+ }
+ fileInp = fopen(input_name,"r");
+ if (!fileInp) {
+ fprintf(stderr,"Invalid input filename, could not open '%s'\n",
+ input_name);
+ print_usage_message(argv[0],usage);
+ exit(FAILED);
+ }
+
+
+ if (!output_name ) {
+ fprintf(stderr,"Output name required, not supplied.\n");
+ print_usage_message(argv[0],usage);
+ exit(FAILED);
+ }
+ fileOut = fopen(output_name,"w");
+ if (!fileOut) {
+ fprintf(stderr,"Invalid output filename, could not open: '%s'\n",
+ output_name);
+ print_usage_message(argv[0],usage);
+ exit(FAILED);
+ }
+ if ((standard_flag && extended_flag) || (!standard_flag && !extended_flag)) {
+ fprintf(stderr,"Invalid table type\n");
+ fprintf(stderr,"Choose -e or -s .\n");
+ print_usage_message(argv[0],usage);
+ exit(FAILED);
+ }
+ if(standard_flag) {
+ table_rows = STD_TAG_TABLE_ROWS;
+ table_columns = STD_TAG_TABLE_COLUMNS;
+ } else {
+ table_rows = EXT_TAG_TABLE_ROWS;
+ table_columns = EXT_TAG_TABLE_COLS;
+ }
+
+
+
+ input_eof = read_value(&num,fileInp); /* 0xffffffff */
+ if (IS_EOF == input_eof) {
+ bad_line_input("Empty input file");
+ }
+ if (num != MAGIC_TOKEN_VALUE) {
+ bad_line_input("Expected 0xffffffff");
+ }
+
+ while (!feof(stdin)) {
+ unsigned int tag = 0;
+ int nTagLoc = 0;
+
+ input_eof = read_value(&tag,fileInp);
+ if (IS_EOF == input_eof) {
+ /* Reached normal eof */
+ break;
+ }
+ if(standard_flag) {
+ if (tag >= table_rows ) {
+ bad_line_input("tag value exceeds standard table size");
+ }
+ } else {
+ if(current_row >= table_rows) {
+ bad_line_input("too many extended table rows.");
+ }
+ tag_tree_combination_table[current_row][0] = tag;
+ }
+ input_eof = read_value(&num,fileInp);
+ if (IS_EOF == input_eof) {
+ bad_line_input("Not terminated correctly..");
+ }
+ nTagLoc = 1;
+ while (num != 0xffffffff) {
+ if(standard_flag) {
+ int idx = num / BITS_PER_WORD;
+ int bit = num % BITS_PER_WORD;
+
+ if (idx >= table_columns) {
+ fprintf(stderr,"Want column %d, have only %d\n",
+ idx,table_columns);
+ bad_line_input("too many TAGs: table incomplete.");
+ }
+ tag_tree_combination_table[tag][idx] |= (1 << bit);
+ } else {
+ if(nTagLoc >= table_columns) {
+ printf("Attempting to use colum %d, max is %d\n",
+ nTagLoc,table_columns);
+ bad_line_input("too many subTAGs, table incomplete.");
+ }
+ tag_tree_combination_table[current_row][nTagLoc] = num;
+ nTagLoc++;
+ }
+ input_eof = read_value(&num,fileInp);
+ if (IS_EOF == input_eof) {
+ bad_line_input("Not terminated correctly.");
+ }
+ }
+ ++current_row; /* for extended table */
+ }
+ fprintf(fileOut,"/* Generated code, do not edit. */\n");
+ fprintf(fileOut,"/* Generated on %s %s */\n",__DATE__,__TIME__);
+ fprintf(fileOut,"\n/* BEGIN FILE */\n\n");
+ if (standard_flag) {
+ fprintf(fileOut,"#define TAG_TREE_COLUMN_COUNT %d\n\n",table_columns);
+ fprintf(fileOut,"#define TAG_TREE_ROW_COUNT %d\n\n",table_rows);
+ fprintf(fileOut,
+ "static unsigned int tag_tree_combination_table"
+ "[TAG_TREE_ROW_COUNT][TAG_TREE_COLUMN_COUNT] = {\n");
+ } else {
+ fprintf(fileOut,"#define TAG_TREE_EXT_COLUMN_COUNT %d\n\n",
+ table_columns);
+ fprintf(fileOut,"#define TAG_TREE_EXT_ROW_COUNT %d\n\n",table_rows);
+ fprintf(fileOut,"/* Common extensions */\n");
+ fprintf(fileOut,
+ "static unsigned int tag_tree_combination_ext_table"
+ "[TAG_TREE_EXT_ROW_COUNT][TAG_TREE_EXT_COLUMN_COUNT] = {\n");
+ }
+
+ for (i = 0; i < table_rows; i++) {
+ int j = 0;
+ const char *name = 0;
+ if (standard_flag) {
+ dwarf_get_TAG_name(i,&name);;
+ fprintf(fileOut,"/* %d %-37s*/\n",i, name);
+ } else {
+ int k = tag_tree_combination_table[i][0];
+ dwarf_get_TAG_name(i,&name);;
+ fprintf(fileOut,"/* %u %-37s*/\n", k, name);
+ }
+ fprintf(fileOut," { ");
+ for(j = 0; j < table_columns; ++j ) {
+ fprintf(fileOut,"0x%08x,",tag_tree_combination_table[i][j]);
+ }
+ fprintf(fileOut,"},\n");
+
+ }
+ fprintf(fileOut,"};\n");
+ fprintf(fileOut,"\n/* END FILE */\n");
+ fclose(fileInp);
+ fclose(fileOut);
+ return (0);
+}
+
+/* A fake so we can use dwarf_names.c */
+void print_error (Dwarf_Debug dbg, string msg,int res, Dwarf_Error err)
+{
+}
+
diff --git a/dwarfdump/tag_tree.list b/dwarfdump/tag_tree.list
new file mode 100644
index 0000000..ebad794
--- /dev/null
+++ b/dwarfdump/tag_tree.list
@@ -0,0 +1,486 @@
+/*
+ Copyright (C) 2000-2010 Silicon Graphics, Inc. All Rights Reserved.
+ Portions Copyright (C) 2009-2011 David Anderson. All Rights Reserved.
+
+ This program is free software; you can redistribute it and/or modify it
+ under the terms of version 2.1 of the GNU Lesser General Public License
+ as published by the Free Software Foundation.
+
+ This program is distributed in the hope that it would be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+ Further, this software is distributed without any warranty that it is
+ free of the rightful claim of any third person regarding infringement
+ or the like. Any license provided herein, whether implied or
+ otherwise, applies only to this software file. Patent licenses, if
+ any, provided herein do not apply to combinations of this program with
+ other software, or any other product whatsoever.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this program; if not, write the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307,
+ USA.
+
+ Contact information: Silicon Graphics, Inc., 1500 Crittenden Lane,
+ Mountain View, CA 94043, or:
+
+ http://www.sgi.com
+
+ For further information regarding this notice, see:
+
+ http://oss.sgi.com/projects/GenInfo/NoticeExplan
+
+
+ $Header: /plroot/cmplrs.src/v7.4.5m/.RCS/PL/dwarfdump/RCS/tag_tree.list,v 1.6 2005/12/01 17:34:59 davea Exp $
+*/
+#include <dwarf.h>
+
+/*
+ list for semantic check of tag-tree.
+
+ 0xffffffff is a "punctuation." The final line of this file
+ must be 0xffffffff. The next line after each 0xffffffff
+ (except the final line) stands for "parent-tag." The lines
+ after this line before the next 0xffffffff are the tags that
+ can be children of the "parent-tag."
+
+ For example,
+
+ 0xffffffff
+ DW_TAG_array_type
+ DW_TAG_subrange_type
+ DW_TAG_enumeration_type
+ 0xffffffff
+
+ means "only DW_TAG_subrange_type and DW_TAG_enumeration_type can
+ be children of DW_TAG_array_type.
+
+ This file is applied to the preprocessor, thus any C comment and
+ preprocessor control line is available.
+*/
+
+0xffffffff
+DW_TAG_access_declaration
+0xffffffff
+DW_TAG_array_type
+DW_TAG_subrange_type
+DW_TAG_enumeration_type
+0xffffffff
+DW_TAG_base_type
+0xffffffff
+DW_TAG_catch_block
+DW_TAG_formal_parameter
+DW_TAG_unspecified_parameters
+DW_TAG_array_type
+DW_TAG_class_type
+DW_TAG_enumeration_type
+DW_TAG_pointer_type
+DW_TAG_reference_type
+DW_TAG_string_type
+DW_TAG_structure_type
+DW_TAG_subroutine_type
+DW_TAG_typedef
+DW_TAG_union_type
+DW_TAG_ptr_to_member_type
+DW_TAG_set_type
+DW_TAG_subrange_type
+DW_TAG_base_type
+DW_TAG_const_type
+DW_TAG_constant
+DW_TAG_file_type
+DW_TAG_packed_type
+DW_TAG_subprogram
+DW_TAG_variable
+DW_TAG_volatile_type
+0xffffffff
+DW_TAG_class_type
+DW_TAG_member
+DW_TAG_inheritance
+DW_TAG_access_declaration
+DW_TAG_friend
+DW_TAG_ptr_to_member_type
+DW_TAG_subprogram
+DW_TAG_template_type_parameter /* template instantiations */
+DW_TAG_template_value_parameter /* template instantiations */
+DW_TAG_typedef
+DW_TAG_base_type
+DW_TAG_pointer_type
+DW_TAG_union_type
+DW_TAG_const_type
+DW_TAG_class_type /* Nested classes */
+DW_TAG_structure_type /* Nested structures */
+DW_TAG_enumeration_type /* Nested enums */
+DW_TAG_imported_declaration
+DW_TAG_template_alias /* C++ 2010 template alias */
+0xffffffff
+DW_TAG_common_block
+DW_TAG_variable
+0xffffffff
+DW_TAG_common_inclusion
+0xffffffff
+DW_TAG_compile_unit
+DW_TAG_array_type
+DW_TAG_class_type
+DW_TAG_enumeration_type
+DW_TAG_imported_declaration
+DW_TAG_pointer_type
+DW_TAG_reference_type
+DW_TAG_string_type
+DW_TAG_structure_type
+DW_TAG_subroutine_type
+DW_TAG_typedef
+DW_TAG_union_type
+DW_TAG_common_block
+DW_TAG_inlined_subroutine
+DW_TAG_module
+DW_TAG_ptr_to_member_type
+DW_TAG_set_type
+DW_TAG_subrange_type
+DW_TAG_base_type
+DW_TAG_const_type
+DW_TAG_constant
+DW_TAG_file_type
+DW_TAG_namelist
+DW_TAG_namespace
+DW_TAG_packed_type
+DW_TAG_subprogram
+DW_TAG_variable
+DW_TAG_volatile_type
+DW_TAG_imported_module
+DW_TAG_template_alias /* C++ 2010 template alias */
+0xffffffff
+DW_TAG_type_unit
+DW_TAG_array_type
+DW_TAG_class_type
+DW_TAG_enumeration_type
+DW_TAG_imported_declaration
+DW_TAG_pointer_type
+DW_TAG_reference_type
+DW_TAG_string_type
+DW_TAG_structure_type
+DW_TAG_subroutine_type
+DW_TAG_typedef
+DW_TAG_union_type
+DW_TAG_common_block
+DW_TAG_inlined_subroutine
+DW_TAG_module
+DW_TAG_ptr_to_member_type
+DW_TAG_set_type
+DW_TAG_subrange_type
+DW_TAG_base_type
+DW_TAG_const_type
+DW_TAG_constant
+DW_TAG_file_type
+DW_TAG_namelist
+DW_TAG_namespace
+DW_TAG_packed_type
+DW_TAG_subprogram
+DW_TAG_variable
+DW_TAG_volatile_type
+DW_TAG_imported_module
+DW_TAG_template_alias /* C++ 2010 template alias */
+0xffffffff
+DW_TAG_condition /* COBOL */
+DW_TAG_constant
+DW_TAG_subrange_type
+0xffffffff
+DW_TAG_const_type
+0xffffffff
+DW_TAG_constant
+0xffffffff
+DW_TAG_dwarf_procedure
+0xffffffff
+DW_TAG_entry_point
+DW_TAG_formal_parameter
+DW_TAG_unspecified_parameters
+DW_TAG_common_inclusion
+0xffffffff
+DW_TAG_enumeration_type
+DW_TAG_enumerator
+0xffffffff
+DW_TAG_enumerator
+0xffffffff
+DW_TAG_file_type
+0xffffffff
+DW_TAG_formal_parameter
+0xffffffff
+DW_TAG_friend
+0xffffffff
+DW_TAG_imported_declaration
+0xffffffff
+DW_TAG_imported_module
+0xffffffff
+DW_TAG_imported_unit
+0xffffffff
+DW_TAG_inheritance
+0xffffffff
+DW_TAG_inlined_subroutine
+DW_TAG_formal_parameter
+DW_TAG_unspecified_parameters
+DW_TAG_array_type
+DW_TAG_class_type
+DW_TAG_enumeration_type
+DW_TAG_pointer_type
+DW_TAG_reference_type
+DW_TAG_string_type
+DW_TAG_structure_type
+DW_TAG_subroutine_type
+DW_TAG_lexical_block
+DW_TAG_typedef
+DW_TAG_union_type
+DW_TAG_inlined_subroutine
+DW_TAG_ptr_to_member_type
+DW_TAG_set_type
+DW_TAG_subrange_type
+DW_TAG_base_type
+DW_TAG_const_type
+DW_TAG_constant
+DW_TAG_file_type
+DW_TAG_namelist
+DW_TAG_packed_type
+DW_TAG_subprogram
+DW_TAG_variable
+DW_TAG_volatile_type
+0xffffffff
+DW_TAG_interface_type
+DW_TAG_member
+DW_TAG_subprogram
+0xffffffff
+DW_TAG_label
+0xffffffff
+DW_TAG_lexical_block
+DW_TAG_array_type
+DW_TAG_class_type
+DW_TAG_enumeration_type
+DW_TAG_imported_declaration
+DW_TAG_pointer_type
+DW_TAG_reference_type
+DW_TAG_string_type
+DW_TAG_structure_type
+DW_TAG_subroutine_type
+DW_TAG_typedef
+DW_TAG_union_type
+DW_TAG_inlined_subroutine
+DW_TAG_lexical_block
+DW_TAG_module
+DW_TAG_ptr_to_member_type
+DW_TAG_set_type
+DW_TAG_subrange_type
+DW_TAG_base_type
+DW_TAG_const_type
+DW_TAG_constant
+DW_TAG_namelist
+DW_TAG_packed_type
+DW_TAG_subprogram
+DW_TAG_variable
+DW_TAG_volatile_type
+DW_TAG_formal_parameter
+0xffffffff
+DW_TAG_member
+0xffffffff
+DW_TAG_module
+0xffffffff
+DW_TAG_namelist
+DW_TAG_namelist_item
+0xffffffff
+DW_TAG_namelist_item
+0xffffffff
+DW_TAG_namespace
+DW_TAG_array_type
+DW_TAG_class_type
+DW_TAG_enumeration_type
+DW_TAG_imported_declaration
+DW_TAG_pointer_type
+DW_TAG_reference_type
+DW_TAG_string_type
+DW_TAG_structure_type
+DW_TAG_subroutine_type
+DW_TAG_typedef
+DW_TAG_union_type
+DW_TAG_common_block
+DW_TAG_inlined_subroutine
+DW_TAG_module
+DW_TAG_ptr_to_member_type
+DW_TAG_set_type
+DW_TAG_subrange_type
+DW_TAG_base_type
+DW_TAG_const_type
+DW_TAG_constant
+DW_TAG_namelist
+DW_TAG_packed_type
+DW_TAG_subprogram
+DW_TAG_variable
+DW_TAG_volatile_type
+DW_TAG_namespace /* Allow a nested namespace */
+DW_TAG_imported_module /* Allow imported module */
+0xffffffff
+DW_TAG_packed_type
+0xffffffff
+DW_TAG_partial_unit
+DW_TAG_array_type
+DW_TAG_class_type
+DW_TAG_enumeration_type
+DW_TAG_imported_declaration
+DW_TAG_pointer_type
+DW_TAG_reference_type
+DW_TAG_string_type
+DW_TAG_structure_type
+DW_TAG_subroutine_type
+DW_TAG_typedef
+DW_TAG_union_type
+DW_TAG_common_block
+DW_TAG_inlined_subroutine
+DW_TAG_module
+DW_TAG_ptr_to_member_type
+DW_TAG_set_type
+DW_TAG_subrange_type
+DW_TAG_base_type
+DW_TAG_const_type
+DW_TAG_constant
+DW_TAG_file_type
+DW_TAG_namelist
+DW_TAG_packed_type
+DW_TAG_subprogram
+DW_TAG_variable
+DW_TAG_volatile_type
+0xffffffff
+DW_TAG_pointer_type
+DW_TAG_rvalue_reference_type
+DW_TAG_reference_type
+DW_TAG_restrict_type
+DW_TAG_ptr_to_member_type
+0xffffffff
+DW_TAG_ptr_to_member_type
+DW_TAG_rvalue_reference_type
+DW_TAG_reference_type
+DW_TAG_pointer_type
+DW_TAG_restrict_type
+0xffffffff
+DW_TAG_reference_type
+DW_TAG_rvalue_reference_type
+DW_TAG_reference_type
+DW_TAG_pointer_type
+DW_TAG_restrict_type
+DW_TAG_ptr_to_member_type
+0xffffffff
+DW_TAG_rvalue_reference_type
+DW_TAG_pointer_type
+DW_TAG_restrict_type
+DW_TAG_ptr_to_member_type
+DW_TAG_reference_type
+0xffffffff
+DW_TAG_restrict_type
+DW_TAG_pointer_type
+DW_TAG_ptr_to_member_type
+DW_TAG_rvalue_reference_type
+0xffffffff
+DW_TAG_set_type
+0xffffffff
+DW_TAG_shared_type
+0xffffffff
+DW_TAG_string_type
+0xffffffff
+DW_TAG_structure_type
+DW_TAG_member
+DW_TAG_inheritance
+DW_TAG_access_declaration
+DW_TAG_friend
+DW_TAG_ptr_to_member_type
+DW_TAG_variant_part
+DW_TAG_subprogram
+DW_TAG_template_type_parameter /* template instantiations */
+DW_TAG_template_value_parameter /* template instantiations */
+DW_TAG_typedef
+DW_TAG_base_type
+DW_TAG_pointer_type
+DW_TAG_union_type
+DW_TAG_const_type
+DW_TAG_structure_type /* nested structures */
+DW_TAG_enumeration_type /* nested enums */
+DW_TAG_class_type /* nested classes */
+DW_TAG_imported_declaration /* References to namespaces */
+DW_TAG_template_alias /* C++ 2010 template alias */
+0xffffffff
+DW_TAG_subprogram
+DW_TAG_formal_parameter
+DW_TAG_unspecified_parameters
+DW_TAG_thrown_type
+DW_TAG_template_type_parameter
+DW_TAG_template_value_parameter
+DW_TAG_common_inclusion
+DW_TAG_common_block
+DW_TAG_array_type
+DW_TAG_class_type
+DW_TAG_enumeration_type
+DW_TAG_pointer_type
+DW_TAG_reference_type
+DW_TAG_string_type
+DW_TAG_lexical_block
+DW_TAG_structure_type
+DW_TAG_subroutine_type
+DW_TAG_typedef
+DW_TAG_union_type
+DW_TAG_inlined_subroutine
+DW_TAG_ptr_to_member_type
+DW_TAG_set_type
+DW_TAG_subrange_type
+DW_TAG_base_type
+DW_TAG_const_type
+DW_TAG_constant
+DW_TAG_file_type
+DW_TAG_namelist
+DW_TAG_packed_type
+DW_TAG_subprogram
+DW_TAG_variable
+DW_TAG_volatile_type
+DW_TAG_label
+DW_TAG_imported_module /* References to namespaces */
+DW_TAG_imported_declaration /* References to namespaces */
+0xffffffff
+DW_TAG_subrange_type
+0xffffffff
+DW_TAG_subroutine_type
+DW_TAG_formal_parameter
+DW_TAG_unspecified_parameters
+0xffffffff
+DW_TAG_template_type_parameter
+0xffffffff
+DW_TAG_template_value_parameter
+0xffffffff
+DW_TAG_thrown_type
+0xffffffff
+DW_TAG_try_block
+0xffffffff
+DW_TAG_typedef
+0xffffffff
+DW_TAG_union_type
+DW_TAG_friend
+DW_TAG_member
+DW_TAG_class_type /* Nested classes */
+DW_TAG_enumeration_type /* Nested enums */
+DW_TAG_structure_type /* Nested structures */
+DW_TAG_typedef /* Nested typedef */
+DW_TAG_subprogram
+DW_TAG_template_type_parameter /* template instantiations */
+DW_TAG_template_value_parameter /* template instantiations */
+0xffffffff
+DW_TAG_template_alias
+DW_TAG_template_type_parameter
+DW_TAG_template_value_parameter
+0xffffffff
+DW_TAG_unspecified_parameters
+0xffffffff
+DW_TAG_unspecified_type
+0xffffffff
+DW_TAG_variable
+0xffffffff
+DW_TAG_variant
+DW_TAG_variant_part
+0xffffffff
+DW_TAG_variant_part
+0xffffffff
+DW_TAG_volatile_type
+0xffffffff
+DW_TAG_with_stmt
+0xffffffff
diff --git a/dwarfdump/tag_tree_ext.list b/dwarfdump/tag_tree_ext.list
new file mode 100644
index 0000000..e671373
--- /dev/null
+++ b/dwarfdump/tag_tree_ext.list
@@ -0,0 +1,63 @@
+/*
+ Copyright (C) 2000-2010 Silicon Graphics, Inc. All Rights Reserved.
+ Portions Copyright 2009-2010 SN Systems Ltd. All rights reserved.
+ Portions Copyright (C) 2009-2011 David Anderson. All Rights Reserved.
+
+ This program is free software; you can redistribute it and/or modify it
+ under the terms of version 2.1 of the GNU Lesser General Public License
+ as published by the Free Software Foundation.
+
+ This program is distributed in the hope that it would be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+ Further, this software is distributed without any warranty that it is
+ free of the rightful claim of any third person regarding infringement
+ or the like. Any license provided herein, whether implied or
+ otherwise, applies only to this software file. Patent licenses, if
+ any, provided herein do not apply to combinations of this program with
+ other software, or any other product whatsoever.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this program; if not, write the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307,
+ USA.
+
+ Contact information: Silicon Graphics, Inc., 1500 Crittenden Lane,
+ Mountain View, CA 94043, or:
+
+ http://www.sgi.com
+
+ For further information regarding this notice, see:
+
+ http://oss.sgi.com/projects/GenInfo/NoticeExplan
+
+
+$Header: /plroot/cmplrs.src/v7.4.5m/.RCS/PL/dwarfdump/RCS/tag_attr.list,v 1.7 2005/12/01 17:34:59 davea Exp $
+*/
+#include <dwarf.h>
+
+/* list for semantic check of tag-tree relation.
+ See tag_tree.list for details.
+
+*/
+
+/* Common DWARF extensions */
+
+0xffffffff
+DW_TAG_structure_type
+DW_TAG_variable /* GNU gcc usage. */
+0xffffffff
+DW_TAG_class_type
+DW_TAG_variable /* GNU gcc usage. */
+DW_TAG_GNU_template_template_parameter /* template instantiations */
+0xffffffff
+DW_TAG_structure_type
+DW_TAG_GNU_template_template_parameter /* template instantiations */
+0xffffffff
+DW_TAG_subprogram
+DW_TAG_GNU_template_template_parameter /* template instantiations */
+0xffffffff
+DW_TAG_union_type
+DW_TAG_GNU_template_template_parameter /* template instantiations */
+0xffffffff
diff --git a/dwarfdump/testesb.c b/dwarfdump/testesb.c
new file mode 100644
index 0000000..c3ea2f0
--- /dev/null
+++ b/dwarfdump/testesb.c
@@ -0,0 +1,78 @@
+/* testesb.c
+ test code for esb.h esb.c
+
+ Not part of a compiled dwarfdump.
+
+*/
+
+#include <stdio.h>
+#include <string.h>
+typedef char *string;
+
+#include "esb.h"
+
+void
+check(string msg, struct esb_s *data, string v)
+{
+ string b = esb_get_string(data);
+ size_t l = 0;
+ size_t alloc = 0;
+
+ if (strcmp(b, v)) {
+ fprintf(stderr, "ERROR: %s content error %s != %s\n", msg, b,
+ v);
+ }
+
+ l = esb_string_len(data);
+
+ if (l != strlen(v)) {
+ fprintf(stderr, "ERROR: %s length error %lu != %lu\n", msg,
+ (unsigned long) l, (unsigned long) strlen(v));
+ }
+ alloc = esb_get_allocated_size(data);
+ if (l > alloc) {
+ fprintf(stderr, "ERROR: %s allocation error %lu > %lu\n", msg,
+ (unsigned long) l, (unsigned long) alloc);
+
+ }
+
+ return;
+}
+
+int
+main(void)
+{
+ struct esb_s data;
+
+
+ esb_alloc_size(2); /* small to get all code paths tested. */
+ esb_constructor(&data);
+
+ esb_append(&data, "a");
+ esb_appendn(&data, "bc", 1);
+ esb_append(&data, "d");
+ esb_append(&data, "e");
+ check("test 1", &data, "abde");
+
+ esb_destructor(&data);
+ esb_constructor(&data);
+
+ esb_append(&data, "abcdefghij" "0123456789");
+ check("test 2", &data, "abcdefghij" "0123456789");
+
+ esb_destructor(&data);
+ esb_constructor(&data);
+ esb_append(&data, "abcdefghij" "0123456789");
+
+ esb_append(&data, "abcdefghij" "0123456789");
+
+ esb_append(&data, "abcdefghij" "0123456789");
+
+ esb_append(&data, "abcdefghij" "0123456789");
+ check("test 3", &data, "abcdefghij"
+ "0123456789"
+ "abcdefghij"
+ "0123456789"
+ "abcdefghij" "0123456789" "abcdefghij" "0123456789");
+ return 0;
+}
diff --git a/dwarfdump/uri.c b/dwarfdump/uri.c
new file mode 100644
index 0000000..1353ab8
--- /dev/null
+++ b/dwarfdump/uri.c
@@ -0,0 +1,493 @@
+/*
+ Copyright 2011 David Anderson. All rights reserved.
+
+ This program is free software; you can redistribute it and/or modify it
+ under the terms of version 2 of the GNU General Public License as
+ published by the Free Software Foundation.
+
+ This program is distributed in the hope that it would be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+ Further, this software is distributed without any warranty that it is
+ free of the rightful claim of any third person regarding infringement
+ or the like. Any license provided herein, whether implied or
+ otherwise, applies only to this software file. Patent licenses, if
+ any, provided herein do not apply to combinations of this program with
+ other software, or any other product whatsoever.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write the Free Software Foundation, Inc., 51
+ Franklin Street - Fifth Floor, Boston MA 02110-1301, USA.
+
+ Contact information: Silicon Graphics, Inc., 1500 Crittenden Lane,
+ Mountain View, CA 94043, or:
+
+ http://www.sgi.com
+
+ For further information regarding this notice, see:
+
+ http://oss.sgi.com/projects/GenInfo/NoticeExplan
+
+*/
+
+/* The address of the Free Software Foundation is
+ Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+ SGI has moved from the Crittenden Lane address.
+*/
+
+#include "globals.h"
+#include "esb.h"
+#include "uri.h"
+#include <stdio.h>
+#include <ctype.h>
+
+/* dwarfdump_ctype table. See uritablebuild.c */
+static char dwarfdump_ctype_table[256] = {
+0, /* NUL 0x00 */
+0, /* control 0x01 */
+0, /* control 0x02 */
+0, /* control 0x03 */
+0, /* control 0x04 */
+0, /* control 0x05 */
+0, /* control 0x06 */
+0, /* control 0x07 */
+0, /* control 0x08 */
+0, /* whitespace 0x09 */
+0, /* whitespace 0x0a */
+0, /* whitespace 0x0b */
+0, /* whitespace 0x0c */
+0, /* whitespace 0x0d */
+0, /* control 0x0e */
+0, /* control 0x0f */
+0, /* control 0x10 */
+0, /* control 0x11 */
+0, /* control 0x12 */
+0, /* control 0x13 */
+0, /* control 0x14 */
+0, /* control 0x15 */
+0, /* control 0x16 */
+0, /* control 0x17 */
+0, /* control 0x18 */
+0, /* control 0x19 */
+0, /* control 0x1a */
+0, /* control 0x1b */
+0, /* control 0x1c */
+0, /* control 0x1d */
+0, /* control 0x1e */
+0, /* control 0x1f */
+1, /* ' ' 0x20 */
+1, /* '!' 0x21 */
+0, /* '"' 0x22 */
+1, /* '#' 0x23 */
+1, /* '$' 0x24 */
+0, /* '%' 0x25 */
+1, /* '&' 0x26 */
+0, /* ''' 0x27 */
+1, /* '(' 0x28 */
+1, /* ')' 0x29 */
+1, /* '*' 0x2a */
+1, /* '+' 0x2b */
+1, /* ',' 0x2c */
+1, /* '-' 0x2d */
+1, /* '.' 0x2e */
+1, /* '/' 0x2f */
+1, /* '0' 0x30 */
+1, /* '1' 0x31 */
+1, /* '2' 0x32 */
+1, /* '3' 0x33 */
+1, /* '4' 0x34 */
+1, /* '5' 0x35 */
+1, /* '6' 0x36 */
+1, /* '7' 0x37 */
+1, /* '8' 0x38 */
+1, /* '9' 0x39 */
+1, /* ':' 0x3a */
+0, /* ';' 0x3b */
+1, /* '<' 0x3c */
+1, /* '=' 0x3d */
+1, /* '>' 0x3e */
+1, /* '?' 0x3f */
+1, /* '@' 0x40 */
+1, /* 'A' 0x41 */
+1, /* 'B' 0x42 */
+1, /* 'C' 0x43 */
+1, /* 'D' 0x44 */
+1, /* 'E' 0x45 */
+1, /* 'F' 0x46 */
+1, /* 'G' 0x47 */
+1, /* 'H' 0x48 */
+1, /* 'I' 0x49 */
+1, /* 'J' 0x4a */
+1, /* 'K' 0x4b */
+1, /* 'L' 0x4c */
+1, /* 'M' 0x4d */
+1, /* 'N' 0x4e */
+1, /* 'O' 0x4f */
+1, /* 'P' 0x50 */
+1, /* 'Q' 0x51 */
+1, /* 'R' 0x52 */
+1, /* 'S' 0x53 */
+1, /* 'T' 0x54 */
+1, /* 'U' 0x55 */
+1, /* 'V' 0x56 */
+1, /* 'W' 0x57 */
+1, /* 'X' 0x58 */
+1, /* 'Y' 0x59 */
+1, /* 'Z' 0x5a */
+1, /* '[' 0x5b */
+1, /* '\' 0x5c */
+1, /* ']' 0x5d */
+1, /* '^' 0x5e */
+1, /* '_' 0x5f */
+0, /* '`' 0x60 */
+1, /* 'a' 0x61 */
+1, /* 'b' 0x62 */
+1, /* 'c' 0x63 */
+1, /* 'd' 0x64 */
+1, /* 'e' 0x65 */
+1, /* 'f' 0x66 */
+1, /* 'g' 0x67 */
+1, /* 'h' 0x68 */
+1, /* 'i' 0x69 */
+1, /* 'j' 0x6a */
+1, /* 'k' 0x6b */
+1, /* 'l' 0x6c */
+1, /* 'm' 0x6d */
+1, /* 'n' 0x6e */
+1, /* 'o' 0x6f */
+1, /* 'p' 0x70 */
+1, /* 'q' 0x71 */
+1, /* 'r' 0x72 */
+1, /* 's' 0x73 */
+1, /* 't' 0x74 */
+1, /* 'u' 0x75 */
+1, /* 'v' 0x76 */
+1, /* 'w' 0x77 */
+1, /* 'x' 0x78 */
+1, /* 'y' 0x79 */
+1, /* 'z' 0x7a */
+1, /* '{' 0x7b */
+1, /* '|' 0x7c */
+1, /* '}' 0x7d */
+1, /* '~' 0x7e */
+0, /* DEL 0x7f */
+1, /* 0x80 */
+1, /* 0x81 */
+1, /* 0x82 */
+1, /* 0x83 */
+1, /* 0x84 */
+1, /* 0x85 */
+1, /* 0x86 */
+1, /* 0x87 */
+1, /* 0x88 */
+1, /* 0x89 */
+1, /* 0x8a */
+1, /* 0x8b */
+1, /* 0x8c */
+1, /* 0x8d */
+1, /* 0x8e */
+1, /* 0x8f */
+1, /* 0x90 */
+1, /* 0x91 */
+1, /* 0x92 */
+1, /* 0x93 */
+1, /* 0x94 */
+1, /* 0x95 */
+1, /* 0x96 */
+1, /* 0x97 */
+1, /* 0x98 */
+1, /* 0x99 */
+1, /* 0x9a */
+1, /* 0x9b */
+1, /* 0x9c */
+1, /* 0x9d */
+1, /* 0x9e */
+1, /* 0x9f */
+0, /* other: 0xa0 */
+1, /* 0xa1 */
+1, /* 0xa2 */
+1, /* 0xa3 */
+1, /* 0xa4 */
+1, /* 0xa5 */
+1, /* 0xa6 */
+1, /* 0xa7 */
+1, /* 0xa8 */
+1, /* 0xa9 */
+1, /* 0xaa */
+1, /* 0xab */
+1, /* 0xac */
+1, /* 0xad */
+1, /* 0xae */
+1, /* 0xaf */
+1, /* 0xb0 */
+1, /* 0xb1 */
+1, /* 0xb2 */
+1, /* 0xb3 */
+1, /* 0xb4 */
+1, /* 0xb5 */
+1, /* 0xb6 */
+1, /* 0xb7 */
+1, /* 0xb8 */
+1, /* 0xb9 */
+1, /* 0xba */
+1, /* 0xbb */
+1, /* 0xbc */
+1, /* 0xbd */
+1, /* 0xbe */
+1, /* 0xbf */
+1, /* 0xc0 */
+1, /* 0xc1 */
+1, /* 0xc2 */
+1, /* 0xc3 */
+1, /* 0xc4 */
+1, /* 0xc5 */
+1, /* 0xc6 */
+1, /* 0xc7 */
+1, /* 0xc8 */
+1, /* 0xc9 */
+1, /* 0xca */
+1, /* 0xcb */
+1, /* 0xcc */
+1, /* 0xcd */
+1, /* 0xce */
+1, /* 0xcf */
+1, /* 0xd0 */
+1, /* 0xd1 */
+1, /* 0xd2 */
+1, /* 0xd3 */
+1, /* 0xd4 */
+1, /* 0xd5 */
+1, /* 0xd6 */
+1, /* 0xd7 */
+1, /* 0xd8 */
+1, /* 0xd9 */
+1, /* 0xda */
+1, /* 0xdb */
+1, /* 0xdc */
+1, /* 0xdd */
+1, /* 0xde */
+1, /* 0xdf */
+1, /* 0xe0 */
+1, /* 0xe1 */
+1, /* 0xe2 */
+1, /* 0xe3 */
+1, /* 0xe4 */
+1, /* 0xe5 */
+1, /* 0xe6 */
+1, /* 0xe7 */
+1, /* 0xe8 */
+1, /* 0xe9 */
+1, /* 0xea */
+1, /* 0xeb */
+1, /* 0xec */
+1, /* 0xed */
+1, /* 0xee */
+1, /* 0xef */
+1, /* 0xf0 */
+1, /* 0xf1 */
+1, /* 0xf2 */
+1, /* 0xf3 */
+1, /* 0xf4 */
+1, /* 0xf5 */
+1, /* 0xf6 */
+1, /* 0xf7 */
+1, /* 0xf8 */
+1, /* 0xf9 */
+1, /* 0xfa */
+1, /* 0xfb */
+1, /* 0xfc */
+1, /* 0xfd */
+1, /* 0xfe */
+0, /* other: 0xff */
+};
+static char *
+xchar(int c, char *buf, int size)
+{
+ snprintf(buf, size,"%%%02x",c);
+ return buf;
+}
+
+/* Translate dangerous and some other characters to safe
+ %xx form.
+*/
+void
+translate_to_uri(const char * filename, struct esb_s *out)
+{
+ char buf[8];
+ const char *cp = 0;
+ for(cp = filename ; *cp; ++cp) {
+ char v[2];
+ int c = 0xff & (unsigned char)*cp;
+ if(dwarfdump_ctype_table[c]) {
+ v[0] = c;
+ v[1] = 0;
+ esb_append(out,v);
+ } else {
+ char *b = xchar(c,buf,sizeof(buf));
+ esb_append(out,b);
+ }
+ }
+}
+
+/* This is not very efficient, but it is seldom called. */
+static char
+hexdig(char c)
+{
+ char ochar = 0;
+ if(c >= 0 && c <= '9') {
+ ochar = (c - '0');
+ return ochar;
+ }
+ if(c >= 'a' && c <= 'f') {
+ ochar = (c - 'a')+10;
+ return ochar;
+ }
+ if(c >= 'A' && c <= 'F') {
+ ochar = (c - 'A')+10;
+ return ochar;
+ }
+ // We have an input botch here.
+ fprintf(stderr,"Translating from uri: "
+ "A supposed hexadecimal input character is "
+ "not 0-9 or a-f or A-F, it is (shown as hex here): %x\n",c);
+ return ochar;
+}
+
+static char tohex(char c1, char c2)
+{
+ char out = (hexdig(c1) << 4) | hexdig(c2);
+ return out;
+}
+static int
+hexpairtochar(const char *cp, char*myochar)
+{
+ char ochar = 0;
+ int olen = 0;
+ char c = cp[0];
+ if(c) {
+ char c2 = cp[1];
+ if(c2) {
+ ochar = tohex(c,c2);
+ olen = 2;
+ } else {
+ fprintf(stderr,"Translating from uri: "
+ "A supposed hexadecimal input character pair "
+ "runs off the end of the input after 1 hex digit.\n");
+ /* botched input. */
+ ochar = c;
+ olen = 1;
+ }
+ } else {
+ /* botched input. */
+ fprintf(stderr,"Translating from uri: "
+ "A supposed hexadecimal input character pair "
+ "runs off the end of the input.\n");
+ ochar = '%';
+ olen = 0;
+ }
+ *myochar = ochar;
+ return olen;
+}
+
+void
+translate_from_uri(const char * input, struct esb_s* out)
+{
+ const char *cp = input;
+ char tempstr[2];
+ for(; *cp; ++cp) {
+ char c = *cp;
+ if(c == '%') {
+ int increment = 0;
+ char c2 = cp[1];
+ // hexpairtochar deals with c2 being NUL.
+ if ( c2 == '%') {
+ tempstr[0] = c;
+ tempstr[1] = 0;
+ esb_append(out,tempstr);
+ ++cp;
+ continue;
+ }
+
+ increment = hexpairtochar(cp+1,&c);
+ tempstr[0] = c;
+ tempstr[1] = 0;
+ esb_append(out,tempstr);
+ cp +=increment;
+ continue;
+ }
+ tempstr[0] = c;
+ tempstr[1] = 0;
+ esb_append(out,tempstr);
+ }
+}
+
+
+
+
+#ifdef TEST
+
+unsigned errcnt = 0;
+
+static void
+mytestfrom(const char * in,const char *expected,int testnum)
+{
+ struct esb_s out;
+ esb_constructor(&out);
+ translate_from_uri(in, &out);
+ if(strcmp(expected, esb_get_string(&out))) {
+ printf(" Fail test %d expected \"%s\" got \"%s\"\n",
+ testnum,expected,esb_get_string(&out));
+ ++errcnt;
+ }
+ esb_destructor(&out);
+}
+
+
+static void
+mytest(char *in,char *expected,int testnum)
+{
+ struct esb_s out;
+ esb_constructor(&out);
+ translate_to_uri(in, &out);
+ if(strcmp(expected, esb_get_string(&out))) {
+ printf(" Fail test %d expected %s got %s\n",testnum,expected,esb_get_string(&out));
+ ++errcnt;
+ }
+ esb_destructor(&out);
+}
+
+
+int
+main()
+{
+ /* We no longer translate space to %20, that
+ turns out not to help all that much. */
+ mytest("aaa","aaa",1);
+ mytest(" bc"," bc",2);
+ mytest(";bc","%3bbc",3);
+ mytest(" bc\n"," bc%0a",4);
+ mytest(";bc\n","%3bbc%0a",5);
+ mytest(" bc\r"," bc%0d",6);
+ mytest(";bc\r","%3bbc%0d",7);
+ mytest(" \x01"," %01",8);
+ mytest(";\x01","%3b%01",9);
+ mytestfrom("abc","abc",10);
+ mytestfrom("a%20bc","a bc",11);
+ mytestfrom("a%%20bc","a%20bc",12);
+ mytestfrom("a%%%20bc","a% bc",13);
+ mytestfrom("a%%%%20bc","a%%20bc",14);
+ mytestfrom("a%20","a ",15);
+ /* The following is mistaken input. */
+ mytestfrom("a%2","a2",16);
+ mytestfrom("a%","a%",17);
+ mytest("%bc","%25bc",18);
+
+ if(errcnt) {
+ printf("uri errcount ",errcnt);
+ }
+ return errcnt? 1:0;
+}
+#endif
+
diff --git a/dwarfdump/uri.h b/dwarfdump/uri.h
new file mode 100644
index 0000000..0dfa386
--- /dev/null
+++ b/dwarfdump/uri.h
@@ -0,0 +1,37 @@
+/*
+ Copyright 2011 David Anderson. All rights reserved.
+
+ This program is free software; you can redistribute it and/or modify it
+ under the terms of version 2 of the GNU General Public License as
+ published by the Free Software Foundation.
+
+ This program is distributed in the hope that it would be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+ Further, this software is distributed without any warranty that it is
+ free of the rightful claim of any third person regarding infringement
+ or the like. Any license provided herein, whether implied or
+ otherwise, applies only to this software file. Patent licenses, if
+ any, provided herein do not apply to combinations of this program with
+ other software, or any other product whatsoever.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write the Free Software Foundation, Inc., 51
+ Franklin Street - Fifth Floor, Boston MA 02110-1301, USA.
+
+ Contact information: Silicon Graphics, Inc., 1500 Crittenden Lane,
+ Mountain View, CA 94043, or:
+
+ http://www.sgi.com
+
+ For further information regarding this notice, see:
+
+ http://oss.sgi.com/projects/GenInfo/NoticeExplan
+
+*/
+
+
+void translate_to_uri(const char * filename, struct esb_s *out);
+void translate_from_uri(const char * input, struct esb_s *out);
+
diff --git a/dwarfdump/uritablebuild.c b/dwarfdump/uritablebuild.c
new file mode 100644
index 0000000..c8c5501
--- /dev/null
+++ b/dwarfdump/uritablebuild.c
@@ -0,0 +1,146 @@
+/*
+ Copyright 2011 David Anderson. All rights reserved.
+
+ This program is free software; you can redistribute it and/or modify it
+ under the terms of version 2 of the GNU General Public License as
+ published by the Free Software Foundation.
+
+ This program is distributed in the hope that it would be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+ Further, this software is distributed without any warranty that it is
+ free of the rightful claim of any third person regarding infringement
+ or the like. Any license provided herein, whether implied or
+ otherwise, applies only to this software file. Patent licenses, if
+ any, provided herein do not apply to combinations of this program with
+ other software, or any other product whatsoever.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write the Free Software Foundation, Inc., 51
+ Franklin Street - Fifth Floor, Boston MA 02110-1301, USA.
+
+ Contact information: Silicon Graphics, Inc., 1500 Crittenden Lane,
+ Mountain View, CA 94043, or:
+
+ http://www.sgi.com
+
+ For further information regarding this notice, see:
+
+ http://oss.sgi.com/projects/GenInfo/NoticeExplan
+
+*/
+
+/* The address of the Free Software Foundation is
+ Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+ SGI has moved from the Crittenden Lane address.
+*/
+
+#include <stdio.h>
+#include <ctype.h>
+
+/* Generates a table which identifies a few dangerous characters.
+ Ones one does not want to appear in output.
+
+ It's a bit arbitrary in that we allow lots of shell-interpreted
+ characters through, and most characters generally.
+
+ But not control characters or single or double quotes.
+ The quotes would be particularly problematic for post-processing
+ dwarfdump output sensibly.
+
+*/
+static void
+print_entry(int c)
+{
+ char v[2];
+ v[0] = c;
+ v[1] = 0;
+ if(c == 0) {
+ printf("0, /* NUL 0x%02x */\n",c);
+ return;
+ }
+ if(isalnum(c) || c == ' ' ) {
+ /* We let the space character print as space since
+ lots of files are named that way in Mac and Windows.
+ */
+ printf("1, /* \'%s\' 0x%02x */\n",v,c);
+ return;
+ }
+ if(c == 0x21 || c == 0x23 || c == 0x26) {
+ /* We let the space character print as space since
+ lots of files are named that way in Mac and Windows.
+ */
+ printf("1, /* \'%s\' 0x%02x */\n",v,c);
+ return;
+ }
+ if(isspace(c) ) {
+ /* Other white space translated. */
+ printf("0, /* whitespace 0x%02x */\n",c);
+ return;
+ }
+ if(c == 0x7f) {
+ printf("0, /* DEL 0x%02x */\n",c);
+ return;
+ }
+ if(c >= 0x01 && c <= 0x20 ) {
+ /* ASCII control characters. */
+ printf("0, /* control 0x%02x */\n",c);
+ return;
+ }
+ if(c == '\'' || c == '\"' || c == '%' || c == ';' ) {
+ printf("0, /* \'%s\' 0x%02x */\n",v,c);
+ return;
+ }
+ if(c >= 0x3a && c <= 0x40 ) {
+ /* ASCII */
+ printf("1, /* \'%s\' 0x%02x */\n",v,c);
+ return;
+ }
+ if(c == 0xa0 || c == 0xff ) {
+ printf("0, /* other: 0x%02x */\n",c);
+ return;
+ }
+ if(c >= 0x27 && c <= 0x2f ) {
+ /* ASCII */
+ printf("1, /* \'%s\' 0x%02x */\n",v,c);
+ return;
+ }
+ if(c >= 0x5b && c <= 0x5f ) {
+ /* ASCII */
+ printf("1, /* \'%s\' 0x%02x */\n",v,c);
+ return;
+ }
+ if(c >= 0x60 && c <= 0x60 ) {
+ /* ASCII */
+ printf("0, /* \'%s\' 0x%02x */\n",v,c);
+ return;
+ }
+ if(c >= 0x7b && c <= 0x7e ) {
+ /* ASCII */
+ printf("1, /* \'%s\' 0x%02x */\n",v,c);
+ return;
+ }
+ if (c < 0x7f) {
+ /* ASCII */
+ printf("1, /* \'%s\' 0x%02x */\n",v,c);
+ return;
+ }
+ /* We are allowing other iso 8859 characters through unchanged. */
+ printf("1, /* 0x%02x */\n",c);
+}
+
+
+int
+main()
+{
+ int i = 0;
+ printf("/* dwarfdump_ctype table */\n");
+ printf("char dwarfdump_ctype_table[256] = { \n");
+ for ( i = 0 ; i <= 255; ++i) {
+ print_entry(i);
+ }
+ printf("};\n");
+}
+