]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blobdiff - binutils/readelf.c
For include/opcode:
[thirdparty/binutils-gdb.git] / binutils / readelf.c
index fa583e441d3049d12e610391d413e9ddc7c7c85c..5cdbc6d3769963e93cc9c347f85900b5657c82cd 100644 (file)
@@ -2,7 +2,7 @@
    Copyright 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
 
    Originally developed by Eric Youngdale <eric@andante.jic.com>
-   Modifications by Nick Clifton <nickc@cygnus.com>
+   Modifications by Nick Clifton <nickc@redhat.com>
 
    This file is part of GNU Binutils.
 
 #include "bucomm.h"
 #include "getopt.h"
 
-char *                 program_name = "readelf";
-unsigned int           dynamic_addr;
-bfd_size_type                  dynamic_size;
-unsigned int           rela_addr;
-unsigned int           rela_size;
-char *                 dynamic_strings;
+char *                 program_name = "readelf";
+unsigned int           dynamic_addr;
+bfd_size_type          dynamic_size;
+unsigned int           rela_addr;
+unsigned int           rela_size;
+char *                 dynamic_strings;
 char *                 string_table;
 unsigned long          string_table_length;
 unsigned long           num_dynamic_syms;
-Elf_Internal_Sym *     dynamic_symbols;
+Elf_Internal_Sym *     dynamic_symbols;
 Elf_Internal_Syminfo * dynamic_syminfo;
-unsigned long          dynamic_syminfo_offset;
+unsigned long          dynamic_syminfo_offset;
 unsigned int           dynamic_syminfo_nent;
-char                   program_interpreter [64];
-int                    dynamic_info[DT_JMPREL + 1];
-int                    version_info[16];
-int                    loadaddr = 0;
+char                   program_interpreter [64];
+int                    dynamic_info[DT_JMPREL + 1];
+int                    version_info[16];
+int                    loadaddr = 0;
 Elf_Internal_Ehdr       elf_header;
 Elf_Internal_Shdr *     section_headers;
 Elf_Internal_Dyn *      dynamic_segment;
-int                    show_name;
-int                    do_dynamic;
-int                    do_syms;
-int                    do_reloc;
-int                    do_sections;
-int                    do_segments;
+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_using_dynamic;
+int                    do_header;
+int                    do_dump;
+int                    do_version;
 int                    do_histogram;
 int                    do_debugging;
 int                     do_debug_info;
@@ -118,6 +118,8 @@ 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_arch;
 int                     do_notes;
 int                    is_32bit_elf;
@@ -152,8 +154,8 @@ static const char *       get_mips_dynamic_type       PARAMS ((unsigned long));
 static const char *       get_sparc64_dynamic_type    PARAMS ((unsigned long));
 static const char *       get_parisc_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_Rel **, 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_Rel **, 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));
