Automatic structure extraction tool...works on binaries with dwarf-2 debug informatio...
authorbdemsky <bdemsky>
Sat, 10 Jul 2004 04:29:04 +0000 (04:29 +0000)
committerbdemsky <bdemsky>
Sat, 10 Jul 2004 04:29:04 +0000 (04:29 +0000)
23 files changed:
Repair/RepairCompiler/structextract/bfd.h [new file with mode: 0755]
Repair/RepairCompiler/structextract/build [new file with mode: 0755]
Repair/RepairCompiler/structextract/dumpstructures.c [new file with mode: 0755]
Repair/RepairCompiler/structextract/dumpstructures.h [new file with mode: 0755]
Repair/RepairCompiler/structextract/include/ansidecl.h [new file with mode: 0755]
Repair/RepairCompiler/structextract/include/bin-bugs.h [new file with mode: 0755]
Repair/RepairCompiler/structextract/include/bucomm.h [new file with mode: 0755]
Repair/RepairCompiler/structextract/include/config.h [new file with mode: 0755]
Repair/RepairCompiler/structextract/include/elf/common.h [new file with mode: 0755]
Repair/RepairCompiler/structextract/include/elf/dwarf2.h [new file with mode: 0755]
Repair/RepairCompiler/structextract/include/elf/external.h [new file with mode: 0755]
Repair/RepairCompiler/structextract/include/elf/i386.h [new file with mode: 0755]
Repair/RepairCompiler/structextract/include/elf/ia64.h [new file with mode: 0755]
Repair/RepairCompiler/structextract/include/elf/internal.h [new file with mode: 0755]
Repair/RepairCompiler/structextract/include/elf/reloc-macros.h [new file with mode: 0755]
Repair/RepairCompiler/structextract/include/fopen-same.h [new file with mode: 0755]
Repair/RepairCompiler/structextract/include/getopt.h [new file with mode: 0755]
Repair/RepairCompiler/structextract/include/symcat.h [new file with mode: 0755]
Repair/RepairCompiler/structextract/readelf.c [new file with mode: 0755]
Repair/RepairCompiler/structextract/typedata.c [new file with mode: 0755]
Repair/RepairCompiler/structextract/typedata.h [new file with mode: 0755]
Repair/RepairCompiler/structextract/unwind-ia64.c [new file with mode: 0755]
Repair/RepairCompiler/structextract/unwind-ia64.h [new file with mode: 0755]

diff --git a/Repair/RepairCompiler/structextract/bfd.h b/Repair/RepairCompiler/structextract/bfd.h
new file mode 100755 (executable)
index 0000000..b697774
--- /dev/null
@@ -0,0 +1,4442 @@
+/* DO NOT EDIT!  -*- buffer-read-only: t -*-  This file is automatically 
+   generated from "bfd-in.h", "init.c", "opncls.c", "libbfd.c", 
+   "bfdio.c", "bfdwin.c", "section.c", "archures.c", "reloc.c", 
+   "syms.c", "bfd.c", "archive.c", "corefile.c", "targets.c", "format.c", 
+   "linker.c" and "simple.c".
+   Run "make headers" in your build bfd/ to regenerate.  */
+
+/* Main header file for the bfd library -- portable access to object files.
+
+   Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
+   1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+
+   Contributed by Cygnus Support.
+
+   This file is part of BFD, the Binary File Descriptor library.
+
+   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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+#ifndef __BFD_H_SEEN__
+#define __BFD_H_SEEN__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "ansidecl.h"
+#include "symcat.h"
+#if defined (__STDC__) || defined (ALMOST_STDC) || defined (HAVE_STRINGIZE)
+#ifndef SABER
+/* This hack is to avoid a problem with some strict ANSI C preprocessors.
+   The problem is, "32_" is not a valid preprocessing token, and we don't
+   want extra underscores (e.g., "nlm_32_").  The XCONCAT2 macro will
+   cause the inner CONCAT2 macros to be evaluated first, producing
+   still-valid pp-tokens.  Then the final concatenation can be done.  */
+#undef CONCAT4
+#define CONCAT4(a,b,c,d) XCONCAT2(CONCAT2(a,b),CONCAT2(c,d))
+#endif
+#endif
+
+/* The word size used by BFD on the host.  This may be 64 with a 32
+   bit target if the host is 64 bit, or if other 64 bit targets have
+   been selected with --enable-targets, or if --enable-64-bit-bfd.  */
+#define BFD_ARCH_SIZE 32
+
+/* The word size of the default bfd target.  */
+#define BFD_DEFAULT_TARGET_SIZE 32
+
+#define BFD_HOST_64BIT_LONG 0
+#if 0
+#define BFD_HOST_64_BIT 
+#define BFD_HOST_U_64_BIT 
+#endif
+
+#if BFD_ARCH_SIZE >= 64
+#define BFD64
+#endif
+
+#ifndef INLINE
+#if __GNUC__ >= 2
+#define INLINE __inline__
+#else
+#define INLINE
+#endif
+#endif
+
+/* Forward declaration.  */
+typedef struct bfd bfd;
+
+/* Boolean type used in bfd.  Too many systems define their own
+   versions of "boolean" for us to safely typedef a "boolean" of
+   our own.  Using an enum for "bfd_boolean" has its own set of
+   problems, with strange looking casts required to avoid warnings
+   on some older compilers.  Thus we just use an int.
+
+   General rule: Functions which are bfd_boolean return TRUE on
+   success and FALSE on failure (unless they're a predicate).  */
+
+typedef int bfd_boolean;
+#undef FALSE
+#undef TRUE
+#define FALSE 0
+#define TRUE 1
+
+#if 0
+/* Poison.  */
+#undef false
+#undef true
+#define false dont_use_false_in_bfd
+#define true dont_use_true_in_bfd
+#endif
+
+/* Support for different sizes of target format ints and addresses.
+   If the type `long' is at least 64 bits, BFD_HOST_64BIT_LONG will be
+   set to 1 above.  Otherwise, if gcc is being used, this code will
+   use gcc's "long long" type.  Otherwise, BFD_HOST_64_BIT must be
+   defined above.  */
+
+#ifndef BFD_HOST_64_BIT
+# if BFD_HOST_64BIT_LONG
+#  define BFD_HOST_64_BIT long
+#  define BFD_HOST_U_64_BIT unsigned long
+# else
+#  ifdef __GNUC__
+#   if __GNUC__ >= 2
+#    define BFD_HOST_64_BIT long long
+#    define BFD_HOST_U_64_BIT unsigned long long
+#   endif /* __GNUC__ >= 2 */
+#  endif /* ! defined (__GNUC__) */
+# endif /* ! BFD_HOST_64BIT_LONG */
+#endif /* ! defined (BFD_HOST_64_BIT) */
+
+#ifdef BFD64
+
+#ifndef BFD_HOST_64_BIT
+ #error No 64 bit integer type available
+#endif /* ! defined (BFD_HOST_64_BIT) */
+
+typedef BFD_HOST_U_64_BIT bfd_vma;
+typedef BFD_HOST_64_BIT bfd_signed_vma;
+typedef BFD_HOST_U_64_BIT bfd_size_type;
+typedef BFD_HOST_U_64_BIT symvalue;
+
+#ifndef fprintf_vma
+#if BFD_HOST_64BIT_LONG
+#define sprintf_vma(s,x) sprintf (s, "%016lx", x)
+#define fprintf_vma(f,x) fprintf (f, "%016lx", x)
+#else
+#define _bfd_int64_low(x) ((unsigned long) (((x) & 0xffffffff)))
+#define _bfd_int64_high(x) ((unsigned long) (((x) >> 32) & 0xffffffff))
+#define fprintf_vma(s,x) \
+  fprintf ((s), "%08lx%08lx", _bfd_int64_high (x), _bfd_int64_low (x))
+#define sprintf_vma(s,x) \
+  sprintf ((s), "%08lx%08lx", _bfd_int64_high (x), _bfd_int64_low (x))
+#endif
+#endif
+
+#else /* not BFD64  */
+
+/* Represent a target address.  Also used as a generic unsigned type
+   which is guaranteed to be big enough to hold any arithmetic types
+   we need to deal with.  */
+typedef unsigned long bfd_vma;
+
+/* A generic signed type which is guaranteed to be big enough to hold any
+   arithmetic types we need to deal with.  Can be assumed to be compatible
+   with bfd_vma in the same way that signed and unsigned ints are compatible
+   (as parameters, in assignment, etc).  */
+typedef long bfd_signed_vma;
+
+typedef unsigned long symvalue;
+typedef unsigned long bfd_size_type;
+
+/* Print a bfd_vma x on stream s.  */
+#define fprintf_vma(s,x) fprintf (s, "%08lx", x)
+#define sprintf_vma(s,x) sprintf (s, "%08lx", x)
+
+#endif /* not BFD64  */
+
+/* A pointer to a position in a file.  */
+/* FIXME:  This should be using off_t from <sys/types.h>.
+   For now, try to avoid breaking stuff by not including <sys/types.h> here.
+   This will break on systems with 64-bit file offsets (e.g. 4.4BSD).
+   Probably the best long-term answer is to avoid using file_ptr AND off_t
+   in this header file, and to handle this in the BFD implementation
+   rather than in its interface.  */
+/* typedef off_t       file_ptr; */
+typedef bfd_signed_vma file_ptr;
+typedef bfd_vma ufile_ptr;
+
+extern void bfd_sprintf_vma
+  PARAMS ((bfd *, char *, bfd_vma));
+extern void bfd_fprintf_vma
+  PARAMS ((bfd *, PTR, bfd_vma));
+
+#define printf_vma(x) fprintf_vma(stdout,x)
+#define bfd_printf_vma(abfd,x) bfd_fprintf_vma (abfd,stdout,x)
+
+typedef unsigned int flagword; /* 32 bits of flags */
+typedef unsigned char bfd_byte;
+\f
+/* File formats.  */
+
+typedef enum bfd_format
+{
+  bfd_unknown = 0,     /* File format is unknown.  */
+  bfd_object,          /* Linker/assember/compiler output.  */
+  bfd_archive,         /* Object archive file.  */
+  bfd_core,            /* Core dump.  */
+  bfd_type_end         /* Marks the end; don't use it!  */
+}
+bfd_format;
+
+/* Values that may appear in the flags field of a BFD.  These also
+   appear in the object_flags field of the bfd_target structure, where
+   they indicate the set of flags used by that backend (not all flags
+   are meaningful for all object file formats) (FIXME: at the moment,
+   the object_flags values have mostly just been copied from backend
+   to another, and are not necessarily correct).  */
+
+/* No flags.  */
+#define BFD_NO_FLAGS           0x00
+
+/* BFD contains relocation entries.  */
+#define HAS_RELOC      0x01
+
+/* BFD is directly executable.  */
+#define EXEC_P         0x02
+
+/* BFD has line number information (basically used for F_LNNO in a
+   COFF header).  */
+#define HAS_LINENO     0x04
+
+/* BFD has debugging information.  */
+#define HAS_DEBUG      0x08
+
+/* BFD has symbols.  */
+#define HAS_SYMS       0x10
+
+/* BFD has local symbols (basically used for F_LSYMS in a COFF
+   header).  */
+#define HAS_LOCALS     0x20
+
+/* BFD is a dynamic object.  */
+#define DYNAMIC        0x40
+
+/* Text section is write protected (if D_PAGED is not set, this is
+   like an a.out NMAGIC file) (the linker sets this by default, but
+   clears it for -r or -N).  */
+#define WP_TEXT        0x80
+
+/* BFD is dynamically paged (this is like an a.out ZMAGIC file) (the
+   linker sets this by default, but clears it for -r or -n or -N).  */
+#define D_PAGED        0x100
+
+/* BFD is relaxable (this means that bfd_relax_section may be able to
+   do something) (sometimes bfd_relax_section can do something even if
+   this is not set).  */
+#define BFD_IS_RELAXABLE 0x200
+
+/* This may be set before writing out a BFD to request using a
+   traditional format.  For example, this is used to request that when
+   writing out an a.out object the symbols not be hashed to eliminate
+   duplicates.  */
+#define BFD_TRADITIONAL_FORMAT 0x400
+
+/* This flag indicates that the BFD contents are actually cached in
+   memory.  If this is set, iostream points to a bfd_in_memory struct.  */
+#define BFD_IN_MEMORY 0x800
+
+/* The sections in this BFD specify a memory page.  */
+#define HAS_LOAD_PAGE 0x1000
+\f
+/* Symbols and relocation.  */
+
+/* A count of carsyms (canonical archive symbols).  */
+typedef unsigned long symindex;
+
+/* How to perform a relocation.  */
+typedef const struct reloc_howto_struct reloc_howto_type;
+
+#define BFD_NO_MORE_SYMBOLS ((symindex) ~0)
+
+/* General purpose part of a symbol X;
+   target specific parts are in libcoff.h, libaout.h, etc.  */
+
+#define bfd_get_section(x) ((x)->section)
+#define bfd_get_output_section(x) ((x)->section->output_section)
+#define bfd_set_section(x,y) ((x)->section) = (y)
+#define bfd_asymbol_base(x) ((x)->section->vma)
+#define bfd_asymbol_value(x) (bfd_asymbol_base(x) + (x)->value)
+#define bfd_asymbol_name(x) ((x)->name)
+/*Perhaps future: #define bfd_asymbol_bfd(x) ((x)->section->owner)*/
+#define bfd_asymbol_bfd(x) ((x)->the_bfd)
+#define bfd_asymbol_flavour(x) (bfd_asymbol_bfd(x)->xvec->flavour)
+
+/* A canonical archive symbol.  */
+/* This is a type pun with struct ranlib on purpose!  */
+typedef struct carsym
+{
+  char *name;
+  file_ptr file_offset;        /* Look here to find the file.  */
+}
+carsym;                        /* To make these you call a carsymogen.  */
+
+/* Used in generating armaps (archive tables of contents).
+   Perhaps just a forward definition would do?  */
+struct orl                     /* Output ranlib.  */
+{
+  char **name;         /* Symbol name.  */
+  union
+  {
+    file_ptr pos;
+    bfd *abfd;
+  } u;                 /* bfd* or file position.  */
+  int namidx;          /* Index into string table.  */
+};
+\f
+/* Linenumber stuff.  */
+typedef struct lineno_cache_entry
+{
+  unsigned int line_number;    /* Linenumber from start of function.  */
+  union
+  {
+    struct symbol_cache_entry *sym;    /* Function name.  */
+    bfd_vma offset;                    /* Offset into section.  */
+  } u;
+}
+alent;
+\f
+/* Object and core file sections.  */
+
+#define        align_power(addr, align)        \
+  (((addr) + ((bfd_vma) 1 << (align)) - 1) & ((bfd_vma) -1 << (align)))
+
+typedef struct sec *sec_ptr;
+
+#define bfd_get_section_name(bfd, ptr) ((ptr)->name + 0)
+#define bfd_get_section_vma(bfd, ptr) ((ptr)->vma + 0)
+#define bfd_get_section_lma(bfd, ptr) ((ptr)->lma + 0)
+#define bfd_get_section_alignment(bfd, ptr) ((ptr)->alignment_power + 0)
+#define bfd_section_name(bfd, ptr) ((ptr)->name)
+#define bfd_section_size(bfd, ptr) (bfd_get_section_size_before_reloc(ptr))
+#define bfd_section_vma(bfd, ptr) ((ptr)->vma)
+#define bfd_section_lma(bfd, ptr) ((ptr)->lma)
+#define bfd_section_alignment(bfd, ptr) ((ptr)->alignment_power)
+#define bfd_get_section_flags(bfd, ptr) ((ptr)->flags + 0)
+#define bfd_get_section_userdata(bfd, ptr) ((ptr)->userdata)
+
+#define bfd_is_com_section(ptr) (((ptr)->flags & SEC_IS_COMMON) != 0)
+
+#define bfd_set_section_vma(bfd, ptr, val) (((ptr)->vma = (ptr)->lma = (val)), ((ptr)->user_set_vma = TRUE), TRUE)
+#define bfd_set_section_alignment(bfd, ptr, val) (((ptr)->alignment_power = (val)),TRUE)
+#define bfd_set_section_userdata(bfd, ptr, val) (((ptr)->userdata = (val)),TRUE)
+
+typedef struct stat stat_type;
+\f
+typedef enum bfd_print_symbol
+{
+  bfd_print_symbol_name,
+  bfd_print_symbol_more,
+  bfd_print_symbol_all
+} bfd_print_symbol_type;
+
+/* Information about a symbol that nm needs.  */
+
+typedef struct _symbol_info
+{
+  symvalue value;
+  char type;
+  const char *name;            /* Symbol name.  */
+  unsigned char stab_type;     /* Stab type.  */
+  char stab_other;             /* Stab other.  */
+  short stab_desc;             /* Stab desc.  */
+  const char *stab_name;       /* String for stab type.  */
+} symbol_info;
+
+/* Get the name of a stabs type code.  */
+
+extern const char *bfd_get_stab_name
+  PARAMS ((int));
+\f
+/* Hash table routines.  There is no way to free up a hash table.  */
+
+/* An element in the hash table.  Most uses will actually use a larger
+   structure, and an instance of this will be the first field.  */
+
+struct bfd_hash_entry
+{
+  /* Next entry for this hash code.  */
+  struct bfd_hash_entry *next;
+  /* String being hashed.  */
+  const char *string;
+  /* Hash code.  This is the full hash code, not the index into the
+     table.  */
+  unsigned long hash;
+};
+
+/* A hash table.  */
+
+struct bfd_hash_table
+{
+  /* The hash array.  */
+  struct bfd_hash_entry **table;
+  /* The number of slots in the hash table.  */
+  unsigned int size;
+  /* A function used to create new elements in the hash table.  The
+     first entry is itself a pointer to an element.  When this
+     function is first invoked, this pointer will be NULL.  However,
+     having the pointer permits a hierarchy of method functions to be
+     built each of which calls the function in the superclass.  Thus
+     each function should be written to allocate a new block of memory
+     only if the argument is NULL.  */
+  struct bfd_hash_entry *(*newfunc)
+    PARAMS ((struct bfd_hash_entry *, struct bfd_hash_table *, const char *));
+   /* An objalloc for this hash table.  This is a struct objalloc *,
+     but we use PTR to avoid requiring the inclusion of objalloc.h.  */
+  PTR memory;
+};
+
+/* Initialize a hash table.  */
+extern bfd_boolean bfd_hash_table_init
+  PARAMS ((struct bfd_hash_table *,
+          struct bfd_hash_entry *(*) (struct bfd_hash_entry *,
+                                      struct bfd_hash_table *,
+                                      const char *)));
+
+/* Initialize a hash table specifying a size.  */
+extern bfd_boolean bfd_hash_table_init_n
+  PARAMS ((struct bfd_hash_table *,
+          struct bfd_hash_entry *(*) (struct bfd_hash_entry *,
+                                      struct bfd_hash_table *,
+                                      const char *),
+          unsigned int size));
+
+/* Free up a hash table.  */
+extern void bfd_hash_table_free
+  PARAMS ((struct bfd_hash_table *));
+
+/* Look up a string in a hash table.  If CREATE is TRUE, a new entry
+   will be created for this string if one does not already exist.  The
+   COPY argument must be TRUE if this routine should copy the string
+   into newly allocated memory when adding an entry.  */
+extern struct bfd_hash_entry *bfd_hash_lookup
+  PARAMS ((struct bfd_hash_table *, const char *, bfd_boolean create,
+          bfd_boolean copy));
+
+/* Replace an entry in a hash table.  */
+extern void bfd_hash_replace
+  PARAMS ((struct bfd_hash_table *, struct bfd_hash_entry *old,
+          struct bfd_hash_entry *nw));
+
+/* Base method for creating a hash table entry.  */
+extern struct bfd_hash_entry *bfd_hash_newfunc
+  PARAMS ((struct bfd_hash_entry *, struct bfd_hash_table *,
+          const char *));
+
+/* Grab some space for a hash table entry.  */
+extern PTR bfd_hash_allocate
+  PARAMS ((struct bfd_hash_table *, unsigned int));
+
+/* Traverse a hash table in a random order, calling a function on each
+   element.  If the function returns FALSE, the traversal stops.  The
+   INFO argument is passed to the function.  */
+extern void bfd_hash_traverse
+  PARAMS ((struct bfd_hash_table *,
+          bfd_boolean (*) (struct bfd_hash_entry *, PTR),
+          PTR info));
+
+#define COFF_SWAP_TABLE (PTR) &bfd_coff_std_swap_table
+
+/* User program access to BFD facilities.  */
+
+/* Direct I/O routines, for programs which know more about the object
+   file than BFD does.  Use higher level routines if possible.  */
+
+extern bfd_size_type bfd_bread
+  PARAMS ((PTR, bfd_size_type, bfd *));
+extern bfd_size_type bfd_bwrite
+  PARAMS ((const PTR, bfd_size_type, bfd *));
+extern int bfd_seek
+  PARAMS ((bfd *, file_ptr, int));
+extern ufile_ptr bfd_tell
+  PARAMS ((bfd *));
+extern int bfd_flush
+  PARAMS ((bfd *));
+extern int bfd_stat
+  PARAMS ((bfd *, struct stat *));
+
+/* Deprecated old routines.  */
+#if __GNUC__
+#define bfd_read(BUF, ELTSIZE, NITEMS, ABFD)                           \
+  (warn_deprecated ("bfd_read", __FILE__, __LINE__, __FUNCTION__),     \
+   bfd_bread ((BUF), (ELTSIZE) * (NITEMS), (ABFD)))
+#define bfd_write(BUF, ELTSIZE, NITEMS, ABFD)                          \
+  (warn_deprecated ("bfd_write", __FILE__, __LINE__, __FUNCTION__),    \
+   bfd_bwrite ((BUF), (ELTSIZE) * (NITEMS), (ABFD)))
+#else
+#define bfd_read(BUF, ELTSIZE, NITEMS, ABFD)                           \
+  (warn_deprecated ("bfd_read", (const char *) 0, 0, (const char *) 0), \
+   bfd_bread ((BUF), (ELTSIZE) * (NITEMS), (ABFD)))
+#define bfd_write(BUF, ELTSIZE, NITEMS, ABFD)                          \
+  (warn_deprecated ("bfd_write", (const char *) 0, 0, (const char *) 0),\
+   bfd_bwrite ((BUF), (ELTSIZE) * (NITEMS), (ABFD)))
+#endif
+extern void warn_deprecated
+  PARAMS ((const char *, const char *, int, const char *));
+
+/* Cast from const char * to char * so that caller can assign to
+   a char * without a warning.  */
+#define bfd_get_filename(abfd) ((char *) (abfd)->filename)
+#define bfd_get_cacheable(abfd) ((abfd)->cacheable)
+#define bfd_get_format(abfd) ((abfd)->format)
+#define bfd_get_target(abfd) ((abfd)->xvec->name)
+#define bfd_get_flavour(abfd) ((abfd)->xvec->flavour)
+#define bfd_family_coff(abfd) \
+  (bfd_get_flavour (abfd) == bfd_target_coff_flavour || \
+   bfd_get_flavour (abfd) == bfd_target_xcoff_flavour)
+#define bfd_big_endian(abfd) ((abfd)->xvec->byteorder == BFD_ENDIAN_BIG)
+#define bfd_little_endian(abfd) ((abfd)->xvec->byteorder == BFD_ENDIAN_LITTLE)
+#define bfd_header_big_endian(abfd) \
+  ((abfd)->xvec->header_byteorder == BFD_ENDIAN_BIG)
+#define bfd_header_little_endian(abfd) \
+  ((abfd)->xvec->header_byteorder == BFD_ENDIAN_LITTLE)
+#define bfd_get_file_flags(abfd) ((abfd)->flags)
+#define bfd_applicable_file_flags(abfd) ((abfd)->xvec->object_flags)
+#define bfd_applicable_section_flags(abfd) ((abfd)->xvec->section_flags)
+#define bfd_my_archive(abfd) ((abfd)->my_archive)
+#define bfd_has_map(abfd) ((abfd)->has_armap)
+
+#define bfd_valid_reloc_types(abfd) ((abfd)->xvec->valid_reloc_types)
+#define bfd_usrdata(abfd) ((abfd)->usrdata)
+
+#define bfd_get_start_address(abfd) ((abfd)->start_address)
+#define bfd_get_symcount(abfd) ((abfd)->symcount)
+#define bfd_get_outsymbols(abfd) ((abfd)->outsymbols)
+#define bfd_count_sections(abfd) ((abfd)->section_count)
+
+#define bfd_get_dynamic_symcount(abfd) ((abfd)->dynsymcount)
+
+#define bfd_get_symbol_leading_char(abfd) ((abfd)->xvec->symbol_leading_char)
+
+#define bfd_set_cacheable(abfd,bool) (((abfd)->cacheable = bool), TRUE)
+
+extern bfd_boolean bfd_cache_close
+  PARAMS ((bfd *abfd));
+/* NB: This declaration should match the autogenerated one in libbfd.h.  */
+
+extern bfd_boolean bfd_record_phdr
+  PARAMS ((bfd *, unsigned long, bfd_boolean, flagword, bfd_boolean, bfd_vma,
+          bfd_boolean, bfd_boolean, unsigned int, struct sec **));
+
+/* Byte swapping routines.  */
+
+bfd_vma bfd_getb64
+  PARAMS ((const unsigned char *));
+bfd_vma bfd_getl64
+  PARAMS ((const unsigned char *));
+bfd_signed_vma bfd_getb_signed_64
+  PARAMS ((const unsigned char *));
+bfd_signed_vma bfd_getl_signed_64
+  PARAMS ((const unsigned char *));
+bfd_vma bfd_getb32
+  PARAMS ((const unsigned char *));
+bfd_vma bfd_getl32
+  PARAMS ((const unsigned char *));
+bfd_signed_vma bfd_getb_signed_32
+  PARAMS ((const unsigned char *));
+bfd_signed_vma bfd_getl_signed_32
+  PARAMS ((const unsigned char *));
+bfd_vma bfd_getb16
+  PARAMS ((const unsigned char *));
+bfd_vma bfd_getl16
+  PARAMS ((const unsigned char *));
+bfd_signed_vma bfd_getb_signed_16
+  PARAMS ((const unsigned char *));
+bfd_signed_vma bfd_getl_signed_16
+  PARAMS ((const unsigned char *));
+void bfd_putb64
+  PARAMS ((bfd_vma, unsigned char *));
+void bfd_putl64
+  PARAMS ((bfd_vma, unsigned char *));
+void bfd_putb32
+  PARAMS ((bfd_vma, unsigned char *));
+void bfd_putl32
+  PARAMS ((bfd_vma, unsigned char *));
+void bfd_putb16
+  PARAMS ((bfd_vma, unsigned char *));
+void bfd_putl16
+  PARAMS ((bfd_vma, unsigned char *));
+
+/* Byte swapping routines which take size and endiannes as arguments.  */
+
+bfd_vma bfd_get_bits
+  PARAMS ((bfd_byte *, int, bfd_boolean));
+void bfd_put_bits
+  PARAMS ((bfd_vma, bfd_byte *, int, bfd_boolean));
+\f
+/* Externally visible ECOFF routines.  */
+
+#if defined(__STDC__) || defined(ALMOST_STDC)
+struct ecoff_debug_info;
+struct ecoff_debug_swap;
+struct ecoff_extr;
+struct symbol_cache_entry;
+struct bfd_link_info;
+struct bfd_link_hash_entry;
+struct bfd_elf_version_tree;
+#endif
+extern bfd_vma bfd_ecoff_get_gp_value
+  PARAMS ((bfd * abfd));
+extern bfd_boolean bfd_ecoff_set_gp_value
+  PARAMS ((bfd *abfd, bfd_vma gp_value));
+extern bfd_boolean bfd_ecoff_set_regmasks
+  PARAMS ((bfd *abfd, unsigned long gprmask, unsigned long fprmask,
+          unsigned long *cprmask));
+extern PTR bfd_ecoff_debug_init
+  PARAMS ((bfd *output_bfd, struct ecoff_debug_info *output_debug,
+          const struct ecoff_debug_swap *output_swap,
+          struct bfd_link_info *));
+extern void bfd_ecoff_debug_free
+  PARAMS ((PTR handle, bfd *output_bfd, struct ecoff_debug_info *output_debug,
+          const struct ecoff_debug_swap *output_swap,
+          struct bfd_link_info *));
+extern bfd_boolean bfd_ecoff_debug_accumulate
+  PARAMS ((PTR handle, bfd *output_bfd, struct ecoff_debug_info *output_debug,
+          const struct ecoff_debug_swap *output_swap,
+          bfd *input_bfd, struct ecoff_debug_info *input_debug,
+          const struct ecoff_debug_swap *input_swap,
+          struct bfd_link_info *));
+extern bfd_boolean bfd_ecoff_debug_accumulate_other
+  PARAMS ((PTR handle, bfd *output_bfd, struct ecoff_debug_info *output_debug,
+          const struct ecoff_debug_swap *output_swap, bfd *input_bfd,
+          struct bfd_link_info *));
+extern bfd_boolean bfd_ecoff_debug_externals
+  PARAMS ((bfd *abfd, struct ecoff_debug_info *debug,
+          const struct ecoff_debug_swap *swap,
+          bfd_boolean relocateable,
+          bfd_boolean (*get_extr) (struct symbol_cache_entry *,
+                                   struct ecoff_extr *),
+          void (*set_index) (struct symbol_cache_entry *,
+                             bfd_size_type)));
+extern bfd_boolean bfd_ecoff_debug_one_external
+  PARAMS ((bfd *abfd, struct ecoff_debug_info *debug,
+          const struct ecoff_debug_swap *swap,
+          const char *name, struct ecoff_extr *esym));
+extern bfd_size_type bfd_ecoff_debug_size
+  PARAMS ((bfd *abfd, struct ecoff_debug_info *debug,
+          const struct ecoff_debug_swap *swap));
+extern bfd_boolean bfd_ecoff_write_debug
+  PARAMS ((bfd *abfd, struct ecoff_debug_info *debug,
+          const struct ecoff_debug_swap *swap, file_ptr where));
+extern bfd_boolean bfd_ecoff_write_accumulated_debug
+  PARAMS ((PTR handle, bfd *abfd, struct ecoff_debug_info *debug,
+          const struct ecoff_debug_swap *swap,
+          struct bfd_link_info *info, file_ptr where));
+extern bfd_boolean bfd_mips_ecoff_create_embedded_relocs
+  PARAMS ((bfd *, struct bfd_link_info *, struct sec *, struct sec *,
+          char **));
+
+/* Externally visible ELF routines.  */
+
+struct bfd_link_needed_list
+{
+  struct bfd_link_needed_list *next;
+  bfd *by;
+  const char *name;
+};
+
+extern bfd_boolean bfd_elf32_record_link_assignment
+  PARAMS ((bfd *, struct bfd_link_info *, const char *, bfd_boolean));
+extern bfd_boolean bfd_elf64_record_link_assignment
+  PARAMS ((bfd *, struct bfd_link_info *, const char *, bfd_boolean));
+extern struct bfd_link_needed_list *bfd_elf_get_needed_list
+  PARAMS ((bfd *, struct bfd_link_info *));
+extern bfd_boolean bfd_elf_get_bfd_needed_list
+  PARAMS ((bfd *, struct bfd_link_needed_list **));
+extern bfd_boolean bfd_elf32_size_dynamic_sections
+  PARAMS ((bfd *, const char *, const char *, const char *,
+          const char * const *, struct bfd_link_info *, struct sec **,
+          struct bfd_elf_version_tree *));
+extern bfd_boolean bfd_elf64_size_dynamic_sections
+  PARAMS ((bfd *, const char *, const char *, const char *,
+          const char * const *, struct bfd_link_info *, struct sec **,
+          struct bfd_elf_version_tree *));
+extern void bfd_elf_set_dt_needed_name
+  PARAMS ((bfd *, const char *));
+extern void bfd_elf_set_dt_needed_soname
+  PARAMS ((bfd *, const char *));
+extern const char *bfd_elf_get_dt_soname
+  PARAMS ((bfd *));
+extern struct bfd_link_needed_list *bfd_elf_get_runpath_list
+  PARAMS ((bfd *, struct bfd_link_info *));
+extern bfd_boolean bfd_elf32_discard_info
+  PARAMS ((bfd *, struct bfd_link_info *));
+extern bfd_boolean bfd_elf64_discard_info
+  PARAMS ((bfd *, struct bfd_link_info *));
+
+/* Return an upper bound on the number of bytes required to store a
+   copy of ABFD's program header table entries.  Return -1 if an error
+   occurs; bfd_get_error will return an appropriate code.  */
+extern long bfd_get_elf_phdr_upper_bound
+  PARAMS ((bfd *abfd));
+
+/* Copy ABFD's program header table entries to *PHDRS.  The entries
+   will be stored as an array of Elf_Internal_Phdr structures, as
+   defined in include/elf/internal.h.  To find out how large the
+   buffer needs to be, call bfd_get_elf_phdr_upper_bound.
+
+   Return the number of program header table entries read, or -1 if an
+   error occurs; bfd_get_error will return an appropriate code.  */
+extern int bfd_get_elf_phdrs
+  PARAMS ((bfd *abfd, void *phdrs));
+
+/* Return the arch_size field of an elf bfd, or -1 if not elf.  */
+extern int bfd_get_arch_size
+  PARAMS ((bfd *));
+
+/* Return TRUE if address "naturally" sign extends, or -1 if not elf.  */
+extern int bfd_get_sign_extend_vma
+  PARAMS ((bfd *));
+
+extern bfd_boolean bfd_m68k_elf32_create_embedded_relocs
+  PARAMS ((bfd *, struct bfd_link_info *, struct sec *, struct sec *,
+          char **));
+extern bfd_boolean bfd_mips_elf32_create_embedded_relocs
+  PARAMS ((bfd *, struct bfd_link_info *, struct sec *, struct sec *,
+          char **));
+
+/* SunOS shared library support routines for the linker.  */
+
+extern struct bfd_link_needed_list *bfd_sunos_get_needed_list
+  PARAMS ((bfd *, struct bfd_link_info *));
+extern bfd_boolean bfd_sunos_record_link_assignment
+  PARAMS ((bfd *, struct bfd_link_info *, const char *));
+extern bfd_boolean bfd_sunos_size_dynamic_sections
+  PARAMS ((bfd *, struct bfd_link_info *, struct sec **, struct sec **,
+          struct sec **));
+
+/* Linux shared library support routines for the linker.  */
+
+extern bfd_boolean bfd_i386linux_size_dynamic_sections
+  PARAMS ((bfd *, struct bfd_link_info *));
+extern bfd_boolean bfd_m68klinux_size_dynamic_sections
+  PARAMS ((bfd *, struct bfd_link_info *));
+extern bfd_boolean bfd_sparclinux_size_dynamic_sections
+  PARAMS ((bfd *, struct bfd_link_info *));
+
+/* mmap hacks */
+
+struct _bfd_window_internal;
+typedef struct _bfd_window_internal bfd_window_internal;
+
+typedef struct _bfd_window
+{
+  /* What the user asked for.  */
+  PTR data;
+  bfd_size_type size;
+  /* The actual window used by BFD.  Small user-requested read-only
+     regions sharing a page may share a single window into the object
+     file.  Read-write versions shouldn't until I've fixed things to
+     keep track of which portions have been claimed by the
+     application; don't want to give the same region back when the
+     application wants two writable copies!  */
+  struct _bfd_window_internal *i;
+}
+bfd_window;
+
+extern void bfd_init_window
+  PARAMS ((bfd_window *));
+extern void bfd_free_window
+  PARAMS ((bfd_window *));
+extern bfd_boolean bfd_get_file_window
+  PARAMS ((bfd *, file_ptr, bfd_size_type, bfd_window *, bfd_boolean));
+
+/* XCOFF support routines for the linker.  */
+
+extern bfd_boolean bfd_xcoff_link_record_set
+  PARAMS ((bfd *, struct bfd_link_info *, struct bfd_link_hash_entry *,
+          bfd_size_type));
+extern bfd_boolean bfd_xcoff_import_symbol
+  PARAMS ((bfd *, struct bfd_link_info *, struct bfd_link_hash_entry *,
+          bfd_vma, const char *, const char *, const char *, unsigned int));
+extern bfd_boolean bfd_xcoff_export_symbol
+  PARAMS ((bfd *, struct bfd_link_info *, struct bfd_link_hash_entry *));
+extern bfd_boolean bfd_xcoff_link_count_reloc
+  PARAMS ((bfd *, struct bfd_link_info *, const char *));
+extern bfd_boolean bfd_xcoff_record_link_assignment
+  PARAMS ((bfd *, struct bfd_link_info *, const char *));
+extern bfd_boolean bfd_xcoff_size_dynamic_sections
+  PARAMS ((bfd *, struct bfd_link_info *, const char *, const char *,
+          unsigned long, unsigned long, unsigned long, bfd_boolean,
+          int, bfd_boolean, bfd_boolean, struct sec **, bfd_boolean));
+extern bfd_boolean bfd_xcoff_link_generate_rtinit
+  PARAMS ((bfd *, const char *, const char *, bfd_boolean));
+
+/* XCOFF support routines for ar.  */
+extern bfd_boolean bfd_xcoff_ar_archive_set_magic
+  PARAMS ((bfd *, char *));
+
+/* Externally visible COFF routines.  */
+
+#if defined(__STDC__) || defined(ALMOST_STDC)
+struct internal_syment;
+union internal_auxent;
+#endif
+
+extern bfd_boolean bfd_coff_get_syment
+  PARAMS ((bfd *, struct symbol_cache_entry *, struct internal_syment *));
+
+extern bfd_boolean bfd_coff_get_auxent
+  PARAMS ((bfd *, struct symbol_cache_entry *, int, union internal_auxent *));
+
+extern bfd_boolean bfd_coff_set_symbol_class
+  PARAMS ((bfd *, struct symbol_cache_entry *, unsigned int));
+
+extern bfd_boolean bfd_m68k_coff_create_embedded_relocs
+  PARAMS ((bfd *, struct bfd_link_info *, struct sec *, struct sec *,
+          char **));
+
+/* ARM Interworking support.  Called from linker.  */
+extern bfd_boolean bfd_arm_allocate_interworking_sections
+  PARAMS ((struct bfd_link_info *));
+
+extern bfd_boolean bfd_arm_process_before_allocation
+  PARAMS ((bfd *, struct bfd_link_info *, int));
+
+extern bfd_boolean bfd_arm_get_bfd_for_interworking
+  PARAMS ((bfd *, struct bfd_link_info *));
+
+/* PE ARM Interworking support.  Called from linker.  */
+extern bfd_boolean bfd_arm_pe_allocate_interworking_sections
+  PARAMS ((struct bfd_link_info *));
+
+extern bfd_boolean bfd_arm_pe_process_before_allocation
+  PARAMS ((bfd *, struct bfd_link_info *, int));
+
+extern bfd_boolean bfd_arm_pe_get_bfd_for_interworking
+  PARAMS ((bfd *, struct bfd_link_info *));
+
+/* ELF ARM Interworking support.  Called from linker.  */
+extern bfd_boolean bfd_elf32_arm_allocate_interworking_sections
+  PARAMS ((struct bfd_link_info *));
+
+extern bfd_boolean bfd_elf32_arm_process_before_allocation
+  PARAMS ((bfd *, struct bfd_link_info *, int));
+
+extern bfd_boolean bfd_elf32_arm_get_bfd_for_interworking
+  PARAMS ((bfd *, struct bfd_link_info *));
+
+extern bfd_boolean bfd_elf32_arm_add_glue_sections_to_bfd
+  PARAMS ((bfd *, struct bfd_link_info *));
+
+/* ARM Note section processing.  */
+extern bfd_boolean bfd_arm_merge_machines
+  PARAMS ((bfd *, bfd *));
+
+extern bfd_boolean bfd_arm_update_notes
+  PARAMS ((bfd *, const char *));
+
+extern unsigned int bfd_arm_get_mach_from_notes
+  PARAMS ((bfd *, const char *));
+
+/* TI COFF load page support.  */
+extern void bfd_ticoff_set_section_load_page
+  PARAMS ((struct sec *, int));
+
+extern int bfd_ticoff_get_section_load_page
+  PARAMS ((struct sec *));
+
+/* Extracted from init.c.  */
+void
+bfd_init PARAMS ((void));
+
+/* Extracted from opncls.c.  */
+bfd *
+bfd_openr PARAMS ((const char *filename, const char *target));
+
+bfd *
+bfd_fdopenr PARAMS ((const char *filename, const char *target, int fd));
+
+bfd *
+bfd_openstreamr PARAMS ((const char *, const char *, PTR));
+
+bfd *
+bfd_openw PARAMS ((const char *filename, const char *target));
+
+bfd_boolean
+bfd_close PARAMS ((bfd *abfd));
+
+bfd_boolean
+bfd_close_all_done PARAMS ((bfd *));
+
+bfd *
+bfd_create PARAMS ((const char *filename, bfd *templ));
+
+bfd_boolean
+bfd_make_writable PARAMS ((bfd *abfd));
+
+bfd_boolean
+bfd_make_readable PARAMS ((bfd *abfd));
+
+char *
+bfd_follow_gnu_debuglink PARAMS ((bfd *abfd, const char *dir));
+
+/* Extracted from libbfd.c.  */
+
+/* Byte swapping macros for user section data.  */
+
+#define bfd_put_8(abfd, val, ptr) \
+                ((void) (*((unsigned char *) (ptr)) = (unsigned char) (val)))
+#define bfd_put_signed_8 \
+               bfd_put_8
+#define bfd_get_8(abfd, ptr) \
+                (*(unsigned char *) (ptr) & 0xff)
+#define bfd_get_signed_8(abfd, ptr) \
+               (((*(unsigned char *) (ptr) & 0xff) ^ 0x80) - 0x80)
+
+#define bfd_put_16(abfd, val, ptr) \
+                BFD_SEND(abfd, bfd_putx16, ((val),(ptr)))
+#define bfd_put_signed_16 \
+                bfd_put_16
+#define bfd_get_16(abfd, ptr) \
+                BFD_SEND(abfd, bfd_getx16, (ptr))
+#define bfd_get_signed_16(abfd, ptr) \
+                BFD_SEND (abfd, bfd_getx_signed_16, (ptr))
+
+#define bfd_put_32(abfd, val, ptr) \
+                BFD_SEND(abfd, bfd_putx32, ((val),(ptr)))
+#define bfd_put_signed_32 \
+                bfd_put_32
+#define bfd_get_32(abfd, ptr) \
+                BFD_SEND(abfd, bfd_getx32, (ptr))
+#define bfd_get_signed_32(abfd, ptr) \
+                BFD_SEND(abfd, bfd_getx_signed_32, (ptr))
+
+#define bfd_put_64(abfd, val, ptr) \
+                BFD_SEND(abfd, bfd_putx64, ((val), (ptr)))
+#define bfd_put_signed_64 \
+                bfd_put_64
+#define bfd_get_64(abfd, ptr) \
+                BFD_SEND(abfd, bfd_getx64, (ptr))
+#define bfd_get_signed_64(abfd, ptr) \
+                BFD_SEND(abfd, bfd_getx_signed_64, (ptr))
+
+#define bfd_get(bits, abfd, ptr)                               \
+                ( (bits) ==  8 ? (bfd_vma) bfd_get_8 (abfd, ptr)       \
+                : (bits) == 16 ? bfd_get_16 (abfd, ptr)        \
+                : (bits) == 32 ? bfd_get_32 (abfd, ptr)        \
+                : (bits) == 64 ? bfd_get_64 (abfd, ptr)        \
+                : (abort (), (bfd_vma) - 1))
+
+#define bfd_put(bits, abfd, val, ptr)                          \
+                ( (bits) ==  8 ? bfd_put_8  (abfd, val, ptr)   \
+                : (bits) == 16 ? bfd_put_16 (abfd, val, ptr)   \
+                : (bits) == 32 ? bfd_put_32 (abfd, val, ptr)   \
+                : (bits) == 64 ? bfd_put_64 (abfd, val, ptr)   \
+                : (abort (), (void) 0))
+
+
+/* Byte swapping macros for file header data.  */
+
+#define bfd_h_put_8(abfd, val, ptr) \
+  bfd_put_8 (abfd, val, ptr)
+#define bfd_h_put_signed_8(abfd, val, ptr) \
+  bfd_put_8 (abfd, val, ptr)
+#define bfd_h_get_8(abfd, ptr) \
+  bfd_get_8 (abfd, ptr)
+#define bfd_h_get_signed_8(abfd, ptr) \
+  bfd_get_signed_8 (abfd, ptr)
+
+#define bfd_h_put_16(abfd, val, ptr) \
+  BFD_SEND (abfd, bfd_h_putx16, (val, ptr))
+#define bfd_h_put_signed_16 \
+  bfd_h_put_16
+#define bfd_h_get_16(abfd, ptr) \
+  BFD_SEND (abfd, bfd_h_getx16, (ptr))
+#define bfd_h_get_signed_16(abfd, ptr) \
+  BFD_SEND (abfd, bfd_h_getx_signed_16, (ptr))
+
+#define bfd_h_put_32(abfd, val, ptr) \
+  BFD_SEND (abfd, bfd_h_putx32, (val, ptr))
+#define bfd_h_put_signed_32 \
+  bfd_h_put_32
+#define bfd_h_get_32(abfd, ptr) \
+  BFD_SEND (abfd, bfd_h_getx32, (ptr))
+#define bfd_h_get_signed_32(abfd, ptr) \
+  BFD_SEND (abfd, bfd_h_getx_signed_32, (ptr))
+
+#define bfd_h_put_64(abfd, val, ptr) \
+  BFD_SEND (abfd, bfd_h_putx64, (val, ptr))
+#define bfd_h_put_signed_64 \
+  bfd_h_put_64
+#define bfd_h_get_64(abfd, ptr) \
+  BFD_SEND (abfd, bfd_h_getx64, (ptr))
+#define bfd_h_get_signed_64(abfd, ptr) \
+  BFD_SEND (abfd, bfd_h_getx_signed_64, (ptr))
+
+/* Refinements on the above, which should eventually go away.  Save
+   cluttering the source with (bfd_vma) and (bfd_byte *) casts.  */
+
+#define H_PUT_64(abfd, val, where) \
+  bfd_h_put_64 ((abfd), (bfd_vma) (val), (bfd_byte *) (where))
+
+#define H_PUT_32(abfd, val, where) \
+  bfd_h_put_32 ((abfd), (bfd_vma) (val), (bfd_byte *) (where))
+
+#define H_PUT_16(abfd, val, where) \
+  bfd_h_put_16 ((abfd), (bfd_vma) (val), (bfd_byte *) (where))
+
+#define H_PUT_8 bfd_h_put_8
+
+#define H_PUT_S64(abfd, val, where) \
+  bfd_h_put_signed_64 ((abfd), (bfd_vma) (val), (bfd_byte *) (where))
+
+#define H_PUT_S32(abfd, val, where) \
+  bfd_h_put_signed_32 ((abfd), (bfd_vma) (val), (bfd_byte *) (where))
+
+#define H_PUT_S16(abfd, val, where) \
+  bfd_h_put_signed_16 ((abfd), (bfd_vma) (val), (bfd_byte *) (where))
+
+#define H_PUT_S8 bfd_h_put_signed_8
+
+#define H_GET_64(abfd, where) \
+  bfd_h_get_64 ((abfd), (bfd_byte *) (where))
+
+#define H_GET_32(abfd, where) \
+  bfd_h_get_32 ((abfd), (bfd_byte *) (where))
+
+#define H_GET_16(abfd, where) \
+  bfd_h_get_16 ((abfd), (bfd_byte *) (where))
+
+#define H_GET_8 bfd_h_get_8
+
+#define H_GET_S64(abfd, where) \
+  bfd_h_get_signed_64 ((abfd), (bfd_byte *) (where))
+
+#define H_GET_S32(abfd, where) \
+  bfd_h_get_signed_32 ((abfd), (bfd_byte *) (where))
+
+#define H_GET_S16(abfd, where) \
+  bfd_h_get_signed_16 ((abfd), (bfd_byte *) (where))
+
+#define H_GET_S8 bfd_h_get_signed_8
+
+
+/* Extracted from bfdio.c.  */
+long
+bfd_get_mtime PARAMS ((bfd *abfd));
+
+long
+bfd_get_size PARAMS ((bfd *abfd));
+
+/* Extracted from bfdwin.c.  */
+/* Extracted from section.c.  */
+/* This structure is used for a comdat section, as in PE.  A comdat
+   section is associated with a particular symbol.  When the linker
+   sees a comdat section, it keeps only one of the sections with a
+   given name and associated with a given symbol.  */
+
+struct bfd_comdat_info
+{
+  /* The name of the symbol associated with a comdat section.  */
+  const char *name;
+
+  /* The local symbol table index of the symbol associated with a
+     comdat section.  This is only meaningful to the object file format
+     specific code; it is not an index into the list returned by
+     bfd_canonicalize_symtab.  */
+  long symbol;
+};
+
+typedef struct sec
+{
+  /* The name of the section; the name isn't a copy, the pointer is
+     the same as that passed to bfd_make_section.  */
+  const char *name;
+
+  /* A unique sequence number.  */
+  int id;
+
+  /* Which section in the bfd; 0..n-1 as sections are created in a bfd.  */
+  int index;
+
+  /* The next section in the list belonging to the BFD, or NULL.  */
+  struct sec *next;
+
+  /* The field flags contains attributes of the section. Some
+     flags are read in from the object file, and some are
+     synthesized from other information.  */
+  flagword flags;
+
+#define SEC_NO_FLAGS   0x000
+
+  /* Tells the OS to allocate space for this section when loading.
+     This is clear for a section containing debug information only.  */
+#define SEC_ALLOC      0x001
+
+  /* Tells the OS to load the section from the file when loading.
+     This is clear for a .bss section.  */
+#define SEC_LOAD       0x002
+
+  /* The section contains data still to be relocated, so there is
+     some relocation information too.  */
+#define SEC_RELOC      0x004
+
+  /* ELF reserves 4 processor specific bits and 8 operating system
+     specific bits in sh_flags; at present we can get away with just
+     one in communicating between the assembler and BFD, but this
+     isn't a good long-term solution.  */
+#define SEC_ARCH_BIT_0 0x008
+
+  /* A signal to the OS that the section contains read only data.  */
+#define SEC_READONLY   0x010
+
+  /* The section contains code only.  */
+#define SEC_CODE       0x020
+
+  /* The section contains data only.  */
+#define SEC_DATA       0x040
+
+  /* The section will reside in ROM.  */
+#define SEC_ROM        0x080
+
+  /* The section contains constructor information. This section
+     type is used by the linker to create lists of constructors and
+     destructors used by <<g++>>. When a back end sees a symbol
+     which should be used in a constructor list, it creates a new
+     section for the type of name (e.g., <<__CTOR_LIST__>>), attaches
+     the symbol to it, and builds a relocation. To build the lists
+     of constructors, all the linker has to do is catenate all the
+     sections called <<__CTOR_LIST__>> and relocate the data
+     contained within - exactly the operations it would peform on
+     standard data.  */
+#define SEC_CONSTRUCTOR 0x100
+
+  /* The section has contents - a data section could be
+     <<SEC_ALLOC>> | <<SEC_HAS_CONTENTS>>; a debug section could be
+     <<SEC_HAS_CONTENTS>>  */
+#define SEC_HAS_CONTENTS 0x200
+
+  /* An instruction to the linker to not output the section
+     even if it has information which would normally be written.  */
+#define SEC_NEVER_LOAD 0x400
+
+  /* The section is a COFF shared library section.  This flag is
+     only for the linker.  If this type of section appears in
+     the input file, the linker must copy it to the output file
+     without changing the vma or size.  FIXME: Although this
+     was originally intended to be general, it really is COFF
+     specific (and the flag was renamed to indicate this).  It
+     might be cleaner to have some more general mechanism to
+     allow the back end to control what the linker does with
+     sections.  */
+#define SEC_COFF_SHARED_LIBRARY 0x800
+
+  /* The section contains thread local data.  */
+#define SEC_THREAD_LOCAL 0x1000
+
+  /* The section has GOT references.  This flag is only for the
+     linker, and is currently only used by the elf32-hppa back end.
+     It will be set if global offset table references were detected
+     in this section, which indicate to the linker that the section
+     contains PIC code, and must be handled specially when doing a
+     static link.  */
+#define SEC_HAS_GOT_REF 0x4000
+
+  /* The section contains common symbols (symbols may be defined
+     multiple times, the value of a symbol is the amount of
+     space it requires, and the largest symbol value is the one
+     used).  Most targets have exactly one of these (which we
+     translate to bfd_com_section_ptr), but ECOFF has two.  */
+#define SEC_IS_COMMON 0x8000
+
+  /* The section contains only debugging information.  For
+     example, this is set for ELF .debug and .stab sections.
+     strip tests this flag to see if a section can be
+     discarded.  */
+#define SEC_DEBUGGING 0x10000
+
+  /* The contents of this section are held in memory pointed to
+     by the contents field.  This is checked by bfd_get_section_contents,
+     and the data is retrieved from memory if appropriate.  */
+#define SEC_IN_MEMORY 0x20000
+
+  /* The contents of this section are to be excluded by the
+     linker for executable and shared objects unless those
+     objects are to be further relocated.  */
+#define SEC_EXCLUDE 0x40000
+
+  /* The contents of this section are to be sorted based on the sum of
+     the symbol and addend values specified by the associated relocation
+     entries.  Entries without associated relocation entries will be
+     appended to the end of the section in an unspecified order.  */
+#define SEC_SORT_ENTRIES 0x80000
+
+  /* When linking, duplicate sections of the same name should be
+     discarded, rather than being combined into a single section as
+     is usually done.  This is similar to how common symbols are
+     handled.  See SEC_LINK_DUPLICATES below.  */
+#define SEC_LINK_ONCE 0x100000
+
+  /* If SEC_LINK_ONCE is set, this bitfield describes how the linker
+     should handle duplicate sections.  */
+#define SEC_LINK_DUPLICATES 0x600000
+
+  /* This value for SEC_LINK_DUPLICATES means that duplicate
+     sections with the same name should simply be discarded.  */
+#define SEC_LINK_DUPLICATES_DISCARD 0x0
+
+  /* This value for SEC_LINK_DUPLICATES means that the linker
+     should warn if there are any duplicate sections, although
+     it should still only link one copy.  */
+#define SEC_LINK_DUPLICATES_ONE_ONLY 0x200000
+
+  /* This value for SEC_LINK_DUPLICATES means that the linker
+     should warn if any duplicate sections are a different size.  */
+#define SEC_LINK_DUPLICATES_SAME_SIZE 0x400000
+
+  /* This value for SEC_LINK_DUPLICATES means that the linker
+     should warn if any duplicate sections contain different
+     contents.  */
+#define SEC_LINK_DUPLICATES_SAME_CONTENTS 0x600000
+
+  /* This section was created by the linker as part of dynamic
+     relocation or other arcane processing.  It is skipped when
+     going through the first-pass output, trusting that someone
+     else up the line will take care of it later.  */
+#define SEC_LINKER_CREATED 0x800000
+
+  /* This section should not be subject to garbage collection.  */
+#define SEC_KEEP 0x1000000
+
+  /* This section contains "short" data, and should be placed
+     "near" the GP.  */
+#define SEC_SMALL_DATA 0x2000000
+
+  /* This section contains data which may be shared with other
+     executables or shared objects.  */
+#define SEC_SHARED 0x4000000
+
+  /* When a section with this flag is being linked, then if the size of
+     the input section is less than a page, it should not cross a page
+     boundary.  If the size of the input section is one page or more, it
+     should be aligned on a page boundary.  */
+#define SEC_BLOCK 0x8000000
+
+  /* Conditionally link this section; do not link if there are no
+     references found to any symbol in the section.  */
+#define SEC_CLINK 0x10000000
+
+  /* Attempt to merge identical entities in the section.
+     Entity size is given in the entsize field.  */
+#define SEC_MERGE 0x20000000
+
+  /* If given with SEC_MERGE, entities to merge are zero terminated
+     strings where entsize specifies character size instead of fixed
+     size entries.  */
+#define SEC_STRINGS 0x40000000
+
+  /* This section contains data about section groups.  */
+#define SEC_GROUP 0x80000000
+
+  /*  End of section flags.  */
+
+  /* Some internal packed boolean fields.  */
+
+  /* See the vma field.  */
+  unsigned int user_set_vma : 1;
+
+  /* Whether relocations have been processed.  */
+  unsigned int reloc_done : 1;
+
+  /* A mark flag used by some of the linker backends.  */
+  unsigned int linker_mark : 1;
+
+  /* Another mark flag used by some of the linker backends.  Set for
+     output sections that have an input section.  */
+  unsigned int linker_has_input : 1;
+
+  /* A mark flag used by some linker backends for garbage collection.  */
+  unsigned int gc_mark : 1;
+
+  /* The following flags are used by the ELF linker. */
+
+  /* Mark sections which have been allocated to segments.  */
+  unsigned int segment_mark : 1;
+
+  /* Type of sec_info information.  */
+  unsigned int sec_info_type:3;
+#define ELF_INFO_TYPE_NONE      0
+#define ELF_INFO_TYPE_STABS     1
+#define ELF_INFO_TYPE_MERGE     2
+#define ELF_INFO_TYPE_EH_FRAME  3
+#define ELF_INFO_TYPE_JUST_SYMS 4
+
+  /* Nonzero if this section uses RELA relocations, rather than REL.  */
+  unsigned int use_rela_p:1;
+
+  /* Bits used by various backends.  */
+  unsigned int has_tls_reloc:1;
+
+  /* Nonzero if this section needs the relax finalize pass.  */
+  unsigned int need_finalize_relax:1;
+
+  /* Usused bits.  */
+  unsigned int flag12:1;
+  unsigned int flag13:1;
+  unsigned int flag14:1;
+  unsigned int flag15:1;
+  unsigned int flag16:4;
+  unsigned int flag20:4;
+  unsigned int flag24:8;
+
+  /* End of internal packed boolean fields.  */
+
+  /*  The virtual memory address of the section - where it will be
+      at run time.  The symbols are relocated against this.  The
+      user_set_vma flag is maintained by bfd; if it's not set, the
+      backend can assign addresses (for example, in <<a.out>>, where
+      the default address for <<.data>> is dependent on the specific
+      target and various flags).  */
+  bfd_vma vma;
+
+  /*  The load address of the section - where it would be in a
+      rom image; really only used for writing section header
+      information.  */
+  bfd_vma lma;
+
+  /* The size of the section in octets, as it will be output.
+     Contains a value even if the section has no contents (e.g., the
+     size of <<.bss>>).  This will be filled in after relocation.  */
+  bfd_size_type _cooked_size;
+
+  /* The original size on disk of the section, in octets.  Normally this
+     value is the same as the size, but if some relaxing has
+     been done, then this value will be bigger.  */
+  bfd_size_type _raw_size;
+
+  /* If this section is going to be output, then this value is the
+     offset in *bytes* into the output section of the first byte in the
+     input section (byte ==> smallest addressable unit on the
+     target).  In most cases, if this was going to start at the
+     100th octet (8-bit quantity) in the output section, this value
+     would be 100.  However, if the target byte size is 16 bits
+     (bfd_octets_per_byte is "2"), this value would be 50.  */
+  bfd_vma output_offset;
+
+  /* The output section through which to map on output.  */
+  struct sec *output_section;
+
+  /* The alignment requirement of the section, as an exponent of 2 -
+     e.g., 3 aligns to 2^3 (or 8).  */
+  unsigned int alignment_power;
+
+  /* If an input section, a pointer to a vector of relocation
+     records for the data in this section.  */
+  struct reloc_cache_entry *relocation;
+
+  /* If an output section, a pointer to a vector of pointers to
+     relocation records for the data in this section.  */
+  struct reloc_cache_entry **orelocation;
+
+  /* The number of relocation records in one of the above.  */
+  unsigned reloc_count;
+
+  /* Information below is back end specific - and not always used
+     or updated.  */
+
+  /* File position of section data.  */
+  file_ptr filepos;
+
+  /* File position of relocation info.  */
+  file_ptr rel_filepos;
+
+  /* File position of line data.  */
+  file_ptr line_filepos;
+
+  /* Pointer to data for applications.  */
+  PTR userdata;
+
+  /* If the SEC_IN_MEMORY flag is set, this points to the actual
+     contents.  */
+  unsigned char *contents;
+
+  /* Attached line number information.  */
+  alent *lineno;
+
+  /* Number of line number records.  */
+  unsigned int lineno_count;
+
+  /* Entity size for merging purposes.  */
+  unsigned int entsize;
+
+  /* Optional information about a COMDAT entry; NULL if not COMDAT.  */
+  struct bfd_comdat_info *comdat;
+
+  /* When a section is being output, this value changes as more
+     linenumbers are written out.  */
+  file_ptr moving_line_filepos;
+
+  /* What the section number is in the target world.  */
+  int target_index;
+
+  PTR used_by_bfd;
+
+  /* If this is a constructor section then here is a list of the
+     relocations created to relocate items within it.  */
+  struct relent_chain *constructor_chain;
+
+  /* The BFD which owns the section.  */
+  bfd *owner;
+
+  /* A symbol which points at this section only.  */
+  struct symbol_cache_entry *symbol;
+  struct symbol_cache_entry **symbol_ptr_ptr;
+
+  struct bfd_link_order *link_order_head;
+  struct bfd_link_order *link_order_tail;
+} asection;
+
+/* These sections are global, and are managed by BFD.  The application
+   and target back end are not permitted to change the values in
+   these sections.  New code should use the section_ptr macros rather
+   than referring directly to the const sections.  The const sections
+   may eventually vanish.  */
+#define BFD_ABS_SECTION_NAME "*ABS*"
+#define BFD_UND_SECTION_NAME "*UND*"
+#define BFD_COM_SECTION_NAME "*COM*"
+#define BFD_IND_SECTION_NAME "*IND*"
+
+/* The absolute section.  */
+extern const asection bfd_abs_section;
+#define bfd_abs_section_ptr ((asection *) &bfd_abs_section)
+#define bfd_is_abs_section(sec) ((sec) == bfd_abs_section_ptr)
+/* Pointer to the undefined section.  */
+extern const asection bfd_und_section;
+#define bfd_und_section_ptr ((asection *) &bfd_und_section)
+#define bfd_is_und_section(sec) ((sec) == bfd_und_section_ptr)
+/* Pointer to the common section.  */
+extern const asection bfd_com_section;
+#define bfd_com_section_ptr ((asection *) &bfd_com_section)
+/* Pointer to the indirect section.  */
+extern const asection bfd_ind_section;
+#define bfd_ind_section_ptr ((asection *) &bfd_ind_section)
+#define bfd_is_ind_section(sec) ((sec) == bfd_ind_section_ptr)
+
+#define bfd_is_const_section(SEC)              \
+ (   ((SEC) == bfd_abs_section_ptr)            \
+  || ((SEC) == bfd_und_section_ptr)            \
+  || ((SEC) == bfd_com_section_ptr)            \
+  || ((SEC) == bfd_ind_section_ptr))
+
+extern const struct symbol_cache_entry * const bfd_abs_symbol;
+extern const struct symbol_cache_entry * const bfd_com_symbol;
+extern const struct symbol_cache_entry * const bfd_und_symbol;
+extern const struct symbol_cache_entry * const bfd_ind_symbol;
+#define bfd_get_section_size_before_reloc(section) \
+     ((section)->reloc_done ? (abort (), (bfd_size_type) 1) \
+                            : (section)->_raw_size)
+#define bfd_get_section_size_after_reloc(section) \
+     ((section)->reloc_done ? (section)->_cooked_size \
+                            : (abort (), (bfd_size_type) 1))
+
+/* Macros to handle insertion and deletion of a bfd's sections.  These
+   only handle the list pointers, ie. do not adjust section_count,
+   target_index etc.  */
+#define bfd_section_list_remove(ABFD, PS) \
+  do                                                   \
+    {                                                  \
+      asection **_ps = PS;                             \
+      asection *_s = *_ps;                             \
+      *_ps = _s->next;                                 \
+      if (_s->next == NULL)                            \
+        (ABFD)->section_tail = _ps;                    \
+    }                                                  \
+  while (0)
+#define bfd_section_list_insert(ABFD, PS, S) \
+  do                                                   \
+    {                                                  \
+      asection **_ps = PS;                             \
+      asection *_s = S;                                \
+      _s->next = *_ps;                                 \
+      *_ps = _s;                                       \
+      if (_s->next == NULL)                            \
+        (ABFD)->section_tail = &_s->next;              \
+    }                                                  \
+  while (0)
+
+void
+bfd_section_list_clear PARAMS ((bfd *));
+
+asection *
+bfd_get_section_by_name PARAMS ((bfd *abfd, const char *name));
+
+char *
+bfd_get_unique_section_name PARAMS ((bfd *abfd,
+    const char *templat,
+    int *count));
+
+asection *
+bfd_make_section_old_way PARAMS ((bfd *abfd, const char *name));
+
+asection *
+bfd_make_section_anyway PARAMS ((bfd *abfd, const char *name));
+
+asection *
+bfd_make_section PARAMS ((bfd *, const char *name));
+
+bfd_boolean
+bfd_set_section_flags PARAMS ((bfd *abfd, asection *sec, flagword flags));
+
+void
+bfd_map_over_sections PARAMS ((bfd *abfd,
+    void (*func) (bfd *abfd,
+    asection *sect,
+    PTR obj),
+    PTR obj));
+
+bfd_boolean
+bfd_set_section_size PARAMS ((bfd *abfd, asection *sec, bfd_size_type val));
+
+bfd_boolean
+bfd_set_section_contents PARAMS ((bfd *abfd, asection *section,
+    PTR data, file_ptr offset,
+    bfd_size_type count));
+
+bfd_boolean
+bfd_get_section_contents PARAMS ((bfd *abfd, asection *section,
+    PTR location, file_ptr offset,
+    bfd_size_type count));
+
+bfd_boolean
+bfd_copy_private_section_data PARAMS ((bfd *ibfd, asection *isec,
+    bfd *obfd, asection *osec));
+
+#define bfd_copy_private_section_data(ibfd, isection, obfd, osection) \
+     BFD_SEND (obfd, _bfd_copy_private_section_data, \
+               (ibfd, isection, obfd, osection))
+void
+_bfd_strip_section_from_output PARAMS ((struct bfd_link_info *info, asection *section));
+
+bfd_boolean
+bfd_generic_discard_group PARAMS ((bfd *abfd, asection *group));
+
+/* Extracted from archures.c.  */
+enum bfd_architecture
+{
+  bfd_arch_unknown,   /* File arch not known.  */
+  bfd_arch_obscure,   /* Arch known, not one of these.  */
+  bfd_arch_m68k,      /* Motorola 68xxx */
+#define bfd_mach_m68000 1
+#define bfd_mach_m68008 2
+#define bfd_mach_m68010 3
+#define bfd_mach_m68020 4
+#define bfd_mach_m68030 5
+#define bfd_mach_m68040 6
+#define bfd_mach_m68060 7
+#define bfd_mach_cpu32  8
+#define bfd_mach_mcf5200  9
+#define bfd_mach_mcf5206e 10
+#define bfd_mach_mcf5307  11
+#define bfd_mach_mcf5407  12
+  bfd_arch_vax,       /* DEC Vax */
+  bfd_arch_i960,      /* Intel 960 */
+    /* The order of the following is important.
+       lower number indicates a machine type that
+       only accepts a subset of the instructions
+       available to machines with higher numbers.
+       The exception is the "ca", which is
+       incompatible with all other machines except
+       "core".  */
+
+#define bfd_mach_i960_core      1
+#define bfd_mach_i960_ka_sa     2
+#define bfd_mach_i960_kb_sb     3
+#define bfd_mach_i960_mc        4
+#define bfd_mach_i960_xa        5
+#define bfd_mach_i960_ca        6
+#define bfd_mach_i960_jx        7
+#define bfd_mach_i960_hx        8
+
+  bfd_arch_or32,      /* OpenRISC 32 */
+
+  bfd_arch_a29k,      /* AMD 29000 */
+  bfd_arch_sparc,     /* SPARC */
+#define bfd_mach_sparc                 1
+/* The difference between v8plus and v9 is that v9 is a true 64 bit env.  */
+#define bfd_mach_sparc_sparclet        2
+#define bfd_mach_sparc_sparclite       3
+#define bfd_mach_sparc_v8plus          4
+#define bfd_mach_sparc_v8plusa         5 /* with ultrasparc add'ns.  */
+#define bfd_mach_sparc_sparclite_le    6
+#define bfd_mach_sparc_v9              7
+#define bfd_mach_sparc_v9a             8 /* with ultrasparc add'ns.  */
+#define bfd_mach_sparc_v8plusb         9 /* with cheetah add'ns.  */
+#define bfd_mach_sparc_v9b             10 /* with cheetah add'ns.  */
+/* Nonzero if MACH has the v9 instruction set.  */
+#define bfd_mach_sparc_v9_p(mach) \
+  ((mach) >= bfd_mach_sparc_v8plus && (mach) <= bfd_mach_sparc_v9b \
+   && (mach) != bfd_mach_sparc_sparclite_le)
+  bfd_arch_mips,      /* MIPS Rxxxx */
+#define bfd_mach_mips3000              3000
+#define bfd_mach_mips3900              3900
+#define bfd_mach_mips4000              4000
+#define bfd_mach_mips4010              4010
+#define bfd_mach_mips4100              4100
+#define bfd_mach_mips4111              4111
+#define bfd_mach_mips4120              4120
+#define bfd_mach_mips4300              4300
+#define bfd_mach_mips4400              4400
+#define bfd_mach_mips4600              4600
+#define bfd_mach_mips4650              4650
+#define bfd_mach_mips5000              5000
+#define bfd_mach_mips5400              5400
+#define bfd_mach_mips5500              5500
+#define bfd_mach_mips6000              6000
+#define bfd_mach_mips8000              8000
+#define bfd_mach_mips10000             10000
+#define bfd_mach_mips12000             12000
+#define bfd_mach_mips16                16
+#define bfd_mach_mips5                 5
+#define bfd_mach_mips_sb1              12310201 /* octal 'SB', 01 */
+#define bfd_mach_mipsisa32             32
+#define bfd_mach_mipsisa32r2           33
+#define bfd_mach_mipsisa64             64
+  bfd_arch_i386,      /* Intel 386 */
+#define bfd_mach_i386_i386 1
+#define bfd_mach_i386_i8086 2
+#define bfd_mach_i386_i386_intel_syntax 3
+#define bfd_mach_x86_64 64
+#define bfd_mach_x86_64_intel_syntax 65
+  bfd_arch_we32k,     /* AT&T WE32xxx */
+  bfd_arch_tahoe,     /* CCI/Harris Tahoe */
+  bfd_arch_i860,      /* Intel 860 */
+  bfd_arch_i370,      /* IBM 360/370 Mainframes */
+  bfd_arch_romp,      /* IBM ROMP PC/RT */
+  bfd_arch_alliant,   /* Alliant */
+  bfd_arch_convex,    /* Convex */
+  bfd_arch_m88k,      /* Motorola 88xxx */
+  bfd_arch_m98k,      /* Motorola 98xxx */
+  bfd_arch_pyramid,   /* Pyramid Technology */
+  bfd_arch_h8300,     /* Renesas H8/300 (formerly Hitachi H8/300) */
+#define bfd_mach_h8300    1
+#define bfd_mach_h8300h   2
+#define bfd_mach_h8300s   3
+#define bfd_mach_h8300hn  4
+#define bfd_mach_h8300sn  5
+  bfd_arch_pdp11,     /* DEC PDP-11 */
+  bfd_arch_powerpc,   /* PowerPC */
+#define bfd_mach_ppc           32
+#define bfd_mach_ppc64         64
+#define bfd_mach_ppc_403       403
+#define bfd_mach_ppc_403gc     4030
+#define bfd_mach_ppc_505       505
+#define bfd_mach_ppc_601       601
+#define bfd_mach_ppc_602       602
+#define bfd_mach_ppc_603       603
+#define bfd_mach_ppc_ec603e    6031
+#define bfd_mach_ppc_604       604
+#define bfd_mach_ppc_620       620
+#define bfd_mach_ppc_630       630
+#define bfd_mach_ppc_750       750
+#define bfd_mach_ppc_860       860
+#define bfd_mach_ppc_a35       35
+#define bfd_mach_ppc_rs64ii    642
+#define bfd_mach_ppc_rs64iii   643
+#define bfd_mach_ppc_7400      7400
+#define bfd_mach_ppc_e500      500
+  bfd_arch_rs6000,    /* IBM RS/6000 */
+#define bfd_mach_rs6k          6000
+#define bfd_mach_rs6k_rs1      6001
+#define bfd_mach_rs6k_rsc      6003
+#define bfd_mach_rs6k_rs2      6002
+  bfd_arch_hppa,      /* HP PA RISC */
+  bfd_arch_d10v,      /* Mitsubishi D10V */
+#define bfd_mach_d10v          1
+#define bfd_mach_d10v_ts2      2
+#define bfd_mach_d10v_ts3      3
+  bfd_arch_d30v,      /* Mitsubishi D30V */
+  bfd_arch_dlx,       /* DLX */
+  bfd_arch_m68hc11,   /* Motorola 68HC11 */
+  bfd_arch_m68hc12,   /* Motorola 68HC12 */
+#define bfd_mach_m6812_default 0
+#define bfd_mach_m6812         1
+#define bfd_mach_m6812s        2
+  bfd_arch_z8k,       /* Zilog Z8000 */
+#define bfd_mach_z8001         1
+#define bfd_mach_z8002         2
+  bfd_arch_h8500,     /* Renesas H8/500 (formerly Hitachi H8/500) */
+  bfd_arch_sh,        /* Renesas / SuperH SH (formerly Hitachi SH) */
+#define bfd_mach_sh            1
+#define bfd_mach_sh2        0x20
+#define bfd_mach_sh_dsp     0x2d
+#define bfd_mach_sh2e       0x2e
+#define bfd_mach_sh3        0x30
+#define bfd_mach_sh3_dsp    0x3d
+#define bfd_mach_sh3e       0x3e
+#define bfd_mach_sh4        0x40
+#define bfd_mach_sh5        0x50
+  bfd_arch_alpha,     /* Dec Alpha */
+#define bfd_mach_alpha_ev4  0x10
+#define bfd_mach_alpha_ev5  0x20
+#define bfd_mach_alpha_ev6  0x30
+  bfd_arch_arm,       /* Advanced Risc Machines ARM.  */
+#define bfd_mach_arm_unknown   0
+#define bfd_mach_arm_2         1
+#define bfd_mach_arm_2a        2
+#define bfd_mach_arm_3         3
+#define bfd_mach_arm_3M        4
+#define bfd_mach_arm_4         5
+#define bfd_mach_arm_4T        6
+#define bfd_mach_arm_5         7
+#define bfd_mach_arm_5T        8
+#define bfd_mach_arm_5TE       9
+#define bfd_mach_arm_XScale    10
+#define bfd_mach_arm_ep9312    11
+#define bfd_mach_arm_iWMMXt    12
+  bfd_arch_ns32k,     /* National Semiconductors ns32000 */
+  bfd_arch_w65,       /* WDC 65816 */
+  bfd_arch_tic30,     /* Texas Instruments TMS320C30 */
+  bfd_arch_tic4x,     /* Texas Instruments TMS320C3X/4X */
+#define bfd_mach_tic3x         30
+#define bfd_mach_tic4x         40
+  bfd_arch_tic54x,    /* Texas Instruments TMS320C54X */
+  bfd_arch_tic80,     /* TI TMS320c80 (MVP) */
+  bfd_arch_v850,      /* NEC V850 */
+#define bfd_mach_v850          1
+#define bfd_mach_v850e         'E'
+  bfd_arch_arc,       /* ARC Cores */
+#define bfd_mach_arc_5         5
+#define bfd_mach_arc_6         6
+#define bfd_mach_arc_7         7
+#define bfd_mach_arc_8         8
+  bfd_arch_m32r,      /* Renesas M32R (formerly Mitsubishi M32R/D) */
+#define bfd_mach_m32r          1 /* For backwards compatibility.  */
+#define bfd_mach_m32rx         'x'
+  bfd_arch_mn10200,   /* Matsushita MN10200 */
+  bfd_arch_mn10300,   /* Matsushita MN10300 */
+#define bfd_mach_mn10300               300
+#define bfd_mach_am33          330
+  bfd_arch_fr30,
+#define bfd_mach_fr30          0x46523330
+  bfd_arch_frv,
+#define bfd_mach_frv           1
+#define bfd_mach_frvsimple     2
+#define bfd_mach_fr300         300
+#define bfd_mach_fr400         400
+#define bfd_mach_frvtomcat     499     /* fr500 prototype */
+#define bfd_mach_fr500         500
+  bfd_arch_mcore,
+  bfd_arch_ia64,      /* HP/Intel ia64 */
+#define bfd_mach_ia64_elf64    64
+#define bfd_mach_ia64_elf32    32
+  bfd_arch_ip2k,      /* Ubicom IP2K microcontrollers. */
+#define bfd_mach_ip2022        1
+#define bfd_mach_ip2022ext     2
+ bfd_arch_iq2000,     /* Vitesse IQ2000.  */
+#define bfd_mach_iq2000        1
+#define bfd_mach_iq10          2
+  bfd_arch_pj,
+  bfd_arch_avr,       /* Atmel AVR microcontrollers.  */
+#define bfd_mach_avr1          1
+#define bfd_mach_avr2          2
+#define bfd_mach_avr3          3
+#define bfd_mach_avr4          4
+#define bfd_mach_avr5          5
+  bfd_arch_cris,      /* Axis CRIS */
+  bfd_arch_s390,      /* IBM s390 */
+#define bfd_mach_s390_31       31
+#define bfd_mach_s390_64       64
+  bfd_arch_openrisc,  /* OpenRISC */
+  bfd_arch_mmix,      /* Donald Knuth's educational processor.  */
+  bfd_arch_xstormy16,
+#define bfd_mach_xstormy16     1
+  bfd_arch_msp430,    /* Texas Instruments MSP430 architecture.  */
+#define bfd_mach_msp110         110
+#define bfd_mach_msp11          11
+#define bfd_mach_msp12          12
+#define bfd_mach_msp13          13
+#define bfd_mach_msp14          14
+#define bfd_mach_msp41          41
+#define bfd_mach_msp31          31
+#define bfd_mach_msp32          32
+#define bfd_mach_msp33          33
+#define bfd_mach_msp43          43
+#define bfd_mach_msp44          44
+#define bfd_mach_msp15          15
+#define bfd_mach_msp16          16  
+  bfd_arch_xtensa,    /* Tensilica's Xtensa cores.  */
+#define bfd_mach_xtensa        1
+  bfd_arch_last
+  };
+
+typedef struct bfd_arch_info
+{
+  int bits_per_word;
+  int bits_per_address;
+  int bits_per_byte;
+  enum bfd_architecture arch;
+  unsigned long mach;
+  const char *arch_name;
+  const char *printable_name;
+  unsigned int section_align_power;
+  /* TRUE if this is the default machine for the architecture.
+     The default arch should be the first entry for an arch so that
+     all the entries for that arch can be accessed via <<next>>.  */
+  bfd_boolean the_default;
+  const struct bfd_arch_info * (*compatible)
+       PARAMS ((const struct bfd_arch_info *a,
+                const struct bfd_arch_info *b));
+
+  bfd_boolean (*scan) PARAMS ((const struct bfd_arch_info *, const char *));
+
+  const struct bfd_arch_info *next;
+}
+bfd_arch_info_type;
+
+const char *
+bfd_printable_name PARAMS ((bfd *abfd));
+
+const bfd_arch_info_type *
+bfd_scan_arch PARAMS ((const char *string));
+
+const char **
+bfd_arch_list PARAMS ((void));
+
+const bfd_arch_info_type *
+bfd_arch_get_compatible PARAMS ((
+    const bfd *abfd,
+    const bfd *bbfd,
+    bfd_boolean accept_unknowns));
+
+void
+bfd_set_arch_info PARAMS ((bfd *abfd, const bfd_arch_info_type *arg));
+
+enum bfd_architecture
+bfd_get_arch PARAMS ((bfd *abfd));
+
+unsigned long
+bfd_get_mach PARAMS ((bfd *abfd));
+
+unsigned int
+bfd_arch_bits_per_byte PARAMS ((bfd *abfd));
+
+unsigned int
+bfd_arch_bits_per_address PARAMS ((bfd *abfd));
+
+const bfd_arch_info_type *
+bfd_get_arch_info PARAMS ((bfd *abfd));
+
+const bfd_arch_info_type *
+bfd_lookup_arch PARAMS ((enum bfd_architecture
+    arch,
+    unsigned long machine));
+
+const char *
+bfd_printable_arch_mach PARAMS ((enum bfd_architecture arch, unsigned long machine));
+
+unsigned int
+bfd_octets_per_byte PARAMS ((bfd *abfd));
+
+unsigned int
+bfd_arch_mach_octets_per_byte PARAMS ((enum bfd_architecture arch,
+    unsigned long machine));
+
+/* Extracted from reloc.c.  */
+typedef enum bfd_reloc_status
+{
+  /* No errors detected.  */
+  bfd_reloc_ok,
+
+  /* The relocation was performed, but there was an overflow.  */
+  bfd_reloc_overflow,
+
+  /* The address to relocate was not within the section supplied.  */
+  bfd_reloc_outofrange,
+
+  /* Used by special functions.  */
+  bfd_reloc_continue,
+
+  /* Unsupported relocation size requested.  */
+  bfd_reloc_notsupported,
+
+  /* Unused.  */
+  bfd_reloc_other,
+
+  /* The symbol to relocate against was undefined.  */
+  bfd_reloc_undefined,
+
+  /* The relocation was performed, but may not be ok - presently
+     generated only when linking i960 coff files with i960 b.out
+     symbols.  If this type is returned, the error_message argument
+     to bfd_perform_relocation will be set.  */
+  bfd_reloc_dangerous
+ }
+ bfd_reloc_status_type;
+
+
+typedef struct reloc_cache_entry
+{
+  /* A pointer into the canonical table of pointers.  */
+  struct symbol_cache_entry **sym_ptr_ptr;
+
+  /* offset in section.  */
+  bfd_size_type address;
+
+  /* addend for relocation value.  */
+  bfd_vma addend;
+
+  /* Pointer to how to perform the required relocation.  */
+  reloc_howto_type *howto;
+
+}
+arelent;
+
+enum complain_overflow
+{
+  /* Do not complain on overflow.  */
+  complain_overflow_dont,
+
+  /* Complain if the bitfield overflows, whether it is considered
+     as signed or unsigned.  */
+  complain_overflow_bitfield,
+
+  /* Complain if the value overflows when considered as signed
+     number.  */
+  complain_overflow_signed,
+
+  /* Complain if the value overflows when considered as an
+     unsigned number.  */
+  complain_overflow_unsigned
+};
+
+struct reloc_howto_struct
+{
+  /*  The type field has mainly a documentary use - the back end can
+      do what it wants with it, though normally the back end's
+      external idea of what a reloc number is stored
+      in this field.  For example, a PC relative word relocation
+      in a coff environment has the type 023 - because that's
+      what the outside world calls a R_PCRWORD reloc.  */
+  unsigned int type;
+
+  /*  The value the final relocation is shifted right by.  This drops
+      unwanted data from the relocation.  */
+  unsigned int rightshift;
+
+  /*  The size of the item to be relocated.  This is *not* a
+      power-of-two measure.  To get the number of bytes operated
+      on by a type of relocation, use bfd_get_reloc_size.  */
+  int size;
+
+  /*  The number of bits in the item to be relocated.  This is used
+      when doing overflow checking.  */
+  unsigned int bitsize;
+
+  /*  Notes that the relocation is relative to the location in the
+      data section of the addend.  The relocation function will
+      subtract from the relocation value the address of the location
+      being relocated.  */
+  bfd_boolean pc_relative;
+
+  /*  The bit position of the reloc value in the destination.
+      The relocated value is left shifted by this amount.  */
+  unsigned int bitpos;
+
+  /* What type of overflow error should be checked for when
+     relocating.  */
+  enum complain_overflow complain_on_overflow;
+
+  /* If this field is non null, then the supplied function is
+     called rather than the normal function.  This allows really
+     strange relocation methods to be accomodated (e.g., i960 callj
+     instructions).  */
+  bfd_reloc_status_type (*special_function)
+    PARAMS ((bfd *, arelent *, struct symbol_cache_entry *, PTR, asection *,
+             bfd *, char **));
+
+  /* The textual name of the relocation type.  */
+  char *name;
+
+  /* Some formats record a relocation addend in the section contents
+     rather than with the relocation.  For ELF formats this is the
+     distinction between USE_REL and USE_RELA (though the code checks
+     for USE_REL == 1/0).  The value of this field is TRUE if the
+     addend is recorded with the section contents; when performing a
+     partial link (ld -r) the section contents (the data) will be
+     modified.  The value of this field is FALSE if addends are
+     recorded with the relocation (in arelent.addend); when performing
+     a partial link the relocation will be modified.
+     All relocations for all ELF USE_RELA targets should set this field
+     to FALSE (values of TRUE should be looked on with suspicion).
+     However, the converse is not true: not all relocations of all ELF
+     USE_REL targets set this field to TRUE.  Why this is so is peculiar
+     to each particular target.  For relocs that aren't used in partial
+     links (e.g. GOT stuff) it doesn't matter what this is set to.  */
+  bfd_boolean partial_inplace;
+
+  /* src_mask selects the part of the instruction (or data) to be used
+     in the relocation sum.  If the target relocations don't have an
+     addend in the reloc, eg. ELF USE_REL, src_mask will normally equal
+     dst_mask to extract the addend from the section contents.  If
+     relocations do have an addend in the reloc, eg. ELF USE_RELA, this
+     field should be zero.  Non-zero values for ELF USE_RELA targets are
+     bogus as in those cases the value in the dst_mask part of the
+     section contents should be treated as garbage.  */
+  bfd_vma src_mask;
+
+  /* dst_mask selects which parts of the instruction (or data) are
+     replaced with a relocated value.  */
+  bfd_vma dst_mask;
+
+  /* When some formats create PC relative instructions, they leave
+     the value of the pc of the place being relocated in the offset
+     slot of the instruction, so that a PC relative relocation can
+     be made just by adding in an ordinary offset (e.g., sun3 a.out).
+     Some formats leave the displacement part of an instruction
+     empty (e.g., m88k bcs); this flag signals the fact.  */
+  bfd_boolean pcrel_offset;
+};
+
+#define HOWTO(C, R, S, B, P, BI, O, SF, NAME, INPLACE, MASKSRC, MASKDST, PC) \
+  { (unsigned) C, R, S, B, P, BI, O, SF, NAME, INPLACE, MASKSRC, MASKDST, PC }
+#define NEWHOWTO(FUNCTION, NAME, SIZE, REL, IN) \
+  HOWTO (0, 0, SIZE, 0, REL, 0, complain_overflow_dont, FUNCTION, \
+         NAME, FALSE, 0, 0, IN)
+
+#define EMPTY_HOWTO(C) \
+  HOWTO ((C), 0, 0, 0, FALSE, 0, complain_overflow_dont, NULL, \
+         NULL, FALSE, 0, 0, FALSE)
+
+#define HOWTO_PREPARE(relocation, symbol)               \
+  {                                                     \
+    if (symbol != (asymbol *) NULL)                     \
+      {                                                 \
+        if (bfd_is_com_section (symbol->section))       \
+          {                                             \
+            relocation = 0;                             \
+          }                                             \
+        else                                            \
+          {                                             \
+            relocation = symbol->value;                 \
+          }                                             \
+      }                                                 \
+  }
+
+unsigned int
+bfd_get_reloc_size PARAMS ((reloc_howto_type *));
+
+typedef struct relent_chain
+{
+  arelent relent;
+  struct relent_chain *next;
+}
+arelent_chain;
+
+bfd_reloc_status_type
+bfd_check_overflow PARAMS ((enum complain_overflow how,
+    unsigned int bitsize,
+    unsigned int rightshift,
+    unsigned int addrsize,
+    bfd_vma relocation));
+
+bfd_reloc_status_type
+bfd_perform_relocation PARAMS ((bfd *abfd,
+    arelent *reloc_entry,
+    PTR data,
+    asection *input_section,
+    bfd *output_bfd,
+    char **error_message));
+
+bfd_reloc_status_type
+bfd_install_relocation PARAMS ((bfd *abfd,
+    arelent *reloc_entry,
+    PTR data, bfd_vma data_start,
+    asection *input_section,
+    char **error_message));
+
+enum bfd_reloc_code_real {
+  _dummy_first_bfd_reloc_code_real,
+
+
+/* Basic absolute relocations of N bits.  */
+  BFD_RELOC_64,
+  BFD_RELOC_32,
+  BFD_RELOC_26,
+  BFD_RELOC_24,
+  BFD_RELOC_16,
+  BFD_RELOC_14,
+  BFD_RELOC_8,
+
+/* PC-relative relocations.  Sometimes these are relative to the address
+of the relocation itself; sometimes they are relative to the start of
+the section containing the relocation.  It depends on the specific target.
+
+The 24-bit relocation is used in some Intel 960 configurations.  */
+  BFD_RELOC_64_PCREL,
+  BFD_RELOC_32_PCREL,
+  BFD_RELOC_24_PCREL,
+  BFD_RELOC_16_PCREL,
+  BFD_RELOC_12_PCREL,
+  BFD_RELOC_8_PCREL,
+
+/* For ELF.  */
+  BFD_RELOC_32_GOT_PCREL,
+  BFD_RELOC_16_GOT_PCREL,
+  BFD_RELOC_8_GOT_PCREL,
+  BFD_RELOC_32_GOTOFF,
+  BFD_RELOC_16_GOTOFF,
+  BFD_RELOC_LO16_GOTOFF,
+  BFD_RELOC_HI16_GOTOFF,
+  BFD_RELOC_HI16_S_GOTOFF,
+  BFD_RELOC_8_GOTOFF,
+  BFD_RELOC_64_PLT_PCREL,
+  BFD_RELOC_32_PLT_PCREL,
+  BFD_RELOC_24_PLT_PCREL,
+  BFD_RELOC_16_PLT_PCREL,
+  BFD_RELOC_8_PLT_PCREL,
+  BFD_RELOC_64_PLTOFF,
+  BFD_RELOC_32_PLTOFF,
+  BFD_RELOC_16_PLTOFF,
+  BFD_RELOC_LO16_PLTOFF,
+  BFD_RELOC_HI16_PLTOFF,
+  BFD_RELOC_HI16_S_PLTOFF,
+  BFD_RELOC_8_PLTOFF,
+
+/* Relocations used by 68K ELF.  */
+  BFD_RELOC_68K_GLOB_DAT,
+  BFD_RELOC_68K_JMP_SLOT,
+  BFD_RELOC_68K_RELATIVE,
+
+/* Linkage-table relative.  */
+  BFD_RELOC_32_BASEREL,
+  BFD_RELOC_16_BASEREL,
+  BFD_RELOC_LO16_BASEREL,
+  BFD_RELOC_HI16_BASEREL,
+  BFD_RELOC_HI16_S_BASEREL,
+  BFD_RELOC_8_BASEREL,
+  BFD_RELOC_RVA,
+
+/* Absolute 8-bit relocation, but used to form an address like 0xFFnn.  */
+  BFD_RELOC_8_FFnn,
+
+/* These PC-relative relocations are stored as word displacements --
+i.e., byte displacements shifted right two bits.  The 30-bit word
+displacement (<<32_PCREL_S2>> -- 32 bits, shifted 2) is used on the
+SPARC.  (SPARC tools generally refer to this as <<WDISP30>>.)  The
+signed 16-bit displacement is used on the MIPS, and the 23-bit
+displacement is used on the Alpha.  */
+  BFD_RELOC_32_PCREL_S2,
+  BFD_RELOC_16_PCREL_S2,
+  BFD_RELOC_23_PCREL_S2,
+
+/* High 22 bits and low 10 bits of 32-bit value, placed into lower bits of
+the target word.  These are used on the SPARC.  */
+  BFD_RELOC_HI22,
+  BFD_RELOC_LO10,
+
+/* For systems that allocate a Global Pointer register, these are
+displacements off that register.  These relocation types are
+handled specially, because the value the register will have is
+decided relatively late.  */
+  BFD_RELOC_GPREL16,
+  BFD_RELOC_GPREL32,
+
+/* Reloc types used for i960/b.out.  */
+  BFD_RELOC_I960_CALLJ,
+
+/* SPARC ELF relocations.  There is probably some overlap with other
+relocation types already defined.  */
+  BFD_RELOC_NONE,
+  BFD_RELOC_SPARC_WDISP22,
+  BFD_RELOC_SPARC22,
+  BFD_RELOC_SPARC13,
+  BFD_RELOC_SPARC_GOT10,
+  BFD_RELOC_SPARC_GOT13,
+  BFD_RELOC_SPARC_GOT22,
+  BFD_RELOC_SPARC_PC10,
+  BFD_RELOC_SPARC_PC22,
+  BFD_RELOC_SPARC_WPLT30,
+  BFD_RELOC_SPARC_COPY,
+  BFD_RELOC_SPARC_GLOB_DAT,
+  BFD_RELOC_SPARC_JMP_SLOT,
+  BFD_RELOC_SPARC_RELATIVE,
+  BFD_RELOC_SPARC_UA16,
+  BFD_RELOC_SPARC_UA32,
+  BFD_RELOC_SPARC_UA64,
+
+/* I think these are specific to SPARC a.out (e.g., Sun 4).  */
+  BFD_RELOC_SPARC_BASE13,
+  BFD_RELOC_SPARC_BASE22,
+
+/* SPARC64 relocations  */
+#define BFD_RELOC_SPARC_64 BFD_RELOC_64
+  BFD_RELOC_SPARC_10,
+  BFD_RELOC_SPARC_11,
+  BFD_RELOC_SPARC_OLO10,
+  BFD_RELOC_SPARC_HH22,
+  BFD_RELOC_SPARC_HM10,
+  BFD_RELOC_SPARC_LM22,
+  BFD_RELOC_SPARC_PC_HH22,
+  BFD_RELOC_SPARC_PC_HM10,
+  BFD_RELOC_SPARC_PC_LM22,
+  BFD_RELOC_SPARC_WDISP16,
+  BFD_RELOC_SPARC_WDISP19,
+  BFD_RELOC_SPARC_7,
+  BFD_RELOC_SPARC_6,
+  BFD_RELOC_SPARC_5,
+#define BFD_RELOC_SPARC_DISP64 BFD_RELOC_64_PCREL
+  BFD_RELOC_SPARC_PLT32,
+  BFD_RELOC_SPARC_PLT64,
+  BFD_RELOC_SPARC_HIX22,
+  BFD_RELOC_SPARC_LOX10,
+  BFD_RELOC_SPARC_H44,
+  BFD_RELOC_SPARC_M44,
+  BFD_RELOC_SPARC_L44,
+  BFD_RELOC_SPARC_REGISTER,
+
+/* SPARC little endian relocation  */
+  BFD_RELOC_SPARC_REV32,
+
+/* SPARC TLS relocations  */
+  BFD_RELOC_SPARC_TLS_GD_HI22,
+  BFD_RELOC_SPARC_TLS_GD_LO10,
+  BFD_RELOC_SPARC_TLS_GD_ADD,
+  BFD_RELOC_SPARC_TLS_GD_CALL,
+  BFD_RELOC_SPARC_TLS_LDM_HI22,
+  BFD_RELOC_SPARC_TLS_LDM_LO10,
+  BFD_RELOC_SPARC_TLS_LDM_ADD,
+  BFD_RELOC_SPARC_TLS_LDM_CALL,
+  BFD_RELOC_SPARC_TLS_LDO_HIX22,
+  BFD_RELOC_SPARC_TLS_LDO_LOX10,
+  BFD_RELOC_SPARC_TLS_LDO_ADD,
+  BFD_RELOC_SPARC_TLS_IE_HI22,
+  BFD_RELOC_SPARC_TLS_IE_LO10,
+  BFD_RELOC_SPARC_TLS_IE_LD,
+  BFD_RELOC_SPARC_TLS_IE_LDX,
+  BFD_RELOC_SPARC_TLS_IE_ADD,
+  BFD_RELOC_SPARC_TLS_LE_HIX22,
+  BFD_RELOC_SPARC_TLS_LE_LOX10,
+  BFD_RELOC_SPARC_TLS_DTPMOD32,
+  BFD_RELOC_SPARC_TLS_DTPMOD64,
+  BFD_RELOC_SPARC_TLS_DTPOFF32,
+  BFD_RELOC_SPARC_TLS_DTPOFF64,
+  BFD_RELOC_SPARC_TLS_TPOFF32,
+  BFD_RELOC_SPARC_TLS_TPOFF64,
+
+/* Alpha ECOFF and ELF relocations.  Some of these treat the symbol or
+"addend" in some special way.
+For GPDISP_HI16 ("gpdisp") relocations, the symbol is ignored when
+writing; when reading, it will be the absolute section symbol.  The
+addend is the displacement in bytes of the "lda" instruction from
+the "ldah" instruction (which is at the address of this reloc).  */
+  BFD_RELOC_ALPHA_GPDISP_HI16,
+
+/* For GPDISP_LO16 ("ignore") relocations, the symbol is handled as
+with GPDISP_HI16 relocs.  The addend is ignored when writing the
+relocations out, and is filled in with the file's GP value on
+reading, for convenience.  */
+  BFD_RELOC_ALPHA_GPDISP_LO16,
+
+/* The ELF GPDISP relocation is exactly the same as the GPDISP_HI16
+relocation except that there is no accompanying GPDISP_LO16
+relocation.  */
+  BFD_RELOC_ALPHA_GPDISP,
+
+/* The Alpha LITERAL/LITUSE relocs are produced by a symbol reference;
+the assembler turns it into a LDQ instruction to load the address of
+the symbol, and then fills in a register in the real instruction.
+
+The LITERAL reloc, at the LDQ instruction, refers to the .lita
+section symbol.  The addend is ignored when writing, but is filled
+in with the file's GP value on reading, for convenience, as with the
+GPDISP_LO16 reloc.
+
+The ELF_LITERAL reloc is somewhere between 16_GOTOFF and GPDISP_LO16.
+It should refer to the symbol to be referenced, as with 16_GOTOFF,
+but it generates output not based on the position within the .got
+section, but relative to the GP value chosen for the file during the
+final link stage.
+
+The LITUSE reloc, on the instruction using the loaded address, gives
+information to the linker that it might be able to use to optimize
+away some literal section references.  The symbol is ignored (read
+as the absolute section symbol), and the "addend" indicates the type
+of instruction using the register:
+1 - "memory" fmt insn
+2 - byte-manipulation (byte offset reg)
+3 - jsr (target of branch)  */
+  BFD_RELOC_ALPHA_LITERAL,
+  BFD_RELOC_ALPHA_ELF_LITERAL,
+  BFD_RELOC_ALPHA_LITUSE,
+
+/* The HINT relocation indicates a value that should be filled into the
+"hint" field of a jmp/jsr/ret instruction, for possible branch-
+prediction logic which may be provided on some processors.  */
+  BFD_RELOC_ALPHA_HINT,
+
+/* The LINKAGE relocation outputs a linkage pair in the object file,
+which is filled by the linker.  */
+  BFD_RELOC_ALPHA_LINKAGE,
+
+/* The CODEADDR relocation outputs a STO_CA in the object file,
+which is filled by the linker.  */
+  BFD_RELOC_ALPHA_CODEADDR,
+
+/* The GPREL_HI/LO relocations together form a 32-bit offset from the
+GP register.  */
+  BFD_RELOC_ALPHA_GPREL_HI16,
+  BFD_RELOC_ALPHA_GPREL_LO16,
+
+/* Like BFD_RELOC_23_PCREL_S2, except that the source and target must
+share a common GP, and the target address is adjusted for
+STO_ALPHA_STD_GPLOAD.  */
+  BFD_RELOC_ALPHA_BRSGP,
+
+/* Alpha thread-local storage relocations.  */
+  BFD_RELOC_ALPHA_TLSGD,
+  BFD_RELOC_ALPHA_TLSLDM,
+  BFD_RELOC_ALPHA_DTPMOD64,
+  BFD_RELOC_ALPHA_GOTDTPREL16,
+  BFD_RELOC_ALPHA_DTPREL64,
+  BFD_RELOC_ALPHA_DTPREL_HI16,
+  BFD_RELOC_ALPHA_DTPREL_LO16,
+  BFD_RELOC_ALPHA_DTPREL16,
+  BFD_RELOC_ALPHA_GOTTPREL16,
+  BFD_RELOC_ALPHA_TPREL64,
+  BFD_RELOC_ALPHA_TPREL_HI16,
+  BFD_RELOC_ALPHA_TPREL_LO16,
+  BFD_RELOC_ALPHA_TPREL16,
+
+/* Bits 27..2 of the relocation address shifted right 2 bits;
+simple reloc otherwise.  */
+  BFD_RELOC_MIPS_JMP,
+
+/* The MIPS16 jump instruction.  */
+  BFD_RELOC_MIPS16_JMP,
+
+/* MIPS16 GP relative reloc.  */
+  BFD_RELOC_MIPS16_GPREL,
+
+/* High 16 bits of 32-bit value; simple reloc.  */
+  BFD_RELOC_HI16,
+
+/* High 16 bits of 32-bit value but the low 16 bits will be sign
+extended and added to form the final result.  If the low 16
+bits form a negative number, we need to add one to the high value
+to compensate for the borrow when the low bits are added.  */
+  BFD_RELOC_HI16_S,
+
+/* Low 16 bits.  */
+  BFD_RELOC_LO16,
+
+/* Like BFD_RELOC_HI16_S, but PC relative.  */
+  BFD_RELOC_PCREL_HI16_S,
+
+/* Like BFD_RELOC_LO16, but PC relative.  */
+  BFD_RELOC_PCREL_LO16,
+
+/* Relocation against a MIPS literal section.  */
+  BFD_RELOC_MIPS_LITERAL,
+
+/* MIPS ELF relocations.  */
+  BFD_RELOC_MIPS_GOT16,
+  BFD_RELOC_MIPS_CALL16,
+  BFD_RELOC_MIPS_GOT_HI16,
+  BFD_RELOC_MIPS_GOT_LO16,
+  BFD_RELOC_MIPS_CALL_HI16,
+  BFD_RELOC_MIPS_CALL_LO16,
+  BFD_RELOC_MIPS_SUB,
+  BFD_RELOC_MIPS_GOT_PAGE,
+  BFD_RELOC_MIPS_GOT_OFST,
+  BFD_RELOC_MIPS_GOT_DISP,
+  BFD_RELOC_MIPS_SHIFT5,
+  BFD_RELOC_MIPS_SHIFT6,
+  BFD_RELOC_MIPS_INSERT_A,
+  BFD_RELOC_MIPS_INSERT_B,
+  BFD_RELOC_MIPS_DELETE,
+  BFD_RELOC_MIPS_HIGHEST,
+  BFD_RELOC_MIPS_HIGHER,
+  BFD_RELOC_MIPS_SCN_DISP,
+  BFD_RELOC_MIPS_REL16,
+  BFD_RELOC_MIPS_RELGOT,
+  BFD_RELOC_MIPS_JALR,
+
+/* Fujitsu Frv Relocations.  */
+  BFD_RELOC_FRV_LABEL16,
+  BFD_RELOC_FRV_LABEL24,
+  BFD_RELOC_FRV_LO16,
+  BFD_RELOC_FRV_HI16,
+  BFD_RELOC_FRV_GPREL12,
+  BFD_RELOC_FRV_GPRELU12,
+  BFD_RELOC_FRV_GPREL32,
+  BFD_RELOC_FRV_GPRELHI,
+  BFD_RELOC_FRV_GPRELLO,
+
+
+/* i386/elf relocations  */
+  BFD_RELOC_386_GOT32,
+  BFD_RELOC_386_PLT32,
+  BFD_RELOC_386_COPY,
+  BFD_RELOC_386_GLOB_DAT,
+  BFD_RELOC_386_JUMP_SLOT,
+  BFD_RELOC_386_RELATIVE,
+  BFD_RELOC_386_GOTOFF,
+  BFD_RELOC_386_GOTPC,
+  BFD_RELOC_386_TLS_TPOFF,
+  BFD_RELOC_386_TLS_IE,
+  BFD_RELOC_386_TLS_GOTIE,
+  BFD_RELOC_386_TLS_LE,
+  BFD_RELOC_386_TLS_GD,
+  BFD_RELOC_386_TLS_LDM,
+  BFD_RELOC_386_TLS_LDO_32,
+  BFD_RELOC_386_TLS_IE_32,
+  BFD_RELOC_386_TLS_LE_32,
+  BFD_RELOC_386_TLS_DTPMOD32,
+  BFD_RELOC_386_TLS_DTPOFF32,
+  BFD_RELOC_386_TLS_TPOFF32,
+
+/* x86-64/elf relocations  */
+  BFD_RELOC_X86_64_GOT32,
+  BFD_RELOC_X86_64_PLT32,
+  BFD_RELOC_X86_64_COPY,
+  BFD_RELOC_X86_64_GLOB_DAT,
+  BFD_RELOC_X86_64_JUMP_SLOT,
+  BFD_RELOC_X86_64_RELATIVE,
+  BFD_RELOC_X86_64_GOTPCREL,
+  BFD_RELOC_X86_64_32S,
+  BFD_RELOC_X86_64_DTPMOD64,
+  BFD_RELOC_X86_64_DTPOFF64,
+  BFD_RELOC_X86_64_TPOFF64,
+  BFD_RELOC_X86_64_TLSGD,
+  BFD_RELOC_X86_64_TLSLD,
+  BFD_RELOC_X86_64_DTPOFF32,
+  BFD_RELOC_X86_64_GOTTPOFF,
+  BFD_RELOC_X86_64_TPOFF32,
+
+/* ns32k relocations  */
+  BFD_RELOC_NS32K_IMM_8,
+  BFD_RELOC_NS32K_IMM_16,
+  BFD_RELOC_NS32K_IMM_32,
+  BFD_RELOC_NS32K_IMM_8_PCREL,
+  BFD_RELOC_NS32K_IMM_16_PCREL,
+  BFD_RELOC_NS32K_IMM_32_PCREL,
+  BFD_RELOC_NS32K_DISP_8,
+  BFD_RELOC_NS32K_DISP_16,
+  BFD_RELOC_NS32K_DISP_32,
+  BFD_RELOC_NS32K_DISP_8_PCREL,
+  BFD_RELOC_NS32K_DISP_16_PCREL,
+  BFD_RELOC_NS32K_DISP_32_PCREL,
+
+/* PDP11 relocations  */
+  BFD_RELOC_PDP11_DISP_8_PCREL,
+  BFD_RELOC_PDP11_DISP_6_PCREL,
+
+/* Picojava relocs.  Not all of these appear in object files.  */
+  BFD_RELOC_PJ_CODE_HI16,
+  BFD_RELOC_PJ_CODE_LO16,
+  BFD_RELOC_PJ_CODE_DIR16,
+  BFD_RELOC_PJ_CODE_DIR32,
+  BFD_RELOC_PJ_CODE_REL16,
+  BFD_RELOC_PJ_CODE_REL32,
+
+/* Power(rs6000) and PowerPC relocations.  */
+  BFD_RELOC_PPC_B26,
+  BFD_RELOC_PPC_BA26,
+  BFD_RELOC_PPC_TOC16,
+  BFD_RELOC_PPC_B16,
+  BFD_RELOC_PPC_B16_BRTAKEN,
+  BFD_RELOC_PPC_B16_BRNTAKEN,
+  BFD_RELOC_PPC_BA16,
+  BFD_RELOC_PPC_BA16_BRTAKEN,
+  BFD_RELOC_PPC_BA16_BRNTAKEN,
+  BFD_RELOC_PPC_COPY,
+  BFD_RELOC_PPC_GLOB_DAT,
+  BFD_RELOC_PPC_JMP_SLOT,
+  BFD_RELOC_PPC_RELATIVE,
+  BFD_RELOC_PPC_LOCAL24PC,
+  BFD_RELOC_PPC_EMB_NADDR32,
+  BFD_RELOC_PPC_EMB_NADDR16,
+  BFD_RELOC_PPC_EMB_NADDR16_LO,
+  BFD_RELOC_PPC_EMB_NADDR16_HI,
+  BFD_RELOC_PPC_EMB_NADDR16_HA,
+  BFD_RELOC_PPC_EMB_SDAI16,
+  BFD_RELOC_PPC_EMB_SDA2I16,
+  BFD_RELOC_PPC_EMB_SDA2REL,
+  BFD_RELOC_PPC_EMB_SDA21,
+  BFD_RELOC_PPC_EMB_MRKREF,
+  BFD_RELOC_PPC_EMB_RELSEC16,
+  BFD_RELOC_PPC_EMB_RELST_LO,
+  BFD_RELOC_PPC_EMB_RELST_HI,
+  BFD_RELOC_PPC_EMB_RELST_HA,
+  BFD_RELOC_PPC_EMB_BIT_FLD,
+  BFD_RELOC_PPC_EMB_RELSDA,
+  BFD_RELOC_PPC64_HIGHER,
+  BFD_RELOC_PPC64_HIGHER_S,
+  BFD_RELOC_PPC64_HIGHEST,
+  BFD_RELOC_PPC64_HIGHEST_S,
+  BFD_RELOC_PPC64_TOC16_LO,
+  BFD_RELOC_PPC64_TOC16_HI,
+  BFD_RELOC_PPC64_TOC16_HA,
+  BFD_RELOC_PPC64_TOC,
+  BFD_RELOC_PPC64_PLTGOT16,
+  BFD_RELOC_PPC64_PLTGOT16_LO,
+  BFD_RELOC_PPC64_PLTGOT16_HI,
+  BFD_RELOC_PPC64_PLTGOT16_HA,
+  BFD_RELOC_PPC64_ADDR16_DS,
+  BFD_RELOC_PPC64_ADDR16_LO_DS,
+  BFD_RELOC_PPC64_GOT16_DS,
+  BFD_RELOC_PPC64_GOT16_LO_DS,
+  BFD_RELOC_PPC64_PLT16_LO_DS,
+  BFD_RELOC_PPC64_SECTOFF_DS,
+  BFD_RELOC_PPC64_SECTOFF_LO_DS,
+  BFD_RELOC_PPC64_TOC16_DS,
+  BFD_RELOC_PPC64_TOC16_LO_DS,
+  BFD_RELOC_PPC64_PLTGOT16_DS,
+  BFD_RELOC_PPC64_PLTGOT16_LO_DS,
+
+/* PowerPC and PowerPC64 thread-local storage relocations.  */
+  BFD_RELOC_PPC_TLS,
+  BFD_RELOC_PPC_DTPMOD,
+  BFD_RELOC_PPC_TPREL16,
+  BFD_RELOC_PPC_TPREL16_LO,
+  BFD_RELOC_PPC_TPREL16_HI,
+  BFD_RELOC_PPC_TPREL16_HA,
+  BFD_RELOC_PPC_TPREL,
+  BFD_RELOC_PPC_DTPREL16,
+  BFD_RELOC_PPC_DTPREL16_LO,
+  BFD_RELOC_PPC_DTPREL16_HI,
+  BFD_RELOC_PPC_DTPREL16_HA,
+  BFD_RELOC_PPC_DTPREL,
+  BFD_RELOC_PPC_GOT_TLSGD16,
+  BFD_RELOC_PPC_GOT_TLSGD16_LO,
+  BFD_RELOC_PPC_GOT_TLSGD16_HI,
+  BFD_RELOC_PPC_GOT_TLSGD16_HA,
+  BFD_RELOC_PPC_GOT_TLSLD16,
+  BFD_RELOC_PPC_GOT_TLSLD16_LO,
+  BFD_RELOC_PPC_GOT_TLSLD16_HI,
+  BFD_RELOC_PPC_GOT_TLSLD16_HA,
+  BFD_RELOC_PPC_GOT_TPREL16,
+  BFD_RELOC_PPC_GOT_TPREL16_LO,
+  BFD_RELOC_PPC_GOT_TPREL16_HI,
+  BFD_RELOC_PPC_GOT_TPREL16_HA,
+  BFD_RELOC_PPC_GOT_DTPREL16,
+  BFD_RELOC_PPC_GOT_DTPREL16_LO,
+  BFD_RELOC_PPC_GOT_DTPREL16_HI,
+  BFD_RELOC_PPC_GOT_DTPREL16_HA,
+  BFD_RELOC_PPC64_TPREL16_DS,
+  BFD_RELOC_PPC64_TPREL16_LO_DS,
+  BFD_RELOC_PPC64_TPREL16_HIGHER,
+  BFD_RELOC_PPC64_TPREL16_HIGHERA,
+  BFD_RELOC_PPC64_TPREL16_HIGHEST,
+  BFD_RELOC_PPC64_TPREL16_HIGHESTA,
+  BFD_RELOC_PPC64_DTPREL16_DS,
+  BFD_RELOC_PPC64_DTPREL16_LO_DS,
+  BFD_RELOC_PPC64_DTPREL16_HIGHER,
+  BFD_RELOC_PPC64_DTPREL16_HIGHERA,
+  BFD_RELOC_PPC64_DTPREL16_HIGHEST,
+  BFD_RELOC_PPC64_DTPREL16_HIGHESTA,
+
+/* IBM 370/390 relocations  */
+  BFD_RELOC_I370_D12,
+
+/* The type of reloc used to build a contructor table - at the moment
+probably a 32 bit wide absolute relocation, but the target can choose.
+It generally does map to one of the other relocation types.  */
+  BFD_RELOC_CTOR,
+
+/* ARM 26 bit pc-relative branch.  The lowest two bits must be zero and are
+not stored in the instruction.  */
+  BFD_RELOC_ARM_PCREL_BRANCH,
+
+/* ARM 26 bit pc-relative branch.  The lowest bit must be zero and is
+not stored in the instruction.  The 2nd lowest bit comes from a 1 bit
+field in the instruction.  */
+  BFD_RELOC_ARM_PCREL_BLX,
+
+/* Thumb 22 bit pc-relative branch.  The lowest bit must be zero and is
+not stored in the instruction.  The 2nd lowest bit comes from a 1 bit
+field in the instruction.  */
+  BFD_RELOC_THUMB_PCREL_BLX,
+
+/* These relocs are only used within the ARM assembler.  They are not
+(at present) written to any object files.  */
+  BFD_RELOC_ARM_IMMEDIATE,
+  BFD_RELOC_ARM_ADRL_IMMEDIATE,
+  BFD_RELOC_ARM_OFFSET_IMM,
+  BFD_RELOC_ARM_SHIFT_IMM,
+  BFD_RELOC_ARM_SWI,
+  BFD_RELOC_ARM_MULTI,
+  BFD_RELOC_ARM_CP_OFF_IMM,
+  BFD_RELOC_ARM_CP_OFF_IMM_S2,
+  BFD_RELOC_ARM_ADR_IMM,
+  BFD_RELOC_ARM_LDR_IMM,
+  BFD_RELOC_ARM_LITERAL,
+  BFD_RELOC_ARM_IN_POOL,
+  BFD_RELOC_ARM_OFFSET_IMM8,
+  BFD_RELOC_ARM_HWLITERAL,
+  BFD_RELOC_ARM_THUMB_ADD,
+  BFD_RELOC_ARM_THUMB_IMM,
+  BFD_RELOC_ARM_THUMB_SHIFT,
+  BFD_RELOC_ARM_THUMB_OFFSET,
+  BFD_RELOC_ARM_GOT12,
+  BFD_RELOC_ARM_GOT32,
+  BFD_RELOC_ARM_JUMP_SLOT,
+  BFD_RELOC_ARM_COPY,
+  BFD_RELOC_ARM_GLOB_DAT,
+  BFD_RELOC_ARM_PLT32,
+  BFD_RELOC_ARM_RELATIVE,
+  BFD_RELOC_ARM_GOTOFF,
+  BFD_RELOC_ARM_GOTPC,
+
+/* Renesas / SuperH SH relocs.  Not all of these appear in object files.  */
+  BFD_RELOC_SH_PCDISP8BY2,
+  BFD_RELOC_SH_PCDISP12BY2,
+  BFD_RELOC_SH_IMM4,
+  BFD_RELOC_SH_IMM4BY2,
+  BFD_RELOC_SH_IMM4BY4,
+  BFD_RELOC_SH_IMM8,
+  BFD_RELOC_SH_IMM8BY2,
+  BFD_RELOC_SH_IMM8BY4,
+  BFD_RELOC_SH_PCRELIMM8BY2,
+  BFD_RELOC_SH_PCRELIMM8BY4,
+  BFD_RELOC_SH_SWITCH16,
+  BFD_RELOC_SH_SWITCH32,
+  BFD_RELOC_SH_USES,
+  BFD_RELOC_SH_COUNT,
+  BFD_RELOC_SH_ALIGN,
+  BFD_RELOC_SH_CODE,
+  BFD_RELOC_SH_DATA,
+  BFD_RELOC_SH_LABEL,
+  BFD_RELOC_SH_LOOP_START,
+  BFD_RELOC_SH_LOOP_END,
+  BFD_RELOC_SH_COPY,
+  BFD_RELOC_SH_GLOB_DAT,
+  BFD_RELOC_SH_JMP_SLOT,
+  BFD_RELOC_SH_RELATIVE,
+  BFD_RELOC_SH_GOTPC,
+  BFD_RELOC_SH_GOT_LOW16,
+  BFD_RELOC_SH_GOT_MEDLOW16,
+  BFD_RELOC_SH_GOT_MEDHI16,
+  BFD_RELOC_SH_GOT_HI16,
+  BFD_RELOC_SH_GOTPLT_LOW16,
+  BFD_RELOC_SH_GOTPLT_MEDLOW16,
+  BFD_RELOC_SH_GOTPLT_MEDHI16,
+  BFD_RELOC_SH_GOTPLT_HI16,
+  BFD_RELOC_SH_PLT_LOW16,
+  BFD_RELOC_SH_PLT_MEDLOW16,
+  BFD_RELOC_SH_PLT_MEDHI16,
+  BFD_RELOC_SH_PLT_HI16,
+  BFD_RELOC_SH_GOTOFF_LOW16,
+  BFD_RELOC_SH_GOTOFF_MEDLOW16,
+  BFD_RELOC_SH_GOTOFF_MEDHI16,
+  BFD_RELOC_SH_GOTOFF_HI16,
+  BFD_RELOC_SH_GOTPC_LOW16,
+  BFD_RELOC_SH_GOTPC_MEDLOW16,
+  BFD_RELOC_SH_GOTPC_MEDHI16,
+  BFD_RELOC_SH_GOTPC_HI16,
+  BFD_RELOC_SH_COPY64,
+  BFD_RELOC_SH_GLOB_DAT64,
+  BFD_RELOC_SH_JMP_SLOT64,
+  BFD_RELOC_SH_RELATIVE64,
+  BFD_RELOC_SH_GOT10BY4,
+  BFD_RELOC_SH_GOT10BY8,
+  BFD_RELOC_SH_GOTPLT10BY4,
+  BFD_RELOC_SH_GOTPLT10BY8,
+  BFD_RELOC_SH_GOTPLT32,
+  BFD_RELOC_SH_SHMEDIA_CODE,
+  BFD_RELOC_SH_IMMU5,
+  BFD_RELOC_SH_IMMS6,
+  BFD_RELOC_SH_IMMS6BY32,
+  BFD_RELOC_SH_IMMU6,
+  BFD_RELOC_SH_IMMS10,
+  BFD_RELOC_SH_IMMS10BY2,
+  BFD_RELOC_SH_IMMS10BY4,
+  BFD_RELOC_SH_IMMS10BY8,
+  BFD_RELOC_SH_IMMS16,
+  BFD_RELOC_SH_IMMU16,
+  BFD_RELOC_SH_IMM_LOW16,
+  BFD_RELOC_SH_IMM_LOW16_PCREL,
+  BFD_RELOC_SH_IMM_MEDLOW16,
+  BFD_RELOC_SH_IMM_MEDLOW16_PCREL,
+  BFD_RELOC_SH_IMM_MEDHI16,
+  BFD_RELOC_SH_IMM_MEDHI16_PCREL,
+  BFD_RELOC_SH_IMM_HI16,
+  BFD_RELOC_SH_IMM_HI16_PCREL,
+  BFD_RELOC_SH_PT_16,
+  BFD_RELOC_SH_TLS_GD_32,
+  BFD_RELOC_SH_TLS_LD_32,
+  BFD_RELOC_SH_TLS_LDO_32,
+  BFD_RELOC_SH_TLS_IE_32,
+  BFD_RELOC_SH_TLS_LE_32,
+  BFD_RELOC_SH_TLS_DTPMOD32,
+  BFD_RELOC_SH_TLS_DTPOFF32,
+  BFD_RELOC_SH_TLS_TPOFF32,
+
+/* Thumb 23-, 12- and 9-bit pc-relative branches.  The lowest bit must
+be zero and is not stored in the instruction.  */
+  BFD_RELOC_THUMB_PCREL_BRANCH9,
+  BFD_RELOC_THUMB_PCREL_BRANCH12,
+  BFD_RELOC_THUMB_PCREL_BRANCH23,
+
+/* ARC Cores relocs.
+ARC 22 bit pc-relative branch.  The lowest two bits must be zero and are
+not stored in the instruction.  The high 20 bits are installed in bits 26
+through 7 of the instruction.  */
+  BFD_RELOC_ARC_B22_PCREL,
+
+/* ARC 26 bit absolute branch.  The lowest two bits must be zero and are not
+stored in the instruction.  The high 24 bits are installed in bits 23
+through 0.  */
+  BFD_RELOC_ARC_B26,
+
+/* Mitsubishi D10V relocs.
+This is a 10-bit reloc with the right 2 bits
+assumed to be 0.  */
+  BFD_RELOC_D10V_10_PCREL_R,
+
+/* Mitsubishi D10V relocs.
+This is a 10-bit reloc with the right 2 bits
+assumed to be 0.  This is the same as the previous reloc
+except it is in the left container, i.e.,
+shifted left 15 bits.  */
+  BFD_RELOC_D10V_10_PCREL_L,
+
+/* This is an 18-bit reloc with the right 2 bits
+assumed to be 0.  */
+  BFD_RELOC_D10V_18,
+
+/* This is an 18-bit reloc with the right 2 bits
+assumed to be 0.  */
+  BFD_RELOC_D10V_18_PCREL,
+
+/* Mitsubishi D30V relocs.
+This is a 6-bit absolute reloc.  */
+  BFD_RELOC_D30V_6,
+
+/* This is a 6-bit pc-relative reloc with
+the right 3 bits assumed to be 0.  */
+  BFD_RELOC_D30V_9_PCREL,
+
+/* This is a 6-bit pc-relative reloc with
+the right 3 bits assumed to be 0. Same
+as the previous reloc but on the right side
+of the container.  */
+  BFD_RELOC_D30V_9_PCREL_R,
+
+/* This is a 12-bit absolute reloc with the
+right 3 bitsassumed to be 0.  */
+  BFD_RELOC_D30V_15,
+
+/* This is a 12-bit pc-relative reloc with
+the right 3 bits assumed to be 0.  */
+  BFD_RELOC_D30V_15_PCREL,
+
+/* This is a 12-bit pc-relative reloc with
+the right 3 bits assumed to be 0. Same
+as the previous reloc but on the right side
+of the container.  */
+  BFD_RELOC_D30V_15_PCREL_R,
+
+/* This is an 18-bit absolute reloc with
+the right 3 bits assumed to be 0.  */
+  BFD_RELOC_D30V_21,
+
+/* This is an 18-bit pc-relative reloc with
+the right 3 bits assumed to be 0.  */
+  BFD_RELOC_D30V_21_PCREL,
+
+/* This is an 18-bit pc-relative reloc with
+the right 3 bits assumed to be 0. Same
+as the previous reloc but on the right side
+of the container.  */
+  BFD_RELOC_D30V_21_PCREL_R,
+
+/* This is a 32-bit absolute reloc.  */
+  BFD_RELOC_D30V_32,
+
+/* This is a 32-bit pc-relative reloc.  */
+  BFD_RELOC_D30V_32_PCREL,
+
+/* DLX relocs  */
+  BFD_RELOC_DLX_HI16_S,
+
+/* DLX relocs  */
+  BFD_RELOC_DLX_LO16,
+
+/* DLX relocs  */
+  BFD_RELOC_DLX_JMP26,
+
+/* Renesas M32R (formerly Mitsubishi M32R) relocs.
+This is a 24 bit absolute address.  */
+  BFD_RELOC_M32R_24,
+
+/* This is a 10-bit pc-relative reloc with the right 2 bits assumed to be 0.  */
+  BFD_RELOC_M32R_10_PCREL,
+
+/* This is an 18-bit reloc with the right 2 bits assumed to be 0.  */
+  BFD_RELOC_M32R_18_PCREL,
+
+/* This is a 26-bit reloc with the right 2 bits assumed to be 0.  */
+  BFD_RELOC_M32R_26_PCREL,
+
+/* This is a 16-bit reloc containing the high 16 bits of an address
+used when the lower 16 bits are treated as unsigned.  */
+  BFD_RELOC_M32R_HI16_ULO,
+
+/* This is a 16-bit reloc containing the high 16 bits of an address
+used when the lower 16 bits are treated as signed.  */
+  BFD_RELOC_M32R_HI16_SLO,
+
+/* This is a 16-bit reloc containing the lower 16 bits of an address.  */
+  BFD_RELOC_M32R_LO16,
+
+/* This is a 16-bit reloc containing the small data area offset for use in
+add3, load, and store instructions.  */
+  BFD_RELOC_M32R_SDA16,
+
+/* This is a 9-bit reloc  */
+  BFD_RELOC_V850_9_PCREL,
+
+/* This is a 22-bit reloc  */
+  BFD_RELOC_V850_22_PCREL,
+
+/* This is a 16 bit offset from the short data area pointer.  */
+  BFD_RELOC_V850_SDA_16_16_OFFSET,
+
+/* This is a 16 bit offset (of which only 15 bits are used) from the
+short data area pointer.  */
+  BFD_RELOC_V850_SDA_15_16_OFFSET,
+
+/* This is a 16 bit offset from the zero data area pointer.  */
+  BFD_RELOC_V850_ZDA_16_16_OFFSET,
+
+/* This is a 16 bit offset (of which only 15 bits are used) from the
+zero data area pointer.  */
+  BFD_RELOC_V850_ZDA_15_16_OFFSET,
+
+/* This is an 8 bit offset (of which only 6 bits are used) from the
+tiny data area pointer.  */
+  BFD_RELOC_V850_TDA_6_8_OFFSET,
+
+/* This is an 8bit offset (of which only 7 bits are used) from the tiny
+data area pointer.  */
+  BFD_RELOC_V850_TDA_7_8_OFFSET,
+
+/* This is a 7 bit offset from the tiny data area pointer.  */
+  BFD_RELOC_V850_TDA_7_7_OFFSET,
+
+/* This is a 16 bit offset from the tiny data area pointer.  */
+  BFD_RELOC_V850_TDA_16_16_OFFSET,
+
+/* This is a 5 bit offset (of which only 4 bits are used) from the tiny
+data area pointer.  */
+  BFD_RELOC_V850_TDA_4_5_OFFSET,
+
+/* This is a 4 bit offset from the tiny data area pointer.  */
+  BFD_RELOC_V850_TDA_4_4_OFFSET,
+
+/* This is a 16 bit offset from the short data area pointer, with the
+bits placed non-contigously in the instruction.  */
+  BFD_RELOC_V850_SDA_16_16_SPLIT_OFFSET,
+
+/* This is a 16 bit offset from the zero data area pointer, with the
+bits placed non-contigously in the instruction.  */
+  BFD_RELOC_V850_ZDA_16_16_SPLIT_OFFSET,
+
+/* This is a 6 bit offset from the call table base pointer.  */
+  BFD_RELOC_V850_CALLT_6_7_OFFSET,
+
+/* This is a 16 bit offset from the call table base pointer.  */
+  BFD_RELOC_V850_CALLT_16_16_OFFSET,
+
+/* Used for relaxing indirect function calls.  */
+  BFD_RELOC_V850_LONGCALL,
+
+/* Used for relaxing indirect jumps.  */
+  BFD_RELOC_V850_LONGJUMP,
+
+/* Used to maintain alignment whilst relaxing.  */
+  BFD_RELOC_V850_ALIGN,
+
+/* This is a 32bit pcrel reloc for the mn10300, offset by two bytes in the
+instruction.  */
+  BFD_RELOC_MN10300_32_PCREL,
+
+/* This is a 16bit pcrel reloc for the mn10300, offset by two bytes in the
+instruction.  */
+  BFD_RELOC_MN10300_16_PCREL,
+
+/* This is a 8bit DP reloc for the tms320c30, where the most
+significant 8 bits of a 24 bit word are placed into the least
+significant 8 bits of the opcode.  */
+  BFD_RELOC_TIC30_LDP,
+
+/* This is a 7bit reloc for the tms320c54x, where the least
+significant 7 bits of a 16 bit word are placed into the least
+significant 7 bits of the opcode.  */
+  BFD_RELOC_TIC54X_PARTLS7,
+
+/* This is a 9bit DP reloc for the tms320c54x, where the most
+significant 9 bits of a 16 bit word are placed into the least
+significant 9 bits of the opcode.  */
+  BFD_RELOC_TIC54X_PARTMS9,
+
+/* This is an extended address 23-bit reloc for the tms320c54x.  */
+  BFD_RELOC_TIC54X_23,
+
+/* This is a 16-bit reloc for the tms320c54x, where the least
+significant 16 bits of a 23-bit extended address are placed into
+the opcode.  */
+  BFD_RELOC_TIC54X_16_OF_23,
+
+/* This is a reloc for the tms320c54x, where the most
+significant 7 bits of a 23-bit extended address are placed into
+the opcode.  */
+  BFD_RELOC_TIC54X_MS7_OF_23,
+
+/* This is a 48 bit reloc for the FR30 that stores 32 bits.  */
+  BFD_RELOC_FR30_48,
+
+/* This is a 32 bit reloc for the FR30 that stores 20 bits split up into
+two sections.  */
+  BFD_RELOC_FR30_20,
+
+/* This is a 16 bit reloc for the FR30 that stores a 6 bit word offset in
+4 bits.  */
+  BFD_RELOC_FR30_6_IN_4,
+
+/* This is a 16 bit reloc for the FR30 that stores an 8 bit byte offset
+into 8 bits.  */
+  BFD_RELOC_FR30_8_IN_8,
+
+/* This is a 16 bit reloc for the FR30 that stores a 9 bit short offset
+into 8 bits.  */
+  BFD_RELOC_FR30_9_IN_8,
+
+/* This is a 16 bit reloc for the FR30 that stores a 10 bit word offset
+into 8 bits.  */
+  BFD_RELOC_FR30_10_IN_8,
+
+/* This is a 16 bit reloc for the FR30 that stores a 9 bit pc relative
+short offset into 8 bits.  */
+  BFD_RELOC_FR30_9_PCREL,
+
+/* This is a 16 bit reloc for the FR30 that stores a 12 bit pc relative
+short offset into 11 bits.  */
+  BFD_RELOC_FR30_12_PCREL,
+
+/* Motorola Mcore relocations.  */
+  BFD_RELOC_MCORE_PCREL_IMM8BY4,
+  BFD_RELOC_MCORE_PCREL_IMM11BY2,
+  BFD_RELOC_MCORE_PCREL_IMM4BY2,
+  BFD_RELOC_MCORE_PCREL_32,
+  BFD_RELOC_MCORE_PCREL_JSR_IMM11BY2,
+  BFD_RELOC_MCORE_RVA,
+
+/* These are relocations for the GETA instruction.  */
+  BFD_RELOC_MMIX_GETA,
+  BFD_RELOC_MMIX_GETA_1,
+  BFD_RELOC_MMIX_GETA_2,
+  BFD_RELOC_MMIX_GETA_3,
+
+/* These are relocations for a conditional branch instruction.  */
+  BFD_RELOC_MMIX_CBRANCH,
+  BFD_RELOC_MMIX_CBRANCH_J,
+  BFD_RELOC_MMIX_CBRANCH_1,
+  BFD_RELOC_MMIX_CBRANCH_2,
+  BFD_RELOC_MMIX_CBRANCH_3,
+
+/* These are relocations for the PUSHJ instruction.  */
+  BFD_RELOC_MMIX_PUSHJ,
+  BFD_RELOC_MMIX_PUSHJ_1,
+  BFD_RELOC_MMIX_PUSHJ_2,
+  BFD_RELOC_MMIX_PUSHJ_3,
+
+/* These are relocations for the JMP instruction.  */
+  BFD_RELOC_MMIX_JMP,
+  BFD_RELOC_MMIX_JMP_1,
+  BFD_RELOC_MMIX_JMP_2,
+  BFD_RELOC_MMIX_JMP_3,
+
+/* This is a relocation for a relative address as in a GETA instruction or
+a branch.  */
+  BFD_RELOC_MMIX_ADDR19,
+
+/* This is a relocation for a relative address as in a JMP instruction.  */
+  BFD_RELOC_MMIX_ADDR27,
+
+/* This is a relocation for an instruction field that may be a general
+register or a value 0..255.  */
+  BFD_RELOC_MMIX_REG_OR_BYTE,
+
+/* This is a relocation for an instruction field that may be a general
+register.  */
+  BFD_RELOC_MMIX_REG,
+
+/* This is a relocation for two instruction fields holding a register and
+an offset, the equivalent of the relocation.  */
+  BFD_RELOC_MMIX_BASE_PLUS_OFFSET,
+
+/* This relocation is an assertion that the expression is not allocated as
+a global register.  It does not modify contents.  */
+  BFD_RELOC_MMIX_LOCAL,
+
+/* This is a 16 bit reloc for the AVR that stores 8 bit pc relative
+short offset into 7 bits.  */
+  BFD_RELOC_AVR_7_PCREL,
+
+/* This is a 16 bit reloc for the AVR that stores 13 bit pc relative
+short offset into 12 bits.  */
+  BFD_RELOC_AVR_13_PCREL,
+
+/* This is a 16 bit reloc for the AVR that stores 17 bit value (usually
+program memory address) into 16 bits.  */
+  BFD_RELOC_AVR_16_PM,
+
+/* This is a 16 bit reloc for the AVR that stores 8 bit value (usually
+data memory address) into 8 bit immediate value of LDI insn.  */
+  BFD_RELOC_AVR_LO8_LDI,
+
+/* This is a 16 bit reloc for the AVR that stores 8 bit value (high 8 bit
+of data memory address) into 8 bit immediate value of LDI insn.  */
+  BFD_RELOC_AVR_HI8_LDI,
+
+/* This is a 16 bit reloc for the AVR that stores 8 bit value (most high 8 bit
+of program memory address) into 8 bit immediate value of LDI insn.  */
+  BFD_RELOC_AVR_HH8_LDI,
+
+/* This is a 16 bit reloc for the AVR that stores negated 8 bit value
+(usually data memory address) into 8 bit immediate value of SUBI insn.  */
+  BFD_RELOC_AVR_LO8_LDI_NEG,
+
+/* This is a 16 bit reloc for the AVR that stores negated 8 bit value
+(high 8 bit of data memory address) into 8 bit immediate value of
+SUBI insn.  */
+  BFD_RELOC_AVR_HI8_LDI_NEG,
+
+/* This is a 16 bit reloc for the AVR that stores negated 8 bit value
+(most high 8 bit of program memory address) into 8 bit immediate value
+of LDI or SUBI insn.  */
+  BFD_RELOC_AVR_HH8_LDI_NEG,
+
+/* This is a 16 bit reloc for the AVR that stores 8 bit value (usually
+command address) into 8 bit immediate value of LDI insn.  */
+  BFD_RELOC_AVR_LO8_LDI_PM,
+
+/* This is a 16 bit reloc for the AVR that stores 8 bit value (high 8 bit
+of command address) into 8 bit immediate value of LDI insn.  */
+  BFD_RELOC_AVR_HI8_LDI_PM,
+
+/* This is a 16 bit reloc for the AVR that stores 8 bit value (most high 8 bit
+of command address) into 8 bit immediate value of LDI insn.  */
+  BFD_RELOC_AVR_HH8_LDI_PM,
+
+/* This is a 16 bit reloc for the AVR that stores negated 8 bit value
+(usually command address) into 8 bit immediate value of SUBI insn.  */
+  BFD_RELOC_AVR_LO8_LDI_PM_NEG,
+
+/* This is a 16 bit reloc for the AVR that stores negated 8 bit value
+(high 8 bit of 16 bit command address) into 8 bit immediate value
+of SUBI insn.  */
+  BFD_RELOC_AVR_HI8_LDI_PM_NEG,
+
+/* This is a 16 bit reloc for the AVR that stores negated 8 bit value
+(high 6 bit of 22 bit command address) into 8 bit immediate
+value of SUBI insn.  */
+  BFD_RELOC_AVR_HH8_LDI_PM_NEG,
+
+/* This is a 32 bit reloc for the AVR that stores 23 bit value
+into 22 bits.  */
+  BFD_RELOC_AVR_CALL,
+
+/* Direct 12 bit.  */
+  BFD_RELOC_390_12,
+
+/* 12 bit GOT offset.  */
+  BFD_RELOC_390_GOT12,
+
+/* 32 bit PC relative PLT address.  */
+  BFD_RELOC_390_PLT32,
+
+/* Copy symbol at runtime.  */
+  BFD_RELOC_390_COPY,
+
+/* Create GOT entry.  */
+  BFD_RELOC_390_GLOB_DAT,
+
+/* Create PLT entry.  */
+  BFD_RELOC_390_JMP_SLOT,
+
+/* Adjust by program base.  */
+  BFD_RELOC_390_RELATIVE,
+
+/* 32 bit PC relative offset to GOT.  */
+  BFD_RELOC_390_GOTPC,
+
+/* 16 bit GOT offset.  */
+  BFD_RELOC_390_GOT16,
+
+/* PC relative 16 bit shifted by 1.  */
+  BFD_RELOC_390_PC16DBL,
+
+/* 16 bit PC rel. PLT shifted by 1.  */
+  BFD_RELOC_390_PLT16DBL,
+
+/* PC relative 32 bit shifted by 1.  */
+  BFD_RELOC_390_PC32DBL,
+
+/* 32 bit PC rel. PLT shifted by 1.  */
+  BFD_RELOC_390_PLT32DBL,
+
+/* 32 bit PC rel. GOT shifted by 1.  */
+  BFD_RELOC_390_GOTPCDBL,
+
+/* 64 bit GOT offset.  */
+  BFD_RELOC_390_GOT64,
+
+/* 64 bit PC relative PLT address.  */
+  BFD_RELOC_390_PLT64,
+
+/* 32 bit rel. offset to GOT entry.  */
+  BFD_RELOC_390_GOTENT,
+
+/* 64 bit offset to GOT.  */
+  BFD_RELOC_390_GOTOFF64,
+
+/* 12-bit offset to symbol-entry within GOT, with PLT handling.  */
+  BFD_RELOC_390_GOTPLT12,
+
+/* 16-bit offset to symbol-entry within GOT, with PLT handling.  */
+  BFD_RELOC_390_GOTPLT16,
+
+/* 32-bit offset to symbol-entry within GOT, with PLT handling.  */
+  BFD_RELOC_390_GOTPLT32,
+
+/* 64-bit offset to symbol-entry within GOT, with PLT handling.  */
+  BFD_RELOC_390_GOTPLT64,
+
+/* 32-bit rel. offset to symbol-entry within GOT, with PLT handling.  */
+  BFD_RELOC_390_GOTPLTENT,
+
+/* 16-bit rel. offset from the GOT to a PLT entry.  */
+  BFD_RELOC_390_PLTOFF16,
+
+/* 32-bit rel. offset from the GOT to a PLT entry.  */
+  BFD_RELOC_390_PLTOFF32,
+
+/* 64-bit rel. offset from the GOT to a PLT entry.  */
+  BFD_RELOC_390_PLTOFF64,
+
+/* s390 tls relocations.  */
+  BFD_RELOC_390_TLS_LOAD,
+  BFD_RELOC_390_TLS_GDCALL,
+  BFD_RELOC_390_TLS_LDCALL,
+  BFD_RELOC_390_TLS_GD32,
+  BFD_RELOC_390_TLS_GD64,
+  BFD_RELOC_390_TLS_GOTIE12,
+  BFD_RELOC_390_TLS_GOTIE32,
+  BFD_RELOC_390_TLS_GOTIE64,
+  BFD_RELOC_390_TLS_LDM32,
+  BFD_RELOC_390_TLS_LDM64,
+  BFD_RELOC_390_TLS_IE32,
+  BFD_RELOC_390_TLS_IE64,
+  BFD_RELOC_390_TLS_IEENT,
+  BFD_RELOC_390_TLS_LE32,
+  BFD_RELOC_390_TLS_LE64,
+  BFD_RELOC_390_TLS_LDO32,
+  BFD_RELOC_390_TLS_LDO64,
+  BFD_RELOC_390_TLS_DTPMOD,
+  BFD_RELOC_390_TLS_DTPOFF,
+  BFD_RELOC_390_TLS_TPOFF,
+
+/* Scenix IP2K - 9-bit register number / data address  */
+  BFD_RELOC_IP2K_FR9,
+
+/* Scenix IP2K - 4-bit register/data bank number  */
+  BFD_RELOC_IP2K_BANK,
+
+/* Scenix IP2K - low 13 bits of instruction word address  */
+  BFD_RELOC_IP2K_ADDR16CJP,
+
+/* Scenix IP2K - high 3 bits of instruction word address  */
+  BFD_RELOC_IP2K_PAGE3,
+
+/* Scenix IP2K - ext/low/high 8 bits of data address  */
+  BFD_RELOC_IP2K_LO8DATA,
+  BFD_RELOC_IP2K_HI8DATA,
+  BFD_RELOC_IP2K_EX8DATA,
+
+/* Scenix IP2K - low/high 8 bits of instruction word address  */
+  BFD_RELOC_IP2K_LO8INSN,
+  BFD_RELOC_IP2K_HI8INSN,
+
+/* Scenix IP2K - even/odd PC modifier to modify snb pcl.0  */
+  BFD_RELOC_IP2K_PC_SKIP,
+
+/* Scenix IP2K - 16 bit word address in text section.  */
+  BFD_RELOC_IP2K_TEXT,
+
+/* Scenix IP2K - 7-bit sp or dp offset  */
+  BFD_RELOC_IP2K_FR_OFFSET,
+
+/* Scenix VPE4K coprocessor - data/insn-space addressing  */
+  BFD_RELOC_VPE4KMATH_DATA,
+  BFD_RELOC_VPE4KMATH_INSN,
+
+/* These two relocations are used by the linker to determine which of
+the entries in a C++ virtual function table are actually used.  When
+the --gc-sections option is given, the linker will zero out the entries
+that are not used, so that the code for those functions need not be
+included in the output.
+
+VTABLE_INHERIT is a zero-space relocation used to describe to the
+linker the inheritence tree of a C++ virtual function table.  The
+relocation's symbol should be the parent class' vtable, and the
+relocation should be located at the child vtable.
+
+VTABLE_ENTRY is a zero-space relocation that describes the use of a
+virtual function table entry.  The reloc's symbol should refer to the
+table of the class mentioned in the code.  Off of that base, an offset
+describes the entry that is being used.  For Rela hosts, this offset
+is stored in the reloc's addend.  For Rel hosts, we are forced to put
+this offset in the reloc's section offset.  */
+  BFD_RELOC_VTABLE_INHERIT,
+  BFD_RELOC_VTABLE_ENTRY,
+
+/* Intel IA64 Relocations.  */
+  BFD_RELOC_IA64_IMM14,
+  BFD_RELOC_IA64_IMM22,
+  BFD_RELOC_IA64_IMM64,
+  BFD_RELOC_IA64_DIR32MSB,
+  BFD_RELOC_IA64_DIR32LSB,
+  BFD_RELOC_IA64_DIR64MSB,
+  BFD_RELOC_IA64_DIR64LSB,
+  BFD_RELOC_IA64_GPREL22,
+  BFD_RELOC_IA64_GPREL64I,
+  BFD_RELOC_IA64_GPREL32MSB,
+  BFD_RELOC_IA64_GPREL32LSB,
+  BFD_RELOC_IA64_GPREL64MSB,
+  BFD_RELOC_IA64_GPREL64LSB,
+  BFD_RELOC_IA64_LTOFF22,
+  BFD_RELOC_IA64_LTOFF64I,
+  BFD_RELOC_IA64_PLTOFF22,
+  BFD_RELOC_IA64_PLTOFF64I,
+  BFD_RELOC_IA64_PLTOFF64MSB,
+  BFD_RELOC_IA64_PLTOFF64LSB,
+  BFD_RELOC_IA64_FPTR64I,
+  BFD_RELOC_IA64_FPTR32MSB,
+  BFD_RELOC_IA64_FPTR32LSB,
+  BFD_RELOC_IA64_FPTR64MSB,
+  BFD_RELOC_IA64_FPTR64LSB,
+  BFD_RELOC_IA64_PCREL21B,
+  BFD_RELOC_IA64_PCREL21BI,
+  BFD_RELOC_IA64_PCREL21M,
+  BFD_RELOC_IA64_PCREL21F,
+  BFD_RELOC_IA64_PCREL22,
+  BFD_RELOC_IA64_PCREL60B,
+  BFD_RELOC_IA64_PCREL64I,
+  BFD_RELOC_IA64_PCREL32MSB,
+  BFD_RELOC_IA64_PCREL32LSB,
+  BFD_RELOC_IA64_PCREL64MSB,
+  BFD_RELOC_IA64_PCREL64LSB,
+  BFD_RELOC_IA64_LTOFF_FPTR22,
+  BFD_RELOC_IA64_LTOFF_FPTR64I,
+  BFD_RELOC_IA64_LTOFF_FPTR32MSB,
+  BFD_RELOC_IA64_LTOFF_FPTR32LSB,
+  BFD_RELOC_IA64_LTOFF_FPTR64MSB,
+  BFD_RELOC_IA64_LTOFF_FPTR64LSB,
+  BFD_RELOC_IA64_SEGREL32MSB,
+  BFD_RELOC_IA64_SEGREL32LSB,
+  BFD_RELOC_IA64_SEGREL64MSB,
+  BFD_RELOC_IA64_SEGREL64LSB,
+  BFD_RELOC_IA64_SECREL32MSB,
+  BFD_RELOC_IA64_SECREL32LSB,
+  BFD_RELOC_IA64_SECREL64MSB,
+  BFD_RELOC_IA64_SECREL64LSB,
+  BFD_RELOC_IA64_REL32MSB,
+  BFD_RELOC_IA64_REL32LSB,
+  BFD_RELOC_IA64_REL64MSB,
+  BFD_RELOC_IA64_REL64LSB,
+  BFD_RELOC_IA64_LTV32MSB,
+  BFD_RELOC_IA64_LTV32LSB,
+  BFD_RELOC_IA64_LTV64MSB,
+  BFD_RELOC_IA64_LTV64LSB,
+  BFD_RELOC_IA64_IPLTMSB,
+  BFD_RELOC_IA64_IPLTLSB,
+  BFD_RELOC_IA64_COPY,
+  BFD_RELOC_IA64_LTOFF22X,
+  BFD_RELOC_IA64_LDXMOV,
+  BFD_RELOC_IA64_TPREL14,
+  BFD_RELOC_IA64_TPREL22,
+  BFD_RELOC_IA64_TPREL64I,
+  BFD_RELOC_IA64_TPREL64MSB,
+  BFD_RELOC_IA64_TPREL64LSB,
+  BFD_RELOC_IA64_LTOFF_TPREL22,
+  BFD_RELOC_IA64_DTPMOD64MSB,
+  BFD_RELOC_IA64_DTPMOD64LSB,
+  BFD_RELOC_IA64_LTOFF_DTPMOD22,
+  BFD_RELOC_IA64_DTPREL14,
+  BFD_RELOC_IA64_DTPREL22,
+  BFD_RELOC_IA64_DTPREL64I,
+  BFD_RELOC_IA64_DTPREL32MSB,
+  BFD_RELOC_IA64_DTPREL32LSB,
+  BFD_RELOC_IA64_DTPREL64MSB,
+  BFD_RELOC_IA64_DTPREL64LSB,
+  BFD_RELOC_IA64_LTOFF_DTPREL22,
+
+/* Motorola 68HC11 reloc.
+This is the 8 bit high part of an absolute address.  */
+  BFD_RELOC_M68HC11_HI8,
+
+/* Motorola 68HC11 reloc.
+This is the 8 bit low part of an absolute address.  */
+  BFD_RELOC_M68HC11_LO8,
+
+/* Motorola 68HC11 reloc.
+This is the 3 bit of a value.  */
+  BFD_RELOC_M68HC11_3B,
+
+/* Motorola 68HC11 reloc.
+This reloc marks the beginning of a jump/call instruction.
+It is used for linker relaxation to correctly identify beginning
+of instruction and change some branchs to use PC-relative
+addressing mode.  */
+  BFD_RELOC_M68HC11_RL_JUMP,
+
+/* Motorola 68HC11 reloc.
+This reloc marks a group of several instructions that gcc generates
+and for which the linker relaxation pass can modify and/or remove
+some of them.  */
+  BFD_RELOC_M68HC11_RL_GROUP,
+
+/* Motorola 68HC11 reloc.
+This is the 16-bit lower part of an address.  It is used for 'call'
+instruction to specify the symbol address without any special
+transformation (due to memory bank window).  */
+  BFD_RELOC_M68HC11_LO16,
+
+/* Motorola 68HC11 reloc.
+This is a 8-bit reloc that specifies the page number of an address.
+It is used by 'call' instruction to specify the page number of
+the symbol.  */
+  BFD_RELOC_M68HC11_PAGE,
+
+/* Motorola 68HC11 reloc.
+This is a 24-bit reloc that represents the address with a 16-bit
+value and a 8-bit page number.  The symbol address is transformed
+to follow the 16K memory bank of 68HC12 (seen as mapped in the window).  */
+  BFD_RELOC_M68HC11_24,
+
+/* These relocs are only used within the CRIS assembler.  They are not
+(at present) written to any object files.  */
+  BFD_RELOC_CRIS_BDISP8,
+  BFD_RELOC_CRIS_UNSIGNED_5,
+  BFD_RELOC_CRIS_SIGNED_6,
+  BFD_RELOC_CRIS_UNSIGNED_6,
+  BFD_RELOC_CRIS_UNSIGNED_4,
+
+/* Relocs used in ELF shared libraries for CRIS.  */
+  BFD_RELOC_CRIS_COPY,
+  BFD_RELOC_CRIS_GLOB_DAT,
+  BFD_RELOC_CRIS_JUMP_SLOT,
+  BFD_RELOC_CRIS_RELATIVE,
+
+/* 32-bit offset to symbol-entry within GOT.  */
+  BFD_RELOC_CRIS_32_GOT,
+
+/* 16-bit offset to symbol-entry within GOT.  */
+  BFD_RELOC_CRIS_16_GOT,
+
+/* 32-bit offset to symbol-entry within GOT, with PLT handling.  */
+  BFD_RELOC_CRIS_32_GOTPLT,
+
+/* 16-bit offset to symbol-entry within GOT, with PLT handling.  */
+  BFD_RELOC_CRIS_16_GOTPLT,
+
+/* 32-bit offset to symbol, relative to GOT.  */
+  BFD_RELOC_CRIS_32_GOTREL,
+
+/* 32-bit offset to symbol with PLT entry, relative to GOT.  */
+  BFD_RELOC_CRIS_32_PLT_GOTREL,
+
+/* 32-bit offset to symbol with PLT entry, relative to this relocation.  */
+  BFD_RELOC_CRIS_32_PLT_PCREL,
+
+/* Intel i860 Relocations.  */
+  BFD_RELOC_860_COPY,
+  BFD_RELOC_860_GLOB_DAT,
+  BFD_RELOC_860_JUMP_SLOT,
+  BFD_RELOC_860_RELATIVE,
+  BFD_RELOC_860_PC26,
+  BFD_RELOC_860_PLT26,
+  BFD_RELOC_860_PC16,
+  BFD_RELOC_860_LOW0,
+  BFD_RELOC_860_SPLIT0,
+  BFD_RELOC_860_LOW1,
+  BFD_RELOC_860_SPLIT1,
+  BFD_RELOC_860_LOW2,
+  BFD_RELOC_860_SPLIT2,
+  BFD_RELOC_860_LOW3,
+  BFD_RELOC_860_LOGOT0,
+  BFD_RELOC_860_SPGOT0,
+  BFD_RELOC_860_LOGOT1,
+  BFD_RELOC_860_SPGOT1,
+  BFD_RELOC_860_LOGOTOFF0,
+  BFD_RELOC_860_SPGOTOFF0,
+  BFD_RELOC_860_LOGOTOFF1,
+  BFD_RELOC_860_SPGOTOFF1,
+  BFD_RELOC_860_LOGOTOFF2,
+  BFD_RELOC_860_LOGOTOFF3,
+  BFD_RELOC_860_LOPC,
+  BFD_RELOC_860_HIGHADJ,
+  BFD_RELOC_860_HAGOT,
+  BFD_RELOC_860_HAGOTOFF,
+  BFD_RELOC_860_HAPC,
+  BFD_RELOC_860_HIGH,
+  BFD_RELOC_860_HIGOT,
+  BFD_RELOC_860_HIGOTOFF,
+
+/* OpenRISC Relocations.  */
+  BFD_RELOC_OPENRISC_ABS_26,
+  BFD_RELOC_OPENRISC_REL_26,
+
+/* H8 elf Relocations.  */
+  BFD_RELOC_H8_DIR16A8,
+  BFD_RELOC_H8_DIR16R8,
+  BFD_RELOC_H8_DIR24A8,
+  BFD_RELOC_H8_DIR24R8,
+  BFD_RELOC_H8_DIR32A16,
+
+/* Sony Xstormy16 Relocations.  */
+  BFD_RELOC_XSTORMY16_REL_12,
+  BFD_RELOC_XSTORMY16_12,
+  BFD_RELOC_XSTORMY16_24,
+  BFD_RELOC_XSTORMY16_FPTR16,
+
+/* Relocations used by VAX ELF.  */
+  BFD_RELOC_VAX_GLOB_DAT,
+  BFD_RELOC_VAX_JMP_SLOT,
+  BFD_RELOC_VAX_RELATIVE,
+
+/* msp430 specific relocation codes  */
+  BFD_RELOC_MSP430_10_PCREL,
+  BFD_RELOC_MSP430_16_PCREL,
+  BFD_RELOC_MSP430_16,
+  BFD_RELOC_MSP430_16_PCREL_BYTE,
+  BFD_RELOC_MSP430_16_BYTE,
+
+/* IQ2000 Relocations.  */
+  BFD_RELOC_IQ2000_OFFSET_16,
+  BFD_RELOC_IQ2000_OFFSET_21,
+  BFD_RELOC_IQ2000_UHI16,
+
+/* Special Xtensa relocation used only by PLT entries in ELF shared
+objects to indicate that the runtime linker should set the value
+to one of its own internal functions or data structures.  */
+  BFD_RELOC_XTENSA_RTLD,
+
+/* Xtensa relocations for ELF shared objects.  */
+  BFD_RELOC_XTENSA_GLOB_DAT,
+  BFD_RELOC_XTENSA_JMP_SLOT,
+  BFD_RELOC_XTENSA_RELATIVE,
+
+/* Xtensa relocation used in ELF object files for symbols that may require
+PLT entries.  Otherwise, this is just a generic 32-bit relocation.  */
+  BFD_RELOC_XTENSA_PLT,
+
+/* Generic Xtensa relocations.  Only the operand number is encoded
+in the relocation.  The details are determined by extracting the
+instruction opcode.  */
+  BFD_RELOC_XTENSA_OP0,
+  BFD_RELOC_XTENSA_OP1,
+  BFD_RELOC_XTENSA_OP2,
+
+/* Xtensa relocation to mark that the assembler expanded the 
+instructions from an original target.  The expansion size is
+encoded in the reloc size.  */
+  BFD_RELOC_XTENSA_ASM_EXPAND,
+
+/* Xtensa relocation to mark that the linker should simplify 
+assembler-expanded instructions.  This is commonly used 
+internally by the linker after analysis of a 
+BFD_RELOC_XTENSA_ASM_EXPAND.  */
+  BFD_RELOC_XTENSA_ASM_SIMPLIFY,
+  BFD_RELOC_UNUSED };
+typedef enum bfd_reloc_code_real bfd_reloc_code_real_type;
+reloc_howto_type *
+bfd_reloc_type_lookup PARAMS ((bfd *abfd, bfd_reloc_code_real_type code));
+
+const char *
+bfd_get_reloc_code_name PARAMS ((bfd_reloc_code_real_type code));
+
+/* Extracted from syms.c.  */
+
+typedef struct symbol_cache_entry
+{
+  /* A pointer to the BFD which owns the symbol. This information
+     is necessary so that a back end can work out what additional
+     information (invisible to the application writer) is carried
+     with the symbol.
+
+     This field is *almost* redundant, since you can use section->owner
+     instead, except that some symbols point to the global sections
+     bfd_{abs,com,und}_section.  This could be fixed by making
+     these globals be per-bfd (or per-target-flavor).  FIXME.  */
+  struct bfd *the_bfd; /* Use bfd_asymbol_bfd(sym) to access this field.  */
+
+  /* The text of the symbol. The name is left alone, and not copied; the
+     application may not alter it.  */
+  const char *name;
+
+  /* The value of the symbol.  This really should be a union of a
+     numeric value with a pointer, since some flags indicate that
+     a pointer to another symbol is stored here.  */
+  symvalue value;
+
+  /* Attributes of a symbol.  */
+#define BSF_NO_FLAGS    0x00
+
+  /* The symbol has local scope; <<static>> in <<C>>. The value
+     is the offset into the section of the data.  */
+#define BSF_LOCAL      0x01
+
+  /* The symbol has global scope; initialized data in <<C>>. The
+     value is the offset into the section of the data.  */
+#define BSF_GLOBAL     0x02
+
+  /* The symbol has global scope and is exported. The value is
+     the offset into the section of the data.  */
+#define BSF_EXPORT     BSF_GLOBAL /* No real difference.  */
+
+  /* A normal C symbol would be one of:
+     <<BSF_LOCAL>>, <<BSF_FORT_COMM>>,  <<BSF_UNDEFINED>> or
+     <<BSF_GLOBAL>>.  */
+
+  /* The symbol is a debugging record. The value has an arbitary
+     meaning, unless BSF_DEBUGGING_RELOC is also set.  */
+#define BSF_DEBUGGING  0x08
+
+  /* The symbol denotes a function entry point.  Used in ELF,
+     perhaps others someday.  */
+#define BSF_FUNCTION    0x10
+
+  /* Used by the linker.  */
+#define BSF_KEEP        0x20
+#define BSF_KEEP_G      0x40
+
+  /* A weak global symbol, overridable without warnings by
+     a regular global symbol of the same name.  */
+#define BSF_WEAK        0x80
+
+  /* This symbol was created to point to a section, e.g. ELF's
+     STT_SECTION symbols.  */
+#define BSF_SECTION_SYM 0x100
+
+  /* The symbol used to be a common symbol, but now it is
+     allocated.  */
+#define BSF_OLD_COMMON  0x200
+
+  /* The default value for common data.  */
+#define BFD_FORT_COMM_DEFAULT_VALUE 0
+
+  /* In some files the type of a symbol sometimes alters its
+     location in an output file - ie in coff a <<ISFCN>> symbol
+     which is also <<C_EXT>> symbol appears where it was
+     declared and not at the end of a section.  This bit is set
+     by the target BFD part to convey this information.  */
+#define BSF_NOT_AT_END    0x400
+
+  /* Signal that the symbol is the label of constructor section.  */
+#define BSF_CONSTRUCTOR   0x800
+
+  /* Signal that the symbol is a warning symbol.  The name is a
+     warning.  The name of the next symbol is the one to warn about;
+     if a reference is made to a symbol with the same name as the next
+     symbol, a warning is issued by the linker.  */
+#define BSF_WARNING       0x1000
+
+  /* Signal that the symbol is indirect.  This symbol is an indirect
+     pointer to the symbol with the same name as the next symbol.  */
+#define BSF_INDIRECT      0x2000
+
+  /* BSF_FILE marks symbols that contain a file name.  This is used
+     for ELF STT_FILE symbols.  */
+#define BSF_FILE          0x4000
+
+  /* Symbol is from dynamic linking information.  */
+#define BSF_DYNAMIC       0x8000
+
+  /* The symbol denotes a data object.  Used in ELF, and perhaps
+     others someday.  */
+#define BSF_OBJECT        0x10000
+
+  /* This symbol is a debugging symbol.  The value is the offset
+     into the section of the data.  BSF_DEBUGGING should be set
+     as well.  */
+#define BSF_DEBUGGING_RELOC 0x20000
+
+  /* This symbol is thread local.  Used in ELF.  */
+#define BSF_THREAD_LOCAL  0x40000
+
+  flagword flags;
+
+  /* A pointer to the section to which this symbol is
+     relative.  This will always be non NULL, there are special
+     sections for undefined and absolute symbols.  */
+  struct sec *section;
+
+  /* Back end special data.  */
+  union
+    {
+      PTR p;
+      bfd_vma i;
+    }
+  udata;
+}
+asymbol;
+
+#define bfd_get_symtab_upper_bound(abfd) \
+     BFD_SEND (abfd, _bfd_get_symtab_upper_bound, (abfd))
+
+bfd_boolean
+bfd_is_local_label PARAMS ((bfd *abfd, asymbol *sym));
+
+bfd_boolean
+bfd_is_local_label_name PARAMS ((bfd *abfd, const char *name));
+
+#define bfd_is_local_label_name(abfd, name) \
+     BFD_SEND (abfd, _bfd_is_local_label_name, (abfd, name))
+
+#define bfd_canonicalize_symtab(abfd, location) \
+     BFD_SEND (abfd, _bfd_canonicalize_symtab,\
+                  (abfd, location))
+
+bfd_boolean
+bfd_set_symtab PARAMS ((bfd *abfd, asymbol **location, unsigned int count));
+
+void
+bfd_print_symbol_vandf PARAMS ((bfd *abfd, PTR file, asymbol *symbol));
+
+#define bfd_make_empty_symbol(abfd) \
+     BFD_SEND (abfd, _bfd_make_empty_symbol, (abfd))
+
+asymbol *
+_bfd_generic_make_empty_symbol PARAMS ((bfd *));
+
+#define bfd_make_debug_symbol(abfd,ptr,size) \
+        BFD_SEND (abfd, _bfd_make_debug_symbol, (abfd, ptr, size))
+
+int
+bfd_decode_symclass PARAMS ((asymbol *symbol));
+
+bfd_boolean
+bfd_is_undefined_symclass PARAMS ((int symclass));
+
+void
+bfd_symbol_info PARAMS ((asymbol *symbol, symbol_info *ret));
+
+bfd_boolean
+bfd_copy_private_symbol_data PARAMS ((bfd *ibfd, asymbol *isym, bfd *obfd, asymbol *osym));
+
+#define bfd_copy_private_symbol_data(ibfd, isymbol, obfd, osymbol) \
+     BFD_SEND (obfd, _bfd_copy_private_symbol_data, \
+               (ibfd, isymbol, obfd, osymbol))
+
+/* Extracted from bfd.c.  */
+struct bfd
+{
+  /* A unique identifier of the BFD  */
+  unsigned int id;
+
+  /* The filename the application opened the BFD with.  */
+  const char *filename;
+
+  /* A pointer to the target jump table.  */
+  const struct bfd_target *xvec;
+
+  /* To avoid dragging too many header files into every file that
+     includes `<<bfd.h>>', IOSTREAM has been declared as a "char *",
+     and MTIME as a "long".  Their correct types, to which they
+     are cast when used, are "FILE *" and "time_t".    The iostream
+     is the result of an fopen on the filename.  However, if the
+     BFD_IN_MEMORY flag is set, then iostream is actually a pointer
+     to a bfd_in_memory struct.  */
+  PTR iostream;
+
+  /* Is the file descriptor being cached?  That is, can it be closed as
+     needed, and re-opened when accessed later?  */
+  bfd_boolean cacheable;
+
+  /* Marks whether there was a default target specified when the
+     BFD was opened. This is used to select which matching algorithm
+     to use to choose the back end.  */
+  bfd_boolean target_defaulted;
+
+  /* The caching routines use these to maintain a
+     least-recently-used list of BFDs.  */
+  struct bfd *lru_prev, *lru_next;
+
+  /* When a file is closed by the caching routines, BFD retains
+     state information on the file here...  */
+  ufile_ptr where;
+
+  /* ... and here: (``once'' means at least once).  */
+  bfd_boolean opened_once;
+
+  /* Set if we have a locally maintained mtime value, rather than
+     getting it from the file each time.  */
+  bfd_boolean mtime_set;
+
+  /* File modified time, if mtime_set is TRUE.  */
+  long mtime;
+
+  /* Reserved for an unimplemented file locking extension.  */
+  int ifd;
+
+  /* The format which belongs to the BFD. (object, core, etc.)  */
+  bfd_format format;
+
+  /* The direction with which the BFD was opened.  */
+  enum bfd_direction
+    {
+      no_direction = 0,
+      read_direction = 1,
+      write_direction = 2,
+      both_direction = 3
+    }
+  direction;
+
+  /* Format_specific flags.  */
+  flagword flags;
+
+  /* Currently my_archive is tested before adding origin to
+     anything. I believe that this can become always an add of
+     origin, with origin set to 0 for non archive files.  */
+  ufile_ptr origin;
+
+  /* Remember when output has begun, to stop strange things
+     from happening.  */
+  bfd_boolean output_has_begun;
+
+  /* A hash table for section names.  */
+  struct bfd_hash_table section_htab;
+
+  /* Pointer to linked list of sections.  */
+  struct sec *sections;
+
+  /* The place where we add to the section list.  */
+  struct sec **section_tail;
+
+  /* The number of sections.  */
+  unsigned int section_count;
+
+  /* Stuff only useful for object files:
+     The start address.  */
+  bfd_vma start_address;
+
+  /* Used for input and output.  */
+  unsigned int symcount;
+
+  /* Symbol table for output BFD (with symcount entries).  */
+  struct symbol_cache_entry  **outsymbols;
+
+  /* Used for slurped dynamic symbol tables.  */
+  unsigned int dynsymcount;
+
+  /* Pointer to structure which contains architecture information.  */
+  const struct bfd_arch_info *arch_info;
+
+  /* Stuff only useful for archives.  */
+  PTR arelt_data;
+  struct bfd *my_archive;      /* The containing archive BFD.  */
+  struct bfd *next;            /* The next BFD in the archive.  */
+  struct bfd *archive_head;    /* The first BFD in the archive.  */
+  bfd_boolean has_armap;
+
+  /* A chain of BFD structures involved in a link.  */
+  struct bfd *link_next;
+
+  /* A field used by _bfd_generic_link_add_archive_symbols.  This will
+     be used only for archive elements.  */
+  int archive_pass;
+
+  /* Used by the back end to hold private data.  */
+  union
+    {
+      struct aout_data_struct *aout_data;
+      struct artdata *aout_ar_data;
+      struct _oasys_data *oasys_obj_data;
+      struct _oasys_ar_data *oasys_ar_data;
+      struct coff_tdata *coff_obj_data;
+      struct pe_tdata *pe_obj_data;
+      struct xcoff_tdata *xcoff_obj_data;
+      struct ecoff_tdata *ecoff_obj_data;
+      struct ieee_data_struct *ieee_data;
+      struct ieee_ar_data_struct *ieee_ar_data;
+      struct srec_data_struct *srec_data;
+      struct ihex_data_struct *ihex_data;
+      struct tekhex_data_struct *tekhex_data;
+      struct elf_obj_tdata *elf_obj_data;
+      struct nlm_obj_tdata *nlm_obj_data;
+      struct bout_data_struct *bout_data;
+      struct mmo_data_struct *mmo_data;
+      struct sun_core_struct *sun_core_data;
+      struct sco5_core_struct *sco5_core_data;
+      struct trad_core_struct *trad_core_data;
+      struct som_data_struct *som_data;
+      struct hpux_core_struct *hpux_core_data;
+      struct hppabsd_core_struct *hppabsd_core_data;
+      struct sgi_core_struct *sgi_core_data;
+      struct lynx_core_struct *lynx_core_data;
+      struct osf_core_struct *osf_core_data;
+      struct cisco_core_struct *cisco_core_data;
+      struct versados_data_struct *versados_data;
+      struct netbsd_core_struct *netbsd_core_data;
+      struct mach_o_data_struct *mach_o_data;
+      struct mach_o_fat_data_struct *mach_o_fat_data;
+      struct bfd_pef_data_struct *pef_data;
+      struct bfd_pef_xlib_data_struct *pef_xlib_data;
+      struct bfd_sym_data_struct *sym_data;
+      PTR any;
+    }
+  tdata;
+
+  /* Used by the application to hold private data.  */
+  PTR usrdata;
+
+  /* Where all the allocated stuff under this BFD goes.  This is a
+     struct objalloc *, but we use PTR to avoid requiring the inclusion of
+     objalloc.h.  */
+  PTR memory;
+};
+
+typedef enum bfd_error
+{
+  bfd_error_no_error = 0,
+  bfd_error_system_call,
+  bfd_error_invalid_target,
+  bfd_error_wrong_format,
+  bfd_error_wrong_object_format,
+  bfd_error_invalid_operation,
+  bfd_error_no_memory,
+  bfd_error_no_symbols,
+  bfd_error_no_armap,
+  bfd_error_no_more_archived_files,
+  bfd_error_malformed_archive,
+  bfd_error_file_not_recognized,
+  bfd_error_file_ambiguously_recognized,
+  bfd_error_no_contents,
+  bfd_error_nonrepresentable_section,
+  bfd_error_no_debug_section,
+  bfd_error_bad_value,
+  bfd_error_file_truncated,
+  bfd_error_file_too_big,
+  bfd_error_invalid_error_code
+}
+bfd_error_type;
+
+bfd_error_type
+bfd_get_error PARAMS ((void));
+
+void
+bfd_set_error PARAMS ((bfd_error_type error_tag));
+
+const char *
+bfd_errmsg PARAMS ((bfd_error_type error_tag));
+
+void
+bfd_perror PARAMS ((const char *message));
+
+typedef void (*bfd_error_handler_type) PARAMS ((const char *, ...));
+
+bfd_error_handler_type
+bfd_set_error_handler PARAMS ((bfd_error_handler_type));
+
+void
+bfd_set_error_program_name PARAMS ((const char *));
+
+bfd_error_handler_type
+bfd_get_error_handler PARAMS ((void));
+
+const char *
+bfd_archive_filename PARAMS ((bfd *));
+
+long
+bfd_get_reloc_upper_bound PARAMS ((bfd *abfd, asection *sect));
+
+long
+bfd_canonicalize_reloc PARAMS ((bfd *abfd,
+    asection *sec,
+    arelent **loc,
+    asymbol **syms));
+
+void
+bfd_set_reloc PARAMS ((bfd *abfd, asection *sec, arelent **rel, unsigned int count));
+
+bfd_boolean
+bfd_set_file_flags PARAMS ((bfd *abfd, flagword flags));
+
+int
+bfd_get_arch_size PARAMS ((bfd *abfd));
+
+int
+bfd_get_sign_extend_vma PARAMS ((bfd *abfd));
+
+bfd_boolean
+bfd_set_start_address PARAMS ((bfd *abfd, bfd_vma vma));
+
+unsigned int
+bfd_get_gp_size PARAMS ((bfd *abfd));
+
+void
+bfd_set_gp_size PARAMS ((bfd *abfd, unsigned int i));
+
+bfd_vma
+bfd_scan_vma PARAMS ((const char *string, const char **end, int base));
+
+bfd_boolean
+bfd_copy_private_bfd_data PARAMS ((bfd *ibfd, bfd *obfd));
+
+#define bfd_copy_private_bfd_data(ibfd, obfd) \
+     BFD_SEND (obfd, _bfd_copy_private_bfd_data, \
+               (ibfd, obfd))
+bfd_boolean
+bfd_merge_private_bfd_data PARAMS ((bfd *ibfd, bfd *obfd));
+
+#define bfd_merge_private_bfd_data(ibfd, obfd) \
+     BFD_SEND (obfd, _bfd_merge_private_bfd_data, \
+               (ibfd, obfd))
+bfd_boolean
+bfd_set_private_flags PARAMS ((bfd *abfd, flagword flags));
+
+#define bfd_set_private_flags(abfd, flags) \
+     BFD_SEND (abfd, _bfd_set_private_flags, (abfd, flags))
+#define bfd_sizeof_headers(abfd, reloc) \
+       BFD_SEND (abfd, _bfd_sizeof_headers, (abfd, reloc))
+
+#define bfd_find_nearest_line(abfd, sec, syms, off, file, func, line) \
+       BFD_SEND (abfd, _bfd_find_nearest_line, \
+                 (abfd, sec, syms, off, file, func, line))
+
+#define bfd_debug_info_start(abfd) \
+       BFD_SEND (abfd, _bfd_debug_info_start, (abfd))
+
+#define bfd_debug_info_end(abfd) \
+       BFD_SEND (abfd, _bfd_debug_info_end, (abfd))
+
+#define bfd_debug_info_accumulate(abfd, section) \
+       BFD_SEND (abfd, _bfd_debug_info_accumulate, (abfd, section))
+
+#define bfd_stat_arch_elt(abfd, stat) \
+       BFD_SEND (abfd, _bfd_stat_arch_elt,(abfd, stat))
+
+#define bfd_update_armap_timestamp(abfd) \
+       BFD_SEND (abfd, _bfd_update_armap_timestamp, (abfd))
+
+#define bfd_set_arch_mach(abfd, arch, mach)\
+       BFD_SEND ( abfd, _bfd_set_arch_mach, (abfd, arch, mach))
+
+#define bfd_relax_section(abfd, section, link_info, again) \
+       BFD_SEND (abfd, _bfd_relax_section, (abfd, section, link_info, again))
+
+#define bfd_gc_sections(abfd, link_info) \
+       BFD_SEND (abfd, _bfd_gc_sections, (abfd, link_info))
+
+#define bfd_merge_sections(abfd, link_info) \
+       BFD_SEND (abfd, _bfd_merge_sections, (abfd, link_info))
+
+#define bfd_discard_group(abfd, sec) \
+       BFD_SEND (abfd, _bfd_discard_group, (abfd, sec))
+
+#define bfd_link_hash_table_create(abfd) \
+       BFD_SEND (abfd, _bfd_link_hash_table_create, (abfd))
+
+#define bfd_link_hash_table_free(abfd, hash) \
+       BFD_SEND (abfd, _bfd_link_hash_table_free, (hash))
+
+#define bfd_link_add_symbols(abfd, info) \
+       BFD_SEND (abfd, _bfd_link_add_symbols, (abfd, info))
+
+#define bfd_link_just_syms(sec, info) \
+       BFD_SEND (abfd, _bfd_link_just_syms, (sec, info))
+
+#define bfd_final_link(abfd, info) \
+       BFD_SEND (abfd, _bfd_final_link, (abfd, info))
+
+#define bfd_free_cached_info(abfd) \
+       BFD_SEND (abfd, _bfd_free_cached_info, (abfd))
+
+#define bfd_get_dynamic_symtab_upper_bound(abfd) \
+       BFD_SEND (abfd, _bfd_get_dynamic_symtab_upper_bound, (abfd))
+
+#define bfd_print_private_bfd_data(abfd, file)\
+       BFD_SEND (abfd, _bfd_print_private_bfd_data, (abfd, file))
+
+#define bfd_canonicalize_dynamic_symtab(abfd, asymbols) \
+       BFD_SEND (abfd, _bfd_canonicalize_dynamic_symtab, (abfd, asymbols))
+
+#define bfd_get_dynamic_reloc_upper_bound(abfd) \
+       BFD_SEND (abfd, _bfd_get_dynamic_reloc_upper_bound, (abfd))
+
+#define bfd_canonicalize_dynamic_reloc(abfd, arels, asyms) \
+       BFD_SEND (abfd, _bfd_canonicalize_dynamic_reloc, (abfd, arels, asyms))
+
+extern bfd_byte *bfd_get_relocated_section_contents
+       PARAMS ((bfd *, struct bfd_link_info *,
+                 struct bfd_link_order *, bfd_byte *,
+                 bfd_boolean, asymbol **));
+
+bfd_boolean
+bfd_alt_mach_code PARAMS ((bfd *abfd, int alternative));
+
+struct bfd_preserve
+{
+  PTR marker;
+  PTR tdata;
+  flagword flags;
+  const struct bfd_arch_info *arch_info;
+  struct sec *sections;
+  struct sec **section_tail;
+  unsigned int section_count;
+  struct bfd_hash_table section_htab;
+};
+
+bfd_boolean
+bfd_preserve_save PARAMS ((bfd *, struct bfd_preserve *));
+
+void
+bfd_preserve_restore PARAMS ((bfd *, struct bfd_preserve *));
+
+void
+bfd_preserve_finish PARAMS ((bfd *, struct bfd_preserve *));
+
+/* Extracted from archive.c.  */
+symindex
+bfd_get_next_mapent PARAMS ((bfd *abfd, symindex previous, carsym **sym));
+
+bfd_boolean
+bfd_set_archive_head PARAMS ((bfd *output, bfd *new_head));
+
+bfd *
+bfd_openr_next_archived_file PARAMS ((bfd *archive, bfd *previous));
+
+/* Extracted from corefile.c.  */
+const char *
+bfd_core_file_failing_command PARAMS ((bfd *abfd));
+
+int
+bfd_core_file_failing_signal PARAMS ((bfd *abfd));
+
+bfd_boolean
+core_file_matches_executable_p PARAMS ((bfd *core_bfd, bfd *exec_bfd));
+
+/* Extracted from targets.c.  */
+#define BFD_SEND(bfd, message, arglist) \
+               ((*((bfd)->xvec->message)) arglist)
+
+#ifdef DEBUG_BFD_SEND
+#undef BFD_SEND
+#define BFD_SEND(bfd, message, arglist) \
+  (((bfd) && (bfd)->xvec && (bfd)->xvec->message) ? \
+    ((*((bfd)->xvec->message)) arglist) : \
+    (bfd_assert (__FILE__,__LINE__), NULL))
+#endif
+#define BFD_SEND_FMT(bfd, message, arglist) \
+            (((bfd)->xvec->message[(int) ((bfd)->format)]) arglist)
+
+#ifdef DEBUG_BFD_SEND
+#undef BFD_SEND_FMT
+#define BFD_SEND_FMT(bfd, message, arglist) \
+  (((bfd) && (bfd)->xvec && (bfd)->xvec->message) ? \
+   (((bfd)->xvec->message[(int) ((bfd)->format)]) arglist) : \
+   (bfd_assert (__FILE__,__LINE__), NULL))
+#endif
+
+enum bfd_flavour
+{
+  bfd_target_unknown_flavour,
+  bfd_target_aout_flavour,
+  bfd_target_coff_flavour,
+  bfd_target_ecoff_flavour,
+  bfd_target_xcoff_flavour,
+  bfd_target_elf_flavour,
+  bfd_target_ieee_flavour,
+  bfd_target_nlm_flavour,
+  bfd_target_oasys_flavour,
+  bfd_target_tekhex_flavour,
+  bfd_target_srec_flavour,
+  bfd_target_ihex_flavour,
+  bfd_target_som_flavour,
+  bfd_target_os9k_flavour,
+  bfd_target_versados_flavour,
+  bfd_target_msdos_flavour,
+  bfd_target_ovax_flavour,
+  bfd_target_evax_flavour,
+  bfd_target_mmo_flavour,
+  bfd_target_mach_o_flavour,
+  bfd_target_pef_flavour,
+  bfd_target_pef_xlib_flavour,
+  bfd_target_sym_flavour
+};
+
+enum bfd_endian { BFD_ENDIAN_BIG, BFD_ENDIAN_LITTLE, BFD_ENDIAN_UNKNOWN };
+
+/* Forward declaration.  */
+typedef struct bfd_link_info _bfd_link_info;
+
+typedef struct bfd_target
+{
+  /* Identifies the kind of target, e.g., SunOS4, Ultrix, etc.  */
+  char *name;
+
+ /* The "flavour" of a back end is a general indication about
+    the contents of a file.  */
+  enum bfd_flavour flavour;
+
+  /* The order of bytes within the data area of a file.  */
+  enum bfd_endian byteorder;
+
+ /* The order of bytes within the header parts of a file.  */
+  enum bfd_endian header_byteorder;
+
+  /* A mask of all the flags which an executable may have set -
+     from the set <<BFD_NO_FLAGS>>, <<HAS_RELOC>>, ...<<D_PAGED>>.  */
+  flagword object_flags;
+
+ /* A mask of all the flags which a section may have set - from
+    the set <<SEC_NO_FLAGS>>, <<SEC_ALLOC>>, ...<<SET_NEVER_LOAD>>.  */
+  flagword section_flags;
+
+ /* The character normally found at the front of a symbol.
+    (if any), perhaps `_'.  */
+  char symbol_leading_char;
+
+ /* The pad character for file names within an archive header.  */
+  char ar_pad_char;
+
+  /* The maximum number of characters in an archive header.  */
+  unsigned short ar_max_namelen;
+
+  /* Entries for byte swapping for data. These are different from the
+     other entry points, since they don't take a BFD asthe first argument.
+     Certain other handlers could do the same.  */
+  bfd_vma        (*bfd_getx64) PARAMS ((const bfd_byte *));
+  bfd_signed_vma (*bfd_getx_signed_64) PARAMS ((const bfd_byte *));
+  void           (*bfd_putx64) PARAMS ((bfd_vma, bfd_byte *));
+  bfd_vma        (*bfd_getx32) PARAMS ((const bfd_byte *));
+  bfd_signed_vma (*bfd_getx_signed_32) PARAMS ((const bfd_byte *));
+  void           (*bfd_putx32) PARAMS ((bfd_vma, bfd_byte *));
+  bfd_vma        (*bfd_getx16) PARAMS ((const bfd_byte *));
+  bfd_signed_vma (*bfd_getx_signed_16) PARAMS ((const bfd_byte *));
+  void           (*bfd_putx16) PARAMS ((bfd_vma, bfd_byte *));
+
+  /* Byte swapping for the headers.  */
+  bfd_vma        (*bfd_h_getx64) PARAMS ((const bfd_byte *));
+  bfd_signed_vma (*bfd_h_getx_signed_64) PARAMS ((const bfd_byte *));
+  void           (*bfd_h_putx64) PARAMS ((bfd_vma, bfd_byte *));
+  bfd_vma        (*bfd_h_getx32) PARAMS ((const bfd_byte *));
+  bfd_signed_vma (*bfd_h_getx_signed_32) PARAMS ((const bfd_byte *));
+  void           (*bfd_h_putx32) PARAMS ((bfd_vma, bfd_byte *));
+  bfd_vma        (*bfd_h_getx16) PARAMS ((const bfd_byte *));
+  bfd_signed_vma (*bfd_h_getx_signed_16) PARAMS ((const bfd_byte *));
+  void           (*bfd_h_putx16) PARAMS ((bfd_vma, bfd_byte *));
+
+  /* Format dependent routines: these are vectors of entry points
+     within the target vector structure, one for each format to check.  */
+
+  /* Check the format of a file being read.  Return a <<bfd_target *>> or zero.  */
+  const struct bfd_target *(*_bfd_check_format[bfd_type_end]) PARAMS ((bfd *));
+
+  /* Set the format of a file being written.  */
+  bfd_boolean (*_bfd_set_format[bfd_type_end]) PARAMS ((bfd *));
+
+  /* Write cached information into a file being written, at <<bfd_close>>.  */
+  bfd_boolean (*_bfd_write_contents[bfd_type_end]) PARAMS ((bfd *));
+
+
+  /* Generic entry points.  */
+#define BFD_JUMP_TABLE_GENERIC(NAME) \
+CONCAT2 (NAME,_close_and_cleanup), \
+CONCAT2 (NAME,_bfd_free_cached_info), \
+CONCAT2 (NAME,_new_section_hook), \
+CONCAT2 (NAME,_get_section_contents), \
+CONCAT2 (NAME,_get_section_contents_in_window)
+
+  /* Called when the BFD is being closed to do any necessary cleanup.  */
+  bfd_boolean (*_close_and_cleanup) PARAMS ((bfd *));
+  /* Ask the BFD to free all cached information.  */
+  bfd_boolean (*_bfd_free_cached_info) PARAMS ((bfd *));
+  /* Called when a new section is created.  */
+  bfd_boolean (*_new_section_hook) PARAMS ((bfd *, sec_ptr));
+  /* Read the contents of a section.  */
+  bfd_boolean (*_bfd_get_section_contents)
+    PARAMS ((bfd *, sec_ptr, PTR, file_ptr, bfd_size_type));
+  bfd_boolean (*_bfd_get_section_contents_in_window)
+    PARAMS ((bfd *, sec_ptr, bfd_window *, file_ptr, bfd_size_type));
+
+  /* Entry points to copy private data.  */
+#define BFD_JUMP_TABLE_COPY(NAME) \
+CONCAT2 (NAME,_bfd_copy_private_bfd_data), \
+CONCAT2 (NAME,_bfd_merge_private_bfd_data), \
+CONCAT2 (NAME,_bfd_copy_private_section_data), \
+CONCAT2 (NAME,_bfd_copy_private_symbol_data), \
+CONCAT2 (NAME,_bfd_set_private_flags), \
+CONCAT2 (NAME,_bfd_print_private_bfd_data) \
+  /* Called to copy BFD general private data from one object file
+     to another.  */
+  bfd_boolean (*_bfd_copy_private_bfd_data) PARAMS ((bfd *, bfd *));
+  /* Called to merge BFD general private data from one object file
+     to a common output file when linking.  */
+  bfd_boolean (*_bfd_merge_private_bfd_data) PARAMS ((bfd *, bfd *));
+  /* Called to copy BFD private section data from one object file
+     to another.  */
+  bfd_boolean (*_bfd_copy_private_section_data)
+    PARAMS ((bfd *, sec_ptr, bfd *, sec_ptr));
+  /* Called to copy BFD private symbol data from one symbol
+     to another.  */
+  bfd_boolean (*_bfd_copy_private_symbol_data)
+    PARAMS ((bfd *, asymbol *, bfd *, asymbol *));
+  /* Called to set private backend flags.  */
+  bfd_boolean (*_bfd_set_private_flags) PARAMS ((bfd *, flagword));
+
+  /* Called to print private BFD data.  */
+  bfd_boolean (*_bfd_print_private_bfd_data) PARAMS ((bfd *, PTR));
+
+  /* Core file entry points.  */
+#define BFD_JUMP_TABLE_CORE(NAME) \
+CONCAT2 (NAME,_core_file_failing_command), \
+CONCAT2 (NAME,_core_file_failing_signal), \
+CONCAT2 (NAME,_core_file_matches_executable_p)
+  char *      (*_core_file_failing_command) PARAMS ((bfd *));
+  int         (*_core_file_failing_signal) PARAMS ((bfd *));
+  bfd_boolean (*_core_file_matches_executable_p) PARAMS ((bfd *, bfd *));
+
+  /* Archive entry points.  */
+#define BFD_JUMP_TABLE_ARCHIVE(NAME) \
+CONCAT2 (NAME,_slurp_armap), \
+CONCAT2 (NAME,_slurp_extended_name_table), \
+CONCAT2 (NAME,_construct_extended_name_table), \
+CONCAT2 (NAME,_truncate_arname), \
+CONCAT2 (NAME,_write_armap), \
+CONCAT2 (NAME,_read_ar_hdr), \
+CONCAT2 (NAME,_openr_next_archived_file), \
+CONCAT2 (NAME,_get_elt_at_index), \
+CONCAT2 (NAME,_generic_stat_arch_elt), \
+CONCAT2 (NAME,_update_armap_timestamp)
+  bfd_boolean (*_bfd_slurp_armap) PARAMS ((bfd *));
+  bfd_boolean (*_bfd_slurp_extended_name_table) PARAMS ((bfd *));
+  bfd_boolean (*_bfd_construct_extended_name_table)
+    PARAMS ((bfd *, char **, bfd_size_type *, const char **));
+  void        (*_bfd_truncate_arname) PARAMS ((bfd *, const char *, char *));
+  bfd_boolean (*write_armap)
+    PARAMS ((bfd *, unsigned int, struct orl *, unsigned int, int));
+  PTR         (*_bfd_read_ar_hdr_fn) PARAMS ((bfd *));
+  bfd *       (*openr_next_archived_file) PARAMS ((bfd *, bfd *));
+#define bfd_get_elt_at_index(b,i) BFD_SEND(b, _bfd_get_elt_at_index, (b,i))
+  bfd *       (*_bfd_get_elt_at_index) PARAMS ((bfd *, symindex));
+  int         (*_bfd_stat_arch_elt) PARAMS ((bfd *, struct stat *));
+  bfd_boolean (*_bfd_update_armap_timestamp) PARAMS ((bfd *));
+
+  /* Entry points used for symbols.  */
+#define BFD_JUMP_TABLE_SYMBOLS(NAME) \
+CONCAT2 (NAME,_get_symtab_upper_bound), \
+CONCAT2 (NAME,_get_symtab), \
+CONCAT2 (NAME,_make_empty_symbol), \
+CONCAT2 (NAME,_print_symbol), \
+CONCAT2 (NAME,_get_symbol_info), \
+CONCAT2 (NAME,_bfd_is_local_label_name), \
+CONCAT2 (NAME,_get_lineno), \
+CONCAT2 (NAME,_find_nearest_line), \
+CONCAT2 (NAME,_bfd_make_debug_symbol), \
+CONCAT2 (NAME,_read_minisymbols), \
+CONCAT2 (NAME,_minisymbol_to_symbol)
+  long        (*_bfd_get_symtab_upper_bound) PARAMS ((bfd *));
+  long        (*_bfd_canonicalize_symtab) PARAMS ((bfd *,
+                                                struct symbol_cache_entry **));
+  struct symbol_cache_entry *
+              (*_bfd_make_empty_symbol) PARAMS ((bfd *));
+  void        (*_bfd_print_symbol)
+    PARAMS ((bfd *, PTR, struct symbol_cache_entry *, bfd_print_symbol_type));
+#define bfd_print_symbol(b,p,s,e) BFD_SEND(b, _bfd_print_symbol, (b,p,s,e))
+  void        (*_bfd_get_symbol_info)
+    PARAMS ((bfd *, struct symbol_cache_entry *, symbol_info *));
+#define bfd_get_symbol_info(b,p,e) BFD_SEND(b, _bfd_get_symbol_info, (b,p,e))
+  bfd_boolean (*_bfd_is_local_label_name) PARAMS ((bfd *, const char *));
+
+  alent *     (*_get_lineno) PARAMS ((bfd *, struct symbol_cache_entry *));
+  bfd_boolean (*_bfd_find_nearest_line)
+    PARAMS ((bfd *, struct sec *, struct symbol_cache_entry **, bfd_vma,
+             const char **, const char **, unsigned int *));
+ /* Back-door to allow format-aware applications to create debug symbols
+    while using BFD for everything else.  Currently used by the assembler
+    when creating COFF files.  */
+  asymbol *   (*_bfd_make_debug_symbol)
+    PARAMS ((bfd *, void *, unsigned long size));
+#define bfd_read_minisymbols(b, d, m, s) \
+  BFD_SEND (b, _read_minisymbols, (b, d, m, s))
+  long        (*_read_minisymbols)
+    PARAMS ((bfd *, bfd_boolean, PTR *, unsigned int *));
+#define bfd_minisymbol_to_symbol(b, d, m, f) \
+  BFD_SEND (b, _minisymbol_to_symbol, (b, d, m, f))
+  asymbol *   (*_minisymbol_to_symbol)
+    PARAMS ((bfd *, bfd_boolean, const PTR, asymbol *));
+
+  /* Routines for relocs.  */
+#define BFD_JUMP_TABLE_RELOCS(NAME) \
+CONCAT2 (NAME,_get_reloc_upper_bound), \
+CONCAT2 (NAME,_canonicalize_reloc), \
+CONCAT2 (NAME,_bfd_reloc_type_lookup)
+  long        (*_get_reloc_upper_bound) PARAMS ((bfd *, sec_ptr));
+  long        (*_bfd_canonicalize_reloc)
+    PARAMS ((bfd *, sec_ptr, arelent **, struct symbol_cache_entry **));
+  /* See documentation on reloc types.  */
+  reloc_howto_type *
+              (*reloc_type_lookup) PARAMS ((bfd *, bfd_reloc_code_real_type));
+
+  /* Routines used when writing an object file.  */
+#define BFD_JUMP_TABLE_WRITE(NAME) \
+CONCAT2 (NAME,_set_arch_mach), \
+CONCAT2 (NAME,_set_section_contents)
+  bfd_boolean (*_bfd_set_arch_mach)
+    PARAMS ((bfd *, enum bfd_architecture, unsigned long));
+  bfd_boolean (*_bfd_set_section_contents)
+    PARAMS ((bfd *, sec_ptr, PTR, file_ptr, bfd_size_type));
+
+  /* Routines used by the linker.  */
+#define BFD_JUMP_TABLE_LINK(NAME) \
+CONCAT2 (NAME,_sizeof_headers), \
+CONCAT2 (NAME,_bfd_get_relocated_section_contents), \
+CONCAT2 (NAME,_bfd_relax_section), \
+CONCAT2 (NAME,_bfd_link_hash_table_create), \
+CONCAT2 (NAME,_bfd_link_hash_table_free), \
+CONCAT2 (NAME,_bfd_link_add_symbols), \
+CONCAT2 (NAME,_bfd_link_just_syms), \
+CONCAT2 (NAME,_bfd_final_link), \
+CONCAT2 (NAME,_bfd_link_split_section), \
+CONCAT2 (NAME,_bfd_gc_sections), \
+CONCAT2 (NAME,_bfd_merge_sections), \
+CONCAT2 (NAME,_bfd_discard_group)
+  int         (*_bfd_sizeof_headers) PARAMS ((bfd *, bfd_boolean));
+  bfd_byte *  (*_bfd_get_relocated_section_contents)
+    PARAMS ((bfd *, struct bfd_link_info *, struct bfd_link_order *,
+             bfd_byte *, bfd_boolean, struct symbol_cache_entry **));
+
+  bfd_boolean (*_bfd_relax_section)
+    PARAMS ((bfd *, struct sec *, struct bfd_link_info *, bfd_boolean *));
+
+  /* Create a hash table for the linker.  Different backends store
+     different information in this table.  */
+  struct bfd_link_hash_table *
+              (*_bfd_link_hash_table_create) PARAMS ((bfd *));
+
+  /* Release the memory associated with the linker hash table.  */
+  void        (*_bfd_link_hash_table_free)
+    PARAMS ((struct bfd_link_hash_table *));
+
+  /* Add symbols from this object file into the hash table.  */
+  bfd_boolean (*_bfd_link_add_symbols)
+    PARAMS ((bfd *, struct bfd_link_info *));
+
+  /* Indicate that we are only retrieving symbol values from this section.  */
+  void        (*_bfd_link_just_syms)
+    PARAMS ((asection *, struct bfd_link_info *));
+
+  /* Do a link based on the link_order structures attached to each
+     section of the BFD.  */
+  bfd_boolean (*_bfd_final_link) PARAMS ((bfd *, struct bfd_link_info *));
+
+  /* Should this section be split up into smaller pieces during linking.  */
+  bfd_boolean (*_bfd_link_split_section) PARAMS ((bfd *, struct sec *));
+
+  /* Remove sections that are not referenced from the output.  */
+  bfd_boolean (*_bfd_gc_sections) PARAMS ((bfd *, struct bfd_link_info *));
+
+  /* Attempt to merge SEC_MERGE sections.  */
+  bfd_boolean (*_bfd_merge_sections) PARAMS ((bfd *, struct bfd_link_info *));
+
+  /* Discard members of a group.  */
+  bfd_boolean (*_bfd_discard_group) PARAMS ((bfd *, struct sec *));
+
+  /* Routines to handle dynamic symbols and relocs.  */
+#define BFD_JUMP_TABLE_DYNAMIC(NAME) \
+CONCAT2 (NAME,_get_dynamic_symtab_upper_bound), \
+CONCAT2 (NAME,_canonicalize_dynamic_symtab), \
+CONCAT2 (NAME,_get_dynamic_reloc_upper_bound), \
+CONCAT2 (NAME,_canonicalize_dynamic_reloc)
+  /* Get the amount of memory required to hold the dynamic symbols.  */
+  long        (*_bfd_get_dynamic_symtab_upper_bound) PARAMS ((bfd *));
+  /* Read in the dynamic symbols.  */
+  long        (*_bfd_canonicalize_dynamic_symtab)
+    PARAMS ((bfd *, struct symbol_cache_entry **));
+  /* Get the amount of memory required to hold the dynamic relocs.  */
+  long        (*_bfd_get_dynamic_reloc_upper_bound) PARAMS ((bfd *));
+  /* Read in the dynamic relocs.  */
+  long        (*_bfd_canonicalize_dynamic_reloc)
+    PARAMS ((bfd *, arelent **, struct symbol_cache_entry **));
+
+  /* Opposite endian version of this target.  */
+  const struct bfd_target * alternative_target;
+
+  /* Data for use by back-end routines, which isn't
+     generic enough to belong in this structure.  */
+  PTR backend_data;
+
+} bfd_target;
+
+bfd_boolean
+bfd_set_default_target PARAMS ((const char *name));
+
+const bfd_target *
+bfd_find_target PARAMS ((const char *target_name, bfd *abfd));
+
+const char **
+bfd_target_list PARAMS ((void));
+
+const bfd_target *
+bfd_search_for_target PARAMS ((int (* search_func)
+       (const bfd_target *, void *),
+    void *));
+
+/* Extracted from format.c.  */
+bfd_boolean
+bfd_check_format PARAMS ((bfd *abfd, bfd_format format));
+
+bfd_boolean
+bfd_check_format_matches PARAMS ((bfd *abfd, bfd_format format,
+    char ***matching));
+
+bfd_boolean
+bfd_set_format PARAMS ((bfd *abfd, bfd_format format));
+
+const char *
+bfd_format_string PARAMS ((bfd_format format));
+
+/* Extracted from linker.c.  */
+bfd_boolean
+bfd_link_split_section PARAMS ((bfd *abfd, asection *sec));
+
+#define bfd_link_split_section(abfd, sec) \
+       BFD_SEND (abfd, _bfd_link_split_section, (abfd, sec))
+
+/* Extracted from simple.c.  */
+bfd_byte *
+bfd_simple_get_relocated_section_contents PARAMS ((bfd *abfd, asection *sec, bfd_byte *outbuf, asymbol **symbol_table));
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/Repair/RepairCompiler/structextract/build b/Repair/RepairCompiler/structextract/build
new file mode 100755 (executable)
index 0000000..67ae82f
--- /dev/null
@@ -0,0 +1,5 @@
+#!/bin/bash
+gcc -gdwarf-2 -c readelf.c -Iinclude
+gcc -gdwarf-2 -c unwind-ia64.c -Iinclude
+gcc -gdwarf-2 -c typedata.c -Iinclude
+gcc -gdwarf-2 dumpstructures.c *.o -Iinclude -o dumpstructures
\ No newline at end of file
diff --git a/Repair/RepairCompiler/structextract/dumpstructures.c b/Repair/RepairCompiler/structextract/dumpstructures.c
new file mode 100755 (executable)
index 0000000..c08eaef
--- /dev/null
@@ -0,0 +1,212 @@
+/*
+   This file is part of Kvasir, a Valgrind skin that implements the
+   C language front-end for the Daikon Invariant Detection System
+
+   Copyright (C) 2004 Philip Guo, MIT CSAIL Program Analysis Group
+
+   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.
+*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+
+#include "dumpstructures.h"
+#include "typedata.h"
+#include "elf/dwarf2.h"
+
+#define GETTYPE 1
+#define POSTNAME 2
+
+int process_elf_binary_data(char* filename);
+
+int main(int argc, char **argv) {
+  if (argc<2)
+    return 0;
+  process_elf_binary_data(argv[1]);
+  daikon_preprocess_entry_array();
+}
+
+// Pre-processes global dwarf_entry_array in order to place
+// the data in a form that can easily be turned into .decls
+// and .dtrace files
+void daikon_preprocess_entry_array()
+{
+  initializeTypeArray();
+}
+
+int typecount=0;
+
+int entry_is_type(dwarf_entry *entry) {
+  if (entry->tag_name==DW_TAG_structure_type||
+      entry->tag_name==DW_TAG_union_type) {
+    collection_type* collection_ptr = (collection_type*)(entry->entry_ptr);
+    if (collection_ptr->name==0) {
+      collection_ptr->name=(char*)malloc(100);
+      sprintf(collection_ptr->name,"TYPE%ld",typecount++);
+    }
+    return 1;
+  }
+  return 0;
+}
+
+int entry_is_valid_function(dwarf_entry *entry) {
+  if (tag_is_function(entry->tag_name)) {
+    function* funcPtr = (function*)(entry->entry_ptr);
+    if (funcPtr->start_pc != 0 && funcPtr->name != 0) {
+      return 1;
+    } else {
+#ifdef SHOW_DEBUG
+      printf("Skipping invalid-looking function %s\n", funcPtr->name);
+#endif
+    }
+  }
+  return 0;
+}
+
+// Finds the number of function entries in the dwarf_entry_array
+// and creates the DaikonFunctionInfo array to match that size
+
+void initializeTypeArray()
+{
+  int i;
+  dwarf_entry * cur_entry;
+  for (i = 0; i < dwarf_entry_array_size; i++)
+    {
+      cur_entry = &dwarf_entry_array[i];
+      if (entry_is_type(cur_entry))
+        {
+         collection_type* collection_ptr = (collection_type*)(cur_entry->entry_ptr);
+         int j=0;
+         int offset=0;
+         printf("structure %s {\n",collection_ptr->name);
+         
+         for(j=0;j<collection_ptr->num_members;j++) {
+           dwarf_entry *entry=collection_ptr->members[j];
+           member * member_ptr=(member *)entry->entry_ptr;
+           char *name=member_ptr->name;
+           dwarf_entry *type=member_ptr->type_ptr;
+           char *typestr=printname(type,GETTYPE);
+           char *poststr=printname(type,POSTNAME);
+           if (member_ptr->data_member_location>offset) {
+             printf("   reserved byte[%ld];\n",member_ptr->data_member_location-offset);
+             offset=member_ptr->data_member_location;
+           }
+           offset+=getsize(type);
+
+           printf("   %s %s%s;\n",typestr,name,poststr);
+         }
+         printf("}\n\n");
+        }
+    }
+}
+
+int getsize(dwarf_entry *type) {
+  if (type==NULL)
+    return 0;
+  switch(type->tag_name) {
+  case DW_TAG_enumeration_type:
+    return 4;
+  case DW_TAG_array_type: {
+    modifier_type * modifier_ptr=(modifier_type*)type->entry_ptr;
+    int size=((array_bound*)modifier_ptr->array_ptr[0]->entry_ptr)->upperbound+1;
+    return size*getsize(modifier_ptr->target_ptr);
+  }
+  case DW_TAG_base_type: {
+    base_type *base=(base_type*)type->entry_ptr;
+    return base->byte_size;
+  }
+  case DW_TAG_pointer_type: {
+    return 4;
+  }
+  case DW_TAG_structure_type: {
+    collection_type *ctype=(collection_type*)type->entry_ptr;
+    return ctype->byte_size;
+  }
+  default:
+    return 0;
+  }
+}
+
+char * printname(dwarf_entry * type,int op) {
+  if (type==NULL) {
+    if (op==GETTYPE)
+      return NULL;
+  }
+
+  switch(type->tag_name) {
+  case DW_TAG_enumeration_type:
+    if (op==GETTYPE)
+      return "int";
+    break;
+  case DW_TAG_array_type: {
+    modifier_type * modifier_ptr=(modifier_type*)type->entry_ptr;
+    if (op==GETTYPE) {
+       char *typename=printname(modifier_ptr->target_ptr,op);
+       return typename;
+    } else if (op==POSTNAME) {
+      int size=((array_bound*)modifier_ptr->array_ptr[0]->entry_ptr)->upperbound+1;
+      char *typename=printname(modifier_ptr->target_ptr,op);
+      char *newptr=(char *)malloc(200);
+      sprintf(newptr,"%s[%ld]",typename,size);
+      return newptr;
+    }
+  }
+    break;
+  case DW_TAG_base_type: {
+    base_type *base=(base_type*)type->entry_ptr;
+    if (op==GETTYPE)
+      switch(base->byte_size) {
+      case 1:
+       return "byte";
+      case 2:
+       return "short";
+      case 4:
+       return "int";
+      default: {
+       char *m=(char*)malloc(100);
+       sprintf(m,"error%ld",base->byte_size);
+       return m;
+      }
+      }
+  }
+    break;
+  case DW_TAG_pointer_type: {
+    modifier_type * modifier_ptr=(modifier_type*)type->entry_ptr;
+    if (op==GETTYPE) {
+      if (modifier_ptr->target_ptr==NULL)
+       return "void *"; /* seems like a good guess */
+      {
+       char *typename=printname(modifier_ptr->target_ptr,op);
+       /* evil hack */
+       char *newptr=(char *)malloc(200);
+       sprintf(newptr,"%s *",typename);
+       return newptr;
+      }
+    }
+  }
+    break;
+  case DW_TAG_structure_type: {
+    collection_type *ctype=(collection_type*)type->entry_ptr;
+    if (op==GETTYPE&&ctype->name==NULL) {
+      ctype->name=(char*)malloc(100);
+      sprintf(ctype->name,"TYPE%ld",typecount++);
+    }
+    if (op==GETTYPE)
+      return ctype->name;
+  }
+    break;
+  default:
+    if (op==GETTYPE)
+      return "unknown";
+  }
+  if (op==POSTNAME)
+    return "";
+  return "ERROR";
+}
+
+
diff --git a/Repair/RepairCompiler/structextract/dumpstructures.h b/Repair/RepairCompiler/structextract/dumpstructures.h
new file mode 100755 (executable)
index 0000000..52b32be
--- /dev/null
@@ -0,0 +1,55 @@
+/*
+   This file is part of Kvasir, a Valgrind skin that implements the
+   C language front-end for the Daikon Invariant Detection System
+
+   Copyright (C) 2004 Philip Guo, MIT CSAIL Program Analysis Group
+
+   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.
+*/
+
+/* kvasir_runtime.h:
+   Contains the majority of the type definitions that are necessary
+   for Kvasir functionality.
+*/
+
+#ifndef DUMP_H
+#define DUMP_H
+
+#include "typedata.h"
+
+
+struct StructureElement {
+  char *fieldname;
+  int StructureType;
+  int isArray;
+  int arraySize;
+  char *structurename;
+  struct StructureElement *next;
+};
+
+struct Structure {
+  char* name;
+  struct StructureElement * struct_ele;
+};
+
+#define TYPE_INT 0
+#define TYPE_SHORT 1
+#define TYPE_BYTE 2
+#define TYPE_BIT 3
+#define TYPE_STRUCTURE 4
+#define TYPE_POINTER 5
+#define TYPE_RESERVED 6
+
+/* Array that holds information about all functions*/
+struct Structure * TypeArray;
+unsigned long TypeArraySize;
+
+void daikon_preprocess_entry_array();
+void initializeTypeArray();
+int entry_is_type(dwarf_entry *entry);
+char * printname(dwarf_entry * entry,int op);
+int getsize(dwarf_entry *type);
+#endif
diff --git a/Repair/RepairCompiler/structextract/include/ansidecl.h b/Repair/RepairCompiler/structextract/include/ansidecl.h
new file mode 100755 (executable)
index 0000000..f8f2d73
--- /dev/null
@@ -0,0 +1,326 @@
+/* ANSI and traditional C compatability macros
+   Copyright 1991, 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001
+   Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+/* ANSI and traditional C compatibility macros
+
+   ANSI C is assumed if __STDC__ is #defined.
+
+   Macro               ANSI C definition       Traditional C definition
+   -----               ---- - ----------       ----------- - ----------
+   ANSI_PROTOTYPES     1                       not defined
+   PTR                 `void *'                `char *'
+   PTRCONST            `void *const'           `char *'
+   LONG_DOUBLE         `long double'           `double'
+   const               not defined             `'
+   volatile            not defined             `'
+   signed              not defined             `'
+   VA_START(ap, var)   va_start(ap, var)       va_start(ap)
+
+   Note that it is safe to write "void foo();" indicating a function
+   with no return value, in all K+R compilers we have been able to test.
+
+   For declaring functions with prototypes, we also provide these:
+
+   PARAMS ((prototype))
+   -- for functions which take a fixed number of arguments.  Use this
+   when declaring the function.  When defining the function, write a
+   K+R style argument list.  For example:
+
+       char *strcpy PARAMS ((char *dest, char *source));
+       ...
+       char *
+       strcpy (dest, source)
+            char *dest;
+            char *source;
+       { ... }
+
+
+   VPARAMS ((prototype, ...))
+   -- for functions which take a variable number of arguments.  Use
+   PARAMS to declare the function, VPARAMS to define it.  For example:
+
+       int printf PARAMS ((const char *format, ...));
+       ...
+       int
+       printf VPARAMS ((const char *format, ...))
+       {
+          ...
+       }
+
+   For writing functions which take variable numbers of arguments, we
+   also provide the VA_OPEN, VA_CLOSE, and VA_FIXEDARG macros.  These
+   hide the differences between K+R <varargs.h> and C89 <stdarg.h> more
+   thoroughly than the simple VA_START() macro mentioned above.
+
+   VA_OPEN and VA_CLOSE are used *instead of* va_start and va_end.
+   Immediately after VA_OPEN, put a sequence of VA_FIXEDARG calls
+   corresponding to the list of fixed arguments.  Then use va_arg
+   normally to get the variable arguments, or pass your va_list object
+   around.  You do not declare the va_list yourself; VA_OPEN does it
+   for you.
+
+   Here is a complete example:
+
+       int
+       printf VPARAMS ((const char *format, ...))
+       {
+          int result;
+
+          VA_OPEN (ap, format);
+          VA_FIXEDARG (ap, const char *, format);
+
+          result = vfprintf (stdout, format, ap);
+          VA_CLOSE (ap);
+
+          return result;
+       }
+
+
+   You can declare variables either before or after the VA_OPEN,
+   VA_FIXEDARG sequence.  Also, VA_OPEN and VA_CLOSE are the beginning
+   and end of a block.  They must appear at the same nesting level,
+   and any variables declared after VA_OPEN go out of scope at
+   VA_CLOSE.  Unfortunately, with a K+R compiler, that includes the
+   argument list.  You can have multiple instances of VA_OPEN/VA_CLOSE
+   pairs in a single function in case you need to traverse the
+   argument list more than once.
+
+   For ease of writing code which uses GCC extensions but needs to be
+   portable to other compilers, we provide the GCC_VERSION macro that
+   simplifies testing __GNUC__ and __GNUC_MINOR__ together, and various
+   wrappers around __attribute__.  Also, __extension__ will be #defined
+   to nothing if it doesn't work.  See below.
+
+   This header also defines a lot of obsolete macros:
+   CONST, VOLATILE, SIGNED, PROTO, EXFUN, DEFUN, DEFUN_VOID,
+   AND, DOTS, NOARGS.  Don't use them.  */
+
+#ifndef        _ANSIDECL_H
+#define _ANSIDECL_H    1
+
+/* Every source file includes this file,
+   so they will all get the switch for lint.  */
+/* LINTLIBRARY */
+
+/* Using MACRO(x,y) in cpp #if conditionals does not work with some
+   older preprocessors.  Thus we can't define something like this:
+
+#define HAVE_GCC_VERSION(MAJOR, MINOR) \
+  (__GNUC__ > (MAJOR) || (__GNUC__ == (MAJOR) && __GNUC_MINOR__ >= (MINOR)))
+
+and then test "#if HAVE_GCC_VERSION(2,7)".
+
+So instead we use the macro below and test it against specific values.  */
+
+/* This macro simplifies testing whether we are using gcc, and if it
+   is of a particular minimum version. (Both major & minor numbers are
+   significant.)  This macro will evaluate to 0 if we are not using
+   gcc at all.  */
+#ifndef GCC_VERSION
+#define GCC_VERSION (__GNUC__ * 1000 + __GNUC_MINOR__)
+#endif /* GCC_VERSION */
+
+#if defined (__STDC__) || defined (_AIX) || (defined (__mips) && defined (_SYSTYPE_SVR4)) || defined(_WIN32) || (defined(__alpha) && defined(__cplusplus))
+/* All known AIX compilers implement these things (but don't always
+   define __STDC__).  The RISC/OS MIPS compiler defines these things
+   in SVR4 mode, but does not define __STDC__.  */
+/* eraxxon@alumni.rice.edu: The Compaq C++ compiler, unlike many other
+   C++ compilers, does not define __STDC__, though it acts as if this
+   was so. (Verified versions: 5.7, 6.2, 6.3, 6.5) */
+
+#define ANSI_PROTOTYPES        1
+#define PTR            void *
+#define PTRCONST       void *const
+#define LONG_DOUBLE    long double
+
+#define PARAMS(ARGS)           ARGS
+#define VPARAMS(ARGS)          ARGS
+#define VA_START(VA_LIST, VAR) va_start(VA_LIST, VAR)
+
+/* variadic function helper macros */
+/* "struct Qdmy" swallows the semicolon after VA_OPEN/VA_FIXEDARG's
+   use without inhibiting further decls and without declaring an
+   actual variable.  */
+#define VA_OPEN(AP, VAR)       { va_list AP; va_start(AP, VAR); { struct Qdmy
+#define VA_CLOSE(AP)           } va_end(AP); }
+#define VA_FIXEDARG(AP, T, N)  struct Qdmy
+#undef const
+#undef volatile
+#undef signed
+
+/* inline requires special treatment; it's in C99, and GCC >=2.7 supports
+   it too, but it's not in C89.  */
+#undef inline
+#if __STDC_VERSION__ > 199901L
+/* it's a keyword */
+#else
+# if GCC_VERSION >= 2007
+#  define inline __inline__   /* __inline__ prevents -pedantic warnings */
+# else
+#  define inline  /* nothing */
+# endif
+#endif
+
+/* These are obsolete.  Do not use.  */
+#ifndef IN_GCC
+#define CONST          const
+#define VOLATILE       volatile
+#define SIGNED         signed
+
+#define PROTO(type, name, arglist)     type name arglist
+#define EXFUN(name, proto)             name proto
+#define DEFUN(name, arglist, args)     name(args)
+#define DEFUN_VOID(name)               name(void)
+#define AND            ,
+#define DOTS           , ...
+#define NOARGS         void
+#endif /* ! IN_GCC */
+
+#else  /* Not ANSI C.  */
+
+#undef  ANSI_PROTOTYPES
+#define PTR            char *
+#define PTRCONST       PTR
+#define LONG_DOUBLE    double
+
+#define PARAMS(args)           ()
+#define VPARAMS(args)          (va_alist) va_dcl
+#define VA_START(va_list, var) va_start(va_list)
+
+#define VA_OPEN(AP, VAR)               { va_list AP; va_start(AP); { struct Qdmy
+#define VA_CLOSE(AP)                   } va_end(AP); }
+#define VA_FIXEDARG(AP, TYPE, NAME)    TYPE NAME = va_arg(AP, TYPE)
+
+/* some systems define these in header files for non-ansi mode */
+#undef const
+#undef volatile
+#undef signed
+#undef inline
+#define const
+#define volatile
+#define signed
+#define inline
+
+#ifndef IN_GCC
+#define CONST
+#define VOLATILE
+#define SIGNED
+
+#define PROTO(type, name, arglist)     type name ()
+#define EXFUN(name, proto)             name()
+#define DEFUN(name, arglist, args)     name arglist args;
+#define DEFUN_VOID(name)               name()
+#define AND            ;
+#define DOTS
+#define NOARGS
+#endif /* ! IN_GCC */
+
+#endif /* ANSI C.  */
+
+/* Define macros for some gcc attributes.  This permits us to use the
+   macros freely, and know that they will come into play for the
+   version of gcc in which they are supported.  */
+
+#if (GCC_VERSION < 2007)
+# define __attribute__(x)
+#endif
+
+/* Attribute __malloc__ on functions was valid as of gcc 2.96. */
+#ifndef ATTRIBUTE_MALLOC
+# if (GCC_VERSION >= 2096)
+#  define ATTRIBUTE_MALLOC __attribute__ ((__malloc__))
+# else
+#  define ATTRIBUTE_MALLOC
+# endif /* GNUC >= 2.96 */
+#endif /* ATTRIBUTE_MALLOC */
+
+/* Attributes on labels were valid as of gcc 2.93. */
+#ifndef ATTRIBUTE_UNUSED_LABEL
+# if (GCC_VERSION >= 2093)
+#  define ATTRIBUTE_UNUSED_LABEL ATTRIBUTE_UNUSED
+# else
+#  define ATTRIBUTE_UNUSED_LABEL
+# endif /* GNUC >= 2.93 */
+#endif /* ATTRIBUTE_UNUSED_LABEL */
+
+#ifndef ATTRIBUTE_UNUSED
+#define ATTRIBUTE_UNUSED __attribute__ ((__unused__))
+#endif /* ATTRIBUTE_UNUSED */
+
+#ifndef ATTRIBUTE_NORETURN
+#define ATTRIBUTE_NORETURN __attribute__ ((__noreturn__))
+#endif /* ATTRIBUTE_NORETURN */
+
+/* Attribute `nonnull' was valid as of gcc 3.3.  */
+#ifndef ATTRIBUTE_NONNULL
+# if (GCC_VERSION >= 3003)
+#  define ATTRIBUTE_NONNULL(m) __attribute__ ((__nonnull__ (m)))
+# else
+#  define ATTRIBUTE_NONNULL(m)
+# endif /* GNUC >= 3.3 */
+#endif /* ATTRIBUTE_NONNULL */
+
+/* Use ATTRIBUTE_PRINTF when the format specifier must not be NULL.
+   This was the case for the `printf' format attribute by itself
+   before GCC 3.3, but as of 3.3 we need to add the `nonnull'
+   attribute to retain this behavior.  */
+#ifndef ATTRIBUTE_PRINTF
+#define ATTRIBUTE_PRINTF(m, n) __attribute__ ((__format__ (__printf__, m, n))) ATTRIBUTE_NONNULL(m)
+#define ATTRIBUTE_PRINTF_1 ATTRIBUTE_PRINTF(1, 2)
+#define ATTRIBUTE_PRINTF_2 ATTRIBUTE_PRINTF(2, 3)
+#define ATTRIBUTE_PRINTF_3 ATTRIBUTE_PRINTF(3, 4)
+#define ATTRIBUTE_PRINTF_4 ATTRIBUTE_PRINTF(4, 5)
+#define ATTRIBUTE_PRINTF_5 ATTRIBUTE_PRINTF(5, 6)
+#endif /* ATTRIBUTE_PRINTF */
+
+/* Use ATTRIBUTE_NULL_PRINTF when the format specifier may be NULL.  A
+   NULL format specifier was allowed as of gcc 3.3.  */
+#ifndef ATTRIBUTE_NULL_PRINTF
+# if (GCC_VERSION >= 3003)
+#  define ATTRIBUTE_NULL_PRINTF(m, n) __attribute__ ((__format__ (__printf__, m, n)))
+# else
+#  define ATTRIBUTE_NULL_PRINTF(m, n)
+# endif /* GNUC >= 3.3 */
+# define ATTRIBUTE_NULL_PRINTF_1 ATTRIBUTE_NULL_PRINTF(1, 2)
+# define ATTRIBUTE_NULL_PRINTF_2 ATTRIBUTE_NULL_PRINTF(2, 3)
+# define ATTRIBUTE_NULL_PRINTF_3 ATTRIBUTE_NULL_PRINTF(3, 4)
+# define ATTRIBUTE_NULL_PRINTF_4 ATTRIBUTE_NULL_PRINTF(4, 5)
+# define ATTRIBUTE_NULL_PRINTF_5 ATTRIBUTE_NULL_PRINTF(5, 6)
+#endif /* ATTRIBUTE_NULL_PRINTF */
+
+/* We use __extension__ in some places to suppress -pedantic warnings
+   about GCC extensions.  This feature didn't work properly before
+   gcc 2.8.  */
+#if GCC_VERSION < 2008
+#define __extension__
+#endif
+
+/* Bootstrap support:  Adjust certain macros defined by Autoconf,
+   which are only valid for the stage1 compiler.  If we detect
+   a modern version of GCC, we are probably in stage2 or beyond,
+   so unconditionally reset the values.  Note that const, inline,
+   etc. have been dealt with above.  */
+#if (GCC_VERSION >= 2007)
+# ifndef HAVE_LONG_DOUBLE
+#  define HAVE_LONG_DOUBLE 1
+# endif
+#endif /* GCC >= 2.7 */
+
+#endif /* ansidecl.h   */
diff --git a/Repair/RepairCompiler/structextract/include/bin-bugs.h b/Repair/RepairCompiler/structextract/include/bin-bugs.h
new file mode 100755 (executable)
index 0000000..3c97715
--- /dev/null
@@ -0,0 +1,3 @@
+#ifndef REPORT_BUGS_TO
+#define REPORT_BUGS_TO "bug-binutils@gnu.org"
+#endif
diff --git a/Repair/RepairCompiler/structextract/include/bucomm.h b/Repair/RepairCompiler/structextract/include/bucomm.h
new file mode 100755 (executable)
index 0000000..2598d13
--- /dev/null
@@ -0,0 +1,214 @@
+/* bucomm.h -- binutils common include file.
+   Copyright 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
+   2002, 2003 Free Software Foundation, Inc.
+
+   This file is part of GNU Binutils.
+
+   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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+\f
+#ifndef _BUCOMM_H
+#define _BUCOMM_H
+
+#include "ansidecl.h"
+#include <stdio.h>
+#include <sys/types.h>
+
+#include "config.h"
+#include "bin-bugs.h"
+
+#ifdef ANSI_PROTOTYPES
+#include <stdarg.h>
+#else
+#include <varargs.h>
+#endif
+
+#ifdef USE_BINARY_FOPEN
+#include "fopen-bin.h"
+#else
+#include "fopen-same.h"
+#endif
+
+#include <errno.h>
+#ifndef errno
+extern int errno;
+#endif
+
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+#ifdef HAVE_STRING_H
+#include <string.h>
+#else
+#ifdef HAVE_STRINGS_H
+#include <strings.h>
+#else
+extern char *strchr ();
+extern char *strrchr ();
+#endif
+#endif
+
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+
+#ifdef HAVE_FCNTL_H
+#include <fcntl.h>
+#else
+#ifdef HAVE_SYS_FILE_H
+#include <sys/file.h>
+#endif
+#endif
+
+#ifdef NEED_DECLARATION_STRSTR
+extern char *strstr ();
+#endif
+
+#ifdef HAVE_SBRK
+#ifdef NEED_DECLARATION_SBRK
+extern char *sbrk ();
+#endif
+#endif
+
+#ifdef NEED_DECLARATION_GETENV
+extern char *getenv ();
+#endif
+
+#ifdef NEED_DECLARATION_ENVIRON
+extern char **environ;
+#endif
+
+#ifndef O_RDONLY
+#define O_RDONLY 0
+#endif
+
+#ifndef O_RDWR
+#define O_RDWR 2
+#endif
+
+#ifndef SEEK_SET
+#define SEEK_SET 0
+#endif
+#ifndef SEEK_CUR
+#define SEEK_CUR 1
+#endif
+#ifndef SEEK_END
+#define SEEK_END 2
+#endif
+
+#if defined(__GNUC__) && !defined(C_ALLOCA)
+# undef alloca
+# define alloca __builtin_alloca
+#else
+# if defined(HAVE_ALLOCA_H) && !defined(C_ALLOCA)
+#  include <alloca.h>
+# else
+#  ifndef alloca /* predefined by HP cc +Olibcalls */
+#   if !defined (__STDC__) && !defined (__hpux)
+char *alloca ();
+#   else
+void *alloca ();
+#   endif /* __STDC__, __hpux */
+#  endif /* alloca */
+# endif /* HAVE_ALLOCA_H */
+#endif
+
+#ifdef HAVE_LOCALE_H
+# include <locale.h>
+#endif
+
+#ifdef ENABLE_NLS
+# include <libintl.h>
+# define _(String) gettext (String)
+# ifdef gettext_noop
+#  define N_(String) gettext_noop (String)
+# else
+#  define N_(String) (String)
+# endif
+#else
+# define gettext(Msgid) (Msgid)
+# define dgettext(Domainname, Msgid) (Msgid)
+# define dcgettext(Domainname, Msgid, Category) (Msgid)
+# define textdomain(Domainname) while (0) /* nothing */
+# define bindtextdomain(Domainname, Dirname) while (0) /* nothing */
+# define _(String) (String)
+# define N_(String) (String)
+#endif
+
+/* bucomm.c */
+void bfd_nonfatal
+  PARAMS ((const char *));
+
+void bfd_fatal
+  PARAMS ((const char *)) ATTRIBUTE_NORETURN;
+
+void report
+  PARAMS ((const char *, va_list));
+
+void fatal
+  PARAMS ((const char *, ...)) ATTRIBUTE_PRINTF_1 ATTRIBUTE_NORETURN;
+
+void non_fatal
+  PARAMS ((const char *, ...)) ATTRIBUTE_PRINTF_1;
+
+void set_default_bfd_target
+  PARAMS ((void));
+
+void list_matching_formats
+  PARAMS ((char **));
+
+void list_supported_targets
+  PARAMS ((const char *, FILE *));
+
+void list_supported_architectures
+  PARAMS ((const char *, FILE *));
+
+int display_info
+  PARAMS ((void));
+  
+void print_arelt_descr
+  PARAMS ((FILE *, bfd *, bfd_boolean));
+
+char *make_tempname
+  PARAMS ((char *));
+
+bfd_vma parse_vma
+  PARAMS ((const char *, const char *));
+
+extern char *program_name;
+
+/* filemode.c */
+void mode_string
+  PARAMS ((unsigned long, char *));
+
+/* version.c */
+extern void print_version
+  PARAMS ((const char *));
+
+/* rename.c */
+extern void set_times
+  PARAMS ((const char *, const struct stat *));
+
+extern int smart_rename
+  PARAMS ((const char *, const char *, int));
+
+/* libiberty.  */
+PTR xmalloc
+  PARAMS ((size_t));
+
+PTR xrealloc
+  PARAMS ((PTR, size_t));
+
+#endif /* _BUCOMM_H */
diff --git a/Repair/RepairCompiler/structextract/include/config.h b/Repair/RepairCompiler/structextract/include/config.h
new file mode 100755 (executable)
index 0000000..b5849dc
--- /dev/null
@@ -0,0 +1,205 @@
+/* config.h.  Generated automatically by configure.  */
+/* config.in.  Generated automatically from configure.in by autoheader.  */
+
+/* Define if using alloca.c.  */
+/* #undef C_ALLOCA */
+
+/* Define to empty if the keyword does not work.  */
+/* #undef const */
+
+/* Define to one of _getb67, GETB67, getb67 for Cray-2 and Cray-YMP systems.
+   This function is required for alloca.c support on those systems.  */
+/* #undef CRAY_STACKSEG_END */
+
+/* Define if you have alloca, as a function or macro.  */
+#define HAVE_ALLOCA 1
+
+/* Define if you have <alloca.h> and it should be used (not on Ultrix).  */
+#define HAVE_ALLOCA_H 1
+
+/* Define if you have a working `mmap' system call.  */
+#define HAVE_MMAP 1
+
+/* Define if you have <sys/wait.h> that is POSIX.1 compatible.  */
+#define HAVE_SYS_WAIT_H 1
+
+/* Define as __inline if that's what the C compiler calls it.  */
+/* #undef inline */
+
+/* Define to `long' if <sys/types.h> doesn't define.  */
+/* #undef off_t */
+
+/* Define to `unsigned' if <sys/types.h> doesn't define.  */
+/* #undef size_t */
+
+/* If using the C implementation of alloca, define if you know the
+   direction of stack growth for your system; otherwise it will be
+   automatically deduced at run-time.
+ STACK_DIRECTION > 0 => grows toward higher addresses
+ STACK_DIRECTION < 0 => grows toward lower addresses
+ STACK_DIRECTION = 0 => direction of growth unknown
+ */
+/* #undef STACK_DIRECTION */
+
+/* Define if you have the ANSI C header files.  */
+#define STDC_HEADERS 1
+
+/* Define if lex declares yytext as a char * by default, not a char[].  */
+#define YYTEXT_POINTER 1
+
+/* Define if you have the __argz_count function.  */
+#define HAVE___ARGZ_COUNT 1
+
+/* Define if you have the __argz_next function.  */
+#define HAVE___ARGZ_NEXT 1
+
+/* Define if you have the __argz_stringify function.  */
+#define HAVE___ARGZ_STRINGIFY 1
+
+/* Define if you have the dcgettext function.  */
+#define HAVE_DCGETTEXT 1
+
+/* Define if you have the getc_unlocked function.  */
+#define HAVE_GETC_UNLOCKED 1
+
+/* Define if you have the getcwd function.  */
+#define HAVE_GETCWD 1
+
+/* Define if you have the getpagesize function.  */
+#define HAVE_GETPAGESIZE 1
+
+/* Define if you have the munmap function.  */
+#define HAVE_MUNMAP 1
+
+/* Define if you have the putenv function.  */
+#define HAVE_PUTENV 1
+
+/* Define if you have the sbrk function.  */
+#define HAVE_SBRK 1
+
+/* Define if you have the setenv function.  */
+#define HAVE_SETENV 1
+
+/* Define if you have the setlocale function.  */
+#define HAVE_SETLOCALE 1
+
+/* Define if you have the setmode function.  */
+/* #undef HAVE_SETMODE */
+
+/* Define if you have the stpcpy function.  */
+#define HAVE_STPCPY 1
+
+/* Define if you have the strcasecmp function.  */
+#define HAVE_STRCASECMP 1
+
+/* Define if you have the strchr function.  */
+#define HAVE_STRCHR 1
+
+/* Define if you have the strcoll function.  */
+#define HAVE_STRCOLL 1
+
+/* Define if you have the utimes function.  */
+#define HAVE_UTIMES 1
+
+/* Define if you have the <argz.h> header file.  */
+#define HAVE_ARGZ_H 1
+
+/* Define if you have the <fcntl.h> header file.  */
+#define HAVE_FCNTL_H 1
+
+/* Define if you have the <limits.h> header file.  */
+#define HAVE_LIMITS_H 1
+
+/* Define if you have the <locale.h> header file.  */
+#define HAVE_LOCALE_H 1
+
+/* Define if you have the <malloc.h> header file.  */
+#define HAVE_MALLOC_H 1
+
+/* Define if you have the <nl_types.h> header file.  */
+#define HAVE_NL_TYPES_H 1
+
+/* Define if you have the <stdlib.h> header file.  */
+#define HAVE_STDLIB_H 1
+
+/* Define if you have the <string.h> header file.  */
+#define HAVE_STRING_H 1
+
+/* Define if you have the <strings.h> header file.  */
+#define HAVE_STRINGS_H 1
+
+/* Define if you have the <sys/file.h> header file.  */
+#define HAVE_SYS_FILE_H 1
+
+/* Define if you have the <sys/param.h> header file.  */
+#define HAVE_SYS_PARAM_H 1
+
+/* Define if you have the <unistd.h> header file.  */
+#define HAVE_UNISTD_H 1
+
+/* Define if you have the <values.h> header file.  */
+#define HAVE_VALUES_H 1
+
+/* Name of package */
+#define PACKAGE "binutils"
+
+/* Version number of package */
+#define VERSION "2.14"
+
+/* Define if you have the stpcpy function */
+#define HAVE_STPCPY 1
+
+/* Define if your locale.h file contains LC_MESSAGES. */
+#define HAVE_LC_MESSAGES 1
+
+/* Define to 1 if NLS is requested */
+#define ENABLE_NLS 1
+
+/* Define as 1 if you have gettext and don't want to use GNU gettext. */
+#define HAVE_GETTEXT 1
+
+/* Does the platform use an executable suffix? */
+/* #undef HAVE_EXECUTABLE_SUFFIX */
+
+/* Suffix used for executables, if any. */
+#define EXECUTABLE_SUFFIX ""
+
+/* Is fopen64 available? */
+#define HAVE_FOPEN64 1
+
+/* Enable LFS */
+/* #undef _LARGEFILE64_SOURCE */
+
+/* Is the type time_t defined in <time.h>? */
+#define HAVE_TIME_T_IN_TIME_H 1
+
+/* Is the type time_t defined in <sys/types.h>? */
+#define HAVE_TIME_T_IN_TYPES_H 1
+
+/* Does <utime.h> define struct utimbuf? */
+#define HAVE_GOOD_UTIME_H 1
+
+/* Define if fprintf is not declared in system header files. */
+/* #undef NEED_DECLARATION_FPRINTF */
+
+/* Define if strstr is not declared in system header files. */
+/* #undef NEED_DECLARATION_STRSTR */
+
+/* Define if sbrk is not declared in system header files. */
+/* #undef NEED_DECLARATION_SBRK */
+
+/* Define if getenv is not declared in system header files. */
+/* #undef NEED_DECLARATION_GETENV */
+
+/* Define if environ is not declared in system header files. */
+#define NEED_DECLARATION_ENVIRON 1
+
+/* Use b modifier when opening binary files? */
+/* #undef USE_BINARY_FOPEN */
+
+/* Configured target name. */
+#define TARGET "i686-pc-linux-gnu"
+
+/* Define to 1 if user symbol names have a leading underscore, 0 if not. */
+#define TARGET_PREPENDS_UNDERSCORE 0
+
diff --git a/Repair/RepairCompiler/structextract/include/elf/common.h b/Repair/RepairCompiler/structextract/include/elf/common.h
new file mode 100755 (executable)
index 0000000..ca79342
--- /dev/null
@@ -0,0 +1,690 @@
+/* ELF support for BFD.
+   Copyright 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
+   2001, 2002, 2003
+   Free Software Foundation, Inc.
+
+   Written by Fred Fish @ Cygnus Support, from information published
+   in "UNIX System V Release 4, Programmers Guide: ANSI C and
+   Programming Support Tools".
+
+   This file is part of BFD, the Binary File Descriptor library.
+
+   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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+
+/* This file is part of ELF support for BFD, and contains the portions
+   that are common to both the internal and external representations.
+   For example, ELFMAG0 is the byte 0x7F in both the internal (in-memory)
+   and external (in-file) representations.  */
+
+#ifndef _ELF_COMMON_H
+#define _ELF_COMMON_H
+
+/* Fields in e_ident[].  */
+
+#define EI_MAG0                0       /* File identification byte 0 index */
+#define ELFMAG0                   0x7F /* Magic number byte 0 */
+
+#define EI_MAG1                1       /* File identification byte 1 index */
+#define ELFMAG1                    'E' /* Magic number byte 1 */
+
+#define EI_MAG2                2       /* File identification byte 2 index */
+#define ELFMAG2                    'L' /* Magic number byte 2 */
+
+#define EI_MAG3                3       /* File identification byte 3 index */
+#define ELFMAG3                    'F' /* Magic number byte 3 */
+
+#define EI_CLASS       4       /* File class */
+#define ELFCLASSNONE         0 /* Invalid class */
+#define ELFCLASS32           1 /* 32-bit objects */
+#define ELFCLASS64           2 /* 64-bit objects */
+
+#define EI_DATA                5       /* Data encoding */
+#define ELFDATANONE          0 /* Invalid data encoding */
+#define ELFDATA2LSB          1 /* 2's complement, little endian */
+#define ELFDATA2MSB          2 /* 2's complement, big endian */
+
+#define EI_VERSION     6       /* File version */
+
+#define EI_OSABI       7       /* Operating System/ABI indication */
+#define ELFOSABI_NONE        0 /* UNIX System V ABI */
+#define ELFOSABI_HPUX        1 /* HP-UX operating system */
+#define ELFOSABI_NETBSD              2 /* NetBSD */
+#define ELFOSABI_LINUX       3 /* GNU/Linux */
+#define ELFOSABI_HURD        4 /* GNU/Hurd */
+#define ELFOSABI_SOLARIS      6        /* Solaris */
+#define ELFOSABI_AIX         7 /* AIX */
+#define ELFOSABI_IRIX        8 /* IRIX */
+#define ELFOSABI_FREEBSD      9        /* FreeBSD */
+#define ELFOSABI_TRU64      10 /* TRU64 UNIX */
+#define ELFOSABI_MODESTO     11        /* Novell Modesto */
+#define ELFOSABI_OPENBSD     12        /* OpenBSD */
+#define ELFOSABI_OPENVMS     13        /* OpenVMS */
+#define ELFOSABI_NSK        14 /* Hewlett-Packard Non-Stop Kernel */
+#define ELFOSABI_AROS       15 /* Amiga Research OS */
+#define ELFOSABI_ARM        97 /* ARM */
+#define ELFOSABI_STANDALONE 255        /* Standalone (embedded) application */
+
+#define EI_ABIVERSION  8       /* ABI version */
+
+#define EI_PAD         9       /* Start of padding bytes */
+
+
+/* Values for e_type, which identifies the object file type.  */
+
+#define ET_NONE                0       /* No file type */
+#define ET_REL         1       /* Relocatable file */
+#define ET_EXEC                2       /* Executable file */
+#define ET_DYN         3       /* Shared object file */
+#define ET_CORE                4       /* Core file */
+#define ET_LOOS                0xFE00  /* Operating system-specific */
+#define ET_HIOS                0xFEFF  /* Operating system-specific */
+#define ET_LOPROC      0xFF00  /* Processor-specific */
+#define ET_HIPROC      0xFFFF  /* Processor-specific */
+
+/* Values for e_machine, which identifies the architecture.  These numbers
+   are officially assigned by registry@caldera.com.  See below for a list of
+   ad-hoc numbers used during initial development.  */
+
+#define EM_NONE                  0     /* No machine */
+#define EM_M32           1     /* AT&T WE 32100 */
+#define EM_SPARC         2     /* SUN SPARC */
+#define EM_386           3     /* Intel 80386 */
+#define EM_68K           4     /* Motorola m68k family */
+#define EM_88K           5     /* Motorola m88k family */
+#define EM_486           6     /* Intel 80486 *//* Reserved for future use */
+#define EM_860           7     /* Intel 80860 */
+#define EM_MIPS                  8     /* MIPS R3000 (officially, big-endian only) */
+#define EM_S370                  9     /* IBM System/370 */
+#define EM_MIPS_RS3_LE  10     /* MIPS R3000 little-endian (Oct 4 1999 Draft) Deprecated */
+
+#define EM_PARISC       15     /* HPPA */
+
+#define EM_VPP550       17     /* Fujitsu VPP500 */
+#define EM_SPARC32PLUS  18     /* Sun's "v8plus" */
+#define EM_960          19     /* Intel 80960 */
+#define EM_PPC          20     /* PowerPC */
+#define EM_PPC64        21     /* 64-bit PowerPC */
+#define EM_S390                 22     /* IBM S/390 */
+
+#define EM_V800                 36     /* NEC V800 series */
+#define EM_FR20                 37     /* Fujitsu FR20 */
+#define EM_RH32                 38     /* TRW RH32 */
+#define EM_MCORE        39     /* Motorola M*Core */ /* May also be taken by Fujitsu MMA */
+#define EM_RCE          39     /* Old name for MCore */
+#define EM_ARM          40     /* ARM */
+#define EM_OLD_ALPHA    41     /* Digital Alpha */
+#define EM_SH           42     /* Renesas (formerly Hitachi) / SuperH SH */
+#define EM_SPARCV9      43     /* SPARC v9 64-bit */
+#define EM_TRICORE      44     /* Siemens Tricore embedded processor */
+#define EM_ARC          45     /* ARC Cores */
+#define EM_H8_300       46     /* Renesas (formerly Hitachi) H8/300 */
+#define EM_H8_300H      47     /* Renesas (formerly Hitachi) H8/300H */
+#define EM_H8S          48     /* Renesas (formerly Hitachi) H8S */
+#define EM_H8_500       49     /* Renesas (formerly Hitachi) H8/500 */
+#define EM_IA_64        50     /* Intel IA-64 Processor */
+#define EM_MIPS_X       51     /* Stanford MIPS-X */
+#define EM_COLDFIRE     52     /* Motorola Coldfire */
+#define EM_68HC12       53     /* Motorola M68HC12 */
+#define EM_MMA          54     /* Fujitsu Multimedia Accelerator */
+#define EM_PCP          55     /* Siemens PCP */
+#define EM_NCPU                 56     /* Sony nCPU embedded RISC processor */
+#define EM_NDR1                 57     /* Denso NDR1 microprocesspr */
+#define EM_STARCORE     58     /* Motorola Star*Core processor */
+#define EM_ME16                 59     /* Toyota ME16 processor */
+#define EM_ST100        60     /* STMicroelectronics ST100 processor */
+#define EM_TINYJ        61     /* Advanced Logic Corp. TinyJ embedded processor */
+#define EM_X86_64       62     /* Advanced Micro Devices X86-64 processor */
+
+#define EM_PDP10        64     /* Digital Equipment Corp. PDP-10 */
+#define EM_PDP11        65     /* Digital Equipment Corp. PDP-11 */
+#define EM_FX66                 66     /* Siemens FX66 microcontroller */
+#define EM_ST9PLUS      67     /* STMicroelectronics ST9+ 8/16 bit microcontroller */
+#define EM_ST7          68     /* STMicroelectronics ST7 8-bit microcontroller */
+#define EM_68HC16       69     /* Motorola MC68HC16 Microcontroller */
+#define EM_68HC11       70     /* Motorola MC68HC11 Microcontroller */
+#define EM_68HC08       71     /* Motorola MC68HC08 Microcontroller */
+#define EM_68HC05       72     /* Motorola MC68HC05 Microcontroller */
+#define EM_SVX          73     /* Silicon Graphics SVx */
+#define EM_ST19                 74     /* STMicroelectronics ST19 8-bit cpu */
+#define EM_VAX          75     /* Digital VAX */
+#define EM_CRIS                 76     /* Axis Communications 32-bit embedded processor */
+#define EM_JAVELIN      77     /* Infineon Technologies 32-bit embedded cpu */
+#define EM_FIREPATH     78     /* Element 14 64-bit DSP processor */
+#define EM_ZSP          79     /* LSI Logic's 16-bit DSP processor */
+#define EM_MMIX                 80     /* Donald Knuth's educational 64-bit processor */
+#define EM_HUANY        81     /* Harvard's machine-independent format */
+#define EM_PRISM        82     /* SiTera Prism */
+#define EM_AVR          83     /* Atmel AVR 8-bit microcontroller */
+#define EM_FR30                 84     /* Fujitsu FR30 */
+#define EM_D10V                 85     /* Mitsubishi D10V */
+#define EM_D30V                 86     /* Mitsubishi D30V */
+#define EM_V850                 87     /* NEC v850 */
+#define EM_M32R                 88     /* Renesas M32R (formerly Mitsubishi M32R) */
+#define EM_MN10300      89     /* Matsushita MN10300 */
+#define EM_MN10200      90     /* Matsushita MN10200 */
+#define EM_PJ           91     /* picoJava */
+#define EM_OPENRISC     92     /* OpenRISC 32-bit embedded processor */
+#define EM_ARC_A5       93     /* ARC Cores Tangent-A5 */
+#define EM_XTENSA       94     /* Tensilica Xtensa Architecture */
+#define EM_IP2K                101     /* Ubicom IP2022 micro controller */
+#define EM_MSP430      105     /* TI msp430 micro controller */
+
+/* If it is necessary to assign new unofficial EM_* values, please pick large
+   random numbers (0x8523, 0xa7f2, etc.) to minimize the chances of collision
+   with official or non-GNU unofficial values.
+
+   NOTE: Do not just increment the most recent number by one.
+   Somebody else somewhere will do exactly the same thing, and you
+   will have a collision.  Instead, pick a random number.
+
+   Normally, each entity or maintainer responsible for a machine with an
+   unofficial e_machine number should eventually ask registry@caldera.com for
+   an officially blessed number to be added to the list above. */
+
+#define EM_PJ_OLD      99      /* picoJava */
+
+/* Cygnus PowerPC ELF backend.  Written in the absence of an ABI.  */
+#define EM_CYGNUS_POWERPC 0x9025
+
+/* Old version of Sparc v9, from before the ABI; this should be
+   removed shortly.  */
+#define EM_OLD_SPARCV9 11
+
+/* Old version of PowerPC, this should be removed shortly. */
+#define EM_PPC_OLD     17
+
+/* (Deprecated) Temporary number for the OpenRISC processor.  */
+#define EM_OR32                0x8472
+
+/* Cygnus M32R ELF backend.  Written in the absence of an ABI.  */
+#define EM_CYGNUS_M32R 0x9041
+
+/* Alpha backend magic number.  Written in the absence of an ABI.  */
+#define EM_ALPHA       0x9026
+
+/* old S/390 backend magic number. Written in the absence of an ABI.  */
+#define EM_S390_OLD    0xa390
+
+/* D10V backend magic number.  Written in the absence of an ABI.  */
+#define EM_CYGNUS_D10V 0x7650
+
+/* D30V backend magic number.  Written in the absence of an ABI.  */
+#define EM_CYGNUS_D30V 0x7676
+
+/* V850 backend magic number.  Written in the absense of an ABI.  */
+#define EM_CYGNUS_V850 0x9080
+
+/* mn10200 and mn10300 backend magic numbers.
+   Written in the absense of an ABI.  */
+#define EM_CYGNUS_MN10200      0xdead
+#define EM_CYGNUS_MN10300      0xbeef
+
+/* FR30 magic number - no EABI available.  */
+#define EM_CYGNUS_FR30         0x3330
+
+/* AVR magic number
+   Written in the absense of an ABI.  */
+#define EM_AVR_OLD             0x1057
+
+/* OpenRISC magic number
+   Written in the absense of an ABI.  */
+#define EM_OPENRISC_OLD                0x3426
+
+/* DLX magic number
+   Written in the absense of an ABI.  */
+#define EM_DLX                 0x5aa5
+
+#define EM_XSTORMY16           0xad45
+
+/* FRV magic number - no EABI available??.  */
+#define EM_CYGNUS_FRV          0x5441
+
+/* Ubicom IP2xxx; no ABI */
+#define EM_IP2K_OLD            0x8217  
+
+/* MSP430 magic number
+      Written in the absense everything.  */
+#define EM_MSP430_OLD          0x1059
+
+/* Vitesse IQ2000.  */
+#define EM_IQ2000              0xFEBA
+
+/* Old, unofficial value for Xtensa.  */
+#define EM_XTENSA_OLD          0xabc7
+
+/* See the above comment before you add a new EM_* value here.  */
+
+/* Values for e_version.  */
+
+#define EV_NONE                0               /* Invalid ELF version */
+#define EV_CURRENT     1               /* Current version */
+
+/* Values for program header, p_type field.  */
+
+#define PT_NULL                0               /* Program header table entry unused */
+#define PT_LOAD                1               /* Loadable program segment */
+#define PT_DYNAMIC     2               /* Dynamic linking information */
+#define PT_INTERP      3               /* Program interpreter */
+#define PT_NOTE                4               /* Auxiliary information */
+#define PT_SHLIB       5               /* Reserved, unspecified semantics */
+#define PT_PHDR                6               /* Entry for header table itself */
+#define PT_TLS         7               /* Thread local storage segment */
+#define PT_LOOS                0x60000000      /* OS-specific */
+#define PT_HIOS                0x6fffffff      /* OS-specific */
+#define PT_LOPROC      0x70000000      /* Processor-specific */
+#define PT_HIPROC      0x7FFFFFFF      /* Processor-specific */
+
+#define PT_GNU_EH_FRAME        (PT_LOOS + 0x474e550)
+
+/* Program segment permissions, in program header p_flags field.  */
+
+#define PF_X           (1 << 0)        /* Segment is executable */
+#define PF_W           (1 << 1)        /* Segment is writable */
+#define PF_R           (1 << 2)        /* Segment is readable */
+/* #define PF_MASKOS   0x0F000000    *//* OS-specific reserved bits */
+#define PF_MASKOS      0x0FF00000      /* New value, Oct 4, 1999 Draft */
+#define PF_MASKPROC    0xF0000000      /* Processor-specific reserved bits */
+
+/* Values for section header, sh_type field.  */
+
+#define SHT_NULL       0               /* Section header table entry unused */
+#define SHT_PROGBITS   1               /* Program specific (private) data */
+#define SHT_SYMTAB     2               /* Link editing symbol table */
+#define SHT_STRTAB     3               /* A string table */
+#define SHT_RELA       4               /* Relocation entries with addends */
+#define SHT_HASH       5               /* A symbol hash table */
+#define SHT_DYNAMIC    6               /* Information for dynamic linking */
+#define SHT_NOTE       7               /* Information that marks file */
+#define SHT_NOBITS     8               /* Section occupies no space in file */
+#define SHT_REL                9               /* Relocation entries, no addends */
+#define SHT_SHLIB      10              /* Reserved, unspecified semantics */
+#define SHT_DYNSYM     11              /* Dynamic linking symbol table */
+
+#define SHT_INIT_ARRAY   14            /* Array of ptrs to init functions */
+#define SHT_FINI_ARRAY   15            /* Array of ptrs to finish functions */
+#define SHT_PREINIT_ARRAY 16           /* Array of ptrs to pre-init funcs */
+#define SHT_GROUP        17            /* Section contains a section group */
+#define SHT_SYMTAB_SHNDX  18           /* Indicies for SHN_XINDEX entries */
+
+#define SHT_LOOS       0x60000000      /* First of OS specific semantics */
+#define SHT_HIOS       0x6fffffff      /* Last of OS specific semantics */
+
+#define SHT_GNU_LIBLIST        0x6ffffff7      /* List of prelink dependencies */
+
+/* The next three section types are defined by Solaris, and are named
+   SHT_SUNW*.  We use them in GNU code, so we also define SHT_GNU*
+   versions.  */
+#define SHT_SUNW_verdef        0x6ffffffd      /* Versions defined by file */
+#define SHT_SUNW_verneed 0x6ffffffe    /* Versions needed by file */
+#define SHT_SUNW_versym        0x6fffffff      /* Symbol versions */
+
+#define SHT_GNU_verdef SHT_SUNW_verdef
+#define SHT_GNU_verneed        SHT_SUNW_verneed
+#define SHT_GNU_versym SHT_SUNW_versym
+
+#define SHT_LOPROC     0x70000000      /* Processor-specific semantics, lo */
+#define SHT_HIPROC     0x7FFFFFFF      /* Processor-specific semantics, hi */
+#define SHT_LOUSER     0x80000000      /* Application-specific semantics */
+/* #define SHT_HIUSER  0x8FFFFFFF    *//* Application-specific semantics */
+#define SHT_HIUSER     0xFFFFFFFF      /* New value, defined in Oct 4, 1999 Draft */
+
+/* Values for section header, sh_flags field.  */
+
+#define SHF_WRITE      (1 << 0)        /* Writable data during execution */
+#define SHF_ALLOC      (1 << 1)        /* Occupies memory during execution */
+#define SHF_EXECINSTR  (1 << 2)        /* Executable machine instructions */
+#define SHF_MERGE      (1 << 4)        /* Data in this section can be merged */
+#define SHF_STRINGS    (1 << 5)        /* Contains null terminated character strings */
+#define SHF_INFO_LINK  (1 << 6)        /* sh_info holds section header table index */
+#define SHF_LINK_ORDER (1 << 7)        /* Preserve section ordering when linking */
+#define SHF_OS_NONCONFORMING (1 << 8)  /* OS specific processing required */
+#define SHF_GROUP      (1 << 9)        /* Member of a section group */
+#define SHF_TLS                (1 << 10)       /* Thread local storage section */
+
+/* #define SHF_MASKOS  0x0F000000    *//* OS-specific semantics */
+#define SHF_MASKOS     0x0FF00000      /* New value, Oct 4, 1999 Draft */
+#define SHF_MASKPROC   0xF0000000      /* Processor-specific semantics */
+
+/* Values of note segment descriptor types for core files.  */
+
+#define NT_PRSTATUS    1               /* Contains copy of prstatus struct */
+#define NT_FPREGSET    2               /* Contains copy of fpregset struct */
+#define NT_PRPSINFO    3               /* Contains copy of prpsinfo struct */
+#define NT_TASKSTRUCT  4               /* Contains copy of task struct */
+#define NT_PRXFPREG    0x46e62b7f      /* Contains a user_xfpregs_struct; */
+                                       /*   note name must be "LINUX".  */
+
+/* Note segments for core files on dir-style procfs systems.  */
+
+#define NT_PSTATUS     10              /* Has a struct pstatus */
+#define NT_FPREGS      12              /* Has a struct fpregset */
+#define NT_PSINFO      13              /* Has a struct psinfo */
+#define NT_LWPSTATUS   16              /* Has a struct lwpstatus_t */
+#define NT_LWPSINFO    17              /* Has a struct lwpsinfo_t */
+#define NT_WIN32PSTATUS        18              /* Has a struct win32_pstatus */
+
+
+/* Note segments for core files on NetBSD systems.  Note name
+   must start with "NetBSD-CORE".  */
+
+#define NT_NETBSDCORE_PROCINFO 1       /* Has a struct procinfo */
+#define NT_NETBSDCORE_FIRSTMACH        32      /* start of machdep note types */
+
+
+/* Values of note segment descriptor types for object files.  */
+
+#define NT_VERSION     1               /* Contains a version string.  */
+#define NT_ARCH                2               /* Contains an architecture string.  */
+
+/* Values for GNU .note.ABI-tag notes.  Note name is "GNU".  */
+
+#define NT_GNU_ABI_TAG         1
+#define GNU_ABI_TAG_LINUX      0
+#define GNU_ABI_TAG_HURD       1
+#define GNU_ABI_TAG_SOLARIS    2
+
+/* Values for NetBSD .note.netbsd.ident notes.  Note name is "NetBSD".  */
+
+#define NT_NETBSD_IDENT                1
+
+/* Values for FreeBSD .note.ABI-tag notes.  Note name is "FreeBSD".  */
+
+#define NT_FREEBSD_ABI_TAG     1
+
+/* These three macros disassemble and assemble a symbol table st_info field,
+   which contains the symbol binding and symbol type.  The STB_ and STT_
+   defines identify the binding and type.  */
+
+#define ELF_ST_BIND(val)               (((unsigned int)(val)) >> 4)
+#define ELF_ST_TYPE(val)               ((val) & 0xF)
+#define ELF_ST_INFO(bind,type)         (((bind) << 4) + ((type) & 0xF))
+
+/* The 64bit and 32bit versions of these macros are identical, but
+   the ELF spec defines them, so here they are.  */
+#define ELF32_ST_BIND  ELF_ST_BIND
+#define ELF32_ST_TYPE  ELF_ST_TYPE
+#define ELF32_ST_INFO  ELF_ST_INFO
+#define ELF64_ST_BIND  ELF_ST_BIND
+#define ELF64_ST_TYPE  ELF_ST_TYPE
+#define ELF64_ST_INFO  ELF_ST_INFO
+
+/* This macro disassembles and assembles a symbol's visibility into
+   the st_other field.  The STV_ defines specificy the actual visibility.  */
+
+#define ELF_ST_VISIBILITY(v)           ((v) & 0x3)
+/* The remaining bits in the st_other field are not currently used.
+   They should be set to zero.  */
+
+#define ELF32_ST_VISIBILITY  ELF_ST_VISIBILITY
+#define ELF64_ST_VISIBILITY  ELF_ST_VISIBILITY
+
+
+#define STN_UNDEF      0               /* Undefined symbol index */
+
+#define STB_LOCAL      0               /* Symbol not visible outside obj */
+#define STB_GLOBAL     1               /* Symbol visible outside obj */
+#define STB_WEAK       2               /* Like globals, lower precedence */
+#define STB_LOOS       10              /* OS-specific semantics */
+#define STB_HIOS       12              /* OS-specific semantics */
+#define STB_LOPROC     13              /* Application-specific semantics */
+#define STB_HIPROC     15              /* Application-specific semantics */
+
+#define STT_NOTYPE     0               /* Symbol type is unspecified */
+#define STT_OBJECT     1               /* Symbol is a data object */
+#define STT_FUNC       2               /* Symbol is a code object */
+#define STT_SECTION    3               /* Symbol associated with a section */
+#define STT_FILE       4               /* Symbol gives a file name */
+#define STT_COMMON     5               /* An uninitialised common block */
+#define STT_TLS                6               /* Thread local data object */
+#define STT_LOOS       10              /* OS-specific semantics */
+#define STT_HIOS       12              /* OS-specific semantics */
+#define STT_LOPROC     13              /* Application-specific semantics */
+#define STT_HIPROC     15              /* Application-specific semantics */
+
+/* Special section indices, which may show up in st_shndx fields, among
+   other places.  */
+
+#define SHN_UNDEF      0               /* Undefined section reference */
+#define SHN_LORESERVE  0xFF00          /* Begin range of reserved indices */
+#define SHN_LOPROC     0xFF00          /* Begin range of appl-specific */
+#define SHN_HIPROC     0xFF1F          /* End range of appl-specific */
+#define SHN_LOOS       0xFF20          /* OS specific semantics, lo */
+#define SHN_HIOS       0xFF3F          /* OS specific semantics, hi */
+#define SHN_ABS                0xFFF1          /* Associated symbol is absolute */
+#define SHN_COMMON     0xFFF2          /* Associated symbol is in common */
+#define SHN_XINDEX     0xFFFF          /* Section index is held elsewhere */
+#define SHN_HIRESERVE  0xFFFF          /* End range of reserved indices */
+#define SHN_BAD                ((unsigned) -1) /* Used internally by bfd */
+
+/* The following constants control how a symbol may be accessed once it has
+   become part of an executable or shared library.  */
+                                          
+#define STV_DEFAULT    0               /* Visibility is specified by binding type */
+#define STV_INTERNAL   1               /* OS specific version of STV_HIDDEN */
+#define STV_HIDDEN     2               /* Can only be seen inside currect component */
+#define STV_PROTECTED  3               /* Treat as STB_LOCAL inside current component */
+
+/* Relocation info handling macros.  */
+
+#define ELF32_R_SYM(i)         ((i) >> 8)
+#define ELF32_R_TYPE(i)                ((i) & 0xff)
+#define ELF32_R_INFO(s,t)      (((s) << 8) + ((t) & 0xff))
+
+#define ELF64_R_SYM(i)         ((i) >> 32)
+#define ELF64_R_TYPE(i)                ((i) & 0xffffffff)
+#define ELF64_R_INFO(s,t)      (((bfd_vma) (s) << 32) + (bfd_vma) (t))
+
+/* Dynamic section tags.  */
+
+#define DT_NULL                0
+#define DT_NEEDED      1
+#define DT_PLTRELSZ    2
+#define DT_PLTGOT      3
+#define DT_HASH                4
+#define DT_STRTAB      5
+#define DT_SYMTAB      6
+#define DT_RELA                7
+#define DT_RELASZ      8
+#define DT_RELAENT     9
+#define DT_STRSZ       10
+#define DT_SYMENT      11
+#define DT_INIT                12
+#define DT_FINI                13
+#define DT_SONAME      14
+#define DT_RPATH       15
+#define DT_SYMBOLIC    16
+#define DT_REL         17
+#define DT_RELSZ       18
+#define DT_RELENT      19
+#define DT_PLTREL      20
+#define DT_DEBUG       21
+#define DT_TEXTREL     22
+#define DT_JMPREL      23
+#define DT_BIND_NOW    24
+#define DT_INIT_ARRAY  25
+#define DT_FINI_ARRAY  26
+#define DT_INIT_ARRAYSZ 27
+#define DT_FINI_ARRAYSZ 28
+#define DT_RUNPATH     29
+#define DT_FLAGS       30
+#define DT_ENCODING    31
+#define DT_PREINIT_ARRAY   32
+#define DT_PREINIT_ARRAYSZ 33
+
+/* Note, the Oct 4, 1999 draft of the ELF ABI changed the values
+   for DT_LOOS and DT_HIOS.  Some implementations however, use
+   values outside of the new range (see below).         */
+#define OLD_DT_LOOS    0x60000000
+#define DT_LOOS                0x6000000d
+#define DT_HIOS                0x6fff0000
+#define OLD_DT_HIOS    0x6fffffff
+
+#define DT_LOPROC      0x70000000
+#define DT_HIPROC      0x7fffffff
+
+/* The next four dynamic tags are used on Solaris.  We support them
+   everywhere. Note these values lie outside of the (new) range for
+   OS specific values. This is a deliberate special case and we
+   maintain it for backwards compatability.  */
+#define DT_VALRNGLO    0x6ffffd00
+#define DT_GNU_PRELINKED 0x6ffffdf5
+#define DT_GNU_CONFLICTSZ 0x6ffffdf6
+#define DT_GNU_LIBLISTSZ 0x6ffffdf7
+#define DT_CHECKSUM    0x6ffffdf8
+#define DT_PLTPADSZ    0x6ffffdf9
+#define DT_MOVEENT     0x6ffffdfa
+#define DT_MOVESZ      0x6ffffdfb
+#define DT_FEATURE     0x6ffffdfc
+#define DT_POSFLAG_1   0x6ffffdfd
+#define DT_SYMINSZ     0x6ffffdfe
+#define DT_SYMINENT    0x6ffffdff
+#define DT_VALRNGHI    0x6ffffdff
+
+#define DT_ADDRRNGLO   0x6ffffe00
+#define DT_GNU_CONFLICT        0x6ffffef8
+#define DT_GNU_LIBLIST 0x6ffffef9
+#define DT_CONFIG      0x6ffffefa
+#define DT_DEPAUDIT    0x6ffffefb
+#define DT_AUDIT       0x6ffffefc
+#define DT_PLTPAD      0x6ffffefd
+#define DT_MOVETAB     0x6ffffefe
+#define DT_SYMINFO     0x6ffffeff
+#define DT_ADDRRNGHI   0x6ffffeff
+
+#define DT_RELACOUNT   0x6ffffff9
+#define DT_RELCOUNT    0x6ffffffa
+#define DT_FLAGS_1     0x6ffffffb
+#define DT_VERDEF      0x6ffffffc
+#define DT_VERDEFNUM   0x6ffffffd
+#define DT_VERNEED     0x6ffffffe
+#define DT_VERNEEDNUM  0x6fffffff
+
+/* This tag is a GNU extension to the Solaris version scheme.  */
+#define DT_VERSYM      0x6ffffff0
+
+#define DT_LOPROC      0x70000000
+#define DT_HIPROC      0x7fffffff
+
+/* These section tags are used on Solaris.  We support them
+   everywhere, and hope they do not conflict.  */
+
+#define DT_AUXILIARY   0x7ffffffd
+#define DT_USED                0x7ffffffe
+#define DT_FILTER      0x7fffffff
+
+
+/* Values used in DT_FEATURE .dynamic entry.  */
+#define DTF_1_PARINIT  0x00000001
+/* From
+
+   http://docs.sun.com:80/ab2/coll.45.13/LLM/@Ab2PageView/21165?Ab2Lang=C&Ab2Enc=iso-8859-1
+
+   DTF_1_CONFEXP is the same as DTF_1_PARINIT. It is a typo. The value
+   defined here is the same as the one in <sys/link.h> on Solaris 8.  */
+#define DTF_1_CONFEXP  0x00000002
+
+/* Flag values used in the DT_POSFLAG_1 .dynamic entry.         */
+#define DF_P1_LAZYLOAD 0x00000001
+#define DF_P1_GROUPPERM        0x00000002
+
+/* Flag value in in the DT_FLAGS_1 .dynamic entry.  */
+#define DF_1_NOW       0x00000001
+#define DF_1_GLOBAL    0x00000002
+#define DF_1_GROUP     0x00000004
+#define DF_1_NODELETE  0x00000008
+#define DF_1_LOADFLTR  0x00000010
+#define DF_1_INITFIRST 0x00000020
+#define DF_1_NOOPEN    0x00000040
+#define DF_1_ORIGIN    0x00000080
+#define DF_1_DIRECT    0x00000100
+#define DF_1_TRANS     0x00000200
+#define DF_1_INTERPOSE 0x00000400
+#define DF_1_NODEFLIB  0x00000800
+#define DF_1_NODUMP    0x00001000
+#define DF_1_CONLFAT   0x00002000
+
+/* Flag values for the DT_FLAGS entry. */
+#define DF_ORIGIN      (1 << 0)
+#define DF_SYMBOLIC    (1 << 1)
+#define DF_TEXTREL     (1 << 2)
+#define DF_BIND_NOW    (1 << 3)
+#define DF_STATIC_TLS  (1 << 4)
+
+/* These constants are used for the version number of a Elf32_Verdef
+   structure.  */
+
+#define VER_DEF_NONE           0
+#define VER_DEF_CURRENT                1
+
+/* These constants appear in the vd_flags field of a Elf32_Verdef
+   structure.  */
+
+#define VER_FLG_BASE           0x1
+#define VER_FLG_WEAK           0x2
+
+/* These special constants can be found in an Elf32_Versym field.  */
+
+#define VER_NDX_LOCAL          0
+#define VER_NDX_GLOBAL         1
+
+/* These constants are used for the version number of a Elf32_Verneed
+   structure.  */
+
+#define VER_NEED_NONE          0
+#define VER_NEED_CURRENT       1
+
+/* This flag appears in a Versym structure.  It means that the symbol
+   is hidden, and is only visible with an explicit version number.
+   This is a GNU extension.  */
+
+#define VERSYM_HIDDEN          0x8000
+
+/* This is the mask for the rest of the Versym information.  */
+
+#define VERSYM_VERSION         0x7fff
+
+/* This is a special token which appears as part of a symbol name.  It
+   indictes that the rest of the name is actually the name of a
+   version node, and is not part of the actual name.  This is a GNU
+   extension.  For example, the symbol name `stat@ver2' is taken to
+   mean the symbol `stat' in version `ver2'.  */
+
+#define ELF_VER_CHR    '@'
+
+/* Possible values for si_boundto.  */
+
+#define SYMINFO_BT_SELF                0xffff  /* Symbol bound to self */
+#define SYMINFO_BT_PARENT      0xfffe  /* Symbol bound to parent */
+#define SYMINFO_BT_LOWRESERVE  0xff00  /* Beginning of reserved entries */
+
+/* Possible bitmasks for si_flags.  */
+
+#define SYMINFO_FLG_DIRECT     0x0001  /* Direct bound symbol */
+#define SYMINFO_FLG_PASSTHRU   0x0002  /* Pass-thru symbol for translator */
+#define SYMINFO_FLG_COPY       0x0004  /* Symbol is a copy-reloc */
+#define SYMINFO_FLG_LAZYLOAD   0x0008  /* Symbol bound to object to be lazy loaded */
+
+/* Syminfo version values.  */
+
+#define SYMINFO_NONE           0
+#define SYMINFO_CURRENT                1
+#define SYMINFO_NUM            2
+
+/* Section Group Flags.         */
+
+#define GRP_COMDAT             0x1     /* A COMDAT group */
+
+#endif /* _ELF_COMMON_H */
diff --git a/Repair/RepairCompiler/structextract/include/elf/dwarf2.h b/Repair/RepairCompiler/structextract/include/elf/dwarf2.h
new file mode 100755 (executable)
index 0000000..9c8ce4e
--- /dev/null
@@ -0,0 +1,728 @@
+/* Declarations and definitions of codes relating to the DWARF2 symbolic
+   debugging information format.
+   Copyright (C) 1992, 1993, 1995, 1996, 1997, 1999, 2000, 2001, 2002
+   Free Software Foundation, Inc.
+
+   Written by Gary Funck (gary@intrepid.com) The Ada Joint Program
+   Office (AJPO), Florida State Unviversity and Silicon Graphics Inc.
+   provided support for this effort -- June 21, 1995.
+
+   Derived from the DWARF 1 implementation written by Ron Guilmette
+   (rfg@netcom.com), November 1990.
+
+   This file is part of GCC.
+
+   GCC 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, or (at your option) any later
+   version.
+
+   GCC 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 GCC; see the file COPYING.  If not, write to the Free
+   Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+   02111-1307, USA.  */
+
+/* This file is derived from the DWARF specification (a public document)
+   Revision 2.0.0 (July 27, 1993) developed by the UNIX International
+   Programming Languages Special Interest Group (UI/PLSIG) and distributed
+   by UNIX International.  Copies of this specification are available from
+   UNIX International, 20 Waterview Boulevard, Parsippany, NJ, 07054.
+
+   This file also now contains definitions from the DWARF 3 specification.  */
+
+/* This file is shared between GCC and GDB, and should not contain
+   prototypes.  */
+
+#ifndef _ELF_DWARF2_H
+#define _ELF_DWARF2_H
+
+/* Structure found in the .debug_line section.  */
+typedef struct
+{
+  unsigned char li_length          [4];
+  unsigned char li_version         [2];
+  unsigned char li_prologue_length [4];
+  unsigned char li_min_insn_length [1];
+  unsigned char li_default_is_stmt [1];
+  unsigned char li_line_base       [1];
+  unsigned char li_line_range      [1];
+  unsigned char li_opcode_base     [1];
+}
+DWARF2_External_LineInfo;
+
+typedef struct
+{
+  unsigned long  li_length;
+  unsigned short li_version;
+  unsigned int   li_prologue_length;
+  unsigned char  li_min_insn_length;
+  unsigned char  li_default_is_stmt;
+  int            li_line_base;
+  unsigned char  li_line_range;
+  unsigned char  li_opcode_base;
+}
+DWARF2_Internal_LineInfo;
+
+/* Structure found in .debug_pubnames section.  */
+typedef struct
+{
+  unsigned char pn_length  [4];
+  unsigned char pn_version [2];
+  unsigned char pn_offset  [4];
+  unsigned char pn_size    [4];
+}
+DWARF2_External_PubNames;
+
+typedef struct
+{
+  unsigned long  pn_length;
+  unsigned short pn_version;
+  unsigned long  pn_offset;
+  unsigned long  pn_size;
+}
+DWARF2_Internal_PubNames;
+
+/* Structure found in .debug_info section.  */
+typedef struct
+{
+  unsigned char  cu_length        [4];
+  unsigned char  cu_version       [2];
+  unsigned char  cu_abbrev_offset [4];
+  unsigned char  cu_pointer_size  [1];
+}
+DWARF2_External_CompUnit;
+
+typedef struct
+{
+  unsigned long  cu_length;
+  unsigned short cu_version;
+  unsigned long  cu_abbrev_offset;
+  unsigned char  cu_pointer_size;
+}
+DWARF2_Internal_CompUnit;
+
+typedef struct
+{
+  unsigned char  ar_length       [4];
+  unsigned char  ar_version      [2];
+  unsigned char  ar_info_offset  [4];
+  unsigned char  ar_pointer_size [1];
+  unsigned char  ar_segment_size [1];
+}
+DWARF2_External_ARange;
+
+typedef struct
+{
+  unsigned long  ar_length;
+  unsigned short ar_version;
+  unsigned long  ar_info_offset;
+  unsigned char  ar_pointer_size;
+  unsigned char  ar_segment_size;
+}
+DWARF2_Internal_ARange;
+
+
+/* Tag names and codes.  */
+enum dwarf_tag
+  {
+    DW_TAG_padding = 0x00,
+    DW_TAG_array_type = 0x01,
+    DW_TAG_class_type = 0x02,
+    DW_TAG_entry_point = 0x03,
+    DW_TAG_enumeration_type = 0x04,
+    DW_TAG_formal_parameter = 0x05,
+    DW_TAG_imported_declaration = 0x08,
+    DW_TAG_label = 0x0a,
+    DW_TAG_lexical_block = 0x0b,
+    DW_TAG_member = 0x0d,
+    DW_TAG_pointer_type = 0x0f,
+    DW_TAG_reference_type = 0x10,
+    DW_TAG_compile_unit = 0x11,
+    DW_TAG_string_type = 0x12,
+    DW_TAG_structure_type = 0x13,
+    DW_TAG_subroutine_type = 0x15,
+    DW_TAG_typedef = 0x16,
+    DW_TAG_union_type = 0x17,
+    DW_TAG_unspecified_parameters = 0x18,
+    DW_TAG_variant = 0x19,
+    DW_TAG_common_block = 0x1a,
+    DW_TAG_common_inclusion = 0x1b,
+    DW_TAG_inheritance = 0x1c,
+    DW_TAG_inlined_subroutine = 0x1d,
+    DW_TAG_module = 0x1e,
+    DW_TAG_ptr_to_member_type = 0x1f,
+    DW_TAG_set_type = 0x20,
+    DW_TAG_subrange_type = 0x21,
+    DW_TAG_with_stmt = 0x22,
+    DW_TAG_access_declaration = 0x23,
+    DW_TAG_base_type = 0x24,
+    DW_TAG_catch_block = 0x25,
+    DW_TAG_const_type = 0x26,
+    DW_TAG_constant = 0x27,
+    DW_TAG_enumerator = 0x28,
+    DW_TAG_file_type = 0x29,
+    DW_TAG_friend = 0x2a,
+    DW_TAG_namelist = 0x2b,
+    DW_TAG_namelist_item = 0x2c,
+    DW_TAG_packed_type = 0x2d,
+    DW_TAG_subprogram = 0x2e,
+    DW_TAG_template_type_param = 0x2f,
+    DW_TAG_template_value_param = 0x30,
+    DW_TAG_thrown_type = 0x31,
+    DW_TAG_try_block = 0x32,
+    DW_TAG_variant_part = 0x33,
+    DW_TAG_variable = 0x34,
+    DW_TAG_volatile_type = 0x35,
+    /* DWARF 3.  */
+    DW_TAG_dwarf_procedure = 0x36,
+    DW_TAG_restrict_type = 0x37,
+    DW_TAG_interface_type = 0x38,
+    DW_TAG_namespace = 0x39,
+    DW_TAG_imported_module = 0x3a,
+    DW_TAG_unspecified_type = 0x3b,
+    DW_TAG_partial_unit = 0x3c,
+    DW_TAG_imported_unit = 0x3d,
+    /* SGI/MIPS Extensions.  */
+    DW_TAG_MIPS_loop = 0x4081,
+    /* GNU extensions.  */
+    DW_TAG_format_label = 0x4101,      /* For FORTRAN 77 and Fortran 90.  */
+    DW_TAG_function_template = 0x4102, /* For C++.  */
+    DW_TAG_class_template = 0x4103,    /* For C++.  */
+    DW_TAG_GNU_BINCL = 0x4104,
+    DW_TAG_GNU_EINCL = 0x4105,
+    /* Extensions for UPC.  See: http://upc.gwu.edu/~upc.  */
+    DW_TAG_upc_shared_type = 0x8765,
+    DW_TAG_upc_strict_type = 0x8766,
+    DW_TAG_upc_relaxed_type = 0x8767
+  };
+
+#define DW_TAG_lo_user 0x4080
+#define DW_TAG_hi_user 0xffff
+
+/* Flag that tells whether entry has a child or not.  */
+#define DW_children_no   0
+#define        DW_children_yes  1
+
+/* Form names and codes.  */
+enum dwarf_form
+  {
+    DW_FORM_addr = 0x01,
+    DW_FORM_block2 = 0x03,
+    DW_FORM_block4 = 0x04,
+    DW_FORM_data2 = 0x05,
+    DW_FORM_data4 = 0x06,
+    DW_FORM_data8 = 0x07,
+    DW_FORM_string = 0x08,
+    DW_FORM_block = 0x09,
+    DW_FORM_block1 = 0x0a,
+    DW_FORM_data1 = 0x0b,
+    DW_FORM_flag = 0x0c,
+    DW_FORM_sdata = 0x0d,
+    DW_FORM_strp = 0x0e,
+    DW_FORM_udata = 0x0f,
+    DW_FORM_ref_addr = 0x10,
+    DW_FORM_ref1 = 0x11,
+    DW_FORM_ref2 = 0x12,
+    DW_FORM_ref4 = 0x13,
+    DW_FORM_ref8 = 0x14,
+    DW_FORM_ref_udata = 0x15,
+    DW_FORM_indirect = 0x16
+  };
+
+/* Attribute names and codes.  */
+
+enum dwarf_attribute
+  {
+    DW_AT_sibling = 0x01,
+    DW_AT_location = 0x02,
+    DW_AT_name = 0x03,
+    DW_AT_ordering = 0x09,
+    DW_AT_subscr_data = 0x0a,
+    DW_AT_byte_size = 0x0b,
+    DW_AT_bit_offset = 0x0c,
+    DW_AT_bit_size = 0x0d,
+    DW_AT_element_list = 0x0f,
+    DW_AT_stmt_list = 0x10,
+    DW_AT_low_pc = 0x11,
+    DW_AT_high_pc = 0x12,
+    DW_AT_language = 0x13,
+    DW_AT_member = 0x14,
+    DW_AT_discr = 0x15,
+    DW_AT_discr_value = 0x16,
+    DW_AT_visibility = 0x17,
+    DW_AT_import = 0x18,
+    DW_AT_string_length = 0x19,
+    DW_AT_common_reference = 0x1a,
+    DW_AT_comp_dir = 0x1b,
+    DW_AT_const_value = 0x1c,
+    DW_AT_containing_type = 0x1d,
+    DW_AT_default_value = 0x1e,
+    DW_AT_inline = 0x20,
+    DW_AT_is_optional = 0x21,
+    DW_AT_lower_bound = 0x22,
+    DW_AT_producer = 0x25,
+    DW_AT_prototyped = 0x27,
+    DW_AT_return_addr = 0x2a,
+    DW_AT_start_scope = 0x2c,
+    DW_AT_stride_size = 0x2e,
+    DW_AT_upper_bound = 0x2f,
+    DW_AT_abstract_origin = 0x31,
+    DW_AT_accessibility = 0x32,
+    DW_AT_address_class = 0x33,
+    DW_AT_artificial = 0x34,
+    DW_AT_base_types = 0x35,
+    DW_AT_calling_convention = 0x36,
+    DW_AT_count = 0x37,
+    DW_AT_data_member_location = 0x38,
+    DW_AT_decl_column = 0x39,
+    DW_AT_decl_file = 0x3a,
+    DW_AT_decl_line = 0x3b,
+    DW_AT_declaration = 0x3c,
+    DW_AT_discr_list = 0x3d,
+    DW_AT_encoding = 0x3e,
+    DW_AT_external = 0x3f,
+    DW_AT_frame_base = 0x40,
+    DW_AT_friend = 0x41,
+    DW_AT_identifier_case = 0x42,
+    DW_AT_macro_info = 0x43,
+    DW_AT_namelist_items = 0x44,
+    DW_AT_priority = 0x45,
+    DW_AT_segment = 0x46,
+    DW_AT_specification = 0x47,
+    DW_AT_static_link = 0x48,
+    DW_AT_type = 0x49,
+    DW_AT_use_location = 0x4a,
+    DW_AT_variable_parameter = 0x4b,
+    DW_AT_virtuality = 0x4c,
+    DW_AT_vtable_elem_location = 0x4d,
+    /* DWARF 3 values.  */
+    DW_AT_allocated     = 0x4e,
+    DW_AT_associated    = 0x4f,
+    DW_AT_data_location = 0x50,
+    DW_AT_stride        = 0x51,
+    DW_AT_entry_pc      = 0x52,
+    DW_AT_use_UTF8      = 0x53,
+    DW_AT_extension     = 0x54,
+    DW_AT_ranges        = 0x55,
+    DW_AT_trampoline    = 0x56,
+    DW_AT_call_column   = 0x57,
+    DW_AT_call_file     = 0x58,
+    DW_AT_call_line     = 0x59,
+    /* SGI/MIPS extensions.  */
+    DW_AT_MIPS_fde = 0x2001,
+    DW_AT_MIPS_loop_begin = 0x2002,
+    DW_AT_MIPS_tail_loop_begin = 0x2003,
+    DW_AT_MIPS_epilog_begin = 0x2004,
+    DW_AT_MIPS_loop_unroll_factor = 0x2005,
+    DW_AT_MIPS_software_pipeline_depth = 0x2006,
+    DW_AT_MIPS_linkage_name = 0x2007,
+    DW_AT_MIPS_stride = 0x2008,
+    DW_AT_MIPS_abstract_name = 0x2009,
+    DW_AT_MIPS_clone_origin = 0x200a,
+    DW_AT_MIPS_has_inlines = 0x200b,
+    /* GNU extensions.  */
+    DW_AT_sf_names   = 0x2101,
+    DW_AT_src_info   = 0x2102,
+    DW_AT_mac_info   = 0x2103,
+    DW_AT_src_coords = 0x2104,
+    DW_AT_body_begin = 0x2105,
+    DW_AT_body_end   = 0x2106,
+    DW_AT_GNU_vector = 0x2107,
+    /* VMS extensions.  */
+    DW_AT_VMS_rtnbeg_pd_address = 0x2201,
+    /* UPC extension.  */
+    DW_AT_upc_threads_scaled = 0x3210
+  };
+
+#define DW_AT_lo_user  0x2000  /* Implementation-defined range start.  */
+#define DW_AT_hi_user  0x3ff0  /* Implementation-defined range end.  */
+
+/* Location atom names and codes.  */
+enum dwarf_location_atom
+  {
+    DW_OP_addr = 0x03,
+    DW_OP_deref = 0x06,
+    DW_OP_const1u = 0x08,
+    DW_OP_const1s = 0x09,
+    DW_OP_const2u = 0x0a,
+    DW_OP_const2s = 0x0b,
+    DW_OP_const4u = 0x0c,
+    DW_OP_const4s = 0x0d,
+    DW_OP_const8u = 0x0e,
+    DW_OP_const8s = 0x0f,
+    DW_OP_constu = 0x10,
+    DW_OP_consts = 0x11,
+    DW_OP_dup = 0x12,
+    DW_OP_drop = 0x13,
+    DW_OP_over = 0x14,
+    DW_OP_pick = 0x15,
+    DW_OP_swap = 0x16,
+    DW_OP_rot = 0x17,
+    DW_OP_xderef = 0x18,
+    DW_OP_abs = 0x19,
+    DW_OP_and = 0x1a,
+    DW_OP_div = 0x1b,
+    DW_OP_minus = 0x1c,
+    DW_OP_mod = 0x1d,
+    DW_OP_mul = 0x1e,
+    DW_OP_neg = 0x1f,
+    DW_OP_not = 0x20,
+    DW_OP_or = 0x21,
+    DW_OP_plus = 0x22,
+    DW_OP_plus_uconst = 0x23,
+    DW_OP_shl = 0x24,
+    DW_OP_shr = 0x25,
+    DW_OP_shra = 0x26,
+    DW_OP_xor = 0x27,
+    DW_OP_bra = 0x28,
+    DW_OP_eq = 0x29,
+    DW_OP_ge = 0x2a,
+    DW_OP_gt = 0x2b,
+    DW_OP_le = 0x2c,
+    DW_OP_lt = 0x2d,
+    DW_OP_ne = 0x2e,
+    DW_OP_skip = 0x2f,
+    DW_OP_lit0 = 0x30,
+    DW_OP_lit1 = 0x31,
+    DW_OP_lit2 = 0x32,
+    DW_OP_lit3 = 0x33,
+    DW_OP_lit4 = 0x34,
+    DW_OP_lit5 = 0x35,
+    DW_OP_lit6 = 0x36,
+    DW_OP_lit7 = 0x37,
+    DW_OP_lit8 = 0x38,
+    DW_OP_lit9 = 0x39,
+    DW_OP_lit10 = 0x3a,
+    DW_OP_lit11 = 0x3b,
+    DW_OP_lit12 = 0x3c,
+    DW_OP_lit13 = 0x3d,
+    DW_OP_lit14 = 0x3e,
+    DW_OP_lit15 = 0x3f,
+    DW_OP_lit16 = 0x40,
+    DW_OP_lit17 = 0x41,
+    DW_OP_lit18 = 0x42,
+    DW_OP_lit19 = 0x43,
+    DW_OP_lit20 = 0x44,
+    DW_OP_lit21 = 0x45,
+    DW_OP_lit22 = 0x46,
+    DW_OP_lit23 = 0x47,
+    DW_OP_lit24 = 0x48,
+    DW_OP_lit25 = 0x49,
+    DW_OP_lit26 = 0x4a,
+    DW_OP_lit27 = 0x4b,
+    DW_OP_lit28 = 0x4c,
+    DW_OP_lit29 = 0x4d,
+    DW_OP_lit30 = 0x4e,
+    DW_OP_lit31 = 0x4f,
+    DW_OP_reg0 = 0x50,
+    DW_OP_reg1 = 0x51,
+    DW_OP_reg2 = 0x52,
+    DW_OP_reg3 = 0x53,
+    DW_OP_reg4 = 0x54,
+    DW_OP_reg5 = 0x55,
+    DW_OP_reg6 = 0x56,
+    DW_OP_reg7 = 0x57,
+    DW_OP_reg8 = 0x58,
+    DW_OP_reg9 = 0x59,
+    DW_OP_reg10 = 0x5a,
+    DW_OP_reg11 = 0x5b,
+    DW_OP_reg12 = 0x5c,
+    DW_OP_reg13 = 0x5d,
+    DW_OP_reg14 = 0x5e,
+    DW_OP_reg15 = 0x5f,
+    DW_OP_reg16 = 0x60,
+    DW_OP_reg17 = 0x61,
+    DW_OP_reg18 = 0x62,
+    DW_OP_reg19 = 0x63,
+    DW_OP_reg20 = 0x64,
+    DW_OP_reg21 = 0x65,
+    DW_OP_reg22 = 0x66,
+    DW_OP_reg23 = 0x67,
+    DW_OP_reg24 = 0x68,
+    DW_OP_reg25 = 0x69,
+    DW_OP_reg26 = 0x6a,
+    DW_OP_reg27 = 0x6b,
+    DW_OP_reg28 = 0x6c,
+    DW_OP_reg29 = 0x6d,
+    DW_OP_reg30 = 0x6e,
+    DW_OP_reg31 = 0x6f,
+    DW_OP_breg0 = 0x70,
+    DW_OP_breg1 = 0x71,
+    DW_OP_breg2 = 0x72,
+    DW_OP_breg3 = 0x73,
+    DW_OP_breg4 = 0x74,
+    DW_OP_breg5 = 0x75,
+    DW_OP_breg6 = 0x76,
+    DW_OP_breg7 = 0x77,
+    DW_OP_breg8 = 0x78,
+    DW_OP_breg9 = 0x79,
+    DW_OP_breg10 = 0x7a,
+    DW_OP_breg11 = 0x7b,
+    DW_OP_breg12 = 0x7c,
+    DW_OP_breg13 = 0x7d,
+    DW_OP_breg14 = 0x7e,
+    DW_OP_breg15 = 0x7f,
+    DW_OP_breg16 = 0x80,
+    DW_OP_breg17 = 0x81,
+    DW_OP_breg18 = 0x82,
+    DW_OP_breg19 = 0x83,
+    DW_OP_breg20 = 0x84,
+    DW_OP_breg21 = 0x85,
+    DW_OP_breg22 = 0x86,
+    DW_OP_breg23 = 0x87,
+    DW_OP_breg24 = 0x88,
+    DW_OP_breg25 = 0x89,
+    DW_OP_breg26 = 0x8a,
+    DW_OP_breg27 = 0x8b,
+    DW_OP_breg28 = 0x8c,
+    DW_OP_breg29 = 0x8d,
+    DW_OP_breg30 = 0x8e,
+    DW_OP_breg31 = 0x8f,
+    DW_OP_regx = 0x90,
+    DW_OP_fbreg = 0x91,
+    DW_OP_bregx = 0x92,
+    DW_OP_piece = 0x93,
+    DW_OP_deref_size = 0x94,
+    DW_OP_xderef_size = 0x95,
+    DW_OP_nop = 0x96,
+    /* DWARF 3 extensions.  */
+    DW_OP_push_object_address = 0x97,
+    DW_OP_call2 = 0x98,
+    DW_OP_call4 = 0x99,
+    DW_OP_call_ref = 0x9a,
+    /* GNU extensions.  */
+    DW_OP_GNU_push_tls_address = 0xe0
+  };
+
+#define DW_OP_lo_user  0xe0    /* Implementation-defined range start.  */
+#define DW_OP_hi_user  0xff    /* Implementation-defined range end.  */
+
+/* Type encodings.  */
+enum dwarf_type
+  {
+    DW_ATE_void = 0x0,
+    DW_ATE_address = 0x1,
+    DW_ATE_boolean = 0x2,
+    DW_ATE_complex_float = 0x3,
+    DW_ATE_float = 0x4,
+    DW_ATE_signed = 0x5,
+    DW_ATE_signed_char = 0x6,
+    DW_ATE_unsigned = 0x7,
+    DW_ATE_unsigned_char = 0x8,
+    /* DWARF 3.  */
+    DW_ATE_imaginary_float = 0x9
+  };
+
+#define        DW_ATE_lo_user 0x80
+#define        DW_ATE_hi_user 0xff
+
+/* Array ordering names and codes.  */
+enum dwarf_array_dim_ordering
+  {
+    DW_ORD_row_major = 0,
+    DW_ORD_col_major = 1
+  };
+
+/* Access attribute.  */
+enum dwarf_access_attribute
+  {
+    DW_ACCESS_public = 1,
+    DW_ACCESS_protected = 2,
+    DW_ACCESS_private = 3
+  };
+
+/* Visibility.  */
+enum dwarf_visibility_attribute
+  {
+    DW_VIS_local = 1,
+    DW_VIS_exported = 2,
+    DW_VIS_qualified = 3
+  };
+
+/* Virtuality.  */
+enum dwarf_virtuality_attribute
+  {
+    DW_VIRTUALITY_none = 0,
+    DW_VIRTUALITY_virtual = 1,
+    DW_VIRTUALITY_pure_virtual = 2
+  };
+
+/* Case sensitivity.  */
+enum dwarf_id_case
+  {
+    DW_ID_case_sensitive = 0,
+    DW_ID_up_case = 1,
+    DW_ID_down_case = 2,
+    DW_ID_case_insensitive = 3
+  };
+
+/* Calling convention.  */
+enum dwarf_calling_convention
+  {
+    DW_CC_normal = 0x1,
+    DW_CC_program = 0x2,
+    DW_CC_nocall = 0x3
+  };
+
+#define DW_CC_lo_user 0x40
+#define DW_CC_hi_user 0xff
+
+/* Inline attribute.  */
+enum dwarf_inline_attribute
+  {
+    DW_INL_not_inlined = 0,
+    DW_INL_inlined = 1,
+    DW_INL_declared_not_inlined = 2,
+    DW_INL_declared_inlined = 3
+  };
+
+/* Discriminant lists.  */
+enum dwarf_discrim_list
+  {
+    DW_DSC_label = 0,
+    DW_DSC_range = 1
+  };
+
+/* Line number opcodes.  */
+enum dwarf_line_number_ops
+  {
+    DW_LNS_extended_op = 0,
+    DW_LNS_copy = 1,
+    DW_LNS_advance_pc = 2,
+    DW_LNS_advance_line = 3,
+    DW_LNS_set_file = 4,
+    DW_LNS_set_column = 5,
+    DW_LNS_negate_stmt = 6,
+    DW_LNS_set_basic_block = 7,
+    DW_LNS_const_add_pc = 8,
+    DW_LNS_fixed_advance_pc = 9,
+    /* DWARF 3.  */
+    DW_LNS_set_prologue_end = 10,
+    DW_LNS_set_epilogue_begin = 11,
+    DW_LNS_set_isa = 12
+  };
+
+/* Line number extended opcodes.  */
+enum dwarf_line_number_x_ops
+  {
+    DW_LNE_end_sequence = 1,
+    DW_LNE_set_address = 2,
+    DW_LNE_define_file = 3
+  };
+
+/* Call frame information.  */
+enum dwarf_call_frame_info
+  {
+    DW_CFA_advance_loc = 0x40,
+    DW_CFA_offset = 0x80,
+    DW_CFA_restore = 0xc0,
+    DW_CFA_nop = 0x00,
+    DW_CFA_set_loc = 0x01,
+    DW_CFA_advance_loc1 = 0x02,
+    DW_CFA_advance_loc2 = 0x03,
+    DW_CFA_advance_loc4 = 0x04,
+    DW_CFA_offset_extended = 0x05,
+    DW_CFA_restore_extended = 0x06,
+    DW_CFA_undefined = 0x07,
+    DW_CFA_same_value = 0x08,
+    DW_CFA_register = 0x09,
+    DW_CFA_remember_state = 0x0a,
+    DW_CFA_restore_state = 0x0b,
+    DW_CFA_def_cfa = 0x0c,
+    DW_CFA_def_cfa_register = 0x0d,
+    DW_CFA_def_cfa_offset = 0x0e,
+
+    /* DWARF 3.  */
+    DW_CFA_def_cfa_expression = 0x0f,
+    DW_CFA_expression = 0x10,
+    DW_CFA_offset_extended_sf = 0x11,
+    DW_CFA_def_cfa_sf = 0x12,
+    DW_CFA_def_cfa_offset_sf = 0x13,
+
+    /* SGI/MIPS specific.  */
+    DW_CFA_MIPS_advance_loc8 = 0x1d,
+
+    /* GNU extensions.  */
+    DW_CFA_GNU_window_save = 0x2d,
+    DW_CFA_GNU_args_size = 0x2e,
+    DW_CFA_GNU_negative_offset_extended = 0x2f
+  };
+
+#define DW_CIE_ID        0xffffffff
+#define DW_CIE_VERSION   1
+
+#define DW_CFA_extended   0
+#define DW_CFA_lo_user    0x1c
+#define DW_CFA_hi_user    0x3f
+
+#define DW_CHILDREN_no              0x00
+#define DW_CHILDREN_yes                     0x01
+
+#define DW_ADDR_none           0
+
+/* Source language names and codes.  */
+enum dwarf_source_language
+  {
+    DW_LANG_C89 = 0x0001,
+    DW_LANG_C = 0x0002,
+    DW_LANG_Ada83 = 0x0003,
+    DW_LANG_C_plus_plus = 0x0004,
+    DW_LANG_Cobol74 = 0x0005,
+    DW_LANG_Cobol85 = 0x0006,
+    DW_LANG_Fortran77 = 0x0007,
+    DW_LANG_Fortran90 = 0x0008,
+    DW_LANG_Pascal83 = 0x0009,
+    DW_LANG_Modula2 = 0x000a,
+    DW_LANG_Java = 0x000b,
+    /* DWARF 3.  */
+    DW_LANG_C99 = 0x000c,
+    DW_LANG_Ada95 = 0x000d,
+    DW_LANG_Fortran95 = 0x000e,
+    /* MIPS.  */
+    DW_LANG_Mips_Assembler = 0x8001,
+    /* UPC.  */
+    DW_LANG_Upc = 0x8765
+  };
+
+#define DW_LANG_lo_user 0x8000 /* Implementation-defined range start.  */
+#define DW_LANG_hi_user 0xffff /* Implementation-defined range start.  */
+
+/* Names and codes for macro information.  */
+enum dwarf_macinfo_record_type
+  {
+    DW_MACINFO_define = 1,
+    DW_MACINFO_undef = 2,
+    DW_MACINFO_start_file = 3,
+    DW_MACINFO_end_file = 4,
+    DW_MACINFO_vendor_ext = 255
+  };
+\f
+/* @@@ For use with GNU frame unwind information.  */
+
+#define DW_EH_PE_absptr                0x00
+#define DW_EH_PE_omit          0xff
+
+#define DW_EH_PE_uleb128       0x01
+#define DW_EH_PE_udata2                0x02
+#define DW_EH_PE_udata4                0x03
+#define DW_EH_PE_udata8                0x04
+#define DW_EH_PE_sleb128       0x09
+#define DW_EH_PE_sdata2                0x0A
+#define DW_EH_PE_sdata4                0x0B
+#define DW_EH_PE_sdata8                0x0C
+#define DW_EH_PE_signed                0x08
+
+#define DW_EH_PE_pcrel         0x10
+#define DW_EH_PE_textrel       0x20
+#define DW_EH_PE_datarel       0x30
+#define DW_EH_PE_funcrel       0x40
+#define DW_EH_PE_aligned       0x50
+
+#define DW_EH_PE_indirect      0x80
+
+#endif /* _ELF_DWARF2_H */
diff --git a/Repair/RepairCompiler/structextract/include/elf/external.h b/Repair/RepairCompiler/structextract/include/elf/external.h
new file mode 100755 (executable)
index 0000000..403ee62
--- /dev/null
@@ -0,0 +1,261 @@
+/* ELF support for BFD.
+   Copyright 1991, 1992, 1993, 1995, 1997, 1998, 1999, 2001
+   Free Software Foundation, Inc.
+
+   Written by Fred Fish @ Cygnus Support, from information published
+   in "UNIX System V Release 4, Programmers Guide: ANSI C and
+   Programming Support Tools".
+
+This file is part of BFD, the Binary File Descriptor library.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+
+/* This file is part of ELF support for BFD, and contains the portions
+   that describe how ELF is represented externally by the BFD library.
+   I.E. it describes the in-file representation of ELF.  It requires
+   the elf/common.h file which contains the portions that are common to
+   both the internal and external representations. */
+
+/* The 64-bit stuff is kind of random.  Perhaps someone will publish a
+   spec someday.  */
+
+#ifndef _ELF_EXTERNAL_H
+#define _ELF_EXTERNAL_H
+
+/* ELF Header (32-bit implementations) */
+
+typedef struct {
+  unsigned char        e_ident[16];            /* ELF "magic number" */
+  unsigned char        e_type[2];              /* Identifies object file type */
+  unsigned char        e_machine[2];           /* Specifies required architecture */
+  unsigned char        e_version[4];           /* Identifies object file version */
+  unsigned char        e_entry[4];             /* Entry point virtual address */
+  unsigned char        e_phoff[4];             /* Program header table file offset */
+  unsigned char        e_shoff[4];             /* Section header table file offset */
+  unsigned char        e_flags[4];             /* Processor-specific flags */
+  unsigned char        e_ehsize[2];            /* ELF header size in bytes */
+  unsigned char        e_phentsize[2];         /* Program header table entry size */
+  unsigned char        e_phnum[2];             /* Program header table entry count */
+  unsigned char        e_shentsize[2];         /* Section header table entry size */
+  unsigned char        e_shnum[2];             /* Section header table entry count */
+  unsigned char        e_shstrndx[2];          /* Section header string table index */
+} Elf32_External_Ehdr;
+
+typedef struct {
+  unsigned char        e_ident[16];            /* ELF "magic number" */
+  unsigned char        e_type[2];              /* Identifies object file type */
+  unsigned char        e_machine[2];           /* Specifies required architecture */
+  unsigned char        e_version[4];           /* Identifies object file version */
+  unsigned char        e_entry[8];             /* Entry point virtual address */
+  unsigned char        e_phoff[8];             /* Program header table file offset */
+  unsigned char        e_shoff[8];             /* Section header table file offset */
+  unsigned char        e_flags[4];             /* Processor-specific flags */
+  unsigned char        e_ehsize[2];            /* ELF header size in bytes */
+  unsigned char        e_phentsize[2];         /* Program header table entry size */
+  unsigned char        e_phnum[2];             /* Program header table entry count */
+  unsigned char        e_shentsize[2];         /* Section header table entry size */
+  unsigned char        e_shnum[2];             /* Section header table entry count */
+  unsigned char        e_shstrndx[2];          /* Section header string table index */
+} Elf64_External_Ehdr;
+
+/* Program header */
+
+typedef struct {
+  unsigned char        p_type[4];              /* Identifies program segment type */
+  unsigned char        p_offset[4];            /* Segment file offset */
+  unsigned char        p_vaddr[4];             /* Segment virtual address */
+  unsigned char        p_paddr[4];             /* Segment physical address */
+  unsigned char        p_filesz[4];            /* Segment size in file */
+  unsigned char        p_memsz[4];             /* Segment size in memory */
+  unsigned char        p_flags[4];             /* Segment flags */
+  unsigned char        p_align[4];             /* Segment alignment, file & memory */
+} Elf32_External_Phdr;
+
+typedef struct {
+  unsigned char        p_type[4];              /* Identifies program segment type */
+  unsigned char        p_flags[4];             /* Segment flags */
+  unsigned char        p_offset[8];            /* Segment file offset */
+  unsigned char        p_vaddr[8];             /* Segment virtual address */
+  unsigned char        p_paddr[8];             /* Segment physical address */
+  unsigned char        p_filesz[8];            /* Segment size in file */
+  unsigned char        p_memsz[8];             /* Segment size in memory */
+  unsigned char        p_align[8];             /* Segment alignment, file & memory */
+} Elf64_External_Phdr;
+
+/* Section header */
+
+typedef struct {
+  unsigned char        sh_name[4];             /* Section name, index in string tbl */
+  unsigned char        sh_type[4];             /* Type of section */
+  unsigned char        sh_flags[4];            /* Miscellaneous section attributes */
+  unsigned char        sh_addr[4];             /* Section virtual addr at execution */
+  unsigned char        sh_offset[4];           /* Section file offset */
+  unsigned char        sh_size[4];             /* Size of section in bytes */
+  unsigned char        sh_link[4];             /* Index of another section */
+  unsigned char        sh_info[4];             /* Additional section information */
+  unsigned char        sh_addralign[4];        /* Section alignment */
+  unsigned char        sh_entsize[4];          /* Entry size if section holds table */
+} Elf32_External_Shdr;
+
+typedef struct {
+  unsigned char        sh_name[4];             /* Section name, index in string tbl */
+  unsigned char        sh_type[4];             /* Type of section */
+  unsigned char        sh_flags[8];            /* Miscellaneous section attributes */
+  unsigned char        sh_addr[8];             /* Section virtual addr at execution */
+  unsigned char        sh_offset[8];           /* Section file offset */
+  unsigned char        sh_size[8];             /* Size of section in bytes */
+  unsigned char        sh_link[4];             /* Index of another section */
+  unsigned char        sh_info[4];             /* Additional section information */
+  unsigned char        sh_addralign[8];        /* Section alignment */
+  unsigned char        sh_entsize[8];          /* Entry size if section holds table */
+} Elf64_External_Shdr;
+
+/* Symbol table entry */
+
+typedef struct {
+  unsigned char        st_name[4];             /* Symbol name, index in string tbl */
+  unsigned char        st_value[4];            /* Value of the symbol */
+  unsigned char        st_size[4];             /* Associated symbol size */
+  unsigned char        st_info[1];             /* Type and binding attributes */
+  unsigned char        st_other[1];            /* No defined meaning, 0 */
+  unsigned char        st_shndx[2];            /* Associated section index */
+} Elf32_External_Sym;
+
+typedef struct {
+  unsigned char        st_name[4];             /* Symbol name, index in string tbl */
+  unsigned char        st_info[1];             /* Type and binding attributes */
+  unsigned char        st_other[1];            /* No defined meaning, 0 */
+  unsigned char        st_shndx[2];            /* Associated section index */
+  unsigned char        st_value[8];            /* Value of the symbol */
+  unsigned char        st_size[8];             /* Associated symbol size */
+} Elf64_External_Sym;
+
+typedef struct {
+  unsigned char est_shndx[4];          /* Section index */
+} Elf_External_Sym_Shndx;
+
+/* Note segments */
+
+typedef struct {
+  unsigned char        namesz[4];              /* Size of entry's owner string */
+  unsigned char        descsz[4];              /* Size of the note descriptor */
+  unsigned char        type[4];                /* Interpretation of the descriptor */
+  char         name[1];                /* Start of the name+desc data */
+} Elf_External_Note;
+
+/* Relocation Entries */
+typedef struct {
+  unsigned char r_offset[4];   /* Location at which to apply the action */
+  unsigned char        r_info[4];      /* index and type of relocation */
+} Elf32_External_Rel;
+
+typedef struct {
+  unsigned char r_offset[4];   /* Location at which to apply the action */
+  unsigned char        r_info[4];      /* index and type of relocation */
+  unsigned char        r_addend[4];    /* Constant addend used to compute value */
+} Elf32_External_Rela;
+
+typedef struct {
+  unsigned char r_offset[8];   /* Location at which to apply the action */
+  unsigned char        r_info[8];      /* index and type of relocation */
+} Elf64_External_Rel;
+
+typedef struct {
+  unsigned char r_offset[8];   /* Location at which to apply the action */
+  unsigned char        r_info[8];      /* index and type of relocation */
+  unsigned char        r_addend[8];    /* Constant addend used to compute value */
+} Elf64_External_Rela;
+
+/* dynamic section structure */
+
+typedef struct {
+  unsigned char        d_tag[4];               /* entry tag value */
+  union {
+    unsigned char      d_val[4];
+    unsigned char      d_ptr[4];
+  } d_un;
+} Elf32_External_Dyn;
+
+typedef struct {
+  unsigned char        d_tag[8];               /* entry tag value */
+  union {
+    unsigned char      d_val[8];
+    unsigned char      d_ptr[8];
+  } d_un;
+} Elf64_External_Dyn;
+
+/* The version structures are currently size independent.  They are
+   named without a 32 or 64.  If that ever changes, these structures
+   will need to be renamed.  */
+
+/* This structure appears in a SHT_GNU_verdef section.  */
+
+typedef struct {
+  unsigned char                vd_version[2];
+  unsigned char                vd_flags[2];
+  unsigned char                vd_ndx[2];
+  unsigned char                vd_cnt[2];
+  unsigned char                vd_hash[4];
+  unsigned char                vd_aux[4];
+  unsigned char                vd_next[4];
+} Elf_External_Verdef;
+
+/* This structure appears in a SHT_GNU_verdef section.  */
+
+typedef struct {
+  unsigned char                vda_name[4];
+  unsigned char                vda_next[4];
+} Elf_External_Verdaux;
+
+/* This structure appears in a SHT_GNU_verneed section.  */
+
+typedef struct {
+  unsigned char                vn_version[2];
+  unsigned char                vn_cnt[2];
+  unsigned char                vn_file[4];
+  unsigned char                vn_aux[4];
+  unsigned char                vn_next[4];
+} Elf_External_Verneed;
+
+/* This structure appears in a SHT_GNU_verneed section.  */
+
+typedef struct {
+  unsigned char                vna_hash[4];
+  unsigned char                vna_flags[2];
+  unsigned char                vna_other[2];
+  unsigned char                vna_name[4];
+  unsigned char                vna_next[4];
+} Elf_External_Vernaux;
+
+/* This structure appears in a SHT_GNU_versym section.  This is not a
+   standard ELF structure; ELF just uses Elf32_Half.  */
+
+typedef struct {
+  unsigned char                vs_vers[2];
+}
+#ifdef __GNUC__
+  __attribute__ ((packed))
+#endif
+  Elf_External_Versym;
+
+/* Structure for syminfo section.  */
+typedef struct
+{
+  unsigned char                si_boundto[2];
+  unsigned char                si_flags[2];
+} Elf_External_Syminfo;
+
+#endif /* _ELF_EXTERNAL_H */
diff --git a/Repair/RepairCompiler/structextract/include/elf/i386.h b/Repair/RepairCompiler/structextract/include/elf/i386.h
new file mode 100755 (executable)
index 0000000..9594119
--- /dev/null
@@ -0,0 +1,70 @@
+/* ix86 ELF support for BFD.
+   Copyright 1998, 1999, 2000 Free Software Foundation, Inc.
+
+   This file is part of BFD, the Binary File Descriptor library.
+
+   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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+#ifndef _ELF_I386_H
+#define _ELF_I386_H
+
+#include "elf/reloc-macros.h"
+
+START_RELOC_NUMBERS (elf_i386_reloc_type)
+     RELOC_NUMBER (R_386_NONE,      0) /* No reloc */
+     RELOC_NUMBER (R_386_32,        1) /* Direct 32 bit  */
+     RELOC_NUMBER (R_386_PC32,      2) /* PC relative 32 bit */
+     RELOC_NUMBER (R_386_GOT32,     3) /* 32 bit GOT entry */
+     RELOC_NUMBER (R_386_PLT32,            4)  /* 32 bit PLT address */
+     RELOC_NUMBER (R_386_COPY,     5)  /* Copy symbol at runtime */
+     RELOC_NUMBER (R_386_GLOB_DAT,  6) /* Create GOT entry */
+     RELOC_NUMBER (R_386_JUMP_SLOT, 7) /* Create PLT entry */
+     RELOC_NUMBER (R_386_RELATIVE,  8) /* Adjust by program base */
+     RELOC_NUMBER (R_386_GOTOFF,    9) /* 32 bit offset to GOT */
+     RELOC_NUMBER (R_386_GOTPC,    10) /* 32 bit PC relative offset to GOT */
+     RELOC_NUMBER (R_386_32PLT,    11) /* Used by Sun */
+     FAKE_RELOC   (FIRST_INVALID_RELOC, 12)
+     FAKE_RELOC   (LAST_INVALID_RELOC,  13)
+     RELOC_NUMBER (R_386_TLS_TPOFF,14)
+     RELOC_NUMBER (R_386_TLS_IE,   15)
+     RELOC_NUMBER (R_386_TLS_GOTIE,16)
+     RELOC_NUMBER (R_386_TLS_LE,   17)
+     RELOC_NUMBER (R_386_TLS_GD,   18)
+     RELOC_NUMBER (R_386_TLS_LDM,  19)
+     RELOC_NUMBER (R_386_16,       20)
+     RELOC_NUMBER (R_386_PC16,     21)
+     RELOC_NUMBER (R_386_8,       22)
+     RELOC_NUMBER (R_386_PC8,      23)
+     RELOC_NUMBER (R_386_TLS_GD_32,    24)
+     RELOC_NUMBER (R_386_TLS_GD_PUSH,  25)
+     RELOC_NUMBER (R_386_TLS_GD_CALL,  26)
+     RELOC_NUMBER (R_386_TLS_GD_POP,   27)
+     RELOC_NUMBER (R_386_TLS_LDM_32,   28)
+     RELOC_NUMBER (R_386_TLS_LDM_PUSH, 29)
+     RELOC_NUMBER (R_386_TLS_LDM_CALL, 30)
+     RELOC_NUMBER (R_386_TLS_LDM_POP,  31)
+     RELOC_NUMBER (R_386_TLS_LDO_32,   32)
+     RELOC_NUMBER (R_386_TLS_IE_32,    33)
+     RELOC_NUMBER (R_386_TLS_LE_32,    34)
+     RELOC_NUMBER (R_386_TLS_DTPMOD32, 35)
+     RELOC_NUMBER (R_386_TLS_DTPOFF32, 36)
+     RELOC_NUMBER (R_386_TLS_TPOFF32,  37)
+
+     /* These are GNU extensions to enable C++ vtable garbage collection.  */
+     RELOC_NUMBER (R_386_GNU_VTINHERIT, 250)
+     RELOC_NUMBER (R_386_GNU_VTENTRY, 251)
+END_RELOC_NUMBERS (R_386_max)
+
+#endif
diff --git a/Repair/RepairCompiler/structextract/include/elf/ia64.h b/Repair/RepairCompiler/structextract/include/elf/ia64.h
new file mode 100755 (executable)
index 0000000..06dfa60
--- /dev/null
@@ -0,0 +1,216 @@
+/* IA-64 ELF support for BFD.
+   Copyright 1998, 1999, 2000, 2003 Free Software Foundation, Inc.
+   Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
+
+   This file is part of BFD, the Binary File Descriptor library.
+
+   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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+#ifndef _ELF_IA64_H
+#define _ELF_IA64_H
+
+/* Bits in the e_flags field of the Elf64_Ehdr:  */
+
+#define EF_IA_64_MASKOS         0x0000000f     /* OS-specific flags.  */
+#define EF_IA_64_ARCH   0xff000000     /* Arch. version mask.  */
+
+/* ??? These four definitions are not part of the SVR4 ABI.
+   They were present in David's initial code drop, so it is probable
+   that they are used by HP/UX.  */
+#define EF_IA_64_TRAPNIL (1 << 0)      /* Trap NIL pointer dereferences.  */
+#define EF_IA_64_EXT    (1 << 2)       /* Program uses arch. extensions.  */
+#define EF_IA_64_BE     (1 << 3)       /* PSR BE bit set (big-endian).  */
+#define EFA_IA_64_EAS2_3 0x23000000    /* IA64 EAS 2.3.  */
+
+#define EF_IA_64_ABI64             (1 << 4) /* 64-bit ABI.  */
+/* Not used yet.  */
+#define EF_IA_64_REDUCEDFP         (1 << 5) /* Only FP6-FP11 used.  */
+#define EF_IA_64_CONS_GP           (1 << 6) /* gp as program wide constant.  */
+#define EF_IA_64_NOFUNCDESC_CONS_GP (1 << 7) /* And no function descriptors.  */
+/* Not used yet.  */
+#define EF_IA_64_ABSOLUTE          (1 << 8) /* Load at absolute addresses.  */
+
+#define ELF_STRING_ia64_archext                ".IA_64.archext"
+#define ELF_STRING_ia64_pltoff         ".IA_64.pltoff"
+#define ELF_STRING_ia64_unwind         ".IA_64.unwind"
+#define ELF_STRING_ia64_unwind_info    ".IA_64.unwind_info"
+#define ELF_STRING_ia64_unwind_once    ".gnu.linkonce.ia64unw."
+#define ELF_STRING_ia64_unwind_info_once ".gnu.linkonce.ia64unwi."
+/* .IA_64.unwind_hdr is only used by HP-UX.  */
+#define ELF_STRING_ia64_unwind_hdr     ".IA_64.unwind_hdr"
+
+/* Bits in the sh_flags field of Elf64_Shdr:  */
+
+#define SHF_IA_64_SHORT                0x10000000      /* Section near gp.  */
+#define SHF_IA_64_NORECOV      0x20000000      /* Spec insns w/o recovery.  */
+
+/* Possible values for sh_type in Elf64_Shdr: */
+
+#define SHT_IA_64_EXT          (SHT_LOPROC + 0)        /* Extension bits.  */
+#define SHT_IA_64_UNWIND       (SHT_LOPROC + 1)        /* Unwind bits.  */
+#define SHT_IA_64_LOPSREG      (SHT_LOPROC + 0x8000000) 
+/* ABI says (SHT_LOPROC + 0xfffffff) but I think it's a typo -- this makes sense.  */
+#define SHT_IA_64_HIPSREG      (SHT_LOPROC + 0x8ffffff) 
+#define SHT_IA_64_PRIORITY_INIT (SHT_LOPROC + 0x9000000)
+
+/* SHT_IA_64_HP_OPT_ANOT is only generated by HPUX compilers for its
+   optimization annotation section.  GCC does not generate it but we
+   want readelf to know what they are.  Do not use two capital Ns in
+   annotate or sed will turn it into 32 or 64 during the build.  */
+#define SHT_IA_64_HP_OPT_ANOT  0x60000004
+
+/* Bits in the p_flags field of Elf64_Phdr:  */
+
+#define PF_IA_64_NORECOV       0x80000000
+
+/* Possible values for p_type in Elf64_Phdr:  */
+
+#define PT_IA_64_ARCHEXT       (PT_LOPROC + 0) /* Arch extension bits,  */
+#define PT_IA_64_UNWIND        (PT_LOPROC + 1) /* IA64 unwind bits.  */
+
+/* HP-UX specific values for p_type in Elf64_Phdr.
+   These values are currently just used to make
+   readelf more usable on HP-UX.  */
+
+#define PT_IA_64_HP_OPT_ANOT   (PT_LOOS + 0x12)
+#define PT_IA_64_HP_HSL_ANOT   (PT_LOOS + 0x13)
+#define PT_IA_64_HP_STACK      (PT_LOOS + 0x14)
+
+/* Possible values for d_tag in Elf64_Dyn:  */
+
+#define DT_IA_64_PLT_RESERVE   (DT_LOPROC + 0)
+
+/* This section only used by HP-UX, The HP linker gives weak symbols
+   precedence over regular common symbols.  We want common to override
+   weak.  Using this common instead of SHN_COMMON does that.  */
+#define SHN_IA_64_ANSI_COMMON 0xFF00
+
+/* IA64-specific relocation types: */
+
+/* Relocs apply to specific instructions within a bundle.  The least
+   significant 2 bits of the address indicate which instruction in the
+   bundle the reloc refers to (0=first slot, 1=second slow, 2=third
+   slot, 3=undefined) and the remaining bits give the address of the
+   bundle (16 byte aligned).
+
+   The top 5 bits of the reloc code specifies the expression type, the
+   low 3 bits the format of the data word being relocated.  */
+
+#include "elf/reloc-macros.h"
+
+START_RELOC_NUMBERS (elf_ia64_reloc_type)
+  RELOC_NUMBER (R_IA64_NONE, 0x00)     /* none */
+
+  RELOC_NUMBER (R_IA64_IMM14, 0x21)    /* symbol + addend, add imm14 */
+  RELOC_NUMBER (R_IA64_IMM22, 0x22)    /* symbol + addend, add imm22 */
+  RELOC_NUMBER (R_IA64_IMM64, 0x23)    /* symbol + addend, mov imm64 */
+  RELOC_NUMBER (R_IA64_DIR32MSB, 0x24) /* symbol + addend, data4 MSB */
+  RELOC_NUMBER (R_IA64_DIR32LSB, 0x25) /* symbol + addend, data4 LSB */
+  RELOC_NUMBER (R_IA64_DIR64MSB, 0x26) /* symbol + addend, data8 MSB */
+  RELOC_NUMBER (R_IA64_DIR64LSB, 0x27) /* symbol + addend, data8 LSB */
+
+  RELOC_NUMBER (R_IA64_GPREL22, 0x2a)  /* @gprel(sym+add), add imm22 */
+  RELOC_NUMBER (R_IA64_GPREL64I, 0x2b) /* @gprel(sym+add), mov imm64 */
+  RELOC_NUMBER (R_IA64_GPREL32MSB, 0x2c) /* @gprel(sym+add), data4 MSB */
+  RELOC_NUMBER (R_IA64_GPREL32LSB, 0x2d) /* @gprel(sym+add), data4 LSB */
+  RELOC_NUMBER (R_IA64_GPREL64MSB, 0x2e) /* @gprel(sym+add), data8 MSB */
+  RELOC_NUMBER (R_IA64_GPREL64LSB, 0x2f) /* @gprel(sym+add), data8 LSB */
+
+  RELOC_NUMBER (R_IA64_LTOFF22, 0x32)  /* @ltoff(sym+add), add imm22 */
+  RELOC_NUMBER (R_IA64_LTOFF64I, 0x33) /* @ltoff(sym+add), mov imm64 */
+
+  RELOC_NUMBER (R_IA64_PLTOFF22, 0x3a) /* @pltoff(sym+add), add imm22 */
+  RELOC_NUMBER (R_IA64_PLTOFF64I, 0x3b)        /* @pltoff(sym+add), mov imm64 */
+  RELOC_NUMBER (R_IA64_PLTOFF64MSB, 0x3e) /* @pltoff(sym+add), data8 MSB */
+  RELOC_NUMBER (R_IA64_PLTOFF64LSB, 0x3f) /* @pltoff(sym+add), data8 LSB */
+
+  RELOC_NUMBER (R_IA64_FPTR64I, 0x43)  /* @fptr(sym+add), mov imm64 */
+  RELOC_NUMBER (R_IA64_FPTR32MSB, 0x44)        /* @fptr(sym+add), data4 MSB */
+  RELOC_NUMBER (R_IA64_FPTR32LSB, 0x45)        /* @fptr(sym+add), data4 LSB */
+  RELOC_NUMBER (R_IA64_FPTR64MSB, 0x46)        /* @fptr(sym+add), data8 MSB */
+  RELOC_NUMBER (R_IA64_FPTR64LSB, 0x47)        /* @fptr(sym+add), data8 LSB */
+
+  RELOC_NUMBER (R_IA64_PCREL60B, 0x48) /* @pcrel(sym+add), brl */
+  RELOC_NUMBER (R_IA64_PCREL21B, 0x49) /* @pcrel(sym+add), ptb, call */
+  RELOC_NUMBER (R_IA64_PCREL21M, 0x4a) /* @pcrel(sym+add), chk.s */
+  RELOC_NUMBER (R_IA64_PCREL21F, 0x4b) /* @pcrel(sym+add), fchkf */
+  RELOC_NUMBER (R_IA64_PCREL32MSB, 0x4c) /* @pcrel(sym+add), data4 MSB */
+  RELOC_NUMBER (R_IA64_PCREL32LSB, 0x4d) /* @pcrel(sym+add), data4 LSB */
+  RELOC_NUMBER (R_IA64_PCREL64MSB, 0x4e) /* @pcrel(sym+add), data8 MSB */
+  RELOC_NUMBER (R_IA64_PCREL64LSB, 0x4f) /* @pcrel(sym+add), data8 LSB */
+
+  RELOC_NUMBER (R_IA64_LTOFF_FPTR22, 0x52) /* @ltoff(@fptr(s+a)), imm22 */
+  RELOC_NUMBER (R_IA64_LTOFF_FPTR64I, 0x53) /* @ltoff(@fptr(s+a)), imm64 */
+  RELOC_NUMBER (R_IA64_LTOFF_FPTR32MSB, 0x54) /* @ltoff(@fptr(s+a)), 4 MSB */
+  RELOC_NUMBER (R_IA64_LTOFF_FPTR32LSB, 0x55) /* @ltoff(@fptr(s+a)), 4 LSB */
+  RELOC_NUMBER (R_IA64_LTOFF_FPTR64MSB, 0x56) /* @ltoff(@fptr(s+a)), 8 MSB */
+  RELOC_NUMBER (R_IA64_LTOFF_FPTR64LSB, 0x57) /* @ltoff(@fptr(s+a)), 8 LSB */
+
+  RELOC_NUMBER (R_IA64_SEGREL32MSB, 0x5c) /* @segrel(sym+add), data4 MSB */
+  RELOC_NUMBER (R_IA64_SEGREL32LSB, 0x5d) /* @segrel(sym+add), data4 LSB */
+  RELOC_NUMBER (R_IA64_SEGREL64MSB, 0x5e) /* @segrel(sym+add), data8 MSB */
+  RELOC_NUMBER (R_IA64_SEGREL64LSB, 0x5f) /* @segrel(sym+add), data8 LSB */
+
+  RELOC_NUMBER (R_IA64_SECREL32MSB, 0x64) /* @secrel(sym+add), data4 MSB */
+  RELOC_NUMBER (R_IA64_SECREL32LSB, 0x65) /* @secrel(sym+add), data4 LSB */
+  RELOC_NUMBER (R_IA64_SECREL64MSB, 0x66) /* @secrel(sym+add), data8 MSB */
+  RELOC_NUMBER (R_IA64_SECREL64LSB, 0x67) /* @secrel(sym+add), data8 LSB */
+
+  RELOC_NUMBER (R_IA64_REL32MSB, 0x6c) /* data 4 + REL */
+  RELOC_NUMBER (R_IA64_REL32LSB, 0x6d) /* data 4 + REL */
+  RELOC_NUMBER (R_IA64_REL64MSB, 0x6e) /* data 8 + REL */
+  RELOC_NUMBER (R_IA64_REL64LSB, 0x6f) /* data 8 + REL */
+
+  RELOC_NUMBER (R_IA64_LTV32MSB, 0x74) /* symbol + addend, data4 MSB */
+  RELOC_NUMBER (R_IA64_LTV32LSB, 0x75) /* symbol + addend, data4 LSB */
+  RELOC_NUMBER (R_IA64_LTV64MSB, 0x76) /* symbol + addend, data8 MSB */
+  RELOC_NUMBER (R_IA64_LTV64LSB, 0x77) /* symbol + addend, data8 LSB */
+
+  RELOC_NUMBER (R_IA64_PCREL21BI, 0x79)        /* @pcrel(sym+add), ptb, call */
+  RELOC_NUMBER (R_IA64_PCREL22, 0x7a)  /* @pcrel(sym+add), imm22 */
+  RELOC_NUMBER (R_IA64_PCREL64I, 0x7b) /* @pcrel(sym+add), imm64 */
+
+  RELOC_NUMBER (R_IA64_IPLTMSB, 0x80)  /* dynamic reloc, imported PLT, MSB */
+  RELOC_NUMBER (R_IA64_IPLTLSB, 0x81)  /* dynamic reloc, imported PLT, LSB */
+  RELOC_NUMBER (R_IA64_COPY, 0x84)     /* dynamic reloc, data copy */
+  RELOC_NUMBER (R_IA64_LTOFF22X, 0x86)  /* LTOFF22, relaxable.  */
+  RELOC_NUMBER (R_IA64_LDXMOV, 0x87)   /* Use of LTOFF22X.  */
+
+  RELOC_NUMBER (R_IA64_TPREL14, 0x91)   /* @tprel(sym+add), add imm14 */
+  RELOC_NUMBER (R_IA64_TPREL22, 0x92)   /* @tprel(sym+add), add imm22 */
+  RELOC_NUMBER (R_IA64_TPREL64I, 0x93)  /* @tprel(sym+add), add imm64 */
+  RELOC_NUMBER (R_IA64_TPREL64MSB, 0x96) /* @tprel(sym+add), data8 MSB */
+  RELOC_NUMBER (R_IA64_TPREL64LSB, 0x97) /* @tprel(sym+add), data8 LSB */
+
+  RELOC_NUMBER (R_IA64_LTOFF_TPREL22, 0x9a) /* @ltoff(@tprel(s+a)), add imm22 */
+
+  RELOC_NUMBER (R_IA64_DTPMOD64MSB, 0xa6) /* @dtpmod(sym+add), data8 MSB */
+  RELOC_NUMBER (R_IA64_DTPMOD64LSB, 0xa7) /* @dtpmod(sym+add), data8 LSB */
+  RELOC_NUMBER (R_IA64_LTOFF_DTPMOD22, 0xaa) /* @ltoff(@dtpmod(s+a)), imm22 */
+
+  RELOC_NUMBER (R_IA64_DTPREL14, 0xb1)    /* @dtprel(sym+add), imm14 */
+  RELOC_NUMBER (R_IA64_DTPREL22, 0xb2)    /* @dtprel(sym+add), imm22 */
+  RELOC_NUMBER (R_IA64_DTPREL64I, 0xb3)   /* @dtprel(sym+add), imm64 */
+  RELOC_NUMBER (R_IA64_DTPREL32MSB, 0xb4) /* @dtprel(sym+add), data4 MSB */
+  RELOC_NUMBER (R_IA64_DTPREL32LSB, 0xb5) /* @dtprel(sym+add), data4 LSB */
+  RELOC_NUMBER (R_IA64_DTPREL64MSB, 0xb6) /* @dtprel(sym+add), data8 MSB */
+  RELOC_NUMBER (R_IA64_DTPREL64LSB, 0xb7) /* @dtprel(sym+add), data8 LSB */
+
+  RELOC_NUMBER (R_IA64_LTOFF_DTPREL22, 0xba) /* @ltoff(@dtprel(s+a)), imm22 */
+
+  FAKE_RELOC (R_IA64_MAX_RELOC_CODE, 0xba)
+END_RELOC_NUMBERS (R_IA64_max)
+
+#endif /* _ELF_IA64_H */
diff --git a/Repair/RepairCompiler/structextract/include/elf/internal.h b/Repair/RepairCompiler/structextract/include/elf/internal.h
new file mode 100755 (executable)
index 0000000..45d682a
--- /dev/null
@@ -0,0 +1,247 @@
+/* ELF support for BFD.
+   Copyright 1991, 1992, 1993, 1994, 1995, 1997, 1998, 2000, 2001, 2002
+   Free Software Foundation, Inc.
+
+   Written by Fred Fish @ Cygnus Support, from information published
+   in "UNIX System V Release 4, Programmers Guide: ANSI C and
+   Programming Support Tools".
+
+This file is part of BFD, the Binary File Descriptor library.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+
+/* This file is part of ELF support for BFD, and contains the portions
+   that describe how ELF is represented internally in the BFD library.
+   I.E. it describes the in-memory representation of ELF.  It requires
+   the elf-common.h file which contains the portions that are common to
+   both the internal and external representations. */
+
+
+/* NOTE that these structures are not kept in the same order as they appear
+   in the object file.  In some cases they've been reordered for more optimal
+   packing under various circumstances.  */
+
+#ifndef _ELF_INTERNAL_H
+#define _ELF_INTERNAL_H
+
+/* ELF Header */
+
+#define EI_NIDENT      16              /* Size of e_ident[] */
+
+typedef struct elf_internal_ehdr {
+  unsigned char                e_ident[EI_NIDENT]; /* ELF "magic number" */
+  bfd_vma              e_entry;        /* Entry point virtual address */
+  bfd_size_type                e_phoff;        /* Program header table file offset */
+  bfd_size_type                e_shoff;        /* Section header table file offset */
+  unsigned long                e_version;      /* Identifies object file version */
+  unsigned long                e_flags;        /* Processor-specific flags */
+  unsigned short       e_type;         /* Identifies object file type */
+  unsigned short       e_machine;      /* Specifies required architecture */
+  unsigned int         e_ehsize;       /* ELF header size in bytes */
+  unsigned int         e_phentsize;    /* Program header table entry size */
+  unsigned int         e_phnum;        /* Program header table entry count */
+  unsigned int         e_shentsize;    /* Section header table entry size */
+  unsigned int         e_shnum;        /* Section header table entry count */
+  unsigned int         e_shstrndx;     /* Section header string table index */
+} Elf_Internal_Ehdr;
+
+/* Program header */
+
+struct elf_internal_phdr {
+  unsigned long        p_type;                 /* Identifies program segment type */
+  unsigned long        p_flags;                /* Segment flags */
+  bfd_vma      p_offset;               /* Segment file offset */
+  bfd_vma      p_vaddr;                /* Segment virtual address */
+  bfd_vma      p_paddr;                /* Segment physical address */
+  bfd_vma      p_filesz;               /* Segment size in file */
+  bfd_vma      p_memsz;                /* Segment size in memory */
+  bfd_vma      p_align;                /* Segment alignment, file & memory */
+};
+
+typedef struct elf_internal_phdr Elf_Internal_Phdr;
+
+/* Section header */
+
+typedef struct elf_internal_shdr {
+  unsigned int sh_name;                /* Section name, index in string tbl */
+  unsigned int sh_type;                /* Type of section */
+  bfd_vma      sh_flags;               /* Miscellaneous section attributes */
+  bfd_vma      sh_addr;                /* Section virtual addr at execution */
+  bfd_size_type        sh_size;                /* Size of section in bytes */
+  bfd_size_type        sh_entsize;             /* Entry size if section holds table */
+  unsigned long        sh_link;                /* Index of another section */
+  unsigned long        sh_info;                /* Additional section information */
+  file_ptr     sh_offset;              /* Section file offset */
+  unsigned int sh_addralign;           /* Section alignment */
+
+  /* The internal rep also has some cached info associated with it. */
+  asection *   bfd_section;            /* Associated BFD section.  */
+  unsigned char *contents;             /* Section contents.  */
+} Elf_Internal_Shdr;
+
+/* Symbol table entry */
+
+struct elf_internal_sym {
+  bfd_vma      st_value;               /* Value of the symbol */
+  bfd_vma      st_size;                /* Associated symbol size */
+  unsigned long        st_name;                /* Symbol name, index in string tbl */
+  unsigned char        st_info;                /* Type and binding attributes */
+  unsigned char        st_other;               /* Visibilty, and target specific */
+  unsigned int  st_shndx;              /* Associated section index */
+};
+
+typedef struct elf_internal_sym Elf_Internal_Sym;
+
+/* Note segments */
+
+typedef struct elf_internal_note {
+  unsigned long        namesz;                 /* Size of entry's owner string */
+  unsigned long        descsz;                 /* Size of the note descriptor */
+  unsigned long        type;                   /* Interpretation of the descriptor */
+  char *       namedata;               /* Start of the name+desc data */
+  char *       descdata;               /* Start of the desc data */
+  bfd_vma      descpos;                /* File offset of the descdata */
+} Elf_Internal_Note;
+
+/* Relocation Entries */
+
+typedef struct elf_internal_rela {
+  bfd_vma      r_offset;       /* Location at which to apply the action */
+  bfd_vma      r_info;         /* Index and Type of relocation */
+  bfd_vma      r_addend;       /* Constant addend used to compute value */
+} Elf_Internal_Rela;
+
+/* dynamic section structure */
+
+typedef struct elf_internal_dyn {
+  /* This needs to support 64-bit values in elf64.  */
+  bfd_vma d_tag;               /* entry tag value */
+  union {
+    /* This needs to support 64-bit values in elf64.  */
+    bfd_vma    d_val;
+    bfd_vma    d_ptr;
+  } d_un;
+} Elf_Internal_Dyn;
+
+/* This structure appears in a SHT_GNU_verdef section.  */
+
+typedef struct elf_internal_verdef {
+  unsigned short vd_version;   /* Version number of structure.  */
+  unsigned short vd_flags;     /* Flags (VER_FLG_*).  */
+  unsigned short vd_ndx;       /* Version index.  */
+  unsigned short vd_cnt;       /* Number of verdaux entries.  */
+  unsigned long         vd_hash;       /* Hash of name.  */
+  unsigned long         vd_aux;        /* Offset to verdaux entries.  */
+  unsigned long         vd_next;       /* Offset to next verdef.  */
+
+  /* These fields are set up when BFD reads in the structure.  FIXME:
+     It would be cleaner to store these in a different structure.  */
+  bfd                        *vd_bfd;          /* BFD.  */
+  const char                 *vd_nodename;     /* Version name.  */
+  struct elf_internal_verdef  *vd_nextdef;     /* vd_next as pointer.  */
+  struct elf_internal_verdaux *vd_auxptr;      /* vd_aux as pointer.  */
+  unsigned int                vd_exp_refno;    /* Used by the linker.  */
+} Elf_Internal_Verdef;
+
+/* This structure appears in a SHT_GNU_verdef section.  */
+
+typedef struct elf_internal_verdaux {
+  unsigned long vda_name;      /* String table offset of name.  */
+  unsigned long vda_next;      /* Offset to next verdaux.  */
+
+  /* These fields are set up when BFD reads in the structure.  FIXME:
+     It would be cleaner to store these in a different structure.  */
+  const char *vda_nodename;                    /* vda_name as pointer.  */
+  struct elf_internal_verdaux *vda_nextptr;    /* vda_next as pointer.  */
+} Elf_Internal_Verdaux;
+
+/* This structure appears in a SHT_GNU_verneed section.  */
+
+typedef struct elf_internal_verneed {
+  unsigned short vn_version;   /* Version number of structure.  */
+  unsigned short vn_cnt;       /* Number of vernaux entries.  */
+  unsigned long         vn_file;       /* String table offset of library name.  */
+  unsigned long         vn_aux;        /* Offset to vernaux entries.  */
+  unsigned long         vn_next;       /* Offset to next verneed.  */
+
+  /* These fields are set up when BFD reads in the structure.  FIXME:
+     It would be cleaner to store these in a different structure.  */
+  bfd                        *vn_bfd;          /* BFD.  */
+  const char                  *vn_filename;    /* vn_file as pointer.  */
+  struct elf_internal_vernaux *vn_auxptr;      /* vn_aux as pointer.  */
+  struct elf_internal_verneed *vn_nextref;     /* vn_nextref as pointer.  */
+} Elf_Internal_Verneed;
+
+/* This structure appears in a SHT_GNU_verneed section.  */
+
+typedef struct elf_internal_vernaux {
+  unsigned long         vna_hash;      /* Hash of dependency name.  */
+  unsigned short vna_flags;    /* Flags (VER_FLG_*).  */
+  unsigned short vna_other;    /* Unused.  */
+  unsigned long         vna_name;      /* String table offset to version name.  */
+  unsigned long         vna_next;      /* Offset to next vernaux.  */
+
+  /* These fields are set up when BFD reads in the structure.  FIXME:
+     It would be cleaner to store these in a different structure.  */
+  const char                  *vna_nodename;   /* vna_name as pointer.  */
+  struct elf_internal_vernaux *vna_nextptr;    /* vna_next as pointer.  */
+} Elf_Internal_Vernaux;
+
+/* This structure appears in a SHT_GNU_versym section.  This is not a
+   standard ELF structure; ELF just uses Elf32_Half.  */
+
+typedef struct elf_internal_versym {
+  unsigned short vs_vers;
+} Elf_Internal_Versym;
+
+/* Structure for syminfo section.  */
+typedef struct
+{
+  unsigned short int   si_boundto;
+  unsigned short int   si_flags;
+} Elf_Internal_Syminfo;
+
+
+/* This structure is used to describe how sections should be assigned
+   to program segments.  */
+
+struct elf_segment_map
+{
+  /* Next program segment.  */
+  struct elf_segment_map *next;
+  /* Program segment type.  */
+  unsigned long p_type;
+  /* Program segment flags.  */
+  unsigned long p_flags;
+  /* Program segment physical address.  */
+  bfd_vma p_paddr;
+  /* Whether the p_flags field is valid; if not, the flags are based
+     on the section flags.  */
+  unsigned int p_flags_valid : 1;
+  /* Whether the p_paddr field is valid; if not, the physical address
+     is based on the section lma values.  */
+  unsigned int p_paddr_valid : 1;
+  /* Whether this segment includes the file header.  */
+  unsigned int includes_filehdr : 1;
+  /* Whether this segment includes the program headers.  */
+  unsigned int includes_phdrs : 1;
+  /* Number of sections (may be 0).  */
+  unsigned int count;
+  /* Sections.  Actual number of elements is in count field.  */
+  asection *sections[1];
+};
+
+#endif /* _ELF_INTERNAL_H */
diff --git a/Repair/RepairCompiler/structextract/include/elf/reloc-macros.h b/Repair/RepairCompiler/structextract/include/elf/reloc-macros.h
new file mode 100755 (executable)
index 0000000..9ad346c
--- /dev/null
@@ -0,0 +1,106 @@
+/* Generic relocation support for BFD.
+   Copyright 1998, 1999, 2000 Free Software Foundation, Inc.
+
+   This file is part of BFD, the Binary File Descriptor library.
+
+   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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+/* These macros are used by the various *.h target specific header
+   files to either generate an enum containing all the known relocations
+   for that target, or if RELOC_MACROS_GEN_FUNC is defined, a recognition
+   function is generated instead.  (This is used by binutils/readelf.c)
+
+   Given a header file like this:
+
+       START_RELOC_NUMBERS (foo)
+           RELOC_NUMBER (R_foo_NONE,    0)
+           RELOC_NUMBER (R_foo_32,      1)
+           EMPTY_RELOC  (R_foo_good)
+           FAKE_RELOC   (R_foo_illegal, 9)
+       END_RELOC_NUMBERS (R_foo_count)
+
+   Then the following will be produced by default (ie if
+   RELOC_MACROS_GEN_FUNC is *not* defined).
+
+       enum foo
+       {
+         R_foo_NONE = 0,
+         R_foo_32 = 1,
+         R_foo_good,
+         R_foo_illegal = 9,
+         R_foo_count
+       };
+
+   If RELOC_MACROS_GEN_FUNC *is* defined, then instead the
+   following function will be generated:
+
+       static const char * foo PARAMS ((unsigned long rtype));
+       static const char *
+       foo (rtype)
+           unsigned long rtype;
+       {
+          switch (rtype)
+          {
+          case 0: return "R_foo_NONE";
+          case 1: return "R_foo_32";
+          default: return NULL;
+          }
+       }
+   */
+
+#ifndef _RELOC_MACROS_H
+#define _RELOC_MACROS_H
+
+#ifdef RELOC_MACROS_GEN_FUNC
+
+/* This function takes the relocation number and returns the
+   string version name of the name of that relocation.  If
+   the relocation is not recognised, NULL is returned.  */
+
+#define START_RELOC_NUMBERS(name)                              \
+static const char * name    PARAMS ((unsigned long rtype));    \
+static const char *                                            \
+name (rtype)                                                   \
+       unsigned long rtype;                                    \
+{                                                              \
+  switch (rtype)                                               \
+  {
+
+#if defined (__STDC__) || defined (ALMOST_STDC)
+#define RELOC_NUMBER(name, number)  case number : return #name ;
+#else
+#define RELOC_NUMBER(name, number)  case number : return "name" ;
+#endif
+
+#define FAKE_RELOC(name, number)
+#define EMPTY_RELOC(name)
+
+#define END_RELOC_NUMBERS(name)        \
+    default: return NULL;      \
+  }                            \
+}
+
+
+#else /* Default to generating enum.  */
+
+#define START_RELOC_NUMBERS(name)   enum name {
+#define RELOC_NUMBER(name, number)  name = number,
+#define FAKE_RELOC(name, number)    name = number,
+#define EMPTY_RELOC(name)           name,
+#define END_RELOC_NUMBERS(name)     name };
+
+#endif
+
+#endif /* RELOC_MACROS_H */
diff --git a/Repair/RepairCompiler/structextract/include/fopen-same.h b/Repair/RepairCompiler/structextract/include/fopen-same.h
new file mode 100755 (executable)
index 0000000..0f37529
--- /dev/null
@@ -0,0 +1,27 @@
+/* Macros for the 'type' part of an fopen, freopen or fdopen. 
+
+       <Read|Write>[Update]<Binary file|text file>
+
+   This version is for "same" systems, where text and binary files are
+   the same.  An example is Unix.  Many Unix systems could also add a
+   "b" to the string, indicating binary files, but some reject this
+   (and thereby don't conform to ANSI C, but what else is new?).
+
+   This file is designed for inclusion by host-dependent .h files.  No
+   user application should include it directly, since that would make
+   the application unable to be configured for both "same" and "binary"
+   variant systems.  */
+
+#define FOPEN_RB       "r"
+#define FOPEN_WB       "w"
+#define FOPEN_AB       "a"
+#define FOPEN_RUB      "r+"
+#define FOPEN_WUB      "w+"
+#define FOPEN_AUB      "a+"
+
+#define FOPEN_RT       "r"
+#define FOPEN_WT       "w"
+#define FOPEN_AT       "a"
+#define FOPEN_RUT      "r+"
+#define FOPEN_WUT      "w+"
+#define FOPEN_AUT      "a+"
diff --git a/Repair/RepairCompiler/structextract/include/getopt.h b/Repair/RepairCompiler/structextract/include/getopt.h
new file mode 100755 (executable)
index 0000000..a99a229
--- /dev/null
@@ -0,0 +1,144 @@
+/* Declarations for getopt.
+   Copyright 1989, 1990, 1991, 1992, 1993, 1994, 1996, 1997, 1998, 2000,
+   2002 Free Software Foundation, Inc.
+
+   NOTE: The canonical source of this file is maintained with the GNU C Library.
+   Bugs can be reported to bug-glibc@gnu.org.
+
+   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, 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+   USA.  */
+
+#ifndef _GETOPT_H
+#define _GETOPT_H 1
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* For communication from `getopt' to the caller.
+   When `getopt' finds an option that takes an argument,
+   the argument value is returned here.
+   Also, when `ordering' is RETURN_IN_ORDER,
+   each non-option ARGV-element is returned here.  */
+
+extern char *optarg;
+
+/* Index in ARGV of the next element to be scanned.
+   This is used for communication to and from the caller
+   and for communication between successive calls to `getopt'.
+
+   On entry to `getopt', zero means this is the first call; initialize.
+
+   When `getopt' returns -1, this is the index of the first of the
+   non-option elements that the caller should itself scan.
+
+   Otherwise, `optind' communicates from one call to the next
+   how much of ARGV has been scanned so far.  */
+
+extern int optind;
+
+/* Callers store zero here to inhibit the error message `getopt' prints
+   for unrecognized options.  */
+
+extern int opterr;
+
+/* Set to an option character which was unrecognized.  */
+
+extern int optopt;
+
+/* Describe the long-named options requested by the application.
+   The LONG_OPTIONS argument to getopt_long or getopt_long_only is a vector
+   of `struct option' terminated by an element containing a name which is
+   zero.
+
+   The field `has_arg' is:
+   no_argument         (or 0) if the option does not take an argument,
+   required_argument   (or 1) if the option requires an argument,
+   optional_argument   (or 2) if the option takes an optional argument.
+
+   If the field `flag' is not NULL, it points to a variable that is set
+   to the value given in the field `val' when the option is found, but
+   left unchanged if the option is not found.
+
+   To have a long-named option do something other than set an `int' to
+   a compiled-in constant, such as set a value from `optarg', set the
+   option's `flag' field to zero and its `val' field to a nonzero
+   value (the equivalent single-letter option character, if there is
+   one).  For long options that have a zero `flag' field, `getopt'
+   returns the contents of the `val' field.  */
+
+struct option
+{
+#if defined (__STDC__) && __STDC__
+  const char *name;
+#else
+  char *name;
+#endif
+  /* has_arg can't be an enum because some compilers complain about
+     type mismatches in all the code that assumes it is an int.  */
+  int has_arg;
+  int *flag;
+  int val;
+};
+
+/* Names for the values of the `has_arg' field of `struct option'.  */
+
+#define        no_argument             0
+#define required_argument      1
+#define optional_argument      2
+
+#if defined (__STDC__) && __STDC__
+/* HAVE_DECL_* is a three-state macro: undefined, 0 or 1.  If it is
+   undefined, we haven't run the autoconf check so provide the
+   declaration without arguments.  If it is 0, we checked and failed
+   to find the declaration so provide a fully prototyped one.  If it
+   is 1, we found it so don't provide any declaration at all.  */
+#if !HAVE_DECL_GETOPT
+#if defined (__GNU_LIBRARY__) || defined (HAVE_DECL_GETOPT)
+/* Many other libraries have conflicting prototypes for getopt, with
+   differences in the consts, in unistd.h.  To avoid compilation
+   errors, only prototype getopt for the GNU C library.  */
+extern int getopt (int argc, char *const *argv, const char *shortopts);
+#else
+#ifndef __cplusplus
+extern int getopt ();
+#endif /* __cplusplus */
+#endif
+#endif /* !HAVE_DECL_GETOPT */
+
+extern int getopt_long (int argc, char *const *argv, const char *shortopts,
+                       const struct option *longopts, int *longind);
+extern int getopt_long_only (int argc, char *const *argv,
+                            const char *shortopts,
+                            const struct option *longopts, int *longind);
+
+/* Internal only.  Users should not call this directly.  */
+extern int _getopt_internal (int argc, char *const *argv,
+                            const char *shortopts,
+                            const struct option *longopts, int *longind,
+                            int long_only);
+#else /* not __STDC__ */
+extern int getopt ();
+extern int getopt_long ();
+extern int getopt_long_only ();
+
+extern int _getopt_internal ();
+#endif /* __STDC__ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* getopt.h */
diff --git a/Repair/RepairCompiler/structextract/include/symcat.h b/Repair/RepairCompiler/structextract/include/symcat.h
new file mode 100755 (executable)
index 0000000..61ce1e9
--- /dev/null
@@ -0,0 +1,49 @@
+/* Symbol concatenation utilities.
+
+   Copyright (C) 1998, 2000 Free Software Foundation, Inc.
+
+   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.,
+   59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+#ifndef SYM_CAT_H
+#define SYM_CAT_H
+
+#if defined (__STDC__) || defined (ALMOST_STDC) || defined (HAVE_STRINGIZE)
+#define CONCAT2(a,b)    a##b
+#define CONCAT3(a,b,c)  a##b##c
+#define CONCAT4(a,b,c,d) a##b##c##d
+#define STRINGX(s) #s
+#else
+/* Note one should never pass extra whitespace to the CONCATn macros,
+   e.g. CONCAT2(foo, bar) because traditonal C will keep the space between
+   the two labels instead of concatenating them.  Instead, make sure to
+   write CONCAT2(foo,bar).  */
+#define CONCAT2(a,b)    a/**/b
+#define CONCAT3(a,b,c)  a/**/b/**/c
+#define CONCAT4(a,b,c,d) a/**/b/**/c/**/d
+#define STRINGX(s) "s"
+#endif
+
+#define XCONCAT2(a,b)     CONCAT2(a,b)
+#define XCONCAT3(a,b,c)   CONCAT3(a,b,c)
+#define XCONCAT4(a,b,c,d) CONCAT4(a,b,c,d)
+
+/* Note the layer of indirection here is typically used to allow
+   stringification of the expansion of macros.  I.e. "#define foo
+   bar", "XSTRING(foo)", to yield "bar".  Be aware that this only
+   works for __STDC__, not for traditional C which will still resolve
+   to "foo".  */
+#define XSTRING(s) STRINGX(s) 
+
+#endif /* SYM_CAT_H */
diff --git a/Repair/RepairCompiler/structextract/readelf.c b/Repair/RepairCompiler/structextract/readelf.c
new file mode 100755 (executable)
index 0000000..16040ad
--- /dev/null
@@ -0,0 +1,10377 @@
+/* readelf.c -- display contents of an ELF format file
+   Copyright 1998, 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+
+   Originally developed by Eric Youngdale <eric@andante.jic.com>
+   Modifications by Nick Clifton <nickc@redhat.com>
+
+   This file is part of GNU Binutils.
+
+   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., 59 Temple Place - Suite 330, Boston, MA
+   02111-1307, USA.  */
+
+/* readelf.c
+   Copyright (C) 2004 Philip Guo, MIT CSAIL Program Analysis Group
+
+   This file was modified by Philip Guo, MIT CSAIL Program Analysis Group,
+   to perform recording of function return types and parameter types
+   for Kvasir, a Valgrind skin that implements the C language
+   front-end for the Daikon Invariant Detection System.
+
+   This file interprets the DWARF2 debugging information within
+   the ELF binary and then calls functions in typedata.c
+   My changes are denoted by //PG marks
+*/
+
+
+#include <assert.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <stdio.h>
+#include <time.h>
+
+#if __GNUC__ >= 2
+/* Define BFD64 here, even if our default architecture is 32 bit ELF
+   as this will allow us to read in and parse 64bit and 32bit ELF files.
+   Only do this if we believe that the compiler can support a 64 bit
+   data type.  For now we only rely on GCC being able to do this.  */
+#define BFD64
+#endif
+
+#include "bfd.h"
+
+#include "elf/common.h"
+#include "elf/external.h"
+#include "elf/internal.h"
+#include "elf/dwarf2.h"
+
+#include "typedata.h" //PG
+
+/* The following headers use the elf/reloc-macros.h file to
+   automatically generate relocation recognition functions
+   such as elf_mips_reloc_type()  */
+
+#define RELOC_MACROS_GEN_FUNC
+
+#include "elf/i386.h"
+
+#include "bucomm.h"
+#include "getopt.h"
+//#include "libiberty.h"
+
+char *program_name = "readelf";
+unsigned long dynamic_addr;
+bfd_size_type dynamic_size;
+char *dynamic_strings;
+char *string_table;
+unsigned long string_table_length;
+unsigned long num_dynamic_syms;
+Elf_Internal_Sym *dynamic_symbols;
+Elf_Internal_Syminfo *dynamic_syminfo;
+unsigned long dynamic_syminfo_offset;
+unsigned int dynamic_syminfo_nent;
+char program_interpreter[64];
+long dynamic_info[DT_JMPREL + 1];
+long version_info[16];
+long loadaddr = 0;
+Elf_Internal_Ehdr elf_header;
+Elf_Internal_Shdr *section_headers;
+Elf_Internal_Dyn *dynamic_segment;
+Elf_Internal_Shdr *symtab_shndx_hdr;
+int show_name;
+int do_dynamic;
+int do_syms;
+int do_reloc;
+int do_sections;
+int do_segments;
+int do_unwind;
+int do_using_dynamic;
+int do_header;
+int do_dump;
+int do_version;
+int do_wide;
+int do_histogram;
+int do_debugging;
+int do_debug_info;
+int do_debug_abbrevs;
+int do_debug_lines;
+int do_debug_pubnames;
+int do_debug_aranges;
+int do_debug_frames;
+int do_debug_frames_interp;
+int do_debug_macinfo;
+int do_debug_str;
+int do_debug_loc;
+int do_arch;
+int do_notes;
+int is_32bit_elf;
+
+//PG set this equal to 1 to print out results
+int print_results = 0;
+
+//PG declarations
+/*
+char tag_is_relevant_entry(unsigned long tag);
+void initialize_dwarf_entry_array(unsigned long num_entries);
+void destroy_dwarf_entry_array(void);
+
+char tag_is_modifier_type(unsigned long tag);
+char tag_is_collection_type(unsigned long tag);
+char tag_is_base_type(unsigned long tag);
+char tag_is_member(unsigned long tag);
+char tag_is_enumerator(unsigned long tag);
+char tag_is_function(unsigned long tag);
+char tag_is_formal_parameter(unsigned long tag);
+*/
+
+/* A dynamic array of flags indicating which sections require dumping.  */
+char *dump_sects = NULL;
+unsigned int num_dump_sects = 0;
+
+#define HEX_DUMP       (1 << 0)
+#define DISASS_DUMP    (1 << 1)
+#define DEBUG_DUMP     (1 << 2)
+
+/* How to rpint a vma value.  */
+typedef enum print_mode
+{
+  HEX,
+  DEC,
+  DEC_5,
+  UNSIGNED,
+  PREFIX_HEX,
+  FULL_HEX,
+  LONG_HEX
+}
+print_mode;
+
+/* Forward declarations for dumb compilers.  */
+static void print_vma
+  PARAMS ((bfd_vma, print_mode));
+static void print_symbol
+  PARAMS ((int, const char *));
+static bfd_vma (*byte_get)
+  PARAMS ((unsigned char *, int));
+static bfd_vma byte_get_little_endian
+  PARAMS ((unsigned char *, int));
+static bfd_vma byte_get_big_endian
+  PARAMS ((unsigned char *, int));
+static void (*byte_put)
+  PARAMS ((unsigned char *, bfd_vma, int));
+static void byte_put_little_endian
+  PARAMS ((unsigned char *, bfd_vma, int));
+static void byte_put_big_endian
+  PARAMS ((unsigned char *, bfd_vma, int));
+static const char *get_mips_dynamic_type
+  PARAMS ((unsigned long));
+static const char *get_sparc64_dynamic_type
+  PARAMS ((unsigned long));
+static const char *get_ppc64_dynamic_type
+  PARAMS ((unsigned long));
+static const char *get_parisc_dynamic_type
+  PARAMS ((unsigned long));
+static const char *get_ia64_dynamic_type
+  PARAMS ((unsigned long));
+static const char *get_dynamic_type
+  PARAMS ((unsigned long));
+static int slurp_rela_relocs
+  PARAMS ((FILE *, unsigned long, unsigned long, Elf_Internal_Rela **,
+          unsigned long *));
+static int slurp_rel_relocs
+  PARAMS ((FILE *, unsigned long, unsigned long, Elf_Internal_Rela **,
+          unsigned long *));
+static int dump_relocations
+  PARAMS ((FILE *, unsigned long, unsigned long, Elf_Internal_Sym *,
+          unsigned long, char *, int));
+static char *get_file_type
+  PARAMS ((unsigned));
+static char *get_machine_name
+  PARAMS ((unsigned));
+static char *get_machine_flags
+  PARAMS ((unsigned, unsigned));
+static const char *get_mips_segment_type
+  PARAMS ((unsigned long));
+static const char *get_parisc_segment_type
+  PARAMS ((unsigned long));
+static const char *get_ia64_segment_type
+  PARAMS ((unsigned long));
+static const char *get_segment_type
+  PARAMS ((unsigned long));
+static const char *get_mips_section_type_name
+  PARAMS ((unsigned int));
+static const char *get_parisc_section_type_name
+  PARAMS ((unsigned int));
+static const char *get_ia64_section_type_name
+  PARAMS ((unsigned int));
+static const char *get_section_type_name
+  PARAMS ((unsigned int));
+static const char *get_symbol_binding
+  PARAMS ((unsigned int));
+static const char *get_symbol_type
+  PARAMS ((unsigned int));
+static const char *get_symbol_visibility
+  PARAMS ((unsigned int));
+static const char *get_symbol_index_type
+  PARAMS ((unsigned int));
+static const char *get_dynamic_flags
+  PARAMS ((bfd_vma));
+static void usage
+  PARAMS ((void));
+static void parse_args
+  PARAMS ((int, char **));
+static int process_file_header
+  PARAMS ((void));
+static int process_program_headers
+  PARAMS ((FILE *));
+static int process_section_headers
+  PARAMS ((FILE *));
+static int process_unwind
+  PARAMS ((FILE *));
+static void dynamic_segment_mips_val
+  PARAMS ((Elf_Internal_Dyn *));
+static void dynamic_segment_parisc_val
+  PARAMS ((Elf_Internal_Dyn *));
+static void dynamic_segment_ia64_val
+  PARAMS ((Elf_Internal_Dyn *));
+static int process_dynamic_segment
+  PARAMS ((FILE *));
+static int process_symbol_table
+  PARAMS ((FILE *));
+static int process_syminfo
+  PARAMS ((FILE *));
+static int process_section_contents
+  PARAMS ((FILE *));
+static int process_mips_specific
+  PARAMS ((FILE *));
+static int process_file
+  PARAMS ((char *));
+static int process_relocs
+  PARAMS ((FILE *));
+static int process_version_sections
+  PARAMS ((FILE *));
+static char *get_ver_flags
+  PARAMS ((unsigned int));
+static int get_32bit_section_headers
+  PARAMS ((FILE *, unsigned int));
+static int get_64bit_section_headers
+  PARAMS ((FILE *, unsigned int));
+static int get_32bit_program_headers
+  PARAMS ((FILE *, Elf_Internal_Phdr *));
+static int get_64bit_program_headers
+  PARAMS ((FILE *, Elf_Internal_Phdr *));
+static int get_file_header
+  PARAMS ((FILE *));
+static Elf_Internal_Sym *get_32bit_elf_symbols
+  PARAMS ((FILE *, Elf_Internal_Shdr *));
+static Elf_Internal_Sym *get_64bit_elf_symbols
+  PARAMS ((FILE *, Elf_Internal_Shdr *));
+static const char *get_elf_section_flags
+  PARAMS ((bfd_vma));
+static int *get_dynamic_data
+  PARAMS ((FILE *, unsigned int));
+static int get_32bit_dynamic_segment
+  PARAMS ((FILE *));
+static int get_64bit_dynamic_segment
+  PARAMS ((FILE *));
+#ifdef SUPPORT_DISASSEMBLY
+static int disassemble_section
+  PARAMS ((Elf_Internal_Shdr *, FILE *));
+#endif
+static int dump_section
+  PARAMS ((Elf_Internal_Shdr *, FILE *));
+static int display_debug_section
+  PARAMS ((Elf_Internal_Shdr *, FILE *));
+static int display_debug_info
+  PARAMS ((Elf_Internal_Shdr *, unsigned char *, FILE *));
+static int display_debug_not_supported
+  PARAMS ((Elf_Internal_Shdr *, unsigned char *, FILE *));
+static int prescan_debug_info
+  PARAMS ((Elf_Internal_Shdr *, unsigned char *, FILE *));
+static int display_debug_lines
+  PARAMS ((Elf_Internal_Shdr *, unsigned char *, FILE *));
+static int display_debug_pubnames
+  PARAMS ((Elf_Internal_Shdr *, unsigned char *, FILE *));
+static int display_debug_abbrev
+  PARAMS ((Elf_Internal_Shdr *, unsigned char *, FILE *));
+static int display_debug_aranges
+  PARAMS ((Elf_Internal_Shdr *, unsigned char *, FILE *));
+static int display_debug_frames
+  PARAMS ((Elf_Internal_Shdr *, unsigned char *, FILE *));
+static int display_debug_macinfo
+  PARAMS ((Elf_Internal_Shdr *, unsigned char *, FILE *));
+static int display_debug_str
+  PARAMS ((Elf_Internal_Shdr *, unsigned char *, FILE *));
+static int display_debug_loc
+  PARAMS ((Elf_Internal_Shdr *, unsigned char *, FILE *));
+static unsigned char *process_abbrev_section
+  PARAMS ((unsigned char *, unsigned char *));
+static void load_debug_str
+  PARAMS ((FILE *));
+static void free_debug_str
+  PARAMS ((void));
+static const char *fetch_indirect_string
+  PARAMS ((unsigned long));
+static void load_debug_loc
+  PARAMS ((FILE *));
+static void free_debug_loc
+  PARAMS ((void));
+static unsigned long read_leb128
+  PARAMS ((unsigned char *, int *, int));
+static int process_extended_line_op
+  PARAMS ((unsigned char *, int, int));
+static void reset_state_machine
+  PARAMS ((int));
+//char *get_TAG_name
+//  PARAMS ((unsigned long)); //PG don't make this static since typedata.c needs it - put it in typedata.h instead
+static char *get_AT_name
+  PARAMS ((unsigned long));
+static char *get_FORM_name
+  PARAMS ((unsigned long));
+static void free_abbrevs
+  PARAMS ((void));
+static void add_abbrev
+  PARAMS ((unsigned long, unsigned long, int));
+static void add_abbrev_attr
+  PARAMS ((unsigned long, unsigned long));
+static unsigned char *read_and_display_attr
+  PARAMS ((unsigned long, unsigned long, unsigned char *, unsigned long,
+          unsigned long, unsigned long, int, dwarf_entry*, char));
+static unsigned char *read_and_display_attr_value
+  PARAMS ((unsigned long, unsigned long, unsigned char *, unsigned long,
+          unsigned long, unsigned long, int, dwarf_entry*, char));
+static unsigned char *display_block
+  PARAMS ((unsigned char *, unsigned long, char));
+static void decode_location_expression
+  PARAMS ((unsigned char *, unsigned int, unsigned long, char, long*));
+static void request_dump
+  PARAMS ((unsigned int, int));
+static const char *get_elf_class
+  PARAMS ((unsigned int));
+static const char *get_data_encoding
+  PARAMS ((unsigned int));
+static const char *get_osabi_name
+  PARAMS ((unsigned int));
+static int guess_is_rela
+  PARAMS ((unsigned long));
+static const char *get_note_type
+  PARAMS ((unsigned int));
+static const char *get_netbsd_elfcore_note_type
+  PARAMS ((unsigned int));
+static int process_note
+  PARAMS ((Elf_Internal_Note *));
+static int process_corefile_note_segment
+  PARAMS ((FILE *, bfd_vma, bfd_vma));
+static int process_corefile_note_segments
+  PARAMS ((FILE *));
+static int process_corefile_contents
+  PARAMS ((FILE *));
+static int process_arch_specific
+  PARAMS ((FILE *));
+static int process_gnu_liblist
+  PARAMS ((FILE *));
+
+
+typedef int Elf32_Word;
+
+#define UNKNOWN -1
+
+#define SECTION_NAME(X)        ((X) == NULL ? "<none>" : \
+                                ((X)->sh_name >= string_table_length \
+                                 ? "<corrupt>" : string_table + (X)->sh_name))
+
+/* Given st_shndx I, map to section_headers index.  */
+#define SECTION_HEADER_INDEX(I)                                \
+  ((I) < SHN_LORESERVE                                 \
+   ? (I)                                               \
+   : ((I) <= SHN_HIRESERVE                             \
+      ? 0                                              \
+      : (I) - (SHN_HIRESERVE + 1 - SHN_LORESERVE)))
+
+/* Reverse of the above.  */
+#define SECTION_HEADER_NUM(N)                          \
+  ((N) < SHN_LORESERVE                                 \
+   ? (N)                                               \
+   : (N) + (SHN_HIRESERVE + 1 - SHN_LORESERVE))
+
+#define SECTION_HEADER(I) (section_headers + SECTION_HEADER_INDEX (I))
+
+#define DT_VERSIONTAGIDX(tag)  (DT_VERNEEDNUM - (tag)) /* Reverse order!  */
+
+#define BYTE_GET(field)        byte_get (field, sizeof (field))
+
+/* If we can support a 64 bit data type then BFD64 should be defined
+   and sizeof (bfd_vma) == 8.  In this case when translating from an
+   external 8 byte field to an internal field, we can assume that the
+   internal field is also 8 bytes wide and so we can extract all the data.
+   If, however, BFD64 is not defined, then we must assume that the
+   internal data structure only has 4 byte wide fields that are the
+   equivalent of the 8 byte wide external counterparts, and so we must
+   truncate the data.  */
+#ifdef  BFD64
+#define BYTE_GET8(field)       byte_get (field, -8)
+#else
+#define BYTE_GET8(field)       byte_get (field, 8)
+#endif
+
+#define NUM_ELEM(array)        (sizeof (array) / sizeof ((array)[0]))
+
+#define GET_ELF_SYMBOLS(file, section)                 \
+  (is_32bit_elf ? get_32bit_elf_symbols (file, section)        \
+   : get_64bit_elf_symbols (file, section))
+
+//PG - begin custom libiberty.a functions
+
+PTR xmalloc (size_t size)
+{
+  return malloc(size);
+}
+
+PTR xrealloc (PTR oldmem, size_t size)
+{
+  return realloc(oldmem, size);
+}
+
+#define ARRAY_SIZE(a) (sizeof (a) / sizeof ((a)[0]))
+
+//PG - end
+
+static void
+error VPARAMS ((const char *message, ...))
+{
+  VA_OPEN (args, message);
+  VA_FIXEDARG (args, const char *, message);
+
+  fprintf (stderr, _("%s: Error: "), program_name);
+  vfprintf (stderr, message, args);
+  VA_CLOSE (args);
+}
+
+static void
+warn VPARAMS ((const char *message, ...))
+{
+  VA_OPEN (args, message);
+  VA_FIXEDARG (args, const char *, message);
+
+  fprintf (stderr, _("%s: Warning: "), program_name);
+  vfprintf (stderr, message, args);
+  VA_CLOSE (args);
+}
+
+static PTR get_data PARAMS ((PTR, FILE *, long, size_t, const char *));
+
+static PTR
+get_data (var, file, offset, size, reason)
+     PTR var;
+     FILE *file;
+     long offset;
+     size_t size;
+     const char *reason;
+{
+  PTR mvar;
+
+  if (size == 0)
+    return NULL;
+
+  if (fseek (file, offset, SEEK_SET))
+    {
+      error (_("Unable to seek to %x for %s\n"), offset, reason);
+      return NULL;
+    }
+
+  mvar = var;
+  if (mvar == NULL)
+    {
+      mvar = (PTR) malloc (size);
+
+      if (mvar == NULL)
+       {
+         error (_("Out of memory allocating %d bytes for %s\n"),
+                size, reason);
+         return NULL;
+       }
+    }
+
+  if (fread (mvar, size, 1, file) != 1)
+    {
+      error (_("Unable to read in %d bytes of %s\n"), size, reason);
+      if (mvar != var)
+       free (mvar);
+      return NULL;
+    }
+
+  return mvar;
+}
+
+static bfd_vma
+byte_get_little_endian (field, size)
+     unsigned char *field;
+     int size;
+{
+  switch (size)
+    {
+    case 1:
+      return *field;
+
+    case 2:
+      return  ((unsigned int) (field[0]))
+       |    (((unsigned int) (field[1])) << 8);
+
+#ifndef BFD64
+    case 8:
+      /* We want to extract data from an 8 byte wide field and
+        place it into a 4 byte wide field.  Since this is a little
+        endian source we can just use the 4 byte extraction code.  */
+      /* Fall through.  */
+#endif
+    case 4:
+      return  ((unsigned long) (field[0]))
+       |    (((unsigned long) (field[1])) << 8)
+       |    (((unsigned long) (field[2])) << 16)
+       |    (((unsigned long) (field[3])) << 24);
+
+#ifdef BFD64
+    case 8:
+    case -8:
+      /* This is a special case, generated by the BYTE_GET8 macro.
+        It means that we are loading an 8 byte value from a field
+        in an external structure into an 8 byte value in a field
+        in an internal strcuture.  */
+      return  ((bfd_vma) (field[0]))
+       |    (((bfd_vma) (field[1])) << 8)
+       |    (((bfd_vma) (field[2])) << 16)
+       |    (((bfd_vma) (field[3])) << 24)
+       |    (((bfd_vma) (field[4])) << 32)
+       |    (((bfd_vma) (field[5])) << 40)
+       |    (((bfd_vma) (field[6])) << 48)
+       |    (((bfd_vma) (field[7])) << 56);
+#endif
+    default:
+      error (_("Unhandled data length: %d\n"), size);
+      abort ();
+    }
+}
+
+static void
+byte_put_little_endian (field, value, size)
+     unsigned char * field;
+     bfd_vma        value;
+     int             size;
+{
+  switch (size)
+    {
+    case 8:
+      field[7] = (((value >> 24) >> 24) >> 8) & 0xff;
+      field[6] = ((value >> 24) >> 24) & 0xff;
+      field[5] = ((value >> 24) >> 16) & 0xff;
+      field[4] = ((value >> 24) >> 8) & 0xff;
+      /* Fall through.  */
+    case 4:
+      field[3] = (value >> 24) & 0xff;
+      field[2] = (value >> 16) & 0xff;
+      /* Fall through.  */
+    case 2:
+      field[1] = (value >> 8) & 0xff;
+      /* Fall through.  */
+    case 1:
+      field[0] = value & 0xff;
+      break;
+
+    default:
+      error (_("Unhandled data length: %d\n"), size);
+      abort ();
+    }
+}
+
+/* Print a VMA value.  */
+static void
+print_vma (vma, mode)
+     bfd_vma vma;
+     print_mode mode;
+{
+#ifdef BFD64
+  if (is_32bit_elf)
+#endif
+    {
+      switch (mode)
+       {
+       case FULL_HEX: printf ("0x"); /* drop through */
+       case LONG_HEX: printf ("%8.8lx", (unsigned long) vma); break;
+       case PREFIX_HEX: printf ("0x"); /* drop through */
+       case HEX: printf ("%lx", (unsigned long) vma); break;
+       case DEC: printf ("%ld", (unsigned long) vma); break;
+       case DEC_5: printf ("%5ld", (long) vma); break;
+       case UNSIGNED: printf ("%lu", (unsigned long) vma); break;
+       }
+    }
+#ifdef BFD64
+  else
+    {
+      switch (mode)
+       {
+       case FULL_HEX:
+         printf ("0x");
+         /* drop through */
+
+       case LONG_HEX:
+         printf_vma (vma);
+         break;
+
+       case PREFIX_HEX:
+         printf ("0x");
+         /* drop through */
+
+       case HEX:
+#if BFD_HOST_64BIT_LONG
+         printf ("%lx", vma);
+#else
+         if (_bfd_int64_high (vma))
+           printf ("%lx%8.8lx", _bfd_int64_high (vma), _bfd_int64_low (vma));
+         else
+           printf ("%lx", _bfd_int64_low (vma));
+#endif
+         break;
+
+       case DEC:
+#if BFD_HOST_64BIT_LONG
+         printf ("%ld", vma);
+#else
+         if (_bfd_int64_high (vma))
+           /* ugg */
+           printf ("++%ld", _bfd_int64_low (vma));
+         else
+           printf ("%ld", _bfd_int64_low (vma));
+#endif
+         break;
+
+       case DEC_5:
+#if BFD_HOST_64BIT_LONG
+         printf ("%5ld", vma);
+#else
+         if (_bfd_int64_high (vma))
+           /* ugg */
+           printf ("++%ld", _bfd_int64_low (vma));
+         else
+           printf ("%5ld", _bfd_int64_low (vma));
+#endif
+         break;
+
+       case UNSIGNED:
+#if BFD_HOST_64BIT_LONG
+         printf ("%lu", vma);
+#else
+         if (_bfd_int64_high (vma))
+           /* ugg */
+           printf ("++%lu", _bfd_int64_low (vma));
+         else
+           printf ("%lu", _bfd_int64_low (vma));
+#endif
+         break;
+       }
+    }
+#endif
+}
+
+/* Display a symbol on stdout.  If do_wide is not true then
+   format the symbol to be at most WIDTH characters,
+   truncating as necessary.  If WIDTH is negative then
+   format the string to be exactly - WIDTH characters,
+   truncating or padding as necessary.  */
+
+static void
+print_symbol (width, symbol)
+     int width;
+     const char *symbol;
+{
+  if (do_wide)
+    printf ("%s", symbol);
+  else if (width < 0)
+    printf ("%-*.*s", width, width, symbol);
+  else
+    printf ("%-.*s", width, symbol);
+}
+
+static bfd_vma
+byte_get_big_endian (field, size)
+     unsigned char *field;
+     int size;
+{
+  switch (size)
+    {
+    case 1:
+      return *field;
+
+    case 2:
+      return ((unsigned int) (field[1])) | (((int) (field[0])) << 8);
+
+    case 4:
+      return ((unsigned long) (field[3]))
+       |   (((unsigned long) (field[2])) << 8)
+       |   (((unsigned long) (field[1])) << 16)
+       |   (((unsigned long) (field[0])) << 24);
+
+#ifndef BFD64
+    case 8:
+      /* Although we are extracing data from an 8 byte wide field, we
+        are returning only 4 bytes of data.  */
+      return ((unsigned long) (field[7]))
+       |   (((unsigned long) (field[6])) << 8)
+       |   (((unsigned long) (field[5])) << 16)
+       |   (((unsigned long) (field[4])) << 24);
+#else
+    case 8:
+    case -8:
+      /* This is a special case, generated by the BYTE_GET8 macro.
+        It means that we are loading an 8 byte value from a field
+        in an external structure into an 8 byte value in a field
+        in an internal strcuture.  */
+      return ((bfd_vma) (field[7]))
+       |   (((bfd_vma) (field[6])) << 8)
+       |   (((bfd_vma) (field[5])) << 16)
+       |   (((bfd_vma) (field[4])) << 24)
+       |   (((bfd_vma) (field[3])) << 32)
+       |   (((bfd_vma) (field[2])) << 40)
+       |   (((bfd_vma) (field[1])) << 48)
+       |   (((bfd_vma) (field[0])) << 56);
+#endif
+
+    default:
+      error (_("Unhandled data length: %d\n"), size);
+      abort ();
+    }
+}
+
+static void
+byte_put_big_endian (field, value, size)
+     unsigned char * field;
+     bfd_vma        value;
+     int             size;
+{
+  switch (size)
+    {
+    case 8:
+      field[7] = value & 0xff;
+      field[6] = (value >> 8) & 0xff;
+      field[5] = (value >> 16) & 0xff;
+      field[4] = (value >> 24) & 0xff;
+      value >>= 16;
+      value >>= 16;
+      /* Fall through.  */
+    case 4:
+      field[3] = value & 0xff;
+      field[2] = (value >> 8) & 0xff;
+      value >>= 16;
+      /* Fall through.  */
+    case 2:
+      field[1] = value & 0xff;
+      value >>= 8;
+      /* Fall through.  */
+    case 1:
+      field[0] = value & 0xff;
+      break;
+
+    default:
+      error (_("Unhandled data length: %d\n"), size);
+      abort ();
+    }
+}
+
+/* Guess the relocation size commonly used by the specific machines.  */
+
+static int
+guess_is_rela (e_machine)
+     unsigned long e_machine;
+{
+  switch (e_machine)
+    {
+      /* Targets that use REL relocations.  */
+    case EM_ARM:
+    case EM_386:
+    case EM_486:
+    case EM_960:
+    case EM_DLX:
+    case EM_OPENRISC:
+    case EM_OR32:
+    case EM_M32R:
+    case EM_CYGNUS_M32R:
+    case EM_D10V:
+    case EM_CYGNUS_D10V:
+    case EM_MIPS:
+    case EM_MIPS_RS3_LE:
+      return FALSE;
+
+      /* Targets that use RELA relocations.  */
+    case EM_68K:
+    case EM_H8_300:
+    case EM_H8_300H:
+    case EM_H8S:
+    case EM_SPARC32PLUS:
+    case EM_SPARCV9:
+    case EM_SPARC:
+    case EM_PPC:
+    case EM_PPC64:
+    case EM_V850:
+    case EM_CYGNUS_V850:
+    case EM_D30V:
+    case EM_CYGNUS_D30V:
+    case EM_MN10200:
+    case EM_CYGNUS_MN10200:
+    case EM_MN10300:
+    case EM_CYGNUS_MN10300:
+    case EM_FR30:
+    case EM_CYGNUS_FR30:
+    case EM_CYGNUS_FRV:
+    case EM_SH:
+    case EM_ALPHA:
+    case EM_MCORE:
+    case EM_IA_64:
+    case EM_AVR:
+    case EM_AVR_OLD:
+    case EM_CRIS:
+    case EM_860:
+    case EM_X86_64:
+    case EM_S390:
+    case EM_S390_OLD:
+    case EM_MMIX:
+    case EM_MSP430:
+    case EM_MSP430_OLD:
+    case EM_XSTORMY16:
+    case EM_VAX:
+    case EM_IP2K:
+    case EM_IP2K_OLD:
+    case EM_IQ2000:
+    case EM_XTENSA:
+    case EM_XTENSA_OLD:
+      return TRUE;
+
+    case EM_MMA:
+    case EM_PCP:
+    case EM_NCPU:
+    case EM_NDR1:
+    case EM_STARCORE:
+    case EM_ME16:
+    case EM_ST100:
+    case EM_TINYJ:
+    case EM_FX66:
+    case EM_ST9PLUS:
+    case EM_ST7:
+    case EM_68HC16:
+    case EM_68HC11:
+    case EM_68HC08:
+    case EM_68HC05:
+    case EM_SVX:
+    case EM_ST19:
+    default:
+      warn (_("Don't know about relocations on this machine architecture\n"));
+      return FALSE;
+    }
+}
+
+static int
+slurp_rela_relocs (file, rel_offset, rel_size, relasp, nrelasp)
+     FILE *file;
+     unsigned long rel_offset;
+     unsigned long rel_size;
+     Elf_Internal_Rela **relasp;
+     unsigned long *nrelasp;
+{
+  Elf_Internal_Rela *relas;
+  unsigned long nrelas;
+  unsigned int i;
+
+  if (is_32bit_elf)
+    {
+      Elf32_External_Rela *erelas;
+
+      erelas = (Elf32_External_Rela *) get_data (NULL, file, rel_offset,
+                                                rel_size, _("relocs"));
+      if (!erelas)
+       return 0;
+
+      nrelas = rel_size / sizeof (Elf32_External_Rela);
+
+      relas = (Elf_Internal_Rela *)
+       malloc (nrelas * sizeof (Elf_Internal_Rela));
+
+      if (relas == NULL)
+       {
+         error(_("out of memory parsing relocs"));
+         return 0;
+       }
+
+      for (i = 0; i < nrelas; i++)
+       {
+         relas[i].r_offset = BYTE_GET (erelas[i].r_offset);
+         relas[i].r_info   = BYTE_GET (erelas[i].r_info);
+         relas[i].r_addend = BYTE_GET (erelas[i].r_addend);
+       }
+
+      free (erelas);
+    }
+  else
+    {
+      Elf64_External_Rela *erelas;
+
+      erelas = (Elf64_External_Rela *) get_data (NULL, file, rel_offset,
+                                                rel_size, _("relocs"));
+      if (!erelas)
+       return 0;
+
+      nrelas = rel_size / sizeof (Elf64_External_Rela);
+
+      relas = (Elf_Internal_Rela *)
+       malloc (nrelas * sizeof (Elf_Internal_Rela));
+
+      if (relas == NULL)
+       {
+         error(_("out of memory parsing relocs"));
+         return 0;
+       }
+
+      for (i = 0; i < nrelas; i++)
+       {
+         relas[i].r_offset = BYTE_GET8 (erelas[i].r_offset);
+         relas[i].r_info   = BYTE_GET8 (erelas[i].r_info);
+         relas[i].r_addend = BYTE_GET8 (erelas[i].r_addend);
+       }
+
+      free (erelas);
+    }
+  *relasp = relas;
+  *nrelasp = nrelas;
+  return 1;
+}
+
+static int
+slurp_rel_relocs (file, rel_offset, rel_size, relsp, nrelsp)
+     FILE *file;
+     unsigned long rel_offset;
+     unsigned long rel_size;
+     Elf_Internal_Rela **relsp;
+     unsigned long *nrelsp;
+{
+  Elf_Internal_Rela *rels;
+  unsigned long nrels;
+  unsigned int i;
+
+  if (is_32bit_elf)
+    {
+      Elf32_External_Rel *erels;
+
+      erels = (Elf32_External_Rel *) get_data (NULL, file, rel_offset,
+                                              rel_size, _("relocs"));
+      if (!erels)
+       return 0;
+
+      nrels = rel_size / sizeof (Elf32_External_Rel);
+
+      rels = (Elf_Internal_Rela *) malloc (nrels * sizeof (Elf_Internal_Rela));
+
+      if (rels == NULL)
+       {
+         error(_("out of memory parsing relocs"));
+         return 0;
+       }
+
+      for (i = 0; i < nrels; i++)
+       {
+         rels[i].r_offset = BYTE_GET (erels[i].r_offset);
+         rels[i].r_info   = BYTE_GET (erels[i].r_info);
+         rels[i].r_addend = 0;
+       }
+
+      free (erels);
+    }
+  else
+    {
+      Elf64_External_Rel *erels;
+
+      erels = (Elf64_External_Rel *) get_data (NULL, file, rel_offset,
+                                              rel_size, _("relocs"));
+      if (!erels)
+       return 0;
+
+      nrels = rel_size / sizeof (Elf64_External_Rel);
+
+      rels = (Elf_Internal_Rela *) malloc (nrels * sizeof (Elf_Internal_Rela));
+
+      if (rels == NULL)
+       {
+         error(_("out of memory parsing relocs"));
+         return 0;
+       }
+
+      for (i = 0; i < nrels; i++)
+       {
+         rels[i].r_offset = BYTE_GET8 (erels[i].r_offset);
+         rels[i].r_info   = BYTE_GET8 (erels[i].r_info);
+         rels[i].r_addend = 0;
+       }
+
+      free (erels);
+    }
+  *relsp = rels;
+  *nrelsp = nrels;
+  return 1;
+}
+
+/* Display the contents of the relocation data found at the specified offset.  */
+
+static int
+dump_relocations (file, rel_offset, rel_size, symtab, nsyms, strtab, is_rela)
+     FILE *file;
+     unsigned long rel_offset;
+     unsigned long rel_size;
+     Elf_Internal_Sym *symtab;
+     unsigned long nsyms;
+     char *strtab;
+     int is_rela;
+{
+  unsigned int i;
+  Elf_Internal_Rela *rels;
+
+
+  if (is_rela == UNKNOWN)
+    is_rela = guess_is_rela (elf_header.e_machine);
+
+  if (is_rela)
+    {
+      if (!slurp_rela_relocs (file, rel_offset, rel_size, &rels, &rel_size))
+       return 0;
+    }
+  else
+    {
+      if (!slurp_rel_relocs (file, rel_offset, rel_size, &rels, &rel_size))
+       return 0;
+    }
+
+  if (is_32bit_elf)
+    {
+      if (is_rela)
+       {
+         if (do_wide)
+           printf (_(" Offset     Info    Type                Sym. Value  Symbol's Name + Addend\n"));
+         else
+           printf (_(" Offset     Info    Type            Sym.Value  Sym. Name + Addend\n"));
+       }
+      else
+       {
+         if (do_wide)
+           printf (_(" Offset     Info    Type                Sym. Value  Symbol's Name\n"));
+         else
+           printf (_(" Offset     Info    Type            Sym.Value  Sym. Name\n"));
+       }
+    }
+  else
+    {
+      if (is_rela)
+       {
+         if (do_wide)
+           printf (_("    Offset             Info             Type               Symbol's Value  Symbol's Name + Addend\n"));
+         else
+           printf (_("  Offset          Info           Type           Sym. Value    Sym. Name + Addend\n"));
+       }
+      else
+       {
+         if (do_wide)
+           printf (_("    Offset             Info             Type               Symbol's Value  Symbol's Name\n"));
+         else
+           printf (_("  Offset          Info           Type           Sym. Value    Sym. Name\n"));
+       }
+    }
+
+  for (i = 0; i < rel_size; i++)
+    {
+      const char *rtype;
+      bfd_vma offset;
+      bfd_vma info;
+      bfd_vma symtab_index;
+      bfd_vma type;
+
+      offset = rels[i].r_offset;
+      info   = rels[i].r_info;
+
+      if (is_32bit_elf)
+       {
+         type         = ELF32_R_TYPE (info);
+         symtab_index = ELF32_R_SYM  (info);
+       }
+      else
+       {
+         /* The #ifdef BFD64 below is to prevent a compile time warning.
+            We know that if we do not have a 64 bit data type that we
+            will never execute this code anyway.  */
+#ifdef BFD64
+          type = ELF64_R_TYPE (info);
+
+         symtab_index = ELF64_R_SYM  (info);
+#endif
+       }
+
+      if (is_32bit_elf)
+       {
+#ifdef _bfd_int64_low
+         printf ("%8.8lx  %8.8lx ", _bfd_int64_low (offset), _bfd_int64_low (info));
+#else
+         printf ("%8.8lx  %8.8lx ", offset, info);
+#endif
+       }
+      else
+       {
+#ifdef _bfd_int64_low
+         printf (do_wide
+                 ? "%8.8lx%8.8lx  %8.8lx%8.8lx "
+                 : "%4.4lx%8.8lx  %4.4lx%8.8lx ",
+                 _bfd_int64_high (offset),
+                 _bfd_int64_low (offset),
+                 _bfd_int64_high (info),
+                 _bfd_int64_low (info));
+#else
+         printf (do_wide
+                 ? "%16.16lx  %16.16lx "
+                 : "%12.12lx  %12.12lx ",
+                 offset, info);
+#endif
+       }
+
+      switch (elf_header.e_machine)
+       {
+       default:
+         rtype = NULL;
+         break;
+
+       case EM_386:
+       case EM_486:
+         rtype = elf_i386_reloc_type (type);
+         break;
+
+       }
+
+      if (rtype == NULL)
+#ifdef _bfd_int64_low
+       printf (_("unrecognized: %-7lx"), _bfd_int64_low (type));
+#else
+       printf (_("unrecognized: %-7lx"), type);
+#endif
+      else
+       printf (do_wide ? "%-22.22s" : "%-17.17s", rtype);
+
+      if (symtab_index)
+       {
+         if (symtab == NULL || symtab_index >= nsyms)
+           printf (" bad symbol index: %08lx", (unsigned long) symtab_index);
+         else
+           {
+             Elf_Internal_Sym *psym;
+
+             psym = symtab + symtab_index;
+
+             printf (" ");
+             print_vma (psym->st_value, LONG_HEX);
+             printf (is_32bit_elf ? "   " : " ");
+
+             if (psym->st_name == 0)
+               {
+                 const char *sec_name = "<null>";
+                 char name_buf[40];
+
+                 if (ELF_ST_TYPE (psym->st_info) == STT_SECTION)
+                   {
+                     bfd_vma sec_index = (bfd_vma) -1;
+
+                     if (psym->st_shndx < SHN_LORESERVE)
+                       sec_index = psym->st_shndx;
+                     else if (psym->st_shndx > SHN_LORESERVE)
+                       sec_index = psym->st_shndx - (SHN_HIRESERVE + 1
+                                                     - SHN_LORESERVE);
+
+                     if (sec_index != (bfd_vma) -1)
+                       sec_name = SECTION_NAME (section_headers + sec_index);
+                     else if (psym->st_shndx == SHN_ABS)
+                       sec_name = "ABS";
+                     else if (psym->st_shndx == SHN_COMMON)
+                       sec_name = "COMMON";
+                     else
+                       {
+                         sprintf (name_buf, "<section 0x%x>",
+                                  (unsigned int) psym->st_shndx);
+                         sec_name = name_buf;
+                       }
+                   }
+                 print_symbol (22, sec_name);
+               }
+             else if (strtab == NULL)
+               printf (_("<string table index %3ld>"), psym->st_name);
+             else
+               print_symbol (22, strtab + psym->st_name);
+
+             if (is_rela)
+               printf (" + %lx", (unsigned long) rels[i].r_addend);
+           }
+       }
+      else if (is_rela)
+       {
+         printf ("%*c", is_32bit_elf ? (do_wide ? 34 : 28) : (do_wide ? 26 : 20), ' ');
+         print_vma (rels[i].r_addend, LONG_HEX);
+       }
+
+      putchar ('\n');
+
+    }
+
+  free (rels);
+
+  return 1;
+}
+
+static const char *
+get_mips_dynamic_type (type)
+     unsigned long type;
+{
+  switch (type)
+    {
+    default:
+      return NULL;
+    }
+}
+
+static const char *
+get_sparc64_dynamic_type (type)
+     unsigned long type;
+{
+  switch (type)
+    {
+    default:
+      return NULL;
+    }
+}
+
+static const char *
+get_ppc64_dynamic_type (type)
+     unsigned long type;
+{
+  switch (type)
+    {
+    default:
+      return NULL;
+    }
+}
+
+static const char *
+get_parisc_dynamic_type (type)
+     unsigned long type;
+{
+  switch (type)
+    {
+    default:
+      return NULL;
+    }
+}
+
+static const char *
+get_ia64_dynamic_type (type)
+     unsigned long type;
+{
+  switch (type)
+    {
+    default:
+      return NULL;
+    }
+}
+
+static const char *
+get_dynamic_type (type)
+     unsigned long type;
+{
+  static char buff[32];
+
+  switch (type)
+    {
+    case DT_NULL:      return "NULL";
+    case DT_NEEDED:    return "NEEDED";
+    case DT_PLTRELSZ:  return "PLTRELSZ";
+    case DT_PLTGOT:    return "PLTGOT";
+    case DT_HASH:      return "HASH";
+    case DT_STRTAB:    return "STRTAB";
+    case DT_SYMTAB:    return "SYMTAB";
+    case DT_RELA:      return "RELA";
+    case DT_RELASZ:    return "RELASZ";
+    case DT_RELAENT:   return "RELAENT";
+    case DT_STRSZ:     return "STRSZ";
+    case DT_SYMENT:    return "SYMENT";
+    case DT_INIT:      return "INIT";
+    case DT_FINI:      return "FINI";
+    case DT_SONAME:    return "SONAME";
+    case DT_RPATH:     return "RPATH";
+    case DT_SYMBOLIC:  return "SYMBOLIC";
+    case DT_REL:       return "REL";
+    case DT_RELSZ:     return "RELSZ";
+    case DT_RELENT:    return "RELENT";
+    case DT_PLTREL:    return "PLTREL";
+    case DT_DEBUG:     return "DEBUG";
+    case DT_TEXTREL:   return "TEXTREL";
+    case DT_JMPREL:    return "JMPREL";
+    case DT_BIND_NOW:   return "BIND_NOW";
+    case DT_INIT_ARRAY: return "INIT_ARRAY";
+    case DT_FINI_ARRAY: return "FINI_ARRAY";
+    case DT_INIT_ARRAYSZ: return "INIT_ARRAYSZ";
+    case DT_FINI_ARRAYSZ: return "FINI_ARRAYSZ";
+    case DT_RUNPATH:    return "RUNPATH";
+    case DT_FLAGS:      return "FLAGS";
+
+    case DT_PREINIT_ARRAY: return "PREINIT_ARRAY";
+    case DT_PREINIT_ARRAYSZ: return "PREINIT_ARRAYSZ";
+
+    case DT_CHECKSUM:  return "CHECKSUM";
+    case DT_PLTPADSZ:  return "PLTPADSZ";
+    case DT_MOVEENT:   return "MOVEENT";
+    case DT_MOVESZ:    return "MOVESZ";
+    case DT_FEATURE:   return "FEATURE";
+    case DT_POSFLAG_1: return "POSFLAG_1";
+    case DT_SYMINSZ:   return "SYMINSZ";
+    case DT_SYMINENT:  return "SYMINENT"; /* aka VALRNGHI */
+
+    case DT_ADDRRNGLO:  return "ADDRRNGLO";
+    case DT_CONFIG:    return "CONFIG";
+    case DT_DEPAUDIT:  return "DEPAUDIT";
+    case DT_AUDIT:     return "AUDIT";
+    case DT_PLTPAD:    return "PLTPAD";
+    case DT_MOVETAB:   return "MOVETAB";
+    case DT_SYMINFO:   return "SYMINFO"; /* aka ADDRRNGHI */
+
+    case DT_VERSYM:    return "VERSYM";
+
+    case DT_RELACOUNT: return "RELACOUNT";
+    case DT_RELCOUNT:  return "RELCOUNT";
+    case DT_FLAGS_1:   return "FLAGS_1";
+    case DT_VERDEF:    return "VERDEF";
+    case DT_VERDEFNUM: return "VERDEFNUM";
+    case DT_VERNEED:   return "VERNEED";
+    case DT_VERNEEDNUM:        return "VERNEEDNUM";
+
+    case DT_AUXILIARY: return "AUXILIARY";
+    case DT_USED:      return "USED";
+    case DT_FILTER:    return "FILTER";
+
+    case DT_GNU_PRELINKED: return "GNU_PRELINKED";
+    case DT_GNU_CONFLICT: return "GNU_CONFLICT";
+    case DT_GNU_CONFLICTSZ: return "GNU_CONFLICTSZ";
+    case DT_GNU_LIBLIST: return "GNU_LIBLIST";
+    case DT_GNU_LIBLISTSZ: return "GNU_LIBLISTSZ";
+
+    default:
+      if ((type >= DT_LOPROC) && (type <= DT_HIPROC))
+       {
+         const char *result;
+
+         switch (elf_header.e_machine)
+           {
+           case EM_MIPS:
+           case EM_MIPS_RS3_LE:
+             result = get_mips_dynamic_type (type);
+             break;
+           case EM_SPARCV9:
+             result = get_sparc64_dynamic_type (type);
+             break;
+           case EM_PPC64:
+             result = get_ppc64_dynamic_type (type);
+             break;
+           case EM_IA_64:
+             result = get_ia64_dynamic_type (type);
+             break;
+           default:
+             result = NULL;
+             break;
+           }
+
+         if (result != NULL)
+           return result;
+
+         sprintf (buff, _("Processor Specific: %lx"), type);
+       }
+      else if ((type >= DT_LOOS) && (type <= DT_HIOS))
+       {
+         const char *result;
+
+         switch (elf_header.e_machine)
+           {
+           case EM_PARISC:
+             result = get_parisc_dynamic_type (type);
+             break;
+           default:
+             result = NULL;
+             break;
+           }
+
+         if (result != NULL)
+           return result;
+
+         sprintf (buff, _("Operating System specific: %lx"), type);
+       }
+      else
+       sprintf (buff, _("<unknown>: %lx"), type);
+
+      return buff;
+    }
+}
+
+static char *
+get_file_type (e_type)
+     unsigned e_type;
+{
+  static char buff[32];
+
+  switch (e_type)
+    {
+    case ET_NONE:      return _("NONE (None)");
+    case ET_REL:       return _("REL (Relocatable file)");
+    case ET_EXEC:       return _("EXEC (Executable file)");
+    case ET_DYN:        return _("DYN (Shared object file)");
+    case ET_CORE:       return _("CORE (Core file)");
+
+    default:
+      if ((e_type >= ET_LOPROC) && (e_type <= ET_HIPROC))
+       sprintf (buff, _("Processor Specific: (%x)"), e_type);
+      else if ((e_type >= ET_LOOS) && (e_type <= ET_HIOS))
+       sprintf (buff, _("OS Specific: (%x)"), e_type);
+      else
+       sprintf (buff, _("<unknown>: %x"), e_type);
+      return buff;
+    }
+}
+
+static char *
+get_machine_name (e_machine)
+     unsigned e_machine;
+{
+  static char buff[64]; /* XXX */
+
+  switch (e_machine)
+    {
+    case EM_NONE:              return _("None");
+    case EM_M32:               return "WE32100";
+    case EM_SPARC:             return "Sparc";
+    case EM_386:               return "Intel 80386";
+    case EM_68K:               return "MC68000";
+    case EM_88K:               return "MC88000";
+    case EM_486:               return "Intel 80486";
+    case EM_860:               return "Intel 80860";
+    case EM_MIPS:              return "MIPS R3000";
+    case EM_S370:              return "IBM System/370";
+    case EM_MIPS_RS3_LE:       return "MIPS R4000 big-endian";
+    case EM_OLD_SPARCV9:       return "Sparc v9 (old)";
+    case EM_PARISC:            return "HPPA";
+    case EM_PPC_OLD:           return "Power PC (old)";
+    case EM_SPARC32PLUS:       return "Sparc v8+" ;
+    case EM_960:               return "Intel 90860";
+    case EM_PPC:               return "PowerPC";
+    case EM_PPC64:             return "PowerPC64";
+    case EM_V800:              return "NEC V800";
+    case EM_FR20:              return "Fujitsu FR20";
+    case EM_RH32:              return "TRW RH32";
+    case EM_MCORE:             return "MCORE";
+    case EM_ARM:               return "ARM";
+    case EM_OLD_ALPHA:         return "Digital Alpha (old)";
+    case EM_SH:                        return "Renesas / SuperH SH";
+    case EM_SPARCV9:           return "Sparc v9";
+    case EM_TRICORE:           return "Siemens Tricore";
+    case EM_ARC:               return "ARC";
+    case EM_H8_300:            return "Renesas H8/300";
+    case EM_H8_300H:           return "Renesas H8/300H";
+    case EM_H8S:               return "Renesas H8S";
+    case EM_H8_500:            return "Renesas H8/500";
+    case EM_IA_64:             return "Intel IA-64";
+    case EM_MIPS_X:            return "Stanford MIPS-X";
+    case EM_COLDFIRE:          return "Motorola Coldfire";
+    case EM_68HC12:            return "Motorola M68HC12";
+    case EM_ALPHA:             return "Alpha";
+    case EM_CYGNUS_D10V:
+    case EM_D10V:              return "d10v";
+    case EM_CYGNUS_D30V:
+    case EM_D30V:              return "d30v";
+    case EM_CYGNUS_M32R:
+    case EM_M32R:              return "Renesas M32R (formerly Mitsubishi M32r)";
+    case EM_CYGNUS_V850:
+    case EM_V850:              return "NEC v850";
+    case EM_CYGNUS_MN10300:
+    case EM_MN10300:           return "mn10300";
+    case EM_CYGNUS_MN10200:
+    case EM_MN10200:           return "mn10200";
+    case EM_CYGNUS_FR30:
+    case EM_FR30:              return "Fujitsu FR30";
+    case EM_CYGNUS_FRV:                return "Fujitsu FR-V";
+    case EM_PJ_OLD:
+    case EM_PJ:                        return "picoJava";
+    case EM_MMA:               return "Fujitsu Multimedia Accelerator";
+    case EM_PCP:               return "Siemens PCP";
+    case EM_NCPU:              return "Sony nCPU embedded RISC processor";
+    case EM_NDR1:              return "Denso NDR1 microprocesspr";
+    case EM_STARCORE:          return "Motorola Star*Core processor";
+    case EM_ME16:              return "Toyota ME16 processor";
+    case EM_ST100:             return "STMicroelectronics ST100 processor";
+    case EM_TINYJ:             return "Advanced Logic Corp. TinyJ embedded processor";
+    case EM_FX66:              return "Siemens FX66 microcontroller";
+    case EM_ST9PLUS:           return "STMicroelectronics ST9+ 8/16 bit microcontroller";
+    case EM_ST7:               return "STMicroelectronics ST7 8-bit microcontroller";
+    case EM_68HC16:            return "Motorola MC68HC16 Microcontroller";
+    case EM_68HC11:            return "Motorola MC68HC11 Microcontroller";
+    case EM_68HC08:            return "Motorola MC68HC08 Microcontroller";
+    case EM_68HC05:            return "Motorola MC68HC05 Microcontroller";
+    case EM_SVX:               return "Silicon Graphics SVx";
+    case EM_ST19:              return "STMicroelectronics ST19 8-bit microcontroller";
+    case EM_VAX:               return "Digital VAX";
+    case EM_AVR_OLD:
+    case EM_AVR:               return "Atmel AVR 8-bit microcontroller";
+    case EM_CRIS:              return "Axis Communications 32-bit embedded processor";
+    case EM_JAVELIN:           return "Infineon Technologies 32-bit embedded cpu";
+    case EM_FIREPATH:          return "Element 14 64-bit DSP processor";
+    case EM_ZSP:               return "LSI Logic's 16-bit DSP processor";
+    case EM_MMIX:              return "Donald Knuth's educational 64-bit processor";
+    case EM_HUANY:             return "Harvard Universitys's machine-independent object format";
+    case EM_PRISM:             return "Vitesse Prism";
+    case EM_X86_64:            return "Advanced Micro Devices X86-64";
+    case EM_S390_OLD:
+    case EM_S390:              return "IBM S/390";
+    case EM_XSTORMY16:         return "Sanyo Xstormy16 CPU core";
+    case EM_OPENRISC:
+    case EM_OR32:              return "OpenRISC";
+    case EM_DLX:               return "OpenDLX";
+    case EM_IP2K_OLD:
+    case EM_IP2K:              return "Ubicom IP2xxx 8-bit microcontrollers";
+    case EM_IQ2000:            return "Vitesse IQ2000";
+    case EM_XTENSA_OLD:
+    case EM_XTENSA:            return "Tensilica Xtensa Processor";
+    default:
+      sprintf (buff, _("<unknown>: %x"), e_machine);
+      return buff;
+    }
+}
+
+static char *
+get_machine_flags (e_flags, e_machine)
+     unsigned e_flags;
+     unsigned e_machine;
+{
+  static char buf[1024];
+
+  buf[0] = '\0';
+  return buf;
+}
+
+static const char *
+get_mips_segment_type (type)
+     unsigned long type;
+{
+  return NULL;
+}
+
+static const char *
+get_parisc_segment_type (type)
+     unsigned long type;
+{
+  return NULL;
+}
+
+static const char *
+get_ia64_segment_type (type)
+     unsigned long type;
+{
+  return NULL;
+}
+
+static const char *
+get_segment_type (p_type)
+     unsigned long p_type;
+{
+  static char buff[32];
+
+  switch (p_type)
+    {
+    case PT_NULL:      return "NULL";
+    case PT_LOAD:      return "LOAD";
+    case PT_DYNAMIC:   return "DYNAMIC";
+    case PT_INTERP:    return "INTERP";
+    case PT_NOTE:      return "NOTE";
+    case PT_SHLIB:     return "SHLIB";
+    case PT_PHDR:      return "PHDR";
+    case PT_TLS:       return "TLS";
+
+    case PT_GNU_EH_FRAME:
+                       return "GNU_EH_FRAME";
+
+    default:
+      if ((p_type >= PT_LOPROC) && (p_type <= PT_HIPROC))
+       {
+         const char *result;
+
+         switch (elf_header.e_machine)
+           {
+           case EM_MIPS:
+           case EM_MIPS_RS3_LE:
+             result = get_mips_segment_type (p_type);
+             break;
+           case EM_PARISC:
+             result = get_parisc_segment_type (p_type);
+             break;
+           case EM_IA_64:
+             result = get_ia64_segment_type (p_type);
+             break;
+           default:
+             result = NULL;
+             break;
+           }
+
+         if (result != NULL)
+           return result;
+
+         sprintf (buff, "LOPROC+%lx", p_type - PT_LOPROC);
+       }
+      else if ((p_type >= PT_LOOS) && (p_type <= PT_HIOS))
+       {
+         const char *result;
+
+         switch (elf_header.e_machine)
+           {
+           case EM_PARISC:
+             result = get_parisc_segment_type (p_type);
+             break;
+           case EM_IA_64:
+             result = get_ia64_segment_type (p_type);
+             break;
+           default:
+             result = NULL;
+             break;
+           }
+
+         if (result != NULL)
+           return result;
+
+         sprintf (buff, "LOOS+%lx", p_type - PT_LOOS);
+       }
+      else
+       sprintf (buff, _("<unknown>: %lx"), p_type);
+
+      return buff;
+    }
+}
+
+static const char *
+get_mips_section_type_name (sh_type)
+     unsigned int sh_type;
+{
+  return NULL;
+}
+
+static const char *
+get_parisc_section_type_name (sh_type)
+     unsigned int sh_type;
+{
+  return NULL;
+}
+
+static const char *
+get_ia64_section_type_name (sh_type)
+     unsigned int sh_type;
+{
+  return NULL;
+}
+
+static const char *
+get_section_type_name (sh_type)
+     unsigned int sh_type;
+{
+  static char buff[32];
+
+  switch (sh_type)
+    {
+    case SHT_NULL:             return "NULL";
+    case SHT_PROGBITS:         return "PROGBITS";
+    case SHT_SYMTAB:           return "SYMTAB";
+    case SHT_STRTAB:           return "STRTAB";
+    case SHT_RELA:             return "RELA";
+    case SHT_HASH:             return "HASH";
+    case SHT_DYNAMIC:          return "DYNAMIC";
+    case SHT_NOTE:             return "NOTE";
+    case SHT_NOBITS:           return "NOBITS";
+    case SHT_REL:              return "REL";
+    case SHT_SHLIB:            return "SHLIB";
+    case SHT_DYNSYM:           return "DYNSYM";
+    case SHT_INIT_ARRAY:       return "INIT_ARRAY";
+    case SHT_FINI_ARRAY:       return "FINI_ARRAY";
+    case SHT_PREINIT_ARRAY:    return "PREINIT_ARRAY";
+    case SHT_GROUP:            return "GROUP";
+    case SHT_SYMTAB_SHNDX:     return "SYMTAB SECTION INDICIES";
+    case SHT_GNU_verdef:       return "VERDEF";
+    case SHT_GNU_verneed:      return "VERNEED";
+    case SHT_GNU_versym:       return "VERSYM";
+    case 0x6ffffff0:           return "VERSYM";
+    case 0x6ffffffc:           return "VERDEF";
+    case 0x7ffffffd:           return "AUXILIARY";
+    case 0x7fffffff:           return "FILTER";
+    case SHT_GNU_LIBLIST:      return "GNU_LIBLIST";
+
+    default:
+      if ((sh_type >= SHT_LOPROC) && (sh_type <= SHT_HIPROC))
+       {
+         const char *result;
+
+         switch (elf_header.e_machine)
+           {
+           case EM_MIPS:
+           case EM_MIPS_RS3_LE:
+             result = get_mips_section_type_name (sh_type);
+             break;
+           case EM_PARISC:
+             result = get_parisc_section_type_name (sh_type);
+             break;
+           case EM_IA_64:
+             result = get_ia64_section_type_name (sh_type);
+             break;
+           default:
+             result = NULL;
+             break;
+           }
+
+         if (result != NULL)
+           return result;
+
+         sprintf (buff, "LOPROC+%x", sh_type - SHT_LOPROC);
+       }
+      else if ((sh_type >= SHT_LOOS) && (sh_type <= SHT_HIOS))
+       sprintf (buff, "LOOS+%x", sh_type - SHT_LOOS);
+      else if ((sh_type >= SHT_LOUSER) && (sh_type <= SHT_HIUSER))
+       sprintf (buff, "LOUSER+%x", sh_type - SHT_LOUSER);
+      else
+       sprintf (buff, _("<unknown>: %x"), sh_type);
+
+      return buff;
+    }
+}
+
+#define OPTION_DEBUG_DUMP      512
+
+struct option options[] =
+{
+  {"all",             no_argument, 0, 'a'},
+  {"file-header",      no_argument, 0, 'h'},
+  {"program-headers",  no_argument, 0, 'l'},
+  {"headers",         no_argument, 0, 'e'},
+  {"histogram",               no_argument, 0, 'I'},
+  {"segments",        no_argument, 0, 'l'},
+  {"sections",        no_argument, 0, 'S'},
+  {"section-headers",  no_argument, 0, 'S'},
+  {"symbols",         no_argument, 0, 's'},
+  {"syms",            no_argument, 0, 's'},
+  {"relocs",          no_argument, 0, 'r'},
+  {"notes",           no_argument, 0, 'n'},
+  {"dynamic",         no_argument, 0, 'd'},
+  {"arch-specific",    no_argument, 0, 'A'},
+  {"version-info",     no_argument, 0, 'V'},
+  {"use-dynamic",      no_argument, 0, 'D'},
+  {"hex-dump",        required_argument, 0, 'x'},
+  {"debug-dump",       optional_argument, 0, OPTION_DEBUG_DUMP},
+  {"unwind",          no_argument, 0, 'u'},
+#ifdef SUPPORT_DISASSEMBLY
+  {"instruction-dump", required_argument, 0, 'i'},
+#endif
+
+  {"version",         no_argument, 0, 'v'},
+  {"wide",            no_argument, 0, 'W'},
+  {"help",            no_argument, 0, 'H'},
+  {0,                 no_argument, 0, 0}
+};
+
+static void
+usage ()
+{
+  fprintf (stdout, _("Usage: readelf <option(s)> elf-file(s)\n"));
+  fprintf (stdout, _(" Display information about the contents of ELF format files\n"));
+  fprintf (stdout, _(" Options are:\n\
+  -a --all               Equivalent to: -h -l -S -s -r -d -V -A -I\n\
+  -h --file-header       Display the ELF file header\n\
+  -l --program-headers   Display the program headers\n\
+     --segments          An alias for --program-headers\n\
+  -S --section-headers   Display the sections' header\n\
+     --sections          An alias for --section-headers\n\
+  -e --headers           Equivalent to: -h -l -S\n\
+  -s --syms              Display the symbol table\n\
+      --symbols          An alias for --syms\n\
+  -n --notes             Display the core notes (if present)\n\
+  -r --relocs            Display the relocations (if present)\n\
+  -u --unwind            Display the unwind info (if present)\n\
+  -d --dynamic           Display the dynamic segment (if present)\n\
+  -V --version-info      Display the version sections (if present)\n\
+  -A --arch-specific     Display architecture specific information (if any).\n\
+  -D --use-dynamic       Use the dynamic section info when displaying symbols\n\
+  -x --hex-dump=<number> Dump the contents of section <number>\n\
+  -w[liaprmfFso] or\n\
+  --debug-dump[=line,=info,=abbrev,=pubnames,=ranges,=macro,=frames,=str,=loc]\n\
+                         Display the contents of DWARF2 debug sections\n"));
+#ifdef SUPPORT_DISASSEMBLY
+  fprintf (stdout, _("\
+  -i --instruction-dump=<number>\n\
+                         Disassemble the contents of section <number>\n"));
+#endif
+  fprintf (stdout, _("\
+  -I --histogram         Display histogram of bucket list lengths\n\
+  -W --wide              Allow output width to exceed 80 characters\n\
+  -H --help              Display this information\n\
+  -v --version           Display the version number of readelf\n"));
+  fprintf (stdout, _("Report bugs to %s\n"), REPORT_BUGS_TO);
+
+  exit (0);
+}
+
+static void
+request_dump (section, type)
+     unsigned int section;
+     int type;
+{
+  if (section >= num_dump_sects)
+    {
+      char *new_dump_sects;
+
+      new_dump_sects = (char *) calloc (section + 1, 1);
+
+      if (new_dump_sects == NULL)
+       error (_("Out of memory allocating dump request table."));
+      else
+       {
+         /* Copy current flag settings.  */
+         memcpy (new_dump_sects, dump_sects, num_dump_sects);
+
+         free (dump_sects);
+
+         dump_sects = new_dump_sects;
+         num_dump_sects = section + 1;
+       }
+    }
+
+  if (dump_sects)
+    dump_sects[section] |= type;
+
+  return;
+}
+
+static void
+parse_args (argc, argv)
+     int argc;
+     char **argv;
+{
+  int c;
+
+  if (argc < 2)
+    usage ();
+
+  while ((c = getopt_long
+         (argc, argv, "ersuahnldSDAIw::x:i:vVWH", options, NULL)) != EOF)
+    {
+      char *cp;
+      int section;
+
+      switch (c)
+       {
+       case 0:
+         /* Long options.  */
+         break;
+       case 'H':
+         usage ();
+         break;
+
+       case 'a':
+         do_syms++;
+         do_reloc++;
+         do_unwind++;
+         do_dynamic++;
+         do_header++;
+         do_sections++;
+         do_segments++;
+         do_version++;
+         do_histogram++;
+         do_arch++;
+         do_notes++;
+         break;
+       case 'e':
+         do_header++;
+         do_sections++;
+         do_segments++;
+         break;
+       case 'A':
+         do_arch++;
+         break;
+       case 'D':
+         do_using_dynamic++;
+         break;
+       case 'r':
+         do_reloc++;
+         break;
+       case 'u':
+         do_unwind++;
+         break;
+       case 'h':
+         do_header++;
+         break;
+       case 'l':
+         do_segments++;
+         break;
+       case 's':
+         do_syms++;
+         break;
+       case 'S':
+         do_sections++;
+         break;
+       case 'd':
+         do_dynamic++;
+         break;
+       case 'I':
+         do_histogram++;
+         break;
+       case 'n':
+         do_notes++;
+         break;
+       case 'x':
+         do_dump++;
+         section = strtoul (optarg, & cp, 0);
+         if (! *cp && section >= 0)
+           {
+             request_dump (section, HEX_DUMP);
+             break;
+           }
+         goto oops;
+       case 'w':
+         do_dump++;
+         if (optarg == 0)
+           do_debugging = 1;
+         else
+           {
+             unsigned int idx = 0;
+
+             do_debugging = 0;
+
+             while (optarg[idx])
+               switch (optarg[idx++])
+                 {
+                 case 'i':
+                 case 'I':
+                   do_debug_info = 1;
+                   break;
+
+                 case 'a':
+                 case 'A':
+                   do_debug_abbrevs = 1;
+                   break;
+
+                 case 'l':
+                 case 'L':
+                   do_debug_lines = 1;
+                   break;
+
+                 case 'p':
+                 case 'P':
+                   do_debug_pubnames = 1;
+                   break;
+
+                 case 'r':
+                 case 'R':
+                   do_debug_aranges = 1;
+                   break;
+
+                 case 'F':
+                   do_debug_frames_interp = 1;
+                 case 'f':
+                   do_debug_frames = 1;
+                   break;
+
+                 case 'm':
+                 case 'M':
+                   do_debug_macinfo = 1;
+                   break;
+
+                 case 's':
+                 case 'S':
+                   do_debug_str = 1;
+                   break;
+
+                 case 'o':
+                 case 'O':
+                   do_debug_loc = 1;
+                   break;
+
+                 default:
+                   warn (_("Unrecognized debug option '%s'\n"), optarg);
+                   break;
+                 }
+           }
+         break;
+       case OPTION_DEBUG_DUMP:
+         do_dump++;
+         if (optarg == 0)
+           do_debugging = 1;
+         else
+           {
+             static const char *debug_dump_opt[]
+               = { "line", "info", "abbrev", "pubnames", "ranges",
+                   "macro", "frames", "frames-interp", "str", "loc", NULL };
+             unsigned int idx;
+             const char *p;
+
+             do_debugging = 0;
+
+             p = optarg;
+             while (*p)
+               {
+                 for (idx = 0; debug_dump_opt[idx]; idx++)
+                   {
+                     size_t len = strlen (debug_dump_opt[idx]);
+
+                     if (strncmp (p, debug_dump_opt[idx], len) == 0
+                         && (p[len] == ',' || p[len] == '\0'))
+                       {
+                         switch (p[0])
+                           {
+                           case 'i':
+                             do_debug_info = 1;
+                             break;
+
+                           case 'a':
+                             do_debug_abbrevs = 1;
+                             break;
+
+                           case 'l':
+                             if (p[1] == 'i')
+                               do_debug_lines = 1;
+                             else
+                               do_debug_loc = 1;
+                             break;
+
+                           case 'p':
+                             do_debug_pubnames = 1;
+                             break;
+
+                           case 'r':
+                             do_debug_aranges = 1;
+                             break;
+
+                           case 'f':
+                             if (len > 6)
+                               do_debug_frames_interp = 1;
+                             do_debug_frames = 1;
+                             break;
+
+                           case 'm':
+                             do_debug_macinfo = 1;
+                             break;
+
+                           case 's':
+                             do_debug_str = 1;
+                             break;
+                           }
+
+                         p += len;
+                         break;
+                       }
+                   }
+
+                 if (debug_dump_opt[idx] == NULL)
+                   {
+                     warn (_("Unrecognized debug option '%s'\n"), p);
+                     p = strchr (p, ',');
+                     if (p == NULL)
+                       break;
+                   }
+
+                 if (*p == ',')
+                   p++;
+               }
+           }
+         break;
+#ifdef SUPPORT_DISASSEMBLY
+       case 'i':
+         do_dump++;
+         section = strtoul (optarg, & cp, 0);
+         if (! *cp && section >= 0)
+           {
+             request_dump (section, DISASS_DUMP);
+             break;
+           }
+         goto oops;
+#endif
+       case 'v':
+         /*      print_version (program_name);*/
+         break;
+       case 'V':
+         do_version++;
+         break;
+       case 'W':
+         do_wide++;
+         break;
+       default:
+       oops:
+         /* xgettext:c-format */
+         error (_("Invalid option '-%c'\n"), c);
+         /* Drop through.  */
+       case '?':
+         usage ();
+       }
+    }
+
+  if (!do_dynamic && !do_syms && !do_reloc && !do_unwind && !do_sections
+      && !do_segments && !do_header && !do_dump && !do_version
+      && !do_histogram && !do_debugging && !do_arch && !do_notes)
+    usage ();
+  else if (argc < 3)
+    {
+      warn (_("Nothing to do.\n"));
+      usage();
+    }
+}
+
+static const char *
+get_elf_class (elf_class)
+     unsigned int elf_class;
+{
+  static char buff[32];
+
+  switch (elf_class)
+    {
+    case ELFCLASSNONE: return _("none");
+    case ELFCLASS32:   return "ELF32";
+    case ELFCLASS64:   return "ELF64";
+    default:
+      sprintf (buff, _("<unknown: %x>"), elf_class);
+      return buff;
+    }
+}
+
+static const char *
+get_data_encoding (encoding)
+     unsigned int encoding;
+{
+  static char buff[32];
+
+  switch (encoding)
+    {
+    case ELFDATANONE: return _("none");
+    case ELFDATA2LSB: return _("2's complement, little endian");
+    case ELFDATA2MSB: return _("2's complement, big endian");
+    default:
+      sprintf (buff, _("<unknown: %x>"), encoding);
+      return buff;
+    }
+}
+
+static const char *
+get_osabi_name (osabi)
+     unsigned int osabi;
+{
+  static char buff[32];
+
+  switch (osabi)
+    {
+    case ELFOSABI_NONE:                return "UNIX - System V";
+    case ELFOSABI_HPUX:                return "UNIX - HP-UX";
+    case ELFOSABI_NETBSD:      return "UNIX - NetBSD";
+    case ELFOSABI_LINUX:       return "UNIX - Linux";
+    case ELFOSABI_HURD:                return "GNU/Hurd";
+    case ELFOSABI_SOLARIS:     return "UNIX - Solaris";
+    case ELFOSABI_AIX:         return "UNIX - AIX";
+    case ELFOSABI_IRIX:                return "UNIX - IRIX";
+    case ELFOSABI_FREEBSD:     return "UNIX - FreeBSD";
+    case ELFOSABI_TRU64:       return "UNIX - TRU64";
+    case ELFOSABI_MODESTO:     return "Novell - Modesto";
+    case ELFOSABI_OPENBSD:     return "UNIX - OpenBSD";
+    case ELFOSABI_OPENVMS:     return "VMS - OpenVMS";
+    case ELFOSABI_NSK:         return "HP - Non-Stop Kernel";
+    case ELFOSABI_AROS:                return "Amiga Research OS";
+    case ELFOSABI_STANDALONE:  return _("Standalone App");
+    case ELFOSABI_ARM:         return "ARM";
+    default:
+      sprintf (buff, _("<unknown: %x>"), osabi);
+      return buff;
+    }
+}
+
+/* Decode the data held in 'elf_header'.  */
+
+static int
+process_file_header ()
+{
+  if (   elf_header.e_ident[EI_MAG0] != ELFMAG0
+      || elf_header.e_ident[EI_MAG1] != ELFMAG1
+      || elf_header.e_ident[EI_MAG2] != ELFMAG2
+      || elf_header.e_ident[EI_MAG3] != ELFMAG3)
+    {
+      error
+       (_("Not an ELF file - it has the wrong magic bytes at the start\n"));
+      return 0;
+    }
+
+  if (do_header)
+    {
+      int i;
+
+      printf (_("ELF Header:\n"));
+      printf (_("  Magic:   "));
+      for (i = 0; i < EI_NIDENT; i++)
+       printf ("%2.2x ", elf_header.e_ident[i]);
+      printf ("\n");
+      printf (_("  Class:                             %s\n"),
+             get_elf_class (elf_header.e_ident[EI_CLASS]));
+      printf (_("  Data:                              %s\n"),
+             get_data_encoding (elf_header.e_ident[EI_DATA]));
+      printf (_("  Version:                           %d %s\n"),
+             elf_header.e_ident[EI_VERSION],
+             (elf_header.e_ident[EI_VERSION] == EV_CURRENT
+              ? "(current)"
+              : (elf_header.e_ident[EI_VERSION] != EV_NONE
+                 ? "<unknown: %lx>"
+                 : "")));
+      printf (_("  OS/ABI:                            %s\n"),
+             get_osabi_name (elf_header.e_ident[EI_OSABI]));
+      printf (_("  ABI Version:                       %d\n"),
+             elf_header.e_ident[EI_ABIVERSION]);
+      printf (_("  Type:                              %s\n"),
+             get_file_type (elf_header.e_type));
+      printf (_("  Machine:                           %s\n"),
+             get_machine_name (elf_header.e_machine));
+      printf (_("  Version:                           0x%lx\n"),
+             (unsigned long) elf_header.e_version);
+
+      printf (_("  Entry point address:               "));
+      print_vma ((bfd_vma) elf_header.e_entry, PREFIX_HEX);
+      printf (_("\n  Start of program headers:          "));
+      print_vma ((bfd_vma) elf_header.e_phoff, DEC);
+      printf (_(" (bytes into file)\n  Start of section headers:          "));
+      print_vma ((bfd_vma) elf_header.e_shoff, DEC);
+      printf (_(" (bytes into file)\n"));
+
+      printf (_("  Flags:                             0x%lx%s\n"),
+             (unsigned long) elf_header.e_flags,
+             get_machine_flags (elf_header.e_flags, elf_header.e_machine));
+      printf (_("  Size of this header:               %ld (bytes)\n"),
+             (long) elf_header.e_ehsize);
+      printf (_("  Size of program headers:           %ld (bytes)\n"),
+             (long) elf_header.e_phentsize);
+      printf (_("  Number of program headers:         %ld\n"),
+             (long) elf_header.e_phnum);
+      printf (_("  Size of section headers:           %ld (bytes)\n"),
+             (long) elf_header.e_shentsize);
+      printf (_("  Number of section headers:         %ld"),
+             (long) elf_header.e_shnum);
+      if (section_headers != NULL && elf_header.e_shnum == 0)
+       printf (" (%ld)", (long) section_headers[0].sh_size);
+      putc ('\n', stdout);
+      printf (_("  Section header string table index: %ld"),
+             (long) elf_header.e_shstrndx);
+      if (section_headers != NULL && elf_header.e_shstrndx == SHN_XINDEX)
+       printf (" (%ld)", (long) section_headers[0].sh_link);
+      putc ('\n', stdout);
+    }
+
+  if (section_headers != NULL)
+    {
+      if (elf_header.e_shnum == 0)
+       elf_header.e_shnum = section_headers[0].sh_size;
+      if (elf_header.e_shstrndx == SHN_XINDEX)
+       elf_header.e_shstrndx = section_headers[0].sh_link;
+      free (section_headers);
+      section_headers = NULL;
+    }
+
+  return 1;
+}
+
+
+static int
+get_32bit_program_headers (file, program_headers)
+     FILE *file;
+     Elf_Internal_Phdr *program_headers;
+{
+  Elf32_External_Phdr *phdrs;
+  Elf32_External_Phdr *external;
+  Elf_Internal_Phdr *internal;
+  unsigned int i;
+
+  phdrs = ((Elf32_External_Phdr *)
+          get_data (NULL, file, elf_header.e_phoff,
+                    elf_header.e_phentsize * elf_header.e_phnum,
+                    _("program headers")));
+  if (!phdrs)
+    return 0;
+
+  for (i = 0, internal = program_headers, external = phdrs;
+       i < elf_header.e_phnum;
+       i++, internal++, external++)
+    {
+      internal->p_type   = BYTE_GET (external->p_type);
+      internal->p_offset = BYTE_GET (external->p_offset);
+      internal->p_vaddr  = BYTE_GET (external->p_vaddr);
+      internal->p_paddr  = BYTE_GET (external->p_paddr);
+      internal->p_filesz = BYTE_GET (external->p_filesz);
+      internal->p_memsz  = BYTE_GET (external->p_memsz);
+      internal->p_flags  = BYTE_GET (external->p_flags);
+      internal->p_align  = BYTE_GET (external->p_align);
+    }
+
+  free (phdrs);
+
+  return 1;
+}
+
+static int
+get_64bit_program_headers (file, program_headers)
+     FILE *file;
+     Elf_Internal_Phdr *program_headers;
+{
+  Elf64_External_Phdr *phdrs;
+  Elf64_External_Phdr *external;
+  Elf_Internal_Phdr *internal;
+  unsigned int i;
+
+  phdrs = ((Elf64_External_Phdr *)
+          get_data (NULL, file, elf_header.e_phoff,
+                    elf_header.e_phentsize * elf_header.e_phnum,
+                    _("program headers")));
+  if (!phdrs)
+    return 0;
+
+  for (i = 0, internal = program_headers, external = phdrs;
+       i < elf_header.e_phnum;
+       i++, internal++, external++)
+    {
+      internal->p_type   = BYTE_GET (external->p_type);
+      internal->p_flags  = BYTE_GET (external->p_flags);
+      internal->p_offset = BYTE_GET8 (external->p_offset);
+      internal->p_vaddr  = BYTE_GET8 (external->p_vaddr);
+      internal->p_paddr  = BYTE_GET8 (external->p_paddr);
+      internal->p_filesz = BYTE_GET8 (external->p_filesz);
+      internal->p_memsz  = BYTE_GET8 (external->p_memsz);
+      internal->p_align  = BYTE_GET8 (external->p_align);
+    }
+
+  free (phdrs);
+
+  return 1;
+}
+
+/* Returns 1 if the program headers were loaded.  */
+
+static int
+process_program_headers (file)
+     FILE *file;
+{
+  Elf_Internal_Phdr *program_headers;
+  Elf_Internal_Phdr *segment;
+  unsigned int i;
+
+  if (elf_header.e_phnum == 0)
+    {
+      if (do_segments)
+       printf (_("\nThere are no program headers in this file.\n"));
+      return 0;
+    }
+
+  if (do_segments && !do_header)
+    {
+      printf (_("\nElf file type is %s\n"), get_file_type (elf_header.e_type));
+      printf (_("Entry point "));
+      print_vma ((bfd_vma) elf_header.e_entry, PREFIX_HEX);
+      printf (_("\nThere are %d program headers, starting at offset "),
+             elf_header.e_phnum);
+      print_vma ((bfd_vma) elf_header.e_phoff, DEC);
+      printf ("\n");
+    }
+
+  program_headers = (Elf_Internal_Phdr *) malloc
+    (elf_header.e_phnum * sizeof (Elf_Internal_Phdr));
+
+  if (program_headers == NULL)
+    {
+      error (_("Out of memory\n"));
+      return 0;
+    }
+
+  if (is_32bit_elf)
+    i = get_32bit_program_headers (file, program_headers);
+  else
+    i = get_64bit_program_headers (file, program_headers);
+
+  if (i == 0)
+    {
+      free (program_headers);
+      return 0;
+    }
+
+  if (do_segments)
+    {
+      if (elf_header.e_phnum > 1)
+       printf (_("\nProgram Headers:\n"));
+      else
+       printf (_("\nProgram Headers:\n"));
+
+      if (is_32bit_elf)
+       printf
+         (_("  Type           Offset   VirtAddr   PhysAddr   FileSiz MemSiz  Flg Align\n"));
+      else if (do_wide)
+       printf
+         (_("  Type           Offset   VirtAddr           PhysAddr           FileSiz  MemSiz   Flg Align\n"));
+      else
+       {
+         printf
+           (_("  Type           Offset             VirtAddr           PhysAddr\n"));
+         printf
+           (_("                 FileSiz            MemSiz              Flags  Align\n"));
+       }
+    }
+
+  loadaddr = -1;
+  dynamic_addr = 0;
+  dynamic_size = 0;
+
+  for (i = 0, segment = program_headers;
+       i < elf_header.e_phnum;
+       i++, segment++)
+    {
+      if (do_segments)
+       {
+         printf ("  %-14.14s ", get_segment_type (segment->p_type));
+
+         if (is_32bit_elf)
+           {
+             printf ("0x%6.6lx ", (unsigned long) segment->p_offset);
+             printf ("0x%8.8lx ", (unsigned long) segment->p_vaddr);
+             printf ("0x%8.8lx ", (unsigned long) segment->p_paddr);
+             printf ("0x%5.5lx ", (unsigned long) segment->p_filesz);
+             printf ("0x%5.5lx ", (unsigned long) segment->p_memsz);
+             printf ("%c%c%c ",
+                     (segment->p_flags & PF_R ? 'R' : ' '),
+                     (segment->p_flags & PF_W ? 'W' : ' '),
+                     (segment->p_flags & PF_X ? 'E' : ' '));
+             printf ("%#lx", (unsigned long) segment->p_align);
+           }
+         else if (do_wide)
+           {
+             if ((unsigned long) segment->p_offset == segment->p_offset)
+               printf ("0x%6.6lx ", (unsigned long) segment->p_offset);
+             else
+               {
+                 print_vma (segment->p_offset, FULL_HEX);
+                 putchar (' ');
+               }
+
+             print_vma (segment->p_vaddr, FULL_HEX);
+             putchar (' ');
+             print_vma (segment->p_paddr, FULL_HEX);
+             putchar (' ');
+
+             if ((unsigned long) segment->p_filesz == segment->p_filesz)
+               printf ("0x%6.6lx ", (unsigned long) segment->p_filesz);
+             else
+               {
+                 print_vma (segment->p_filesz, FULL_HEX);
+                 putchar (' ');
+               }
+
+             if ((unsigned long) segment->p_memsz == segment->p_memsz)
+               printf ("0x%6.6lx", (unsigned long) segment->p_memsz);
+             else
+               {
+                 print_vma (segment->p_offset, FULL_HEX);
+               }
+
+             printf (" %c%c%c ",
+                     (segment->p_flags & PF_R ? 'R' : ' '),
+                     (segment->p_flags & PF_W ? 'W' : ' '),
+                     (segment->p_flags & PF_X ? 'E' : ' '));
+
+             if ((unsigned long) segment->p_align == segment->p_align)
+               printf ("%#lx", (unsigned long) segment->p_align);
+             else
+               {
+                 print_vma (segment->p_align, PREFIX_HEX);
+               }
+           }
+         else
+           {
+             print_vma (segment->p_offset, FULL_HEX);
+             putchar (' ');
+             print_vma (segment->p_vaddr, FULL_HEX);
+             putchar (' ');
+             print_vma (segment->p_paddr, FULL_HEX);
+             printf ("\n                 ");
+             print_vma (segment->p_filesz, FULL_HEX);
+             putchar (' ');
+             print_vma (segment->p_memsz, FULL_HEX);
+             printf ("  %c%c%c    ",
+                     (segment->p_flags & PF_R ? 'R' : ' '),
+                     (segment->p_flags & PF_W ? 'W' : ' '),
+                     (segment->p_flags & PF_X ? 'E' : ' '));
+             print_vma (segment->p_align, HEX);
+           }
+       }
+
+      switch (segment->p_type)
+       {
+       case PT_LOAD:
+         if (loadaddr == -1)
+           {
+             unsigned long align_mask = -segment->p_align;
+
+             if (align_mask == 0)
+               --align_mask;
+             loadaddr = ((segment->p_vaddr & align_mask)
+                         - (segment->p_offset & align_mask));
+           }
+         break;
+
+       case PT_DYNAMIC:
+         if (dynamic_addr)
+           error (_("more than one dynamic segment\n"));
+
+         dynamic_addr = segment->p_offset;
+         dynamic_size = segment->p_filesz;
+         break;
+
+       case PT_INTERP:
+         if (fseek (file, (long) segment->p_offset, SEEK_SET))
+           error (_("Unable to find program interpreter name\n"));
+         else
+           {
+             program_interpreter[0] = 0;
+             fscanf (file, "%63s", program_interpreter);
+
+             if (do_segments)
+               printf (_("\n      [Requesting program interpreter: %s]"),
+                   program_interpreter);
+           }
+         break;
+       }
+
+      if (do_segments)
+       putc ('\n', stdout);
+    }
+
+  if (loadaddr == -1)
+    {
+      /* Very strange.  */
+      loadaddr = 0;
+    }
+
+  if (do_segments && section_headers != NULL)
+    {
+      printf (_("\n Section to Segment mapping:\n"));
+      printf (_("  Segment Sections...\n"));
+
+      assert (string_table != NULL);
+
+      for (i = 0; i < elf_header.e_phnum; i++)
+       {
+         unsigned int j;
+         Elf_Internal_Shdr *section;
+
+         segment = program_headers + i;
+         section = section_headers;
+
+         printf ("   %2.2d     ", i);
+
+         for (j = 1; j < elf_header.e_shnum; j++, section++)
+           {
+             if (section->sh_size > 0
+                 /* Compare allocated sections by VMA, unallocated
+                    sections by file offset.  */
+                 && (section->sh_flags & SHF_ALLOC
+                     ? (section->sh_addr >= segment->p_vaddr
+                        && section->sh_addr + section->sh_size
+                        <= segment->p_vaddr + segment->p_memsz)
+                     : ((bfd_vma) section->sh_offset >= segment->p_offset
+                        && (section->sh_offset + section->sh_size
+                            <= segment->p_offset + segment->p_filesz))))
+               printf ("%s ", SECTION_NAME (section));
+           }
+
+         putc ('\n',stdout);
+       }
+    }
+
+  free (program_headers);
+
+  return 1;
+}
+
+
+static int
+get_32bit_section_headers (file, num)
+     FILE *file;
+     unsigned int num;
+{
+  Elf32_External_Shdr *shdrs;
+  Elf_Internal_Shdr *internal;
+  unsigned int i;
+
+  shdrs = ((Elf32_External_Shdr *)
+          get_data (NULL, file, elf_header.e_shoff,
+                    elf_header.e_shentsize * num,
+                    _("section headers")));
+  if (!shdrs)
+    return 0;
+
+  section_headers = ((Elf_Internal_Shdr *)
+                    malloc (num * sizeof (Elf_Internal_Shdr)));
+
+  //  printf("Just allocated section_headers at 0x%x, size = %d * %d\n",
+  //         section_headers, num, sizeof (Elf_Internal_Shdr)); //PG
+
+  if (section_headers == NULL)
+    {
+      error (_("Out of memory\n"));
+      return 0;
+    }
+
+  for (i = 0, internal = section_headers;
+       i < num;
+       i++, internal++)
+    {
+      internal->sh_name      = BYTE_GET (shdrs[i].sh_name);
+      internal->sh_type      = BYTE_GET (shdrs[i].sh_type);
+      internal->sh_flags     = BYTE_GET (shdrs[i].sh_flags);
+      internal->sh_addr      = BYTE_GET (shdrs[i].sh_addr);
+      internal->sh_offset    = BYTE_GET (shdrs[i].sh_offset);
+      internal->sh_size      = BYTE_GET (shdrs[i].sh_size);
+      internal->sh_link      = BYTE_GET (shdrs[i].sh_link);
+      internal->sh_info      = BYTE_GET (shdrs[i].sh_info);
+      internal->sh_addralign = BYTE_GET (shdrs[i].sh_addralign);
+      internal->sh_entsize   = BYTE_GET (shdrs[i].sh_entsize);
+    }
+
+  free (shdrs);
+
+  return 1;
+}
+
+static int
+get_64bit_section_headers (file, num)
+     FILE *file;
+     unsigned int num;
+{
+  Elf64_External_Shdr *shdrs;
+  Elf_Internal_Shdr *internal;
+  unsigned int i;
+
+  shdrs = ((Elf64_External_Shdr *)
+          get_data (NULL, file, elf_header.e_shoff,
+                    elf_header.e_shentsize * num,
+                    _("section headers")));
+  if (!shdrs)
+    return 0;
+
+  section_headers = ((Elf_Internal_Shdr *)
+                    malloc (num * sizeof (Elf_Internal_Shdr)));
+
+  if (section_headers == NULL)
+    {
+      error (_("Out of memory\n"));
+      return 0;
+    }
+
+  for (i = 0, internal = section_headers;
+       i < num;
+       i++, internal++)
+    {
+      internal->sh_name      = BYTE_GET (shdrs[i].sh_name);
+      internal->sh_type      = BYTE_GET (shdrs[i].sh_type);
+      internal->sh_flags     = BYTE_GET8 (shdrs[i].sh_flags);
+      internal->sh_addr      = BYTE_GET8 (shdrs[i].sh_addr);
+      internal->sh_size      = BYTE_GET8 (shdrs[i].sh_size);
+      internal->sh_entsize   = BYTE_GET8 (shdrs[i].sh_entsize);
+      internal->sh_link      = BYTE_GET (shdrs[i].sh_link);
+      internal->sh_info      = BYTE_GET (shdrs[i].sh_info);
+      internal->sh_offset    = BYTE_GET (shdrs[i].sh_offset);
+      internal->sh_addralign = BYTE_GET (shdrs[i].sh_addralign);
+    }
+
+  free (shdrs);
+
+  return 1;
+}
+
+static Elf_Internal_Sym *
+get_32bit_elf_symbols (file, section)
+     FILE *file;
+     Elf_Internal_Shdr *section;
+{
+  unsigned long number;
+  Elf32_External_Sym *esyms;
+  Elf_External_Sym_Shndx *shndx;
+  Elf_Internal_Sym *isyms;
+  Elf_Internal_Sym *psym;
+  unsigned int j;
+
+  esyms = ((Elf32_External_Sym *)
+          get_data (NULL, file, section->sh_offset,
+                    section->sh_size, _("symbols")));
+  if (!esyms)
+    return NULL;
+
+  shndx = NULL;
+  if (symtab_shndx_hdr != NULL
+      && (symtab_shndx_hdr->sh_link
+         == (unsigned long) SECTION_HEADER_NUM (section - section_headers)))
+    {
+      shndx = ((Elf_External_Sym_Shndx *)
+              get_data (NULL, file, symtab_shndx_hdr->sh_offset,
+                        symtab_shndx_hdr->sh_size, _("symtab shndx")));
+      if (!shndx)
+       {
+         free (esyms);
+         return NULL;
+       }
+    }
+
+  number = section->sh_size / section->sh_entsize;
+  isyms = (Elf_Internal_Sym *) malloc (number * sizeof (Elf_Internal_Sym));
+
+  if (isyms == NULL)
+    {
+      error (_("Out of memory\n"));
+      if (shndx)
+       free (shndx);
+      free (esyms);
+      return NULL;
+    }
+
+  for (j = 0, psym = isyms;
+       j < number;
+       j++, psym++)
+    {
+      psym->st_name  = BYTE_GET (esyms[j].st_name);
+      psym->st_value = BYTE_GET (esyms[j].st_value);
+      psym->st_size  = BYTE_GET (esyms[j].st_size);
+      psym->st_shndx = BYTE_GET (esyms[j].st_shndx);
+      if (psym->st_shndx == SHN_XINDEX && shndx != NULL)
+       psym->st_shndx
+         = byte_get ((unsigned char *) &shndx[j], sizeof (shndx[j]));
+      psym->st_info  = BYTE_GET (esyms[j].st_info);
+      psym->st_other = BYTE_GET (esyms[j].st_other);
+    }
+
+  if (shndx)
+    free (shndx);
+  free (esyms);
+
+  return isyms;
+}
+
+static Elf_Internal_Sym *
+get_64bit_elf_symbols (file, section)
+     FILE *file;
+     Elf_Internal_Shdr *section;
+{
+  unsigned long number;
+  Elf64_External_Sym *esyms;
+  Elf_External_Sym_Shndx *shndx;
+  Elf_Internal_Sym *isyms;
+  Elf_Internal_Sym *psym;
+  unsigned int j;
+
+  esyms = ((Elf64_External_Sym *)
+          get_data (NULL, file, section->sh_offset,
+                    section->sh_size, _("symbols")));
+  if (!esyms)
+    return NULL;
+
+  shndx = NULL;
+  if (symtab_shndx_hdr != NULL
+      && (symtab_shndx_hdr->sh_link
+         == (unsigned long) SECTION_HEADER_NUM (section - section_headers)))
+    {
+      shndx = ((Elf_External_Sym_Shndx *)
+              get_data (NULL, file, symtab_shndx_hdr->sh_offset,
+                        symtab_shndx_hdr->sh_size, _("symtab shndx")));
+      if (!shndx)
+       {
+         free (esyms);
+         return NULL;
+       }
+    }
+
+  number = section->sh_size / section->sh_entsize;
+  isyms = (Elf_Internal_Sym *) malloc (number * sizeof (Elf_Internal_Sym));
+
+  if (isyms == NULL)
+    {
+      error (_("Out of memory\n"));
+      if (shndx)
+       free (shndx);
+      free (esyms);
+      return NULL;
+    }
+
+  for (j = 0, psym = isyms;
+       j < number;
+       j++, psym++)
+    {
+      psym->st_name  = BYTE_GET (esyms[j].st_name);
+      psym->st_info  = BYTE_GET (esyms[j].st_info);
+      psym->st_other = BYTE_GET (esyms[j].st_other);
+      psym->st_shndx = BYTE_GET (esyms[j].st_shndx);
+      if (psym->st_shndx == SHN_XINDEX && shndx != NULL)
+       psym->st_shndx
+         = byte_get ((unsigned char *) &shndx[j], sizeof (shndx[j]));
+      psym->st_value = BYTE_GET8 (esyms[j].st_value);
+      psym->st_size  = BYTE_GET8 (esyms[j].st_size);
+    }
+
+  if (shndx)
+    free (shndx);
+  free (esyms);
+
+  return isyms;
+}
+
+static const char *
+get_elf_section_flags (sh_flags)
+     bfd_vma sh_flags;
+{
+  static char buff[32];
+
+  *buff = 0;
+
+  while (sh_flags)
+    {
+      bfd_vma flag;
+
+      flag = sh_flags & - sh_flags;
+      sh_flags &= ~ flag;
+
+      switch (flag)
+       {
+       case SHF_WRITE:            strcat (buff, "W"); break;
+       case SHF_ALLOC:            strcat (buff, "A"); break;
+       case SHF_EXECINSTR:        strcat (buff, "X"); break;
+       case SHF_MERGE:            strcat (buff, "M"); break;
+       case SHF_STRINGS:          strcat (buff, "S"); break;
+       case SHF_INFO_LINK:        strcat (buff, "I"); break;
+       case SHF_LINK_ORDER:       strcat (buff, "L"); break;
+       case SHF_OS_NONCONFORMING: strcat (buff, "O"); break;
+       case SHF_GROUP:            strcat (buff, "G"); break;
+       case SHF_TLS:              strcat (buff, "T"); break;
+
+       default:
+         if (flag & SHF_MASKOS)
+           {
+             strcat (buff, "o");
+             sh_flags &= ~ SHF_MASKOS;
+           }
+         else if (flag & SHF_MASKPROC)
+           {
+             strcat (buff, "p");
+             sh_flags &= ~ SHF_MASKPROC;
+           }
+         else
+           strcat (buff, "x");
+         break;
+       }
+    }
+
+  return buff;
+}
+
+static int
+process_section_headers (file)
+     FILE *file;
+{
+  Elf_Internal_Shdr *section;
+  unsigned int i;
+
+  section_headers = NULL;
+
+  if (elf_header.e_shnum == 0)
+    {
+      if (do_sections)
+       printf (_("\nThere are no sections in this file.\n"));
+
+      return 1;
+    }
+
+  if (do_sections && !do_header)
+    printf (_("There are %d section headers, starting at offset 0x%lx:\n"),
+           elf_header.e_shnum, (unsigned long) elf_header.e_shoff);
+
+  if (is_32bit_elf)
+    {
+      if (! get_32bit_section_headers (file, elf_header.e_shnum))
+       return 0;
+    }
+  else if (! get_64bit_section_headers (file, elf_header.e_shnum))
+    return 0;
+
+  /* Read in the string table, so that we have names to display.  */
+  section = SECTION_HEADER (elf_header.e_shstrndx);
+
+  if (section->sh_size != 0)
+    {
+      string_table = (char *) get_data (NULL, file, section->sh_offset,
+                                       section->sh_size, _("string table"));
+
+      string_table_length = section->sh_size;
+    }
+
+  /* Scan the sections for the dynamic symbol table
+     and dynamic string table and debug sections.  */
+  dynamic_symbols = NULL;
+  dynamic_strings = NULL;
+  dynamic_syminfo = NULL;
+  symtab_shndx_hdr = NULL;
+
+  for (i = 0, section = section_headers;
+       i < elf_header.e_shnum;
+       i++, section++)
+    {
+      char *name = SECTION_NAME (section);
+
+      if (section->sh_type == SHT_DYNSYM)
+       {
+         if (dynamic_symbols != NULL)
+           {
+             error (_("File contains multiple dynamic symbol tables\n"));
+             continue;
+           }
+
+         num_dynamic_syms = section->sh_size / section->sh_entsize;
+         dynamic_symbols = GET_ELF_SYMBOLS (file, section);
+       }
+      else if (section->sh_type == SHT_STRTAB
+              && strcmp (name, ".dynstr") == 0)
+       {
+         if (dynamic_strings != NULL)
+           {
+             error (_("File contains multiple dynamic string tables\n"));
+             continue;
+           }
+
+         dynamic_strings = (char *) get_data (NULL, file, section->sh_offset,
+                                              section->sh_size,
+                                              _("dynamic strings"));
+       }
+      else if (section->sh_type == SHT_SYMTAB_SHNDX)
+       {
+         if (symtab_shndx_hdr != NULL)
+           {
+             error (_("File contains multiple symtab shndx tables\n"));
+             continue;
+           }
+         symtab_shndx_hdr = section;
+       }
+      else if ((do_debugging || do_debug_info || do_debug_abbrevs
+               || do_debug_lines || do_debug_pubnames || do_debug_aranges
+               || do_debug_frames || do_debug_macinfo || do_debug_str
+               || do_debug_loc)
+              && strncmp (name, ".debug_", 7) == 0)
+       {
+         name += 7;
+
+         if (do_debugging
+             || (do_debug_info     && (strcmp (name, "info") == 0))
+             || (do_debug_abbrevs  && (strcmp (name, "abbrev") == 0))
+             || (do_debug_lines    && (strcmp (name, "line") == 0))
+             || (do_debug_pubnames && (strcmp (name, "pubnames") == 0))
+             || (do_debug_aranges  && (strcmp (name, "aranges") == 0))
+             || (do_debug_frames   && (strcmp (name, "frame") == 0))
+             || (do_debug_macinfo  && (strcmp (name, "macinfo") == 0))
+             || (do_debug_str      && (strcmp (name, "str") == 0))
+             || (do_debug_loc      && (strcmp (name, "loc") == 0))
+             )
+           request_dump (i, DEBUG_DUMP);
+       }
+      /* linkonce section to be combined with .debug_info at link time.  */
+      else if ((do_debugging || do_debug_info)
+              && strncmp (name, ".gnu.linkonce.wi.", 17) == 0)
+       request_dump (i, DEBUG_DUMP);
+      else if (do_debug_frames && strcmp (name, ".eh_frame") == 0)
+       request_dump (i, DEBUG_DUMP);
+    }
+
+  if (! do_sections)
+    return 1;
+
+  if (elf_header.e_shnum > 1)
+    printf (_("\nSection Headers:\n"));
+  else
+    printf (_("\nSection Header:\n"));
+
+  if (is_32bit_elf)
+    printf
+      (_("  [Nr] Name              Type            Addr     Off    Size   ES Flg Lk Inf Al\n"));
+  else if (do_wide)
+    printf
+      (_("  [Nr] Name              Type            Address          Off    Size   ES Flg Lk Inf Al\n"));
+  else
+    {
+      printf (_("  [Nr] Name              Type             Address           Offset\n"));
+      printf (_("       Size              EntSize          Flags  Link  Info  Align\n"));
+    }
+
+  for (i = 0, section = section_headers;
+       i < elf_header.e_shnum;
+       i++, section++)
+    {
+      printf ("  [%2u] %-17.17s %-15.15s ",
+             SECTION_HEADER_NUM (i),
+             SECTION_NAME (section),
+             get_section_type_name (section->sh_type));
+
+      if (is_32bit_elf)
+       {
+         print_vma (section->sh_addr, LONG_HEX);
+
+         printf ( " %6.6lx %6.6lx %2.2lx",
+                  (unsigned long) section->sh_offset,
+                  (unsigned long) section->sh_size,
+                  (unsigned long) section->sh_entsize);
+
+         printf (" %3s ", get_elf_section_flags (section->sh_flags));
+
+         printf ("%2ld %3lx %2ld\n",
+                 (unsigned long) section->sh_link,
+                 (unsigned long) section->sh_info,
+                 (unsigned long) section->sh_addralign);
+       }
+      else if (do_wide)
+       {
+         print_vma (section->sh_addr, LONG_HEX);
+
+         if ((long) section->sh_offset == section->sh_offset)
+           printf (" %6.6lx", (unsigned long) section->sh_offset);
+         else
+           {
+             putchar (' ');
+             print_vma (section->sh_offset, LONG_HEX);
+           }
+
+         if ((unsigned long) section->sh_size == section->sh_size)
+           printf (" %6.6lx", (unsigned long) section->sh_size);
+         else
+           {
+             putchar (' ');
+             print_vma (section->sh_size, LONG_HEX);
+           }
+
+         if ((unsigned long) section->sh_entsize == section->sh_entsize)
+           printf (" %2.2lx", (unsigned long) section->sh_entsize);
+         else
+           {
+             putchar (' ');
+             print_vma (section->sh_entsize, LONG_HEX);
+           }
+
+         printf (" %3s ", get_elf_section_flags (section->sh_flags));
+
+         printf ("%2ld %3lx ",
+                 (unsigned long) section->sh_link,
+                 (unsigned long) section->sh_info);
+
+         if ((unsigned long) section->sh_addralign == section->sh_addralign)
+           printf ("%2ld\n", (unsigned long) section->sh_addralign);
+         else
+           {
+             print_vma (section->sh_addralign, DEC);
+             putchar ('\n');
+           }
+       }
+      else
+       {
+         putchar (' ');
+         print_vma (section->sh_addr, LONG_HEX);
+         if ((long) section->sh_offset == section->sh_offset)
+           printf ("  %8.8lx", (unsigned long) section->sh_offset);
+         else
+           {
+             printf ("  ");
+             print_vma (section->sh_offset, LONG_HEX);
+           }
+         printf ("\n       ");
+         print_vma (section->sh_size, LONG_HEX);
+         printf ("  ");
+         print_vma (section->sh_entsize, LONG_HEX);
+
+         printf (" %3s ", get_elf_section_flags (section->sh_flags));
+
+         printf ("     %2ld   %3lx     %ld\n",
+                 (unsigned long) section->sh_link,
+                 (unsigned long) section->sh_info,
+                 (unsigned long) section->sh_addralign);
+       }
+    }
+
+  printf (_("Key to Flags:\n\
+  W (write), A (alloc), X (execute), M (merge), S (strings)\n\
+  I (info), L (link order), G (group), x (unknown)\n\
+  O (extra OS processing required) o (OS specific), p (processor specific)\n"));
+
+  return 1;
+}
+
+struct
+{
+  const char *name;
+  int reloc;
+  int size;
+  int rela;
+} dynamic_relocations [] =
+{
+    { "REL", DT_REL, DT_RELSZ, FALSE },
+    { "RELA", DT_RELA, DT_RELASZ, TRUE },
+    { "PLT", DT_JMPREL, DT_PLTRELSZ, UNKNOWN }
+};
+
+/* Process the reloc section.  */
+static int
+process_relocs (file)
+     FILE *file;
+{
+  unsigned long rel_size;
+  unsigned long rel_offset;
+
+
+  if (!do_reloc)
+    return 1;
+
+  if (do_using_dynamic)
+    {
+      int is_rela;
+      const char *name;
+      int has_dynamic_reloc;
+      unsigned int i;
+
+      has_dynamic_reloc = 0;
+
+      for (i = 0; i < ARRAY_SIZE (dynamic_relocations); i++)
+       {
+         is_rela = dynamic_relocations [i].rela;
+         name = dynamic_relocations [i].name;
+         rel_size = dynamic_info [dynamic_relocations [i].size];
+         rel_offset = dynamic_info [dynamic_relocations [i].reloc];
+
+         has_dynamic_reloc |= rel_size;
+
+         if (is_rela == UNKNOWN)
+           {
+             if (dynamic_relocations [i].reloc == DT_JMPREL)
+               switch (dynamic_info[DT_PLTREL])
+                 {
+                 case DT_REL:
+                   is_rela = FALSE;
+                   break;
+                 case DT_RELA:
+                   is_rela = TRUE;
+                   break;
+                 }
+           }
+
+         if (rel_size)
+           {
+             printf
+               (_("\n'%s' relocation section at offset 0x%lx contains %ld bytes:\n"),
+                name, rel_offset, rel_size);
+
+             dump_relocations (file, rel_offset - loadaddr, rel_size,
+                               dynamic_symbols, num_dynamic_syms,
+                               dynamic_strings, is_rela);
+           }
+       }
+
+      if (! has_dynamic_reloc)
+       printf (_("\nThere are no dynamic relocations in this file.\n"));
+    }
+  else
+    {
+      Elf_Internal_Shdr *section;
+      unsigned long i;
+      int found = 0;
+
+      for (i = 0, section = section_headers;
+          i < elf_header.e_shnum;
+          i++, section++)
+       {
+         if (   section->sh_type != SHT_RELA
+             && section->sh_type != SHT_REL)
+           continue;
+
+         rel_offset = section->sh_offset;
+         rel_size   = section->sh_size;
+
+         if (rel_size)
+           {
+             Elf_Internal_Shdr *strsec;
+             Elf_Internal_Sym *symtab;
+             char *strtab;
+             int is_rela;
+             unsigned long nsyms;
+
+             printf (_("\nRelocation section "));
+
+             if (string_table == NULL)
+               printf ("%d", section->sh_name);
+             else
+               printf (_("'%s'"), SECTION_NAME (section));
+
+             printf (_(" at offset 0x%lx contains %lu entries:\n"),
+                rel_offset, (unsigned long) (rel_size / section->sh_entsize));
+
+             symtab = NULL;
+             strtab = NULL;
+             nsyms = 0;
+             if (section->sh_link)
+               {
+                 Elf_Internal_Shdr *symsec;
+
+                 symsec = SECTION_HEADER (section->sh_link);
+                 nsyms = symsec->sh_size / symsec->sh_entsize;
+                 symtab = GET_ELF_SYMBOLS (file, symsec);
+
+                 if (symtab == NULL)
+                   continue;
+
+                 strsec = SECTION_HEADER (symsec->sh_link);
+
+                 strtab = (char *) get_data (NULL, file, strsec->sh_offset,
+                                             strsec->sh_size,
+                                             _("string table"));
+               }
+             is_rela = section->sh_type == SHT_RELA;
+
+             dump_relocations (file, rel_offset, rel_size,
+                               symtab, nsyms, strtab, is_rela);
+
+             if (strtab)
+               free (strtab);
+             if (symtab)
+               free (symtab);
+
+             found = 1;
+           }
+       }
+
+      if (! found)
+       printf (_("\nThere are no relocations in this file.\n"));
+    }
+
+  return 1;
+}
+
+#include "unwind-ia64.h"
+
+/* An absolute address consists of a section and an offset.  If the
+   section is NULL, the offset itself is the address, otherwise, the
+   address equals to LOAD_ADDRESS(section) + offset.  */
+
+struct absaddr
+  {
+    unsigned short section;
+    bfd_vma offset;
+  };
+
+struct unw_aux_info
+  {
+    struct unw_table_entry
+      {
+       struct absaddr start;
+       struct absaddr end;
+       struct absaddr info;
+      }
+    *table;                    /* Unwind table.  */
+    unsigned long table_len;   /* Length of unwind table.  */
+    unsigned char *info;       /* Unwind info.  */
+    unsigned long info_size;   /* Size of unwind info.  */
+    bfd_vma info_addr;         /* starting address of unwind info.  */
+    bfd_vma seg_base;          /* Starting address of segment.  */
+    Elf_Internal_Sym *symtab;  /* The symbol table.  */
+    unsigned long nsyms;       /* Number of symbols.  */
+    char *strtab;              /* The string table.  */
+    unsigned long strtab_size; /* Size of string table.  */
+  };
+
+static void find_symbol_for_address
+  PARAMS ((struct unw_aux_info *, struct absaddr, const char **, bfd_vma *));
+static void dump_ia64_unwind
+  PARAMS ((struct unw_aux_info *));
+static int slurp_ia64_unwind_table
+  PARAMS ((FILE *, struct unw_aux_info *, Elf_Internal_Shdr *));
+
+static void
+find_symbol_for_address (aux, addr, symname, offset)
+     struct unw_aux_info *aux;
+     struct absaddr addr;
+     const char **symname;
+     bfd_vma *offset;
+{
+  bfd_vma dist = (bfd_vma) 0x100000;
+  Elf_Internal_Sym *sym, *best = NULL;
+  unsigned long i;
+
+  for (i = 0, sym = aux->symtab; i < aux->nsyms; ++i, ++sym)
+    {
+      if (ELF_ST_TYPE (sym->st_info) == STT_FUNC
+         && sym->st_name != 0
+         && (addr.section == SHN_UNDEF || addr.section == sym->st_shndx)
+         && addr.offset >= sym->st_value
+         && addr.offset - sym->st_value < dist)
+       {
+         best = sym;
+         dist = addr.offset - sym->st_value;
+         if (!dist)
+           break;
+       }
+    }
+  if (best)
+    {
+      *symname = (best->st_name >= aux->strtab_size
+                 ? "<corrupt>" : aux->strtab + best->st_name);
+      *offset = dist;
+      return;
+    }
+  *symname = NULL;
+  *offset = addr.offset;
+}
+
+static void
+dump_ia64_unwind (aux)
+     struct unw_aux_info *aux;
+{
+  bfd_vma addr_size;
+  struct unw_table_entry *tp;
+  int in_body;
+
+  addr_size = is_32bit_elf ? 4 : 8;
+
+  for (tp = aux->table; tp < aux->table + aux->table_len; ++tp)
+    {
+      bfd_vma stamp;
+      bfd_vma offset;
+      const unsigned char *dp;
+      const unsigned char *head;
+      const char *procname;
+
+      find_symbol_for_address (aux, tp->start, &procname, &offset);
+
+      fputs ("\n<", stdout);
+
+      if (procname)
+       {
+         fputs (procname, stdout);
+
+         if (offset)
+           printf ("+%lx", (unsigned long) offset);
+       }
+
+      fputs (">: [", stdout);
+      print_vma (tp->start.offset, PREFIX_HEX);
+      fputc ('-', stdout);
+      print_vma (tp->end.offset, PREFIX_HEX);
+      printf ("], info at +0x%lx\n",
+             (unsigned long) (tp->info.offset - aux->seg_base));
+
+      head = aux->info + (tp->info.offset - aux->info_addr);
+      stamp = BYTE_GET8 ((unsigned char *) head);
+
+      printf ("  v%u, flags=0x%lx (%s%s), len=%lu bytes\n",
+             (unsigned) UNW_VER (stamp),
+             (unsigned long) ((stamp & UNW_FLAG_MASK) >> 32),
+             UNW_FLAG_EHANDLER (stamp) ? " ehandler" : "",
+             UNW_FLAG_UHANDLER (stamp) ? " uhandler" : "",
+             (unsigned long) (addr_size * UNW_LENGTH (stamp)));
+
+      if (UNW_VER (stamp) != 1)
+       {
+         printf ("\tUnknown version.\n");
+         continue;
+       }
+
+      in_body = 0;
+      for (dp = head + 8; dp < head + 8 + addr_size * UNW_LENGTH (stamp);)
+       dp = unw_decode (dp, in_body, & in_body);
+    }
+}
+
+static int
+slurp_ia64_unwind_table (file, aux, sec)
+     FILE *file;
+     struct unw_aux_info *aux;
+     Elf_Internal_Shdr *sec;
+{
+  unsigned long size, addr_size, nrelas, i;
+  Elf_Internal_Phdr *prog_hdrs, *seg;
+  struct unw_table_entry *tep;
+  Elf_Internal_Shdr *relsec;
+  Elf_Internal_Rela *rela, *rp;
+  unsigned char *table, *tp;
+  Elf_Internal_Sym *sym;
+  const char *relname;
+  int result;
+
+  addr_size = is_32bit_elf ? 4 : 8;
+
+  /* First, find the starting address of the segment that includes
+     this section: */
+
+  if (elf_header.e_phnum)
+    {
+      prog_hdrs = (Elf_Internal_Phdr *)
+       xmalloc (elf_header.e_phnum * sizeof (Elf_Internal_Phdr));
+
+      if (is_32bit_elf)
+       result = get_32bit_program_headers (file, prog_hdrs);
+      else
+       result = get_64bit_program_headers (file, prog_hdrs);
+
+      if (!result)
+       {
+         free (prog_hdrs);
+         return 0;
+       }
+
+      for (seg = prog_hdrs; seg < prog_hdrs + elf_header.e_phnum; ++seg)
+       {
+         if (seg->p_type != PT_LOAD)
+           continue;
+
+         if (sec->sh_addr >= seg->p_vaddr
+             && (sec->sh_addr + sec->sh_size <= seg->p_vaddr + seg->p_memsz))
+           {
+             aux->seg_base = seg->p_vaddr;
+             break;
+           }
+       }
+
+      free (prog_hdrs);
+    }
+
+  /* Second, build the unwind table from the contents of the unwind section:  */
+  size = sec->sh_size;
+  table = (char *) get_data (NULL, file, sec->sh_offset,
+                            size, _("unwind table"));
+  if (!table)
+    return 0;
+
+  tep = aux->table = xmalloc (size / (3 * addr_size) * sizeof (aux->table[0]));
+  for (tp = table; tp < table + size; tp += 3 * addr_size, ++tep)
+    {
+      tep->start.section = SHN_UNDEF;
+      tep->end.section   = SHN_UNDEF;
+      tep->info.section  = SHN_UNDEF;
+      if (is_32bit_elf)
+       {
+         tep->start.offset = byte_get ((unsigned char *) tp + 0, 4);
+         tep->end.offset   = byte_get ((unsigned char *) tp + 4, 4);
+         tep->info.offset  = byte_get ((unsigned char *) tp + 8, 4);
+       }
+      else
+       {
+         tep->start.offset = BYTE_GET8 ((unsigned char *) tp +  0);
+         tep->end.offset   = BYTE_GET8 ((unsigned char *) tp +  8);
+         tep->info.offset  = BYTE_GET8 ((unsigned char *) tp + 16);
+       }
+      tep->start.offset += aux->seg_base;
+      tep->end.offset   += aux->seg_base;
+      tep->info.offset  += aux->seg_base;
+    }
+  free (table);
+
+  /* Third, apply any relocations to the unwind table: */
+
+  for (relsec = section_headers;
+       relsec < section_headers + elf_header.e_shnum;
+       ++relsec)
+    {
+      if (relsec->sh_type != SHT_RELA
+         || SECTION_HEADER (relsec->sh_info) != sec)
+       continue;
+
+      if (!slurp_rela_relocs (file, relsec->sh_offset, relsec->sh_size,
+                             & rela, & nrelas))
+       return 0;
+
+      for (rp = rela; rp < rela + nrelas; ++rp)
+       {
+         if (is_32bit_elf)
+           {
+             relname = elf_ia64_reloc_type (ELF32_R_TYPE (rp->r_info));
+             sym = aux->symtab + ELF32_R_SYM (rp->r_info);
+
+             if (ELF32_ST_TYPE (sym->st_info) != STT_SECTION)
+               {
+                 warn (_("Skipping unexpected symbol type %u\n"),
+                       ELF32_ST_TYPE (sym->st_info));
+                 continue;
+               }
+           }
+         else
+           {
+             relname = elf_ia64_reloc_type (ELF64_R_TYPE (rp->r_info));
+             sym = aux->symtab + ELF64_R_SYM (rp->r_info);
+
+             if (ELF64_ST_TYPE (sym->st_info) != STT_SECTION)
+               {
+                 warn (_("Skipping unexpected symbol type %u\n"),
+                       ELF64_ST_TYPE (sym->st_info));
+                 continue;
+               }
+           }
+
+         if (strncmp (relname, "R_IA64_SEGREL", 13) != 0)
+           {
+             warn (_("Skipping unexpected relocation type %s\n"), relname);
+             continue;
+           }
+
+         i = rp->r_offset / (3 * addr_size);
+
+         switch (rp->r_offset/addr_size % 3)
+           {
+           case 0:
+             aux->table[i].start.section = sym->st_shndx;
+             aux->table[i].start.offset += rp->r_addend;
+             break;
+           case 1:
+             aux->table[i].end.section   = sym->st_shndx;
+             aux->table[i].end.offset   += rp->r_addend;
+             break;
+           case 2:
+             aux->table[i].info.section  = sym->st_shndx;
+             aux->table[i].info.offset  += rp->r_addend;
+             break;
+           default:
+             break;
+           }
+       }
+
+      free (rela);
+    }
+
+  aux->table_len = size / (3 * addr_size);
+  return 1;
+}
+
+static int
+process_unwind (file)
+     FILE *file;
+{
+  Elf_Internal_Shdr *sec, *unwsec = NULL, *strsec;
+  unsigned long i, addr_size, unwcount = 0, unwstart = 0;
+  struct unw_aux_info aux;
+
+  if (!do_unwind)
+    return 1;
+
+  if (elf_header.e_machine != EM_IA_64)
+    {
+      printf (_("\nThere are no unwind sections in this file.\n"));
+      return 1;
+    }
+
+  memset (& aux, 0, sizeof (aux));
+
+  addr_size = is_32bit_elf ? 4 : 8;
+
+  for (i = 0, sec = section_headers; i < elf_header.e_shnum; ++i, ++sec)
+    {
+      if (sec->sh_type == SHT_SYMTAB)
+       {
+         aux.nsyms = sec->sh_size / sec->sh_entsize;
+         aux.symtab = GET_ELF_SYMBOLS (file, sec);
+
+         strsec = SECTION_HEADER (sec->sh_link);
+         aux.strtab_size = strsec->sh_size;
+         aux.strtab = (char *) get_data (NULL, file, strsec->sh_offset,
+                                         aux.strtab_size, _("string table"));
+       }
+      else if (sec->sh_type == SHT_IA_64_UNWIND)
+       unwcount++;
+    }
+
+  if (!unwcount)
+    printf (_("\nThere are no unwind sections in this file.\n"));
+
+  while (unwcount-- > 0)
+    {
+      char *suffix;
+      size_t len, len2;
+
+      for (i = unwstart, sec = section_headers + unwstart;
+          i < elf_header.e_shnum; ++i, ++sec)
+       if (sec->sh_type == SHT_IA_64_UNWIND)
+         {
+           unwsec = sec;
+           break;
+         }
+
+      unwstart = i + 1;
+      len = sizeof (ELF_STRING_ia64_unwind_once) - 1;
+
+      if (strncmp (SECTION_NAME (unwsec), ELF_STRING_ia64_unwind_once,
+                  len) == 0)
+       {
+         /* .gnu.linkonce.ia64unw.FOO -> .gnu.linkonce.ia64unwi.FOO */
+         len2 = sizeof (ELF_STRING_ia64_unwind_info_once) - 1;
+         suffix = SECTION_NAME (unwsec) + len;
+         for (i = 0, sec = section_headers; i < elf_header.e_shnum;
+              ++i, ++sec)
+           if (strncmp (SECTION_NAME (sec),
+                        ELF_STRING_ia64_unwind_info_once, len2) == 0
+               && strcmp (SECTION_NAME (sec) + len2, suffix) == 0)
+             break;
+       }
+      else
+       {
+         /* .IA_64.unwindFOO -> .IA_64.unwind_infoFOO
+            .IA_64.unwind or BAR -> .IA_64.unwind_info */
+         len = sizeof (ELF_STRING_ia64_unwind) - 1;
+         len2 = sizeof (ELF_STRING_ia64_unwind_info) - 1;
+         suffix = "";
+         if (strncmp (SECTION_NAME (unwsec), ELF_STRING_ia64_unwind,
+                      len) == 0)
+           suffix = SECTION_NAME (unwsec) + len;
+         for (i = 0, sec = section_headers; i < elf_header.e_shnum;
+              ++i, ++sec)
+           if (strncmp (SECTION_NAME (sec),
+                        ELF_STRING_ia64_unwind_info, len2) == 0
+               && strcmp (SECTION_NAME (sec) + len2, suffix) == 0)
+             break;
+       }
+
+      if (i == elf_header.e_shnum)
+       {
+         printf (_("\nCould not find unwind info section for "));
+
+         if (string_table == NULL)
+           printf ("%d", unwsec->sh_name);
+         else
+           printf (_("'%s'"), SECTION_NAME (unwsec));
+       }
+      else
+       {
+         aux.info_size = sec->sh_size;
+         aux.info_addr = sec->sh_addr;
+         aux.info = (char *) get_data (NULL, file, sec->sh_offset,
+                                       aux.info_size, _("unwind info"));
+
+         printf (_("\nUnwind section "));
+
+         if (string_table == NULL)
+           printf ("%d", unwsec->sh_name);
+         else
+           printf (_("'%s'"), SECTION_NAME (unwsec));
+
+         printf (_(" at offset 0x%lx contains %lu entries:\n"),
+                 (unsigned long) unwsec->sh_offset,
+                 (unsigned long) (unwsec->sh_size / (3 * addr_size)));
+
+         (void) slurp_ia64_unwind_table (file, & aux, unwsec);
+
+         if (aux.table_len > 0)
+           dump_ia64_unwind (& aux);
+
+         if (aux.table)
+           free ((char *) aux.table);
+         if (aux.info)
+           free ((char *) aux.info);
+         aux.table = NULL;
+         aux.info = NULL;
+       }
+    }
+
+  if (aux.symtab)
+    free (aux.symtab);
+  if (aux.strtab)
+    free ((char *) aux.strtab);
+
+  return 1;
+}
+
+static void
+dynamic_segment_mips_val (entry)
+     Elf_Internal_Dyn *entry;
+{
+  switch (entry->d_tag)
+    {
+    default:
+      printf ("%#lx\n", (long) entry->d_un.d_ptr);
+    }
+}
+
+
+static void
+dynamic_segment_parisc_val (entry)
+     Elf_Internal_Dyn *entry;
+{
+  switch (entry->d_tag)
+    {
+    default:
+      print_vma (entry->d_un.d_ptr, PREFIX_HEX);
+      break;
+    }
+  putchar ('\n');
+}
+
+static void
+dynamic_segment_ia64_val (entry)
+     Elf_Internal_Dyn *entry;
+{
+}
+
+static int
+get_32bit_dynamic_segment (file)
+     FILE *file;
+{
+  Elf32_External_Dyn *edyn;
+  Elf_Internal_Dyn *entry;
+  bfd_size_type i;
+
+  edyn = (Elf32_External_Dyn *) get_data (NULL, file, dynamic_addr,
+                                         dynamic_size, _("dynamic segment"));
+  if (!edyn)
+    return 0;
+
+  /* SGI's ELF has more than one section in the DYNAMIC segment.  Determine
+     how large this .dynamic is now.  We can do this even before the byte
+     swapping since the DT_NULL tag is recognizable.  */
+  dynamic_size = 0;
+  while (*(Elf32_Word *) edyn[dynamic_size++].d_tag != DT_NULL)
+    ;
+
+  dynamic_segment = (Elf_Internal_Dyn *)
+    malloc (dynamic_size * sizeof (Elf_Internal_Dyn));
+
+  if (dynamic_segment == NULL)
+    {
+      error (_("Out of memory\n"));
+      free (edyn);
+      return 0;
+    }
+
+  for (i = 0, entry = dynamic_segment;
+       i < dynamic_size;
+       i++, entry++)
+    {
+      entry->d_tag      = BYTE_GET (edyn[i].d_tag);
+      entry->d_un.d_val = BYTE_GET (edyn[i].d_un.d_val);
+    }
+
+  free (edyn);
+
+  return 1;
+}
+
+static int
+get_64bit_dynamic_segment (file)
+     FILE *file;
+{
+  Elf64_External_Dyn *edyn;
+  Elf_Internal_Dyn *entry;
+  bfd_size_type i;
+
+  edyn = (Elf64_External_Dyn *) get_data (NULL, file, dynamic_addr,
+                                         dynamic_size, _("dynamic segment"));
+  if (!edyn)
+    return 0;
+
+  /* SGI's ELF has more than one section in the DYNAMIC segment.  Determine
+     how large this .dynamic is now.  We can do this even before the byte
+     swapping since the DT_NULL tag is recognizable.  */
+  dynamic_size = 0;
+  while (*(bfd_vma *) edyn[dynamic_size++].d_tag != DT_NULL)
+    ;
+
+  dynamic_segment = (Elf_Internal_Dyn *)
+    malloc (dynamic_size * sizeof (Elf_Internal_Dyn));
+
+  if (dynamic_segment == NULL)
+    {
+      error (_("Out of memory\n"));
+      free (edyn);
+      return 0;
+    }
+
+  for (i = 0, entry = dynamic_segment;
+       i < dynamic_size;
+       i++, entry++)
+    {
+      entry->d_tag      = BYTE_GET8 (edyn[i].d_tag);
+      entry->d_un.d_val = BYTE_GET8 (edyn[i].d_un.d_val);
+    }
+
+  free (edyn);
+
+  return 1;
+}
+
+static const char *
+get_dynamic_flags (flags)
+     bfd_vma flags;
+{
+  static char buff[128];
+  char *p = buff;
+
+  *p = '\0';
+  while (flags)
+    {
+      bfd_vma flag;
+
+      flag = flags & - flags;
+      flags &= ~ flag;
+
+      if (p != buff)
+       *p++ = ' ';
+
+      switch (flag)
+       {
+       case DF_ORIGIN:         strcpy (p, "ORIGIN"); break;
+       case DF_SYMBOLIC:       strcpy (p, "SYMBOLIC"); break;
+       case DF_TEXTREL:        strcpy (p, "TEXTREL"); break;
+       case DF_BIND_NOW:       strcpy (p, "BIND_NOW"); break;
+       case DF_STATIC_TLS:     strcpy (p, "STATIC_TLS"); break;
+       default:                strcpy (p, "unknown"); break;
+       }
+
+      p = strchr (p, '\0');
+    }
+  return buff;
+}
+
+/* Parse and display the contents of the dynamic segment.  */
+static int
+process_dynamic_segment (file)
+     FILE *file;
+{
+  Elf_Internal_Dyn *entry;
+  bfd_size_type i;
+
+  if (dynamic_size == 0)
+    {
+      if (do_dynamic)
+       printf (_("\nThere is no dynamic segment in this file.\n"));
+
+      return 1;
+    }
+
+  if (is_32bit_elf)
+    {
+      if (! get_32bit_dynamic_segment (file))
+       return 0;
+    }
+  else if (! get_64bit_dynamic_segment (file))
+    return 0;
+
+  /* Find the appropriate symbol table.  */
+  if (dynamic_symbols == NULL)
+    {
+      for (i = 0, entry = dynamic_segment;
+          i < dynamic_size;
+          ++i, ++entry)
+       {
+         Elf_Internal_Shdr section;
+
+         if (entry->d_tag != DT_SYMTAB)
+           continue;
+
+         dynamic_info[DT_SYMTAB] = entry->d_un.d_val;
+
+         /* Since we do not know how big the symbol table is,
+            we default to reading in the entire file (!) and
+            processing that.  This is overkill, I know, but it
+            should work.  */
+         section.sh_offset = entry->d_un.d_val - loadaddr;
+
+         if (fseek (file, 0, SEEK_END))
+           error (_("Unable to seek to end of file!"));
+
+         section.sh_size = ftell (file) - section.sh_offset;
+         if (is_32bit_elf)
+           section.sh_entsize = sizeof (Elf32_External_Sym);
+         else
+           section.sh_entsize = sizeof (Elf64_External_Sym);
+
+         num_dynamic_syms = section.sh_size / section.sh_entsize;
+         if (num_dynamic_syms < 1)
+           {
+             error (_("Unable to determine the number of symbols to load\n"));
+             continue;
+           }
+
+         dynamic_symbols = GET_ELF_SYMBOLS (file, &section);
+       }
+    }
+
+  /* Similarly find a string table.  */
+  if (dynamic_strings == NULL)
+    {
+      for (i = 0, entry = dynamic_segment;
+          i < dynamic_size;
+          ++i, ++entry)
+       {
+         unsigned long offset;
+         long str_tab_len;
+
+         if (entry->d_tag != DT_STRTAB)
+           continue;
+
+         dynamic_info[DT_STRTAB] = entry->d_un.d_val;
+
+         /* Since we do not know how big the string table is,
+            we default to reading in the entire file (!) and
+            processing that.  This is overkill, I know, but it
+            should work.  */
+
+         offset = entry->d_un.d_val - loadaddr;
+         if (fseek (file, 0, SEEK_END))
+           error (_("Unable to seek to end of file\n"));
+         str_tab_len = ftell (file) - offset;
+
+         if (str_tab_len < 1)
+           {
+             error
+               (_("Unable to determine the length of the dynamic string table\n"));
+             continue;
+           }
+
+         dynamic_strings = (char *) get_data (NULL, file, offset, str_tab_len,
+                                              _("dynamic string table"));
+         break;
+       }
+    }
+
+  /* And find the syminfo section if available.  */
+  if (dynamic_syminfo == NULL)
+    {
+      unsigned long syminsz = 0;
+
+      for (i = 0, entry = dynamic_segment;
+          i < dynamic_size;
+          ++i, ++entry)
+       {
+         if (entry->d_tag == DT_SYMINENT)
+           {
+             /* Note: these braces are necessary to avoid a syntax
+                error from the SunOS4 C compiler.  */
+             assert (sizeof (Elf_External_Syminfo) == entry->d_un.d_val);
+           }
+         else if (entry->d_tag == DT_SYMINSZ)
+           syminsz = entry->d_un.d_val;
+         else if (entry->d_tag == DT_SYMINFO)
+           dynamic_syminfo_offset = entry->d_un.d_val - loadaddr;
+       }
+
+      if (dynamic_syminfo_offset != 0 && syminsz != 0)
+       {
+         Elf_External_Syminfo *extsyminfo;
+         Elf_Internal_Syminfo *syminfo;
+
+         /* There is a syminfo section.  Read the data.  */
+         extsyminfo = ((Elf_External_Syminfo *)
+                       get_data (NULL, file, dynamic_syminfo_offset,
+                                 syminsz, _("symbol information")));
+         if (!extsyminfo)
+           return 0;
+
+         dynamic_syminfo = (Elf_Internal_Syminfo *) malloc (syminsz);
+         if (dynamic_syminfo == NULL)
+           {
+             error (_("Out of memory\n"));
+             return 0;
+           }
+
+         dynamic_syminfo_nent = syminsz / sizeof (Elf_External_Syminfo);
+         for (i = 0, syminfo = dynamic_syminfo; i < dynamic_syminfo_nent;
+              ++i, ++syminfo)
+           {
+             syminfo->si_boundto = BYTE_GET (extsyminfo[i].si_boundto);
+             syminfo->si_flags = BYTE_GET (extsyminfo[i].si_flags);
+           }
+
+         free (extsyminfo);
+       }
+    }
+
+  if (do_dynamic && dynamic_addr)
+    printf (_("\nDynamic segment at offset 0x%lx contains %ld entries:\n"),
+           dynamic_addr, (long) dynamic_size);
+  if (do_dynamic)
+    printf (_("  Tag        Type                         Name/Value\n"));
+
+  for (i = 0, entry = dynamic_segment;
+       i < dynamic_size;
+       i++, entry++)
+    {
+      if (do_dynamic)
+       {
+         const char *dtype;
+
+         putchar (' ');
+         print_vma (entry->d_tag, FULL_HEX);
+         dtype = get_dynamic_type (entry->d_tag);
+         printf (" (%s)%*s", dtype,
+                 ((is_32bit_elf ? 27 : 19)
+                  - (int) strlen (dtype)),
+                 " ");
+       }
+
+      switch (entry->d_tag)
+       {
+       case DT_FLAGS:
+         if (do_dynamic)
+           puts (get_dynamic_flags (entry->d_un.d_val));
+         break;
+
+       case DT_AUXILIARY:
+       case DT_FILTER:
+       case DT_CONFIG:
+       case DT_DEPAUDIT:
+       case DT_AUDIT:
+         if (do_dynamic)
+           {
+             switch (entry->d_tag)
+               {
+               case DT_AUXILIARY:
+                 printf (_("Auxiliary library"));
+                 break;
+
+               case DT_FILTER:
+                 printf (_("Filter library"));
+                 break;
+
+               case DT_CONFIG:
+                 printf (_("Configuration file"));
+                 break;
+
+               case DT_DEPAUDIT:
+                 printf (_("Dependency audit library"));
+                 break;
+
+               case DT_AUDIT:
+                 printf (_("Audit library"));
+                 break;
+               }
+
+             if (dynamic_strings)
+               printf (": [%s]\n", dynamic_strings + entry->d_un.d_val);
+             else
+               {
+                 printf (": ");
+                 print_vma (entry->d_un.d_val, PREFIX_HEX);
+                 putchar ('\n');
+               }
+           }
+         break;
+
+       case DT_FEATURE:
+         if (do_dynamic)
+           {
+             printf (_("Flags:"));
+
+             if (entry->d_un.d_val == 0)
+               printf (_(" None\n"));
+             else
+               {
+                 unsigned long int val = entry->d_un.d_val;
+
+                 if (val & DTF_1_PARINIT)
+                   {
+                     printf (" PARINIT");
+                     val ^= DTF_1_PARINIT;
+                   }
+                 if (val & DTF_1_CONFEXP)
+                   {
+                     printf (" CONFEXP");
+                     val ^= DTF_1_CONFEXP;
+                   }
+                 if (val != 0)
+                   printf (" %lx", val);
+                 puts ("");
+               }
+           }
+         break;
+
+       case DT_POSFLAG_1:
+         if (do_dynamic)
+           {
+             printf (_("Flags:"));
+
+             if (entry->d_un.d_val == 0)
+               printf (_(" None\n"));
+             else
+               {
+                 unsigned long int val = entry->d_un.d_val;
+
+                 if (val & DF_P1_LAZYLOAD)
+                   {
+                     printf (" LAZYLOAD");
+                     val ^= DF_P1_LAZYLOAD;
+                   }
+                 if (val & DF_P1_GROUPPERM)
+                   {
+                     printf (" GROUPPERM");
+                     val ^= DF_P1_GROUPPERM;
+                   }
+                 if (val != 0)
+                   printf (" %lx", val);
+                 puts ("");
+               }
+           }
+         break;
+
+       case DT_FLAGS_1:
+         if (do_dynamic)
+           {
+             printf (_("Flags:"));
+             if (entry->d_un.d_val == 0)
+               printf (_(" None\n"));
+             else
+               {
+                 unsigned long int val = entry->d_un.d_val;
+
+                 if (val & DF_1_NOW)
+                   {
+                     printf (" NOW");
+                     val ^= DF_1_NOW;
+                   }
+                 if (val & DF_1_GLOBAL)
+                   {
+                     printf (" GLOBAL");
+                     val ^= DF_1_GLOBAL;
+                   }
+                 if (val & DF_1_GROUP)
+                   {
+                     printf (" GROUP");
+                     val ^= DF_1_GROUP;
+                   }
+                 if (val & DF_1_NODELETE)
+                   {
+                     printf (" NODELETE");
+                     val ^= DF_1_NODELETE;
+                   }
+                 if (val & DF_1_LOADFLTR)
+                   {
+                     printf (" LOADFLTR");
+                     val ^= DF_1_LOADFLTR;
+                   }
+                 if (val & DF_1_INITFIRST)
+                   {
+                     printf (" INITFIRST");
+                     val ^= DF_1_INITFIRST;
+                   }
+                 if (val & DF_1_NOOPEN)
+                   {
+                     printf (" NOOPEN");
+                     val ^= DF_1_NOOPEN;
+                   }
+                 if (val & DF_1_ORIGIN)
+                   {
+                     printf (" ORIGIN");
+                     val ^= DF_1_ORIGIN;
+                   }
+                 if (val & DF_1_DIRECT)
+                   {
+                     printf (" DIRECT");
+                     val ^= DF_1_DIRECT;
+                   }
+                 if (val & DF_1_TRANS)
+                   {
+                     printf (" TRANS");
+                     val ^= DF_1_TRANS;
+                   }
+                 if (val & DF_1_INTERPOSE)
+                   {
+                     printf (" INTERPOSE");
+                     val ^= DF_1_INTERPOSE;
+                   }
+                 if (val & DF_1_NODEFLIB)
+                   {
+                     printf (" NODEFLIB");
+                     val ^= DF_1_NODEFLIB;
+                   }
+                 if (val & DF_1_NODUMP)
+                   {
+                     printf (" NODUMP");
+                     val ^= DF_1_NODUMP;
+                   }
+                 if (val & DF_1_CONLFAT)
+                   {
+                     printf (" CONLFAT");
+                     val ^= DF_1_CONLFAT;
+                   }
+                 if (val != 0)
+                   printf (" %lx", val);
+                 puts ("");
+               }
+           }
+         break;
+
+       case DT_PLTREL:
+         dynamic_info[entry->d_tag] = entry->d_un.d_val;
+         if (do_dynamic)
+           puts (get_dynamic_type (entry->d_un.d_val));
+         break;
+
+       case DT_NULL    :
+       case DT_NEEDED  :
+       case DT_PLTGOT  :
+       case DT_HASH    :
+       case DT_STRTAB  :
+       case DT_SYMTAB  :
+       case DT_RELA    :
+       case DT_INIT    :
+       case DT_FINI    :
+       case DT_SONAME  :
+       case DT_RPATH   :
+       case DT_SYMBOLIC:
+       case DT_REL     :
+       case DT_DEBUG   :
+       case DT_TEXTREL :
+       case DT_JMPREL  :
+       case DT_RUNPATH :
+         dynamic_info[entry->d_tag] = entry->d_un.d_val;
+
+         if (do_dynamic)
+           {
+             char *name;
+
+             if (dynamic_strings == NULL)
+               name = NULL;
+             else
+               name = dynamic_strings + entry->d_un.d_val;
+
+             if (name)
+               {
+                 switch (entry->d_tag)
+                   {
+                   case DT_NEEDED:
+                     printf (_("Shared library: [%s]"), name);
+
+                     if (strcmp (name, program_interpreter) == 0)
+                       printf (_(" program interpreter"));
+                     break;
+
+                   case DT_SONAME:
+                     printf (_("Library soname: [%s]"), name);
+                     break;
+
+                   case DT_RPATH:
+                     printf (_("Library rpath: [%s]"), name);
+                     break;
+
+                   case DT_RUNPATH:
+                     printf (_("Library runpath: [%s]"), name);
+                     break;
+
+                   default:
+                     print_vma (entry->d_un.d_val, PREFIX_HEX);
+                     break;
+                   }
+               }
+             else
+               print_vma (entry->d_un.d_val, PREFIX_HEX);
+
+             putchar ('\n');
+           }
+         break;
+
+       case DT_PLTRELSZ:
+       case DT_RELASZ  :
+       case DT_STRSZ   :
+       case DT_RELSZ   :
+       case DT_RELAENT :
+       case DT_SYMENT  :
+       case DT_RELENT  :
+         dynamic_info[entry->d_tag] = entry->d_un.d_val;
+       case DT_PLTPADSZ:
+       case DT_MOVEENT :
+       case DT_MOVESZ  :
+       case DT_INIT_ARRAYSZ:
+       case DT_FINI_ARRAYSZ:
+       case DT_GNU_CONFLICTSZ:
+       case DT_GNU_LIBLISTSZ:
+         if (do_dynamic)
+           {
+             print_vma (entry->d_un.d_val, UNSIGNED);
+             printf (" (bytes)\n");
+           }
+         break;
+
+       case DT_VERDEFNUM:
+       case DT_VERNEEDNUM:
+       case DT_RELACOUNT:
+       case DT_RELCOUNT:
+         if (do_dynamic)
+           {
+             print_vma (entry->d_un.d_val, UNSIGNED);
+             putchar ('\n');
+           }
+         break;
+
+       case DT_SYMINSZ:
+       case DT_SYMINENT:
+       case DT_SYMINFO:
+       case DT_USED:
+       case DT_INIT_ARRAY:
+       case DT_FINI_ARRAY:
+         if (do_dynamic)
+           {
+             if (dynamic_strings != NULL && entry->d_tag == DT_USED)
+               {
+                 char *name;
+
+                 name = dynamic_strings + entry->d_un.d_val;
+
+                 if (*name)
+                   {
+                     printf (_("Not needed object: [%s]\n"), name);
+                     break;
+                   }
+               }
+
+             print_vma (entry->d_un.d_val, PREFIX_HEX);
+             putchar ('\n');
+           }
+         break;
+
+       case DT_BIND_NOW:
+         /* The value of this entry is ignored.  */
+         if (do_dynamic)
+           putchar ('\n');
+         break;
+
+       case DT_GNU_PRELINKED:
+         if (do_dynamic)
+           {
+             struct tm *tmp;
+             time_t the_time = entry->d_un.d_val;
+
+             tmp = gmtime (&the_time);
+             printf ("%04u-%02u-%02uT%02u:%02u:%02u\n",
+                     tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
+                     tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
+
+           }
+         break;
+
+       default:
+         if ((entry->d_tag >= DT_VERSYM) && (entry->d_tag <= DT_VERNEEDNUM))
+           version_info[DT_VERSIONTAGIDX (entry->d_tag)] =
+             entry->d_un.d_val;
+
+         if (do_dynamic)
+           {
+             switch (elf_header.e_machine)
+               {
+               case EM_MIPS:
+               case EM_MIPS_RS3_LE:
+                 dynamic_segment_mips_val (entry);
+                 break;
+               case EM_PARISC:
+                 dynamic_segment_parisc_val (entry);
+                 break;
+               case EM_IA_64:
+                 dynamic_segment_ia64_val (entry);
+                 break;
+               default:
+                 print_vma (entry->d_un.d_val, PREFIX_HEX);
+                 putchar ('\n');
+               }
+           }
+         break;
+       }
+    }
+
+  return 1;
+}
+
+static char *
+get_ver_flags (flags)
+     unsigned int flags;
+{
+  static char buff[32];
+
+  buff[0] = 0;
+
+  if (flags == 0)
+    return _("none");
+
+  if (flags & VER_FLG_BASE)
+    strcat (buff, "BASE ");
+
+  if (flags & VER_FLG_WEAK)
+    {
+      if (flags & VER_FLG_BASE)
+       strcat (buff, "| ");
+
+      strcat (buff, "WEAK ");
+    }
+
+  if (flags & ~(VER_FLG_BASE | VER_FLG_WEAK))
+    strcat (buff, "| <unknown>");
+
+  return buff;
+}
+
+/* Display the contents of the version sections.  */
+static int
+process_version_sections (file)
+     FILE *file;
+{
+  Elf_Internal_Shdr *section;
+  unsigned i;
+  int found = 0;
+
+  if (! do_version)
+    return 1;
+
+  for (i = 0, section = section_headers;
+       i < elf_header.e_shnum;
+       i++, section++)
+    {
+      switch (section->sh_type)
+       {
+       case SHT_GNU_verdef:
+         {
+           Elf_External_Verdef *edefs;
+           unsigned int idx;
+           unsigned int cnt;
+
+           found = 1;
+
+           printf
+             (_("\nVersion definition section '%s' contains %ld entries:\n"),
+              SECTION_NAME (section), section->sh_info);
+
+           printf (_("  Addr: 0x"));
+           printf_vma (section->sh_addr);
+           printf (_("  Offset: %#08lx  Link: %lx (%s)\n"),
+                   (unsigned long) section->sh_offset, section->sh_link,
+                   SECTION_NAME (SECTION_HEADER (section->sh_link)));
+
+           edefs = ((Elf_External_Verdef *)
+                    get_data (NULL, file, section->sh_offset,
+                              section->sh_size,
+                              _("version definition section")));
+           if (!edefs)
+             break;
+
+           for (idx = cnt = 0; cnt < section->sh_info; ++cnt)
+             {
+               char *vstart;
+               Elf_External_Verdef *edef;
+               Elf_Internal_Verdef ent;
+               Elf_External_Verdaux *eaux;
+               Elf_Internal_Verdaux aux;
+               int j;
+               int isum;
+
+               vstart = ((char *) edefs) + idx;
+
+               edef = (Elf_External_Verdef *) vstart;
+
+               ent.vd_version = BYTE_GET (edef->vd_version);
+               ent.vd_flags   = BYTE_GET (edef->vd_flags);
+               ent.vd_ndx     = BYTE_GET (edef->vd_ndx);
+               ent.vd_cnt     = BYTE_GET (edef->vd_cnt);
+               ent.vd_hash    = BYTE_GET (edef->vd_hash);
+               ent.vd_aux     = BYTE_GET (edef->vd_aux);
+               ent.vd_next    = BYTE_GET (edef->vd_next);
+
+               printf (_("  %#06x: Rev: %d  Flags: %s"),
+                       idx, ent.vd_version, get_ver_flags (ent.vd_flags));
+
+               printf (_("  Index: %d  Cnt: %d  "),
+                       ent.vd_ndx, ent.vd_cnt);
+
+               vstart += ent.vd_aux;
+
+               eaux = (Elf_External_Verdaux *) vstart;
+
+               aux.vda_name = BYTE_GET (eaux->vda_name);
+               aux.vda_next = BYTE_GET (eaux->vda_next);
+
+               if (dynamic_strings)
+                 printf (_("Name: %s\n"), dynamic_strings + aux.vda_name);
+               else
+                 printf (_("Name index: %ld\n"), aux.vda_name);
+
+               isum = idx + ent.vd_aux;
+
+               for (j = 1; j < ent.vd_cnt; j++)
+                 {
+                   isum   += aux.vda_next;
+                   vstart += aux.vda_next;
+
+                   eaux = (Elf_External_Verdaux *) vstart;
+
+                   aux.vda_name = BYTE_GET (eaux->vda_name);
+                   aux.vda_next = BYTE_GET (eaux->vda_next);
+
+                   if (dynamic_strings)
+                     printf (_("  %#06x: Parent %d: %s\n"),
+                             isum, j, dynamic_strings + aux.vda_name);
+                   else
+                     printf (_("  %#06x: Parent %d, name index: %ld\n"),
+                             isum, j, aux.vda_name);
+                 }
+
+               idx += ent.vd_next;
+             }
+
+           free (edefs);
+         }
+         break;
+
+       case SHT_GNU_verneed:
+         {
+           Elf_External_Verneed *eneed;
+           unsigned int idx;
+           unsigned int cnt;
+
+           found = 1;
+
+           printf (_("\nVersion needs section '%s' contains %ld entries:\n"),
+                   SECTION_NAME (section), section->sh_info);
+
+           printf (_(" Addr: 0x"));
+           printf_vma (section->sh_addr);
+           printf (_("  Offset: %#08lx  Link to section: %ld (%s)\n"),
+                   (unsigned long) section->sh_offset, section->sh_link,
+                   SECTION_NAME (SECTION_HEADER (section->sh_link)));
+
+           eneed = ((Elf_External_Verneed *)
+                    get_data (NULL, file, section->sh_offset,
+                              section->sh_size, _("version need section")));
+           if (!eneed)
+             break;
+
+           for (idx = cnt = 0; cnt < section->sh_info; ++cnt)
+             {
+               Elf_External_Verneed *entry;
+               Elf_Internal_Verneed ent;
+               int j;
+               int isum;
+               char *vstart;
+
+               vstart = ((char *) eneed) + idx;
+
+               entry = (Elf_External_Verneed *) vstart;
+
+               ent.vn_version = BYTE_GET (entry->vn_version);
+               ent.vn_cnt     = BYTE_GET (entry->vn_cnt);
+               ent.vn_file    = BYTE_GET (entry->vn_file);
+               ent.vn_aux     = BYTE_GET (entry->vn_aux);
+               ent.vn_next    = BYTE_GET (entry->vn_next);
+
+               printf (_("  %#06x: Version: %d"), idx, ent.vn_version);
+
+               if (dynamic_strings)
+                 printf (_("  File: %s"), dynamic_strings + ent.vn_file);
+               else
+                 printf (_("  File: %lx"), ent.vn_file);
+
+               printf (_("  Cnt: %d\n"), ent.vn_cnt);
+
+               vstart += ent.vn_aux;
+
+               for (j = 0, isum = idx + ent.vn_aux; j < ent.vn_cnt; ++j)
+                 {
+                   Elf_External_Vernaux *eaux;
+                   Elf_Internal_Vernaux aux;
+
+                   eaux = (Elf_External_Vernaux *) vstart;
+
+                   aux.vna_hash  = BYTE_GET (eaux->vna_hash);
+                   aux.vna_flags = BYTE_GET (eaux->vna_flags);
+                   aux.vna_other = BYTE_GET (eaux->vna_other);
+                   aux.vna_name  = BYTE_GET (eaux->vna_name);
+                   aux.vna_next  = BYTE_GET (eaux->vna_next);
+
+                   if (dynamic_strings)
+                     printf (_("  %#06x: Name: %s"),
+                             isum, dynamic_strings + aux.vna_name);
+                   else
+                     printf (_("  %#06x: Name index: %lx"),
+                             isum, aux.vna_name);
+
+                   printf (_("  Flags: %s  Version: %d\n"),
+                           get_ver_flags (aux.vna_flags), aux.vna_other);
+
+                   isum   += aux.vna_next;
+                   vstart += aux.vna_next;
+                 }
+
+               idx += ent.vn_next;
+             }
+
+           free (eneed);
+         }
+         break;
+
+       case SHT_GNU_versym:
+         {
+           Elf_Internal_Shdr *link_section;
+           int total;
+           int cnt;
+           unsigned char *edata;
+           unsigned short *data;
+           char *strtab;
+           Elf_Internal_Sym *symbols;
+           Elf_Internal_Shdr *string_sec;
+
+           link_section = SECTION_HEADER (section->sh_link);
+           total = section->sh_size / section->sh_entsize;
+
+           found = 1;
+
+           symbols = GET_ELF_SYMBOLS (file, link_section);
+
+           string_sec = SECTION_HEADER (link_section->sh_link);
+
+           strtab = (char *) get_data (NULL, file, string_sec->sh_offset,
+                                       string_sec->sh_size,
+                                       _("version string table"));
+           if (!strtab)
+             break;
+
+           printf (_("\nVersion symbols section '%s' contains %d entries:\n"),
+                   SECTION_NAME (section), total);
+
+           printf (_(" Addr: "));
+           printf_vma (section->sh_addr);
+           printf (_("  Offset: %#08lx  Link: %lx (%s)\n"),
+                   (unsigned long) section->sh_offset, section->sh_link,
+                   SECTION_NAME (link_section));
+
+           edata =
+             ((unsigned char *)
+              get_data (NULL, file,
+                        version_info[DT_VERSIONTAGIDX (DT_VERSYM)] - loadaddr,
+                        total * sizeof (short), _("version symbol data")));
+           if (!edata)
+             {
+               free (strtab);
+               break;
+             }
+
+           data = (unsigned short *) malloc (total * sizeof (short));
+
+           for (cnt = total; cnt --;)
+             data[cnt] = byte_get (edata + cnt * sizeof (short),
+                                   sizeof (short));
+
+           free (edata);
+
+           for (cnt = 0; cnt < total; cnt += 4)
+             {
+               int j, nn;
+               int check_def, check_need;
+               char *name;
+
+               printf ("  %03x:", cnt);
+
+               for (j = 0; (j < 4) && (cnt + j) < total; ++j)
+                 switch (data[cnt + j])
+                   {
+                   case 0:
+                     fputs (_("   0 (*local*)    "), stdout);
+                     break;
+
+                   case 1:
+                     fputs (_("   1 (*global*)   "), stdout);
+                     break;
+
+                   default:
+                     nn = printf ("%4x%c", data[cnt + j] & 0x7fff,
+                                  data[cnt + j] & 0x8000 ? 'h' : ' ');
+
+                     check_def = 1;
+                     check_need = 1;
+                     if (SECTION_HEADER (symbols[cnt + j].st_shndx)->sh_type
+                         != SHT_NOBITS)
+                       {
+                         if (symbols[cnt + j].st_shndx == SHN_UNDEF)
+                           check_def = 0;
+                         else
+                           check_need = 0;
+                       }
+
+                     if (check_need
+                         && version_info[DT_VERSIONTAGIDX (DT_VERNEED)])
+                       {
+                         Elf_Internal_Verneed ivn;
+                         unsigned long offset;
+
+                         offset = version_info[DT_VERSIONTAGIDX (DT_VERNEED)]
+                           - loadaddr;
+
+                         do
+                           {
+                             Elf_Internal_Vernaux ivna;
+                             Elf_External_Verneed evn;
+                             Elf_External_Vernaux evna;
+                             unsigned long a_off;
+
+                             get_data (&evn, file, offset, sizeof (evn),
+                                       _("version need"));
+
+                             ivn.vn_aux  = BYTE_GET (evn.vn_aux);
+                             ivn.vn_next = BYTE_GET (evn.vn_next);
+
+                             a_off = offset + ivn.vn_aux;
+
+                             do
+                               {
+                                 get_data (&evna, file, a_off, sizeof (evna),
+                                           _("version need aux (2)"));
+
+                                 ivna.vna_next  = BYTE_GET (evna.vna_next);
+                                 ivna.vna_other = BYTE_GET (evna.vna_other);
+
+                                 a_off += ivna.vna_next;
+                               }
+                             while (ivna.vna_other != data[cnt + j]
+                                    && ivna.vna_next != 0);
+
+                             if (ivna.vna_other == data[cnt + j])
+                               {
+                                 ivna.vna_name = BYTE_GET (evna.vna_name);
+
+                                 name = strtab + ivna.vna_name;
+                                 nn += printf ("(%s%-*s",
+                                               name,
+                                               12 - (int) strlen (name),
+                                               ")");
+                                 check_def = 0;
+                                 break;
+                               }
+
+                             offset += ivn.vn_next;
+                           }
+                         while (ivn.vn_next);
+                       }
+
+                     if (check_def && data[cnt + j] != 0x8001
+                         && version_info[DT_VERSIONTAGIDX (DT_VERDEF)])
+                       {
+                         Elf_Internal_Verdef ivd;
+                         Elf_External_Verdef evd;
+                         unsigned long offset;
+
+                         offset = (version_info[DT_VERSIONTAGIDX (DT_VERDEF)]
+                                   - loadaddr);
+
+                         do
+                           {
+                             get_data (&evd, file, offset, sizeof (evd),
+                                       _("version def"));
+
+                             ivd.vd_next = BYTE_GET (evd.vd_next);
+                             ivd.vd_ndx  = BYTE_GET (evd.vd_ndx);
+
+                             offset += ivd.vd_next;
+                           }
+                         while (ivd.vd_ndx != (data[cnt + j] & 0x7fff)
+                                && ivd.vd_next != 0);
+
+                         if (ivd.vd_ndx == (data[cnt + j] & 0x7fff))
+                           {
+                             Elf_External_Verdaux evda;
+                             Elf_Internal_Verdaux ivda;
+
+                             ivd.vd_aux = BYTE_GET (evd.vd_aux);
+
+                             get_data (&evda, file,
+                                       offset - ivd.vd_next + ivd.vd_aux,
+                                       sizeof (evda), _("version def aux"));
+
+                             ivda.vda_name = BYTE_GET (evda.vda_name);
+
+                             name = strtab + ivda.vda_name;
+                             nn += printf ("(%s%-*s",
+                                           name,
+                                           12 - (int) strlen (name),
+                                           ")");
+                           }
+                       }
+
+                     if (nn < 18)
+                       printf ("%*c", 18 - nn, ' ');
+                   }
+
+               putchar ('\n');
+             }
+
+           free (data);
+           free (strtab);
+           free (symbols);
+         }
+         break;
+
+       default:
+         break;
+       }
+    }
+
+  if (! found)
+    printf (_("\nNo version information found in this file.\n"));
+
+  return 1;
+}
+
+static const char *
+get_symbol_binding (binding)
+     unsigned int binding;
+{
+  static char buff[32];
+
+  switch (binding)
+    {
+    case STB_LOCAL:    return "LOCAL";
+    case STB_GLOBAL:   return "GLOBAL";
+    case STB_WEAK:     return "WEAK";
+    default:
+      if (binding >= STB_LOPROC && binding <= STB_HIPROC)
+       sprintf (buff, _("<processor specific>: %d"), binding);
+      else if (binding >= STB_LOOS && binding <= STB_HIOS)
+       sprintf (buff, _("<OS specific>: %d"), binding);
+      else
+       sprintf (buff, _("<unknown>: %d"), binding);
+      return buff;
+    }
+}
+
+static const char *
+get_symbol_type (type)
+     unsigned int type;
+{
+  static char buff[32];
+
+  switch (type)
+    {
+    case STT_NOTYPE:   return "NOTYPE";
+    case STT_OBJECT:   return "OBJECT";
+    case STT_FUNC:     return "FUNC";
+    case STT_SECTION:  return "SECTION";
+    case STT_FILE:     return "FILE";
+    case STT_COMMON:   return "COMMON";
+    case STT_TLS:      return "TLS";
+    default:
+      if (type >= STT_LOPROC && type <= STT_HIPROC)
+       {
+         sprintf (buff, _("<processor specific>: %d"), type);
+       }
+      else if (type >= STT_LOOS && type <= STT_HIOS)
+       {
+         sprintf (buff, _("<OS specific>: %d"), type);
+       }
+      else
+       sprintf (buff, _("<unknown>: %d"), type);
+      return buff;
+    }
+}
+
+static const char *
+get_symbol_visibility (visibility)
+     unsigned int visibility;
+{
+  switch (visibility)
+    {
+    case STV_DEFAULT:  return "DEFAULT";
+    case STV_INTERNAL: return "INTERNAL";
+    case STV_HIDDEN:   return "HIDDEN";
+    case STV_PROTECTED: return "PROTECTED";
+    default: abort ();
+    }
+}
+
+static const char *
+get_symbol_index_type (type)
+     unsigned int type;
+{
+  static char buff[32];
+
+  switch (type)
+    {
+    case SHN_UNDEF:    return "UND";
+    case SHN_ABS:      return "ABS";
+    case SHN_COMMON:   return "COM";
+    default:
+      if (type >= SHN_LOPROC && type <= SHN_HIPROC)
+       sprintf (buff, "PRC[0x%04x]", type);
+      else if (type >= SHN_LOOS && type <= SHN_HIOS)
+       sprintf (buff, "OS [0x%04x]", type);
+      else if (type >= SHN_LORESERVE && type <= SHN_HIRESERVE)
+       sprintf (buff, "RSV[0x%04x]", type);
+      else
+       sprintf (buff, "%3d", type);
+      break;
+    }
+
+  return buff;
+}
+
+static int *
+get_dynamic_data (file, number)
+     FILE *file;
+     unsigned int number;
+{
+  unsigned char *e_data;
+  int *i_data;
+
+  e_data = (unsigned char *) malloc (number * 4);
+
+  if (e_data == NULL)
+    {
+      error (_("Out of memory\n"));
+      return NULL;
+    }
+
+  if (fread (e_data, 4, number, file) != number)
+    {
+      error (_("Unable to read in dynamic data\n"));
+      return NULL;
+    }
+
+  i_data = (int *) malloc (number * sizeof (*i_data));
+
+  if (i_data == NULL)
+    {
+      error (_("Out of memory\n"));
+      free (e_data);
+      return NULL;
+    }
+
+  while (number--)
+    i_data[number] = byte_get (e_data + number * 4, 4);
+
+  free (e_data);
+
+  return i_data;
+}
+
+/* Dump the symbol table.  */
+static int
+process_symbol_table (file)
+     FILE *file;
+{
+  Elf_Internal_Shdr *section;
+  unsigned char nb[4];
+  unsigned char nc[4];
+  int nbuckets = 0;
+  int nchains = 0;
+  int *buckets = NULL;
+  int *chains = NULL;
+
+  if (! do_syms && !do_histogram)
+    return 1;
+
+  if (dynamic_info[DT_HASH] && ((do_using_dynamic && dynamic_strings != NULL)
+                               || do_histogram))
+    {
+      if (fseek (file, dynamic_info[DT_HASH] - loadaddr, SEEK_SET))
+       {
+         error (_("Unable to seek to start of dynamic information"));
+         return 0;
+       }
+
+      if (fread (nb, sizeof (nb), 1, file) != 1)
+       {
+         error (_("Failed to read in number of buckets\n"));
+         return 0;
+       }
+
+      if (fread (nc, sizeof (nc), 1, file) != 1)
+       {
+         error (_("Failed to read in number of chains\n"));
+         return 0;
+       }
+
+      nbuckets = byte_get (nb, 4);
+      nchains  = byte_get (nc, 4);
+
+      buckets = get_dynamic_data (file, nbuckets);
+      chains  = get_dynamic_data (file, nchains);
+
+      if (buckets == NULL || chains == NULL)
+       return 0;
+    }
+
+  if (do_syms
+      && dynamic_info[DT_HASH] && do_using_dynamic && dynamic_strings != NULL)
+    {
+      int hn;
+      int si;
+
+      printf (_("\nSymbol table for image:\n"));
+      if (is_32bit_elf)
+       printf (_("  Num Buc:    Value  Size   Type   Bind Vis      Ndx Name\n"));
+      else
+       printf (_("  Num Buc:    Value          Size   Type   Bind Vis      Ndx Name\n"));
+
+      for (hn = 0; hn < nbuckets; hn++)
+       {
+         if (! buckets[hn])
+           continue;
+
+         for (si = buckets[hn]; si < nchains && si > 0; si = chains[si])
+           {
+             Elf_Internal_Sym *psym;
+
+             psym = dynamic_symbols + si;
+
+             printf ("  %3d %3d: ", si, hn);
+             print_vma (psym->st_value, LONG_HEX);
+             putchar (' ' );
+             print_vma (psym->st_size, DEC_5);
+
+             printf ("  %6s", get_symbol_type (ELF_ST_TYPE (psym->st_info)));
+             printf (" %6s",  get_symbol_binding (ELF_ST_BIND (psym->st_info)));
+             printf (" %3s",  get_symbol_visibility (ELF_ST_VISIBILITY (psym->st_other)));
+             printf (" %3.3s ", get_symbol_index_type (psym->st_shndx));
+             print_symbol (25, dynamic_strings + psym->st_name);
+             putchar ('\n');
+           }
+       }
+    }
+  else if (do_syms && !do_using_dynamic)
+    {
+      unsigned int i;
+
+      for (i = 0, section = section_headers;
+          i < elf_header.e_shnum;
+          i++, section++)
+       {
+         unsigned int si;
+         char *strtab;
+         Elf_Internal_Sym *symtab;
+         Elf_Internal_Sym *psym;
+
+
+         if (   section->sh_type != SHT_SYMTAB
+             && section->sh_type != SHT_DYNSYM)
+           continue;
+
+         printf (_("\nSymbol table '%s' contains %lu entries:\n"),
+                 SECTION_NAME (section),
+                 (unsigned long) (section->sh_size / section->sh_entsize));
+         if (is_32bit_elf)
+           printf (_("   Num:    Value  Size Type    Bind   Vis      Ndx Name\n"));
+         else
+           printf (_("   Num:    Value          Size Type    Bind   Vis      Ndx Name\n"));
+
+         symtab = GET_ELF_SYMBOLS (file, section);
+         if (symtab == NULL)
+           continue;
+
+         if (section->sh_link == elf_header.e_shstrndx)
+           strtab = string_table;
+         else
+           {
+             Elf_Internal_Shdr *string_sec;
+
+             string_sec = SECTION_HEADER (section->sh_link);
+
+             strtab = (char *) get_data (NULL, file, string_sec->sh_offset,
+                                         string_sec->sh_size,
+                                         _("string table"));
+           }
+
+         for (si = 0, psym = symtab;
+              si < section->sh_size / section->sh_entsize;
+              si++, psym++)
+           {
+             printf ("%6d: ", si);
+             print_vma (psym->st_value, LONG_HEX);
+             putchar (' ');
+             print_vma (psym->st_size, DEC_5);
+             printf (" %-7s", get_symbol_type (ELF_ST_TYPE (psym->st_info)));
+             printf (" %-6s", get_symbol_binding (ELF_ST_BIND (psym->st_info)));
+             printf (" %-3s", get_symbol_visibility (ELF_ST_VISIBILITY (psym->st_other)));
+             printf (" %4s ", get_symbol_index_type (psym->st_shndx));
+             print_symbol (25, strtab + psym->st_name);
+
+             if (section->sh_type == SHT_DYNSYM &&
+                 version_info[DT_VERSIONTAGIDX (DT_VERSYM)] != 0)
+               {
+                 unsigned char data[2];
+                 unsigned short vers_data;
+                 unsigned long offset;
+                 int is_nobits;
+                 int check_def;
+
+                 offset = version_info[DT_VERSIONTAGIDX (DT_VERSYM)]
+                   - loadaddr;
+
+                 get_data (&data, file, offset + si * sizeof (vers_data),
+                           sizeof (data), _("version data"));
+
+                 vers_data = byte_get (data, 2);
+
+                 is_nobits = (SECTION_HEADER (psym->st_shndx)->sh_type
+                              == SHT_NOBITS);
+
+                 check_def = (psym->st_shndx != SHN_UNDEF);
+
+                 if ((vers_data & 0x8000) || vers_data > 1)
+                   {
+                     if (version_info[DT_VERSIONTAGIDX (DT_VERNEED)]
+                         && (is_nobits || ! check_def))
+                       {
+                         Elf_External_Verneed evn;
+                         Elf_Internal_Verneed ivn;
+                         Elf_Internal_Vernaux ivna;
+
+                         /* We must test both.  */
+                         offset = (version_info[DT_VERSIONTAGIDX (DT_VERNEED)]
+                                   - loadaddr);
+
+                         do
+                           {
+                             unsigned long vna_off;
+
+                             get_data (&evn, file, offset, sizeof (evn),
+                                       _("version need"));
+
+                             ivn.vn_aux  = BYTE_GET (evn.vn_aux);
+                             ivn.vn_next = BYTE_GET (evn.vn_next);
+
+                             vna_off = offset + ivn.vn_aux;
+
+                             do
+                               {
+                                 Elf_External_Vernaux evna;
+
+                                 get_data (&evna, file, vna_off,
+                                           sizeof (evna),
+                                           _("version need aux (3)"));
+
+                                 ivna.vna_other = BYTE_GET (evna.vna_other);
+                                 ivna.vna_next  = BYTE_GET (evna.vna_next);
+                                 ivna.vna_name  = BYTE_GET (evna.vna_name);
+
+                                 vna_off += ivna.vna_next;
+                               }
+                             while (ivna.vna_other != vers_data
+                                    && ivna.vna_next != 0);
+
+                             if (ivna.vna_other == vers_data)
+                               break;
+
+                             offset += ivn.vn_next;
+                           }
+                         while (ivn.vn_next != 0);
+
+                         if (ivna.vna_other == vers_data)
+                           {
+                             printf ("@%s (%d)",
+                                     strtab + ivna.vna_name, ivna.vna_other);
+                             check_def = 0;
+                           }
+                         else if (! is_nobits)
+                           error (_("bad dynamic symbol"));
+                         else
+                           check_def = 1;
+                       }
+
+                     if (check_def)
+                       {
+                         if (vers_data != 0x8001
+                             && version_info[DT_VERSIONTAGIDX (DT_VERDEF)])
+                           {
+                             Elf_Internal_Verdef ivd;
+                             Elf_Internal_Verdaux ivda;
+                             Elf_External_Verdaux evda;
+                             unsigned long off;
+
+                             off
+                               = (version_info[DT_VERSIONTAGIDX (DT_VERDEF)]
+                                  - loadaddr);
+
+                             do
+                               {
+                                 Elf_External_Verdef evd;
+
+                                 get_data (&evd, file, off, sizeof (evd),
+                                           _("version def"));
+
+                                 ivd.vd_ndx = BYTE_GET (evd.vd_ndx);
+                                 ivd.vd_aux = BYTE_GET (evd.vd_aux);
+                                 ivd.vd_next = BYTE_GET (evd.vd_next);
+
+                                 off += ivd.vd_next;
+                               }
+                             while (ivd.vd_ndx != (vers_data & 0x7fff)
+                                    && ivd.vd_next != 0);
+
+                             off -= ivd.vd_next;
+                             off += ivd.vd_aux;
+
+                             get_data (&evda, file, off, sizeof (evda),
+                                       _("version def aux"));
+
+                             ivda.vda_name = BYTE_GET (evda.vda_name);
+
+                             if (psym->st_name != ivda.vda_name)
+                               printf ((vers_data & 0x8000)
+                                       ? "@%s" : "@@%s",
+                                       strtab + ivda.vda_name);
+                           }
+                       }
+                   }
+               }
+
+             putchar ('\n');
+           }
+
+         free (symtab);
+         if (strtab != string_table)
+           free (strtab);
+       }
+    }
+  else if (do_syms)
+    printf
+      (_("\nDynamic symbol information is not available for displaying symbols.\n"));
+
+  if (do_histogram && buckets != NULL)
+    {
+      int *lengths;
+      int *counts;
+      int hn;
+      int si;
+      int maxlength = 0;
+      int nzero_counts = 0;
+      int nsyms = 0;
+
+      printf (_("\nHistogram for bucket list length (total of %d buckets):\n"),
+             nbuckets);
+      printf (_(" Length  Number     %% of total  Coverage\n"));
+
+      lengths = (int *) calloc (nbuckets, sizeof (int));
+      if (lengths == NULL)
+       {
+         error (_("Out of memory"));
+         return 0;
+       }
+      for (hn = 0; hn < nbuckets; ++hn)
+       {
+         if (! buckets[hn])
+           continue;
+
+         for (si = buckets[hn]; si > 0 && si < nchains; si = chains[si])
+           {
+             ++nsyms;
+             if (maxlength < ++lengths[hn])
+               ++maxlength;
+           }
+       }
+
+      counts = (int *) calloc (maxlength + 1, sizeof (int));
+      if (counts == NULL)
+       {
+         error (_("Out of memory"));
+         return 0;
+       }
+
+      for (hn = 0; hn < nbuckets; ++hn)
+       ++counts[lengths[hn]];
+
+      if (nbuckets > 0)
+       {
+         printf ("      0  %-10d (%5.1f%%)\n",
+                 counts[0], (counts[0] * 100.0) / nbuckets);
+         for (si = 1; si <= maxlength; ++si)
+           {
+             nzero_counts += counts[si] * si;
+             printf ("%7d  %-10d (%5.1f%%)    %5.1f%%\n",
+                     si, counts[si], (counts[si] * 100.0) / nbuckets,
+                     (nzero_counts * 100.0) / nsyms);
+           }
+       }
+
+      free (counts);
+      free (lengths);
+    }
+
+  if (buckets != NULL)
+    {
+      free (buckets);
+      free (chains);
+    }
+
+  return 1;
+}
+
+static int
+process_syminfo (file)
+     FILE *file ATTRIBUTE_UNUSED;
+{
+  unsigned int i;
+
+  if (dynamic_syminfo == NULL
+      || !do_dynamic)
+    /* No syminfo, this is ok.  */
+    return 1;
+
+  /* There better should be a dynamic symbol section.  */
+  if (dynamic_symbols == NULL || dynamic_strings == NULL)
+    return 0;
+
+  if (dynamic_addr)
+    printf (_("\nDynamic info segment at offset 0x%lx contains %d entries:\n"),
+           dynamic_syminfo_offset, dynamic_syminfo_nent);
+
+  printf (_(" Num: Name                           BoundTo     Flags\n"));
+  for (i = 0; i < dynamic_syminfo_nent; ++i)
+    {
+      unsigned short int flags = dynamic_syminfo[i].si_flags;
+
+      printf ("%4d: ", i);
+      print_symbol (30, dynamic_strings + dynamic_symbols[i].st_name);
+      putchar (' ');
+
+      switch (dynamic_syminfo[i].si_boundto)
+       {
+       case SYMINFO_BT_SELF:
+         fputs ("SELF       ", stdout);
+         break;
+       case SYMINFO_BT_PARENT:
+         fputs ("PARENT     ", stdout);
+         break;
+       default:
+         if (dynamic_syminfo[i].si_boundto > 0
+             && dynamic_syminfo[i].si_boundto < dynamic_size)
+           {
+             print_symbol (10,
+                           dynamic_strings
+                           + (dynamic_segment
+                              [dynamic_syminfo[i].si_boundto].d_un.d_val));
+             putchar (' ' );
+           }
+         else
+           printf ("%-10d ", dynamic_syminfo[i].si_boundto);
+         break;
+       }
+
+      if (flags & SYMINFO_FLG_DIRECT)
+       printf (" DIRECT");
+      if (flags & SYMINFO_FLG_PASSTHRU)
+       printf (" PASSTHRU");
+      if (flags & SYMINFO_FLG_COPY)
+       printf (" COPY");
+      if (flags & SYMINFO_FLG_LAZYLOAD)
+       printf (" LAZYLOAD");
+
+      puts ("");
+    }
+
+  return 1;
+}
+
+#ifdef SUPPORT_DISASSEMBLY
+static void
+disassemble_section (section, file)
+     Elf_Internal_Shdr *section;
+     FILE *file;
+{
+  printf (_("\nAssembly dump of section %s\n"),
+         SECTION_NAME (section));
+
+  /* XXX -- to be done --- XXX */
+
+  return 1;
+}
+#endif
+
+static int
+dump_section (section, file)
+     Elf_Internal_Shdr *section;
+     FILE *file;
+{
+  bfd_size_type bytes;
+  bfd_vma addr;
+  unsigned char *data;
+  unsigned char *start;
+
+  bytes = section->sh_size;
+
+  if (bytes == 0)
+    {
+      printf (_("\nSection '%s' has no data to dump.\n"),
+             SECTION_NAME (section));
+      return 0;
+    }
+  else
+    printf (_("\nHex dump of section '%s':\n"), SECTION_NAME (section));
+
+  addr = section->sh_addr;
+
+  start = (unsigned char *) get_data (NULL, file, section->sh_offset, bytes,
+                                     _("section data"));
+  if (!start)
+    return 0;
+
+  data = start;
+
+  while (bytes)
+    {
+      int j;
+      int k;
+      int lbytes;
+
+      lbytes = (bytes > 16 ? 16 : bytes);
+
+      printf ("  0x%8.8lx ", (unsigned long) addr);
+
+      switch (elf_header.e_ident[EI_DATA])
+       {
+       default:
+       case ELFDATA2LSB:
+         for (j = 15; j >= 0; j --)
+           {
+             if (j < lbytes)
+               printf ("%2.2x", data[j]);
+             else
+               printf ("  ");
+
+             if (!(j & 0x3))
+               printf (" ");
+           }
+         break;
+
+       case ELFDATA2MSB:
+         for (j = 0; j < 16; j++)
+           {
+             if (j < lbytes)
+               printf ("%2.2x", data[j]);
+             else
+               printf ("  ");
+
+             if ((j & 3) == 3)
+               printf (" ");
+           }
+         break;
+       }
+
+      for (j = 0; j < lbytes; j++)
+       {
+         k = data[j];
+         if (k >= ' ' && k < 0x80)
+           printf ("%c", k);
+         else
+           printf (".");
+       }
+
+      putchar ('\n');
+
+      data  += lbytes;
+      addr  += lbytes;
+      bytes -= lbytes;
+    }
+
+  free (start);
+
+  return 1;
+}
+
+
+static unsigned long int
+read_leb128 (data, length_return, sign)
+     unsigned char *data;
+     int *length_return;
+     int sign;
+{
+  unsigned long int result = 0;
+  unsigned int num_read = 0;
+  int shift = 0;
+  unsigned char byte;
+
+  do
+    {
+      byte = *data++;
+      num_read++;
+
+      result |= (byte & 0x7f) << shift;
+
+      shift += 7;
+
+    }
+  while (byte & 0x80);
+
+  if (length_return != NULL)
+    *length_return = num_read;
+
+  if (sign && (shift < 32) && (byte & 0x40))
+    result |= -1 << shift;
+
+  return result;
+}
+
+typedef struct State_Machine_Registers
+{
+  unsigned long address;
+  unsigned int file;
+  unsigned int line;
+  unsigned int column;
+  int is_stmt;
+  int basic_block;
+  int end_sequence;
+/* This variable hold the number of the last entry seen
+   in the File Table.  */
+  unsigned int last_file_entry;
+} SMR;
+
+static SMR state_machine_regs;
+
+static void
+reset_state_machine (is_stmt)
+     int is_stmt;
+{
+  state_machine_regs.address = 0;
+  state_machine_regs.file = 1;
+  state_machine_regs.line = 1;
+  state_machine_regs.column = 0;
+  state_machine_regs.is_stmt = is_stmt;
+  state_machine_regs.basic_block = 0;
+  state_machine_regs.end_sequence = 0;
+  state_machine_regs.last_file_entry = 0;
+}
+
+/* Handled an extend line op.  Returns true if this is the end
+   of sequence.  */
+static int
+process_extended_line_op (data, is_stmt, pointer_size)
+     unsigned char *data;
+     int is_stmt;
+     int pointer_size;
+{
+  unsigned char op_code;
+  int bytes_read;
+  unsigned int len;
+  unsigned char *name;
+  unsigned long adr;
+
+  len = read_leb128 (data, & bytes_read, 0);
+  data += bytes_read;
+
+  if (len == 0)
+    {
+      warn (_("badly formed extended line op encountered!\n"));
+      return bytes_read;
+    }
+
+  len += bytes_read;
+  op_code = *data++;
+
+  printf (_("  Extended opcode %d: "), op_code);
+
+  switch (op_code)
+    {
+    case DW_LNE_end_sequence:
+      printf (_("End of Sequence\n\n"));
+      reset_state_machine (is_stmt);
+      break;
+
+    case DW_LNE_set_address:
+      adr = byte_get (data, pointer_size);
+      printf (_("set Address to 0x%lx\n"), adr);
+      state_machine_regs.address = adr;
+      break;
+
+    case DW_LNE_define_file:
+      printf (_("  define new File Table entry\n"));
+      printf (_("  Entry\tDir\tTime\tSize\tName\n"));
+
+      printf (_("   %d\t"), ++state_machine_regs.last_file_entry);
+      name = data;
+      data += strlen ((char *) data) + 1;
+      printf (_("%lu\t"), read_leb128 (data, & bytes_read, 0));
+      data += bytes_read;
+      printf (_("%lu\t"), read_leb128 (data, & bytes_read, 0));
+      data += bytes_read;
+      printf (_("%lu\t"), read_leb128 (data, & bytes_read, 0));
+      printf (_("%s\n\n"), name);
+      break;
+
+    default:
+      printf (_("UNKNOWN: length %d\n"), len - bytes_read);
+      break;
+    }
+
+  return len;
+}
+
+/* Size of pointers in the .debug_line section.  This information is not
+   really present in that section.  It's obtained before dumping the debug
+   sections by doing some pre-scan of the .debug_info section.  */
+static int debug_line_pointer_size = 4;
+
+static int
+display_debug_lines (section, start, file)
+     Elf_Internal_Shdr *section;
+     unsigned char * start;
+     FILE *file ATTRIBUTE_UNUSED;
+{
+  unsigned char *hdrptr;
+  DWARF2_Internal_LineInfo info;
+  unsigned char *standard_opcodes;
+  unsigned char *data = start;
+  unsigned char *end = start + section->sh_size;
+  unsigned char *end_of_sequence;
+  int i;
+  int offset_size;
+  int initial_length_size;
+
+  printf (_("\nDump of debug contents of section %s:\n\n"),
+         SECTION_NAME (section));
+
+  while (data < end)
+    {
+      hdrptr = data;
+
+      /* Check the length of the block.  */
+      info.li_length = byte_get (hdrptr, 4);
+      hdrptr += 4;
+
+      if (info.li_length == 0xffffffff)
+       {
+         /* This section is 64-bit DWARF 3.  */
+         info.li_length = byte_get (hdrptr, 8);
+         hdrptr += 8;
+         offset_size = 8;
+         initial_length_size = 12;
+       }
+      else
+       {
+         offset_size = 4;
+         initial_length_size = 4;
+       }
+
+      if (info.li_length + initial_length_size > section->sh_size)
+       {
+         warn
+           (_("The line info appears to be corrupt - the section is too small\n"));
+         return 0;
+       }
+
+      /* Check its version number.  */
+      info.li_version = byte_get (hdrptr, 2);
+      hdrptr += 2;
+      if (info.li_version != 2 && info.li_version != 3)
+       {
+         warn (_("Only DWARF version 2 and 3 line info is currently supported.\n"));
+         return 0;
+       }
+
+      info.li_prologue_length = byte_get (hdrptr, offset_size);
+      hdrptr += offset_size;
+      info.li_min_insn_length = byte_get (hdrptr, 1);
+      hdrptr++;
+      info.li_default_is_stmt = byte_get (hdrptr, 1);
+      hdrptr++;
+      info.li_line_base = byte_get (hdrptr, 1);
+      hdrptr++;
+      info.li_line_range = byte_get (hdrptr, 1);
+      hdrptr++;
+      info.li_opcode_base = byte_get (hdrptr, 1);
+      hdrptr++;
+
+      /* Sign extend the line base field.  */
+      info.li_line_base <<= 24;
+      info.li_line_base >>= 24;
+
+      printf (_("  Length:                      %ld\n"), info.li_length);
+      printf (_("  DWARF Version:               %d\n"), info.li_version);
+      printf (_("  Prologue Length:             %d\n"), info.li_prologue_length);
+      printf (_("  Minimum Instruction Length:  %d\n"), info.li_min_insn_length);
+      printf (_("  Initial value of 'is_stmt':  %d\n"), info.li_default_is_stmt);
+      printf (_("  Line Base:                   %d\n"), info.li_line_base);
+      printf (_("  Line Range:                  %d\n"), info.li_line_range);
+      printf (_("  Opcode Base:                 %d\n"), info.li_opcode_base);
+
+      end_of_sequence = data + info.li_length + initial_length_size;
+
+      reset_state_machine (info.li_default_is_stmt);
+
+      /* Display the contents of the Opcodes table.  */
+      standard_opcodes = hdrptr;
+
+      printf (_("\n Opcodes:\n"));
+
+      for (i = 1; i < info.li_opcode_base; i++)
+       printf (_("  Opcode %d has %d args\n"), i, standard_opcodes[i - 1]);
+
+      /* Display the contents of the Directory table.  */
+      data = standard_opcodes + info.li_opcode_base - 1;
+
+      if (*data == 0)
+       printf (_("\n The Directory Table is empty.\n"));
+      else
+       {
+         printf (_("\n The Directory Table:\n"));
+
+         while (*data != 0)
+           {
+             printf (_("  %s\n"), data);
+
+             data += strlen ((char *) data) + 1;
+           }
+       }
+
+      /* Skip the NUL at the end of the table.  */
+      data++;
+
+      /* Display the contents of the File Name table.  */
+      if (*data == 0)
+       printf (_("\n The File Name Table is empty.\n"));
+      else
+       {
+         printf (_("\n The File Name Table:\n"));
+         printf (_("  Entry\tDir\tTime\tSize\tName\n"));
+
+         while (*data != 0)
+           {
+             unsigned char *name;
+             int bytes_read;
+
+             printf (_("  %d\t"), ++state_machine_regs.last_file_entry);
+             name = data;
+
+             data += strlen ((char *) data) + 1;
+
+             printf (_("%lu\t"), read_leb128 (data, & bytes_read, 0));
+             data += bytes_read;
+             printf (_("%lu\t"), read_leb128 (data, & bytes_read, 0));
+             data += bytes_read;
+             printf (_("%lu\t"), read_leb128 (data, & bytes_read, 0));
+             data += bytes_read;
+             printf (_("%s\n"), name);
+           }
+       }
+
+      /* Skip the NUL at the end of the table.  */
+      data++;
+
+      /* Now display the statements.  */
+      printf (_("\n Line Number Statements:\n"));
+
+
+      while (data < end_of_sequence)
+       {
+         unsigned char op_code;
+         int adv;
+         int bytes_read;
+
+         op_code = *data++;
+
+         if (op_code >= info.li_opcode_base)
+           {
+             op_code -= info.li_opcode_base;
+             adv      = (op_code / info.li_line_range) * info.li_min_insn_length;
+             state_machine_regs.address += adv;
+             printf (_("  Special opcode %d: advance Address by %d to 0x%lx"),
+                     op_code, adv, state_machine_regs.address);
+             adv = (op_code % info.li_line_range) + info.li_line_base;
+             state_machine_regs.line += adv;
+             printf (_(" and Line by %d to %d\n"),
+                     adv, state_machine_regs.line);
+           }
+         else switch (op_code)
+           {
+           case DW_LNS_extended_op:
+             data += process_extended_line_op (data, info.li_default_is_stmt,
+                                               debug_line_pointer_size);
+             break;
+
+           case DW_LNS_copy:
+             printf (_("  Copy\n"));
+             break;
+
+           case DW_LNS_advance_pc:
+             adv = info.li_min_insn_length * read_leb128 (data, & bytes_read, 0);
+             data += bytes_read;
+             state_machine_regs.address += adv;
+             printf (_("  Advance PC by %d to %lx\n"), adv,
+                     state_machine_regs.address);
+             break;
+
+           case DW_LNS_advance_line:
+             adv = read_leb128 (data, & bytes_read, 1);
+             data += bytes_read;
+             state_machine_regs.line += adv;
+             printf (_("  Advance Line by %d to %d\n"), adv,
+                     state_machine_regs.line);
+             break;
+
+           case DW_LNS_set_file:
+             adv = read_leb128 (data, & bytes_read, 0);
+             data += bytes_read;
+             printf (_("  Set File Name to entry %d in the File Name Table\n"),
+                     adv);
+             state_machine_regs.file = adv;
+             break;
+
+           case DW_LNS_set_column:
+             adv = read_leb128 (data, & bytes_read, 0);
+             data += bytes_read;
+             printf (_("  Set column to %d\n"), adv);
+             state_machine_regs.column = adv;
+             break;
+
+           case DW_LNS_negate_stmt:
+             adv = state_machine_regs.is_stmt;
+             adv = ! adv;
+             printf (_("  Set is_stmt to %d\n"), adv);
+             state_machine_regs.is_stmt = adv;
+             break;
+
+           case DW_LNS_set_basic_block:
+             printf (_("  Set basic block\n"));
+             state_machine_regs.basic_block = 1;
+             break;
+
+           case DW_LNS_const_add_pc:
+             adv = (((255 - info.li_opcode_base) / info.li_line_range)
+                    * info.li_min_insn_length);
+             state_machine_regs.address += adv;
+             printf (_("  Advance PC by constant %d to 0x%lx\n"), adv,
+                     state_machine_regs.address);
+             break;
+
+           case DW_LNS_fixed_advance_pc:
+             adv = byte_get (data, 2);
+             data += 2;
+             state_machine_regs.address += adv;
+             printf (_("  Advance PC by fixed size amount %d to 0x%lx\n"),
+                     adv, state_machine_regs.address);
+             break;
+
+           case DW_LNS_set_prologue_end:
+             printf (_("  Set prologue_end to true\n"));
+             break;
+
+           case DW_LNS_set_epilogue_begin:
+             printf (_("  Set epilogue_begin to true\n"));
+             break;
+
+           case DW_LNS_set_isa:
+             adv = read_leb128 (data, & bytes_read, 0);
+             data += bytes_read;
+             printf (_("  Set ISA to %d\n"), adv);
+             break;
+
+           default:
+             printf (_("  Unknown opcode %d with operands: "), op_code);
+             {
+               int j;
+               for (j = standard_opcodes[op_code - 1]; j > 0 ; --j)
+                 {
+                   printf ("0x%lx%s", read_leb128 (data, &bytes_read, 0),
+                           j == 1 ? "" : ", ");
+                   data += bytes_read;
+                 }
+               putchar ('\n');
+             }
+             break;
+           }
+       }
+      putchar ('\n');
+    }
+
+  return 1;
+}
+
+static int
+display_debug_pubnames (section, start, file)
+     Elf_Internal_Shdr *section;
+     unsigned char *start;
+     FILE *file ATTRIBUTE_UNUSED;
+{
+  DWARF2_Internal_PubNames pubnames;
+  unsigned char *end;
+
+  end = start + section->sh_size;
+
+  printf (_("Contents of the %s section:\n\n"), SECTION_NAME (section));
+
+  while (start < end)
+    {
+      unsigned char *data;
+      unsigned long offset;
+      int offset_size, initial_length_size;
+
+      data = start;
+
+      pubnames.pn_length = byte_get (data, 4);
+      data += 4;
+      if (pubnames.pn_length == 0xffffffff)
+       {
+         pubnames.pn_length = byte_get (data, 8);
+         data += 8;
+         offset_size = 8;
+         initial_length_size = 12;
+       }
+      else
+       {
+         offset_size = 4;
+         initial_length_size = 4;
+       }
+
+      pubnames.pn_version = byte_get (data, 2);
+      data += 2;
+      pubnames.pn_offset = byte_get (data, offset_size);
+      data += offset_size;
+      pubnames.pn_size = byte_get (data, offset_size);
+      data += offset_size;
+
+      start += pubnames.pn_length + initial_length_size;
+
+      if (pubnames.pn_version != 2 && pubnames.pn_version != 3)
+       {
+         static int warned = 0;
+
+         if (! warned)
+           {
+             warn (_("Only DWARF 2 and 3 pubnames are currently supported\n"));
+             warned = 1;
+           }
+
+         continue;
+       }
+
+      printf (_("  Length:                              %ld\n"),
+             pubnames.pn_length);
+      printf (_("  Version:                             %d\n"),
+             pubnames.pn_version);
+      printf (_("  Offset into .debug_info section:     %ld\n"),
+             pubnames.pn_offset);
+      printf (_("  Size of area in .debug_info section: %ld\n"),
+             pubnames.pn_size);
+
+      printf (_("\n    Offset\tName\n"));
+
+      do
+       {
+         offset = byte_get (data, offset_size);
+
+         if (offset != 0)
+           {
+             data += offset_size;
+             printf ("    %ld\t\t%s\n", offset, data);
+             data += strlen ((char *) data) + 1;
+           }
+       }
+      while (offset != 0);
+    }
+
+  printf ("\n");
+  return 1;
+}
+
+//PG don't make this static!
+char *
+get_TAG_name (tag)
+     unsigned long tag;
+{
+  switch (tag)
+    {
+    case DW_TAG_padding:               return "DW_TAG_padding";
+    case DW_TAG_array_type:            return "DW_TAG_array_type";
+    case DW_TAG_class_type:            return "DW_TAG_class_type";
+    case DW_TAG_entry_point:           return "DW_TAG_entry_point";
+    case DW_TAG_enumeration_type:      return "DW_TAG_enumeration_type";
+    case DW_TAG_formal_parameter:      return "DW_TAG_formal_parameter";
+    case DW_TAG_imported_declaration:  return "DW_TAG_imported_declaration";
+    case DW_TAG_label:                 return "DW_TAG_label";
+    case DW_TAG_lexical_block:         return "DW_TAG_lexical_block";
+    case DW_TAG_member:                        return "DW_TAG_member";
+    case DW_TAG_pointer_type:          return "DW_TAG_pointer_type";
+    case DW_TAG_reference_type:                return "DW_TAG_reference_type";
+    case DW_TAG_compile_unit:          return "DW_TAG_compile_unit";
+    case DW_TAG_string_type:           return "DW_TAG_string_type";
+    case DW_TAG_structure_type:                return "DW_TAG_structure_type";
+    case DW_TAG_subroutine_type:       return "DW_TAG_subroutine_type";
+    case DW_TAG_typedef:               return "DW_TAG_typedef";
+    case DW_TAG_union_type:            return "DW_TAG_union_type";
+    case DW_TAG_unspecified_parameters: return "DW_TAG_unspecified_parameters";
+    case DW_TAG_variant:               return "DW_TAG_variant";
+    case DW_TAG_common_block:          return "DW_TAG_common_block";
+    case DW_TAG_common_inclusion:      return "DW_TAG_common_inclusion";
+    case DW_TAG_inheritance:           return "DW_TAG_inheritance";
+    case DW_TAG_inlined_subroutine:    return "DW_TAG_inlined_subroutine";
+    case DW_TAG_module:                        return "DW_TAG_module";
+    case DW_TAG_ptr_to_member_type:    return "DW_TAG_ptr_to_member_type";
+    case DW_TAG_set_type:              return "DW_TAG_set_type";
+    case DW_TAG_subrange_type:         return "DW_TAG_subrange_type";
+    case DW_TAG_with_stmt:             return "DW_TAG_with_stmt";
+    case DW_TAG_access_declaration:    return "DW_TAG_access_declaration";
+    case DW_TAG_base_type:             return "DW_TAG_base_type";
+    case DW_TAG_catch_block:           return "DW_TAG_catch_block";
+    case DW_TAG_const_type:            return "DW_TAG_const_type";
+    case DW_TAG_constant:              return "DW_TAG_constant";
+    case DW_TAG_enumerator:            return "DW_TAG_enumerator";
+    case DW_TAG_file_type:             return "DW_TAG_file_type";
+    case DW_TAG_friend:                        return "DW_TAG_friend";
+    case DW_TAG_namelist:              return "DW_TAG_namelist";
+    case DW_TAG_namelist_item:         return "DW_TAG_namelist_item";
+    case DW_TAG_packed_type:           return "DW_TAG_packed_type";
+    case DW_TAG_subprogram:            return "DW_TAG_subprogram";
+    case DW_TAG_template_type_param:   return "DW_TAG_template_type_param";
+    case DW_TAG_template_value_param:  return "DW_TAG_template_value_param";
+    case DW_TAG_thrown_type:           return "DW_TAG_thrown_type";
+    case DW_TAG_try_block:             return "DW_TAG_try_block";
+    case DW_TAG_variant_part:          return "DW_TAG_variant_part";
+    case DW_TAG_variable:              return "DW_TAG_variable";
+    case DW_TAG_volatile_type:         return "DW_TAG_volatile_type";
+    case DW_TAG_MIPS_loop:             return "DW_TAG_MIPS_loop";
+    case DW_TAG_format_label:          return "DW_TAG_format_label";
+    case DW_TAG_function_template:     return "DW_TAG_function_template";
+    case DW_TAG_class_template:                return "DW_TAG_class_template";
+      /* DWARF 2.1 values.  */
+    case DW_TAG_dwarf_procedure:       return "DW_TAG_dwarf_procedure";
+    case DW_TAG_restrict_type:         return "DW_TAG_restrict_type";
+    case DW_TAG_interface_type:                return "DW_TAG_interface_type";
+    case DW_TAG_namespace:             return "DW_TAG_namespace";
+    case DW_TAG_imported_module:       return "DW_TAG_imported_module";
+    case DW_TAG_unspecified_type:      return "DW_TAG_unspecified_type";
+    case DW_TAG_partial_unit:          return "DW_TAG_partial_unit";
+    case DW_TAG_imported_unit:         return "DW_TAG_imported_unit";
+      /* UPC values.  */
+    case DW_TAG_upc_shared_type:        return "DW_TAG_upc_shared_type";
+    case DW_TAG_upc_strict_type:        return "DW_TAG_upc_strict_type";
+    case DW_TAG_upc_relaxed_type:       return "DW_TAG_upc_relaxed_type";
+    default:
+      {
+       static char buffer[100];
+
+       sprintf (buffer, _("Unknown TAG value: %lx"), tag);
+       return buffer;
+      }
+    }
+}
+
+static char *
+get_AT_name (attribute)
+     unsigned long attribute;
+{
+  switch (attribute)
+    {
+    case DW_AT_sibling:                        return "DW_AT_sibling";
+    case DW_AT_location:               return "DW_AT_location";
+    case DW_AT_name:                   return "DW_AT_name";
+    case DW_AT_ordering:               return "DW_AT_ordering";
+    case DW_AT_subscr_data:            return "DW_AT_subscr_data";
+    case DW_AT_byte_size:              return "DW_AT_byte_size";
+    case DW_AT_bit_offset:             return "DW_AT_bit_offset";
+    case DW_AT_bit_size:               return "DW_AT_bit_size";
+    case DW_AT_element_list:           return "DW_AT_element_list";
+    case DW_AT_stmt_list:              return "DW_AT_stmt_list";
+    case DW_AT_low_pc:                 return "DW_AT_low_pc";
+    case DW_AT_high_pc:                        return "DW_AT_high_pc";
+    case DW_AT_language:               return "DW_AT_language";
+    case DW_AT_member:                 return "DW_AT_member";
+    case DW_AT_discr:                  return "DW_AT_discr";
+    case DW_AT_discr_value:            return "DW_AT_discr_value";
+    case DW_AT_visibility:             return "DW_AT_visibility";
+    case DW_AT_import:                 return "DW_AT_import";
+    case DW_AT_string_length:          return "DW_AT_string_length";
+    case DW_AT_common_reference:       return "DW_AT_common_reference";
+    case DW_AT_comp_dir:               return "DW_AT_comp_dir";
+    case DW_AT_const_value:            return "DW_AT_const_value";
+    case DW_AT_containing_type:                return "DW_AT_containing_type";
+    case DW_AT_default_value:          return "DW_AT_default_value";
+    case DW_AT_inline:                 return "DW_AT_inline";
+    case DW_AT_is_optional:            return "DW_AT_is_optional";
+    case DW_AT_lower_bound:            return "DW_AT_lower_bound";
+    case DW_AT_producer:               return "DW_AT_producer";
+    case DW_AT_prototyped:             return "DW_AT_prototyped";
+    case DW_AT_return_addr:            return "DW_AT_return_addr";
+    case DW_AT_start_scope:            return "DW_AT_start_scope";
+    case DW_AT_stride_size:            return "DW_AT_stride_size";
+    case DW_AT_upper_bound:            return "DW_AT_upper_bound";
+    case DW_AT_abstract_origin:                return "DW_AT_abstract_origin";
+    case DW_AT_accessibility:          return "DW_AT_accessibility";
+    case DW_AT_address_class:          return "DW_AT_address_class";
+    case DW_AT_artificial:             return "DW_AT_artificial";
+    case DW_AT_base_types:             return "DW_AT_base_types";
+    case DW_AT_calling_convention:     return "DW_AT_calling_convention";
+    case DW_AT_count:                  return "DW_AT_count";
+    case DW_AT_data_member_location:   return "DW_AT_data_member_location";
+    case DW_AT_decl_column:            return "DW_AT_decl_column";
+    case DW_AT_decl_file:              return "DW_AT_decl_file";
+    case DW_AT_decl_line:              return "DW_AT_decl_line";
+    case DW_AT_declaration:            return "DW_AT_declaration";
+    case DW_AT_discr_list:             return "DW_AT_discr_list";
+    case DW_AT_encoding:               return "DW_AT_encoding";
+    case DW_AT_external:               return "DW_AT_external";
+    case DW_AT_frame_base:             return "DW_AT_frame_base";
+    case DW_AT_friend:                 return "DW_AT_friend";
+    case DW_AT_identifier_case:                return "DW_AT_identifier_case";
+    case DW_AT_macro_info:             return "DW_AT_macro_info";
+    case DW_AT_namelist_items:         return "DW_AT_namelist_items";
+    case DW_AT_priority:               return "DW_AT_priority";
+    case DW_AT_segment:                        return "DW_AT_segment";
+    case DW_AT_specification:          return "DW_AT_specification";
+    case DW_AT_static_link:            return "DW_AT_static_link";
+    case DW_AT_type:                   return "DW_AT_type";
+    case DW_AT_use_location:           return "DW_AT_use_location";
+    case DW_AT_variable_parameter:     return "DW_AT_variable_parameter";
+    case DW_AT_virtuality:             return "DW_AT_virtuality";
+    case DW_AT_vtable_elem_location:   return "DW_AT_vtable_elem_location";
+      /* DWARF 2.1 values.  */
+    case DW_AT_allocated:              return "DW_AT_allocated";
+    case DW_AT_associated:             return "DW_AT_associated";
+    case DW_AT_data_location:          return "DW_AT_data_location";
+    case DW_AT_stride:                 return "DW_AT_stride";
+    case DW_AT_entry_pc:               return "DW_AT_entry_pc";
+    case DW_AT_use_UTF8:               return "DW_AT_use_UTF8";
+    case DW_AT_extension:              return "DW_AT_extension";
+    case DW_AT_ranges:                 return "DW_AT_ranges";
+    case DW_AT_trampoline:             return "DW_AT_trampoline";
+    case DW_AT_call_column:            return "DW_AT_call_column";
+    case DW_AT_call_file:              return "DW_AT_call_file";
+    case DW_AT_call_line:              return "DW_AT_call_line";
+      /* SGI/MIPS extensions.  */
+    case DW_AT_MIPS_fde:               return "DW_AT_MIPS_fde";
+    case DW_AT_MIPS_loop_begin:                return "DW_AT_MIPS_loop_begin";
+    case DW_AT_MIPS_tail_loop_begin:   return "DW_AT_MIPS_tail_loop_begin";
+    case DW_AT_MIPS_epilog_begin:      return "DW_AT_MIPS_epilog_begin";
+    case DW_AT_MIPS_loop_unroll_factor: return "DW_AT_MIPS_loop_unroll_factor";
+    case DW_AT_MIPS_software_pipeline_depth:
+      return "DW_AT_MIPS_software_pipeline_depth";
+    case DW_AT_MIPS_linkage_name:      return "DW_AT_MIPS_linkage_name";
+    case DW_AT_MIPS_stride:            return "DW_AT_MIPS_stride";
+    case DW_AT_MIPS_abstract_name:     return "DW_AT_MIPS_abstract_name";
+    case DW_AT_MIPS_clone_origin:      return "DW_AT_MIPS_clone_origin";
+    case DW_AT_MIPS_has_inlines:       return "DW_AT_MIPS_has_inlines";
+      /* GNU extensions.  */
+    case DW_AT_sf_names:               return "DW_AT_sf_names";
+    case DW_AT_src_info:               return "DW_AT_src_info";
+    case DW_AT_mac_info:               return "DW_AT_mac_info";
+    case DW_AT_src_coords:             return "DW_AT_src_coords";
+    case DW_AT_body_begin:             return "DW_AT_body_begin";
+    case DW_AT_body_end:               return "DW_AT_body_end";
+    case DW_AT_GNU_vector:             return "DW_AT_GNU_vector";
+      /* UPC extension.  */
+    case DW_AT_upc_threads_scaled:     return "DW_AT_upc_threads_scaled";
+    default:
+      {
+       static char buffer[100];
+
+       sprintf (buffer, _("Unknown AT value: %lx"), attribute);
+       return buffer;
+      }
+    }
+}
+
+static char *
+get_FORM_name (form)
+     unsigned long form;
+{
+  switch (form)
+    {
+    case DW_FORM_addr:         return "DW_FORM_addr";
+    case DW_FORM_block2:       return "DW_FORM_block2";
+    case DW_FORM_block4:       return "DW_FORM_block4";
+    case DW_FORM_data2:                return "DW_FORM_data2";
+    case DW_FORM_data4:                return "DW_FORM_data4";
+    case DW_FORM_data8:                return "DW_FORM_data8";
+    case DW_FORM_string:       return "DW_FORM_string";
+    case DW_FORM_block:                return "DW_FORM_block";
+    case DW_FORM_block1:       return "DW_FORM_block1";
+    case DW_FORM_data1:                return "DW_FORM_data1";
+    case DW_FORM_flag:         return "DW_FORM_flag";
+    case DW_FORM_sdata:                return "DW_FORM_sdata";
+    case DW_FORM_strp:         return "DW_FORM_strp";
+    case DW_FORM_udata:                return "DW_FORM_udata";
+    case DW_FORM_ref_addr:     return "DW_FORM_ref_addr";
+    case DW_FORM_ref1:         return "DW_FORM_ref1";
+    case DW_FORM_ref2:         return "DW_FORM_ref2";
+    case DW_FORM_ref4:         return "DW_FORM_ref4";
+    case DW_FORM_ref8:         return "DW_FORM_ref8";
+    case DW_FORM_ref_udata:    return "DW_FORM_ref_udata";
+    case DW_FORM_indirect:     return "DW_FORM_indirect";
+    default:
+      {
+       static char buffer[100];
+
+       sprintf (buffer, _("Unknown FORM value: %lx"), form);
+       return buffer;
+      }
+    }
+}
+
+/* FIXME:  There are better and more effiecint ways to handle
+   these structures.  For now though, I just want something that
+   is simple to implement.  */
+typedef struct abbrev_attr
+{
+  unsigned long attribute;
+  unsigned long form;
+  struct abbrev_attr *next;
+}
+abbrev_attr;
+
+typedef struct abbrev_entry
+{
+  unsigned long entry;
+  unsigned long tag;
+  int children;
+  struct abbrev_attr *first_attr;
+  struct abbrev_attr *last_attr;
+  struct abbrev_entry *next;
+}
+abbrev_entry;
+
+static abbrev_entry *first_abbrev = NULL;
+static abbrev_entry *last_abbrev = NULL;
+
+static void
+free_abbrevs ()
+{
+  abbrev_entry *abbrev;
+
+  for (abbrev = first_abbrev; abbrev;)
+    {
+      abbrev_entry *next = abbrev->next;
+      abbrev_attr *attr;
+
+      for (attr = abbrev->first_attr; attr;)
+       {
+         abbrev_attr *next_attr = attr->next;
+
+         free (attr);
+         attr = next_attr;
+       }
+
+      free (abbrev);
+      abbrev = next;
+    }
+
+  last_abbrev = first_abbrev = NULL;
+}
+
+static void
+add_abbrev (number, tag, children)
+     unsigned long number;
+     unsigned long tag;
+     int children;
+{
+  abbrev_entry *entry;
+
+  entry = (abbrev_entry *) malloc (sizeof (*entry));
+
+  if (entry == NULL)
+    /* ugg */
+    return;
+
+  entry->entry      = number;
+  entry->tag        = tag;
+  entry->children   = children;
+  entry->first_attr = NULL;
+  entry->last_attr  = NULL;
+  entry->next       = NULL;
+
+  if (first_abbrev == NULL)
+    first_abbrev = entry;
+  else
+    last_abbrev->next = entry;
+
+  last_abbrev = entry;
+}
+
+static void
+add_abbrev_attr (attribute, form)
+     unsigned long attribute;
+     unsigned long form;
+{
+  abbrev_attr *attr;
+
+  attr = (abbrev_attr *) malloc (sizeof (*attr));
+
+  if (attr == NULL)
+    /* ugg */
+    return;
+
+  attr->attribute = attribute;
+  attr->form      = form;
+  attr->next      = NULL;
+
+  if (last_abbrev->first_attr == NULL)
+    last_abbrev->first_attr = attr;
+  else
+    last_abbrev->last_attr->next = attr;
+
+  last_abbrev->last_attr = attr;
+}
+
+/* Processes the (partial) contents of a .debug_abbrev section.
+   Returns NULL if the end of the section was encountered.
+   Returns the address after the last byte read if the end of
+   an abbreviation set was found.  */
+
+static unsigned char *
+process_abbrev_section (start, end)
+     unsigned char *start;
+     unsigned char *end;
+{
+  if (first_abbrev != NULL)
+    return NULL;
+
+  while (start < end)
+    {
+      int bytes_read;
+      unsigned long entry;
+      unsigned long tag;
+      unsigned long attribute;
+      int children;
+
+      entry = read_leb128 (start, & bytes_read, 0);
+      start += bytes_read;
+
+      /* A single zero is supposed to end the section according
+        to the standard.  If there's more, then signal that to
+        the caller.  */
+      if (entry == 0)
+       return start == end ? NULL : start;
+
+      tag = read_leb128 (start, & bytes_read, 0);
+      start += bytes_read;
+
+      children = *start++;
+
+      add_abbrev (entry, tag, children);
+
+      do
+       {
+         unsigned long form;
+
+         attribute = read_leb128 (start, & bytes_read, 0);
+         start += bytes_read;
+
+         form = read_leb128 (start, & bytes_read, 0);
+         start += bytes_read;
+
+         if (attribute != 0)
+           add_abbrev_attr (attribute, form);
+       }
+      while (attribute != 0);
+    }
+
+  return NULL;
+}
+
+
+static int
+display_debug_macinfo (section, start, file)
+     Elf_Internal_Shdr *section;
+     unsigned char *start;
+     FILE *file ATTRIBUTE_UNUSED;
+{
+  unsigned char *end = start + section->sh_size;
+  unsigned char *curr = start;
+  unsigned int bytes_read;
+  enum dwarf_macinfo_record_type op;
+
+  printf (_("Contents of the %s section:\n\n"), SECTION_NAME (section));
+
+  while (curr < end)
+    {
+      unsigned int lineno;
+      const char *string;
+
+      op = *curr;
+      curr++;
+
+      switch (op)
+       {
+       case DW_MACINFO_start_file:
+         {
+           unsigned int filenum;
+
+           lineno = read_leb128 (curr, & bytes_read, 0);
+           curr += bytes_read;
+           filenum = read_leb128 (curr, & bytes_read, 0);
+           curr += bytes_read;
+
+           printf (_(" DW_MACINFO_start_file - lineno: %d filenum: %d\n"), lineno, filenum);
+         }
+         break;
+
+       case DW_MACINFO_end_file:
+         printf (_(" DW_MACINFO_end_file\n"));
+         break;
+
+       case DW_MACINFO_define:
+         lineno = read_leb128 (curr, & bytes_read, 0);
+         curr += bytes_read;
+         string = curr;
+         curr += strlen (string) + 1;
+         printf (_(" DW_MACINFO_define - lineno : %d macro : %s\n"), lineno, string);
+         break;
+
+       case DW_MACINFO_undef:
+         lineno = read_leb128 (curr, & bytes_read, 0);
+         curr += bytes_read;
+         string = curr;
+         curr += strlen (string) + 1;
+         printf (_(" DW_MACINFO_undef - lineno : %d macro : %s\n"), lineno, string);
+         break;
+
+       case DW_MACINFO_vendor_ext:
+         {
+           unsigned int constant;
+
+           constant = read_leb128 (curr, & bytes_read, 0);
+           curr += bytes_read;
+           string = curr;
+           curr += strlen (string) + 1;
+           printf (_(" DW_MACINFO_vendor_ext - constant : %d string : %s\n"), constant, string);
+         }
+         break;
+       }
+    }
+
+  return 1;
+}
+
+
+static int
+display_debug_abbrev (section, start, file)
+     Elf_Internal_Shdr *section;
+     unsigned char *start;
+     FILE *file ATTRIBUTE_UNUSED;
+{
+  abbrev_entry *entry;
+  unsigned char *end = start + section->sh_size;
+
+  printf (_("Contents of the %s section:\n\n"), SECTION_NAME (section));
+
+  do
+    {
+      start = process_abbrev_section (start, end);
+
+      if (first_abbrev == NULL)
+       continue;
+
+      printf (_("  Number TAG\n"));
+
+      for (entry = first_abbrev; entry; entry = entry->next)
+       {
+         abbrev_attr *attr;
+
+         printf (_("   %ld      %s    [%s]\n"),
+                 entry->entry,
+                 get_TAG_name (entry->tag),
+                 entry->children ? _("has children") : _("no children"));
+
+         for (attr = entry->first_attr; attr; attr = attr->next)
+           {
+             printf (_("    %-18s %s\n"),
+                     get_AT_name (attr->attribute),
+                     get_FORM_name (attr->form));
+           }
+       }
+
+      free_abbrevs ();
+    }
+  while (start);
+
+  printf ("\n");
+
+  return 1;
+}
+
+
+static unsigned char *
+display_block (data, length, ok_to_harvest)
+     unsigned char *data;
+     unsigned long length;
+     char ok_to_harvest;
+{
+  if (print_results && ok_to_harvest)
+    printf (_(" %lu byte block: "), length);
+
+  while (length --)
+    {
+      unsigned long temp = (unsigned long) byte_get (data++, 1);
+      if (print_results && ok_to_harvest)
+        printf ("%lx ", temp);
+      //    printf ("%lx ", (unsigned long) byte_get (data++, 1));
+    }
+
+  return data;
+}
+
+static void
+decode_location_expression (data, pointer_size, length, ok_to_harvest, location_data)
+     unsigned char * data;
+     unsigned int pointer_size;
+     unsigned long length;
+     char ok_to_harvest;
+     long* location_data;
+{
+  unsigned op;
+  int bytes_read;
+  unsigned long uvalue;
+  unsigned char *end = data + length;
+
+  int print_results_and_ok = print_results && ok_to_harvest;
+
+  while (data < end)
+    {
+      op = *data++;
+
+      switch (op)
+       {
+       case DW_OP_addr:
+          if (print_results_and_ok)
+            {
+              printf ("DW_OP_addr: %lx",
+                      (unsigned long) byte_get (data, pointer_size));
+              data += pointer_size;
+            }
+          else
+            {
+              byte_get (data, pointer_size);
+              data += pointer_size;
+            }
+         break;
+       case DW_OP_deref:
+         if (print_results_and_ok) {printf ("DW_OP_deref");}
+         break;
+       case DW_OP_const1u:
+         if (print_results_and_ok) {printf ("DW_OP_const1u: %lu", (unsigned long) byte_get (data++, 1));}
+          else {byte_get (data++, 1);}
+         break;
+       case DW_OP_const1s:
+         if (print_results_and_ok) {printf ("DW_OP_const1s: %ld", (long) byte_get (data++, 1));}
+          else {byte_get (data++, 1);}
+         break;
+       case DW_OP_const2u:
+          if (print_results_and_ok)
+            {
+              printf ("DW_OP_const2u: %lu", (unsigned long) byte_get (data, 2));
+              data += 2;
+            }
+          else
+            {
+              byte_get (data, 2);
+              data += 2;
+            }
+         break;
+       case DW_OP_const2s:
+          if (print_results_and_ok)
+            {
+              printf ("DW_OP_const2s: %ld", (long) byte_get (data, 2));
+              data += 2;
+            }
+          else
+            {
+              byte_get (data, 2);
+              data += 2;
+            }
+         break;
+       case DW_OP_const4u:
+          if (print_results_and_ok)
+            {
+              printf ("DW_OP_const4u: %lu", (unsigned long) byte_get (data, 4));
+              data += 4;
+            }
+          else
+            {
+              byte_get (data, 4);
+              data += 4;
+            }
+         break;
+       case DW_OP_const4s:
+          if (print_results_and_ok)
+            {
+              printf ("DW_OP_const4s: %ld", (long) byte_get (data, 4));
+              data += 4;
+            }
+          else
+            {
+              byte_get (data, 4);
+              data += 4;
+            }
+         break;
+       case DW_OP_const8u:
+          if (print_results_and_ok)
+            {
+              printf ("DW_OP_const8u: %lu %lu", (unsigned long) byte_get (data, 4),
+                      (unsigned long) byte_get (data + 4, 4));
+              data += 8;
+            }
+          else
+            {
+              byte_get (data, 4);
+              byte_get (data + 4, 4);
+              data += 8;
+            }
+         break;
+       case DW_OP_const8s:
+          if (print_results_and_ok)
+            {
+              printf ("DW_OP_const8s: %ld %ld", (long) byte_get (data, 4),
+                      (long) byte_get (data + 4, 4));
+              data += 8;
+            }
+          else
+            {
+              byte_get (data, 4);
+              byte_get (data + 4, 4);
+              data += 8;
+            }
+         break;
+       case DW_OP_constu:
+          if (print_results_and_ok)
+            {
+              printf ("DW_OP_constu: %lu", read_leb128 (data, &bytes_read, 0));
+              data += bytes_read;
+            }
+          else
+            {
+              read_leb128 (data, &bytes_read, 0);
+              data += bytes_read;
+            }
+         break;
+       case DW_OP_consts:
+          if (print_results_and_ok)
+            {
+              printf ("DW_OP_consts: %ld", read_leb128 (data, &bytes_read, 1));
+              data += bytes_read;
+            }
+          else
+            {
+              read_leb128 (data, &bytes_read, 1);
+              data += bytes_read;
+            }
+         break;
+       case DW_OP_dup:
+         if (print_results_and_ok) printf ("DW_OP_dup");
+         break;
+       case DW_OP_drop:
+         if (print_results_and_ok) printf ("DW_OP_drop");
+         break;
+       case DW_OP_over:
+         if (print_results_and_ok) printf ("DW_OP_over");
+         break;
+       case DW_OP_pick:
+         if (print_results_and_ok)
+            {
+              printf ("DW_OP_pick: %ld", (unsigned long) byte_get (data++, 1));
+            }
+          else
+            {
+              byte_get (data++, 1);
+            }
+         break;
+       case DW_OP_swap:
+         if (print_results_and_ok) printf ("DW_OP_swap");
+         break;
+       case DW_OP_rot:
+         if (print_results_and_ok) printf ("DW_OP_rot");
+         break;
+       case DW_OP_xderef:
+         if (print_results_and_ok) printf ("DW_OP_xderef");
+         break;
+       case DW_OP_abs:
+         if (print_results_and_ok) printf ("DW_OP_abs");
+         break;
+       case DW_OP_and:
+         if (print_results_and_ok) printf ("DW_OP_and");
+         break;
+       case DW_OP_div:
+         if (print_results_and_ok) printf ("DW_OP_div");
+         break;
+       case DW_OP_minus:
+         if (print_results_and_ok) printf ("DW_OP_minus");
+         break;
+       case DW_OP_mod:
+         if (print_results_and_ok) printf ("DW_OP_mod");
+         break;
+       case DW_OP_mul:
+         if (print_results_and_ok) printf ("DW_OP_mul");
+         break;
+       case DW_OP_neg:
+         if (print_results_and_ok) printf ("DW_OP_neg");
+         break;
+       case DW_OP_not:
+         if (print_results_and_ok) printf ("DW_OP_not");
+         break;
+       case DW_OP_or:
+         if (print_results_and_ok) printf ("DW_OP_or");
+         break;
+       case DW_OP_plus:
+         if (print_results_and_ok) printf ("DW_OP_plus");
+         break;
+       case DW_OP_plus_uconst:
+         if (ok_to_harvest && location_data)
+            {
+              unsigned long uconst_data = read_leb128 (data, &bytes_read, 0);
+              *location_data = (long)uconst_data;
+              if (print_results)
+                {
+                  printf ("DW_OP_plus_uconst: %lu",
+                          uconst_data);
+                }
+              data += bytes_read;
+            }
+          else
+            {
+              read_leb128 (data, &bytes_read, 0);
+              data += bytes_read;
+            }
+         break;
+       case DW_OP_shl:
+         if (print_results_and_ok) printf ("DW_OP_shl");
+         break;
+       case DW_OP_shr:
+         if (print_results_and_ok) printf ("DW_OP_shr");
+         break;
+       case DW_OP_shra:
+         if (print_results_and_ok) printf ("DW_OP_shra");
+         break;
+       case DW_OP_xor:
+         if (print_results_and_ok) printf ("DW_OP_xor");
+         break;
+       case DW_OP_bra:
+          if (print_results_and_ok)
+            {
+              printf ("DW_OP_bra: %ld", (long) byte_get (data, 2));
+              data += 2;
+            }
+          else
+            {
+              byte_get (data, 2);
+              data += 2;
+            }
+         break;
+       case DW_OP_eq:
+         if (print_results_and_ok) printf ("DW_OP_eq");
+         break;
+       case DW_OP_ge:
+         if (print_results_and_ok) printf ("DW_OP_ge");
+         break;
+       case DW_OP_gt:
+         if (print_results_and_ok) printf ("DW_OP_gt");
+         break;
+       case DW_OP_le:
+         if (print_results_and_ok) printf ("DW_OP_le");
+         break;
+       case DW_OP_lt:
+         if (print_results_and_ok) printf ("DW_OP_lt");
+         break;
+       case DW_OP_ne:
+         if (print_results_and_ok) printf ("DW_OP_ne");
+         break;
+       case DW_OP_skip:
+          if (print_results_and_ok)
+            {
+              printf ("DW_OP_skip: %ld", (long) byte_get (data, 2));
+              data += 2;
+            }
+          else
+            {
+              byte_get (data, 2);
+              data += 2;
+            }
+         break;
+
+       case DW_OP_lit0:
+       case DW_OP_lit1:
+       case DW_OP_lit2:
+       case DW_OP_lit3:
+       case DW_OP_lit4:
+       case DW_OP_lit5:
+       case DW_OP_lit6:
+       case DW_OP_lit7:
+       case DW_OP_lit8:
+       case DW_OP_lit9:
+       case DW_OP_lit10:
+       case DW_OP_lit11:
+       case DW_OP_lit12:
+       case DW_OP_lit13:
+       case DW_OP_lit14:
+       case DW_OP_lit15:
+       case DW_OP_lit16:
+       case DW_OP_lit17:
+       case DW_OP_lit18:
+       case DW_OP_lit19:
+       case DW_OP_lit20:
+       case DW_OP_lit21:
+       case DW_OP_lit22:
+       case DW_OP_lit23:
+       case DW_OP_lit24:
+       case DW_OP_lit25:
+       case DW_OP_lit26:
+       case DW_OP_lit27:
+       case DW_OP_lit28:
+       case DW_OP_lit29:
+       case DW_OP_lit30:
+       case DW_OP_lit31:
+         if (print_results_and_ok) printf ("DW_OP_lit%d", op - DW_OP_lit0);
+         break;
+
+       case DW_OP_reg0:
+       case DW_OP_reg1:
+       case DW_OP_reg2:
+       case DW_OP_reg3:
+       case DW_OP_reg4:
+       case DW_OP_reg5:
+       case DW_OP_reg6:
+       case DW_OP_reg7:
+       case DW_OP_reg8:
+       case DW_OP_reg9:
+       case DW_OP_reg10:
+       case DW_OP_reg11:
+       case DW_OP_reg12:
+       case DW_OP_reg13:
+       case DW_OP_reg14:
+       case DW_OP_reg15:
+       case DW_OP_reg16:
+       case DW_OP_reg17:
+       case DW_OP_reg18:
+       case DW_OP_reg19:
+       case DW_OP_reg20:
+       case DW_OP_reg21:
+       case DW_OP_reg22:
+       case DW_OP_reg23:
+       case DW_OP_reg24:
+       case DW_OP_reg25:
+       case DW_OP_reg26:
+       case DW_OP_reg27:
+       case DW_OP_reg28:
+       case DW_OP_reg29:
+       case DW_OP_reg30:
+       case DW_OP_reg31:
+         if (print_results_and_ok) printf ("DW_OP_reg%d", op - DW_OP_reg0);
+         break;
+
+       case DW_OP_breg0:
+       case DW_OP_breg1:
+       case DW_OP_breg2:
+       case DW_OP_breg3:
+       case DW_OP_breg4:
+       case DW_OP_breg5:
+       case DW_OP_breg6:
+       case DW_OP_breg7:
+       case DW_OP_breg8:
+       case DW_OP_breg9:
+       case DW_OP_breg10:
+       case DW_OP_breg11:
+       case DW_OP_breg12:
+       case DW_OP_breg13:
+       case DW_OP_breg14:
+       case DW_OP_breg15:
+       case DW_OP_breg16:
+       case DW_OP_breg17:
+       case DW_OP_breg18:
+       case DW_OP_breg19:
+       case DW_OP_breg20:
+       case DW_OP_breg21:
+       case DW_OP_breg22:
+       case DW_OP_breg23:
+       case DW_OP_breg24:
+       case DW_OP_breg25:
+       case DW_OP_breg26:
+       case DW_OP_breg27:
+       case DW_OP_breg28:
+       case DW_OP_breg29:
+       case DW_OP_breg30:
+       case DW_OP_breg31:
+          if (print_results_and_ok)
+            {
+              printf ("DW_OP_breg%d: %ld", op - DW_OP_breg0,
+                      read_leb128 (data, &bytes_read, 1));
+              data += bytes_read;
+            }
+          else
+            {
+              read_leb128 (data, &bytes_read, 1);
+              data += bytes_read;
+            }
+         break;
+
+       case DW_OP_regx:
+          if (print_results_and_ok)
+            {
+              printf ("DW_OP_regx: %lu", read_leb128 (data, &bytes_read, 0));
+              data += bytes_read;
+            }
+          else
+            {
+              read_leb128 (data, &bytes_read, 0);
+              data += bytes_read;
+            }
+         break;
+       case DW_OP_fbreg:
+          if (ok_to_harvest && location_data)
+            {
+              unsigned long fbreg_value = read_leb128 (data, &bytes_read, 1);
+              *location_data = (long)fbreg_value;
+              if (print_results_and_ok)
+                {
+                  printf ("DW_OP_fbreg: %ld", fbreg_value);
+                }
+              data += bytes_read;
+            }
+          else
+            {
+              read_leb128 (data, &bytes_read, 1);
+              data += bytes_read;
+            }
+         break;
+       case DW_OP_bregx:
+          if (print_results_and_ok)
+            {
+              uvalue = read_leb128 (data, &bytes_read, 0);
+              data += bytes_read;
+              printf ("DW_OP_bregx: %lu %ld", uvalue,
+                      read_leb128 (data, &bytes_read, 1));
+              data += bytes_read;
+            }
+          else
+            {
+              uvalue = read_leb128 (data, &bytes_read, 0);
+              data += bytes_read;
+              read_leb128 (data, &bytes_read, 1);
+              data += bytes_read;
+            }
+          break;
+       case DW_OP_piece:
+          if (print_results_and_ok)
+            {
+              printf ("DW_OP_piece: %lu", read_leb128 (data, &bytes_read, 0));
+              data += bytes_read;
+            }
+          else
+            {
+              read_leb128 (data, &bytes_read, 0);
+              data += bytes_read;
+            }
+         break;
+       case DW_OP_deref_size:
+          if (print_results_and_ok)
+            {
+              printf ("DW_OP_deref_size: %ld", (long) byte_get (data++, 1));
+            }
+          else
+            {
+              byte_get (data++, 1);
+            }
+         break;
+       case DW_OP_xderef_size:
+          if (print_results_and_ok)
+            {
+              printf ("DW_OP_xderef_size: %ld", (long) byte_get (data++, 1));
+            }
+          else
+            {
+              byte_get (data++, 1);
+            }
+         break;
+       case DW_OP_nop:
+         if (print_results_and_ok) printf ("DW_OP_nop");
+         break;
+
+         /* DWARF 3 extensions.  */
+       case DW_OP_push_object_address:
+         if (print_results_and_ok) printf ("DW_OP_push_object_address");
+         break;
+       case DW_OP_call2:
+          if (print_results_and_ok)
+            {
+              printf ("DW_OP_call2: <%lx>", (long) byte_get (data, 2));
+              data += 2;
+            }
+          else
+            {
+              byte_get (data, 2);
+              data += 2;
+            }
+         break;
+       case DW_OP_call4:
+          if (print_results_and_ok)
+            {
+              printf ("DW_OP_call4: <%lx>", (long) byte_get (data, 4));
+              data += 4;
+            }
+          else
+            {
+              byte_get (data, 4);
+              data += 4;
+            }
+         break;
+       case DW_OP_call_ref:
+         if (print_results_and_ok) printf ("DW_OP_call_ref");
+         break;
+
+         /* GNU extensions.  */
+       case DW_OP_GNU_push_tls_address:
+         if (print_results_and_ok) printf ("DW_OP_GNU_push_tls_address");
+         break;
+
+       default:
+         if (op >= DW_OP_lo_user
+             && op <= DW_OP_hi_user)
+           printf (_("(User defined location op)"));
+         else
+           printf (_("(Unknown location op)"));
+         /* No way to tell where the next op is, so just bail.  */
+         return;
+       }
+
+      /* Separate the ops.  */
+      if (data < end)
+        {
+          if (print_results_and_ok)
+            printf ("; ");
+        }
+    }
+}
+
+/*
+  unsigned op;
+  int bytes_read;
+  unsigned long uvalue;
+  unsigned char *end = data + length;
+
+  while (data < end)
+    {
+      op = *data++;
+
+      switch (op)
+       {
+       case DW_OP_addr:
+         if (display) printf ("DW_OP_addr: %lx",
+                 (unsigned long) byte_get (data, pointer_size));
+         data += pointer_size;
+         break;
+       case DW_OP_deref:
+         if (display) printf ("DW_OP_deref");
+         break;
+       case DW_OP_const1u:
+         if (display) printf ("DW_OP_const1u: %lu", (unsigned long) byte_get (data++, 1));
+          else data++;
+         break;
+       case DW_OP_const1s:
+         if (display) printf ("DW_OP_const1s: %ld", (long) byte_get (data++, 1));
+          else data++;
+         break;
+       case DW_OP_const2u:
+         if (display) printf ("DW_OP_const2u: %lu", (unsigned long) byte_get (data, 2));
+         data += 2;
+         break;
+       case DW_OP_const2s:
+         if (display) printf ("DW_OP_const2s: %ld", (long) byte_get (data, 2));
+         data += 2;
+         break;
+       case DW_OP_const4u:
+         if (display) printf ("DW_OP_const4u: %lu", (unsigned long) byte_get (data, 4));
+         data += 4;
+         break;
+       case DW_OP_const4s:
+         if (display) printf ("DW_OP_const4s: %ld", (long) byte_get (data, 4));
+         data += 4;
+         break;
+       case DW_OP_const8u:
+         if (display) printf ("DW_OP_const8u: %lu %lu", (unsigned long) byte_get (data, 4),
+                 (unsigned long) byte_get (data + 4, 4));
+         data += 8;
+         break;
+       case DW_OP_const8s:
+         if (display) printf ("DW_OP_const8s: %ld %ld", (long) byte_get (data, 4),
+                 (long) byte_get (data + 4, 4));
+         data += 8;
+         break;
+       case DW_OP_constu:
+         if (display) printf ("DW_OP_constu: %lu", read_leb128 (data, &bytes_read, 0));
+         data += bytes_read;
+         break;
+       case DW_OP_consts:
+         if (display) printf ("DW_OP_consts: %ld", read_leb128 (data, &bytes_read, 1));
+         data += bytes_read;
+         break;
+       case DW_OP_dup:
+         if (display) printf ("DW_OP_dup");
+         break;
+       case DW_OP_drop:
+         if (display) printf ("DW_OP_drop");
+         break;
+       case DW_OP_over:
+         if (display) printf ("DW_OP_over");
+         break;
+       case DW_OP_pick:
+         if (display) printf ("DW_OP_pick: %ld", (unsigned long) byte_get (data++, 1));
+          else data++;
+         break;
+       case DW_OP_swap:
+         if (display) printf ("DW_OP_swap");
+         break;
+       case DW_OP_rot:
+         if (display) printf ("DW_OP_rot");
+         break;
+       case DW_OP_xderef:
+         if (display) printf ("DW_OP_xderef");
+         break;
+       case DW_OP_abs:
+         if (display) printf ("DW_OP_abs");
+         break;
+       case DW_OP_and:
+         if (display) printf ("DW_OP_and");
+         break;
+       case DW_OP_div:
+         if (display) printf ("DW_OP_div");
+         break;
+       case DW_OP_minus:
+         if (display) printf ("DW_OP_minus");
+         break;
+       case DW_OP_mod:
+         if (display) printf ("DW_OP_mod");
+         break;
+       case DW_OP_mul:
+         if (display) printf ("DW_OP_mul");
+         break;
+       case DW_OP_neg:
+         if (display) printf ("DW_OP_neg");
+         break;
+       case DW_OP_not:
+         if (display) printf ("DW_OP_not");
+         break;
+       case DW_OP_or:
+         if (display) printf ("DW_OP_or");
+         break;
+       case DW_OP_plus:
+         if (display) printf ("DW_OP_plus");
+         break;
+       case DW_OP_plus_uconst:
+         if (display)
+            {
+              unsigned long uconst_data = read_leb128 (data, &bytes_read, 0);
+              if (location_data)
+                *location_data = (long)uconst_data;
+              printf ("DW_OP_plus_uconst: %lu",
+                      uconst_data);
+            }
+         data += bytes_read;
+         break;
+       case DW_OP_shl:
+         if (display) printf ("DW_OP_shl");
+         break;
+       case DW_OP_shr:
+         if (display) printf ("DW_OP_shr");
+         break;
+       case DW_OP_shra:
+         if (display) printf ("DW_OP_shra");
+         break;
+       case DW_OP_xor:
+         if (display) printf ("DW_OP_xor");
+         break;
+       case DW_OP_bra:
+         if (display) printf ("DW_OP_bra: %ld", (long) byte_get (data, 2));
+         data += 2;
+         break;
+       case DW_OP_eq:
+         if (display) printf ("DW_OP_eq");
+         break;
+       case DW_OP_ge:
+         if (display) printf ("DW_OP_ge");
+         break;
+       case DW_OP_gt:
+         if (display) printf ("DW_OP_gt");
+         break;
+       case DW_OP_le:
+         if (display) printf ("DW_OP_le");
+         break;
+       case DW_OP_lt:
+         if (display) printf ("DW_OP_lt");
+         break;
+       case DW_OP_ne:
+         if (display) printf ("DW_OP_ne");
+         break;
+       case DW_OP_skip:
+         if (display) printf ("DW_OP_skip: %ld", (long) byte_get (data, 2));
+         data += 2;
+         break;
+
+       case DW_OP_lit0:
+       case DW_OP_lit1:
+       case DW_OP_lit2:
+       case DW_OP_lit3:
+       case DW_OP_lit4:
+       case DW_OP_lit5:
+       case DW_OP_lit6:
+       case DW_OP_lit7:
+       case DW_OP_lit8:
+       case DW_OP_lit9:
+       case DW_OP_lit10:
+       case DW_OP_lit11:
+       case DW_OP_lit12:
+       case DW_OP_lit13:
+       case DW_OP_lit14:
+       case DW_OP_lit15:
+       case DW_OP_lit16:
+       case DW_OP_lit17:
+       case DW_OP_lit18:
+       case DW_OP_lit19:
+       case DW_OP_lit20:
+       case DW_OP_lit21:
+       case DW_OP_lit22:
+       case DW_OP_lit23:
+       case DW_OP_lit24:
+       case DW_OP_lit25:
+       case DW_OP_lit26:
+       case DW_OP_lit27:
+       case DW_OP_lit28:
+       case DW_OP_lit29:
+       case DW_OP_lit30:
+       case DW_OP_lit31:
+         if (display) printf ("DW_OP_lit%d", op - DW_OP_lit0);
+         break;
+
+       case DW_OP_reg0:
+       case DW_OP_reg1:
+       case DW_OP_reg2:
+       case DW_OP_reg3:
+       case DW_OP_reg4:
+       case DW_OP_reg5:
+       case DW_OP_reg6:
+       case DW_OP_reg7:
+       case DW_OP_reg8:
+       case DW_OP_reg9:
+       case DW_OP_reg10:
+       case DW_OP_reg11:
+       case DW_OP_reg12:
+       case DW_OP_reg13:
+       case DW_OP_reg14:
+       case DW_OP_reg15:
+       case DW_OP_reg16:
+       case DW_OP_reg17:
+       case DW_OP_reg18:
+       case DW_OP_reg19:
+       case DW_OP_reg20:
+       case DW_OP_reg21:
+       case DW_OP_reg22:
+       case DW_OP_reg23:
+       case DW_OP_reg24:
+       case DW_OP_reg25:
+       case DW_OP_reg26:
+       case DW_OP_reg27:
+       case DW_OP_reg28:
+       case DW_OP_reg29:
+       case DW_OP_reg30:
+       case DW_OP_reg31:
+         if (display) printf ("DW_OP_reg%d", op - DW_OP_reg0);
+         break;
+
+       case DW_OP_breg0:
+       case DW_OP_breg1:
+       case DW_OP_breg2:
+       case DW_OP_breg3:
+       case DW_OP_breg4:
+       case DW_OP_breg5:
+       case DW_OP_breg6:
+       case DW_OP_breg7:
+       case DW_OP_breg8:
+       case DW_OP_breg9:
+       case DW_OP_breg10:
+       case DW_OP_breg11:
+       case DW_OP_breg12:
+       case DW_OP_breg13:
+       case DW_OP_breg14:
+       case DW_OP_breg15:
+       case DW_OP_breg16:
+       case DW_OP_breg17:
+       case DW_OP_breg18:
+       case DW_OP_breg19:
+       case DW_OP_breg20:
+       case DW_OP_breg21:
+       case DW_OP_breg22:
+       case DW_OP_breg23:
+       case DW_OP_breg24:
+       case DW_OP_breg25:
+       case DW_OP_breg26:
+       case DW_OP_breg27:
+       case DW_OP_breg28:
+       case DW_OP_breg29:
+       case DW_OP_breg30:
+       case DW_OP_breg31:
+         if (display) printf ("DW_OP_breg%d: %ld", op - DW_OP_breg0,
+                 read_leb128 (data, &bytes_read, 1));
+         data += bytes_read;
+         break;
+
+       case DW_OP_regx:
+         if (display) printf ("DW_OP_regx: %lu", read_leb128 (data, &bytes_read, 0));
+         data += bytes_read;
+         break;
+       case DW_OP_fbreg:
+         if (display)
+            {
+              unsigned long fbreg_value = read_leb128 (data, &bytes_read, 1);
+              if (location_data)
+                *location_data = (long)fbreg_value;
+              printf ("DW_OP_fbreg: %ld", fbreg_value);
+            }
+         data += bytes_read;
+         break;
+       case DW_OP_bregx:
+         uvalue = read_leb128 (data, &bytes_read, 0);
+         data += bytes_read;
+         if (display) printf ("DW_OP_bregx: %lu %ld", uvalue,
+                 read_leb128 (data, &bytes_read, 1));
+         data += bytes_read;
+         break;
+       case DW_OP_piece:
+         if (display) printf ("DW_OP_piece: %lu", read_leb128 (data, &bytes_read, 0));
+         data += bytes_read;
+         break;
+       case DW_OP_deref_size:
+         if (display) printf ("DW_OP_deref_size: %ld", (long) byte_get (data++, 1));
+          else data++;
+         break;
+       case DW_OP_xderef_size:
+         if (display) printf ("DW_OP_xderef_size: %ld", (long) byte_get (data++, 1));
+          else data++;
+         break;
+       case DW_OP_nop:
+         if (display) printf ("DW_OP_nop");
+         break;
+
+         // DWARF 3 extensions.
+       case DW_OP_push_object_address:
+         if (display) printf ("DW_OP_push_object_address");
+         break;
+       case DW_OP_call2:
+         if (display) printf ("DW_OP_call2: <%lx>", (long) byte_get (data, 2));
+         data += 2;
+         break;
+       case DW_OP_call4:
+         if (display) printf ("DW_OP_call4: <%lx>", (long) byte_get (data, 4));
+         data += 4;
+         break;
+       case DW_OP_call_ref:
+         if (display) printf ("DW_OP_call_ref");
+         break;
+
+         // GNU extensions.
+       case DW_OP_GNU_push_tls_address:
+         if (display) printf ("DW_OP_GNU_push_tls_address");
+         break;
+
+       default:
+         if (op >= DW_OP_lo_user
+             && op <= DW_OP_hi_user)
+            {
+              if (display) printf (_("(User defined location op)"));
+            }
+         else
+            {
+              if (display) printf (_("(Unknown location op)"));
+            }
+         // No way to tell where the next op is, so just bail.
+         return;
+       }
+
+      // Separate the ops.
+      if (data < end)
+        {
+          if (display) printf ("; ");
+        }
+    }
+}
+*/
+
+static const char *debug_loc_contents;
+static bfd_vma debug_loc_size;
+
+static void
+load_debug_loc (file)
+     FILE *file;
+{
+  Elf_Internal_Shdr *sec;
+  unsigned int i;
+
+  /* If it is already loaded, do nothing.  */
+  if (debug_loc_contents != NULL)
+    return;
+
+  /* Locate the .debug_loc section.  */
+  for (i = 0, sec = section_headers;
+       i < elf_header.e_shnum;
+       i++, sec++)
+    if (strcmp (SECTION_NAME (sec), ".debug_loc") == 0)
+      break;
+
+  if (i == elf_header.e_shnum || sec->sh_size == 0)
+    return;
+
+  debug_loc_size = sec->sh_size;
+
+  debug_loc_contents = ((char *)
+                       get_data (NULL, file, sec->sh_offset, sec->sh_size,
+                                 _("debug_loc section data")));
+}
+
+static void
+free_debug_loc ()
+{
+  if (debug_loc_contents == NULL)
+    return;
+
+  free ((char *) debug_loc_contents);
+  debug_loc_contents = NULL;
+  debug_loc_size = 0;
+}
+
+
+static int
+display_debug_loc (section, start, file)
+     Elf_Internal_Shdr *section;
+     unsigned char *start;
+     FILE *file ATTRIBUTE_UNUSED;
+{
+  unsigned char *section_end;
+  unsigned long bytes;
+  unsigned char *section_begin = start;
+  bfd_vma addr;
+
+  addr = section->sh_addr;
+  bytes = section->sh_size;
+  section_end = start + bytes;
+
+  if (bytes == 0)
+    {
+      printf (_("\nThe .debug_loc section is empty.\n"));
+      return 0;
+    }
+
+  printf (_("Contents of the .debug_loc section:\n\n"));
+  printf (_("\n    Offset   Begin    End      Expression\n"));
+
+  while (start < section_end)
+    {
+      unsigned long begin;
+      unsigned long end;
+      unsigned short length;
+      unsigned long offset;
+
+      offset = start - section_begin;
+
+      while (1)
+       {
+         /* Normally, the lists in the debug_loc section are related to a
+            given compilation unit, and thus, we would use the pointer size
+            of that compilation unit.  However, since we are displaying it
+            seperately here, we either have to store pointer sizes of all
+            compilation units, or assume they don't change.   We assume,
+            like the debug_line display, that it doesn't change.  */
+         begin = byte_get (start, debug_line_pointer_size);
+         start += debug_line_pointer_size;
+         end = byte_get (start, debug_line_pointer_size);
+         start += debug_line_pointer_size;
+
+         if (begin == 0 && end == 0)
+           break;
+
+         /* For now, skip any base address specifiers.  */
+         if (begin == 0xffffffff)
+           continue;
+
+         begin += addr;
+         end += addr;
+
+         length = byte_get (start, 2);
+         start += 2;
+
+         printf ("    %8.8lx %8.8lx %8.8lx (", offset, begin, end);
+         decode_location_expression (start, debug_line_pointer_size, length, 1, 0);
+         printf (")\n");
+
+         start += length;
+       }
+      printf ("\n");
+    }
+  return 1;
+}
+
+static const char *debug_str_contents;
+static bfd_vma debug_str_size;
+
+static void
+load_debug_str (file)
+     FILE *file;
+{
+  Elf_Internal_Shdr *sec;
+  unsigned int i;
+
+  /* If it is already loaded, do nothing.  */
+  if (debug_str_contents != NULL)
+    return;
+
+  /* Locate the .debug_str section.  */
+  for (i = 0, sec = section_headers;
+       i < elf_header.e_shnum;
+       i++, sec++)
+    if (strcmp (SECTION_NAME (sec), ".debug_str") == 0)
+      break;
+
+  if (i == elf_header.e_shnum || sec->sh_size == 0)
+    return;
+
+  debug_str_size = sec->sh_size;
+
+  debug_str_contents = ((char *)
+                       get_data (NULL, file, sec->sh_offset, sec->sh_size,
+                                 _("debug_str section data")));
+}
+
+static void
+free_debug_str ()
+{
+  if (debug_str_contents == NULL)
+    return;
+
+  free ((char *) debug_str_contents);
+  debug_str_contents = NULL;
+  debug_str_size = 0;
+}
+
+static const char *
+fetch_indirect_string (offset)
+     unsigned long offset;
+{
+  if (debug_str_contents == NULL)
+    return _("<no .debug_str section>");
+
+  if (offset > debug_str_size)
+    return _("<offset is too big>");
+
+  return debug_str_contents + offset;
+}
+
+static int
+display_debug_str (section, start, file)
+     Elf_Internal_Shdr *section;
+     unsigned char *start;
+     FILE *file ATTRIBUTE_UNUSED;
+{
+  unsigned long bytes;
+  bfd_vma addr;
+
+  addr  = section->sh_addr;
+  bytes = section->sh_size;
+
+  if (bytes == 0)
+    {
+      printf (_("\nThe .debug_str section is empty.\n"));
+      return 0;
+    }
+
+  printf (_("Contents of the .debug_str section:\n\n"));
+
+  while (bytes)
+    {
+      int j;
+      int k;
+      int lbytes;
+
+      lbytes = (bytes > 16 ? 16 : bytes);
+
+      printf ("  0x%8.8lx ", (unsigned long) addr);
+
+      for (j = 0; j < 16; j++)
+       {
+         if (j < lbytes)
+           printf ("%2.2x", start[j]);
+         else
+           printf ("  ");
+
+         if ((j & 3) == 3)
+           printf (" ");
+       }
+
+      for (j = 0; j < lbytes; j++)
+       {
+         k = start[j];
+         if (k >= ' ' && k < 0x80)
+           printf ("%c", k);
+         else
+           printf (".");
+       }
+
+      putchar ('\n');
+
+      start += lbytes;
+      addr  += lbytes;
+      bytes -= lbytes;
+    }
+
+  return 1;
+}
+
+static unsigned char *
+read_and_display_attr_value (attribute, form, data, cu_offset, pointer_size,
+                             offset_size, dwarf_version, entry, ok)
+     unsigned long attribute;
+     unsigned long form;
+     unsigned char *data;
+     unsigned long cu_offset;
+     unsigned long pointer_size;
+     unsigned long offset_size;
+     int dwarf_version;
+     dwarf_entry* entry;
+     char ok;
+{
+  unsigned long uvalue = 0;
+  unsigned char *block_start = NULL;
+  int bytes_read;
+
+  int print_results_and_ok = print_results && ok;
+
+  switch (form)
+    {
+    default:
+      break;
+
+    case DW_FORM_ref_addr:
+      if (dwarf_version == 2)
+       {
+         uvalue = byte_get (data, pointer_size);
+         data += pointer_size;
+       }
+      else if (dwarf_version == 3)
+       {
+         uvalue = byte_get (data, offset_size);
+         data += offset_size;
+       }
+      else
+        {
+         error (_("Internal error: DWARF version is not 2 or 3.\n"));
+       }
+      break;
+
+    case DW_FORM_addr:
+      uvalue = byte_get (data, pointer_size);
+      data += pointer_size;
+      break;
+
+    case DW_FORM_strp:
+      uvalue = byte_get (data, offset_size);
+      data += offset_size;
+      break;
+
+    case DW_FORM_ref1:
+    case DW_FORM_flag:
+    case DW_FORM_data1:
+      uvalue = byte_get (data++, 1);
+      break;
+
+    case DW_FORM_ref2:
+    case DW_FORM_data2:
+      uvalue = byte_get (data, 2);
+      data += 2;
+      break;
+
+    case DW_FORM_ref4:
+    case DW_FORM_data4:
+      uvalue = byte_get (data, 4);
+      data += 4;
+      break;
+
+    case DW_FORM_sdata:
+      uvalue = read_leb128 (data, & bytes_read, 1);
+      data += bytes_read;
+      break;
+
+    case DW_FORM_ref_udata:
+    case DW_FORM_udata:
+      uvalue = read_leb128 (data, & bytes_read, 0);
+      data += bytes_read;
+      break;
+
+    case DW_FORM_indirect:
+      form = read_leb128 (data, & bytes_read, 0);
+      data += bytes_read;
+      if (print_results_and_ok) {printf (" %s", get_FORM_name (form));}
+      return read_and_display_attr_value (attribute, form, data, cu_offset,
+                                         pointer_size, offset_size,
+                                         dwarf_version, entry, ok);
+    }
+
+  switch (form)
+    {
+    case DW_FORM_ref_addr:
+      if (print_results_and_ok) {printf (" <#%lx>", uvalue);}
+      break;
+
+      // DW_AT_type returns data in this form (REMEMBER cu_offset!):
+    case DW_FORM_ref1:
+    case DW_FORM_ref2:
+    case DW_FORM_ref4:
+    case DW_FORM_ref_udata:
+      if (ok)
+        {
+          harvest_type_value(entry, uvalue + cu_offset);
+          if (print_results)
+            {
+              printf (" <%lx>", uvalue + cu_offset);
+            }
+        }
+      break;
+
+    case DW_FORM_addr:
+      if (ok)
+        {
+          harvest_address_value(entry, attribute, uvalue);
+          if (print_results)
+            printf (" %#lx", uvalue);
+        }
+      break;
+      if (print_results_and_ok)
+
+      // DW_AT_byte_size, DW_AT_encoding, DW_AT_const_value,
+      // DW_AT_bit_size, DW_AT_bit_offset, and DW_AT_external
+      // return data in this form:
+    case DW_FORM_flag:
+    case DW_FORM_data1:
+    case DW_FORM_data2:
+    case DW_FORM_data4:
+    case DW_FORM_sdata:
+    case DW_FORM_udata:
+      if (ok)
+        {
+          harvest_ordinary_unsigned_value(entry, attribute, uvalue);
+          if (print_results_and_ok)
+            {
+              printf (" %ld", uvalue);
+            }
+        }
+      break;
+
+    case DW_FORM_ref8:
+    case DW_FORM_data8:
+      uvalue = byte_get (data, 4);
+      if (print_results_and_ok) {printf (" %lx", uvalue);}
+      if (print_results_and_ok)
+        {
+          printf (" %lx", (unsigned long) byte_get (data + 4, 4));
+        }
+      else
+        {
+          byte_get (data + 4, 4);
+        }
+      data += 8;
+      break;
+
+      // DW_AT_name/DW_AT_comp_dir can be a string, or an indirect string ... (see below)
+    case DW_FORM_string:
+      if (ok)
+        {
+          harvest_string(entry, attribute, data);
+          if (print_results_and_ok)
+            {
+              printf (" %s", data);
+            }
+        }
+      data += strlen ((char *) data) + 1;
+      break;
+
+    case DW_FORM_block:
+      uvalue = read_leb128 (data, & bytes_read, 0);
+      block_start = data + bytes_read;
+      data = display_block (block_start, uvalue, ok);
+      break;
+
+    case DW_FORM_block1:
+      uvalue = byte_get (data, 1);
+      block_start = data + 1;
+      data = display_block (block_start, uvalue, ok);
+      break;
+
+    case DW_FORM_block2:
+      uvalue = byte_get (data, 2);
+      block_start = data + 2;
+      data = display_block (block_start, uvalue, ok);
+      break;
+
+    case DW_FORM_block4:
+      uvalue = byte_get (data, 4);
+      block_start = data + 4;
+      data = display_block (block_start, uvalue, ok);
+      break;
+
+      // DW_AT_name/DW_AT_comp_dir can be an indirect string ... but it can also be a string (see above)
+    case DW_FORM_strp:
+      if (ok)
+        {
+          const char* ind_str = fetch_indirect_string (uvalue);
+          harvest_string(entry, attribute, ind_str);
+          if (print_results_and_ok)
+            {
+              printf (_(" (indirect string, offset: 0x%lx): %s"),
+                      uvalue, ind_str);
+            }
+        }
+      break;
+
+    case DW_FORM_indirect:
+      /* Handled above.  */
+      break;
+
+    default:
+      warn (_("Unrecognized form: %d\n"), form);
+      break;
+    }
+
+  /* For some attributes we can display futher information.  */
+
+  if (print_results_and_ok) {printf ("\t");}
+
+  switch (attribute)
+    {
+    case DW_AT_inline:
+      switch (uvalue)
+       {
+       case DW_INL_not_inlined:
+          if (print_results_and_ok) {printf (_("(not inlined)"));}
+         break;
+       case DW_INL_inlined:
+          if (print_results_and_ok) {printf (_("(inlined)"));}
+         break;
+       case DW_INL_declared_not_inlined:
+          if (print_results_and_ok) {printf (_("(declared as inline but ignored)"));}
+         break;
+       case DW_INL_declared_inlined:
+          if (print_results_and_ok) {printf (_("(declared as inline and inlined)"));}
+         break;
+       default:
+          if (print_results_and_ok) {printf (_("  (Unknown inline attribute value: %lx)"), uvalue);}
+         break;
+       }
+      break;
+
+    case DW_AT_language:
+      switch (uvalue)
+       {
+       case DW_LANG_C:                 if (print_results_and_ok) {printf ("(non-ANSI C)");} break;
+       case DW_LANG_C89:               if (print_results_and_ok) {printf ("(ANSI C)");} break;
+       case DW_LANG_C_plus_plus:       if (print_results_and_ok) {printf ("(C++)");} break;
+       case DW_LANG_Fortran77:         if (print_results_and_ok) {printf ("(FORTRAN 77)");} break;
+       case DW_LANG_Fortran90:         if (print_results_and_ok) {printf ("(Fortran 90)");} break;
+       case DW_LANG_Modula2:           if (print_results_and_ok) {printf ("(Modula 2)");} break;
+       case DW_LANG_Pascal83:          if (print_results_and_ok) {printf ("(ANSI Pascal)");} break;
+       case DW_LANG_Ada83:             if (print_results_and_ok) {printf ("(Ada)");} break;
+       case DW_LANG_Cobol74:           if (print_results_and_ok) {printf ("(Cobol 74)");} break;
+       case DW_LANG_Cobol85:           if (print_results_and_ok) {printf ("(Cobol 85)");} break;
+         /* DWARF 2.1 values.  */
+       case DW_LANG_C99:               if (print_results_and_ok) {printf ("(ANSI C99)");} break;
+       case DW_LANG_Ada95:             if (print_results_and_ok) {printf ("(ADA 95)");} break;
+       case DW_LANG_Fortran95:         if (print_results_and_ok) {printf ("(Fortran 95)");} break;
+         /* MIPS extension.  */
+       case DW_LANG_Mips_Assembler:    if (print_results_and_ok) {printf ("(MIPS assembler)");} break;
+         /* UPC extension.  */
+       case DW_LANG_Upc:               if (print_results_and_ok) {printf ("(Unified Parallel C)");} break;
+       default:
+         if (print_results_and_ok) {printf ("(Unknown: %lx)", uvalue);}
+         break;
+       }
+      break;
+
+    case DW_AT_encoding:
+      switch (uvalue)
+       {
+       case DW_ATE_void:               if (print_results_and_ok) {printf ("(void)");} break;
+       case DW_ATE_address:            if (print_results_and_ok) {printf ("(machine address)");} break;
+       case DW_ATE_boolean:            if (print_results_and_ok) {printf ("(boolean)");} break;
+       case DW_ATE_complex_float:      if (print_results_and_ok) {printf ("(complex float)");} break;
+       case DW_ATE_float:              if (print_results_and_ok) {printf ("(float)");} break;
+       case DW_ATE_signed:             if (print_results_and_ok) {printf ("(signed)");} break;
+       case DW_ATE_signed_char:        if (print_results_and_ok) {printf ("(signed char)");} break;
+       case DW_ATE_unsigned:           if (print_results_and_ok) {printf ("(unsigned)");} break;
+       case DW_ATE_unsigned_char:      if (print_results_and_ok) {printf ("(unsigned char)");} break;
+         /* DWARF 2.1 value.  */
+       case DW_ATE_imaginary_float:    if (print_results_and_ok) {printf ("(imaginary float)");} break;
+       default:
+         if (uvalue >= DW_ATE_lo_user
+             && uvalue <= DW_ATE_hi_user)
+            {
+           if (print_results_and_ok) {printf ("(user defined type)");}
+            }
+         else
+            {
+           if (print_results_and_ok) {printf ("(unknown type)");}
+            }
+         break;
+       }
+      break;
+
+    case DW_AT_accessibility:
+      switch (uvalue)
+       {
+       case DW_ACCESS_public:          if (print_results_and_ok) printf ("(public)"); break;
+       case DW_ACCESS_protected:       if (print_results_and_ok) printf ("(protected)"); break;
+       case DW_ACCESS_private:         if (print_results_and_ok) printf ("(private)"); break;
+       default:
+         if (print_results_and_ok) printf ("(unknown accessibility)");
+         break;
+       }
+      break;
+
+    case DW_AT_visibility:
+      switch (uvalue)
+       {
+       case DW_VIS_local:              if (print_results_and_ok) printf ("(local)"); break;
+       case DW_VIS_exported:           if (print_results_and_ok) printf ("(exported)"); break;
+       case DW_VIS_qualified:          if (print_results_and_ok) printf ("(qualified)"); break;
+       default:                        if (print_results_and_ok) printf ("(unknown visibility)"); break;
+       }
+      break;
+
+    case DW_AT_virtuality:
+      switch (uvalue)
+       {
+       case DW_VIRTUALITY_none:        if (print_results_and_ok) printf ("(none)"); break;
+       case DW_VIRTUALITY_virtual:     if (print_results_and_ok) printf ("(virtual)"); break;
+       case DW_VIRTUALITY_pure_virtual:if (print_results_and_ok) printf ("(pure_virtual)"); break;
+       default:                        if (print_results_and_ok) printf ("(unknown virtuality)"); break;
+       }
+      break;
+
+    case DW_AT_identifier_case:
+      switch (uvalue)
+       {
+       case DW_ID_case_sensitive:      if (print_results_and_ok) printf ("(case_sensitive)"); break;
+       case DW_ID_up_case:             if (print_results_and_ok) printf ("(up_case)"); break;
+       case DW_ID_down_case:           if (print_results_and_ok) printf ("(down_case)"); break;
+       case DW_ID_case_insensitive:    if (print_results_and_ok) printf ("(case_insensitive)"); break;
+       default:                        if (print_results_and_ok) printf ("(unknown case)"); break;
+       }
+      break;
+
+    case DW_AT_calling_convention:
+      switch (uvalue)
+       {
+       case DW_CC_normal:      if (print_results_and_ok) printf ("(normal)"); break;
+       case DW_CC_program:     if (print_results_and_ok) printf ("(program)"); break;
+       case DW_CC_nocall:      if (print_results_and_ok) printf ("(nocall)"); break;
+       default:
+         if (uvalue >= DW_CC_lo_user
+             && uvalue <= DW_CC_hi_user)
+            {
+              if (print_results_and_ok) printf ("(user defined)");
+            }
+         else
+            {
+              if (print_results_and_ok) printf ("(unknown convention)");
+            }
+       }
+      break;
+
+    case DW_AT_ordering:
+      switch (uvalue)
+       {
+       case -1: if (print_results_and_ok) printf ("(undefined)"); break;
+       case 0:  if (print_results_and_ok) printf ("(row major)"); break;
+       case 1:  if (print_results_and_ok) printf ("(column major)"); break;
+       }
+      break;
+
+      // DW_AT_location, DW_AT_data_member_location return data in this form:
+    case DW_AT_location:
+      if (block_start)
+       {
+          long loc_data = 0;
+         if (print_results_and_ok) printf ("(");
+         decode_location_expression (block_start, pointer_size, uvalue, ok, &loc_data);
+         if (print_results_and_ok) printf (")");
+          harvest_location(entry, loc_data);
+       }
+      else if (form == DW_FORM_data4 || form == DW_FORM_data8)
+       {
+         if (print_results_and_ok) printf ("(");
+         if (print_results_and_ok) printf ("location list");
+         if (print_results_and_ok) printf (")");
+       }
+      break;
+
+    case DW_AT_data_member_location:
+      if (block_start)
+       {
+          long loc_data = 0;
+         if (print_results_and_ok) printf ("(");
+         decode_location_expression (block_start, pointer_size, uvalue, ok, &loc_data);
+         if (print_results_and_ok) printf (")");
+          harvest_data_member_location(entry, loc_data);
+       }
+      else if (form == DW_FORM_data4 || form == DW_FORM_data8)
+       {
+          if (print_results_and_ok) printf ("(");
+          if (print_results_and_ok) printf ("location list");
+          if (print_results_and_ok) printf (")");
+       }
+      break;
+
+    case DW_AT_frame_base:
+    case DW_AT_vtable_elem_location:
+    case DW_AT_allocated:
+    case DW_AT_associated:
+    case DW_AT_data_location:
+    case DW_AT_stride:
+    case DW_AT_upper_bound:
+    case DW_AT_lower_bound:
+      if (block_start)
+       {
+          if (print_results_and_ok) printf ("(");
+         decode_location_expression (block_start, pointer_size, uvalue, ok, 0);
+          if (print_results_and_ok) printf (")");
+       }
+      else if (form == DW_FORM_data4 || form == DW_FORM_data8)
+       {
+          if (print_results_and_ok) printf ("(");
+          if (print_results_and_ok) printf ("location list");
+          if (print_results_and_ok) printf (")");
+       }
+      break;
+
+    default:
+      break;
+    }
+
+  return data;
+}
+
+static unsigned char *
+read_and_display_attr (attribute, form, data, cu_offset, pointer_size,
+                       offset_size, dwarf_version, entry, ok_to_harvest)
+     unsigned long attribute;
+     unsigned long form;
+     unsigned char *data;
+     unsigned long cu_offset;
+     unsigned long pointer_size;
+     unsigned long offset_size;
+     int dwarf_version;
+     dwarf_entry* entry;
+     char ok_to_harvest;
+{
+  char entry_is_listening = entry_is_listening_for_attribute(entry, attribute);
+
+  // Ok process attributes when ok_to_harvest is on and the entry is listening:
+  char ok_to_process = entry_is_listening && ok_to_harvest;
+  //  printf("ENTRY LISTENING: %d\n", (int)entry_is_listening);
+  //  if (ok_to_process)
+  if (print_results && ok_to_process)
+    printf ("     %-18s:", get_AT_name (attribute));
+  data = read_and_display_attr_value (attribute, form, data, cu_offset,
+                                     pointer_size, offset_size, dwarf_version,
+                                      entry, ok_to_process);
+  if (ok_to_process && print_results)
+    printf ("\n");
+  return data;
+}
+
+static int
+display_debug_info (section, start, file)
+     Elf_Internal_Shdr *section;
+     unsigned char *start;
+     FILE *file;
+{
+  unsigned char *end = start + section->sh_size;
+  unsigned char *section_begin = start;
+
+  //PG - Number of relevant entries to record in the dwarf_entry array
+  unsigned long num_relevant_entries = 0;
+  unsigned long idx = 0; // The index in the array, (< dwarf_entry_array_size)
+
+  //PG - Do one dummy run to see how many entries need to be put in the dwarf_entry array
+  // The sole purpose of this run is to get a number into num_relevant_entries
+  Elf_Internal_Shdr *section_dummy = section;
+  unsigned char *start_dummy = start;
+  FILE *file_dummy = file;
+
+  unsigned char *end_dummy = start_dummy + section_dummy->sh_size;
+  unsigned char *section_begin_dummy = start_dummy;
+
+  //  printf (_("The section %s contains:\n\n"), SECTION_NAME (section_dummy));
+
+  load_debug_str (file_dummy);
+  load_debug_loc (file_dummy);
+
+  while (start_dummy < end_dummy)
+    {
+      DWARF2_Internal_CompUnit compunit;
+      Elf_Internal_Shdr *relsec;
+      unsigned char *hdrptr;
+      unsigned char *cu_abbrev_offset_ptr;
+      unsigned char *tags;
+      unsigned int i;
+      int level;
+      unsigned long cu_offset;
+      int offset_size;
+      int initial_length_size;
+
+      hdrptr = start_dummy;
+
+      compunit.cu_length = byte_get (hdrptr, 4);
+      hdrptr += 4;
+
+      if (compunit.cu_length == 0xffffffff)
+       {
+         compunit.cu_length = byte_get (hdrptr, 8);
+         hdrptr += 8;
+         offset_size = 8;
+         initial_length_size = 12;
+       }
+      else
+       {
+         offset_size = 4;
+         initial_length_size = 4;
+       }
+
+      compunit.cu_version = byte_get (hdrptr, 2);
+      hdrptr += 2;
+
+      /* Apply addends of RELA relocations.  */
+      for (relsec = section_headers;
+          relsec < section_headers + elf_header.e_shnum;
+          ++relsec)
+       {
+         unsigned long nrelas;
+         Elf_Internal_Rela *rela, *rp;
+         Elf_Internal_Shdr *symsec;
+         Elf_Internal_Sym *symtab;
+         Elf_Internal_Sym *sym;
+
+         if (relsec->sh_type != SHT_RELA
+             || SECTION_HEADER (relsec->sh_info) != section_dummy
+             || relsec->sh_size == 0)
+           continue;
+
+         if (!slurp_rela_relocs (file_dummy, relsec->sh_offset, relsec->sh_size,
+                                 & rela, & nrelas))
+           return 0;
+
+         symsec = SECTION_HEADER (relsec->sh_link);
+         symtab = GET_ELF_SYMBOLS (file_dummy, symsec);
+
+         for (rp = rela; rp < rela + nrelas; ++rp)
+           {
+             unsigned char *loc;
+
+             if (rp->r_offset >= (bfd_vma) (hdrptr - section_begin_dummy)
+                 && section_dummy->sh_size > (bfd_vma) offset_size
+                 && rp->r_offset <= section_dummy->sh_size - offset_size)
+               loc = section_begin_dummy + rp->r_offset;
+             else
+               continue;
+
+             if (is_32bit_elf)
+               {
+                 sym = symtab + ELF32_R_SYM (rp->r_info);
+
+                 if (ELF32_R_SYM (rp->r_info) != 0
+                     && ELF32_ST_TYPE (sym->st_info) != STT_SECTION)
+                   {
+                     warn (_("Skipping unexpected symbol type %u\n"),
+                           ELF32_ST_TYPE (sym->st_info));
+                     continue;
+                   }
+               }
+             else
+               {
+                 sym = symtab + ELF64_R_SYM (rp->r_info);
+
+                 if (ELF64_R_SYM (rp->r_info) != 0
+                     && ELF64_ST_TYPE (sym->st_info) != STT_SECTION)
+                   {
+                     warn (_("Skipping unexpected symbol type %u\n"),
+                           ELF64_ST_TYPE (sym->st_info));
+                     continue;
+                   }
+               }
+
+             byte_put (loc, rp->r_addend, offset_size);
+           }
+
+         free (rela);
+         break;
+       }
+
+      cu_abbrev_offset_ptr = hdrptr;
+      compunit.cu_abbrev_offset = byte_get (hdrptr, offset_size);
+      hdrptr += offset_size;
+
+      compunit.cu_pointer_size = byte_get (hdrptr, 1);
+      hdrptr += 1;
+
+      tags = hdrptr;
+      cu_offset = start_dummy - section_begin_dummy;
+      start_dummy += compunit.cu_length + initial_length_size;
+
+      //      printf (_("  Compilation Unit @ %lx:\n"), cu_offset);
+      //      printf (_("   Length:        %ld\n"), compunit.cu_length);
+      //      printf (_("   Version:       %d\n"), compunit.cu_version);
+      //      printf (_("   Abbrev Offset: %ld\n"), compunit.cu_abbrev_offset);
+      //      printf (_("   Pointer Size:  %d\n"), compunit.cu_pointer_size);
+
+      if (compunit.cu_version != 2 && compunit.cu_version != 3)
+       {
+         warn (_("Only version 2 and 3 DWARF debug information is currently supported.\n"));
+         continue;
+       }
+
+      free_abbrevs ();
+
+      /* Read in the abbrevs used by this compilation unit.  */
+      {
+       Elf_Internal_Shdr *sec;
+       unsigned char *begin;
+
+       /* Locate the .debug_abbrev section and process it.  */
+       for (i = 0, sec = section_headers;
+            i < elf_header.e_shnum;
+            i++, sec++)
+         if (strcmp (SECTION_NAME (sec), ".debug_abbrev") == 0)
+           break;
+
+       if (i == elf_header.e_shnum || sec->sh_size == 0)
+         {
+           warn (_("Unable to locate .debug_abbrev section!\n"));
+           return 0;
+         }
+
+       begin = ((unsigned char *)
+                get_data (NULL, file_dummy, sec->sh_offset, sec->sh_size,
+                          _("debug_abbrev section data")));
+       if (!begin)
+         return 0;
+
+       process_abbrev_section (begin + compunit.cu_abbrev_offset,
+                               begin + sec->sh_size);
+
+       free (begin);
+      }
+
+      level = 0;
+      while (tags < start_dummy)
+       {
+         int bytes_read;
+         unsigned long abbrev_number;
+         abbrev_entry *entry;
+         abbrev_attr *attr;
+          char is_relevant_entry; //PG
+
+         abbrev_number = read_leb128 (tags, & bytes_read, 0);
+         tags += bytes_read;
+
+         /* A null DIE marks the end of a list of children.  */
+         if (abbrev_number == 0)
+           {
+             --level;
+             continue;
+           }
+
+         /* Scan through the abbreviation list until we reach the
+            correct entry.  */
+         for (entry = first_abbrev;
+              entry && entry->entry != abbrev_number;
+              entry = entry->next)
+           continue;
+
+         if (entry == NULL)
+           {
+             warn (_("Unable to locate entry %lu in the abbreviation table\n"),
+                   abbrev_number);
+             return 0;
+           }
+
+          //PG - increment relevant entry and make a note of it:
+          is_relevant_entry = tag_is_relevant_entry(entry->tag);
+          if (is_relevant_entry)
+            {
+              //              printf ("RELEVANT ENTRY!!!\n");
+              num_relevant_entries++;
+
+              /*
+              printf (_(" <%d><%lx>: Abbrev Number: %lu (%s)\n"),
+                      level,
+                      (unsigned long) (tags - section_begin_dummy - bytes_read),
+                      abbrev_number,
+                      get_TAG_name (entry->tag));
+              */
+            }
+
+         for (attr = entry->first_attr; attr; attr = attr->next)
+           tags = read_and_display_attr (attr->attribute,
+                                         attr->form,
+                                         tags, cu_offset,
+                                         compunit.cu_pointer_size,
+                                         offset_size,
+                                         compunit.cu_version,
+                                          entry, /* XXX this can't be right */
+                                          0); // parse tags but DO NOT harvest data
+
+         if (entry->children)
+           ++level;
+       }
+    }
+
+  free_debug_str ();
+  free_debug_loc ();
+
+#ifdef SHOW_DEBUG
+  printf ("Number of relevant entries: %u\n\n", num_relevant_entries);
+#endif
+  //PG - End dummy run code
+
+  // Construct the global dwarf_entry array
+  // Question - when do we destroy it???
+  dwarf_entry_array_size = num_relevant_entries;
+  initialize_dwarf_entry_array(num_relevant_entries);
+
+  //PG - Begin real code
+#ifdef SHOW_DEBUG
+  printf (_("The section %s contains:\n\n"), SECTION_NAME (section));
+#endif
+
+  load_debug_str (file);
+  load_debug_loc (file);
+
+  while (start < end)
+    {
+      DWARF2_Internal_CompUnit compunit;
+      Elf_Internal_Shdr *relsec;
+      unsigned char *hdrptr;
+      unsigned char *cu_abbrev_offset_ptr;
+      unsigned char *tags;
+      unsigned int i;
+      int level;
+      unsigned long cu_offset;
+      int offset_size;
+      int initial_length_size;
+
+      hdrptr = start;
+
+      compunit.cu_length = byte_get (hdrptr, 4);
+      hdrptr += 4;
+
+      if (compunit.cu_length == 0xffffffff)
+       {
+         compunit.cu_length = byte_get (hdrptr, 8);
+         hdrptr += 8;
+         offset_size = 8;
+         initial_length_size = 12;
+       }
+      else
+       {
+         offset_size = 4;
+         initial_length_size = 4;
+       }
+
+      compunit.cu_version = byte_get (hdrptr, 2);
+      hdrptr += 2;
+
+      /* Apply addends of RELA relocations.  */
+      for (relsec = section_headers;
+          relsec < section_headers + elf_header.e_shnum;
+          ++relsec)
+       {
+         unsigned long nrelas;
+         Elf_Internal_Rela *rela, *rp;
+         Elf_Internal_Shdr *symsec;
+         Elf_Internal_Sym *symtab;
+         Elf_Internal_Sym *sym;
+
+         if (relsec->sh_type != SHT_RELA
+             || SECTION_HEADER (relsec->sh_info) != section
+             || relsec->sh_size == 0)
+           continue;
+
+         if (!slurp_rela_relocs (file, relsec->sh_offset, relsec->sh_size,
+                                 & rela, & nrelas))
+           return 0;
+
+         symsec = SECTION_HEADER (relsec->sh_link);
+         symtab = GET_ELF_SYMBOLS (file, symsec);
+
+         for (rp = rela; rp < rela + nrelas; ++rp)
+           {
+             unsigned char *loc;
+
+             if (rp->r_offset >= (bfd_vma) (hdrptr - section_begin)
+                 && section->sh_size > (bfd_vma) offset_size
+                 && rp->r_offset <= section->sh_size - offset_size)
+               loc = section_begin + rp->r_offset;
+             else
+               continue;
+
+             if (is_32bit_elf)
+               {
+                 sym = symtab + ELF32_R_SYM (rp->r_info);
+
+                 if (ELF32_R_SYM (rp->r_info) != 0
+                     && ELF32_ST_TYPE (sym->st_info) != STT_SECTION)
+                   {
+                     warn (_("Skipping unexpected symbol type %u\n"),
+                           ELF32_ST_TYPE (sym->st_info));
+                     continue;
+                   }
+               }
+             else
+               {
+                 sym = symtab + ELF64_R_SYM (rp->r_info);
+
+                 if (ELF64_R_SYM (rp->r_info) != 0
+                     && ELF64_ST_TYPE (sym->st_info) != STT_SECTION)
+                   {
+                     warn (_("Skipping unexpected symbol type %u\n"),
+                           ELF64_ST_TYPE (sym->st_info));
+                     continue;
+                   }
+               }
+
+             byte_put (loc, rp->r_addend, offset_size);
+           }
+
+         free (rela);
+         break;
+       }
+
+      cu_abbrev_offset_ptr = hdrptr;
+      compunit.cu_abbrev_offset = byte_get (hdrptr, offset_size);
+      hdrptr += offset_size;
+
+      compunit.cu_pointer_size = byte_get (hdrptr, 1);
+      hdrptr += 1;
+
+      tags = hdrptr;
+      cu_offset = start - section_begin;
+      start += compunit.cu_length + initial_length_size;
+
+#ifdef SHOW_DEBUG
+      printf (_("  Compilation Unit @ %lx:\n"), cu_offset);
+      printf (_("   Length:        %ld\n"), compunit.cu_length);
+      printf (_("   Version:       %d\n"), compunit.cu_version);
+      printf (_("   Abbrev Offset: %ld\n"), compunit.cu_abbrev_offset);
+      printf (_("   Pointer Size:  %d\n"), compunit.cu_pointer_size);
+#endif
+
+      if (compunit.cu_version != 2 && compunit.cu_version != 3)
+       {
+         warn (_("Only version 2 and 3 DWARF debug information is currently supported.\n"));
+         continue;
+       }
+
+      free_abbrevs ();
+
+      /* Read in the abbrevs used by this compilation unit.  */
+      {
+       Elf_Internal_Shdr *sec;
+       unsigned char *begin;
+
+       /* Locate the .debug_abbrev section and process it.  */
+       for (i = 0, sec = section_headers;
+            i < elf_header.e_shnum;
+            i++, sec++)
+         if (strcmp (SECTION_NAME (sec), ".debug_abbrev") == 0)
+           break;
+
+       if (i == elf_header.e_shnum || sec->sh_size == 0)
+         {
+           warn (_("Unable to locate .debug_abbrev section!\n"));
+           return 0;
+         }
+
+       begin = ((unsigned char *)
+                get_data (NULL, file, sec->sh_offset, sec->sh_size,
+                          _("debug_abbrev section data")));
+       if (!begin)
+         return 0;
+
+       process_abbrev_section (begin + compunit.cu_abbrev_offset,
+                               begin + sec->sh_size);
+
+       free (begin);
+      }
+
+      level = 0;
+      while (tags < start)
+       {
+         int bytes_read;
+         unsigned long abbrev_number;
+         abbrev_entry *entry;
+         abbrev_attr *attr;
+          char is_relevant_entry; //PG
+
+         abbrev_number = read_leb128 (tags, & bytes_read, 0);
+         tags += bytes_read;
+
+         /* A null DIE marks the end of a list of children.  */
+         if (abbrev_number == 0)
+           {
+             --level;
+             continue;
+           }
+
+         /* Scan through the abbreviation list until we reach the
+            correct entry.  */
+         for (entry = first_abbrev;
+              entry && entry->entry != abbrev_number;
+              entry = entry->next)
+           continue;
+
+         if (entry == NULL)
+           {
+             warn (_("Unable to locate entry %lu in the abbreviation table\n"),
+                   abbrev_number);
+             return 0;
+           }
+
+          is_relevant_entry = tag_is_relevant_entry(entry->tag);
+          if (is_relevant_entry)
+            //PG - This is where all the action takes place
+            //     store the info. as a dwarf_entry struct in dwarf_entry_array
+            {
+              unsigned long temp_ID = (unsigned long) (tags - section_begin - bytes_read);
+              unsigned long temp_tag_name = entry->tag;
+
+              // Fill the ID and tag_name fields:
+              dwarf_entry_array[idx].ID = temp_ID;
+              dwarf_entry_array[idx].tag_name = temp_tag_name;
+             dwarf_entry_array[idx].level=level;
+
+              // Initialize the entry_ptr based on tag_name
+              initialize_dwarf_entry_ptr(&dwarf_entry_array[idx]);
+
+              if (print_results)
+                {
+                  printf (_(" <%d><%lx>: Abbrev Number: %lu (%s)\n"),
+                          level,
+                          temp_ID,
+                          abbrev_number,
+                          get_TAG_name (temp_tag_name));
+                }
+
+              for (attr = entry->first_attr; attr; attr = attr->next)
+                tags = read_and_display_attr (attr->attribute,
+                                              attr->form,
+                                              tags, cu_offset,
+                                              compunit.cu_pointer_size,
+                                              offset_size,
+                                              compunit.cu_version,
+                                              &dwarf_entry_array[idx],
+                                              1); // DO harvest
+
+              //              printf("Index=%u, ID=%x, tag_name=%s\n",
+              //                     idx,
+              //                     dwarf_entry_array[idx].ID,
+              //                     get_TAG_name(dwarf_entry_array[idx].tag_name));
+
+              if (entry->children)
+                ++level;
+
+              idx++;
+            }
+          else
+            {
+              for (attr = entry->first_attr; attr; attr = attr->next)
+                tags = read_and_display_attr (attr->attribute,
+                                              attr->form,
+                                              tags, cu_offset,
+                                              compunit.cu_pointer_size,
+                                              offset_size,
+                                              compunit.cu_version,
+                                              0,
+                                              0); // DO NOT harvest
+
+              if (entry->children)
+                ++level;
+            }
+
+       }
+    }
+
+  free_debug_str ();
+  free_debug_loc ();
+
+  //PG - Now that all of the entries are in the array, finish initializing
+  //     it by creating various links and filling in all dwarf_entry fields
+  finish_dwarf_entry_array_init();
+
+  //  print_dwarf_entry_array();
+  //  printf ("\n");
+
+  return 1;
+}
+
+static int
+display_debug_aranges (section, start, file)
+     Elf_Internal_Shdr *section;
+     unsigned char *start;
+     FILE *file ATTRIBUTE_UNUSED;
+{
+  unsigned char *end = start + section->sh_size;
+
+  printf (_("The section %s contains:\n\n"), SECTION_NAME (section));
+
+  while (start < end)
+    {
+      unsigned char *hdrptr;
+      DWARF2_Internal_ARange arange;
+      unsigned char *ranges;
+      unsigned long length;
+      unsigned long address;
+      int excess;
+      int offset_size;
+      int initial_length_size;
+
+      hdrptr = start;
+
+      arange.ar_length = byte_get (hdrptr, 4);
+      hdrptr += 4;
+
+      if (arange.ar_length == 0xffffffff)
+       {
+         arange.ar_length = byte_get (hdrptr, 8);
+         hdrptr += 8;
+         offset_size = 8;
+         initial_length_size = 12;
+       }
+      else
+        {
+         offset_size = 4;
+         initial_length_size = 4;
+       }
+
+      arange.ar_version = byte_get (hdrptr, 2);
+      hdrptr += 2;
+
+      arange.ar_info_offset = byte_get (hdrptr, offset_size);
+      hdrptr += offset_size;
+
+      arange.ar_pointer_size = byte_get (hdrptr, 1);
+      hdrptr += 1;
+
+      arange.ar_segment_size = byte_get (hdrptr, 1);
+      hdrptr += 1;
+
+      if (arange.ar_version != 2 && arange.ar_version != 3)
+       {
+         warn (_("Only DWARF 2 and 3 aranges are currently supported.\n"));
+         break;
+       }
+
+      printf (_("  Length:                   %ld\n"), arange.ar_length);
+      printf (_("  Version:                  %d\n"), arange.ar_version);
+      printf (_("  Offset into .debug_info:  %lx\n"), arange.ar_info_offset);
+      printf (_("  Pointer Size:             %d\n"), arange.ar_pointer_size);
+      printf (_("  Segment Size:             %d\n"), arange.ar_segment_size);
+
+      printf (_("\n    Address  Length\n"));
+
+      ranges = hdrptr;
+
+      /* Must pad to an alignment boundary that is twice the pointer size.  */
+      excess = (hdrptr - start) % (2 * arange.ar_pointer_size);
+      if (excess)
+       ranges += (2 * arange.ar_pointer_size) - excess;
+
+      for (;;)
+       {
+         address = byte_get (ranges, arange.ar_pointer_size);
+
+         ranges += arange.ar_pointer_size;
+
+         length  = byte_get (ranges, arange.ar_pointer_size);
+
+         ranges += arange.ar_pointer_size;
+
+         /* A pair of zeros marks the end of the list.  */
+         if (address == 0 && length == 0)
+           break;
+
+         printf ("    %8.8lx %lu\n", address, length);
+       }
+
+      start += arange.ar_length + initial_length_size;
+    }
+
+  printf ("\n");
+
+  return 1;
+}
+
+typedef struct Frame_Chunk
+{
+  struct Frame_Chunk *next;
+  unsigned char *chunk_start;
+  int ncols;
+  /* DW_CFA_{undefined,same_value,offset,register,unreferenced}  */
+  short int *col_type;
+  int *col_offset;
+  char *augmentation;
+  unsigned int code_factor;
+  int data_factor;
+  unsigned long pc_begin;
+  unsigned long pc_range;
+  int cfa_reg;
+  int cfa_offset;
+  int ra;
+  unsigned char fde_encoding;
+  unsigned char cfa_exp;
+}
+Frame_Chunk;
+
+/* A marker for a col_type that means this column was never referenced
+   in the frame info.  */
+#define DW_CFA_unreferenced (-1)
+
+static void frame_need_space PARAMS ((Frame_Chunk *, int));
+static void frame_display_row PARAMS ((Frame_Chunk *, int *, int *));
+static int size_of_encoded_value PARAMS ((int));
+
+static void
+frame_need_space (fc, reg)
+     Frame_Chunk *fc;
+     int reg;
+{
+  int prev = fc->ncols;
+
+  if (reg < fc->ncols)
+    return;
+
+  fc->ncols = reg + 1;
+  fc->col_type = (short int *) xrealloc (fc->col_type,
+                                        fc->ncols * sizeof (short int));
+  fc->col_offset = (int *) xrealloc (fc->col_offset,
+                                    fc->ncols * sizeof (int));
+
+  while (prev < fc->ncols)
+    {
+      fc->col_type[prev] = DW_CFA_unreferenced;
+      fc->col_offset[prev] = 0;
+      prev++;
+    }
+}
+
+static void
+frame_display_row (fc, need_col_headers, max_regs)
+     Frame_Chunk *fc;
+     int *need_col_headers;
+     int *max_regs;
+{
+  int r;
+  char tmp[100];
+
+  if (*max_regs < fc->ncols)
+    *max_regs = fc->ncols;
+
+  if (*need_col_headers)
+    {
+      *need_col_headers = 0;
+
+      printf ("   LOC   CFA      ");
+
+      for (r = 0; r < *max_regs; r++)
+       if (fc->col_type[r] != DW_CFA_unreferenced)
+         {
+           if (r == fc->ra)
+             printf ("ra   ");
+           else
+             printf ("r%-4d", r);
+         }
+
+      printf ("\n");
+    }
+
+  printf ("%08lx ", fc->pc_begin);
+  if (fc->cfa_exp)
+    strcpy (tmp, "exp");
+  else
+    sprintf (tmp, "r%d%+d", fc->cfa_reg, fc->cfa_offset);
+  printf ("%-8s ", tmp);
+
+  for (r = 0; r < fc->ncols; r++)
+    {
+      if (fc->col_type[r] != DW_CFA_unreferenced)
+       {
+         switch (fc->col_type[r])
+           {
+           case DW_CFA_undefined:
+             strcpy (tmp, "u");
+             break;
+           case DW_CFA_same_value:
+             strcpy (tmp, "s");
+             break;
+           case DW_CFA_offset:
+             sprintf (tmp, "c%+d", fc->col_offset[r]);
+             break;
+           case DW_CFA_register:
+             sprintf (tmp, "r%d", fc->col_offset[r]);
+             break;
+           case DW_CFA_expression:
+             strcpy (tmp, "exp");
+             break;
+           default:
+             strcpy (tmp, "n/a");
+             break;
+           }
+         printf ("%-5s", tmp);
+       }
+    }
+  printf ("\n");
+}
+
+static int
+size_of_encoded_value (encoding)
+     int encoding;
+{
+  switch (encoding & 0x7)
+    {
+    default:   /* ??? */
+    case 0:    return is_32bit_elf ? 4 : 8;
+    case 2:    return 2;
+    case 3:    return 4;
+    case 4:    return 8;
+    }
+}
+
+#define GET(N) byte_get (start, N); start += N
+#define LEB()  read_leb128 (start, & length_return, 0); start += length_return
+#define SLEB() read_leb128 (start, & length_return, 1); start += length_return
+
+static int
+display_debug_frames (section, start, file)
+     Elf_Internal_Shdr *section;
+     unsigned char *start;
+     FILE *file ATTRIBUTE_UNUSED;
+{
+  unsigned char *end = start + section->sh_size;
+  unsigned char *section_start = start;
+  Frame_Chunk *chunks = 0;
+  Frame_Chunk *remembered_state = 0;
+  Frame_Chunk *rs;
+  int is_eh = (strcmp (SECTION_NAME (section), ".eh_frame") == 0);
+  int length_return;
+  int max_regs = 0;
+  int addr_size = is_32bit_elf ? 4 : 8;
+
+  printf (_("The section %s contains:\n"), SECTION_NAME (section));
+
+  while (start < end)
+    {
+      unsigned char *saved_start;
+      unsigned char *block_end;
+      unsigned long length;
+      unsigned long cie_id;
+      Frame_Chunk *fc;
+      Frame_Chunk *cie;
+      int need_col_headers = 1;
+      unsigned char *augmentation_data = NULL;
+      unsigned long augmentation_data_len = 0;
+      int encoded_ptr_size = addr_size;
+      int offset_size;
+      int initial_length_size;
+
+      saved_start = start;
+      length = byte_get (start, 4); start += 4;
+
+      if (length == 0)
+       {
+         printf ("\n%08lx ZERO terminator\n\n",
+                   (unsigned long)(saved_start - section_start));
+         return 1;
+       }
+
+      if (length == 0xffffffff)
+       {
+         length = byte_get (start, 8);
+         start += 8;
+         offset_size = 8;
+         initial_length_size = 12;
+       }
+      else
+       {
+         offset_size = 4;
+         initial_length_size = 4;
+       }
+
+      block_end = saved_start + length + initial_length_size;
+      cie_id = byte_get (start, offset_size); start += offset_size;
+
+      if (is_eh ? (cie_id == 0) : (cie_id == DW_CIE_ID))
+       {
+         int version;
+
+         fc = (Frame_Chunk *) xmalloc (sizeof (Frame_Chunk));
+         memset (fc, 0, sizeof (Frame_Chunk));
+
+         fc->next = chunks;
+         chunks = fc;
+         fc->chunk_start = saved_start;
+         fc->ncols = 0;
+         fc->col_type = (short int *) xmalloc (sizeof (short int));
+         fc->col_offset = (int *) xmalloc (sizeof (int));
+         frame_need_space (fc, max_regs-1);
+
+         version = *start++;
+
+         fc->augmentation = start;
+         start = strchr (start, '\0') + 1;
+
+         if (fc->augmentation[0] == 'z')
+           {
+             fc->code_factor = LEB ();
+             fc->data_factor = SLEB ();
+             fc->ra = byte_get (start, 1); start += 1;
+             augmentation_data_len = LEB ();
+             augmentation_data = start;
+             start += augmentation_data_len;
+           }
+         else if (strcmp (fc->augmentation, "eh") == 0)
+           {
+             start += addr_size;
+             fc->code_factor = LEB ();
+             fc->data_factor = SLEB ();
+             fc->ra = byte_get (start, 1); start += 1;
+           }
+         else
+           {
+             fc->code_factor = LEB ();
+             fc->data_factor = SLEB ();
+             fc->ra = byte_get (start, 1); start += 1;
+           }
+         cie = fc;
+
+         if (do_debug_frames_interp)
+           printf ("\n%08lx %08lx %08lx CIE \"%s\" cf=%d df=%d ra=%d\n",
+                   (unsigned long)(saved_start - section_start), length, cie_id,
+                   fc->augmentation, fc->code_factor, fc->data_factor,
+                   fc->ra);
+         else
+           {
+             printf ("\n%08lx %08lx %08lx CIE\n",
+                     (unsigned long)(saved_start - section_start), length, cie_id);
+             printf ("  Version:               %d\n", version);
+             printf ("  Augmentation:          \"%s\"\n", fc->augmentation);
+             printf ("  Code alignment factor: %u\n", fc->code_factor);
+             printf ("  Data alignment factor: %d\n", fc->data_factor);
+             printf ("  Return address column: %d\n", fc->ra);
+
+             if (augmentation_data_len)
+               {
+                 unsigned long i;
+                 printf ("  Augmentation data:    ");
+                 for (i = 0; i < augmentation_data_len; ++i)
+                   printf (" %02x", augmentation_data[i]);
+                 putchar ('\n');
+               }
+             putchar ('\n');
+           }
+
+         if (augmentation_data_len)
+           {
+             unsigned char *p, *q;
+             p = fc->augmentation + 1;
+             q = augmentation_data;
+
+             while (1)
+               {
+                 if (*p == 'L')
+                   q++;
+                 else if (*p == 'P')
+                   q += 1 + size_of_encoded_value (*q);
+                 else if (*p == 'R')
+                   fc->fde_encoding = *q++;
+                 else
+                   break;
+                 p++;
+               }
+
+             if (fc->fde_encoding)
+               encoded_ptr_size = size_of_encoded_value (fc->fde_encoding);
+           }
+
+         frame_need_space (fc, fc->ra);
+       }
+      else
+       {
+         unsigned char *look_for;
+         static Frame_Chunk fde_fc;
+
+         fc = & fde_fc;
+         memset (fc, 0, sizeof (Frame_Chunk));
+
+         look_for = is_eh ? start - 4 - cie_id : section_start + cie_id;
+
+         for (cie = chunks; cie ; cie = cie->next)
+           if (cie->chunk_start == look_for)
+             break;
+
+         if (!cie)
+           {
+             warn ("Invalid CIE pointer %08lx in FDE at %08lx\n",
+                   cie_id, saved_start);
+             start = block_end;
+             fc->ncols = 0;
+             fc->col_type = (short int *) xmalloc (sizeof (short int));
+             fc->col_offset = (int *) xmalloc (sizeof (int));
+             frame_need_space (fc, max_regs - 1);
+             cie = fc;
+             fc->augmentation = "";
+             fc->fde_encoding = 0;
+           }
+         else
+           {
+             fc->ncols = cie->ncols;
+             fc->col_type = (short int *) xmalloc (fc->ncols * sizeof (short int));
+             fc->col_offset = (int *) xmalloc (fc->ncols * sizeof (int));
+             memcpy (fc->col_type, cie->col_type, fc->ncols * sizeof (short int));
+             memcpy (fc->col_offset, cie->col_offset, fc->ncols * sizeof (int));
+             fc->augmentation = cie->augmentation;
+             fc->code_factor = cie->code_factor;
+             fc->data_factor = cie->data_factor;
+             fc->cfa_reg = cie->cfa_reg;
+             fc->cfa_offset = cie->cfa_offset;
+             fc->ra = cie->ra;
+             frame_need_space (fc, max_regs-1);
+             fc->fde_encoding = cie->fde_encoding;
+           }
+
+         if (fc->fde_encoding)
+           encoded_ptr_size = size_of_encoded_value (fc->fde_encoding);
+
+         fc->pc_begin = byte_get (start, encoded_ptr_size);
+         if ((fc->fde_encoding & 0x70) == DW_EH_PE_pcrel)
+           fc->pc_begin += section->sh_addr + (start - section_start);
+         start += encoded_ptr_size;
+         fc->pc_range = byte_get (start, encoded_ptr_size);
+         start += encoded_ptr_size;
+
+         if (cie->augmentation[0] == 'z')
+           {
+             augmentation_data_len = LEB ();
+             augmentation_data = start;
+             start += augmentation_data_len;
+           }
+
+         printf ("\n%08lx %08lx %08lx FDE cie=%08lx pc=%08lx..%08lx\n",
+                 (unsigned long)(saved_start - section_start), length, cie_id,
+                 (unsigned long)(cie->chunk_start - section_start),
+                 fc->pc_begin, fc->pc_begin + fc->pc_range);
+         if (! do_debug_frames_interp && augmentation_data_len)
+           {
+             unsigned long i;
+             printf ("  Augmentation data:    ");
+             for (i = 0; i < augmentation_data_len; ++i)
+               printf (" %02x", augmentation_data[i]);
+             putchar ('\n');
+             putchar ('\n');
+           }
+       }
+
+      /* At this point, fc is the current chunk, cie (if any) is set, and we're
+        about to interpret instructions for the chunk.  */
+
+      if (do_debug_frames_interp)
+       {
+         /* Start by making a pass over the chunk, allocating storage
+            and taking note of what registers are used.  */
+         unsigned char *tmp = start;
+
+         while (start < block_end)
+           {
+             unsigned op, opa;
+             unsigned long reg, temp;
+
+             op = *start++;
+             opa = op & 0x3f;
+             if (op & 0xc0)
+               op &= 0xc0;
+
+             /* Warning: if you add any more cases to this switch, be
+                sure to add them to the corresponding switch below.  */
+             switch (op)
+               {
+               case DW_CFA_advance_loc:
+                 break;
+               case DW_CFA_offset:
+                 LEB ();
+                 frame_need_space (fc, opa);
+                 fc->col_type[opa] = DW_CFA_undefined;
+                 break;
+               case DW_CFA_restore:
+                 frame_need_space (fc, opa);
+                 fc->col_type[opa] = DW_CFA_undefined;
+                 break;
+               case DW_CFA_set_loc:
+                 start += encoded_ptr_size;
+                 break;
+               case DW_CFA_advance_loc1:
+                 start += 1;
+                 break;
+               case DW_CFA_advance_loc2:
+                 start += 2;
+                 break;
+               case DW_CFA_advance_loc4:
+                 start += 4;
+                 break;
+               case DW_CFA_offset_extended:
+                 reg = LEB (); LEB ();
+                 frame_need_space (fc, reg);
+                 fc->col_type[reg] = DW_CFA_undefined;
+                 break;
+               case DW_CFA_restore_extended:
+                 reg = LEB ();
+                 frame_need_space (fc, reg);
+                 fc->col_type[reg] = DW_CFA_undefined;
+                 break;
+               case DW_CFA_undefined:
+                 reg = LEB ();
+                 frame_need_space (fc, reg);
+                 fc->col_type[reg] = DW_CFA_undefined;
+                 break;
+               case DW_CFA_same_value:
+                 reg = LEB ();
+                 frame_need_space (fc, reg);
+                 fc->col_type[reg] = DW_CFA_undefined;
+                 break;
+               case DW_CFA_register:
+                 reg = LEB (); LEB ();
+                 frame_need_space (fc, reg);
+                 fc->col_type[reg] = DW_CFA_undefined;
+                 break;
+               case DW_CFA_def_cfa:
+                 LEB (); LEB ();
+                 break;
+               case DW_CFA_def_cfa_register:
+                 LEB ();
+                 break;
+               case DW_CFA_def_cfa_offset:
+                 LEB ();
+                 break;
+               case DW_CFA_def_cfa_expression:
+                 temp = LEB ();
+                 start += temp;
+                 break;
+               case DW_CFA_expression:
+                 reg = LEB ();
+                 temp = LEB ();
+                 start += temp;
+                 frame_need_space (fc, reg);
+                 fc->col_type[reg] = DW_CFA_undefined;
+                 break;
+               case DW_CFA_offset_extended_sf:
+                 reg = LEB (); SLEB ();
+                 frame_need_space (fc, reg);
+                 fc->col_type[reg] = DW_CFA_undefined;
+                 break;
+               case DW_CFA_def_cfa_sf:
+                 LEB (); SLEB ();
+                 break;
+               case DW_CFA_def_cfa_offset_sf:
+                 SLEB ();
+                 break;
+               case DW_CFA_MIPS_advance_loc8:
+                 start += 8;
+                 break;
+               case DW_CFA_GNU_args_size:
+                 LEB ();
+                 break;
+               case DW_CFA_GNU_negative_offset_extended:
+                 reg = LEB (); LEB ();
+                 frame_need_space (fc, reg);
+                 fc->col_type[reg] = DW_CFA_undefined;
+
+               default:
+                 break;
+               }
+           }
+         start = tmp;
+       }
+
+      /* Now we know what registers are used, make a second pass over
+         the chunk, this time actually printing out the info.  */
+
+      while (start < block_end)
+       {
+         unsigned op, opa;
+         unsigned long ul, reg, roffs;
+         long l, ofs;
+         bfd_vma vma;
+
+         op = *start++;
+         opa = op & 0x3f;
+         if (op & 0xc0)
+           op &= 0xc0;
+
+         /* Warning: if you add any more cases to this switch, be
+            sure to add them to the corresponding switch above.  */
+         switch (op)
+           {
+           case DW_CFA_advance_loc:
+             if (do_debug_frames_interp)
+               frame_display_row (fc, &need_col_headers, &max_regs);
+             else
+               printf ("  DW_CFA_advance_loc: %d to %08lx\n",
+                       opa * fc->code_factor,
+                       fc->pc_begin + opa * fc->code_factor);
+             fc->pc_begin += opa * fc->code_factor;
+             break;
+
+           case DW_CFA_offset:
+             roffs = LEB ();
+             if (! do_debug_frames_interp)
+               printf ("  DW_CFA_offset: r%d at cfa%+ld\n",
+                       opa, roffs * fc->data_factor);
+             fc->col_type[opa] = DW_CFA_offset;
+             fc->col_offset[opa] = roffs * fc->data_factor;
+             break;
+
+           case DW_CFA_restore:
+             if (! do_debug_frames_interp)
+               printf ("  DW_CFA_restore: r%d\n", opa);
+             fc->col_type[opa] = cie->col_type[opa];
+             fc->col_offset[opa] = cie->col_offset[opa];
+             break;
+
+           case DW_CFA_set_loc:
+             vma = byte_get (start, encoded_ptr_size);
+             if ((fc->fde_encoding & 0x70) == DW_EH_PE_pcrel)
+               vma += section->sh_addr + (start - section_start);
+             start += encoded_ptr_size;
+             if (do_debug_frames_interp)
+               frame_display_row (fc, &need_col_headers, &max_regs);
+             else
+               printf ("  DW_CFA_set_loc: %08lx\n", (unsigned long)vma);
+             fc->pc_begin = vma;
+             break;
+
+           case DW_CFA_advance_loc1:
+             ofs = byte_get (start, 1); start += 1;
+             if (do_debug_frames_interp)
+               frame_display_row (fc, &need_col_headers, &max_regs);
+             else
+               printf ("  DW_CFA_advance_loc1: %ld to %08lx\n",
+                       ofs * fc->code_factor,
+                       fc->pc_begin + ofs * fc->code_factor);
+             fc->pc_begin += ofs * fc->code_factor;
+             break;
+
+           case DW_CFA_advance_loc2:
+             ofs = byte_get (start, 2); start += 2;
+             if (do_debug_frames_interp)
+               frame_display_row (fc, &need_col_headers, &max_regs);
+             else
+               printf ("  DW_CFA_advance_loc2: %ld to %08lx\n",
+                       ofs * fc->code_factor,
+                       fc->pc_begin + ofs * fc->code_factor);
+             fc->pc_begin += ofs * fc->code_factor;
+             break;
+
+           case DW_CFA_advance_loc4:
+             ofs = byte_get (start, 4); start += 4;
+             if (do_debug_frames_interp)
+               frame_display_row (fc, &need_col_headers, &max_regs);
+             else
+               printf ("  DW_CFA_advance_loc4: %ld to %08lx\n",
+                       ofs * fc->code_factor,
+                       fc->pc_begin + ofs * fc->code_factor);
+             fc->pc_begin += ofs * fc->code_factor;
+             break;
+
+           case DW_CFA_offset_extended:
+             reg = LEB ();
+             roffs = LEB ();
+             if (! do_debug_frames_interp)
+               printf ("  DW_CFA_offset_extended: r%ld at cfa%+ld\n",
+                       reg, roffs * fc->data_factor);
+             fc->col_type[reg] = DW_CFA_offset;
+             fc->col_offset[reg] = roffs * fc->data_factor;
+             break;
+
+           case DW_CFA_restore_extended:
+             reg = LEB ();
+             if (! do_debug_frames_interp)
+               printf ("  DW_CFA_restore_extended: r%ld\n", reg);
+             fc->col_type[reg] = cie->col_type[reg];
+             fc->col_offset[reg] = cie->col_offset[reg];
+             break;
+
+           case DW_CFA_undefined:
+             reg = LEB ();
+             if (! do_debug_frames_interp)
+               printf ("  DW_CFA_undefined: r%ld\n", reg);
+             fc->col_type[reg] = DW_CFA_undefined;
+             fc->col_offset[reg] = 0;
+             break;
+
+           case DW_CFA_same_value:
+             reg = LEB ();
+             if (! do_debug_frames_interp)
+               printf ("  DW_CFA_same_value: r%ld\n", reg);
+             fc->col_type[reg] = DW_CFA_same_value;
+             fc->col_offset[reg] = 0;
+             break;
+
+           case DW_CFA_register:
+             reg = LEB ();
+             roffs = LEB ();
+             if (! do_debug_frames_interp)
+               printf ("  DW_CFA_register: r%ld\n", reg);
+             fc->col_type[reg] = DW_CFA_register;
+             fc->col_offset[reg] = roffs;
+             break;
+
+           case DW_CFA_remember_state:
+             if (! do_debug_frames_interp)
+               printf ("  DW_CFA_remember_state\n");
+             rs = (Frame_Chunk *) xmalloc (sizeof (Frame_Chunk));
+             rs->ncols = fc->ncols;
+             rs->col_type = (short int *) xmalloc (rs->ncols * sizeof (short int));
+             rs->col_offset = (int *) xmalloc (rs->ncols * sizeof (int));
+             memcpy (rs->col_type, fc->col_type, rs->ncols);
+             memcpy (rs->col_offset, fc->col_offset, rs->ncols * sizeof (int));
+             rs->next = remembered_state;
+             remembered_state = rs;
+             break;
+
+           case DW_CFA_restore_state:
+             if (! do_debug_frames_interp)
+               printf ("  DW_CFA_restore_state\n");
+             rs = remembered_state;
+             remembered_state = rs->next;
+             frame_need_space (fc, rs->ncols-1);
+             memcpy (fc->col_type, rs->col_type, rs->ncols);
+             memcpy (fc->col_offset, rs->col_offset, rs->ncols * sizeof (int));
+             free (rs->col_type);
+             free (rs->col_offset);
+             free (rs);
+             break;
+
+           case DW_CFA_def_cfa:
+             fc->cfa_reg = LEB ();
+             fc->cfa_offset = LEB ();
+             fc->cfa_exp = 0;
+             if (! do_debug_frames_interp)
+               printf ("  DW_CFA_def_cfa: r%d ofs %d\n",
+                       fc->cfa_reg, fc->cfa_offset);
+             break;
+
+           case DW_CFA_def_cfa_register:
+             fc->cfa_reg = LEB ();
+             fc->cfa_exp = 0;
+             if (! do_debug_frames_interp)
+               printf ("  DW_CFA_def_cfa_reg: r%d\n", fc->cfa_reg);
+             break;
+
+           case DW_CFA_def_cfa_offset:
+             fc->cfa_offset = LEB ();
+             if (! do_debug_frames_interp)
+               printf ("  DW_CFA_def_cfa_offset: %d\n", fc->cfa_offset);
+             break;
+
+           case DW_CFA_nop:
+             if (! do_debug_frames_interp)
+               printf ("  DW_CFA_nop\n");
+             break;
+
+           case DW_CFA_def_cfa_expression:
+             ul = LEB ();
+             if (! do_debug_frames_interp)
+               {
+                 printf ("  DW_CFA_def_cfa_expression (");
+                 decode_location_expression (start, addr_size, ul, 1, 0);
+                 printf (")\n");
+               }
+             fc->cfa_exp = 1;
+             start += ul;
+             break;
+
+           case DW_CFA_expression:
+             reg = LEB ();
+             ul = LEB ();
+             if (! do_debug_frames_interp)
+               {
+                 printf ("  DW_CFA_expression: r%ld (", reg);
+                 decode_location_expression (start, addr_size, ul, 1, 0);
+                 printf (")\n");
+               }
+             fc->col_type[reg] = DW_CFA_expression;
+             start += ul;
+             break;
+
+           case DW_CFA_offset_extended_sf:
+             reg = LEB ();
+             l = SLEB ();
+             frame_need_space (fc, reg);
+             if (! do_debug_frames_interp)
+               printf ("  DW_CFA_offset_extended_sf: r%ld at cfa%+ld\n",
+                       reg, l * fc->data_factor);
+             fc->col_type[reg] = DW_CFA_offset;
+             fc->col_offset[reg] = l * fc->data_factor;
+             break;
+
+           case DW_CFA_def_cfa_sf:
+             fc->cfa_reg = LEB ();
+             fc->cfa_offset = SLEB ();
+             fc->cfa_exp = 0;
+             if (! do_debug_frames_interp)
+               printf ("  DW_CFA_def_cfa_sf: r%d ofs %d\n",
+                       fc->cfa_reg, fc->cfa_offset);
+             break;
+
+           case DW_CFA_def_cfa_offset_sf:
+             fc->cfa_offset = SLEB ();
+             if (! do_debug_frames_interp)
+               printf ("  DW_CFA_def_cfa_offset_sf: %d\n", fc->cfa_offset);
+             break;
+
+           case DW_CFA_MIPS_advance_loc8:
+             ofs = byte_get (start, 8); start += 8;
+             if (do_debug_frames_interp)
+               frame_display_row (fc, &need_col_headers, &max_regs);
+             else
+               printf ("  DW_CFA_MIPS_advance_loc8: %ld to %08lx\n",
+                       ofs * fc->code_factor,
+                       fc->pc_begin + ofs * fc->code_factor);
+             fc->pc_begin += ofs * fc->code_factor;
+             break;
+
+           case DW_CFA_GNU_window_save:
+             if (! do_debug_frames_interp)
+               printf ("  DW_CFA_GNU_window_save\n");
+             break;
+
+           case DW_CFA_GNU_args_size:
+             ul = LEB ();
+             if (! do_debug_frames_interp)
+               printf ("  DW_CFA_GNU_args_size: %ld\n", ul);
+             break;
+
+           case DW_CFA_GNU_negative_offset_extended:
+             reg = LEB ();
+             l = - LEB ();
+             frame_need_space (fc, reg);
+             if (! do_debug_frames_interp)
+               printf ("  DW_CFA_GNU_negative_offset_extended: r%ld at cfa%+ld\n",
+                       reg, l * fc->data_factor);
+             fc->col_type[reg] = DW_CFA_offset;
+             fc->col_offset[reg] = l * fc->data_factor;
+             break;
+
+           default:
+             fprintf (stderr, "unsupported or unknown DW_CFA_%d\n", op);
+             start = block_end;
+           }
+       }
+
+      if (do_debug_frames_interp)
+       frame_display_row (fc, &need_col_headers, &max_regs);
+
+      start = block_end;
+    }
+
+  printf ("\n");
+
+  return 1;
+}
+
+#undef GET
+#undef LEB
+#undef SLEB
+
+static int
+display_debug_not_supported (section, start, file)
+     Elf_Internal_Shdr *section;
+     unsigned char *start ATTRIBUTE_UNUSED;
+     FILE *file ATTRIBUTE_UNUSED;
+{
+  printf (_("Displaying the debug contents of section %s is not yet supported.\n"),
+           SECTION_NAME (section));
+
+  return 1;
+}
+
+/* Pre-scan the .debug_info section to record the size of address.
+   When dumping the .debug_line, we use that size information, assuming
+   that all compilation units have the same address size.  */
+static int
+prescan_debug_info (section, start, file)
+     Elf_Internal_Shdr *section ATTRIBUTE_UNUSED;
+     unsigned char *start;
+     FILE *file ATTRIBUTE_UNUSED;
+{
+  unsigned long length;
+
+  /* Read the first 4 bytes.  For a 32-bit DWARF section, this will
+     be the length.  For a 64-bit DWARF section, it'll be the escape
+     code 0xffffffff followed by an 8 byte length.  For the purposes
+     of this prescan, we don't care about the actual length, but the
+     presence of the escape bytes does affect the location of the byte
+     which describes the address size.  */
+  length = byte_get (start, 4);
+
+  if (length == 0xffffffff)
+    {
+      /* For 64-bit DWARF, the 1-byte address_size field is 22 bytes
+         from the start of the section.  This is computed as follows:
+
+           unit_length:         12 bytes
+           version:              2 bytes
+           debug_abbrev_offset:  8 bytes
+           -----------------------------
+           Total:               22 bytes  */
+
+      debug_line_pointer_size = byte_get (start + 22, 1);
+    }
+  else
+    {
+      /* For 32-bit DWARF, the 1-byte address_size field is 10 bytes from
+         the start of the section:
+           unit_length:          4 bytes
+           version:              2 bytes
+           debug_abbrev_offset:  4 bytes
+           -----------------------------
+           Total:               10 bytes  */
+
+      debug_line_pointer_size = byte_get (start + 10, 1);
+    }
+  return 0;
+}
+
+  /* A structure containing the name of a debug section and a pointer
+     to a function that can decode it.  The third field is a prescan
+     function to be run over the section before displaying any of the
+     sections.  */
+struct
+{
+  const char *const name;
+  int (*display) PARAMS ((Elf_Internal_Shdr *, unsigned char *, FILE *));
+  int (*prescan) PARAMS ((Elf_Internal_Shdr *, unsigned char *, FILE *));
+}
+debug_displays[] =
+{
+  { ".debug_abbrev",           display_debug_abbrev, NULL },
+  { ".debug_aranges",          display_debug_aranges, NULL },
+  { ".debug_frame",            display_debug_frames, NULL },
+  { ".debug_info",             display_debug_info, prescan_debug_info },
+  { ".debug_line",             display_debug_lines, NULL },
+  { ".debug_pubnames",         display_debug_pubnames, NULL },
+  { ".eh_frame",               display_debug_frames, NULL },
+  { ".debug_macinfo",          display_debug_macinfo, NULL },
+  { ".debug_str",              display_debug_str, NULL },
+  { ".debug_loc",              display_debug_loc, NULL },
+  { ".debug_pubtypes",         display_debug_not_supported, NULL },
+  { ".debug_ranges",           display_debug_not_supported, NULL },
+  { ".debug_static_func",      display_debug_not_supported, NULL },
+  { ".debug_static_vars",      display_debug_not_supported, NULL },
+  { ".debug_types",            display_debug_not_supported, NULL },
+  { ".debug_weaknames",                display_debug_not_supported, NULL }
+};
+
+static int
+display_debug_section (section, file)
+     Elf_Internal_Shdr *section;
+     FILE *file;
+{
+  char *name = SECTION_NAME (section);
+  bfd_size_type length;
+  unsigned char *start;
+  int i;
+
+  length = section->sh_size;
+  if (length == 0)
+    {
+      printf (_("\nSection '%s' has no debugging data.\n"), name);
+      return 0;
+    }
+
+  start = (unsigned char *) get_data (NULL, file, section->sh_offset, length,
+                                     _("debug section data"));
+  if (!start)
+    return 0;
+
+  /* See if we know how to display the contents of this section.  */
+  if (strncmp (name, ".gnu.linkonce.wi.", 17) == 0)
+    name = ".debug_info";
+
+  for (i = NUM_ELEM (debug_displays); i--;)
+    if (strcmp (debug_displays[i].name, name) == 0)
+      {
+       debug_displays[i].display (section, start, file);
+       break;
+      }
+
+  if (i == -1)
+    printf (_("Unrecognized debug section: %s\n"), name);
+
+  free (start);
+
+  /* If we loaded in the abbrev section at some point,
+     we must release it here.  */
+  free_abbrevs ();
+
+  return 1;
+}
+
+static int
+process_section_contents (file)
+     FILE *file;
+{
+  Elf_Internal_Shdr *section;
+  unsigned int i;
+
+  if (! do_dump)
+    return 1;
+
+  //  printf("process_section_contents() - before 1st for loop\n");
+
+  /* Pre-scan the debug sections to find some debug information not
+     present in some of them.  For the .debug_line, we must find out the
+     size of address (specified in .debug_info and .debug_aranges).  */
+  for (i = 0, section = section_headers;
+       i < elf_header.e_shnum && i < num_dump_sects;
+       i++, section++)
+    {
+      char *name = SECTION_NAME (section);
+      int j;
+
+      if (section->sh_size == 0)
+       continue;
+
+      /* See if there is some pre-scan operation for this section.  */
+      for (j = NUM_ELEM (debug_displays); j--;)
+       if (strcmp (debug_displays[j].name, name) == 0)
+         {
+           if (debug_displays[j].prescan != NULL)
+             {
+               bfd_size_type length;
+               unsigned char *start;
+
+               length = section->sh_size;
+               start = ((unsigned char *)
+                        get_data (NULL, file, section->sh_offset, length,
+                                  _("debug section data")));
+               if (!start)
+                 return 0;
+
+               debug_displays[j].prescan (section, start, file);
+               free (start);
+             }
+
+           break;
+         }
+    }
+
+  //  printf("process_section_contents() - before 2nd for loop\n");
+
+  for (i = 0, section = section_headers;
+       i < elf_header.e_shnum && i < num_dump_sects;
+       i++, section++)
+    {
+#ifdef SUPPORT_DISASSEMBLY
+      if (dump_sects[i] & DISASS_DUMP)
+       disassemble_section (section, file);
+#endif
+      if (dump_sects[i] & HEX_DUMP)
+        {
+          dump_section (section, file);
+        }
+
+      if (dump_sects[i] & DEBUG_DUMP)
+        {
+          display_debug_section (section, file);
+        }
+    }
+
+  //  printf("process_section_contents() - after 2nd for loop\n");
+
+  if (i < num_dump_sects)
+    {
+      warn (_("Some sections were not dumped because they do not exist!\n"));
+    }
+
+  return 1;
+}
+
+static int
+process_mips_specific (file)
+     FILE *file;
+{
+  /* We have a lot of special sections.  Thanks SGI!  */
+  if (dynamic_segment == NULL)
+    /* No information available.  */
+    return 0;
+  return 1;
+}
+
+static int
+process_gnu_liblist (file)
+     FILE *file;
+{
+  return 1;
+}
+
+static const char *
+get_note_type (e_type)
+     unsigned e_type;
+{
+  static char buff[64];
+
+  switch (e_type)
+    {
+    case NT_PRSTATUS:  return _("NT_PRSTATUS (prstatus structure)");
+    case NT_FPREGSET:  return _("NT_FPREGSET (floating point registers)");
+    case NT_PRPSINFO:  return _("NT_PRPSINFO (prpsinfo structure)");
+    case NT_TASKSTRUCT:        return _("NT_TASKSTRUCT (task structure)");
+    case NT_PRXFPREG:  return _("NT_PRXFPREG (user_xfpregs structure)");
+    case NT_PSTATUS:   return _("NT_PSTATUS (pstatus structure)");
+    case NT_FPREGS:    return _("NT_FPREGS (floating point registers)");
+    case NT_PSINFO:    return _("NT_PSINFO (psinfo structure)");
+    case NT_LWPSTATUS: return _("NT_LWPSTATUS (lwpstatus_t structure)");
+    case NT_LWPSINFO:  return _("NT_LWPSINFO (lwpsinfo_t structure)");
+    case NT_WIN32PSTATUS: return _("NT_WIN32PSTATUS (win32_pstatus structure)");
+    default:
+      sprintf (buff, _("Unknown note type: (0x%08x)"), e_type);
+      return buff;
+    }
+}
+
+static const char *
+get_netbsd_elfcore_note_type (e_type)
+     unsigned e_type;
+{
+  static char buff[64];
+
+  if (e_type == NT_NETBSDCORE_PROCINFO)
+    {
+      /* NetBSD core "procinfo" structure.  */
+      return _("NetBSD procinfo structure");
+    }
+
+  /* As of Jan 2002 there are no other machine-independent notes
+     defined for NetBSD core files.  If the note type is less
+     than the start of the machine-dependent note types, we don't
+     understand it.  */
+
+  if (e_type < NT_NETBSDCORE_FIRSTMACH)
+    {
+      sprintf (buff, _("Unknown note type: (0x%08x)"), e_type);
+      return buff;
+    }
+
+  switch (elf_header.e_machine)
+    {
+    /* On the Alpha, SPARC (32-bit and 64-bit), PT_GETREGS == mach+0
+       and PT_GETFPREGS == mach+2.  */
+
+    case EM_OLD_ALPHA:
+    case EM_ALPHA:
+    case EM_SPARC:
+    case EM_SPARC32PLUS:
+    case EM_SPARCV9:
+      switch (e_type)
+       {
+       case NT_NETBSDCORE_FIRSTMACH+0:
+         return _("PT_GETREGS (reg structure)");
+       case NT_NETBSDCORE_FIRSTMACH+2:
+         return _("PT_GETFPREGS (fpreg structure)");
+       default:
+         break;
+       }
+      break;
+
+    /* On all other arch's, PT_GETREGS == mach+1 and
+       PT_GETFPREGS == mach+3.  */
+    default:
+      switch (e_type)
+       {
+       case NT_NETBSDCORE_FIRSTMACH+1:
+         return _("PT_GETREGS (reg structure)");
+       case NT_NETBSDCORE_FIRSTMACH+3:
+         return _("PT_GETFPREGS (fpreg structure)");
+       default:
+         break;
+       }
+    }
+
+  sprintf (buff, _("PT_FIRSTMACH+%d"), e_type - NT_NETBSDCORE_FIRSTMACH);
+  return buff;
+}
+
+/* Note that by the ELF standard, the name field is already null byte
+   terminated, and namesz includes the terminating null byte.
+   I.E. the value of namesz for the name "FSF" is 4.
+
+   If the value of namesz is zero, there is no name present.  */
+static int
+process_note (pnote)
+     Elf_Internal_Note *pnote;
+{
+  const char *nt;
+
+  if (pnote->namesz == 0)
+    {
+      /* If there is no note name, then use the default set of
+        note type strings.  */
+      nt = get_note_type (pnote->type);
+    }
+  else if (strncmp (pnote->namedata, "NetBSD-CORE", 11) == 0)
+    {
+      /* NetBSD-specific core file notes.  */
+      nt = get_netbsd_elfcore_note_type (pnote->type);
+    }
+  else
+    {
+      /* Don't recognize this note name; just use the default set of
+        note type strings.  */
+      nt = get_note_type (pnote->type);
+    }
+
+  printf ("  %s\t\t0x%08lx\t%s\n",
+         pnote->namesz ? pnote->namedata : "(NONE)",
+         pnote->descsz, nt);
+  return 1;
+}
+
+
+static int
+process_corefile_note_segment (file, offset, length)
+     FILE *file;
+     bfd_vma offset;
+     bfd_vma length;
+{
+  Elf_External_Note *pnotes;
+  Elf_External_Note *external;
+  int res = 1;
+
+  if (length <= 0)
+    return 0;
+
+  pnotes = (Elf_External_Note *) get_data (NULL, file, offset, length,
+                                          _("notes"));
+  if (!pnotes)
+    return 0;
+
+  external = pnotes;
+
+  printf (_("\nNotes at offset 0x%08lx with length 0x%08lx:\n"),
+         (unsigned long) offset, (unsigned long) length);
+  printf (_("  Owner\t\tData size\tDescription\n"));
+
+  while (external < (Elf_External_Note *)((char *) pnotes + length))
+    {
+      Elf_External_Note *next;
+      Elf_Internal_Note inote;
+      char *temp = NULL;
+
+      inote.type     = BYTE_GET (external->type);
+      inote.namesz   = BYTE_GET (external->namesz);
+      inote.namedata = external->name;
+      inote.descsz   = BYTE_GET (external->descsz);
+      inote.descdata = inote.namedata + align_power (inote.namesz, 2);
+      inote.descpos  = offset + (inote.descdata - (char *) pnotes);
+
+      next = (Elf_External_Note *)(inote.descdata + align_power (inote.descsz, 2));
+
+      if (((char *) next) > (((char *) pnotes) + length))
+       {
+         warn (_("corrupt note found at offset %x into core notes\n"),
+               ((char *) external) - ((char *) pnotes));
+         warn (_(" type: %x, namesize: %08lx, descsize: %08lx\n"),
+               inote.type, inote.namesz, inote.descsz);
+         break;
+       }
+
+      external = next;
+
+      /* Verify that name is null terminated.  It appears that at least
+        one version of Linux (RedHat 6.0) generates corefiles that don't
+        comply with the ELF spec by failing to include the null byte in
+        namesz.  */
+      if (inote.namedata[inote.namesz] != '\0')
+       {
+         temp = malloc (inote.namesz + 1);
+
+         if (temp == NULL)
+           {
+             error (_("Out of memory\n"));
+             res = 0;
+             break;
+           }
+
+         strncpy (temp, inote.namedata, inote.namesz);
+         temp[inote.namesz] = 0;
+
+         /* warn (_("'%s' NOTE name not properly null terminated\n"), temp);  */
+         inote.namedata = temp;
+       }
+
+      res &= process_note (& inote);
+
+      if (temp != NULL)
+       {
+         free (temp);
+         temp = NULL;
+       }
+    }
+
+  free (pnotes);
+
+  return res;
+}
+
+static int
+process_corefile_note_segments (file)
+     FILE *file;
+{
+  Elf_Internal_Phdr *program_headers;
+  Elf_Internal_Phdr *segment;
+  unsigned int i;
+  int res = 1;
+
+  program_headers = (Elf_Internal_Phdr *) malloc
+    (elf_header.e_phnum * sizeof (Elf_Internal_Phdr));
+
+  if (program_headers == NULL)
+    {
+      error (_("Out of memory\n"));
+      return 0;
+    }
+
+  if (is_32bit_elf)
+    i = get_32bit_program_headers (file, program_headers);
+  else
+    i = get_64bit_program_headers (file, program_headers);
+
+  if (i == 0)
+    {
+      free (program_headers);
+      return 0;
+    }
+
+  for (i = 0, segment = program_headers;
+       i < elf_header.e_phnum;
+       i++, segment++)
+    {
+      if (segment->p_type == PT_NOTE)
+       res &= process_corefile_note_segment (file,
+                                             (bfd_vma) segment->p_offset,
+                                             (bfd_vma) segment->p_filesz);
+    }
+
+  free (program_headers);
+
+  return res;
+}
+
+static int
+process_corefile_contents (file)
+     FILE *file;
+{
+  /* If we have not been asked to display the notes then do nothing.  */
+  if (! do_notes)
+    return 1;
+
+  /* If file is not a core file then exit.  */
+  if (elf_header.e_type != ET_CORE)
+    return 1;
+
+  /* No program headers means no NOTE segment.  */
+  if (elf_header.e_phnum == 0)
+    {
+      printf (_("No note segments present in the core file.\n"));
+      return 1;
+   }
+
+  return process_corefile_note_segments (file);
+}
+
+static int
+process_arch_specific (file)
+     FILE *file;
+{
+  if (! do_arch)
+    return 1;
+
+  switch (elf_header.e_machine)
+    {
+    case EM_MIPS:
+    case EM_MIPS_RS3_LE:
+      return process_mips_specific (file);
+      break;
+    default:
+      break;
+    }
+  return 1;
+}
+
+static int
+get_file_header (file)
+     FILE *file;
+{
+  /* Read in the identity array.  */
+  if (fread (elf_header.e_ident, EI_NIDENT, 1, file) != 1)
+    return 0;
+
+  /* Determine how to read the rest of the header.  */
+  switch (elf_header.e_ident[EI_DATA])
+    {
+    default: /* fall through */
+    case ELFDATANONE: /* fall through */
+    case ELFDATA2LSB:
+      byte_get = byte_get_little_endian;
+      byte_put = byte_put_little_endian;
+      break;
+    case ELFDATA2MSB:
+      byte_get = byte_get_big_endian;
+      byte_put = byte_put_big_endian;
+      break;
+    }
+
+  /* For now we only support 32 bit and 64 bit ELF files.  */
+  is_32bit_elf = (elf_header.e_ident[EI_CLASS] != ELFCLASS64);
+
+  /* Read in the rest of the header.  */
+  if (is_32bit_elf)
+    {
+      Elf32_External_Ehdr ehdr32;
+
+      if (fread (ehdr32.e_type, sizeof (ehdr32) - EI_NIDENT, 1, file) != 1)
+       return 0;
+
+      elf_header.e_type      = BYTE_GET (ehdr32.e_type);
+      elf_header.e_machine   = BYTE_GET (ehdr32.e_machine);
+      elf_header.e_version   = BYTE_GET (ehdr32.e_version);
+      elf_header.e_entry     = BYTE_GET (ehdr32.e_entry);
+      elf_header.e_phoff     = BYTE_GET (ehdr32.e_phoff);
+      elf_header.e_shoff     = BYTE_GET (ehdr32.e_shoff);
+      elf_header.e_flags     = BYTE_GET (ehdr32.e_flags);
+      elf_header.e_ehsize    = BYTE_GET (ehdr32.e_ehsize);
+      elf_header.e_phentsize = BYTE_GET (ehdr32.e_phentsize);
+      elf_header.e_phnum     = BYTE_GET (ehdr32.e_phnum);
+      elf_header.e_shentsize = BYTE_GET (ehdr32.e_shentsize);
+      elf_header.e_shnum     = BYTE_GET (ehdr32.e_shnum);
+      elf_header.e_shstrndx  = BYTE_GET (ehdr32.e_shstrndx);
+    }
+  else
+    {
+      Elf64_External_Ehdr ehdr64;
+
+      /* If we have been compiled with sizeof (bfd_vma) == 4, then
+        we will not be able to cope with the 64bit data found in
+        64 ELF files.  Detect this now and abort before we start
+        overwritting things.  */
+      if (sizeof (bfd_vma) < 8)
+       {
+         error (_("This instance of readelf has been built without support for a\n\
+64 bit data type and so it cannot read 64 bit ELF files.\n"));
+         return 0;
+       }
+
+      if (fread (ehdr64.e_type, sizeof (ehdr64) - EI_NIDENT, 1, file) != 1)
+       return 0;
+
+      elf_header.e_type      = BYTE_GET (ehdr64.e_type);
+      elf_header.e_machine   = BYTE_GET (ehdr64.e_machine);
+      elf_header.e_version   = BYTE_GET (ehdr64.e_version);
+      elf_header.e_entry     = BYTE_GET8 (ehdr64.e_entry);
+      elf_header.e_phoff     = BYTE_GET8 (ehdr64.e_phoff);
+      elf_header.e_shoff     = BYTE_GET8 (ehdr64.e_shoff);
+      elf_header.e_flags     = BYTE_GET (ehdr64.e_flags);
+      elf_header.e_ehsize    = BYTE_GET (ehdr64.e_ehsize);
+      elf_header.e_phentsize = BYTE_GET (ehdr64.e_phentsize);
+      elf_header.e_phnum     = BYTE_GET (ehdr64.e_phnum);
+      elf_header.e_shentsize = BYTE_GET (ehdr64.e_shentsize);
+      elf_header.e_shnum     = BYTE_GET (ehdr64.e_shnum);
+      elf_header.e_shstrndx  = BYTE_GET (ehdr64.e_shstrndx);
+    }
+
+  if (elf_header.e_shoff)
+    {
+      /* There may be some extensions in the first section header.  Don't
+        bomb if we can't read it.  */
+      if (is_32bit_elf)
+       get_32bit_section_headers (file, 1);
+      else
+       get_64bit_section_headers (file, 1);
+    }
+
+  return 1;
+}
+
+static int
+process_file (file_name)
+     char *file_name;
+{
+  FILE *file;
+  struct stat statbuf;
+  unsigned int i;
+
+  if (stat (file_name, & statbuf) < 0)
+    {
+      error (_("Cannot stat input file %s.\n"), file_name);
+      return 1;
+    }
+
+  file = fopen (file_name, "rb");
+  if (file == NULL)
+    {
+      error (_("Input file %s not found.\n"), file_name);
+      return 1;
+    }
+
+  if (! get_file_header (file))
+    {
+      error (_("%s: Failed to read file header\n"), file_name);
+      fclose (file);
+      return 1;
+    }
+
+  /* Initialise per file variables.  */
+  for (i = NUM_ELEM (version_info); i--;)
+    version_info[i] = 0;
+
+  for (i = NUM_ELEM (dynamic_info); i--;)
+    dynamic_info[i] = 0;
+
+  /* Process the file.  */
+#ifdef SHOW_DEBUG
+  if (show_name)
+    printf (_("\nFile: %s\n"), file_name);
+#endif
+
+  //  printf("before process_file_header()\n"); //PG
+
+  if (! process_file_header ())
+    {
+      printf("failed process_file_header()\n"); //PG
+      fclose (file);
+      return 1;
+    }
+
+  //  printf("before process_section_headers()\n"); //PG
+
+  if (! process_section_headers (file))
+    {
+      printf("failed process_section_headers()\n"); //PG
+      /* Without loaded section headers we
+        cannot process lots of things.  */
+      do_unwind = do_version = do_dump = do_arch = 0;
+
+      if (! do_using_dynamic)
+       do_syms = do_reloc = 0;
+    }
+
+  //  printf("before process_program_headers()\n"); //PG
+
+  if (process_program_headers (file))
+    process_dynamic_segment (file);
+  //  printf("before process_relocs()\n"); //PG
+  process_relocs (file);
+  //  printf("before process_unwind()\n"); //PG
+  process_unwind (file);
+  //  printf("before process_symbol_table()\n"); //PG
+  process_symbol_table (file);
+  //  printf("before process_syminfo()\n"); //PG
+  process_syminfo (file);
+  //  printf("before process_version_sections()\n"); //PG
+  process_version_sections (file);
+  //  printf("before process_section_contents()\n"); //PG
+  process_section_contents (file);
+  //  printf("before process_corefile_contents()\n"); //PG
+  process_corefile_contents (file);
+  //  printf("before process_gnu_liblist()\n"); //PG
+  process_gnu_liblist (file);
+  //  printf("before process_arch_specific()\n"); //PG
+  process_arch_specific (file);
+
+  fclose (file);
+
+  if (section_headers)
+    {
+      free (section_headers);
+      section_headers = NULL;
+    }
+
+  if (string_table)
+    {
+      free (string_table);
+      string_table = NULL;
+      string_table_length = 0;
+    }
+
+  if (dynamic_strings)
+    {
+      free (dynamic_strings);
+      dynamic_strings = NULL;
+    }
+
+  if (dynamic_symbols)
+    {
+      free (dynamic_symbols);
+      dynamic_symbols = NULL;
+      num_dynamic_syms = 0;
+    }
+
+  if (dynamic_syminfo)
+    {
+      free (dynamic_syminfo);
+      dynamic_syminfo = NULL;
+    }
+
+  return 0;
+}
+
+#ifdef SUPPORT_DISASSEMBLY
+/* Needed by the i386 disassembler.  For extra credit, someone could
+   fix this so that we insert symbolic addresses here, esp for GOT/PLT
+   symbols.  */
+
+void
+print_address (unsigned int addr, FILE *outfile)
+{
+  fprintf (outfile,"0x%8.8x", addr);
+}
+
+/* Needed by the i386 disassembler.  */
+void
+db_task_printsym (unsigned int addr)
+{
+  print_address (addr, stderr);
+}
+#endif
+
+//PG insert a fake main which is a hacked copy that can be called
+// with a filename argument
+
+int process_elf_binary_data(char* filename)
+{
+  int err;
+  char *cmdline_dump_sects = NULL;
+
+  char **hack_argv = 0;
+  int argc = 3;
+
+  static char default_exec_name[10] = "./readelf"; // dummy!!! (why size 10 instead of 9?)
+  static char default_option[17] = "--debug-dump=info";
+
+  // int i;
+  //  for (i = 0; i < argc; i++)
+    //    printf("argv[%d] = %s\n", i, argv[i]);
+
+  //  printf("\n-------------------------------------\n\n");
+
+/* //PG
+argument format - argv[0] is executable, argv[1] is the option that we
+                  want to hijack "--debug-dump=info", and argv[2] is the filename
+argv[0] = ./readelf (executable name)
+argv[1] = --debug-dump=info (desired option)
+argv[2] = ../tests/TypesTest/TypesTest (filename)
+
+Here is my hack.  Instead of requiring the user to pass in --debug-dump=info,
+we just make the user pass in the filename as the only argument and then
+apply --debug-dump=info by default
+
+Let's create our own hack_argv array:
+
+hack_argv[0] = "./readelf"
+hack_argv[1] = "--debug-dump=info"
+hack_argv[2] = filename
+*/
+
+  // Allocate three character pointer
+  hack_argv = malloc(3 * sizeof(*hack_argv));
+
+  hack_argv[0] = default_exec_name;
+  hack_argv[1] = default_option;
+  hack_argv[2] = filename;
+
+#ifdef SHOW_DEBUG
+  printf("filename: 0x%x\n", filename);
+  for (i = 0; i < argc; i++)
+    printf("hack_argv[%d] = %s\n", i, hack_argv[i]);
+
+  printf("\n-------------------------------------\n\n");
+#endif
+
+  // PG - now hijack parse_args and pass in my hacked argv
+  //  parse_args (argc, argv);
+  //  printf("before parse_args(%d, 0x%x)\n", argc, hack_argv);
+  parse_args (argc, hack_argv);
+  //  printf("after parse_args\n");
+  //  printf("optind = %d\n", optind);
+
+  //  if (optind < (argc - 1))
+  show_name = 1;
+
+  /* When processing more than one file remember the dump requests
+     issued on command line to reset them after each file.  */
+
+  /*
+  if (optind + 1 < argc && dump_sects != NULL)
+    {
+      cmdline_dump_sects = malloc (num_dump_sects);
+      if (cmdline_dump_sects == NULL)
+       error (_("Out of memory allocating dump request table."));
+      else
+       {
+         memcpy (cmdline_dump_sects, dump_sects, num_dump_sects);
+         num_cmdline_dump_sects = num_dump_sects;
+       }
+    }
+  */
+
+  err = 0;
+  //  while (optind < argc)
+  //    {
+  //      err |= process_file (hack_argv[optind++]); //PG - replace argv with hack_argv
+  //
+  //      /* Reset dump requests.  */
+  //      if (optind < argc && dump_sects != NULL)
+  //   {
+  //     num_dump_sects = num_cmdline_dump_sects;
+  //     if (num_cmdline_dump_sects > 0)
+  //       memcpy (dump_sects, cmdline_dump_sects, num_cmdline_dump_sects);
+  //   }
+  //    }
+
+  err = process_file (hack_argv[argc - 1]); //PG - replace argv with hack_argv
+
+  //  printf("AFTER process_file(0x%x)\n", hack_argv[argc-1]);
+
+  if (dump_sects != NULL)
+    free (dump_sects);
+  if (cmdline_dump_sects != NULL)
+    free (cmdline_dump_sects);
+
+  return err;
+}
+
+// End //PG
+/*
+int main PARAMS ((int, char **));
+
+int
+main (argc, argv)
+     int argc;
+     char **argv;
+{
+  int status = process_elf_binary_data(argv[argc-1]); // Past last argument, which should be target filename
+  return status;
+}
+*/
diff --git a/Repair/RepairCompiler/structextract/typedata.c b/Repair/RepairCompiler/structextract/typedata.c
new file mode 100755 (executable)
index 0000000..5601a3a
--- /dev/null
@@ -0,0 +1,1221 @@
+/*
+   This file is part of Kvasir, a Valgrind skin that implements the
+   C language front-end for the Daikon Invariant Detection System
+
+   Copyright (C) 2004 Philip Guo, MIT CSAIL Program Analysis Group
+
+   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.
+*/
+
+/* typedata.c:
+   This file contains functions that serve to complement readelf.c
+   and arrange the DWARF2 debugging information in an orderly
+   format within dwarf_entry_array
+*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "typedata.h"
+#include "elf/dwarf2.h"
+
+// Global array of all dwarf entries, sorted (hopefully) by dwarf_entry.ID
+// so that binary search is possible
+// DO NOT MODIFY THIS POINTER MANUALLY!!!
+// Representation invariants:
+// 1. Every entry in dwarf_entry_array is sorted by ascending ID
+//    (This makes binary search possible)
+// 2. dwarf_entry_array points to the beginning of the array
+// 3. The size of the array is specified by dwarf_entry_array_size
+// 4. All function entries are listed adjacent to their formal parameters
+// 5. All struct, union, and enumeration entries are listed adjacent
+//    to their members
+// 6. All entries in the array belong to the file specified by the first
+//    compile_unit entry to its left (lower indices) in the array
+dwarf_entry* dwarf_entry_array = 0;
+
+// The size of this array
+unsigned long dwarf_entry_array_size = 0;
+
+
+/*----------------------------------------
+Extracting type information from DWARF tag
+-----------------------------------------*/
+
+
+/*
+Requires:
+Modifies:
+Returns: 1 if tag = {DW_TAG_base_type, _const_type, _enumerator,
+                     _formal_parameter, _pointer_type, _array_type, _subprogram,
+                     _union_type, _enumeration_type, _member,
+                     _structure_type, _volatile_type, _compile_unit},
+                     0 otherwise
+Effects: Used to determine which entries to record into a dwarf_entry structure;
+         All relevant entries should be included here
+*/
+char tag_is_relevant_entry(unsigned long tag)
+{
+  return 1;
+  switch (tag)
+    {
+    case DW_TAG_enumeration_type:
+    case DW_TAG_formal_parameter:
+    case DW_TAG_member:
+    case DW_TAG_pointer_type:
+    case DW_TAG_structure_type:
+    case DW_TAG_union_type:
+    case DW_TAG_base_type:
+    case DW_TAG_const_type:
+    case DW_TAG_enumerator:
+    case DW_TAG_subprogram:
+    case DW_TAG_volatile_type:
+    case DW_TAG_compile_unit:
+    case DW_TAG_array_type:
+    case DW_TAG_subroutine_type:
+    case DW_TAG_subrange_type:
+      return 1;
+    default:
+      return 0;
+    }
+}
+
+/*
+Requires:
+Modifies:
+Returns: 1 if tag = {DW_TAG_pointer_type, _array_type, _const_type, _volatile_type},
+                     0 otherwise
+Effects: Used to determine if the type is a modifier - modifier types
+         refer to another type within the dwarf_entry_array after
+         preprocessing
+*/
+char tag_is_modifier_type(unsigned long tag)
+{
+  switch (tag)
+    {
+    case DW_TAG_pointer_type:
+    case DW_TAG_array_type:
+    case DW_TAG_const_type:
+    case DW_TAG_volatile_type:
+      return 1;
+    default:
+      return 0;
+    }
+}
+
+/*
+Requires:
+Modifies:
+Returns: 1 if tag = {DW_TAG_enumeration_type, _structure_type, _union_type},
+                     0 otherwise
+Effects: Used to determine if the type is a collection of some sort -
+         collections have members and unique type names
+*/
+char tag_is_collection_type(unsigned long tag)
+{
+  switch (tag)
+    {
+    case DW_TAG_enumeration_type:
+    case DW_TAG_structure_type:
+    case DW_TAG_union_type:
+      return 1;
+    default:
+      return 0;
+    }
+}
+
+// The rest of these should be self-explanatory:
+char tag_is_base_type(unsigned long tag)
+{
+  return (tag == DW_TAG_base_type);
+}
+
+char tag_is_member(unsigned long tag)
+{
+  return (tag == DW_TAG_member);
+}
+
+char tag_is_enumerator(unsigned long tag)
+{
+  return (tag == DW_TAG_enumerator);
+}
+
+char tag_is_function(unsigned long tag)
+{
+  return (tag == DW_TAG_subprogram);
+}
+
+char tag_is_formal_parameter(unsigned long tag)
+{
+  return (tag == DW_TAG_formal_parameter);
+}
+
+char tag_is_compile_unit(unsigned long tag)
+{
+  return (tag == DW_TAG_compile_unit);
+}
+
+char tag_is_function_type(unsigned long tag) {
+  return (tag == DW_TAG_subroutine_type);
+}
+
+/*------------------
+ Attribute listeners
+ ------------------*/
+
+// Each type stored in dwarf_entry.entry_ptr listens for particular
+// attributes.  e.g. collection_type listens for DW_AT_name and DW_AT_byte_size
+
+// DW_AT_location: formal_parameter
+// DW_AT_name: collection_type, member, enumerator, function, formal_parameter, compile_unit
+// DW_AT_byte_size: base_type, collection_type, member
+// DW_AT_bit_offset: base_type, member
+// DW_AT_bit_size: base_type, member
+// DW_AT_const_value: enumerator
+// DW_AT_data_member_location: member
+// DW_AT_type: modifier, member, function, formal_parameter
+// DW_AT_encoding: base_type
+// DW_AT_comp_dir: compile_unit
+// DW_AT_external: function
+// DW_AT_low_pc: function
+
+// Returns: 1 if the entry has a type that is listening for the
+// given attribute (attr), 0 otherwise
+char entry_is_listening_for_attribute(dwarf_entry* e, unsigned long attr)
+{
+  unsigned long tag;
+
+  if(e == 0)
+    return 0;
+
+  tag = e->tag_name;
+  switch(attr)
+    {
+    case DW_AT_location:
+      return tag_is_formal_parameter(tag);
+    case DW_AT_name:
+      return (tag_is_collection_type(tag) ||
+              tag_is_member(tag) ||
+              tag_is_enumerator(tag) ||
+              tag_is_function(tag) ||
+              tag_is_formal_parameter(tag) ||
+              tag_is_compile_unit(tag));
+    case DW_AT_byte_size:
+      return (tag_is_base_type(tag) ||
+              tag_is_collection_type(tag) ||
+              tag_is_member(tag));
+    case DW_AT_bit_offset:
+      return (tag_is_base_type(tag) ||
+              tag_is_member(tag));
+    case DW_AT_bit_size:
+      return (tag_is_base_type(tag) ||
+              tag_is_member(tag));
+    case DW_AT_const_value:
+      return tag_is_enumerator(tag);
+    case DW_AT_data_member_location:
+      return tag_is_member(tag);
+    case DW_AT_type:
+      return (tag_is_modifier_type(tag) ||
+              tag_is_member(tag) ||
+              tag_is_function(tag) ||
+              tag_is_formal_parameter(tag) ||
+              tag_is_function_type(tag));
+    case DW_AT_upper_bound:
+      return (tag==DW_TAG_subrange_type);
+    case DW_AT_encoding:
+      return tag_is_base_type(tag);
+    case DW_AT_comp_dir:
+      return tag_is_compile_unit(tag);
+    case DW_AT_external:
+      return tag_is_function(tag);
+    case DW_AT_low_pc:
+      return tag_is_function(tag);
+    default:
+      return 0;
+    }
+}
+
+/*--------
+Harvesters
+---------*/
+// Harvest attribute values into the appropriate entry
+// Returns a boolean to signal success or failure
+// Remember to only harvest attribute value if the type is listening for it
+
+char harvest_type_value(dwarf_entry* e, unsigned long value)
+{
+  unsigned long tag;
+  if ((e == 0) || (e->entry_ptr == 0))
+    return 0;
+
+  tag = e->tag_name;
+
+  if (tag ==DW_TAG_subrange_type) {
+    ((array_bound*)e->entry_ptr)->target_ID = value;
+    return 1;
+  } else if (tag_is_modifier_type(tag))
+    {
+      ((modifier_type*)e->entry_ptr)->target_ID = value;
+      return 1;
+    }
+  else if (tag_is_member(tag))
+    {
+      ((member*)e->entry_ptr)->type_ID = value;
+      return 1;
+    }
+  else if (tag_is_function(tag))
+    {
+      ((function*)e->entry_ptr)->return_type_ID = value;
+      return 1;
+    }
+  else if (tag_is_formal_parameter(tag))
+    {
+      ((formal_parameter*)e->entry_ptr)->type_ID = value;
+      return 1;
+    }
+  else if (tag_is_function_type(tag))
+    {
+      ((function_type *)e->entry_ptr)->return_type_ID = value;
+      return 1;
+    }
+  else
+    return 0;
+}
+
+char harvest_byte_size_value(dwarf_entry* e, unsigned long value)
+{
+  unsigned long tag;
+  if ((e == 0) || (e->entry_ptr == 0))
+    return 0;
+
+  tag = e->tag_name;
+
+  if (tag_is_base_type(tag))
+    {
+      ((base_type*)e->entry_ptr)->byte_size = value;
+      return 1;
+    }
+  else if (tag_is_collection_type(tag))
+    {
+      ((collection_type*)e->entry_ptr)->byte_size = value;
+      return 1;
+    }
+  else if (tag_is_member(tag))
+    {
+      ((member*)e->entry_ptr)->byte_size = value;
+      return 1;
+    }
+  else
+    return 0;
+}
+
+char harvest_encoding_value(dwarf_entry* e, unsigned long value)
+{
+  unsigned long tag;
+  if ((e == 0) || (e->entry_ptr == 0))
+    return 0;
+
+  tag = e->tag_name;
+
+  if (tag_is_base_type(tag))
+    {
+      ((base_type*)e->entry_ptr)->encoding = value;
+      return 1;
+    }
+  else
+    return 0;
+}
+
+char harvest_bit_size_value(dwarf_entry* e, unsigned long value)
+{
+  unsigned long tag;
+  if ((e == 0) || (e->entry_ptr == 0))
+    return 0;
+
+  tag = e->tag_name;
+
+  if (tag_is_base_type(tag))
+    {
+      ((base_type*)e->entry_ptr)->bit_size = value;
+      return 1;
+    }
+  else if (tag_is_member(tag))
+    {
+      ((member*)e->entry_ptr)->bit_size = value;
+      return 1;
+    }
+  else
+    return 0;
+}
+
+
+char harvest_bit_offset_value(dwarf_entry* e, unsigned long value)
+{
+  unsigned long tag;
+  if ((e == 0) || (e->entry_ptr == 0))
+    return 0;
+
+  tag = e->tag_name;
+
+  if (tag_is_base_type(tag))
+    {
+      ((base_type*)e->entry_ptr)->bit_offset = value;
+      return 1;
+    }
+  else if (tag_is_member(tag))
+    {
+      ((member*)e->entry_ptr)->bit_offset = value;
+      return 1;
+    }
+  else
+    return 0;
+}
+
+char harvest_const_value(dwarf_entry* e, unsigned long value)
+{
+  unsigned long tag;
+  if ((e == 0) || (e->entry_ptr == 0))
+    return 0;
+
+  tag = e->tag_name;
+
+  if (tag_is_enumerator(tag))
+    {
+      ((enumerator*)e->entry_ptr)->const_value = value;
+      return 1;
+    }
+  else
+    return 0;
+}
+
+char harvest_upper_bound(dwarf_entry* e, unsigned long value)
+{
+  unsigned long tag;
+  if ((e == 0) || (e->entry_ptr == 0))
+    return 0;
+
+  tag = e->tag_name;
+
+  if (tag==DW_TAG_subrange_type)
+    {
+      ((array_bound*)e->entry_ptr)->upperbound = value;
+      return 1;
+    }
+  else
+    return 0;
+}
+
+// REMEMBER to use strdup to make a COPY of the string
+// or else you will run into SERIOUS memory corruption
+// problems when readelf.c frees those strings from memory!!!
+char harvest_name(dwarf_entry* e, const char* str)
+{
+  unsigned long tag;
+  if ((e == 0) || (e->entry_ptr == 0))
+    return 0;
+
+  tag = e->tag_name;
+
+  if (tag_is_enumerator(tag))
+    {
+      ((enumerator*)e->entry_ptr)->name = strdup(str);
+      return 1;
+    }
+  else if (tag_is_collection_type(tag))
+    {
+      ((collection_type*)e->entry_ptr)->name = strdup(str);
+      return 1;
+    }
+  else if (tag_is_member(tag))
+    {
+      ((member*)e->entry_ptr)->name = strdup(str);
+      return 1;
+    }
+  else if (tag_is_function(tag))
+    {
+      ((function*)e->entry_ptr)->name = strdup(str);
+      return 1;
+    }
+  else if (tag_is_formal_parameter(tag))
+    {
+      ((formal_parameter*)e->entry_ptr)->name = strdup(str);
+      return 1;
+    }
+  else if (tag_is_compile_unit(tag))
+    {
+      ((compile_unit*)e->entry_ptr)->filename = strdup(str);
+      return 1;
+    }
+  else
+    return 0;
+}
+
+char harvest_comp_dir(dwarf_entry* e, const char* str)
+{
+  unsigned long tag;
+  if ((e == 0) || (e->entry_ptr == 0))
+    return 0;
+
+  tag = e->tag_name;
+
+  if (tag_is_compile_unit(tag))
+    {
+      ((compile_unit*)e->entry_ptr)->comp_dir = strdup(str);
+      return 1;
+    }
+  else
+    return 0;
+}
+
+char harvest_location(dwarf_entry* e, long value)
+{
+  unsigned long tag;
+  if ((e == 0) || (e->entry_ptr == 0))
+    return 0;
+
+  tag = e->tag_name;
+
+  if (tag_is_formal_parameter(tag))
+    {
+      ((formal_parameter*)e->entry_ptr)->location = value;
+      return 1;
+    }
+  else
+    return 0;
+}
+
+char harvest_data_member_location(dwarf_entry* e, long value)
+{
+  unsigned long tag;
+  if ((e == 0) || (e->entry_ptr == 0))
+    return 0;
+
+  tag = e->tag_name;
+
+  if (tag_is_member(tag))
+    {
+      ((member*)e->entry_ptr)->data_member_location = value;
+      return 1;
+    }
+  else
+    return 0;
+}
+
+char harvest_string(dwarf_entry* e, unsigned long attr, const char* str)
+{
+  if ((e == 0) || (e->entry_ptr == 0))
+    return 0;
+
+  if (attr == DW_AT_name)
+    return harvest_name(e, str);
+  else if (attr == DW_AT_comp_dir)
+    return harvest_comp_dir(e, str);
+  else
+    return 0;
+}
+
+char harvest_external_flag_value(dwarf_entry *e, unsigned long value) {
+  unsigned long tag;
+  if ((e == 0) || (e->entry_ptr == 0))
+    return 0;
+
+  tag = e->tag_name;
+
+  if (tag_is_function(tag))
+    {
+      ((function*)e->entry_ptr)->is_external = value;
+      return 1;
+    }
+  else
+    return 0;
+}
+
+char harvest_address_value(dwarf_entry* e, unsigned long attr,
+                           unsigned long value) {
+  unsigned long tag;
+  if ((e == 0) || (e->entry_ptr == 0))
+    return 0;
+
+  tag = e->tag_name;
+
+  if (tag_is_function(tag) && attr == DW_AT_low_pc)
+    {
+      ((function*)e->entry_ptr)->start_pc = value;
+      return 1;
+    }
+  else
+    return 0;
+}
+
+
+char harvest_ordinary_unsigned_value(dwarf_entry* e, unsigned long attr, unsigned long value)
+{
+  if ((e == 0) || (e->entry_ptr == 0))
+    return 0;
+
+  // Multiplex since
+  // DW_AT_byte_size, DW_AT_encoding, DW_AT_const_value,
+  // DW_AT_bit_size, DW_AT_bit_offset and DW_AT_external
+  // return ordinary unsigned data
+  switch(attr)
+    {
+    case DW_AT_byte_size:
+      return harvest_byte_size_value(e, value);
+    case DW_AT_encoding:
+      return harvest_encoding_value(e, value);
+    case DW_AT_const_value:
+      return harvest_const_value(e, value);
+    case DW_AT_upper_bound:
+      return harvest_upper_bound(e, value);
+    case DW_AT_bit_size:
+      return harvest_bit_size_value(e, value);
+    case DW_AT_bit_offset:
+      return harvest_bit_offset_value(e, value);
+    case DW_AT_external:
+      return harvest_external_flag_value(e, value);
+    default:
+      return 0;
+    }
+}
+
+/*
+Requires: dwarf_entry_array initialized
+Modifies:
+Returns: success
+Effects: Performs a binary search through dwarf_entry_array, looking for
+         the entry with the matching ID field (target_ID).
+         Stores the index of the matching entry in index_ptr
+*/
+char binary_search_dwarf_entry_array(unsigned long target_ID, unsigned long* index_ptr)
+{
+  unsigned long upper = dwarf_entry_array_size - 1;
+  unsigned long lower = 0;
+
+  //  printf("--target_ID: 0x%x, index_ptr: 0x%x, upper.ID: 0x%x, lower.ID: 0x%x\n",
+         //         target_ID,
+         //         index_ptr,
+         //         dwarf_entry_array[upper].ID,
+         //         dwarf_entry_array[lower].ID);
+
+  // First do boundary sanity check to save ourselves lots of useless work:
+  if ((target_ID > dwarf_entry_array[upper].ID) ||
+      (target_ID < dwarf_entry_array[lower].ID))
+    return 0;
+
+  while (upper > lower)
+    {
+      unsigned long mid = (upper + lower) / 2;
+      unsigned long cur_ID = dwarf_entry_array[mid].ID;
+
+      //      printf("**lower: %d, mid: %d, upper: %d, target_ID: 0x%x, cur_ID: 0x%x\n",
+      //             lower,
+      //             mid,
+      //             upper,
+      //             target_ID,
+      //             cur_ID);
+
+      // Special case - (upper == (lower + 1)) - that means only 2 entries left to check:
+      if (upper == (lower + 1))
+        {
+          if (target_ID == dwarf_entry_array[lower].ID)
+            {
+              *index_ptr = lower;
+              return 1;
+            }
+          else if (target_ID == dwarf_entry_array[upper].ID)
+            {
+              *index_ptr = upper;
+              return 1;
+            }
+          else
+            {
+              // YOU LOSE!  The target_ID is BETWEEN the lower and upper entries
+              return 0;
+            }
+        }
+      else if (target_ID == cur_ID) // Right on!
+        {
+          *index_ptr = mid;
+          return 1;
+        }
+      else if (target_ID < cur_ID)
+        {
+          upper = mid;
+        }
+      else if (target_ID > cur_ID)
+        {
+          lower = mid;
+        }
+    }
+
+  // Return 0 if no answer found
+  return 0;
+}
+
+/*
+Requires: dwarf_entry_array initialized
+Modifies: certain fields within certain entries within dwarf_entry_array
+          (modifier_type::target_ptr, function::return_type,
+           member::type_ptr, formal_parameter::type_ptr)
+Returns:
+Effects: Links every entry with a type_ID to the actual entry of that type
+         within dwarf_entry_array.  Sets the appropriate type_ptr pointers to point
+         to entries within dwarf_entry_array where that type resides
+         (relevant for modifier_type, member, function, and formal_parameter entries)
+*/
+void link_entries_to_type_entries()
+{
+  unsigned long idx;
+  dwarf_entry* cur_entry = 0;
+
+  for (idx = 0; idx < dwarf_entry_array_size; idx++)
+    {
+      unsigned long tag;
+      cur_entry = &dwarf_entry_array[idx];
+      tag = cur_entry->tag_name;
+
+      if (tag_is_modifier_type(tag))
+        {
+          char success = 0;
+          unsigned long target_index = 0;
+          modifier_type* modifier_ptr = (modifier_type*)(cur_entry->entry_ptr);
+          unsigned long target_ID = modifier_ptr->target_ID;
+
+          // Use a binary search to try to find the index of the entry in the
+          // array with the corresponding target_ID
+          success = binary_search_dwarf_entry_array(target_ID, &target_index);
+          if (success)
+            {
+              modifier_ptr->target_ptr=&dwarf_entry_array[target_index];
+            }
+         if (tag==DW_TAG_array_type) {
+           int currentlevel=cur_entry->level;
+           dwarf_entry* tmp_entry = cur_entry+1;
+           int dist_to_end=dwarf_entry_array_size-idx;
+           int member_count=0;
+           while ((member_count < dist_to_end) // put this first! short-circuit eval.
+                  && tmp_entry->level> currentlevel)
+             {
+               if (tmp_entry->tag_name==DW_TAG_subrange_type&&(tmp_entry->level==(currentlevel+1)))
+                 member_count++;
+               tmp_entry++;
+             }
+           modifier_ptr->array_ptr=(dwarf_entry**)calloc(1,member_count*sizeof(dwarf_entry*));
+           modifier_ptr->num_array=member_count;
+           member_count=0;
+           tmp_entry=cur_entry+1;
+           while ((member_count < dist_to_end) // put this first! short-circuit eval.
+                  && tmp_entry->level> currentlevel)
+             {
+               if (tmp_entry->tag_name==DW_TAG_subrange_type&&(tmp_entry->level==(currentlevel+1)))
+                 modifier_ptr->array_ptr[member_count++]=tmp_entry;
+               tmp_entry++;
+             }
+         }
+        }
+      else if (tag==DW_TAG_subrange_type) {
+          char success = 0;
+          unsigned long target_index = 0;
+          array_bound* bound_ptr = (array_bound*)(cur_entry->entry_ptr);
+          unsigned long target_ID = bound_ptr->target_ID;
+
+          // Use a binary search to try to find the index of the entry in the
+          // array with the corresponding target_ID
+          success = binary_search_dwarf_entry_array(target_ID, &target_index);
+          if (success)
+            {
+              bound_ptr->target_ptr=&dwarf_entry_array[target_index];
+            }
+      }
+      else if (tag_is_function(tag))
+        {
+          char success = 0;
+          unsigned long target_index = 0;
+          function* function_ptr = (function*)(cur_entry->entry_ptr);
+          unsigned long target_ID = function_ptr->return_type_ID;
+
+          // Use a binary search to try to find the index of the entry in the
+          // array with the corresponding target_ID
+          success = binary_search_dwarf_entry_array(target_ID, &target_index);
+          if (success)
+            {
+              function_ptr->return_type=&dwarf_entry_array[target_index];
+            }
+        }
+      else if (tag_is_function_type(tag))
+        {
+          char success = 0;
+          unsigned long target_index = 0;
+          function_type *function_ptr
+            = (function_type *)(cur_entry->entry_ptr);
+          unsigned long target_ID = function_ptr->return_type_ID;
+
+          // Use a binary search to try to find the index of the entry in the
+          // array with the corresponding target_ID
+          success = binary_search_dwarf_entry_array(target_ID, &target_index);
+          if (success)
+            {
+              function_ptr->return_type=&dwarf_entry_array[target_index];
+            }
+        }
+      else if (tag_is_member(tag))
+        {
+          char success = 0;
+          unsigned long target_index = 0;
+          member* member_ptr = (member*)(cur_entry->entry_ptr);
+          unsigned long target_ID = member_ptr->type_ID;
+
+          // Use a binary search to try to find the index of the entry in the
+          // array with the corresponding target_ID
+          success = binary_search_dwarf_entry_array(target_ID, &target_index);
+          if (success)
+            {
+              member_ptr->type_ptr=&dwarf_entry_array[target_index];
+            }
+        }
+      else if (tag_is_formal_parameter(tag))
+        {
+          char success = 0;
+          unsigned long target_index = 0;
+          formal_parameter* formal_param_ptr = (formal_parameter*)(cur_entry->entry_ptr);
+          unsigned long target_ID = formal_param_ptr->type_ID;
+
+          // Use a binary search to try to find the index of the entry in the
+          // array with the corresponding target_ID
+          success = binary_search_dwarf_entry_array(target_ID, &target_index);
+          if (success)
+            {
+              formal_param_ptr->type_ptr=&dwarf_entry_array[target_index];
+            }
+        }
+    }
+}
+
+/*
+Requires: dist_to_end indicates distance from e until end of dwarf_entry_array,
+          e points to an element of dwarf_entry_array
+Modifies: e->num_members, e->members
+Returns:
+Effects: Links the collection entry to its members, which are located
+         adjacent to it in the dwarf_entry array, making sure not to
+         accidentally segfault by indexing out of bounds
+         (indicated by dist_to_end param
+          which indicates distance until the end of the array)
+*/
+void link_collection_to_members(dwarf_entry* e, unsigned long dist_to_end)
+{
+  // 1. Figure out what kind of collection it is (struct, union, enumeration)
+  // 2. Traverse through subsequent entries, checking if the type_ID
+  //    is the appropriate member type for that collection
+  // 3. Stop either when you hit a type_ID that is not a member OR
+  //    when you are about to run out of array bounds
+  // 4. Store the subsequent array entry (e + 1) as pointer to first member
+  //    (as long as its not out of bounds) and store the number of entries
+  //    you traversed as the number of members
+
+  unsigned long member_count = 0;
+  unsigned int currentlevel=e->level;
+  dwarf_entry* cur_entry = e;
+  collection_type* collection_ptr = (collection_type*)(e->entry_ptr);
+
+  // If you are at the end of the array, you're screwed anyways
+  if(dist_to_end == 0)
+    return;
+
+  switch (e->tag_name)
+    {
+      // enumerations expect DW_TAG_enumerator as members
+    case DW_TAG_enumeration_type:
+      cur_entry++; // Move to the next entry - safe since dist_to_end > 0 by this point
+      while ((member_count < dist_to_end) // put this first! short-circuit eval.
+             && cur_entry->level> currentlevel)
+        {
+         if (cur_entry->tag_name==DW_TAG_enumerator&&(cur_entry->level==(currentlevel+1)))
+           member_count++;
+          cur_entry++;
+        }
+      break;
+      // structs and unions expect DW_TAG_member as members
+    case DW_TAG_structure_type:
+    case DW_TAG_union_type:
+      cur_entry++; // Move to the next entry - safe since dist_to_end > 0 by this point
+      while ((member_count < dist_to_end) // put this first! short-circuit eval.
+             && cur_entry->level>currentlevel)
+        {
+         if (cur_entry->tag_name==DW_TAG_member&&cur_entry->level==(currentlevel+1))
+           member_count++;
+          cur_entry++;
+        }
+      break;
+    default:
+      return;
+    }
+
+  collection_ptr->num_members = member_count;
+  collection_ptr->members = (dwarf_entry **)calloc(1,member_count*sizeof(dwarf_entry *));
+
+  cur_entry = e;
+  member_count=0;
+  switch (e->tag_name)
+    {
+      // enumerations expect DW_TAG_enumerator as members
+    case DW_TAG_enumeration_type:
+      cur_entry++; // Move to the next entry - safe since dist_to_end > 0 by this point
+      while ((member_count < dist_to_end) // put this first! short-circuit eval.
+             && cur_entry->level> currentlevel)
+        {
+         if (cur_entry->tag_name==DW_TAG_enumerator&&(cur_entry->level==(currentlevel+1)))
+           collection_ptr->members[member_count++]=cur_entry;
+          cur_entry++;
+        }
+      break;
+      // structs and unions expect DW_TAG_member as members
+    case DW_TAG_structure_type:
+    case DW_TAG_union_type:
+      cur_entry++; // Move to the next entry - safe since dist_to_end > 0 by this point
+      while ((member_count < dist_to_end) // put this first! short-circuit eval.
+             && cur_entry->level>currentlevel)
+        {
+         if (cur_entry->tag_name==DW_TAG_member&&cur_entry->level==(currentlevel+1))
+           collection_ptr->members[member_count++]=cur_entry;
+          cur_entry++;
+        }
+      break;
+    default:
+      return;
+    }
+}
+
+// Same as above except linking functions with formal parameters
+void link_function_to_params(dwarf_entry* e, unsigned long dist_to_end)
+{
+  unsigned long param_count = 0;
+  dwarf_entry* cur_entry = e;
+  function* function_ptr = (function*)(e->entry_ptr);
+
+  // If you are at the end of the array, you're screwed anyways
+  if(dist_to_end == 0)
+    return;
+
+  cur_entry++; // Move to the next entry - safe since dist_to_end > 0 by this point
+  // functions expect DW_TAG_formal_parameter as parameters
+  while ((param_count < dist_to_end) // important that this is first! short-circuit eval.
+         && cur_entry->tag_name == DW_TAG_formal_parameter)
+    {
+      param_count++;
+      cur_entry++;
+    }
+
+  function_ptr->num_formal_params = param_count;
+  function_ptr->params = (e + 1);
+}
+
+/*
+Requires: dwarf_entry_array is initialized
+Modifies: ((function*)cur_entry->entry_ptr)->filename for function entries
+Returns:
+Effects: Initialize the filename field of each function entry
+         by linearly traversing dwarf_entry_array and noting that every compile_unit
+         entry describes a file and all functions to the right of that entry
+         (but to the left of the next entry) belong to that file
+         e.g. [compile_unit foo.c][...][func1][...][func2][...][compile_unit bar.c][func3]
+         func1 and func2 belong to foo.c and func3 belongs to bar.c
+*/
+void initialize_function_filenames()
+{
+  unsigned long idx;
+  char* cur_file = 0;
+  dwarf_entry* cur_entry = 0;
+
+  for (idx = 0; idx < dwarf_entry_array_size; idx++)
+    {
+      cur_entry = &dwarf_entry_array[idx];
+
+      if (tag_is_compile_unit(cur_entry->tag_name))
+        cur_file = ((compile_unit*)cur_entry->entry_ptr)->filename;
+      else if (tag_is_function(cur_entry->tag_name))
+        ((function*)cur_entry->entry_ptr)->filename = cur_file;
+    }
+}
+
+/*
+Requires: dwarf_entry_array is initialized
+Modifies: function and collection entries within dwarf_entry_array
+Returns:
+Effects: Links function and collections entries to their respective members
+         e.g. functions need to have a list of their formal parameters
+         while structs, unions, and enumeration types need to have lists of members
+         THIS ALGORITHM EXPLOITS THE FACT THAT MEMBERS/PARAMETERS ARE LISTED
+         RIGHT AFTER THE RESPECTIVE FUNCTION OR STRUCT
+         e.g. [function][param1][param2][param3][something_else]
+*/
+void link_array_entries_to_members()
+{
+  unsigned long idx;
+  dwarf_entry* cur_entry = 0;
+
+  // Linearly traverse the array and pick off function or collections
+  // (struct, union, enumeration) entries to link to members:
+  for (idx = 0; idx < dwarf_entry_array_size; idx++)
+    {
+      cur_entry = &dwarf_entry_array[idx];
+      if (tag_is_collection_type(cur_entry->tag_name))
+        link_collection_to_members(cur_entry, dwarf_entry_array_size - idx - 1);
+      else if (tag_is_function(cur_entry->tag_name))
+        link_function_to_params(cur_entry, dwarf_entry_array_size - idx - 1);
+    }
+}
+
+// Prints the contents of the entry depending on its type
+void print_dwarf_entry(dwarf_entry* e)
+{
+  if (e == 0)
+    {
+      printf("ERROR! Pointer e is null in print_dwarf_entry\n");
+      return;
+    }
+
+  printf("ID:0x%lx, TAG:%s\n", e->ID, get_TAG_name(e->tag_name));
+
+  switch(e->tag_name)
+    {
+    case DW_TAG_subprogram:
+      {
+        function* function_ptr = (function*)(e->entry_ptr);
+        printf("  Name: %s, Filename: %s, Return Type ID (addr): 0x%lx (%p), Num. params: %ld, 1st param addr: %p\n",
+               function_ptr->name,
+               function_ptr->filename,
+               function_ptr->return_type_ID,
+               function_ptr->return_type,
+               function_ptr->num_formal_params,
+               function_ptr->params);
+        break;
+      }
+    case DW_TAG_formal_parameter:
+      {
+        formal_parameter* formal_param_ptr = (formal_parameter*)(e->entry_ptr);
+        printf("  Name: %s, Type ID (addr): 0x%lx (%p), Location: %ld\n",
+               formal_param_ptr->name,
+               formal_param_ptr->type_ID,
+               formal_param_ptr->type_ptr,
+               formal_param_ptr->location);
+        break;
+      }
+    case DW_TAG_member:
+      {
+        member* member_ptr = (member*)(e->entry_ptr);
+        printf("  Name: %s, Type ID (addr): 0x%lx (%p), Data member location: %ld, Byte size: %ld, Bit offset: %ld, Bit size: %ld\n",
+               member_ptr->name,
+               member_ptr->type_ID,
+               member_ptr->type_ptr,
+               member_ptr->data_member_location,
+               member_ptr->byte_size,
+               member_ptr->bit_offset,
+               member_ptr->bit_size);
+        break;
+      }
+    case DW_TAG_enumerator:
+      {
+        enumerator* enumerator_ptr = (enumerator*)(e->entry_ptr);
+        printf("  Name: %s, Const value: %ld\n",
+               enumerator_ptr->name,
+               enumerator_ptr->const_value);
+        break;
+      }
+
+    case DW_TAG_structure_type:
+    case DW_TAG_union_type:
+    case DW_TAG_enumeration_type:
+      {
+        collection_type* collection_ptr = (collection_type*)(e->entry_ptr);
+        printf("  Name: %s, Byte size: %ld, Num. members: %ld, 1st member addr: %p\n",
+               collection_ptr->name,
+               collection_ptr->byte_size,
+               collection_ptr->num_members,
+               collection_ptr->members);
+        break;
+      }
+
+    case DW_TAG_base_type:
+      {
+        base_type* base_ptr = (base_type*)(e->entry_ptr);
+        printf("  Byte size: %ld, Encoding: %ld ",
+               base_ptr->byte_size,
+               base_ptr->encoding);
+
+        // More detailed encoding information
+        switch (base_ptr->encoding)
+          {
+          case DW_ATE_void:             printf ("(void)"); break;
+          case DW_ATE_address:         printf ("(machine address)"); break;
+          case DW_ATE_boolean:         printf ("(boolean)"); break;
+          case DW_ATE_complex_float:   printf ("(complex float)"); break;
+          case DW_ATE_float:           printf ("(float)"); break;
+          case DW_ATE_signed:          printf ("(signed)"); break;
+          case DW_ATE_signed_char:     printf ("(signed char)"); break;
+          case DW_ATE_unsigned:                printf ("(unsigned)"); break;
+          case DW_ATE_unsigned_char:   printf ("(unsigned char)"); break;
+            /* DWARF 2.1 value.  */
+          case DW_ATE_imaginary_float: printf ("(imaginary float)"); break;
+          default:
+            if (base_ptr->encoding >= DW_ATE_lo_user
+                && base_ptr->encoding <= DW_ATE_hi_user)
+              {
+                printf ("(user defined type)");
+              }
+            else
+              {
+                printf ("(unknown type)");
+              }
+            break;
+          }
+
+        printf(", Bit size: %ld, Bit offset: %ld\n",
+               base_ptr->bit_size,
+               base_ptr->bit_offset);
+
+        break;
+      }
+    case DW_TAG_const_type:
+    case DW_TAG_pointer_type:
+    case DW_TAG_array_type:
+    case DW_TAG_volatile_type:
+      {
+        modifier_type* modifier_ptr = (modifier_type*)(e->entry_ptr);
+        printf("  Target ID (addr): 0x%lx (%p)\n",
+               modifier_ptr->target_ID,
+               modifier_ptr->target_ptr);
+        break;
+      }
+
+    case DW_TAG_compile_unit:
+      {
+        compile_unit* compile_ptr = (compile_unit*)(e->entry_ptr);
+        printf("  Filename: %s, Compile dir: %s\n",
+               compile_ptr->filename,
+               compile_ptr->comp_dir);
+      }
+
+    case DW_TAG_subroutine_type:
+      {
+        function_type * func_type = (function_type *)(e->entry_ptr);
+        printf("  Return type ID (addr): 0x%lx (%p)\n",
+               func_type->return_type_ID, func_type->return_type);
+      }
+
+    default:
+      return;
+    }
+}
+
+/*
+Requires:
+Modifies: dwarf_entry_array (initializes and blanks all entries to zero)
+Returns:
+Effects: Initializes sets up dwarf_entry_array to hold num_entries components
+*/
+void initialize_dwarf_entry_array(unsigned long num_entries)
+{
+  // use calloc to blank everything upon initialization
+  dwarf_entry_array = calloc(num_entries, sizeof *dwarf_entry_array);
+}
+
+/*
+Requires: dwarf_entry_array is initialized
+Modifies: dwarf_entry_array (free and set to 0)
+Returns:
+Effects: Destroys dwarf_entry_array and all entry_ptr fields of all entries
+*/
+void destroy_dwarf_entry_array()
+{
+  // Traverse the array and free the entry_ptr of all entries within array
+
+  unsigned long i;
+  for (i = 0; i < dwarf_entry_array_size; i++)
+    {
+      free(dwarf_entry_array[i].entry_ptr);
+    }
+
+  // Free the array itself
+  free(dwarf_entry_array);
+}
+
+void print_dwarf_entry_array()
+{
+  unsigned long i;
+  printf("--- BEGIN DWARF ENTRY ARRAY - size: %ld\n", dwarf_entry_array_size);
+  for (i = 0; i < dwarf_entry_array_size; i++)
+    {
+      printf("array[%ld] (%p): ", i, dwarf_entry_array + i);
+      print_dwarf_entry(&dwarf_entry_array[i]);
+    }
+  printf("--- END DWARF ENTRY ARRAY\n");
+}
+
+/*
+Requires: e is initialized and has a e->tag_name
+Modifies: e->entry_ptr (initializes and set to 0)
+Returns:
+Effects: Initialize the value of e->entry_ptr to the appropriate sub-type
+         based on the value of tag_name
+         If tag_name is 0, then don't do anything
+*/
+void initialize_dwarf_entry_ptr(dwarf_entry* e)
+{
+  if (e->tag_name)
+    {
+      if (tag_is_base_type(e->tag_name))
+        {
+          e->entry_ptr = calloc(1, sizeof(base_type));
+        }
+      else if (e->tag_name==DW_TAG_subrange_type) {
+       e->entry_ptr=calloc(1,sizeof(array_bound));
+      }
+      else if (tag_is_modifier_type(e->tag_name))
+        {
+          e->entry_ptr = calloc(1, sizeof(modifier_type));
+        }
+      else if (tag_is_collection_type(e->tag_name))
+        {
+          e->entry_ptr = calloc(1, sizeof(collection_type));
+        }
+      else if (tag_is_member(e->tag_name))
+        {
+          e->entry_ptr = calloc(1, sizeof(member));
+        }
+      else if (tag_is_enumerator(e->tag_name))
+        {
+          e->entry_ptr = calloc(1, sizeof(enumerator));
+        }
+      else if (tag_is_function(e->tag_name))
+        {
+          e->entry_ptr = calloc(1, sizeof(function));
+        }
+      else if (tag_is_formal_parameter(e->tag_name))
+        {
+          e->entry_ptr = calloc(1, sizeof(formal_parameter));
+        }
+      else if (tag_is_compile_unit(e->tag_name))
+        {
+          e->entry_ptr = calloc(1, sizeof(compile_unit));
+        }
+      else if (tag_is_function_type(e->tag_name))
+        {
+          e->entry_ptr = calloc(1, sizeof(function_type));
+        }
+    }
+}
+
+// Now that dwarf_entry_array is initialized with values, we must link
+// the entries together in a coherent manner
+void finish_dwarf_entry_array_init(void)
+{
+  // These must be done in this order or else things will go screwy!!!
+  link_array_entries_to_members();
+  initialize_function_filenames();
+  link_entries_to_type_entries();
+}
diff --git a/Repair/RepairCompiler/structextract/typedata.h b/Repair/RepairCompiler/structextract/typedata.h
new file mode 100755 (executable)
index 0000000..053c549
--- /dev/null
@@ -0,0 +1,208 @@
+/*
+   This file is part of Kvasir, a Valgrind skin that implements the
+   C language front-end for the Daikon Invariant Detection System
+
+   Copyright (C) 2004 Philip Guo, MIT CSAIL Program Analysis Group
+
+   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.
+*/
+
+/* typedata.h:
+   Everything here attempts to extract the information directly
+   from the DWARF2 debugging information embedded within an ELF
+   executable, piggy-backing off of readelf.c code. These data
+   structures mimic the types of DWARF2 entries that we are interested
+   in tracking.
+*/
+
+#ifndef TYPEDATA_H
+#define TYPEDATA_H
+
+// Type information data structures
+
+// Contains one entry that holds data for one of many possible types
+// depending on tag_name
+typedef struct
+{
+  unsigned long ID; // Unique ID for each entry
+  unsigned long tag_name; // DW_TAG_____ for the type of this entry
+  void* entry_ptr; // Cast this pointer depending on value of tag_name
+  unsigned int level;
+} dwarf_entry;
+
+// Entries for individual types
+
+typedef struct
+{
+  unsigned long byte_size; // DW_AT_byte_size
+  unsigned long encoding;
+
+  //  char is_bit_field; // 1 = bit field
+  // Only relevant for bit fields
+  unsigned long bit_size;
+  unsigned long bit_offset;
+} base_type; // DW_TAG_base_type
+
+// COP-OUT!!! Treat array_type JUST LIKE pointer_type for now
+// so we don't keep track of the array size.  We only care about the
+// FIRST ELEMENT of the array since we just treat all pointers as
+// arrays of size 1 -
+// I will add full support for arrays later!!! //PG
+// modifier_type = {const_type, pointer_type, array_type, volatile_type}
+typedef struct
+{
+  unsigned long target_ID; // ID of the entry that contains the type that this modifies
+  dwarf_entry* target_ptr; // Type that this entry modifies (DW_AT_type)
+  int num_array;
+  dwarf_entry** array_ptr;
+} modifier_type;
+
+typedef struct
+{ 
+  unsigned long target_ID; // ID of the entry that contains the type that this modifies
+  unsigned long upperbound;
+  dwarf_entry* target_ptr; // Type that this entry modifies (DW_AT_type)
+} array_bound;
+
+// collection_type = {structure_type, union_type, enumeration_type}
+typedef struct
+{
+  char* name;
+  unsigned long byte_size;
+  unsigned long num_members;
+  dwarf_entry** members; // Array of size num_members, type = {member, enumerator}
+} collection_type;
+
+// struct or union member
+typedef struct
+{
+  char* name;
+  unsigned long type_ID;
+  dwarf_entry* type_ptr;
+  long data_member_location; // Addr offset relative to struct head
+                             // This will be 0 for a union
+                             // This is stored as:
+                             // (DW_OP_plus_uconst: x)
+                             // where x is the location relative to struct head
+  //  char is_bit_field; // 1 = bit field
+  // Only relevant for bit fields
+  unsigned long byte_size;
+  unsigned long bit_offset;
+  unsigned long bit_size;
+} member;
+
+// enumeration member
+typedef struct
+{
+  char* name;
+  long const_value; // Enumeration value (SIGNED!)
+} enumerator;
+
+// FUNCTION!!!
+typedef struct
+{
+  char* name;
+  char* filename; // The file name relative to the compilation directory
+  unsigned long return_type_ID;
+  dwarf_entry* return_type;
+  unsigned long num_formal_params;
+  dwarf_entry* params; // Array of size num_formal_params, type = {formal_parameter}
+  int is_external; /* Is it extern? If so, probably want to skip it */
+  unsigned long start_pc; /* Location of the function in memory */
+} function;
+
+/* This is for abstract function types, as might be used in declaring
+   a parameter as taking a function pointer. At least for the moment, we
+   won't bother about the parameters. */
+typedef struct {
+  unsigned long return_type_ID;
+  dwarf_entry* return_type;
+} function_type;
+
+// function formal parameter
+typedef struct
+{
+  char* name;
+  unsigned long type_ID;
+  dwarf_entry* type_ptr;
+  long location; // Offset from function base (this is SIGNED!)
+                 // This is stored as: (DW_OP_fbreg: x),
+                 // where x is location offset
+} formal_parameter;
+
+// compile_unit - only used to figure out filename and compilation directory
+// We assume that every function belongs to the file specified
+// by the nearest compile_unit entry (to its left) in dwarf_entry_array
+typedef struct
+{
+  char* filename;
+  char* comp_dir;
+} compile_unit;
+
+// Globals
+
+extern dwarf_entry* dwarf_entry_array;
+extern unsigned long dwarf_entry_array_size;
+
+// Function declarations
+
+// From readelf.c
+char *get_TAG_name(unsigned long tag);
+int process_elf_binary_data(char* filename);
+
+// From typedata.c
+char tag_is_relevant_entry(unsigned long tag);
+char tag_is_modifier_type(unsigned long tag);
+char tag_is_collection_type(unsigned long tag);
+char tag_is_base_type(unsigned long tag);
+char tag_is_member(unsigned long tag);
+char tag_is_enumerator(unsigned long tag);
+char tag_is_function(unsigned long tag);
+char tag_is_formal_parameter(unsigned long tag);
+char tag_is_compile_unit(unsigned long tag);
+char tag_is_function_type(unsigned long tag);
+char entry_is_listening_for_attribute(dwarf_entry* e, unsigned long attr);
+
+char harvest_type_value(dwarf_entry* e, unsigned long value);
+char harvest_byte_size_value(dwarf_entry* e, unsigned long value);
+char harvest_encoding_value(dwarf_entry* e, unsigned long value);
+char harvest_bit_size_value(dwarf_entry* e, unsigned long value);
+char harvest_bit_offset_value(dwarf_entry* e, unsigned long value);
+char harvest_const_value(dwarf_entry* e, unsigned long value);
+char harvest_name(dwarf_entry* e, const char* str);
+char harvest_comp_dir(dwarf_entry* e, const char* str);
+char harvest_location(dwarf_entry* e, long value);
+char harvest_data_member_location(dwarf_entry* e, long value);
+char harvest_string(dwarf_entry* e, unsigned long attr, const char* str);
+char harvest_external_flag_value(dwarf_entry *e, unsigned long value);
+char harvest_address_value(dwarf_entry* e, unsigned long attr, unsigned long value);
+char harvest_ordinary_unsigned_value(dwarf_entry* e, unsigned long attr, unsigned long value);
+
+char binary_search_dwarf_entry_array(unsigned long target_ID, unsigned long* index_ptr);
+
+void link_entries_to_type_entries();
+void link_collection_to_members(dwarf_entry* e, unsigned long dist_to_end);
+void link_function_to_params(dwarf_entry* e, unsigned long dist_to_end);
+void initialize_function_filenames();
+void link_array_entries_to_members();
+void print_dwarf_entry(dwarf_entry* e);
+
+void initialize_dwarf_entry_array(unsigned long num_entries);
+void destroy_dwarf_entry_array(void);
+void print_dwarf_entry_array();
+void initialize_dwarf_entry_ptr(dwarf_entry* e);
+void finish_dwarf_entry_array_init(void);
+
+char tag_is_modifier_type(unsigned long tag);
+char tag_is_collection_type(unsigned long tag);
+char tag_is_base_type(unsigned long tag);
+char tag_is_member(unsigned long tag);
+char tag_is_enumerator(unsigned long tag);
+char tag_is_function(unsigned long tag);
+char tag_is_formal_parameter(unsigned long tag);
+
+
+#endif
diff --git a/Repair/RepairCompiler/structextract/unwind-ia64.c b/Repair/RepairCompiler/structextract/unwind-ia64.c
new file mode 100755 (executable)
index 0000000..803a5fa
--- /dev/null
@@ -0,0 +1,1129 @@
+/* unwind-ia64.c -- utility routines to dump IA-64 unwind info for readelf.
+   Copyright 2000, 2001 Free Software Foundation, Inc.
+       Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
+
+This file is part of GNU Binutils.
+
+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, 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+#include "unwind-ia64.h"
+#include <stdio.h>
+#include <string.h>
+
+#if __GNUC__ >= 2
+/* Define BFD64 here, even if our default architecture is 32 bit ELF
+   as this will allow us to read in and parse 64bit and 32bit ELF files.
+   Only do this if we belive that the compiler can support a 64 bit
+   data type.  For now we only rely on GCC being able to do this.  */
+#define BFD64
+#endif
+#include "bfd.h"
+
+static bfd_vma unw_rlen = 0;
+
+static void unw_print_brmask PARAMS ((char *, unsigned int));
+static void unw_print_grmask PARAMS ((char *, unsigned int));
+static void unw_print_frmask PARAMS ((char *, unsigned int));
+static void unw_print_abreg PARAMS ((char *, unsigned int));
+static void unw_print_xyreg PARAMS ((char *, unsigned int, unsigned int));
+
+static void
+unw_print_brmask (cp, mask)
+     char * cp;
+     unsigned int mask;
+{
+  int sep = 0;
+  int i;
+
+  for (i = 0; mask && (i < 5); ++i)
+    {
+      if (mask & 1)
+       {
+         if (sep)
+           *cp++ = ',';
+         *cp++ = 'b';
+         *cp++ = i + 1 + '0';
+         sep = 1;
+       }
+      mask >>= 1;
+    }
+  *cp = '\0';
+}
+
+static void
+unw_print_grmask (cp, mask)
+     char * cp;
+     unsigned int mask;
+{
+  int sep = 0;
+  int i;
+
+  for (i = 0; i < 4; ++i)
+    {
+      if (mask & 1)
+       {
+         if (sep)
+           *cp++ = ',';
+         *cp++ = 'r';
+         *cp++ = i + 4 + '0';
+         sep = 1;
+       }
+      mask >>= 1;
+    }
+  *cp = '\0';
+}
+
+static void
+unw_print_frmask (cp, mask)
+     char * cp;
+     unsigned int mask;
+{
+  int sep = 0;
+  int i;
+
+  for (i = 0; i < 20; ++i)
+    {
+      if (mask & 1)
+       {
+         if (sep)
+           *cp++ = ',';
+         *cp++ = 'f';
+         if (i < 4)
+           *cp++ = i + 2 + '0';
+         else
+           {
+             *cp++ = (i + 2) / 10 + 1 + '0';
+             *cp++ = (i + 2) % 10 + '0';
+           }
+         sep = 1;
+       }
+      mask >>= 1;
+    }
+  *cp = '\0';
+}
+
+static void
+unw_print_abreg (cp, abreg)
+     char * cp;
+     unsigned int abreg;
+{
+  static const char *special_reg[16] =
+  {
+    "pr", "psp", "@priunat", "rp", "ar.bsp", "ar.bspstore", "ar.rnat",
+    "ar.unat", "ar.fpsr", "ar.pfs", "ar.lc",
+    "Unknown11", "Unknown12", "Unknown13", "Unknown14", "Unknown15"
+  };
+
+  switch ((abreg >> 5) & 0x3)
+    {
+    case 0: /* gr */
+      sprintf (cp, "r%u", (abreg & 0x1f));
+      break;
+
+    case 1: /* fr */
+      sprintf (cp, "f%u", (abreg & 0x1f));
+      break;
+
+    case 2: /* br */
+      sprintf (cp, "b%u", (abreg & 0x1f));
+      break;
+
+    case 3: /* special */
+      strcpy (cp, special_reg[abreg & 0xf]);
+      break;
+    }
+}
+
+static void
+unw_print_xyreg (cp, x, ytreg)
+     char *        cp;
+     unsigned int x;
+     unsigned int ytreg;
+{
+  switch ((x << 1) | ((ytreg >> 7) & 1))
+    {
+    case 0: /* gr */
+      sprintf (cp, "r%u", (ytreg & 0x1f));
+      break;
+
+    case 1: /* fr */
+      sprintf (cp, "f%u", (ytreg & 0x1f));
+      break;
+
+    case 2: /* br */
+      sprintf (cp, "b%u", (ytreg & 0x1f));
+      break;
+    }
+}
+
+#define UNW_REG_BSP            "bsp"
+#define UNW_REG_BSPSTORE       "bspstore"
+#define UNW_REG_FPSR           "fpsr"
+#define UNW_REG_LC             "lc"
+#define UNW_REG_PFS            "pfs"
+#define UNW_REG_PR             "pr"
+#define UNW_REG_PSP            "psp"
+#define UNW_REG_RNAT           "rnat"
+#define UNW_REG_RP             "rp"
+#define UNW_REG_UNAT           "unat"
+
+typedef bfd_vma unw_word;
+
+#define UNW_DEC_BAD_CODE(code)                 \
+    printf ("Unknown code 0x%02x\n", code)
+
+#define UNW_DEC_PROLOGUE(fmt, body, rlen, arg)                                 \
+  do                                                                           \
+    {                                                                          \
+      unw_rlen = rlen;                                                         \
+      *(int *)arg = body;                                                      \
+      printf ("    %s:%s(rlen=%lu)\n",                                         \
+             fmt, body ? "body" : "prologue", (unsigned long) rlen);           \
+    }                                                                          \
+  while (0)
+
+#define UNW_DEC_PROLOGUE_GR(fmt, rlen, mask, grsave, arg)                      \
+  do                                                                           \
+    {                                                                          \
+      char regname[16], maskstr[64], *sep;                                     \
+                                                                               \
+      unw_rlen = rlen;                                                         \
+      *(int *)arg = 0;                                                         \
+                                                                               \
+      maskstr[0] = '\0';                                                       \
+      sep = "";                                                                        \
+      if (mask & 0x8)                                                          \
+       {                                                                       \
+         strcat (maskstr, "rp");                                               \
+         sep = ",";                                                            \
+       }                                                                       \
+      if (mask & 0x4)                                                          \
+       {                                                                       \
+         strcat (maskstr, sep);                                                \
+         strcat (maskstr, "ar.pfs");                                           \
+         sep = ",";                                                            \
+       }                                                                       \
+      if (mask & 0x2)                                                          \
+       {                                                                       \
+         strcat (maskstr, sep);                                                \
+         strcat (maskstr, "psp");                                              \
+         sep = ",";                                                            \
+       }                                                                       \
+      if (mask & 0x1)                                                          \
+       {                                                                       \
+         strcat (maskstr, sep);                                                \
+         strcat (maskstr, "pr");                                               \
+       }                                                                       \
+      sprintf (regname, "r%u", grsave);                                                \
+      printf ("    %s:prologue_gr(mask=[%s],grsave=%s,rlen=%lu)\n",            \
+             fmt, maskstr, regname, (unsigned long) rlen);                     \
+    }                                                                          \
+  while (0)
+
+#define UNW_DEC_FR_MEM(fmt, frmask, arg)                       \
+  do                                                           \
+    {                                                          \
+      char frstr[200];                                         \
+                                                               \
+      unw_print_frmask (frstr, frmask);                                \
+      printf ("\t%s:fr_mem(frmask=[%s])\n", fmt, frstr);       \
+    }                                                          \
+  while (0)
+
+#define UNW_DEC_GR_MEM(fmt, grmask, arg)                       \
+  do                                                           \
+    {                                                          \
+      char grstr[200];                                         \
+                                                               \
+      unw_print_grmask (grstr, grmask);                                \
+      printf ("\t%s:gr_mem(grmask=[%s])\n", fmt, grstr);       \
+    }                                                          \
+  while (0)
+
+#define UNW_DEC_FRGR_MEM(fmt, grmask, frmask, arg)                             \
+  do                                                                           \
+    {                                                                          \
+      char frstr[200], grstr[20];                                              \
+                                                                               \
+      unw_print_grmask (grstr, grmask);                                                \
+      unw_print_frmask (frstr, frmask);                                                \
+      printf ("\t%s:frgr_mem(grmask=[%s],frmask=[%s])\n", fmt, grstr, frstr);  \
+    }                                                                          \
+  while (0)
+
+#define UNW_DEC_BR_MEM(fmt, brmask, arg)                               \
+  do                                                                   \
+    {                                                                  \
+      char brstr[20];                                                  \
+                                                                       \
+      unw_print_brmask (brstr, brmask);                                        \
+      printf ("\t%s:br_mem(brmask=[%s])\n", fmt, brstr);               \
+    }                                                                  \
+  while (0)
+
+#define UNW_DEC_BR_GR(fmt, brmask, gr, arg)                            \
+  do                                                                   \
+    {                                                                  \
+      char brstr[20];                                                  \
+                                                                       \
+      unw_print_brmask (brstr, brmask);                                        \
+      printf ("\t%s:br_gr(brmask=[%s],gr=r%u)\n", fmt, brstr, gr);     \
+    }                                                                  \
+  while (0)
+
+#define UNW_DEC_REG_GR(fmt, src, dst, arg)             \
+  printf ("\t%s:%s_gr(reg=r%u)\n", fmt, src, dst)
+
+#define UNW_DEC_RP_BR(fmt, dst, arg)           \
+  printf ("\t%s:rp_br(reg=b%u)\n", fmt, dst)
+
+#define UNW_DEC_REG_WHEN(fmt, reg, t, arg)                             \
+  printf ("\t%s:%s_when(t=%lu)\n", fmt, reg, (unsigned long) t)
+
+#define UNW_DEC_REG_SPREL(fmt, reg, spoff, arg)                \
+  printf ("\t%s:%s_sprel(spoff=0x%lx)\n",              \
+         fmt, reg, 4*(unsigned long)spoff)
+
+#define UNW_DEC_REG_PSPREL(fmt, reg, pspoff, arg)              \
+  printf ("\t%s:%s_psprel(pspoff=0x10-0x%lx)\n",               \
+         fmt, reg, 4*(unsigned long)pspoff)
+
+#define UNW_DEC_GR_GR(fmt, grmask, gr, arg)                            \
+  do                                                                   \
+    {                                                                  \
+      char grstr[20];                                                  \
+                                                                       \
+      unw_print_grmask (grstr, grmask);                                        \
+      printf ("\t%s:gr_gr(grmask=[%s],r%u)\n", fmt, grstr, gr);                \
+    }                                                                  \
+  while (0)
+
+#define UNW_DEC_ABI(fmt, abi, context, arg)                    \
+  do                                                           \
+    {                                                          \
+      static const char *abiname[] =                           \
+      {                                                                \
+       "@svr4", "@hpux", "@nt"                                 \
+      };                                                       \
+      char buf[20];                                            \
+      const char *abistr = buf;                                        \
+                                                               \
+      if (abi < 3)                                             \
+       abistr = abiname[abi];                                  \
+      else                                                     \
+       sprintf (buf, "0x%x", abi);                             \
+      printf ("\t%s:unwabi(abi=%s,context=0x%02x)\n",          \
+             fmt, abistr, context);                            \
+    }                                                          \
+  while (0)
+
+#define UNW_DEC_PRIUNAT_GR(fmt, r, arg)                \
+  printf ("\t%s:priunat_gr(reg=r%u)\n", fmt, r)
+
+#define UNW_DEC_PRIUNAT_WHEN_GR(fmt, t, arg)                           \
+  printf ("\t%s:priunat_when_gr(t=%lu)\n", fmt, (unsigned long) t)
+
+#define UNW_DEC_PRIUNAT_WHEN_MEM(fmt, t, arg)                          \
+  printf ("\t%s:priunat_when_mem(t=%lu)\n", fmt, (unsigned long) t)
+
+#define UNW_DEC_PRIUNAT_PSPREL(fmt, pspoff, arg)               \
+  printf ("\t%s:priunat_psprel(pspoff=0x10-0x%lx)\n",          \
+         fmt, 4*(unsigned long)pspoff)
+
+#define UNW_DEC_PRIUNAT_SPREL(fmt, spoff, arg)         \
+  printf ("\t%s:priunat_sprel(spoff=0x%lx)\n",         \
+         fmt, 4*(unsigned long)spoff)
+
+#define UNW_DEC_MEM_STACK_F(fmt, t, size, arg)         \
+  printf ("\t%s:mem_stack_f(t=%lu,size=%lu)\n",                \
+         fmt, (unsigned long) t, 16*(unsigned long)size)
+
+#define UNW_DEC_MEM_STACK_V(fmt, t, arg)                               \
+  printf ("\t%s:mem_stack_v(t=%lu)\n", fmt, (unsigned long) t)
+
+#define UNW_DEC_SPILL_BASE(fmt, pspoff, arg)                   \
+  printf ("\t%s:spill_base(pspoff=0x10-0x%lx)\n",              \
+         fmt, 4*(unsigned long)pspoff)
+
+#define UNW_DEC_SPILL_MASK(fmt, dp, arg)                                       \
+  do                                                                           \
+    {                                                                          \
+      static const char * spill_type = "-frb";                                 \
+      unsigned const char * imaskp = dp;                                       \
+      unsigned char mask = 0;                                                  \
+      bfd_vma insn = 0;                                                                \
+                                                                               \
+      printf ("\t%s:spill_mask(imask=[", fmt);                                 \
+      for (insn = 0; insn < unw_rlen; ++insn)                                  \
+       {                                                                       \
+         if ((insn % 4) == 0)                                                  \
+           mask = *imaskp++;                                                   \
+         if (insn > 0 && (insn % 3) == 0)                                      \
+           putchar (',');                                                      \
+         putchar (spill_type[(mask >> (2 * (3 - (insn & 0x3)))) & 0x3]);       \
+       }                                                                       \
+      printf ("])\n");                                                         \
+      dp = imaskp;                                                             \
+    }                                                                          \
+  while (0)
+
+#define UNW_DEC_SPILL_SPREL(fmt, t, abreg, spoff, arg)                         \
+  do                                                                           \
+    {                                                                          \
+      char regname[10];                                                                \
+                                                                               \
+      unw_print_abreg (regname, abreg);                                                \
+      printf ("\t%s:spill_sprel(reg=%s,t=%lu,spoff=0x%lx)\n",                  \
+             fmt, regname, (unsigned long) t, 4*(unsigned long)off);           \
+    }                                                                          \
+  while (0)
+
+#define UNW_DEC_SPILL_PSPREL(fmt, t, abreg, pspoff, arg)                       \
+  do                                                                           \
+    {                                                                          \
+      char regname[10];                                                                \
+                                                                               \
+      unw_print_abreg (regname, abreg);                                                \
+      printf ("\t%s:spill_psprel(reg=%s,t=%lu,pspoff=0x10-0x%lx)\n",           \
+             fmt, regname, (unsigned long) t, 4*(unsigned long)pspoff);        \
+    }                                                                          \
+  while (0)
+
+#define UNW_DEC_RESTORE(fmt, t, abreg, arg)                    \
+  do                                                           \
+    {                                                          \
+      char regname[10];                                                \
+                                                               \
+      unw_print_abreg (regname, abreg);                                \
+      printf ("\t%s:restore(t=%lu,reg=%s)\n",                  \
+             fmt, (unsigned long) t, regname);                 \
+    }                                                          \
+  while (0)
+
+#define UNW_DEC_SPILL_REG(fmt, t, abreg, x, ytreg, arg)                \
+  do                                                           \
+    {                                                          \
+      char abregname[10], tregname[10];                                \
+                                                               \
+      unw_print_abreg (abregname, abreg);                      \
+      unw_print_xyreg (tregname, x, ytreg);                    \
+      printf ("\t%s:spill_reg(t=%lu,reg=%s,treg=%s)\n",                \
+             fmt, (unsigned long) t, abregname, tregname);     \
+    }                                                          \
+  while (0)
+
+#define UNW_DEC_SPILL_SPREL_P(fmt, qp, t, abreg, spoff, arg)                       \
+  do                                                                               \
+    {                                                                              \
+      char regname[20];                                                                    \
+                                                                                   \
+      unw_print_abreg (regname, abreg);                                                    \
+      printf ("\t%s:spill_sprel_p(qp=p%u,t=%lu,reg=%s,spoff=0x%lx)\n",             \
+             fmt, qp, (unsigned long) t, regname, 4 * (unsigned long)spoff);       \
+    }                                                                              \
+  while (0)
+
+#define UNW_DEC_SPILL_PSPREL_P(fmt, qp, t, abreg, pspoff, arg)         \
+  do                                                                   \
+    {                                                                  \
+      char regname[20];                                                        \
+                                                                       \
+      unw_print_abreg (regname, abreg);                                        \
+      printf ("\t%s:spill_psprel_p(qp=p%u,t=%lu,reg=%s,pspoff=0x10-0x%lx)\n",\
+             fmt, qp, (unsigned long) t, regname, 4*(unsigned long)pspoff);\
+    }                                                                  \
+  while (0)
+
+#define UNW_DEC_RESTORE_P(fmt, qp, t, abreg, arg)                      \
+  do                                                                   \
+    {                                                                  \
+      char regname[20];                                                        \
+                                                                       \
+      unw_print_abreg (regname, abreg);                                        \
+      printf ("\t%s:restore_p(qp=p%u,t=%lu,reg=%s)\n",                 \
+             fmt, qp, (unsigned long) t, regname);                     \
+    }                                                                  \
+  while (0)
+
+#define UNW_DEC_SPILL_REG_P(fmt, qp, t, abreg, x, ytreg, arg)          \
+  do                                                                   \
+    {                                                                  \
+      char regname[20], tregname[20];                                  \
+                                                                       \
+      unw_print_abreg (regname, abreg);                                        \
+      unw_print_xyreg (tregname, x, ytreg);                            \
+      printf ("\t%s:spill_reg_p(qp=p%u,t=%lu,reg=%s,treg=%s)\n",       \
+             fmt, qp, (unsigned long) t, regname, tregname);           \
+    }                                                                  \
+  while (0)
+
+#define UNW_DEC_LABEL_STATE(fmt, label, arg)                           \
+  printf ("\t%s:label_state(label=%lu)\n", fmt, (unsigned long) label)
+
+#define UNW_DEC_COPY_STATE(fmt, label, arg)                            \
+  printf ("\t%s:copy_state(label=%lu)\n", fmt, (unsigned long) label)
+
+#define UNW_DEC_EPILOGUE(fmt, t, ecount, arg)          \
+  printf ("\t%s:epilogue(t=%lu,ecount=%lu)\n",         \
+         fmt, (unsigned long) t, (unsigned long) ecount)
+
+/*
+ * Generic IA-64 unwind info decoder.
+ *
+ * This file is used both by the Linux kernel and objdump.  Please
+ * keep the two copies of this file in sync (modulo differences in the
+ * prototypes...).
+ *
+ * You need to customize the decoder by defining the following
+ * macros/constants before including this file:
+ *
+ *  Types:
+ *     unw_word        Unsigned integer type with at least 64 bits
+ *
+ *  Register names:
+ *     UNW_REG_BSP
+ *     UNW_REG_BSPSTORE
+ *     UNW_REG_FPSR
+ *     UNW_REG_LC
+ *     UNW_REG_PFS
+ *     UNW_REG_PR
+ *     UNW_REG_RNAT
+ *     UNW_REG_PSP
+ *     UNW_REG_RP
+ *     UNW_REG_UNAT
+ *
+ *  Decoder action macros:
+ *     UNW_DEC_BAD_CODE(code)
+ *     UNW_DEC_ABI(fmt,abi,context,arg)
+ *     UNW_DEC_BR_GR(fmt,brmask,gr,arg)
+ *     UNW_DEC_BR_MEM(fmt,brmask,arg)
+ *     UNW_DEC_COPY_STATE(fmt,label,arg)
+ *     UNW_DEC_EPILOGUE(fmt,t,ecount,arg)
+ *     UNW_DEC_FRGR_MEM(fmt,grmask,frmask,arg)
+ *     UNW_DEC_FR_MEM(fmt,frmask,arg)
+ *     UNW_DEC_GR_GR(fmt,grmask,gr,arg)
+ *     UNW_DEC_GR_MEM(fmt,grmask,arg)
+ *     UNW_DEC_LABEL_STATE(fmt,label,arg)
+ *     UNW_DEC_MEM_STACK_F(fmt,t,size,arg)
+ *     UNW_DEC_MEM_STACK_V(fmt,t,arg)
+ *     UNW_DEC_PRIUNAT_GR(fmt,r,arg)
+ *     UNW_DEC_PRIUNAT_WHEN_GR(fmt,t,arg)
+ *     UNW_DEC_PRIUNAT_WHEN_MEM(fmt,t,arg)
+ *     UNW_DEC_PRIUNAT_WHEN_PSPREL(fmt,pspoff,arg)
+ *     UNW_DEC_PRIUNAT_WHEN_SPREL(fmt,spoff,arg)
+ *     UNW_DEC_PROLOGUE(fmt,body,rlen,arg)
+ *     UNW_DEC_PROLOGUE_GR(fmt,rlen,mask,grsave,arg)
+ *     UNW_DEC_REG_PSPREL(fmt,reg,pspoff,arg)
+ *     UNW_DEC_REG_REG(fmt,src,dst,arg)
+ *     UNW_DEC_REG_SPREL(fmt,reg,spoff,arg)
+ *     UNW_DEC_REG_WHEN(fmt,reg,t,arg)
+ *     UNW_DEC_RESTORE(fmt,t,abreg,arg)
+ *     UNW_DEC_RESTORE_P(fmt,qp,t,abreg,arg)
+ *     UNW_DEC_SPILL_BASE(fmt,pspoff,arg)
+ *     UNW_DEC_SPILL_MASK(fmt,imaskp,arg)
+ *     UNW_DEC_SPILL_PSPREL(fmt,t,abreg,pspoff,arg)
+ *     UNW_DEC_SPILL_PSPREL_P(fmt,qp,t,abreg,pspoff,arg)
+ *     UNW_DEC_SPILL_REG(fmt,t,abreg,x,ytreg,arg)
+ *     UNW_DEC_SPILL_REG_P(fmt,qp,t,abreg,x,ytreg,arg)
+ *     UNW_DEC_SPILL_SPREL(fmt,t,abreg,spoff,arg)
+ *     UNW_DEC_SPILL_SPREL_P(fmt,qp,t,abreg,pspoff,arg)
+ */
+
+static unw_word unw_decode_uleb128 PARAMS ((const unsigned char **));
+static const unsigned char *unw_decode_x1 PARAMS ((const unsigned char *,
+                                                  unsigned int, void *));
+static const unsigned char *unw_decode_x2 PARAMS ((const unsigned char *,
+                                                  unsigned int, void *));
+static const unsigned char *unw_decode_x3 PARAMS ((const unsigned char *,
+                                                  unsigned int, void *));
+static const unsigned char *unw_decode_x4 PARAMS ((const unsigned char *,
+                                                  unsigned int, void *));
+static const unsigned char *unw_decode_r1 PARAMS ((const unsigned char *,
+                                                  unsigned int, void *));
+static const unsigned char *unw_decode_r2 PARAMS ((const unsigned char *,
+                                                  unsigned int, void *));
+static const unsigned char *unw_decode_r3 PARAMS ((const unsigned char *,
+                                                  unsigned int, void *));
+static const unsigned char *unw_decode_p1 PARAMS ((const unsigned char *,
+                                                  unsigned int, void *));
+static const unsigned char *unw_decode_p2_p5 PARAMS ((const unsigned char *,
+                                                     unsigned int, void *));
+static const unsigned char *unw_decode_p6 PARAMS ((const unsigned char *,
+                                                  unsigned int, void *));
+static const unsigned char *unw_decode_p7_p10 PARAMS ((const unsigned char *,
+                                                      unsigned int, void *));
+static const unsigned char *unw_decode_b1 PARAMS ((const unsigned char *,
+                                                  unsigned int, void *));
+static const unsigned char *unw_decode_b2 PARAMS ((const unsigned char *,
+                                                  unsigned int, void *));
+static const unsigned char *unw_decode_b3_x4 PARAMS ((const unsigned char *,
+                                                     unsigned int, void *));
+
+static unw_word
+unw_decode_uleb128 (dpp)
+     const unsigned char **dpp;
+{
+  unsigned shift = 0;
+  unw_word byte, result = 0;
+  const unsigned char *bp = *dpp;
+
+  while (1)
+    {
+      byte = *bp++;
+      result |= (byte & 0x7f) << shift;
+
+      if ((byte & 0x80) == 0)
+       break;
+
+      shift += 7;
+    }
+
+  *dpp = bp;
+
+  return result;
+}
+
+static const unsigned char *
+unw_decode_x1 (dp, code, arg)
+     const unsigned char * dp;
+     unsigned int         code ATTRIBUTE_UNUSED;
+     void *                arg ATTRIBUTE_UNUSED;
+{
+  unsigned char byte1, abreg;
+  unw_word t, off;
+
+  byte1 = *dp++;
+  t = unw_decode_uleb128 (&dp);
+  off = unw_decode_uleb128 (&dp);
+  abreg = (byte1 & 0x7f);
+  if (byte1 & 0x80)
+    UNW_DEC_SPILL_SPREL ("X1", t, abreg, off, arg);
+  else
+    UNW_DEC_SPILL_PSPREL ("X1", t, abreg, off, arg);
+  return dp;
+}
+
+static const unsigned char *
+unw_decode_x2 (dp, code, arg)
+     const unsigned char * dp;
+     unsigned int         code ATTRIBUTE_UNUSED;
+     void *                arg ATTRIBUTE_UNUSED;
+{
+  unsigned char byte1, byte2, abreg, x, ytreg;
+  unw_word t;
+
+  byte1 = *dp++;
+  byte2 = *dp++;
+  t = unw_decode_uleb128 (&dp);
+  abreg = (byte1 & 0x7f);
+  ytreg = byte2;
+  x = (byte1 >> 7) & 1;
+  if ((byte1 & 0x80) == 0 && ytreg == 0)
+    UNW_DEC_RESTORE ("X2", t, abreg, arg);
+  else
+    UNW_DEC_SPILL_REG ("X2", t, abreg, x, ytreg, arg);
+  return dp;
+}
+
+static const unsigned char *
+unw_decode_x3 (dp, code, arg)
+     const unsigned char * dp;
+     unsigned int         code ATTRIBUTE_UNUSED;
+     void *                arg ATTRIBUTE_UNUSED;
+{
+  unsigned char byte1, byte2, abreg, qp;
+  unw_word t, off;
+
+  byte1 = *dp++;
+  byte2 = *dp++;
+  t = unw_decode_uleb128 (&dp);
+  off = unw_decode_uleb128 (&dp);
+
+  qp = (byte1 & 0x3f);
+  abreg = (byte2 & 0x7f);
+
+  if (byte1 & 0x80)
+    UNW_DEC_SPILL_SPREL_P ("X3", qp, t, abreg, off, arg);
+  else
+    UNW_DEC_SPILL_PSPREL_P ("X3", qp, t, abreg, off, arg);
+  return dp;
+}
+
+static const unsigned char *
+unw_decode_x4 (dp, code, arg)
+     const unsigned char * dp;
+     unsigned int         code ATTRIBUTE_UNUSED;
+     void *                arg ATTRIBUTE_UNUSED;
+{
+  unsigned char byte1, byte2, byte3, qp, abreg, x, ytreg;
+  unw_word t;
+
+  byte1 = *dp++;
+  byte2 = *dp++;
+  byte3 = *dp++;
+  t = unw_decode_uleb128 (&dp);
+
+  qp = (byte1 & 0x3f);
+  abreg = (byte2 & 0x7f);
+  x = (byte2 >> 7) & 1;
+  ytreg = byte3;
+
+  if ((byte2 & 0x80) == 0 && byte3 == 0)
+    UNW_DEC_RESTORE_P ("X4", qp, t, abreg, arg);
+  else
+    UNW_DEC_SPILL_REG_P ("X4", qp, t, abreg, x, ytreg, arg);
+  return dp;
+}
+
+static const unsigned char *
+unw_decode_r1 (dp, code, arg)
+     const unsigned char *dp;
+     unsigned int code;
+     void *arg;
+{
+  int body = (code & 0x20) != 0;
+  unw_word rlen;
+
+  rlen = (code & 0x1f);
+  UNW_DEC_PROLOGUE ("R1", body, rlen, arg);
+  return dp;
+}
+
+static const unsigned char *
+unw_decode_r2 (dp, code, arg)
+     const unsigned char *dp;
+     unsigned int code;
+     void *arg;
+{
+  unsigned char byte1, mask, grsave;
+  unw_word rlen;
+
+  byte1 = *dp++;
+
+  mask = ((code & 0x7) << 1) | ((byte1 >> 7) & 1);
+  grsave = (byte1 & 0x7f);
+  rlen = unw_decode_uleb128 (& dp);
+  UNW_DEC_PROLOGUE_GR ("R2", rlen, mask, grsave, arg);
+  return dp;
+}
+
+static const unsigned char *
+unw_decode_r3 (dp, code, arg)
+     const unsigned char *dp;
+     unsigned int code;
+     void *arg;
+{
+  unw_word rlen;
+
+  rlen = unw_decode_uleb128 (& dp);
+  UNW_DEC_PROLOGUE ("R3", ((code & 0x3) == 1), rlen, arg);
+  return dp;
+}
+
+static const unsigned char *
+unw_decode_p1 (dp, code, arg)
+     const unsigned char * dp;
+     unsigned int         code;
+     void *                arg ATTRIBUTE_UNUSED;
+{
+  unsigned char brmask = (code & 0x1f);
+
+  UNW_DEC_BR_MEM ("P1", brmask, arg);
+  return dp;
+}
+
+static const unsigned char *
+unw_decode_p2_p5 (dp, code, arg)
+     const unsigned char * dp;
+     unsigned int         code;
+     void *                arg ATTRIBUTE_UNUSED;
+{
+  if ((code & 0x10) == 0)
+    {
+      unsigned char byte1 = *dp++;
+
+      UNW_DEC_BR_GR ("P2", ((code & 0xf) << 1) | ((byte1 >> 7) & 1),
+                    (byte1 & 0x7f), arg);
+    }
+  else if ((code & 0x08) == 0)
+    {
+      unsigned char byte1 = *dp++, r, dst;
+
+      r = ((code & 0x7) << 1) | ((byte1 >> 7) & 1);
+      dst = (byte1 & 0x7f);
+      switch (r)
+       {
+       case 0:
+         UNW_DEC_REG_GR ("P3", UNW_REG_PSP, dst, arg);
+         break;
+       case 1:
+         UNW_DEC_REG_GR ("P3", UNW_REG_RP, dst, arg);
+         break;
+       case 2:
+         UNW_DEC_REG_GR ("P3", UNW_REG_PFS, dst, arg);
+         break;
+       case 3:
+         UNW_DEC_REG_GR ("P3", UNW_REG_PR, dst, arg);
+         break;
+       case 4:
+         UNW_DEC_REG_GR ("P3", UNW_REG_UNAT, dst, arg);
+         break;
+       case 5:
+         UNW_DEC_REG_GR ("P3", UNW_REG_LC, dst, arg);
+         break;
+       case 6:
+         UNW_DEC_RP_BR ("P3", dst, arg);
+         break;
+       case 7:
+         UNW_DEC_REG_GR ("P3", UNW_REG_RNAT, dst, arg);
+         break;
+       case 8:
+         UNW_DEC_REG_GR ("P3", UNW_REG_BSP, dst, arg);
+         break;
+       case 9:
+         UNW_DEC_REG_GR ("P3", UNW_REG_BSPSTORE, dst, arg);
+         break;
+       case 10:
+         UNW_DEC_REG_GR ("P3", UNW_REG_FPSR, dst, arg);
+         break;
+       case 11:
+         UNW_DEC_PRIUNAT_GR ("P3", dst, arg);
+         break;
+       default:
+         UNW_DEC_BAD_CODE (r);
+         break;
+       }
+    }
+  else if ((code & 0x7) == 0)
+    UNW_DEC_SPILL_MASK ("P4", dp, arg);
+  else if ((code & 0x7) == 1)
+    {
+      unw_word grmask, frmask, byte1, byte2, byte3;
+
+      byte1 = *dp++;
+      byte2 = *dp++;
+      byte3 = *dp++;
+      grmask = ((byte1 >> 4) & 0xf);
+      frmask = ((byte1 & 0xf) << 16) | (byte2 << 8) | byte3;
+      UNW_DEC_FRGR_MEM ("P5", grmask, frmask, arg);
+    }
+  else
+    UNW_DEC_BAD_CODE (code);
+
+  return dp;
+}
+
+static const unsigned char *
+unw_decode_p6 (dp, code, arg)
+     const unsigned char * dp;
+     unsigned int         code;
+     void *                arg ATTRIBUTE_UNUSED;
+{
+  int gregs = (code & 0x10) != 0;
+  unsigned char mask = (code & 0x0f);
+
+  if (gregs)
+    UNW_DEC_GR_MEM ("P6", mask, arg);
+  else
+    UNW_DEC_FR_MEM ("P6", mask, arg);
+  return dp;
+}
+
+static const unsigned char *
+unw_decode_p7_p10 (dp, code, arg)
+     const unsigned char *dp;
+     unsigned int code;
+     void *arg;
+{
+  unsigned char r, byte1, byte2;
+  unw_word t, size;
+
+  if ((code & 0x10) == 0)
+    {
+      r = (code & 0xf);
+      t = unw_decode_uleb128 (&dp);
+      switch (r)
+       {
+       case 0:
+         size = unw_decode_uleb128 (&dp);
+         UNW_DEC_MEM_STACK_F ("P7", t, size, arg);
+         break;
+
+       case 1:
+         UNW_DEC_MEM_STACK_V ("P7", t, arg);
+         break;
+       case 2:
+         UNW_DEC_SPILL_BASE ("P7", t, arg);
+         break;
+       case 3:
+         UNW_DEC_REG_SPREL ("P7", UNW_REG_PSP, t, arg);
+         break;
+       case 4:
+         UNW_DEC_REG_WHEN ("P7", UNW_REG_RP, t, arg);
+         break;
+       case 5:
+         UNW_DEC_REG_PSPREL ("P7", UNW_REG_RP, t, arg);
+         break;
+       case 6:
+         UNW_DEC_REG_WHEN ("P7", UNW_REG_PFS, t, arg);
+         break;
+       case 7:
+         UNW_DEC_REG_PSPREL ("P7", UNW_REG_PFS, t, arg);
+         break;
+       case 8:
+         UNW_DEC_REG_WHEN ("P7", UNW_REG_PR, t, arg);
+         break;
+       case 9:
+         UNW_DEC_REG_PSPREL ("P7", UNW_REG_PR, t, arg);
+         break;
+       case 10:
+         UNW_DEC_REG_WHEN ("P7", UNW_REG_LC, t, arg);
+         break;
+       case 11:
+         UNW_DEC_REG_PSPREL ("P7", UNW_REG_LC, t, arg);
+         break;
+       case 12:
+         UNW_DEC_REG_WHEN ("P7", UNW_REG_UNAT, t, arg);
+         break;
+       case 13:
+         UNW_DEC_REG_PSPREL ("P7", UNW_REG_UNAT, t, arg);
+         break;
+       case 14:
+         UNW_DEC_REG_WHEN ("P7", UNW_REG_FPSR, t, arg);
+         break;
+       case 15:
+         UNW_DEC_REG_PSPREL ("P7", UNW_REG_FPSR, t, arg);
+         break;
+       default:
+         UNW_DEC_BAD_CODE (r);
+         break;
+       }
+    }
+  else
+    {
+      switch (code & 0xf)
+       {
+       case 0x0:               /* p8 */
+         {
+           r = *dp++;
+           t = unw_decode_uleb128 (&dp);
+           switch (r)
+             {
+             case 1:
+               UNW_DEC_REG_SPREL ("P8", UNW_REG_RP, t, arg);
+               break;
+             case 2:
+               UNW_DEC_REG_SPREL ("P8", UNW_REG_PFS, t, arg);
+               break;
+             case 3:
+               UNW_DEC_REG_SPREL ("P8", UNW_REG_PR, t, arg);
+               break;
+             case 4:
+               UNW_DEC_REG_SPREL ("P8", UNW_REG_LC, t, arg);
+               break;
+             case 5:
+               UNW_DEC_REG_SPREL ("P8", UNW_REG_UNAT, t, arg);
+               break;
+             case 6:
+               UNW_DEC_REG_SPREL ("P8", UNW_REG_FPSR, t, arg);
+               break;
+             case 7:
+               UNW_DEC_REG_WHEN ("P8", UNW_REG_BSP, t, arg);
+               break;
+             case 8:
+               UNW_DEC_REG_PSPREL ("P8", UNW_REG_BSP, t, arg);
+               break;
+             case 9:
+               UNW_DEC_REG_SPREL ("P8", UNW_REG_BSP, t, arg);
+               break;
+             case 10:
+               UNW_DEC_REG_WHEN ("P8", UNW_REG_BSPSTORE, t, arg);
+               break;
+             case 11:
+               UNW_DEC_REG_PSPREL ("P8", UNW_REG_BSPSTORE, t, arg);
+               break;
+             case 12:
+               UNW_DEC_REG_SPREL ("P8", UNW_REG_BSPSTORE, t, arg);
+               break;
+             case 13:
+               UNW_DEC_REG_WHEN ("P8", UNW_REG_RNAT, t, arg);
+               break;
+             case 14:
+               UNW_DEC_REG_PSPREL ("P8", UNW_REG_RNAT, t, arg);
+               break;
+             case 15:
+               UNW_DEC_REG_SPREL ("P8", UNW_REG_RNAT, t, arg);
+               break;
+             case 16:
+               UNW_DEC_PRIUNAT_WHEN_GR ("P8", t, arg);
+               break;
+             case 17:
+               UNW_DEC_PRIUNAT_PSPREL ("P8", t, arg);
+               break;
+             case 18:
+               UNW_DEC_PRIUNAT_SPREL ("P8", t, arg);
+               break;
+             case 19:
+               UNW_DEC_PRIUNAT_WHEN_MEM ("P8", t, arg);
+               break;
+             default:
+               UNW_DEC_BAD_CODE (r);
+               break;
+             }
+         }
+         break;
+
+       case 0x1:
+         byte1 = *dp++;
+         byte2 = *dp++;
+         UNW_DEC_GR_GR ("P9", (byte1 & 0xf), (byte2 & 0x7f), arg);
+         break;
+
+       case 0xf:               /* p10 */
+         byte1 = *dp++;
+         byte2 = *dp++;
+         UNW_DEC_ABI ("P10", byte1, byte2, arg);
+         break;
+
+       case 0x9:
+         return unw_decode_x1 (dp, code, arg);
+
+       case 0xa:
+         return unw_decode_x2 (dp, code, arg);
+
+       case 0xb:
+         return unw_decode_x3 (dp, code, arg);
+
+       case 0xc:
+         return unw_decode_x4 (dp, code, arg);
+
+       default:
+         UNW_DEC_BAD_CODE (code);
+         break;
+       }
+    }
+  return dp;
+}
+
+static const unsigned char *
+unw_decode_b1 (dp, code, arg)
+     const unsigned char * dp;
+     unsigned int         code;
+     void *                arg ATTRIBUTE_UNUSED;
+{
+  unw_word label = (code & 0x1f);
+
+  if ((code & 0x20) != 0)
+    UNW_DEC_COPY_STATE ("B1", label, arg);
+  else
+    UNW_DEC_LABEL_STATE ("B1", label, arg);
+  return dp;
+}
+
+static const unsigned char *
+unw_decode_b2 (dp, code, arg)
+     const unsigned char * dp;
+     unsigned int         code;
+     void *                arg ATTRIBUTE_UNUSED;
+{
+  unw_word t;
+
+  t = unw_decode_uleb128 (& dp);
+  UNW_DEC_EPILOGUE ("B2", t, (code & 0x1f), arg);
+  return dp;
+}
+
+static const unsigned char *
+unw_decode_b3_x4 (dp, code, arg)
+     const unsigned char *dp;
+     unsigned int code;
+     void *arg;
+{
+  unw_word t, ecount, label;
+
+  if ((code & 0x10) == 0)
+    {
+      t = unw_decode_uleb128 (&dp);
+      ecount = unw_decode_uleb128 (&dp);
+      UNW_DEC_EPILOGUE ("B3", t, ecount, arg);
+    }
+  else if ((code & 0x07) == 0)
+    {
+      label = unw_decode_uleb128 (&dp);
+      if ((code & 0x08) != 0)
+       UNW_DEC_COPY_STATE ("B4", label, arg);
+      else
+       UNW_DEC_LABEL_STATE ("B4", label, arg);
+    }
+  else
+    switch (code & 0x7)
+      {
+      case 1:
+       return unw_decode_x1 (dp, code, arg);
+      case 2:
+       return unw_decode_x2 (dp, code, arg);
+      case 3:
+       return unw_decode_x3 (dp, code, arg);
+      case 4:
+       return unw_decode_x4 (dp, code, arg);
+      default:
+       UNW_DEC_BAD_CODE (code);
+       break;
+      }
+  return dp;
+}
+
+typedef const unsigned char *(*unw_decoder)
+     PARAMS ((const unsigned char *, unsigned int, void *));
+
+static unw_decoder unw_decode_table[2][8] =
+  {
+    /* prologue table: */
+    {
+      unw_decode_r1,           /* 0 */
+      unw_decode_r1,
+      unw_decode_r2,
+      unw_decode_r3,
+      unw_decode_p1,           /* 4 */
+      unw_decode_p2_p5,
+      unw_decode_p6,
+      unw_decode_p7_p10
+    },
+    {
+      unw_decode_r1,           /* 0 */
+      unw_decode_r1,
+      unw_decode_r2,
+      unw_decode_r3,
+      unw_decode_b1,           /* 4 */
+      unw_decode_b1,
+      unw_decode_b2,
+      unw_decode_b3_x4
+    }
+  };
+
+/* Decode one descriptor and return address of next descriptor.  */
+const unsigned char *
+unw_decode (dp, inside_body, ptr_inside_body)
+     const unsigned char * dp;
+     int                   inside_body;
+     void *                ptr_inside_body;
+{
+  unw_decoder decoder;
+  unsigned char code;
+
+  code = *dp++;
+  decoder = unw_decode_table[inside_body][code >> 5];
+  return (*decoder) (dp, code, ptr_inside_body);
+}
diff --git a/Repair/RepairCompiler/structextract/unwind-ia64.h b/Repair/RepairCompiler/structextract/unwind-ia64.h
new file mode 100755 (executable)
index 0000000..30f15b8
--- /dev/null
@@ -0,0 +1,31 @@
+/* unwind-ia64.h -- dump IA-64 unwind info.
+   Copyright 2000, 2001, 2002 Free Software Foundation, Inc.
+       Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
+
+This file is part of GNU Binutils.
+
+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, 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+#include "elf/ia64.h"
+#include "ansidecl.h"
+
+#define UNW_VER(x)             ((x) >> 48)
+#define UNW_FLAG_MASK          0x0000ffff00000000LL
+#define UNW_FLAG_OSMASK                0x0000f00000000000LL
+#define UNW_FLAG_EHANDLER(x)   ((x) & 0x0000000100000000LL)
+#define UNW_FLAG_UHANDLER(x)   ((x) & 0x0000000200000000LL)
+#define UNW_LENGTH(x)          ((x) & 0x00000000ffffffffLL)
+
+extern const unsigned char *   unw_decode PARAMS ((const unsigned char *, int, void *));