@@ -171,7 +173,7 @@ 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 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));
@@ -182,8 +184,11 @@ static void               dynamic_segment_mips_val    PARAMS ((Elf_Internal_Dyn
 static void               dynamic_segment_parisc_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 void               process_file                PARAMS ((char *));
+static void               process_mips_fpe_exception  PARAMS ((int));
+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));
@@ -199,16 +204,19 @@ static int *              get_dynamic_data            PARAMS ((FILE *, unsigned
 static int                get_32bit_dynamic_segment   PARAMS ((FILE *));
 static int                get_64bit_dynamic_segment   PARAMS ((FILE *));
 #ifdef SUPPORT_DISASSEMBLY
-static int               disassemble_section         PARAMS ((Elf32_Internal_Shdr *, FILE *));
+static int               disassemble_section         PARAMS ((Elf32_Internal_Shdr *, FILE *));
 #endif
-static int               dump_section                PARAMS ((Elf32_Internal_Shdr *, FILE *));
-static int               display_debug_section       PARAMS ((Elf32_Internal_Shdr *, FILE *));
+static int               dump_section                PARAMS ((Elf32_Internal_Shdr *, FILE *));
+static int               display_debug_section       PARAMS ((Elf32_Internal_Shdr *, FILE *));
 static int                display_debug_info          PARAMS ((Elf32_Internal_Shdr *, unsigned char *, FILE *));
 static int                display_debug_not_supported PARAMS ((Elf32_Internal_Shdr *, unsigned char *, FILE *));
+static int                prescan_debug_info          PARAMS ((Elf32_Internal_Shdr *, unsigned char *, FILE *));
 static int                display_debug_lines         PARAMS ((Elf32_Internal_Shdr *, unsigned char *, FILE *));
+static int                display_debug_pubnames      PARAMS ((Elf32_Internal_Shdr *, unsigned char *, FILE *));
 static int                display_debug_abbrev        PARAMS ((Elf32_Internal_Shdr *, unsigned char *, FILE *));
 static int                display_debug_aranges       PARAMS ((Elf32_Internal_Shdr *, unsigned char *, FILE *));
 static int                display_debug_frames        PARAMS ((Elf32_Internal_Shdr *, unsigned char *, FILE *));
+static int                display_debug_macinfo       PARAMS ((Elf32_Internal_Shdr *, unsigned char *, FILE *));
 static unsigned char *    process_abbrev_section      PARAMS ((unsigned char *, unsigned char *));
 static unsigned long      read_leb128                 PARAMS ((unsigned char *, int *, int));
 static int                process_extended_line_op    PARAMS ((unsigned char *, int, int));
@@ -227,11 +235,12 @@ static const char *       get_elf_class               PARAMS ((unsigned char));
 static const char *       get_data_encoding           PARAMS ((unsigned char));
 static const char *       get_osabi_name              PARAMS ((unsigned char));
 static int               guess_is_rela               PARAMS ((unsigned long));
-static char *            get_note_type                  PARAMS ((unsigned int));
+static char *            get_note_type                  PARAMS ((unsigned int));
 static int               process_note                   PARAMS ((Elf32_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_corefile_contents      PARAMS ((FILE *));
+static int               process_arch_specific          PARAMS ((FILE *));
 
 typedef int Elf32_Word;
 
@@ -241,13 +250,13 @@ typedef int Elf32_Word;
 #endif
 #define UNKNOWN -1
 
-#define SECTION_NAME(X)        ((X) == NULL ? "<none>" : \
+#define SECTION_NAME(X)        ((X) == NULL ? "<none>" : \
                                 ((X)->sh_name >= string_table_length \
                                  ? "<corrupt>" : string_table + (X)->sh_name))
 
 #define DT_VERSIONTAGIDX(tag)  (DT_VERNEEDNUM - (tag)) /* Reverse order! */
 
-#define BYTE_GET(field)        byte_get (field, sizeof (field))
+#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
@@ -258,48 +267,12 @@ typedef int Elf32_Word;
    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)
+#define BYTE_GET8(field)       byte_get (field, -8)
 #else
-#define BYTE_GET8(field)       byte_get (field, 8)
+#define BYTE_GET8(field)       byte_get (field, 8)
 #endif
 
-#define NUM_ELEM(array)        (sizeof (array) / sizeof ((array)[0]))
-
-#define GET_DATA_ALLOC(offset, size, var, type, reason)                        \
-  if (fseek (file, offset, SEEK_SET))                                  \
-    {                                                                  \
-      error (_("Unable to seek to start of %s at %x\n"), reason, offset); \
-      return 0;                                                                \
-    }                                                                  \
-                                                                       \
-  var = (type) malloc (size);                                          \
-                                                                       \
-  if (var == NULL)                                                     \
-    {                                                                  \
-      error (_("Out of memory allocating %d bytes for %s\n"), size, reason); \
-      return 0;                                                                \
-    }                                                                  \
-                                                                       \
-  if (fread (var, size, 1, file) != 1)                                         \
-    {                                                                  \
-      error (_("Unable to read in %d bytes of %s\n"), size, reason);   \
-      free (var);                                                      \
-      var = NULL;                                                      \
-      return 0;                                                        \
-    }
-
-
-#define GET_DATA(offset, var, reason)                                  \
-  if (fseek (file, offset, SEEK_SET))                                  \
-    {                                                                  \
-      error (_("Unable to seek to %x for %s\n"), offset, reason);      \
-      return 0;                                                                \
-    }                                                                  \
-  else if (fread (& var, sizeof (var), 1, file) != 1)                  \
-    {                                                                  \
-      error (_("Unable to read data at %x for %s\n"), offset, reason); \
-      return 0;                                                                \
-    }
+#define NUM_ELEM(array)        (sizeof (array) / sizeof ((array)[0]))
 
 #define GET_ELF_SYMBOLS(file, offset, size)                    \
   (is_32bit_elf ? get_32bit_elf_symbols (file, offset, size)   \
@@ -362,6 +335,51 @@ warn (va_alist)
 }
 #endif
 
+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;
@@ -376,11 +394,13 @@ byte_get_little_endian (field, size)
       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 juts use the 4 byte extraction code.  */
       /* Fall through.  */
+#endif
     case 4:
       return  ((unsigned long) (field [0]))
        |    (((unsigned long) (field [1])) << 8)
@@ -388,6 +408,7 @@ byte_get_little_endian (field, size)
        |    (((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
@@ -516,6 +537,7 @@ byte_get_big_endian (field, size)
        |   (((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.  */
@@ -523,8 +545,8 @@ byte_get_big_endian (field, size)
        |   (((unsigned long) (field [6])) << 8)
        |   (((unsigned long) (field [5])) << 16)
        |   (((unsigned long) (field [4])) << 24);
-
-#ifdef BFD64
+#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
@@ -562,7 +584,7 @@ guess_is_rela (e_machine)
     case EM_CYGNUS_M32R:
     case EM_CYGNUS_D10V:
     case EM_MIPS:
-    case EM_MIPS_RS4_BE:
+    case EM_MIPS_RS3_LE:
       return FALSE;
 
       /* Targets that use RELA relocations.  */
@@ -628,8 +650,10 @@ slurp_rela_relocs (file, rel_offset, rel_size, relasp, nrelasp)
     {
       Elf32_External_Rela * erelas;
 
-      GET_DATA_ALLOC (rel_offset, rel_size, erelas,
-                     Elf32_External_Rela *, "relocs");
+      erelas = (Elf32_External_Rela *) get_data (NULL, file, rel_offset,
+                                                rel_size, _("relocs"));
+      if (!erelas)
+       return 0;
 
       nrelas = rel_size / sizeof (Elf32_External_Rela);
 
@@ -655,8 +679,10 @@ slurp_rela_relocs (file, rel_offset, rel_size, relasp, nrelasp)
     {
       Elf64_External_Rela * erelas;
 
-      GET_DATA_ALLOC (rel_offset, rel_size, erelas,
-                     Elf64_External_Rela *, "relocs");
+      erelas = (Elf64_External_Rela *) get_data (NULL, file, rel_offset,
+                                                rel_size, _("relocs"));
+      if (!erelas)
+       return 0;
 
       nrelas = rel_size / sizeof (Elf64_External_Rela);
 
@@ -699,8 +725,10 @@ slurp_rel_relocs (file, rel_offset, rel_size, relsp, nrelsp)
     {
       Elf32_External_Rel * erels;
 
-      GET_DATA_ALLOC (rel_offset, rel_size, erels,
-                     Elf32_External_Rel *, "relocs");
+      erels = (Elf32_External_Rel *) get_data (NULL, file, rel_offset,
+                                              rel_size, _("relocs"));
+      if (!erels)
+       return 0;
 
       nrels = rel_size / sizeof (Elf32_External_Rel);
 
@@ -724,8 +752,10 @@ slurp_rel_relocs (file, rel_offset, rel_size, relsp, nrelsp)
     {
       Elf64_External_Rel * erels;
 
-      GET_DATA_ALLOC (rel_offset, rel_size, erels,
-                     Elf64_External_Rel *, "relocs");
+      erels = (Elf64_External_Rel *) get_data (NULL, file, rel_offset,
+                                              rel_size, _("relocs"));
+      if (!erels)
+       return 0;
 
       nrels = rel_size / sizeof (Elf64_External_Rel);
 
@@ -780,12 +810,24 @@ dump_relocations (file, rel_offset, rel_size, symtab, nsyms, strtab, is_rela)
        return 0;
     }
 
-  if (is_rela)
-    printf
-      (_("  Offset    Info  Type            Symbol's Value  Symbol's Name          Addend\n"));
+  if (is_32bit_elf)
+    {
+      if (is_rela)
+       printf
+         (_(" Offset     Info    Type            Symbol's Value  Symbol's Name          Addend\n"));
+      else
+       printf
+         (_(" Offset     Info    Type            Symbol's Value  Symbol's Name\n"));
+    }
   else
-    printf
-      (_("  Offset    Info  Type            Symbol's Value  Symbol's Name\n"));
+    {
+      if (is_rela)
+       printf
+         (_("    Offset             Info            Type               Symbol's Value   Symbol's Name           Addend\n"));
+      else
+       printf
+         (_("    Offset             Info            Type               Symbol's Value   Symbol's Name\n"));
+    }
 
   for (i = 0; i < rel_size; i++)
     {
@@ -825,11 +867,26 @@ dump_relocations (file, rel_offset, rel_size, symtab, nsyms, strtab, is_rela)
 #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 ("  %8.8lx  %5.5lx ", _bfd_int64_low (offset), _bfd_int64_low (info));
+         printf ("%8.8lx%8.8lx  %8.8lx%8.8lx ",
+                 _bfd_int64_high (offset),
+                 _bfd_int64_low (offset),
+                 _bfd_int64_high (info),
+                 _bfd_int64_low (info));
 #else
-      printf ("  %8.8lx  %5.5lx ", offset, info);
+         printf ("%16.16lx  %16.16lx ", offset, info);
 #endif
+       }
 
       switch (elf_header.e_machine)
        {
@@ -902,7 +959,7 @@ dump_relocations (file, rel_offset, rel_size, symtab, nsyms, strtab, is_rela)
          break;
 
        case EM_MIPS:
-       case EM_MIPS_RS4_BE:
+       case EM_MIPS_RS3_LE:
          rtype = elf_mips_reloc_type (type);
          break;
 
@@ -959,31 +1016,28 @@ dump_relocations (file, rel_offset, rel_size, symtab, nsyms, strtab, is_rela)
 
       if (symtab_index)
        {
-         if (symtab != NULL)
+         if (symtab == NULL || symtab_index >= nsyms)
+           printf (" bad symbol index: %08lx", (unsigned long) symtab_index);
+         else
            {
-             if (symtab_index >= nsyms)
-               printf (" bad symbol index: %08lx", (unsigned long) symtab_index);
-             else
-               {
-                 Elf_Internal_Sym * psym;
+             Elf_Internal_Sym * psym;
 
-                 psym = symtab + symtab_index;
+             psym = symtab + symtab_index;
 
-                 printf (" ");
-                 print_vma (psym->st_value, LONG_HEX);
-                 printf ("  ");
+             printf (" ");
+             print_vma (psym->st_value, LONG_HEX);
+             printf ("  ");
 
-                 if (psym->st_name == 0)
-                   printf ("%-25.25s",
-                           SECTION_NAME (section_headers + psym->st_shndx));
-                 else if (strtab == NULL)
-                   printf (_("<string table index %3ld>"), psym->st_name);
-                 else
-                   printf ("%-25.25s", strtab + psym->st_name);
+             if (psym->st_name == 0)
+               printf ("%-25.25s",
+                       SECTION_NAME (section_headers + psym->st_shndx));
+             else if (strtab == NULL)
+               printf (_("<string table index %3ld>"), psym->st_name);
+             else
+               printf ("%-25.25s", strtab + psym->st_name);
 
-                 if (is_rela)
-                   printf (" + %lx", (unsigned long) relas [i].r_addend);
-               }
+             if (is_rela)
+               printf (" + %lx", (unsigned long) relas [i].r_addend);
            }
        }
       else if (is_rela)
@@ -1179,7 +1233,7 @@ get_dynamic_type (type)
          switch (elf_header.e_machine)
            {
            case EM_MIPS:
-           case EM_MIPS_RS4_BE:
+           case EM_MIPS_RS3_LE:
              result = get_mips_dynamic_type (type);
              break;
            case EM_SPARCV9:
@@ -1254,32 +1308,32 @@ get_machine_name (e_machine)
 
   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_RS4_BE:       return "MIPS R4000 big-endian";
+    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_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_V800:              return "NEC V800";
-    case EM_FR20:              return "Fujitsu FR20";
-    case EM_RH32:              return "TRW RH32";
+    case EM_SPARC32PLUS:       return "Sparc v8+" ;
+    case EM_960:               return "Intel 90860";
+    case EM_PPC:               return "PowerPC";
+    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 "Hitachi SH";
-    case EM_SPARCV9:           return "Sparc v9";
-    case EM_TRICORE:           return "Siemens Tricore";
+    case EM_ARM:               return "ARM";
+    case EM_OLD_ALPHA:         return "Digital Alpha (old)";
+    case EM_SH:                        return "Hitachi SH";
+    case EM_SPARCV9:           return "Sparc v9";
+    case EM_TRICORE:           return "Siemens Tricore";
     case EM_ARC:               return "ARC";
     case EM_H8_300:            return "Hitachi H8/300";
     case EM_H8_300H:           return "Hitachi H8/300H";
@@ -1289,7 +1343,7 @@ get_machine_name (e_machine)
     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_ALPHA:             return "Alpha";
     case EM_CYGNUS_D10V:        return "d10v";
     case EM_CYGNUS_D30V:        return "d30v";
     case EM_CYGNUS_ARC:                return "ARC";
@@ -1299,32 +1353,32 @@ get_machine_name (e_machine)
     case EM_CYGNUS_MN10200:    return "mn10200";
     case EM_CYGNUS_FR30:       return "Fujitsu FR30";
     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_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:                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_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 "SiTera Prism";
+    case EM_HUANY:             return "Harvard Universitys's machine-independent object format";
+    case EM_PRISM:             return "SiTera Prism";
     case EM_X86_64:            return "Advanced Micro Devices X86-64";
     case EM_S390_OLD:
     case EM_S390:               return "IBM S/390";
@@ -1537,7 +1591,7 @@ get_machine_flags (e_flags, e_machine)
          break;
 
        case EM_MIPS:
-       case EM_MIPS_RS4_BE:
+       case EM_MIPS_RS3_LE:
          if (e_flags & EF_MIPS_NOREORDER)
            strcat (buf, ", noreorder");
 
@@ -1547,6 +1601,9 @@ get_machine_flags (e_flags, e_machine)
          if (e_flags & EF_MIPS_CPIC)
            strcat (buf, ", cpic");
 
+         if (e_flags & EF_MIPS_UCODE)
+           strcat (buf, ", ugen_reserved");
+
          if (e_flags & EF_MIPS_ABI2)
            strcat (buf, ", abi2");
 
@@ -1752,7 +1809,7 @@ get_segment_type (p_type)
          switch (elf_header.e_machine)
            {
            case EM_MIPS:
-           case EM_MIPS_RS4_BE:
+           case EM_MIPS_RS3_LE:
              result = get_mips_segment_type (p_type);
              break;
            case EM_PARISC:
@@ -1918,7 +1975,7 @@ get_section_type_name (sh_type)
          switch (elf_header.e_machine)
            {
            case EM_MIPS:
-           case EM_MIPS_RS4_BE:
+           case EM_MIPS_RS3_LE:
              result = get_mips_section_type_name (sh_type);
              break;
            case EM_PARISC:
@@ -2000,7 +2057,7 @@ usage ()
   fprintf (stdout, _("  -D or --use-dynamic       Use the dynamic section info when displaying symbols\n"));
   fprintf (stdout, _("  -x <number> or --hex-dump=<number>\n"));
   fprintf (stdout, _("                            Dump the contents of section <number>\n"));
-  fprintf (stdout, _("  -w[liaprf] or --debug-dump[=line,=info,=abbrev,=pubnames,=ranges,=frames]\n"));
+  fprintf (stdout, _("  -w[liaprmf] or --debug-dump[=line,=info,=abbrev,=pubnames,=ranges,=macro,=frames]\n"));
   fprintf (stdout, _("                            Display the contents of DWARF2 debug sections\n"));
 #ifdef SUPPORT_DISASSEMBLY
   fprintf (stdout, _("  -i <number> or --instruction-dump=<number>\n"));
@@ -2164,11 +2221,17 @@ parse_args (argc, argv)
                  do_debug_aranges = 1;
                  break;
 
-               case 'f':
                case 'F':
+                 do_debug_frames_interp = 1;
+               case 'f':
                  do_debug_frames = 1;
                  break;
 
+               case 'm':
+               case 'M':
+                 do_debug_macinfo = 1;
+                 break;
+
                default:
                  warn (_("Unrecognised debug option '%s'\n"), optarg);
                  break;
@@ -2359,9 +2422,12 @@ get_32bit_program_headers (file, program_headers)
   Elf32_Internal_Phdr * internal;
   unsigned int          i;
 
-  GET_DATA_ALLOC (elf_header.e_phoff,
-                 elf_header.e_phentsize * elf_header.e_phnum,
-                 phdrs, Elf32_External_Phdr *, "program headers");
+  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;
@@ -2392,9 +2458,12 @@ get_64bit_program_headers (file, program_headers)
   Elf64_Internal_Phdr * internal;
   unsigned int          i;
 
-  GET_DATA_ALLOC (elf_header.e_phoff,
-                 elf_header.e_phentsize * elf_header.e_phnum,
-                 phdrs, Elf64_External_Phdr *, "program headers");
+  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;
@@ -2613,9 +2682,12 @@ get_32bit_section_headers (file)
   Elf32_Internal_Shdr * internal;
   unsigned int          i;
 
-  GET_DATA_ALLOC (elf_header.e_shoff,
-                 elf_header.e_shentsize * elf_header.e_shnum,
-                 shdrs, Elf32_External_Shdr *, "section headers");
+  shdrs = ((Elf32_External_Shdr *)
+          get_data (NULL, file, elf_header.e_shoff,
+                    elf_header.e_shentsize * elf_header.e_shnum,
+                    _("section headers")));
+  if (!shdrs)
+    return 0;
 
   section_headers = (Elf_Internal_Shdr *) malloc
     (elf_header.e_shnum * sizeof (Elf_Internal_Shdr));
@@ -2655,9 +2727,12 @@ get_64bit_section_headers (file)
   Elf64_Internal_Shdr * internal;
   unsigned int          i;
 
-  GET_DATA_ALLOC (elf_header.e_shoff,
-                 elf_header.e_shentsize * elf_header.e_shnum,
-                 shdrs, Elf64_External_Shdr *, "section headers");
+  shdrs = ((Elf64_External_Shdr *)
+          get_data (NULL, file, elf_header.e_shoff,
+                    elf_header.e_shentsize * elf_header.e_shnum,
+                    _("section headers")));
+  if (!shdrs)
+    return 0;
 
   section_headers = (Elf_Internal_Shdr *) malloc
     (elf_header.e_shnum * sizeof (Elf_Internal_Shdr));
@@ -2700,8 +2775,11 @@ get_32bit_elf_symbols (file, offset, number)
   Elf_Internal_Sym *   psym;
   unsigned int         j;
 
-  GET_DATA_ALLOC (offset, number * sizeof (Elf32_External_Sym),
-                 esyms, Elf32_External_Sym *, "symbols");
+  esyms = ((Elf32_External_Sym *)
+          get_data (NULL, file, offset,
+                    number * sizeof (Elf32_External_Sym), _("symbols")));
+  if (!esyms)
+    return NULL;
 
   isyms = (Elf_Internal_Sym *) malloc (number * sizeof (Elf_Internal_Sym));
 
@@ -2741,8 +2819,11 @@ get_64bit_elf_symbols (file, offset, number)
   Elf_Internal_Sym *   psym;
   unsigned int         j;
 
-  GET_DATA_ALLOC (offset, number * sizeof (Elf64_External_Sym),
-                 esyms, Elf64_External_Sym *, "symbols");
+  esyms = ((Elf64_External_Sym *)
+          get_data (NULL, file, offset,
+                    number * sizeof (Elf64_External_Sym), _("symbols")));
+  if (!esyms)
+    return NULL;
 
   isyms = (Elf_Internal_Sym *) malloc (number * sizeof (Elf_Internal_Sym));
 
@@ -2852,8 +2933,8 @@ process_section_headers (file)
 
   if (section->sh_size != 0)
     {
-      GET_DATA_ALLOC (section->sh_offset, section->sh_size,
-                     string_table, char *, "string table");
+      string_table = (char *) get_data (NULL, file, section->sh_offset,
+                                       section->sh_size, _("string table"));
 
       string_table_length = section->sh_size;
     }
@@ -2891,11 +2972,13 @@ process_section_headers (file)
              continue;
            }
 
-         GET_DATA_ALLOC (section->sh_offset, section->sh_size,
-                         dynamic_strings, char *, "dynamic strings");
+         dynamic_strings = (char *) get_data (NULL, file, section->sh_offset,
+                                              section->sh_size,
+                                              _("dynamic strings"));
        }
       else if ((do_debugging || do_debug_info || do_debug_abbrevs
-               || do_debug_lines || do_debug_pubnames || do_debug_aranges || do_debug_frames)
+               || do_debug_lines || do_debug_pubnames || do_debug_aranges
+               || do_debug_frames || do_debug_macinfo)
               && strncmp (name, ".debug_", 7) == 0)
        {
          name += 7;
@@ -2907,6 +2990,7 @@ process_section_headers (file)
              || (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))
              )
            request_dump (i, DEBUG_DUMP);
        }
@@ -3049,8 +3133,8 @@ process_relocs (file)
   else
     {
       Elf32_Internal_Shdr *     section;
-      unsigned long            i;
-      int                      found = 0;
+      unsigned long            i;
+      int              found = 0;
 
       for (i = 0, section = section_headers;
           i < elf_header.e_shnum;
@@ -3066,7 +3150,6 @@ process_relocs (file)
          if (rel_size)
            {
              Elf32_Internal_Shdr * strsec;
-             Elf32_Internal_Shdr * symsec;
              Elf_Internal_Sym *    symtab;
              char *                strtab;
              int                   is_rela;
@@ -3082,25 +3165,35 @@ process_relocs (file)
              printf (_(" at offset 0x%lx contains %lu entries:\n"),
                 rel_offset, (unsigned long) (rel_size / section->sh_entsize));
 
-             symsec = section_headers + section->sh_link;
-
-             nsyms = symsec->sh_size / symsec->sh_entsize;
-             symtab = GET_ELF_SYMBOLS (file, symsec->sh_offset, nsyms);
+             symtab = NULL;
+             strtab = NULL;
+             nsyms = 0;
+             if (section->sh_link)
+               {
+                 Elf32_Internal_Shdr * symsec;
 
-             if (symtab == NULL)
-               continue;
+                 symsec = section_headers + section->sh_link;
+                 nsyms = symsec->sh_size / symsec->sh_entsize;
+                 symtab = GET_ELF_SYMBOLS (file, symsec->sh_offset, nsyms);
 
-             strsec = section_headers + symsec->sh_link;
+                 if (symtab == NULL)
+                   continue;
 
-             GET_DATA_ALLOC (strsec->sh_offset, strsec->sh_size, strtab,
-                             char *, "string table");
+                 strsec = section_headers + 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);
+             dump_relocations (file, rel_offset, rel_size,
+                               symtab, nsyms, strtab, is_rela);
 
-             free (strtab);
-             free (symtab);
+             if (strtab)
+               free (strtab);
+             if (symtab)
+               free (symtab);
 
              found = 1;
            }
@@ -3195,7 +3288,7 @@ dump_ia64_unwind (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)
@@ -3302,7 +3395,10 @@ slurp_ia64_unwind_table (file, aux, sec)
 
   /* Second, build the unwind table from the contents of the unwind section:  */
   size = sec->sh_size;
-  GET_DATA_ALLOC (sec->sh_offset, size, table, char *, "unwind table");
+  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)
@@ -3408,7 +3504,7 @@ process_unwind (file)
      FILE * file;
 {
   Elf32_Internal_Shdr *sec, *unwsec = NULL, *strsec;
-  unsigned long i, addr_size;
+  unsigned long i, addr_size, unwcount = 0, unwstart = 0;
   struct unw_aux_info aux;
 
   if (!do_unwind)
@@ -3433,44 +3529,104 @@ process_unwind (file)
 
          strsec = section_headers + sec->sh_link;
          aux.strtab_size = strsec->sh_size;
-         GET_DATA_ALLOC (strsec->sh_offset, aux.strtab_size,
-                         aux.strtab, char *, "string table");
+         aux.strtab = (char *) get_data (NULL, file, strsec->sh_offset,
+                                         aux.strtab_size, _("string table"));
        }
       else if (sec->sh_type == SHT_IA_64_UNWIND)
-       unwsec = sec;
-      else if (strcmp (SECTION_NAME (sec), ELF_STRING_ia64_unwind_info) == 0)
-       {
-         aux.info_size = sec->sh_size;
-         aux.info_addr = sec->sh_addr;
-         GET_DATA_ALLOC (sec->sh_offset, aux.info_size, aux.info,
-                         char *, "unwind info");
-       }
+       unwcount++;
     }
 
-  if (unwsec)
+  if (!unwcount)
+    printf (_("\nThere are no unwind sections in this file.\n"));
+
+  while (unwcount-- > 0)
     {
-      printf (_("\nUnwind section "));
+      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 (string_table == NULL)
-       printf ("%d", unwsec->sh_name);
+      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
-       printf ("'%s'", SECTION_NAME (unwsec));
+       {
+         /* .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;
+       }
 
-      printf (_(" at offset 0x%lx contains %lu entries:\n"),
-             unwsec->sh_offset, (unsigned long) (unwsec->sh_size / (3 * addr_size)));
+      if (i == elf_header.e_shnum)
+       {
+         printf (_("\nCould not find unwind info section for "));
 
-      (void) slurp_ia64_unwind_table (file, & aux, unwsec);
+         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 (aux.table_len > 0)
-       dump_ia64_unwind (& aux);
+         if (string_table == NULL)
+           printf ("%d", unwsec->sh_name);
+         else
+           printf ("'%s'", SECTION_NAME (unwsec));
+
+         printf (_(" at offset 0x%lx contains %lu entries:\n"),
+                 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;
+       }
     }
-  else
-    printf (_("\nThere are no unwind sections in this file.\n"));
 
-  if (aux.table)
-    free ((char *) aux.table);
-  if (aux.info)
-    free ((char *) aux.info);
   if (aux.symtab)
     free (aux.symtab);
   if (aux.strtab)
@@ -3618,8 +3774,10 @@ get_32bit_dynamic_segment (file)
   Elf_Internal_Dyn *   entry;
   bfd_size_type        i;
 
-  GET_DATA_ALLOC (dynamic_addr, dynamic_size,
-                 edyn, Elf32_External_Dyn *, "dynamic segment");
+  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
@@ -3659,8 +3817,10 @@ get_64bit_dynamic_segment (file)
   Elf_Internal_Dyn *   entry;
   bfd_size_type        i;
 
-  GET_DATA_ALLOC (dynamic_addr, dynamic_size,
-                 edyn, Elf64_External_Dyn *, "dynamic segment");
+  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
@@ -3810,8 +3970,8 @@ process_dynamic_segment (file)
              continue;
            }
 
-         GET_DATA_ALLOC (offset, str_tab_len, dynamic_strings, char *,
-                         "dynamic string table");
+         dynamic_strings = (char *) get_data (NULL, file, offset, str_tab_len,
+                                              _("dynamic string table"));
 
          break;
        }
@@ -3844,8 +4004,11 @@ process_dynamic_segment (file)
          Elf_Internal_Syminfo * syminfo;
 
          /* There is a syminfo section.  Read the data.  */
-         GET_DATA_ALLOC (dynamic_syminfo_offset, syminsz, extsyminfo,
-                         Elf_External_Syminfo *, "symbol information");
+         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)
@@ -4213,7 +4376,7 @@ process_dynamic_segment (file)
              switch (elf_header.e_machine)
                {
                case EM_MIPS:
-               case EM_MIPS_RS4_BE:
+               case EM_MIPS_RS3_LE:
                  dynamic_segment_mips_val (entry);
                  break;
                case EM_PARISC:
@@ -4295,9 +4458,12 @@ process_version_sections (file)
                    (unsigned long) section->sh_offset, section->sh_link,
                    SECTION_NAME (section_headers + section->sh_link));
 
-           GET_DATA_ALLOC (section->sh_offset, section->sh_size,
-                           edefs, Elf_External_Verdef *,
-                           "version definition section");
+           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)
              {
@@ -4383,9 +4549,11 @@ process_version_sections (file)
                    (unsigned long) section->sh_offset, section->sh_link,
                    SECTION_NAME (section_headers + section->sh_link));
 
-           GET_DATA_ALLOC (section->sh_offset, section->sh_size,
-                           eneed, Elf_External_Verneed *,
-                           "version need section");
+           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)
              {
@@ -4453,12 +4621,12 @@ process_version_sections (file)
        case SHT_GNU_versym:
          {
            Elf32_Internal_Shdr *       link_section;
-           int                         total;
-           int                         cnt;
-           unsigned char *             edata;
-           unsigned short *            data;
-           char *                      strtab;
-           Elf_Internal_Sym *          symbols;
+           int         total;
+           int         cnt;
+           unsigned char *             edata;
+           unsigned short *            data;
+           char *              strtab;
+           Elf_Internal_Sym *          symbols;
            Elf32_Internal_Shdr *       string_sec;
 
            link_section = section_headers + section->sh_link;
@@ -4471,8 +4639,11 @@ process_version_sections (file)
 
            string_sec = section_headers + link_section->sh_link;
 
-           GET_DATA_ALLOC (string_sec->sh_offset, string_sec->sh_size,
-                           strtab, char *, "version string table");
+           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);
@@ -4483,10 +4654,16 @@ process_version_sections (file)
                    (unsigned long) section->sh_offset, section->sh_link,
                    SECTION_NAME (link_section));
 
-           GET_DATA_ALLOC (version_info [DT_VERSIONTAGIDX (DT_VERSYM)]
-                           - loadaddr,
-                           total * sizeof (short), edata,
-                           unsigned char *, "version symbol data");
+           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));
 
@@ -4547,7 +4724,8 @@ process_version_sections (file)
                              Elf_External_Vernaux   evna;
                              unsigned long          a_off;
 
-                             GET_DATA (offset, evn, "version need");
+                             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);
@@ -4556,8 +4734,8 @@ process_version_sections (file)
 
                              do
                                {
-                                 GET_DATA (a_off, evna,
-                                           "version need aux (2)");
+                                 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);
@@ -4597,7 +4775,8 @@ process_version_sections (file)
 
                          do
                            {
-                             GET_DATA (offset, evd, "version def");
+                             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);
@@ -4614,8 +4793,9 @@ process_version_sections (file)
 
                              ivd.vd_aux = BYTE_GET (evd.vd_aux);
 
-                             GET_DATA (offset - ivd.vd_next + ivd.vd_aux,
-                                       evda, "version def 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);
 
@@ -4920,8 +5100,9 @@ process_symbol_table (file)
 
              string_sec = section_headers + section->sh_link;
 
-             GET_DATA_ALLOC (string_sec->sh_offset, string_sec->sh_size,
-                             strtab, char *, "string table");
+             strtab = (char *) get_data (NULL, file, string_sec->sh_offset,
+                                         string_sec->sh_size,
+                                         _("string table"));
            }
 
          for (si = 0, psym = symtab;
@@ -4950,8 +5131,8 @@ process_symbol_table (file)
                  offset = version_info [DT_VERSIONTAGIDX (DT_VERSYM)]
                    - loadaddr;
 
-                 GET_DATA (offset + si * sizeof (vers_data), data,
-                           "version data");
+                 get_data (&data, file, offset + si * sizeof (vers_data),
+                           sizeof (data), _("version data"));
 
                  vers_data = byte_get (data, 2);
 
@@ -4978,7 +5159,8 @@ process_symbol_table (file)
                            {
                              unsigned long  vna_off;
 
-                             GET_DATA (offset, evn, "version need");
+                             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);
@@ -4989,8 +5171,9 @@ process_symbol_table (file)
                                {
                                  Elf_External_Vernaux  evna;
 
-                                 GET_DATA (vna_off, evna,
-                                           "version need aux (3)");
+                                 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);
@@ -5038,7 +5221,8 @@ process_symbol_table (file)
                                {
                                  Elf_External_Verdef   evd;
 
-                                 GET_DATA (offset, evd, "version def");
+                                 get_data (&evd, file, offset, sizeof (evd),
+                                           _("version def"));
 
                                  ivd.vd_ndx  = BYTE_GET (evd.vd_ndx);
                                  ivd.vd_aux  = BYTE_GET (evd.vd_aux);
@@ -5052,7 +5236,8 @@ process_symbol_table (file)
                              offset -= ivd.vd_next;
                              offset += ivd.vd_aux;
 
-                             GET_DATA (offset, evda, "version def aux");
+                             get_data (&evda, file, offset, sizeof (evda),
+                                       _("version def aux"));
 
                              ivda.vda_name = BYTE_GET (evda.vda_name);
 
@@ -5245,8 +5430,10 @@ dump_section (section, file)
 
   addr = section->sh_addr;
 
-  GET_DATA_ALLOC (section->sh_offset, bytes, start, unsigned char *,
-                 "section data");
+  start = (unsigned char *) get_data (NULL, file, section->sh_offset, bytes,
+                                     _("section data"));
+  if (!start)
+    return 0;
 
   data = start;
 
@@ -5742,58 +5929,67 @@ get_TAG_name (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_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";
+    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";
     default:
       {
        static char buffer [100];
@@ -5810,85 +6006,100 @@ get_AT_name (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_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_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";
-    case DW_AT_MIPS_fde: return "DW_AT_MIPS_fde";
-    case DW_AT_MIPS_loop_begin: return "DW_AT_MIPS_loop_begin";
+      /* 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_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";
-    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_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";
     default:
       {
        static char buffer [100];
@@ -5905,27 +6116,27 @@ get_FORM_name (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_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";
+    case DW_FORM_indirect:  return "DW_FORM_indirect";
     default:
       {
        static char buffer [100];
@@ -6097,6 +6308,80 @@ process_abbrev_section (start, end)
 }
 
 
+static int
+display_debug_macinfo (section, start, file)
+     Elf32_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)
      Elf32_Internal_Shdr * section;
@@ -6448,6 +6733,22 @@ decode_location_expression (data, pointer_size, length)
          printf ("DW_OP_nop");
          break;
 
+         /* DWARF 2.1 extensions.  */
+       case DW_OP_push_object_address:
+         printf ("DW_OP_push_object_address");
+         break;
+       case DW_OP_call2:
+         printf ("DW_OP_call2: <%lx>", (long) byte_get (data, 2));
+         data += 2;
+         break;
+       case DW_OP_call4:
+         printf ("DW_OP_call4: <%lx>", (long) byte_get (data, 4));
+         data += 4;
+         break;
+       case DW_OP_calli:
+         printf ("DW_OP_calli");
+         break;
+
        default:
          if (op >= DW_OP_lo_user
              && op <= DW_OP_hi_user)
@@ -6457,6 +6758,9 @@ decode_location_expression (data, pointer_size, length)
          /* No way to tell where the next op is, so just bail.  */
          return;
        }
+
+      /* Separate the ops.  */
+      printf ("; ");
     }
 }
 
@@ -6618,6 +6922,11 @@ read_and_display_attr (attribute, form, data, cu_offset, pointer_size)
        case DW_LANG_Ada83:          printf ("(Ada)"); break;
        case DW_LANG_Cobol74:        printf ("(Cobol 74)"); break;
        case DW_LANG_Cobol85:        printf ("(Cobol 85)"); break;
+         /* DWARF 2.1 values.  */
+       case DW_LANG_C99:            printf ("(ANSI C99)"); break;
+       case DW_LANG_Ada95:          printf ("(ADA 95)"); break;
+       case DW_LANG_Fortran95:       printf ("(Fortran 95)"); break;
+         /* MIPS extension.  */
        case DW_LANG_Mips_Assembler: printf ("(MIPS assembler)"); break;
        default:                     printf ("(Unknown: %lx)", uvalue); break;
        }
@@ -6635,6 +6944,8 @@ read_and_display_attr (attribute, form, data, cu_offset, pointer_size)
        case DW_ATE_signed_char:     printf ("(signed char)"); break;
        case DW_ATE_unsigned:        printf ("(unsigned)"); break;
        case DW_ATE_unsigned_char:   printf ("(unsigned char)"); break;
+         /* DWARF 2.1 value.  */
+       case DW_ATE_imaginary_float: printf ("(imaginary float)"); break;
        default:
          if (uvalue >= DW_ATE_lo_user
              && uvalue <= DW_ATE_hi_user)
@@ -6701,10 +7012,25 @@ read_and_display_attr (attribute, form, data, cu_offset, pointer_size)
        }
       break;
 
+    case DW_AT_ordering:
+      switch (uvalue)
+       {
+       case -1: printf ("(undefined)"); break;
+       case 0:  printf ("(row major)"); break;
+       case 1:  printf ("(column major)"); break;
+       }
+      break;
+
     case DW_AT_frame_base:
     case DW_AT_location:
     case DW_AT_data_member_location:
     case DW_AT_vtable_elem_location:
+    case DW_AT_allocated:
+    case DW_AT_associated:
+    case DW_AT_data_location:
+    case DW_AT_stride:
+    case DW_AT_upper_bound:
+    case DW_AT_lower_bound:
       if (block_start)
        {
          printf ("(");
@@ -6736,6 +7062,7 @@ display_debug_info (section, start, file)
     {
       DWARF2_External_CompUnit * external;
       DWARF2_Internal_CompUnit   compunit;
+      Elf32_Internal_Shdr *      relsec;
       unsigned char *            tags;
       int                        i;
       int                       level;
@@ -6748,6 +7075,68 @@ display_debug_info (section, start, file)
       compunit.cu_abbrev_offset = BYTE_GET (external->cu_abbrev_offset);
       compunit.cu_pointer_size  = BYTE_GET (external->cu_pointer_size);
 
+      /* Check for RELA relocations in the abbrev_offset address, and
+         apply them.  */
+      for (relsec = section_headers;
+          relsec < section_headers + elf_header.e_shnum;
+          ++relsec)
+       {
+         unsigned long nrelas, nsyms;
+         Elf_Internal_Rela *rela, *rp;
+         Elf32_Internal_Shdr *symsec;
+         Elf_Internal_Sym *symtab;
+         Elf_Internal_Sym *sym;
+
+         if (relsec->sh_type != SHT_RELA
+             || section_headers + relsec->sh_info != section)
+           continue;
+
+         if (!slurp_rela_relocs (file, relsec->sh_offset, relsec->sh_size,
+                                 & rela, & nrelas))
+           return 0;
+
+         symsec = section_headers + relsec->sh_link;
+         nsyms = symsec->sh_size / symsec->sh_entsize;
+         symtab = GET_ELF_SYMBOLS (file, symsec->sh_offset, nsyms);
+
+         for (rp = rela; rp < rela + nrelas; ++rp)
+           {
+             if (rp->r_offset
+                 != (bfd_vma) ((unsigned char *) &external->cu_abbrev_offset
+                               - section_begin))
+               continue;
+             
+             if (is_32bit_elf)
+               {
+                 sym = symtab + ELF32_R_SYM (rp->r_info);
+
+                 if (ELF32_ST_TYPE (sym->st_info) != STT_SECTION)
+                   {
+                     warn (_("Skipping unexpected symbol type %u"),
+                           ELF32_ST_TYPE (sym->st_info));
+                     continue;
+                   }
+               }
+             else
+               {
+                 sym = symtab + ELF64_R_SYM (rp->r_info);
+
+                 if (ELF64_ST_TYPE (sym->st_info) != STT_SECTION)
+                   {
+                     warn (_("Skipping unexpected symbol type %u"),
+                           ELF64_ST_TYPE (sym->st_info));
+                     continue;
+                   }
+               }
+
+             compunit.cu_abbrev_offset += rp->r_addend;
+             break;
+           }
+
+         free (rela);
+         break;
+       }
+
       tags = start + sizeof (* external);
       cu_offset = start - section_begin;
       start += compunit.cu_length + sizeof (external->cu_length);
@@ -6786,8 +7175,11 @@ display_debug_info (section, start, file)
            return 0;
          }
 
-       GET_DATA_ALLOC (sec->sh_offset, sec->sh_size, begin, unsigned char *,
-                       "debug_abbrev section data");
+       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);
@@ -6827,8 +7219,9 @@ display_debug_info (section, start, file)
              return 0;
            }
 
-         printf (_(" <%d><%x>: Abbrev Number: %lu (%s)\n"),
-                 level, tags - section_begin - bytes_read,
+         printf (_(" <%d><%lx>: Abbrev Number: %lu (%s)\n"),
+                 level,
+                 (unsigned long) (tags - section_begin - bytes_read),
                  abbrev_number,
                  get_TAG_name (entry->tag));
 
@@ -6931,12 +7324,13 @@ typedef struct Frame_Chunk
   int *                col_offset;
   char *               augmentation;
   unsigned int         code_factor;
-  unsigned int         data_factor;
+  int                  data_factor;
   unsigned long        pc_begin;
   unsigned long        pc_range;
   int                  cfa_reg;
   int                  cfa_offset;
   int                  ra;
+  unsigned char        fde_encoding;
 }
 Frame_Chunk;
 
@@ -6944,6 +7338,10 @@ Frame_Chunk;
    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;
@@ -6998,7 +7396,7 @@ frame_display_row (fc, need_col_headers, max_regs)
       printf ("\n");
     }
 
-  printf ("%08x ", (unsigned int) fc->pc_begin);
+  printf ("%08lx ", fc->pc_begin);
   sprintf (tmp, "r%d%+d", fc->cfa_reg, fc->cfa_offset);
   printf ("%-8s ", tmp);
 
@@ -7030,6 +7428,20 @@ frame_display_row (fc, need_col_headers, max_regs)
   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
@@ -7048,6 +7460,7 @@ display_debug_frames (section, start, file)
   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));
 
@@ -7060,6 +7473,9 @@ display_debug_frames (section, start, file)
       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;
 
       saved_start = start;
       length = byte_get (start, 4); start += 4;
@@ -7070,10 +7486,10 @@ display_debug_frames (section, start, file)
       block_end = saved_start + length + 4;
       cie_id = byte_get (start, 4); start += 4;
 
-      printf ("\n%08x %08lx %08lx ", saved_start - section_start, length, cie_id);
-
       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));
 
@@ -7085,27 +7501,23 @@ display_debug_frames (section, start, file)
          fc->col_offset = (int *) xmalloc (sizeof (int));
          frame_need_space (fc, max_regs-1);
 
-         start ++; /* version */
-         fc->augmentation = start;
-
-         while (* start)
-           start++;
+         version = *start++;
 
-         start++; /* skip past NUL */
+         fc->augmentation = start;
+         start = strchr (start, '\0') + 1;
 
          if (fc->augmentation[0] == 'z')
            {
-             int xtra;
              fc->code_factor = LEB ();
              fc->data_factor = SLEB ();
              fc->ra = byte_get (start, 1); start += 1;
-             xtra = LEB ();
-             printf ("skipping %d extra bytes\n", xtra);
-             start += xtra;
+             augmentation_data_len = LEB ();
+             augmentation_data = start;
+             start += augmentation_data_len;
            }
          else if (strcmp (fc->augmentation, "eh") == 0)
            {
-             start += 4;
+             start += addr_size;
              fc->code_factor = LEB ();
              fc->data_factor = SLEB ();
              fc->ra = byte_get (start, 1); start += 1;
@@ -7117,8 +7529,55 @@ display_debug_frames (section, start, file)
              fc->ra = byte_get (start, 1); start += 1;
            }
          cie = fc;
-         printf ("CIE \"%s\" cf=%d df=%d ra=%d\n",
-                 fc->augmentation, fc->code_factor, fc->data_factor, fc->ra);
+
+         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);
        }
@@ -7130,15 +7589,16 @@ display_debug_frames (section, start, file)
          fc = & fde_fc;
          memset (fc, 0, sizeof (Frame_Chunk));
 
-         look_for = is_eh ? start-4-cie_id : (unsigned char *) cie_id;
+         look_for = is_eh ? start - 4 - cie_id : section_start + cie_id;
 
-         fc->pc_begin = byte_get (start, 4); start += 4;
-         fc->pc_range = byte_get (start, 4); start += 4;
+         for (cie=chunks; cie ; cie = cie->next)
+           if (cie->chunk_start == look_for)
+             break;
 
-         for (cie=chunks; cie && (cie->chunk_start != look_for); cie = cie->next);
          if (!cie)
            {
-             warn ("Invalid CIE pointer %08x in FDE at %08x\n", cie_id, saved_start);
+             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));
@@ -7146,6 +7606,7 @@ display_debug_frames (section, start, file)
              frame_need_space (fc, max_regs - 1);
              cie = fc;
              fc->augmentation = "";
+             fc->fde_encoding = 0;
            }
          else
            {
@@ -7161,25 +7622,43 @@ display_debug_frames (section, start, file)
              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);
+         start += encoded_ptr_size;
+         fc->pc_range = byte_get (start, encoded_ptr_size);
+         start += encoded_ptr_size;
+
          if (cie->augmentation[0] == 'z')
            {
-             unsigned long l = LEB ();
-             start += l;
+             augmentation_data_len = LEB ();
+             augmentation_data = start;
+             start += augmentation_data_len;
            }
 
-         printf ("FDE cie=%08x pc=%08lx..%08lx\n",
-                 cie->chunk_start-section_start, fc->pc_begin,
-                 fc->pc_begin + fc->pc_range);
+         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.  */
 
-      /* This exists for readelf maintainers.  */
-#define FDEBUG 0
-
+      if (do_debug_frames_interp)
       {
        /* Start by making a pass over the chunk, allocating storage
            and taking note of what registers are used.  */
@@ -7189,13 +7668,12 @@ display_debug_frames (section, start, file)
          {
            unsigned op, opa;
            unsigned long reg;
-           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 below.  */
            switch (op)
@@ -7212,7 +7690,7 @@ display_debug_frames (section, start, file)
                fc->col_type[opa] = DW_CFA_undefined;
                break;
              case DW_CFA_set_loc:
-               start += sizeof (vma);
+               start += encoded_ptr_size;
                break;
              case DW_CFA_advance_loc1:
                start += 1;
@@ -7262,15 +7740,15 @@ display_debug_frames (section, start, file)
 #endif
              case DW_CFA_GNU_args_size:
                LEB ();
-               break;          
+               break;
 #ifndef DW_CFA_GNU_negative_offset_extended
 #define DW_CFA_GNU_negative_offset_extended 0x2f
 #endif
              case DW_CFA_GNU_negative_offset_extended:
-               reg = LEB (); LEB ();      
+               reg = LEB (); LEB ();
                frame_need_space (fc, reg);
                fc->col_type[reg] = DW_CFA_undefined;
-               
+
              default:
                break;
              }
@@ -7298,103 +7776,104 @@ display_debug_frames (section, start, file)
          switch (op)
            {
            case DW_CFA_advance_loc:
-             frame_display_row (fc, &need_col_headers, &max_regs);
-#if FDEBUG
-             printf ("  DW_CFA_advance_loc: %08x = %08x + %d*%d\n",
-                     fc->pc_begin + opa * fc->code_factor, fc->pc_begin, opa, fc->code_factor);
-#endif
+             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 FDEBUG
-             printf ("  DW_CFA_offset: r%d = cfa[%d*%d]\n", opa, roffs, fc->data_factor);
-#endif
+             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 FDEBUG
-             printf ("  DW_CFA_restore: r%d\n", opa);
-#endif
+             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:
-             frame_display_row (fc, &need_col_headers, &max_regs);
-             vma = byte_get (start, sizeof (vma)); start += sizeof (vma);
-#if FDEBUG
-             printf ("  DW_CFA_set_loc: %08x\n", vma);
-#endif
+             vma = byte_get (start, encoded_ptr_size);
+             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:
-             frame_display_row (fc, &need_col_headers, &max_regs);
              ofs = byte_get (start, 1); start += 1;
-#if FDEBUG
-             printf ("  DW_CFA_advance_loc1: %08x = %08x + %d*%d\n",
-                     fc->pc_begin + ofs * fc->code_factor, fc->pc_begin, ofs, fc->code_factor);
-#endif
+             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:
-             frame_display_row (fc, &need_col_headers, &max_regs);
              ofs = byte_get (start, 2); start += 2;
-#if FDEBUG
-             printf ("  DW_CFA_advance_loc2: %08x = %08x + %d*%d\n",
-                     fc->pc_begin + ofs * fc->code_factor, fc->pc_begin, ofs, fc->code_factor);
-#endif
+             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:
-             frame_display_row (fc, &need_col_headers, &max_regs);
              ofs = byte_get (start, 4); start += 4;
-#if FDEBUG
-             printf ("  DW_CFA_advance_loc4: %08x = %08x + %d*%d\n",
-                     fc->pc_begin + ofs * fc->code_factor, fc->pc_begin, ofs, fc->code_factor);
-#endif
+             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 FDEBUG
-             printf ("  DW_CFA_offset_extended: r%d = cfa[%d*%d]\n", reg, roffs, fc->data_factor);
-#endif
+             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 FDEBUG
-             printf ("  DW_CFA_restore_extended: r%d\n", reg);
-#endif
+             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 FDEBUG
-             printf ("  DW_CFA_undefined: r%d\n", reg);
-#endif
+             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 FDEBUG
-             printf ("  DW_CFA_same_value: r%d\n", reg);
-#endif
+             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;
@@ -7402,17 +7881,15 @@ display_debug_frames (section, start, file)
            case DW_CFA_register:
              reg = LEB ();
              roffs = LEB ();
-#if FDEBUG
-             printf ("  DW_CFA_register: r%d\n", reg);
-#endif
+             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 FDEBUG
-             printf ("  DW_CFA_remember_state\n");
-#endif
+             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));
@@ -7424,9 +7901,8 @@ display_debug_frames (section, start, file)
              break;
 
            case DW_CFA_restore_state:
-#if FDEBUG
-             printf ("  DW_CFA_restore_state\n");
-#endif
+             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);
@@ -7440,60 +7916,49 @@ display_debug_frames (section, start, file)
            case DW_CFA_def_cfa:
              fc->cfa_reg = LEB ();
              fc->cfa_offset = LEB ();
-#if FDEBUG
-             printf ("  DW_CFA_def_cfa: reg %d ofs %d\n", fc->cfa_reg, fc->cfa_offset);
-#endif
+             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 ();
-#if FDEBUG
-             printf ("  DW_CFA_def_cfa_reg: %d\n", fc->cfa_reg);
-#endif
+             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 FDEBUG
-             printf ("  DW_CFA_def_cfa_offset: %d\n", fc->cfa_offset);
-#endif
+             if (! do_debug_frames_interp)
+               printf ("  DW_CFA_def_cfa_offset: %d\n", fc->cfa_offset);
              break;
 
            case DW_CFA_nop:
-#if FDEBUG
-             printf ("  DW_CFA_nop\n");
-#endif
+             if (! do_debug_frames_interp)
+               printf ("  DW_CFA_nop\n");
              break;
 
 #ifndef DW_CFA_GNU_window_save
 #define DW_CFA_GNU_window_save 0x2d
 #endif
            case DW_CFA_GNU_window_save:
-#if FDEBUG
-             printf ("  DW_CFA_GNU_window_save\n");
-#endif
+             if (! do_debug_frames_interp)
+               printf ("  DW_CFA_GNU_window_save\n");
              break;
 
-#ifndef DW_CFA_GNU_args_size
-#define DW_CFA_GNU_args_size 0x2e
-#endif
            case DW_CFA_GNU_args_size:
              ul = LEB ();
-#if FDEBUG
-             printf ("  DW_CFA_GNU_args_size: %d\n", ul);
-#endif
+             if (! do_debug_frames_interp)
+               printf ("  DW_CFA_GNU_args_size: %ld\n", ul);
              break;
 
-#ifndef DW_CFA_GNU_negative_offset_extended
-#define DW_CFA_GNU_negative_offset_extended 0x2f
-#endif
            case DW_CFA_GNU_negative_offset_extended:
              reg = LEB ();
              l = - LEB ();
              frame_need_space (fc, reg);
-#if FDEBUG
-             printf ("  DW_CFA_GNU_negative_offset_extended: r%d = cfa[%d*%d]\n", reg, l, fc->data_factor);
-#endif
+             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;
@@ -7504,7 +7969,8 @@ display_debug_frames (section, start, file)
            }
        }
 
-      frame_display_row (fc, &need_col_headers, &max_regs);
+      if (do_debug_frames_interp)
+        frame_display_row (fc, &need_col_headers, &max_regs);
 
       start = block_end;
     }
@@ -7566,8 +8032,7 @@ debug_displays[] =
   { ".debug_pubnames",    display_debug_pubnames, NULL },
   { ".debug_frame",       display_debug_frames, NULL },
   { ".eh_frame",          display_debug_frames, NULL },
-  { ".debug_macinfo",     display_debug_not_supported, NULL },
-  { ".debug_frame",       display_debug_not_supported, NULL },
+  { ".debug_macinfo",     display_debug_macinfo, NULL },
   { ".debug_str",         display_debug_not_supported, NULL },
   { ".debug_static_func", display_debug_not_supported, NULL },
   { ".debug_static_vars", display_debug_not_supported, NULL },
@@ -7592,12 +8057,14 @@ display_debug_section (section, file)
       return 0;
     }
 
-  GET_DATA_ALLOC (section->sh_offset, length, start, unsigned char *,
-                 "debug section data");
+  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";  
+    name = ".debug_info";
 
   for (i = NUM_ELEM (debug_displays); i--;)
     if (strcmp (debug_displays[i].name, name) == 0)
@@ -7624,7 +8091,7 @@ process_section_contents (file)
      FILE * file;
 {
   Elf32_Internal_Shdr * section;
-  unsigned int         i;
+  unsigned int i;
 
   if (! do_dump)
     return 1;
@@ -7652,8 +8119,11 @@ process_section_contents (file)
                unsigned char * start;
 
                length = section->sh_size;
-               GET_DATA_ALLOC (section->sh_offset, length, start, unsigned char *,
-                               "debug section data");
+               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);
@@ -7749,73 +8219,77 @@ process_mips_specific (file)
       Elf32_External_Lib * elib;
       size_t cnt;
 
-      GET_DATA_ALLOC (liblist_offset, liblistno * sizeof (Elf32_External_Lib),
-                     elib, Elf32_External_Lib *, "liblist");
-
-      printf ("\nSection '.liblist' contains %lu entries:\n",
-             (unsigned long) liblistno);
-      fputs ("     Library              Time Stamp          Checksum   Version Flags\n",
-            stdout);
-
-      for (cnt = 0; cnt < liblistno; ++cnt)
+      elib = ((Elf32_External_Lib *)
+             get_data (NULL, file, liblist_offset,
+                       liblistno * sizeof (Elf32_External_Lib),
+                       _("liblist")));
+      if (elib)
        {
-         Elf32_Lib liblist;
-         time_t time;
-         char timebuf[20];
-         struct tm * tmp;
-
-         liblist.l_name = BYTE_GET (elib[cnt].l_name);
-         time = BYTE_GET (elib[cnt].l_time_stamp);
-         liblist.l_checksum = BYTE_GET (elib[cnt].l_checksum);
-         liblist.l_version = BYTE_GET (elib[cnt].l_version);
-         liblist.l_flags = BYTE_GET (elib[cnt].l_flags);
-
-         tmp = gmtime (&time);
-         sprintf (timebuf, "%04u-%02u-%02uT%02u:%02u:%02u",
-                  tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
-                  tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
-
-         printf ("%3lu: %-20s %s %#10lx %-7ld", (unsigned long) cnt,
-                 dynamic_strings + liblist.l_name, timebuf,
-                 liblist.l_checksum, liblist.l_version);
-
-         if (liblist.l_flags == 0)
-           puts (" NONE");
-         else
+         printf ("\nSection '.liblist' contains %lu entries:\n",
+                 (unsigned long) liblistno);
+         fputs ("     Library              Time Stamp          Checksum   Version Flags\n",
+                stdout);
+
+         for (cnt = 0; cnt < liblistno; ++cnt)
            {
-             static const struct
-             {
-               const char * name;
-               int bit;
-             }
-             l_flags_vals[] =
-             {
-               { " EXACT_MATCH", LL_EXACT_MATCH },
-               { " IGNORE_INT_VER", LL_IGNORE_INT_VER },
-               { " REQUIRE_MINOR", LL_REQUIRE_MINOR },
-               { " EXPORTS", LL_EXPORTS },
-               { " DELAY_LOAD", LL_DELAY_LOAD },
-               { " DELTA", LL_DELTA }
-             };
-             int flags = liblist.l_flags;
-             size_t fcnt;
-
-             for (fcnt = 0;
-                  fcnt < sizeof (l_flags_vals) / sizeof (l_flags_vals[0]);
-                  ++fcnt)
-               if ((flags & l_flags_vals[fcnt].bit) != 0)
+             Elf32_Lib liblist;
+             time_t time;
+             char timebuf[20];
+             struct tm * tmp;
+
+             liblist.l_name = BYTE_GET (elib[cnt].l_name);
+             time = BYTE_GET (elib[cnt].l_time_stamp);
+             liblist.l_checksum = BYTE_GET (elib[cnt].l_checksum);
+             liblist.l_version = BYTE_GET (elib[cnt].l_version);
+             liblist.l_flags = BYTE_GET (elib[cnt].l_flags);
+
+             tmp = gmtime (&time);
+             sprintf (timebuf, "%04u-%02u-%02uT%02u:%02u:%02u",
+                      tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
+                      tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
+
+             printf ("%3lu: %-20s %s %#10lx %-7ld", (unsigned long) cnt,
+                     dynamic_strings + liblist.l_name, timebuf,
+                     liblist.l_checksum, liblist.l_version);
+
+             if (liblist.l_flags == 0)
+               puts (" NONE");
+             else
+               {
+                 static const struct
                  {
-                   fputs (l_flags_vals[fcnt].name, stdout);
-                   flags ^= l_flags_vals[fcnt].bit;
+                   const char * name;
+                   int bit;
                  }
-             if (flags != 0)
-               printf (" %#x", (unsigned int) flags);
+                 l_flags_vals[] =
+                 {
+                   { " EXACT_MATCH", LL_EXACT_MATCH },
+                   { " IGNORE_INT_VER", LL_IGNORE_INT_VER },
+                   { " REQUIRE_MINOR", LL_REQUIRE_MINOR },
+                   { " EXPORTS", LL_EXPORTS },
+                   { " DELAY_LOAD", LL_DELAY_LOAD },
+                   { " DELTA", LL_DELTA }
+                 };
+                 int flags = liblist.l_flags;
+                 size_t fcnt;
+
+                 for (fcnt = 0;
+                      fcnt < sizeof (l_flags_vals) / sizeof (l_flags_vals[0]);
+                      ++fcnt)
+                   if ((flags & l_flags_vals[fcnt].bit) != 0)
+                     {
+                       fputs (l_flags_vals[fcnt].name, stdout);
+                       flags ^= l_flags_vals[fcnt].bit;
+                     }
+                 if (flags != 0)
+                   printf (" %#x", (unsigned int) flags);
 
-             puts ("");
+                 puts ("");
+               }
            }
-       }
 
-      free (elib);
+         free (elib);
+       }
     }
 
   if (options_offset != 0)
@@ -7831,194 +8305,194 @@ process_mips_specific (file)
       while (sect->sh_type != SHT_MIPS_OPTIONS)
        ++ sect;
 
-      GET_DATA_ALLOC (options_offset, sect->sh_size, eopt,
-                     Elf_External_Options *, "options");
-
-      iopt = (Elf_Internal_Options *) malloc ((sect->sh_size / sizeof (eopt))
-                                             * sizeof (* iopt));
-      if (iopt == NULL)
+      eopt = (Elf_External_Options *) get_data (NULL, file, options_offset,
+                                               sect->sh_size, _("options"));
+      if (eopt)
        {
-         error (_("Out of memory"));
-         return 0;
-       }
-
-      offset = cnt = 0;
-      option = iopt;
+         iopt = ((Elf_Internal_Options *)
+                 malloc ((sect->sh_size / sizeof (eopt)) * sizeof (* iopt)));
+         if (iopt == NULL)
+           {
+             error (_("Out of memory"));
+             return 0;
+           }
 
-      while (offset < sect->sh_size)
-       {
-         Elf_External_Options * eoption;
+         offset = cnt = 0;
+         option = iopt;
 
-         eoption = (Elf_External_Options *) ((char *) eopt + offset);
+         while (offset < sect->sh_size)
+           {
+             Elf_External_Options * eoption;
 
-         option->kind = BYTE_GET (eoption->kind);
-         option->size = BYTE_GET (eoption->size);
-         option->section = BYTE_GET (eoption->section);
-         option->info = BYTE_GET (eoption->info);
+             eoption = (Elf_External_Options *) ((char *) eopt + offset);
 
-         offset += option->size;
+             option->kind = BYTE_GET (eoption->kind);
+             option->size = BYTE_GET (eoption->size);
+             option->section = BYTE_GET (eoption->section);
+             option->info = BYTE_GET (eoption->info);
 
-         ++option;
-         ++cnt;
-       }
+             offset += option->size;
 
-      printf (_("\nSection '%s' contains %d entries:\n"),
-             SECTION_NAME (sect), cnt);
+             ++option;
+             ++cnt;
+           }
 
-      option = iopt;
+         printf (_("\nSection '%s' contains %d entries:\n"),
+                 SECTION_NAME (sect), cnt);
 
-      while (cnt-- > 0)
-       {
-         size_t len;
+         option = iopt;
 
-         switch (option->kind)
+         while (cnt-- > 0)
            {
-           case ODK_NULL:
-             /* This shouldn't happen.  */
-             printf (" NULL       %d %lx", option->section, option->info);
-             break;
-           case ODK_REGINFO:
-             printf (" REGINFO    ");
-             if (elf_header.e_machine == EM_MIPS)
-               {
-                 /* 32bit form.  */
-                 Elf32_External_RegInfo * ereg;
-                 Elf32_RegInfo            reginfo;
-
-                 ereg = (Elf32_External_RegInfo *) (option + 1);
-                 reginfo.ri_gprmask = BYTE_GET (ereg->ri_gprmask);
-                 reginfo.ri_cprmask[0] = BYTE_GET (ereg->ri_cprmask[0]);
-                 reginfo.ri_cprmask[1] = BYTE_GET (ereg->ri_cprmask[1]);
-                 reginfo.ri_cprmask[2] = BYTE_GET (ereg->ri_cprmask[2]);
-                 reginfo.ri_cprmask[3] = BYTE_GET (ereg->ri_cprmask[3]);
-                 reginfo.ri_gp_value = BYTE_GET (ereg->ri_gp_value);
-
-                 printf ("GPR %08lx  GP 0x%lx\n",
-                         reginfo.ri_gprmask,
-                         (unsigned long) reginfo.ri_gp_value);
-                 printf ("            CPR0 %08lx  CPR1 %08lx  CPR2 %08lx  CPR3 %08lx\n",
-                         reginfo.ri_cprmask[0], reginfo.ri_cprmask[1],
-                         reginfo.ri_cprmask[2], reginfo.ri_cprmask[3]);
-               }
-             else
+             size_t len;
+
+             switch (option->kind)
                {
-                 /* 64 bit form.  */
-                 Elf64_External_RegInfo * ereg;
-                 Elf64_Internal_RegInfo reginfo;
-
-                 ereg = (Elf64_External_RegInfo *) (option + 1);
-                 reginfo.ri_gprmask    = BYTE_GET (ereg->ri_gprmask);
-                 reginfo.ri_cprmask[0] = BYTE_GET (ereg->ri_cprmask[0]);
-                 reginfo.ri_cprmask[1] = BYTE_GET (ereg->ri_cprmask[1]);
-                 reginfo.ri_cprmask[2] = BYTE_GET (ereg->ri_cprmask[2]);
-                 reginfo.ri_cprmask[3] = BYTE_GET (ereg->ri_cprmask[3]);
-                 reginfo.ri_gp_value   = BYTE_GET8 (ereg->ri_gp_value);
-
-                 printf ("GPR %08lx  GP 0x",
-                         reginfo.ri_gprmask);
-                 printf_vma (reginfo.ri_gp_value);
-                 printf ("\n");
-
-                 printf ("            CPR0 %08lx  CPR1 %08lx  CPR2 %08lx  CPR3 %08lx\n",
-                         reginfo.ri_cprmask[0], reginfo.ri_cprmask[1],
-                         reginfo.ri_cprmask[2], reginfo.ri_cprmask[3]);
+               case ODK_NULL:
+                 /* This shouldn't happen.  */
+                 printf (" NULL       %d %lx", option->section, option->info);
+                 break;
+               case ODK_REGINFO:
+                 printf (" REGINFO    ");
+                 if (elf_header.e_machine == EM_MIPS)
+                   {
+                     /* 32bit form.  */
+                     Elf32_External_RegInfo * ereg;
+                     Elf32_RegInfo            reginfo;
+
+                     ereg = (Elf32_External_RegInfo *) (option + 1);
+                     reginfo.ri_gprmask = BYTE_GET (ereg->ri_gprmask);
+                     reginfo.ri_cprmask[0] = BYTE_GET (ereg->ri_cprmask[0]);
+                     reginfo.ri_cprmask[1] = BYTE_GET (ereg->ri_cprmask[1]);
+                     reginfo.ri_cprmask[2] = BYTE_GET (ereg->ri_cprmask[2]);
+                     reginfo.ri_cprmask[3] = BYTE_GET (ereg->ri_cprmask[3]);
+                     reginfo.ri_gp_value = BYTE_GET (ereg->ri_gp_value);
+
+                     printf ("GPR %08lx  GP 0x%lx\n",
+                             reginfo.ri_gprmask,
+                             (unsigned long) reginfo.ri_gp_value);
+                     printf ("            CPR0 %08lx  CPR1 %08lx  CPR2 %08lx  CPR3 %08lx\n",
+                             reginfo.ri_cprmask[0], reginfo.ri_cprmask[1],
+                             reginfo.ri_cprmask[2], reginfo.ri_cprmask[3]);
+                   }
+                 else
+                   {
+                     /* 64 bit form.  */
+                     Elf64_External_RegInfo * ereg;
+                     Elf64_Internal_RegInfo reginfo;
+
+                     ereg = (Elf64_External_RegInfo *) (option + 1);
+                     reginfo.ri_gprmask    = BYTE_GET (ereg->ri_gprmask);
+                     reginfo.ri_cprmask[0] = BYTE_GET (ereg->ri_cprmask[0]);
+                     reginfo.ri_cprmask[1] = BYTE_GET (ereg->ri_cprmask[1]);
+                     reginfo.ri_cprmask[2] = BYTE_GET (ereg->ri_cprmask[2]);
+                     reginfo.ri_cprmask[3] = BYTE_GET (ereg->ri_cprmask[3]);
+                     reginfo.ri_gp_value   = BYTE_GET8 (ereg->ri_gp_value);
+
+                     printf ("GPR %08lx  GP 0x",
+                             reginfo.ri_gprmask);
+                     printf_vma (reginfo.ri_gp_value);
+                     printf ("\n");
+
+                     printf ("            CPR0 %08lx  CPR1 %08lx  CPR2 %08lx  CPR3 %08lx\n",
+                             reginfo.ri_cprmask[0], reginfo.ri_cprmask[1],
+                             reginfo.ri_cprmask[2], reginfo.ri_cprmask[3]);
+                   }
+                 ++option;
+                 continue;
+               case ODK_EXCEPTIONS:
+                 fputs (" EXCEPTIONS fpe_min(", stdout);
+                 process_mips_fpe_exception (option->info & OEX_FPU_MIN);
+                 fputs (") fpe_max(", stdout);
+                 process_mips_fpe_exception ((option->info & OEX_FPU_MAX) >> 8);
+                 fputs (")", stdout);
+
+                 if (option->info & OEX_PAGE0)
+                   fputs (" PAGE0", stdout);
+                 if (option->info & OEX_SMM)
+                   fputs (" SMM", stdout);
+                 if (option->info & OEX_FPDBUG)
+                   fputs (" FPDBUG", stdout);
+                 if (option->info & OEX_DISMISS)
+                   fputs (" DISMISS", stdout);
+                 break;
+               case ODK_PAD:
+                 fputs (" PAD       ", stdout);
+                 if (option->info & OPAD_PREFIX)
+                   fputs (" PREFIX", stdout);
+                 if (option->info & OPAD_POSTFIX)
+                   fputs (" POSTFIX", stdout);
+                 if (option->info & OPAD_SYMBOL)
+                   fputs (" SYMBOL", stdout);
+                 break;
+               case ODK_HWPATCH:
+                 fputs (" HWPATCH   ", stdout);
+                 if (option->info & OHW_R4KEOP)
+                   fputs (" R4KEOP", stdout);
+                 if (option->info & OHW_R8KPFETCH)
+                   fputs (" R8KPFETCH", stdout);
+                 if (option->info & OHW_R5KEOP)
+                   fputs (" R5KEOP", stdout);
+                 if (option->info & OHW_R5KCVTL)
+                   fputs (" R5KCVTL", stdout);
+                 break;
+               case ODK_FILL:
+                 fputs (" FILL       ", stdout);
+                 /* XXX Print content of info word?  */
+                 break;
+               case ODK_TAGS:
+                 fputs (" TAGS       ", stdout);
+                 /* XXX Print content of info word?  */
+                 break;
+               case ODK_HWAND:
+                 fputs (" HWAND     ", stdout);
+                 if (option->info & OHWA0_R4KEOP_CHECKED)
+                   fputs (" R4KEOP_CHECKED", stdout);
+                 if (option->info & OHWA0_R4KEOP_CLEAN)
+                   fputs (" R4KEOP_CLEAN", stdout);
+                 break;
+               case ODK_HWOR:
+                 fputs (" HWOR      ", stdout);
+                 if (option->info & OHWA0_R4KEOP_CHECKED)
+                   fputs (" R4KEOP_CHECKED", stdout);
+                 if (option->info & OHWA0_R4KEOP_CLEAN)
+                   fputs (" R4KEOP_CLEAN", stdout);
+                 break;
+               case ODK_GP_GROUP:
+                 printf (" GP_GROUP  %#06lx  self-contained %#06lx",
+                         option->info & OGP_GROUP,
+                         (option->info & OGP_SELF) >> 16);
+                 break;
+               case ODK_IDENT:
+                 printf (" IDENT     %#06lx  self-contained %#06lx",
+                         option->info & OGP_GROUP,
+                         (option->info & OGP_SELF) >> 16);
+                 break;
+               default:
+                 /* This shouldn't happen.  */
+                 printf (" %3d ???     %d %lx",
+                         option->kind, option->section, option->info);
+                 break;
                }
+
+             len = sizeof (* eopt);
+             while (len < option->size)
+               if (((char *) option)[len] >= ' '
+                   && ((char *) option)[len] < 0x7f)
+                 printf ("%c", ((char *) option)[len++]);
+               else
+                 printf ("\\%03o", ((char *) option)[len++]);
+
+             fputs ("\n", stdout);
              ++option;
-             continue;
-           case ODK_EXCEPTIONS:
-             fputs (" EXCEPTIONS fpe_min(", stdout);
-             process_mips_fpe_exception (option->info & OEX_FPU_MIN);
-             fputs (") fpe_max(", stdout);
-             process_mips_fpe_exception ((option->info & OEX_FPU_MAX) >> 8);
-             fputs (")", stdout);
-
-             if (option->info & OEX_PAGE0)
-               fputs (" PAGE0", stdout);
-             if (option->info & OEX_SMM)
-               fputs (" SMM", stdout);
-             if (option->info & OEX_FPDBUG)
-               fputs (" FPDBUG", stdout);
-             if (option->info & OEX_DISMISS)
-               fputs (" DISMISS", stdout);
-             break;
-           case ODK_PAD:
-             fputs (" PAD       ", stdout);
-             if (option->info & OPAD_PREFIX)
-               fputs (" PREFIX", stdout);
-             if (option->info & OPAD_POSTFIX)
-               fputs (" POSTFIX", stdout);
-             if (option->info & OPAD_SYMBOL)
-               fputs (" SYMBOL", stdout);
-             break;
-           case ODK_HWPATCH:
-             fputs (" HWPATCH   ", stdout);
-             if (option->info & OHW_R4KEOP)
-               fputs (" R4KEOP", stdout);
-             if (option->info & OHW_R8KPFETCH)
-               fputs (" R8KPFETCH", stdout);
-             if (option->info & OHW_R5KEOP)
-               fputs (" R5KEOP", stdout);
-             if (option->info & OHW_R5KCVTL)
-               fputs (" R5KCVTL", stdout);
-             break;
-           case ODK_FILL:
-             fputs (" FILL       ", stdout);
-             /* XXX Print content of info word?  */
-             break;
-           case ODK_TAGS:
-             fputs (" TAGS       ", stdout);
-             /* XXX Print content of info word?  */
-             break;
-           case ODK_HWAND:
-             fputs (" HWAND     ", stdout);
-             if (option->info & OHWA0_R4KEOP_CHECKED)
-               fputs (" R4KEOP_CHECKED", stdout);
-             if (option->info & OHWA0_R4KEOP_CLEAN)
-               fputs (" R4KEOP_CLEAN", stdout);
-             break;
-           case ODK_HWOR:
-             fputs (" HWOR      ", stdout);
-             if (option->info & OHWA0_R4KEOP_CHECKED)
-               fputs (" R4KEOP_CHECKED", stdout);
-             if (option->info & OHWA0_R4KEOP_CLEAN)
-               fputs (" R4KEOP_CLEAN", stdout);
-             break;
-           case ODK_GP_GROUP:
-             printf (" GP_GROUP  %#06lx  self-contained %#06lx",
-                     option->info & OGP_GROUP,
-                     (option->info & OGP_SELF) >> 16);
-             break;
-           case ODK_IDENT:
-             printf (" IDENT     %#06lx  self-contained %#06lx",
-                     option->info & OGP_GROUP,
-                     (option->info & OGP_SELF) >> 16);
-             break;
-           default:
-             /* This shouldn't happen.  */
-             printf (" %3d ???     %d %lx",
-                     option->kind, option->section, option->info);
-             break;
            }
 
-         len = sizeof (* eopt);
-         while (len < option->size)
-           if (((char *) option)[len] >= ' '
-               && ((char *) option)[len] < 0x7f)
-             printf ("%c", ((char *) option)[len++]);
-           else
-             printf ("\\%03o", ((char *) option)[len++]);
-
-         fputs ("\n", stdout);
-         ++option;
+         free (eopt);
        }
-
-      free (eopt);
     }
 
   if (conflicts_offset != 0 && conflictsno != 0)
     {
-      Elf32_External_Conflict * econf32;
-      Elf64_External_Conflict * econf64;
       Elf32_Conflict * iconf;
       size_t cnt;
 
@@ -8037,22 +8511,39 @@ process_mips_specific (file)
 
       if (is_32bit_elf)
        {
-         GET_DATA_ALLOC (conflicts_offset, conflictsno * sizeof (* econf32),
-                         econf32, Elf32_External_Conflict *, "conflict");
+         Elf32_External_Conflict * econf32;
+
+         econf32 = ((Elf32_External_Conflict *)
+                    get_data (NULL, file, conflicts_offset,
+                              conflictsno * sizeof (* econf32),
+                              _("conflict")));
+         if (!econf32)
+           return 0;
 
          for (cnt = 0; cnt < conflictsno; ++cnt)
            iconf[cnt] = BYTE_GET (econf32[cnt]);
+
+         free (econf32);
        }
       else
        {
-         GET_DATA_ALLOC (conflicts_offset, conflictsno * sizeof (* econf64),
-                         econf64, Elf64_External_Conflict *, "conflict");
+         Elf64_External_Conflict * econf64;
+
+         econf64 = ((Elf64_External_Conflict *)
+                    get_data (NULL, file, conflicts_offset,
+                              conflictsno * sizeof (* econf64),
+                              _("conflict")));
+         if (!econf64)
+           return 0;
 
          for (cnt = 0; cnt < conflictsno; ++cnt)
            iconf[cnt] = BYTE_GET (econf64[cnt]);
+
+         free (econf64);
        }
 
-      printf (_("\nSection '.conflict' contains %d entries:\n"), conflictsno);
+      printf (_("\nSection '.conflict' contains %ld entries:\n"),
+             (long) conflictsno);
       puts (_("  Num:    Index       Value  Name"));
 
       for (cnt = 0; cnt < conflictsno; ++cnt)
@@ -8106,7 +8597,7 @@ process_note (pnote)
 {
   printf ("  %s\t\t0x%08lx\t%s\n",
          pnote->namesz ? pnote->namedata : "(NONE)",
-         pnote->descsz, get_note_type (pnote->type));
+         pnote->descsz, get_note_type (pnote->type));
   return 1;
 }
 
@@ -8124,7 +8615,10 @@ process_corefile_note_segment (file, offset, length)
   if (length <= 0)
     return 0;
 
-  GET_DATA_ALLOC (offset, length, pnotes, Elf_External_Note *, "notes");
+  pnotes = (Elf_External_Note *) get_data (NULL, file, offset, length,
+                                          _("notes"));
+  if (!pnotes)
+    return 0;
 
   external = pnotes;
 
@@ -8258,7 +8752,7 @@ process_arch_specific (file)
   switch (elf_header.e_machine)
     {
     case EM_MIPS:
-    case EM_MIPS_RS4_BE:
+    case EM_MIPS_RS3_LE:
       return process_mips_specific (file);
       break;
     default:
@@ -8345,7 +8839,7 @@ get_file_header (file)
   return 1;
 }
 
-static void
+static int
 process_file (file_name)
      char * file_name;
 {
@@ -8356,21 +8850,21 @@ process_file (file_name)
   if (stat (file_name, & statbuf) < 0)
     {
       error (_("Cannot stat input file %s.\n"), file_name);
-      return;
+      return 1;
     }
 
   file = fopen (file_name, "rb");
   if (file == NULL)
     {
       error (_("Input file %s not found.\n"), file_name);
-      return;
+      return 1;
     }
 
   if (! get_file_header (file))
     {
       error (_("%s: Failed to read file header\n"), file_name);
       fclose (file);
-      return;
+      return 1;
     }
 
   /* Initialise per file variables.  */
@@ -8387,7 +8881,7 @@ process_file (file_name)
   if (! process_file_header ())
     {
       fclose (file);
-      return;
+      return 1;
     }
 
   process_section_headers (file);
@@ -8445,6 +8939,8 @@ process_file (file_name)
       free (dynamic_syminfo);
       dynamic_syminfo = NULL;
     }
+
+  return 0;
 }
 
 #ifdef SUPPORT_DISASSEMBLY
@@ -8471,6 +8967,8 @@ main (argc, argv)
      int     argc;
      char ** argv;
 {
+  int err;
+
 #if defined (HAVE_SETLOCALE) && defined (HAVE_LC_MESSAGES)
   setlocale (LC_MESSAGES, "");
 #endif
@@ -8482,11 +8980,12 @@ main (argc, argv)
   if (optind < (argc - 1))
     show_name = 1;
 
+  err = 0;
   while (optind < argc)
-    process_file (argv [optind ++]);
+    err |= process_file (argv [optind ++]);
 
   if (dump_sects != NULL)
     free (dump_sects);
 
-  return 0;
+  return err;
 }