Fix typo in previous patch.
[deliverable/binutils-gdb.git] / binutils / readelf.c
index c1a52db7ffa426c81c3b8166752b45266b00c07a..fb8d80f83739589368c3042465e756a8d481971f 100644 (file)
 #include "elf/iq2000.h"
 #include "elf/xtensa.h"
 
+#include "aout/ar.h"
+
 #include "bucomm.h"
 #include "getopt.h"
 #include "libiberty.h"
 
 char *program_name = "readelf";
+long archive_file_offset;
+unsigned long archive_file_size;
 unsigned long dynamic_addr;
 bfd_size_type dynamic_size;
 char *dynamic_strings;
@@ -106,11 +110,11 @@ Elf_Internal_Syminfo *dynamic_syminfo;
 unsigned long dynamic_syminfo_offset;
 unsigned int dynamic_syminfo_nent;
 char program_interpreter[64];
-long dynamic_info[DT_JMPREL + 1];
-long version_info[16];
-long loadaddr = 0;
+bfd_vma dynamic_info[DT_JMPREL + 1];
+bfd_vma version_info[16];
 Elf_Internal_Ehdr elf_header;
 Elf_Internal_Shdr *section_headers;
+Elf_Internal_Phdr *program_headers;
 Elf_Internal_Dyn *dynamic_segment;
 Elf_Internal_Shdr *symtab_shndx_hdr;
 int show_name;
@@ -162,234 +166,8 @@ typedef enum print_mode
 }
 print_mode;
 
-/* Forward declarations for dumb compilers.  */
-static void print_vma
-  PARAMS ((bfd_vma, print_mode));
-static void print_symbol
-  PARAMS ((int, const char *));
-static bfd_vma (*byte_get)
-  PARAMS ((unsigned char *, int));
-static bfd_vma byte_get_little_endian
-  PARAMS ((unsigned char *, int));
-static bfd_vma byte_get_big_endian
-  PARAMS ((unsigned char *, int));
-static void (*byte_put)
-  PARAMS ((unsigned char *, bfd_vma, int));
-static void byte_put_little_endian
-  PARAMS ((unsigned char *, bfd_vma, int));
-static void byte_put_big_endian
-  PARAMS ((unsigned char *, bfd_vma, int));
-static const char *get_mips_dynamic_type
-  PARAMS ((unsigned long));
-static const char *get_sparc64_dynamic_type
-  PARAMS ((unsigned long));
-static const char *get_ppc64_dynamic_type
-  PARAMS ((unsigned long));
-static const char *get_parisc_dynamic_type
-  PARAMS ((unsigned long));
-static const char *get_ia64_dynamic_type
-  PARAMS ((unsigned long));
-static const char *get_dynamic_type
-  PARAMS ((unsigned long));
-static int slurp_rela_relocs
-  PARAMS ((FILE *, unsigned long, unsigned long, Elf_Internal_Rela **,
-          unsigned long *));
-static int slurp_rel_relocs
-  PARAMS ((FILE *, unsigned long, unsigned long, Elf_Internal_Rela **,
-          unsigned long *));
-static int dump_relocations
-  PARAMS ((FILE *, unsigned long, unsigned long, Elf_Internal_Sym *,
-          unsigned long, char *, int));
-static char *get_file_type
-  PARAMS ((unsigned));
-static char *get_machine_name
-  PARAMS ((unsigned));
-static void decode_ARM_machine_flags
-  PARAMS ((unsigned, char[]));
-static char *get_machine_flags
-  PARAMS ((unsigned, unsigned));
-static const char *get_mips_segment_type
-  PARAMS ((unsigned long));
-static const char *get_parisc_segment_type
-  PARAMS ((unsigned long));
-static const char *get_ia64_segment_type
-  PARAMS ((unsigned long));
-static const char *get_segment_type
-  PARAMS ((unsigned long));
-static const char *get_mips_section_type_name
-  PARAMS ((unsigned int));
-static const char *get_parisc_section_type_name
-  PARAMS ((unsigned int));
-static const char *get_ia64_section_type_name
-  PARAMS ((unsigned int));
-static const char *get_section_type_name
-  PARAMS ((unsigned int));
-static const char *get_symbol_binding
-  PARAMS ((unsigned int));
-static const char *get_symbol_type
-  PARAMS ((unsigned int));
-static const char *get_symbol_visibility
-  PARAMS ((unsigned int));
-static const char *get_symbol_index_type
-  PARAMS ((unsigned int));
-static const char *get_dynamic_flags
-  PARAMS ((bfd_vma));
-static void usage
-  PARAMS ((void));
-static void parse_args
-  PARAMS ((int, char **));
-static int process_file_header
-  PARAMS ((void));
-static int process_program_headers
-  PARAMS ((FILE *));
-static int process_section_headers
-  PARAMS ((FILE *));
-static int process_unwind
-  PARAMS ((FILE *));
-static void dynamic_segment_mips_val
-  PARAMS ((Elf_Internal_Dyn *));
-static void dynamic_segment_parisc_val
-  PARAMS ((Elf_Internal_Dyn *));
-static void dynamic_segment_ia64_val
-  PARAMS ((Elf_Internal_Dyn *));
-static int process_dynamic_segment
-  PARAMS ((FILE *));
-static int process_symbol_table
-  PARAMS ((FILE *));
-static int process_syminfo
-  PARAMS ((FILE *));
-static int process_section_contents
-  PARAMS ((FILE *));
-static 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));
-static int get_32bit_section_headers
-  PARAMS ((FILE *, unsigned int));
-static int get_64bit_section_headers
-  PARAMS ((FILE *, unsigned int));
-static int get_32bit_program_headers
-  PARAMS ((FILE *, Elf_Internal_Phdr *));
-static int get_64bit_program_headers
-  PARAMS ((FILE *, Elf_Internal_Phdr *));
-static int get_file_header
-  PARAMS ((FILE *));
-static Elf_Internal_Sym *get_32bit_elf_symbols
-  PARAMS ((FILE *, Elf_Internal_Shdr *));
-static Elf_Internal_Sym *get_64bit_elf_symbols
-  PARAMS ((FILE *, Elf_Internal_Shdr *));
-static const char *get_elf_section_flags
-  PARAMS ((bfd_vma));
-static int *get_dynamic_data
-  PARAMS ((FILE *, unsigned int));
-static int get_32bit_dynamic_segment
-  PARAMS ((FILE *));
-static int get_64bit_dynamic_segment
-  PARAMS ((FILE *));
-#ifdef SUPPORT_DISASSEMBLY
-static int disassemble_section
-  PARAMS ((Elf_Internal_Shdr *, FILE *));
-#endif
-static int dump_section
-  PARAMS ((Elf_Internal_Shdr *, FILE *));
-static int display_debug_section
-  PARAMS ((Elf_Internal_Shdr *, FILE *));
-static int display_debug_info
-  PARAMS ((Elf_Internal_Shdr *, unsigned char *, FILE *));
-static int display_debug_not_supported
-  PARAMS ((Elf_Internal_Shdr *, unsigned char *, FILE *));
-static int prescan_debug_info
-  PARAMS ((Elf_Internal_Shdr *, unsigned char *, FILE *));
-static int display_debug_lines
-  PARAMS ((Elf_Internal_Shdr *, unsigned char *, FILE *));
-static int display_debug_pubnames
-  PARAMS ((Elf_Internal_Shdr *, unsigned char *, FILE *));
-static int display_debug_abbrev
-  PARAMS ((Elf_Internal_Shdr *, unsigned char *, FILE *));
-static int display_debug_aranges
-  PARAMS ((Elf_Internal_Shdr *, unsigned char *, FILE *));
-static int display_debug_frames
-  PARAMS ((Elf_Internal_Shdr *, unsigned char *, FILE *));
-static int display_debug_macinfo
-  PARAMS ((Elf_Internal_Shdr *, unsigned char *, FILE *));
-static int display_debug_str
-  PARAMS ((Elf_Internal_Shdr *, unsigned char *, FILE *));
-static int display_debug_loc
-  PARAMS ((Elf_Internal_Shdr *, unsigned char *, FILE *));
-static unsigned char *process_abbrev_section
-  PARAMS ((unsigned char *, unsigned char *));
-static void load_debug_str
-  PARAMS ((FILE *));
-static void free_debug_str
-  PARAMS ((void));
-static const char *fetch_indirect_string
-  PARAMS ((unsigned long));
-static void load_debug_loc
-  PARAMS ((FILE *));
-static void free_debug_loc
-  PARAMS ((void));
-static unsigned long read_leb128
-  PARAMS ((unsigned char *, int *, int));
-static int process_extended_line_op
-  PARAMS ((unsigned char *, int, int));
-static void reset_state_machine
-  PARAMS ((int));
-static char *get_TAG_name
-  PARAMS ((unsigned long));
-static char *get_AT_name
-  PARAMS ((unsigned long));
-static char *get_FORM_name
-  PARAMS ((unsigned long));
-static void free_abbrevs
-  PARAMS ((void));
-static void add_abbrev
-  PARAMS ((unsigned long, unsigned long, int));
-static void add_abbrev_attr
-  PARAMS ((unsigned long, unsigned long));
-static unsigned char *read_and_display_attr
-  PARAMS ((unsigned long, unsigned long, unsigned char *, unsigned long,
-          unsigned long, unsigned long, int));
-static unsigned char *read_and_display_attr_value
-  PARAMS ((unsigned long, unsigned long, unsigned char *, unsigned long,
-          unsigned long, unsigned long, int));
-static unsigned char *display_block
-  PARAMS ((unsigned char *, unsigned long));
-static void decode_location_expression
-  PARAMS ((unsigned char *, unsigned int, unsigned long));
-static void request_dump
-  PARAMS ((unsigned int, int));
-static const char *get_elf_class
-  PARAMS ((unsigned int));
-static const char *get_data_encoding
-  PARAMS ((unsigned int));
-static const char *get_osabi_name
-  PARAMS ((unsigned int));
-static int guess_is_rela
-  PARAMS ((unsigned long));
-static const char *get_note_type
-  PARAMS ((unsigned int));
-static const char *get_netbsd_elfcore_note_type
-  PARAMS ((unsigned int));
-static int process_note
-  PARAMS ((Elf_Internal_Note *));
-static int process_corefile_note_segment
-  PARAMS ((FILE *, bfd_vma, bfd_vma));
-static int process_corefile_note_segments
-  PARAMS ((FILE *));
-static int process_corefile_contents
-  PARAMS ((FILE *));
-static int process_arch_specific
-  PARAMS ((FILE *));
-static int process_gnu_liblist
-  PARAMS ((FILE *));
+static bfd_vma (*byte_get) (unsigned char *, int);
+static void (*byte_put) (unsigned char *, bfd_vma, int);
 
 typedef int Elf32_Word;
 
@@ -441,56 +219,50 @@ typedef int Elf32_Word;
 
 
 static void
-error VPARAMS ((const char *message, ...))
+error (const char *message, ...)
 {
-  VA_OPEN (args, message);
-  VA_FIXEDARG (args, const char *, message);
+  va_list args;
 
+  va_start (args, message);
   fprintf (stderr, _("%s: Error: "), program_name);
   vfprintf (stderr, message, args);
-  VA_CLOSE (args);
+  va_end (args);
 }
 
 static void
-warn VPARAMS ((const char *message, ...))
+warn (const char *message, ...)
 {
-  VA_OPEN (args, message);
-  VA_FIXEDARG (args, const char *, message);
+  va_list args;
 
+  va_start (args, message);
   fprintf (stderr, _("%s: Warning: "), program_name);
   vfprintf (stderr, message, args);
-  VA_CLOSE (args);
+  va_end (args);
 }
 
-static PTR get_data PARAMS ((PTR, FILE *, long, size_t, const char *));
-
-static PTR
-get_data (var, file, offset, size, reason)
-     PTR var;
-     FILE *file;
-     long offset;
-     size_t size;
-     const char *reason;
+static void *
+get_data (void *var, FILE *file, long offset, size_t size, const char *reason)
 {
-  PTR mvar;
+  void *mvar;
 
   if (size == 0)
     return NULL;
 
-  if (fseek (file, offset, SEEK_SET))
+  if (fseek (file, archive_file_offset + offset, SEEK_SET))
     {
-      error (_("Unable to seek to %x for %s\n"), offset, reason);
+      error (_("Unable to seek to 0x%x for %s\n"),
+            archive_file_offset + offset, reason);
       return NULL;
     }
 
   mvar = var;
   if (mvar == NULL)
     {
-      mvar = (PTR) malloc (size);
+      mvar = malloc (size);
 
       if (mvar == NULL)
        {
-         error (_("Out of memory allocating %d bytes for %s\n"),
+         error (_("Out of memory allocating 0x%x bytes for %s\n"),
                 size, reason);
          return NULL;
        }
@@ -498,7 +270,7 @@ get_data (var, file, offset, size, reason)
 
   if (fread (mvar, size, 1, file) != 1)
     {
-      error (_("Unable to read in %d bytes of %s\n"), size, reason);
+      error (_("Unable to read in 0x%x bytes of %s\n"), size, reason);
       if (mvar != var)
        free (mvar);
       return NULL;
@@ -508,9 +280,7 @@ get_data (var, file, offset, size, reason)
 }
 
 static bfd_vma
-byte_get_little_endian (field, size)
-     unsigned char *field;
-     int size;
+byte_get_little_endian (unsigned char *field, int size)
 {
   switch (size)
     {
@@ -540,7 +310,7 @@ byte_get_little_endian (field, size)
       /* This is a special case, generated by the BYTE_GET8 macro.
         It means that we are loading an 8 byte value from a field
         in an external structure into an 8 byte value in a field
-        in an internal strcuture.  */
+        in an internal structure.  */
       return  ((bfd_vma) (field[0]))
        |    (((bfd_vma) (field[1])) << 8)
        |    (((bfd_vma) (field[2])) << 16)
@@ -556,11 +326,29 @@ byte_get_little_endian (field, size)
     }
 }
 
+static bfd_vma
+byte_get_signed (unsigned char *field, int size)
+{
+  bfd_vma x = byte_get (field, size);
+
+  switch (size)
+    {
+    case 1:
+      return (x ^ 0x80) - 0x80;
+    case 2:
+      return (x ^ 0x8000) - 0x8000;
+    case 4:
+      return (x ^ 0x80000000) - 0x80000000;
+    case 8:
+    case -8:
+      return x;
+    default:
+      abort ();
+    }
+}
+
 static void
-byte_put_little_endian (field, value, size)
-     unsigned char * field;
-     bfd_vma        value;
-     int             size;
+byte_put_little_endian (unsigned char *field, bfd_vma value, int size)
 {
   switch (size)
     {
@@ -589,9 +377,7 @@ byte_put_little_endian (field, value, size)
 
 /* Print a VMA value.  */
 static void
-print_vma (vma, mode)
-     bfd_vma vma;
-     print_mode mode;
+print_vma (bfd_vma vma, print_mode mode)
 {
 #ifdef BFD64
   if (is_32bit_elf)
@@ -599,13 +385,34 @@ print_vma (vma, mode)
     {
       switch (mode)
        {
-       case FULL_HEX: printf ("0x"); /* drop through */
-       case LONG_HEX: printf ("%8.8lx", (unsigned long) vma); break;
-       case PREFIX_HEX: printf ("0x"); /* drop through */
-       case HEX: printf ("%lx", (unsigned long) vma); break;
-       case DEC: printf ("%ld", (unsigned long) vma); break;
-       case DEC_5: printf ("%5ld", (long) vma); break;
-       case UNSIGNED: printf ("%lu", (unsigned long) vma); break;
+       case FULL_HEX:
+         printf ("0x");
+         /* Drop through.  */
+       case LONG_HEX:
+         printf ("%8.8lx", (unsigned long) vma);
+         break;
+
+       case DEC_5:
+         if (vma <= 99999)
+           {
+             printf ("%5ld", (long) vma);
+             break;
+           }
+         /* Drop through.  */
+       case PREFIX_HEX:
+         printf ("0x");
+         /* Drop through.  */
+       case HEX:
+         printf ("%lx", (unsigned long) vma);
+         break;
+
+       case DEC:
+         printf ("%ld", (unsigned long) vma);
+         break;
+
+       case UNSIGNED:
+         printf ("%lu", (unsigned long) vma);
+         break;
        }
     }
 #ifdef BFD64
@@ -615,7 +422,7 @@ print_vma (vma, mode)
        {
        case FULL_HEX:
          printf ("0x");
-         /* drop through */
+         /* Drop through.  */
 
        case LONG_HEX:
          printf_vma (vma);
@@ -623,7 +430,7 @@ print_vma (vma, mode)
 
        case PREFIX_HEX:
          printf ("0x");
-         /* drop through */
+         /* Drop through.  */
 
        case HEX:
 #if BFD_HOST_64BIT_LONG
@@ -650,13 +457,18 @@ print_vma (vma, mode)
 
        case DEC_5:
 #if BFD_HOST_64BIT_LONG
-         printf ("%5ld", vma);
+         if (vma <= 99999)
+           printf ("%5ld", vma);
+         else
+           printf ("%#lx", vma);
 #else
          if (_bfd_int64_high (vma))
            /* ugg */
            printf ("++%ld", _bfd_int64_low (vma));
-         else
+         else if (vma <= 99999)
            printf ("%5ld", _bfd_int64_low (vma));
+         else
+           printf ("%#lx", _bfd_int64_low (vma));
 #endif
          break;
 
@@ -683,9 +495,7 @@ print_vma (vma, mode)
    truncating or padding as necessary.  */
 
 static void
-print_symbol (width, symbol)
-     int width;
-     const char *symbol;
+print_symbol (int width, const char *symbol)
 {
   if (do_wide)
     printf ("%s", symbol);
@@ -696,9 +506,7 @@ print_symbol (width, symbol)
 }
 
 static bfd_vma
-byte_get_big_endian (field, size)
-     unsigned char *field;
-     int size;
+byte_get_big_endian (unsigned char *field, int size)
 {
   switch (size)
     {
@@ -728,7 +536,7 @@ byte_get_big_endian (field, size)
       /* This is a special case, generated by the BYTE_GET8 macro.
         It means that we are loading an 8 byte value from a field
         in an external structure into an 8 byte value in a field
-        in an internal strcuture.  */
+        in an internal structure.  */
       return ((bfd_vma) (field[7]))
        |   (((bfd_vma) (field[6])) << 8)
        |   (((bfd_vma) (field[5])) << 16)
@@ -746,10 +554,7 @@ byte_get_big_endian (field, size)
 }
 
 static void
-byte_put_big_endian (field, value, size)
-     unsigned char * field;
-     bfd_vma        value;
-     int             size;
+byte_put_big_endian (unsigned char *field, bfd_vma value, int size)
 {
   switch (size)
     {
@@ -783,8 +588,7 @@ byte_put_big_endian (field, value, size)
 /* Guess the relocation size commonly used by the specific machines.  */
 
 static int
-guess_is_rela (e_machine)
-     unsigned long e_machine;
+guess_is_rela (unsigned long e_machine)
 {
   switch (e_machine)
     {
@@ -872,12 +676,11 @@ guess_is_rela (e_machine)
 }
 
 static int
-slurp_rela_relocs (file, rel_offset, rel_size, relasp, nrelasp)
-     FILE *file;
-     unsigned long rel_offset;
-     unsigned long rel_size;
-     Elf_Internal_Rela **relasp;
-     unsigned long *nrelasp;
+slurp_rela_relocs (FILE *file,
+                  unsigned long rel_offset,
+                  unsigned long rel_size,
+                  Elf_Internal_Rela **relasp,
+                  unsigned long *nrelasp)
 {
   Elf_Internal_Rela *relas;
   unsigned long nrelas;
@@ -887,15 +690,13 @@ slurp_rela_relocs (file, rel_offset, rel_size, relasp, nrelasp)
     {
       Elf32_External_Rela *erelas;
 
-      erelas = (Elf32_External_Rela *) get_data (NULL, file, rel_offset,
-                                                rel_size, _("relocs"));
+      erelas = get_data (NULL, file, rel_offset, rel_size, _("relocs"));
       if (!erelas)
        return 0;
 
       nrelas = rel_size / sizeof (Elf32_External_Rela);
 
-      relas = (Elf_Internal_Rela *)
-       malloc (nrelas * sizeof (Elf_Internal_Rela));
+      relas = malloc (nrelas * sizeof (Elf_Internal_Rela));
 
       if (relas == NULL)
        {
@@ -916,15 +717,13 @@ slurp_rela_relocs (file, rel_offset, rel_size, relasp, nrelasp)
     {
       Elf64_External_Rela *erelas;
 
-      erelas = (Elf64_External_Rela *) get_data (NULL, file, rel_offset,
-                                                rel_size, _("relocs"));
+      erelas = get_data (NULL, file, rel_offset, rel_size, _("relocs"));
       if (!erelas)
        return 0;
 
       nrelas = rel_size / sizeof (Elf64_External_Rela);
 
-      relas = (Elf_Internal_Rela *)
-       malloc (nrelas * sizeof (Elf_Internal_Rela));
+      relas = malloc (nrelas * sizeof (Elf_Internal_Rela));
 
       if (relas == NULL)
        {
@@ -947,12 +746,11 @@ slurp_rela_relocs (file, rel_offset, rel_size, relasp, nrelasp)
 }
 
 static int
-slurp_rel_relocs (file, rel_offset, rel_size, relsp, nrelsp)
-     FILE *file;
-     unsigned long rel_offset;
-     unsigned long rel_size;
-     Elf_Internal_Rela **relsp;
-     unsigned long *nrelsp;
+slurp_rel_relocs (FILE *file,
+                 unsigned long rel_offset,
+                 unsigned long rel_size,
+                 Elf_Internal_Rela **relsp,
+                 unsigned long *nrelsp)
 {
   Elf_Internal_Rela *rels;
   unsigned long nrels;
@@ -962,14 +760,13 @@ slurp_rel_relocs (file, rel_offset, rel_size, relsp, nrelsp)
     {
       Elf32_External_Rel *erels;
 
-      erels = (Elf32_External_Rel *) get_data (NULL, file, rel_offset,
-                                              rel_size, _("relocs"));
+      erels = get_data (NULL, file, rel_offset, rel_size, _("relocs"));
       if (!erels)
        return 0;
 
       nrels = rel_size / sizeof (Elf32_External_Rel);
 
-      rels = (Elf_Internal_Rela *) malloc (nrels * sizeof (Elf_Internal_Rela));
+      rels = malloc (nrels * sizeof (Elf_Internal_Rela));
 
       if (rels == NULL)
        {
@@ -990,14 +787,13 @@ slurp_rel_relocs (file, rel_offset, rel_size, relsp, nrelsp)
     {
       Elf64_External_Rel *erels;
 
-      erels = (Elf64_External_Rel *) get_data (NULL, file, rel_offset,
-                                              rel_size, _("relocs"));
+      erels = get_data (NULL, file, rel_offset, rel_size, _("relocs"));
       if (!erels)
        return 0;
 
       nrels = rel_size / sizeof (Elf64_External_Rel);
 
-      rels = (Elf_Internal_Rela *) malloc (nrels * sizeof (Elf_Internal_Rela));
+      rels = malloc (nrels * sizeof (Elf_Internal_Rela));
 
       if (rels == NULL)
        {
@@ -1019,17 +815,17 @@ slurp_rel_relocs (file, rel_offset, rel_size, relsp, nrelsp)
   return 1;
 }
 
-/* Display the contents of the relocation data found at the specified offset.  */
+/* Display the contents of the relocation data found at the specified
+   offset.  */
 
 static int
-dump_relocations (file, rel_offset, rel_size, symtab, nsyms, strtab, is_rela)
-     FILE *file;
-     unsigned long rel_offset;
-     unsigned long rel_size;
-     Elf_Internal_Sym *symtab;
-     unsigned long nsyms;
-     char *strtab;
-     int is_rela;
+dump_relocations (FILE *file,
+                 unsigned long rel_offset,
+                 unsigned long rel_size,
+                 Elf_Internal_Sym *symtab,
+                 unsigned long nsyms,
+                 char *strtab,
+                 int is_rela)
 {
   unsigned int i;
   Elf_Internal_Rela *rels;
@@ -1093,8 +889,8 @@ dump_relocations (file, rel_offset, rel_size, symtab, nsyms, strtab, is_rela)
       bfd_vma info;
       bfd_vma symtab_index;
       bfd_vma type;
-      bfd_vma type2 = (bfd_vma) NULL;
-      bfd_vma type3 = (bfd_vma) NULL;
+      bfd_vma type2 = 0;
+      bfd_vma type3 = 0;
 
       offset = rels[i].r_offset;
       info   = rels[i].r_info;
@@ -1398,6 +1194,10 @@ dump_relocations (file, rel_offset, rel_size, symtab, nsyms, strtab, is_rela)
                        sec_name = "ABS";
                      else if (psym->st_shndx == SHN_COMMON)
                        sec_name = "COMMON";
+                     else if (elf_header.e_machine == EM_IA_64
+                              && elf_header.e_ident[EI_OSABI] == ELFOSABI_HPUX
+                              && psym->st_shndx == SHN_IA_64_ANSI_COMMON)
+                       sec_name = "ANSI_COM";
                      else
                        {
                          sprintf (name_buf, "<section 0x%x>",
@@ -1462,8 +1262,7 @@ dump_relocations (file, rel_offset, rel_size, symtab, nsyms, strtab, is_rela)
 }
 
 static const char *
-get_mips_dynamic_type (type)
-     unsigned long type;
+get_mips_dynamic_type (unsigned long type)
 {
   switch (type)
     {
@@ -1516,8 +1315,7 @@ get_mips_dynamic_type (type)
 }
 
 static const char *
-get_sparc64_dynamic_type (type)
-     unsigned long type;
+get_sparc64_dynamic_type (unsigned long type)
 {
   switch (type)
     {
@@ -1528,8 +1326,7 @@ get_sparc64_dynamic_type (type)
 }
 
 static const char *
-get_ppc64_dynamic_type (type)
-     unsigned long type;
+get_ppc64_dynamic_type (unsigned long type)
 {
   switch (type)
     {
@@ -1542,8 +1339,7 @@ get_ppc64_dynamic_type (type)
 }
 
 static const char *
-get_parisc_dynamic_type (type)
-     unsigned long type;
+get_parisc_dynamic_type (unsigned long type)
 {
   switch (type)
     {
@@ -1566,8 +1362,7 @@ get_parisc_dynamic_type (type)
 }
 
 static const char *
-get_ia64_dynamic_type (type)
-     unsigned long type;
+get_ia64_dynamic_type (unsigned long type)
 {
   switch (type)
     {
@@ -1578,8 +1373,7 @@ get_ia64_dynamic_type (type)
 }
 
 static const char *
-get_dynamic_type (type)
-     unsigned long type;
+get_dynamic_type (unsigned long type)
 {
   static char buff[32];
 
@@ -1714,8 +1508,7 @@ get_dynamic_type (type)
 }
 
 static char *
-get_file_type (e_type)
-     unsigned e_type;
+get_file_type (unsigned e_type)
 {
   static char buff[32];
 
@@ -1739,8 +1532,7 @@ get_file_type (e_type)
 }
 
 static char *
-get_machine_name (e_machine)
-     unsigned e_machine;
+get_machine_name (unsigned e_machine)
 {
   static char buff[64]; /* XXX */
 
@@ -1846,9 +1638,7 @@ get_machine_name (e_machine)
 }
 
 static void
-decode_ARM_machine_flags (e_flags, buf)
-     unsigned e_flags;
-     char buf[];
+decode_ARM_machine_flags (unsigned e_flags, char buf[])
 {
   unsigned eabi;
   int unknown = 0;
@@ -1992,9 +1782,7 @@ decode_ARM_machine_flags (e_flags, buf)
 }
 
 static char *
-get_machine_flags (e_flags, e_machine)
-     unsigned e_flags;
-     unsigned e_machine;
+get_machine_flags (unsigned e_flags, unsigned e_machine)
 {
   static char buf[1024];
 
@@ -2033,6 +1821,9 @@ get_machine_flags (e_flags, e_machine)
        case EM_CYGNUS_V850:
          switch (e_flags & EF_V850_ARCH)
            {
+           case E_V850E1_ARCH:
+             strcat (buf, ", v850e1");
+             break;
            case E_V850E_ARCH:
              strcat (buf, ", v850e");
              break;
@@ -2125,6 +1916,7 @@ get_machine_flags (e_flags, e_machine)
            case E_MIPS_ARCH_32: strcat (buf, ", mips32"); break;
            case E_MIPS_ARCH_32R2: strcat (buf, ", mips32r2"); break;
            case E_MIPS_ARCH_64: strcat (buf, ", mips64"); break;
+           case E_MIPS_ARCH_64R2: strcat (buf, ", mips64r2"); break;
            default: strcat (buf, ", unknown ISA"); break;
            }
 
@@ -2224,8 +2016,37 @@ get_machine_flags (e_flags, e_machine)
 }
 
 static const char *
-get_mips_segment_type (type)
-     unsigned long type;
+get_osabi_name (unsigned int osabi)
+{
+  static char buff[32];
+
+  switch (osabi)
+    {
+    case ELFOSABI_NONE:                return "UNIX - System V";
+    case ELFOSABI_HPUX:                return "UNIX - HP-UX";
+    case ELFOSABI_NETBSD:      return "UNIX - NetBSD";
+    case ELFOSABI_LINUX:       return "UNIX - Linux";
+    case ELFOSABI_HURD:                return "GNU/Hurd";
+    case ELFOSABI_SOLARIS:     return "UNIX - Solaris";
+    case ELFOSABI_AIX:         return "UNIX - AIX";
+    case ELFOSABI_IRIX:                return "UNIX - IRIX";
+    case ELFOSABI_FREEBSD:     return "UNIX - FreeBSD";
+    case ELFOSABI_TRU64:       return "UNIX - TRU64";
+    case ELFOSABI_MODESTO:     return "Novell - Modesto";
+    case ELFOSABI_OPENBSD:     return "UNIX - OpenBSD";
+    case ELFOSABI_OPENVMS:     return "VMS - OpenVMS";
+    case ELFOSABI_NSK:         return "HP - Non-Stop Kernel";
+    case ELFOSABI_AROS:                return "Amiga Research OS";
+    case ELFOSABI_STANDALONE:  return _("Standalone App");
+    case ELFOSABI_ARM:         return "ARM";
+    default:
+      sprintf (buff, _("<unknown: %x>"), osabi);
+      return buff;
+    }
+}
+
+static const char *
+get_mips_segment_type (unsigned long type)
 {
   switch (type)
     {
@@ -2243,8 +2064,7 @@ get_mips_segment_type (type)
 }
 
 static const char *
-get_parisc_segment_type (type)
-     unsigned long type;
+get_parisc_segment_type (unsigned long type)
 {
   switch (type)
     {
@@ -2270,8 +2090,7 @@ get_parisc_segment_type (type)
 }
 
 static const char *
-get_ia64_segment_type (type)
-     unsigned long type;
+get_ia64_segment_type (unsigned long type)
 {
   switch (type)
     {
@@ -2289,8 +2108,7 @@ get_ia64_segment_type (type)
 }
 
 static const char *
-get_segment_type (p_type)
-     unsigned long p_type;
+get_segment_type (unsigned long p_type)
 {
   static char buff[32];
 
@@ -2307,6 +2125,7 @@ get_segment_type (p_type)
 
     case PT_GNU_EH_FRAME:
                        return "GNU_EH_FRAME";
+    case PT_GNU_STACK: return "STACK";
 
     default:
       if ((p_type >= PT_LOPROC) && (p_type <= PT_HIPROC))
@@ -2365,8 +2184,7 @@ get_segment_type (p_type)
 }
 
 static const char *
-get_mips_section_type_name (sh_type)
-     unsigned int sh_type;
+get_mips_section_type_name (unsigned int sh_type)
 {
   switch (sh_type)
     {
@@ -2416,8 +2234,7 @@ get_mips_section_type_name (sh_type)
 }
 
 static const char *
-get_parisc_section_type_name (sh_type)
-     unsigned int sh_type;
+get_parisc_section_type_name (unsigned int sh_type)
 {
   switch (sh_type)
     {
@@ -2431,8 +2248,7 @@ get_parisc_section_type_name (sh_type)
 }
 
 static const char *
-get_ia64_section_type_name (sh_type)
-     unsigned int sh_type;
+get_ia64_section_type_name (unsigned int sh_type)
 {
   /* If the top 8 bits are 0x78 the next 8 are the os/abi ID. */
   if ((sh_type & 0xFF000000) == SHT_IA_64_LOPSREG)
@@ -2450,8 +2266,7 @@ get_ia64_section_type_name (sh_type)
 }
 
 static const char *
-get_section_type_name (sh_type)
-     unsigned int sh_type;
+get_section_type_name (unsigned int sh_type)
 {
   static char buff[32];
 
@@ -2555,7 +2370,7 @@ struct option options[] =
 };
 
 static void
-usage ()
+usage (void)
 {
   fprintf (stdout, _("Usage: readelf <option(s)> elf-file(s)\n"));
   fprintf (stdout, _(" Display information about the contents of ELF format files\n"));
@@ -2596,15 +2411,13 @@ usage ()
 }
 
 static void
-request_dump (section, type)
-     unsigned int section;
-     int type;
+request_dump (unsigned int section, int type)
 {
   if (section >= num_dump_sects)
     {
       char *new_dump_sects;
 
-      new_dump_sects = (char *) calloc (section + 1, 1);
+      new_dump_sects = calloc (section + 1, 1);
 
       if (new_dump_sects == NULL)
        error (_("Out of memory allocating dump request table."));
@@ -2627,9 +2440,7 @@ request_dump (section, type)
 }
 
 static void
-parse_args (argc, argv)
-     int argc;
-     char **argv;
+parse_args (int argc, char **argv)
 {
   int c;
 
@@ -2900,8 +2711,7 @@ parse_args (argc, argv)
 }
 
 static const char *
-get_elf_class (elf_class)
-     unsigned int elf_class;
+get_elf_class (unsigned int elf_class)
 {
   static char buff[32];
 
@@ -2917,8 +2727,7 @@ get_elf_class (elf_class)
 }
 
 static const char *
-get_data_encoding (encoding)
-     unsigned int encoding;
+get_data_encoding (unsigned int encoding)
 {
   static char buff[32];
 
@@ -2933,41 +2742,10 @@ get_data_encoding (encoding)
     }
 }
 
-static const char *
-get_osabi_name (osabi)
-     unsigned int osabi;
-{
-  static char buff[32];
-
-  switch (osabi)
-    {
-    case ELFOSABI_NONE:                return "UNIX - System V";
-    case ELFOSABI_HPUX:                return "UNIX - HP-UX";
-    case ELFOSABI_NETBSD:      return "UNIX - NetBSD";
-    case ELFOSABI_LINUX:       return "UNIX - Linux";
-    case ELFOSABI_HURD:                return "GNU/Hurd";
-    case ELFOSABI_SOLARIS:     return "UNIX - Solaris";
-    case ELFOSABI_AIX:         return "UNIX - AIX";
-    case ELFOSABI_IRIX:                return "UNIX - IRIX";
-    case ELFOSABI_FREEBSD:     return "UNIX - FreeBSD";
-    case ELFOSABI_TRU64:       return "UNIX - TRU64";
-    case ELFOSABI_MODESTO:     return "Novell - Modesto";
-    case ELFOSABI_OPENBSD:     return "UNIX - OpenBSD";
-    case ELFOSABI_OPENVMS:     return "VMS - OpenVMS";
-    case ELFOSABI_NSK:         return "HP - Non-Stop Kernel";
-    case ELFOSABI_AROS:                return "Amiga Research OS";
-    case ELFOSABI_STANDALONE:  return _("Standalone App");
-    case ELFOSABI_ARM:         return "ARM";
-    default:
-      sprintf (buff, _("<unknown: %x>"), osabi);
-      return buff;
-    }
-}
-
 /* Decode the data held in 'elf_header'.  */
 
 static int
-process_file_header ()
+process_file_header (void)
 {
   if (   elf_header.e_ident[EI_MAG0] != ELFMAG0
       || elf_header.e_ident[EI_MAG1] != ELFMAG1
@@ -3056,19 +2834,16 @@ process_file_header ()
 
 
 static int
-get_32bit_program_headers (file, program_headers)
-     FILE *file;
-     Elf_Internal_Phdr *program_headers;
+get_32bit_program_headers (FILE *file, Elf_Internal_Phdr *program_headers)
 {
   Elf32_External_Phdr *phdrs;
   Elf32_External_Phdr *external;
   Elf_Internal_Phdr *internal;
   unsigned int i;
 
-  phdrs = ((Elf32_External_Phdr *)
-          get_data (NULL, file, elf_header.e_phoff,
-                    elf_header.e_phentsize * elf_header.e_phnum,
-                    _("program headers")));
+  phdrs = get_data (NULL, file, elf_header.e_phoff,
+                   elf_header.e_phentsize * elf_header.e_phnum,
+                   _("program headers"));
   if (!phdrs)
     return 0;
 
@@ -3092,19 +2867,16 @@ get_32bit_program_headers (file, program_headers)
 }
 
 static int
-get_64bit_program_headers (file, program_headers)
-     FILE *file;
-     Elf_Internal_Phdr *program_headers;
+get_64bit_program_headers (FILE *file, Elf_Internal_Phdr *program_headers)
 {
   Elf64_External_Phdr *phdrs;
   Elf64_External_Phdr *external;
   Elf_Internal_Phdr *internal;
   unsigned int i;
 
-  phdrs = ((Elf64_External_Phdr *)
-          get_data (NULL, file, elf_header.e_phoff,
-                    elf_header.e_phentsize * elf_header.e_phnum,
-                    _("program headers")));
+  phdrs = get_data (NULL, file, elf_header.e_phoff,
+                   elf_header.e_phentsize * elf_header.e_phnum,
+                   _("program headers"));
   if (!phdrs)
     return 0;
 
@@ -3127,13 +2899,42 @@ get_64bit_program_headers (file, program_headers)
   return 1;
 }
 
+/* Returns 1 if the program headers were read into `program_headers'.  */
+
+static int
+get_program_headers (FILE *file)
+{
+  Elf_Internal_Phdr *phdrs;
+
+  /* Check cache of prior read.  */
+  if (program_headers != NULL)
+    return 1;
+
+  phdrs = malloc (elf_header.e_phnum * sizeof (Elf_Internal_Phdr));
+
+  if (phdrs == NULL)
+    {
+      error (_("Out of memory\n"));
+      return 0;
+    }
+
+  if (is_32bit_elf
+      ? get_32bit_program_headers (file, phdrs)
+      : get_64bit_program_headers (file, phdrs))
+    {
+      program_headers = phdrs;
+      return 1;
+    }
+
+  free (phdrs);
+  return 0;
+}
+
 /* Returns 1 if the program headers were loaded.  */
 
 static int
-process_program_headers (file)
-     FILE *file;
+process_program_headers (FILE *file)
 {
-  Elf_Internal_Phdr *program_headers;
   Elf_Internal_Phdr *segment;
   unsigned int i;
 
@@ -3155,25 +2956,8 @@ process_program_headers (file)
       printf ("\n");
     }
 
-  program_headers = (Elf_Internal_Phdr *) malloc
-    (elf_header.e_phnum * sizeof (Elf_Internal_Phdr));
-
-  if (program_headers == NULL)
-    {
-      error (_("Out of memory\n"));
+  if (! get_program_headers (file))
       return 0;
-    }
-
-  if (is_32bit_elf)
-    i = get_32bit_program_headers (file, program_headers);
-  else
-    i = get_64bit_program_headers (file, program_headers);
-
-  if (i == 0)
-    {
-      free (program_headers);
-      return 0;
-    }
 
   if (do_segments)
     {
@@ -3197,7 +2981,6 @@ process_program_headers (file)
        }
     }
 
-  loadaddr = -1;
   dynamic_addr = 0;
   dynamic_size = 0;
 
@@ -3285,18 +3068,6 @@ process_program_headers (file)
 
       switch (segment->p_type)
        {
-       case PT_LOAD:
-         if (loadaddr == -1)
-           {
-             unsigned long align_mask = -segment->p_align;
-
-             if (align_mask == 0)
-               --align_mask;
-             loadaddr = ((segment->p_vaddr & align_mask)
-                         - (segment->p_offset & align_mask));
-           }
-         break;
-
        case PT_DYNAMIC:
          if (dynamic_addr)
            error (_("more than one dynamic segment\n"));
@@ -3306,7 +3077,8 @@ process_program_headers (file)
          break;
 
        case PT_INTERP:
-         if (fseek (file, (long) segment->p_offset, SEEK_SET))
+         if (fseek (file, archive_file_offset + (long) segment->p_offset,
+                    SEEK_SET))
            error (_("Unable to find program interpreter name\n"));
          else
            {
@@ -3324,12 +3096,6 @@ process_program_headers (file)
        putc ('\n', stdout);
     }
 
-  if (loadaddr == -1)
-    {
-      /* Very strange.  */
-      loadaddr = 0;
-    }
-
   if (do_segments && section_headers != NULL)
     {
       printf (_("\n Section to Segment mapping:\n"));
@@ -3366,30 +3132,54 @@ process_program_headers (file)
        }
     }
 
-  free (program_headers);
-
   return 1;
 }
 
 
+/* Find the file offset corresponding to VMA by using the program headers.  */
+
+static long
+offset_from_vma (FILE *file, bfd_vma vma, bfd_size_type size)
+{
+  Elf_Internal_Phdr *seg;
+
+  if (! get_program_headers (file))
+    {
+      warn (_("Cannot interpret virtual addresses without program headers.\n"));
+      return (long) vma;
+    }
+
+  for (seg = program_headers;
+       seg < program_headers + elf_header.e_phnum;
+       ++seg)
+    {
+      if (seg->p_type != PT_LOAD)
+       continue;
+
+      if (vma >= (seg->p_vaddr & -seg->p_align)
+         && vma + size <= seg->p_vaddr + seg->p_filesz)
+       return vma - seg->p_vaddr + seg->p_offset;
+    }
+
+  warn (_("Virtual address 0x%lx not located in any PT_LOAD segment.\n"),
+       (long) vma);
+  return (long) vma;
+}
+
+
 static int
-get_32bit_section_headers (file, num)
-     FILE *file;
-     unsigned int num;
+get_32bit_section_headers (FILE *file, unsigned int num)
 {
   Elf32_External_Shdr *shdrs;
   Elf_Internal_Shdr *internal;
   unsigned int i;
 
-  shdrs = ((Elf32_External_Shdr *)
-          get_data (NULL, file, elf_header.e_shoff,
-                    elf_header.e_shentsize * num,
-                    _("section headers")));
+  shdrs = get_data (NULL, file, elf_header.e_shoff,
+                   elf_header.e_shentsize * num, _("section headers"));
   if (!shdrs)
     return 0;
 
-  section_headers = ((Elf_Internal_Shdr *)
-                    malloc (num * sizeof (Elf_Internal_Shdr)));
+  section_headers = malloc (num * sizeof (Elf_Internal_Shdr));
 
   if (section_headers == NULL)
     {
@@ -3419,23 +3209,18 @@ get_32bit_section_headers (file, num)
 }
 
 static int
-get_64bit_section_headers (file, num)
-     FILE *file;
-     unsigned int num;
+get_64bit_section_headers (FILE *file, unsigned int num)
 {
   Elf64_External_Shdr *shdrs;
   Elf_Internal_Shdr *internal;
   unsigned int i;
 
-  shdrs = ((Elf64_External_Shdr *)
-          get_data (NULL, file, elf_header.e_shoff,
-                    elf_header.e_shentsize * num,
-                    _("section headers")));
+  shdrs = get_data (NULL, file, elf_header.e_shoff,
+                   elf_header.e_shentsize * num, _("section headers"));
   if (!shdrs)
     return 0;
 
-  section_headers = ((Elf_Internal_Shdr *)
-                    malloc (num * sizeof (Elf_Internal_Shdr)));
+  section_headers = malloc (num * sizeof (Elf_Internal_Shdr));
 
   if (section_headers == NULL)
     {
@@ -3465,9 +3250,7 @@ get_64bit_section_headers (file, num)
 }
 
 static Elf_Internal_Sym *
-get_32bit_elf_symbols (file, section)
-     FILE *file;
-     Elf_Internal_Shdr *section;
+get_32bit_elf_symbols (FILE *file, Elf_Internal_Shdr *section)
 {
   unsigned long number;
   Elf32_External_Sym *esyms;
@@ -3476,9 +3259,8 @@ get_32bit_elf_symbols (file, section)
   Elf_Internal_Sym *psym;
   unsigned int j;
 
-  esyms = ((Elf32_External_Sym *)
-          get_data (NULL, file, section->sh_offset,
-                    section->sh_size, _("symbols")));
+  esyms = get_data (NULL, file, section->sh_offset, section->sh_size,
+                   _("symbols"));
   if (!esyms)
     return NULL;
 
@@ -3487,9 +3269,8 @@ get_32bit_elf_symbols (file, section)
       && (symtab_shndx_hdr->sh_link
          == (unsigned long) SECTION_HEADER_NUM (section - section_headers)))
     {
-      shndx = ((Elf_External_Sym_Shndx *)
-              get_data (NULL, file, symtab_shndx_hdr->sh_offset,
-                        symtab_shndx_hdr->sh_size, _("symtab shndx")));
+      shndx = get_data (NULL, file, symtab_shndx_hdr->sh_offset,
+                       symtab_shndx_hdr->sh_size, _("symtab shndx"));
       if (!shndx)
        {
          free (esyms);
@@ -3498,7 +3279,7 @@ get_32bit_elf_symbols (file, section)
     }
 
   number = section->sh_size / section->sh_entsize;
-  isyms = (Elf_Internal_Sym *) malloc (number * sizeof (Elf_Internal_Sym));
+  isyms = malloc (number * sizeof (Elf_Internal_Sym));
 
   if (isyms == NULL)
     {
@@ -3532,9 +3313,7 @@ get_32bit_elf_symbols (file, section)
 }
 
 static Elf_Internal_Sym *
-get_64bit_elf_symbols (file, section)
-     FILE *file;
-     Elf_Internal_Shdr *section;
+get_64bit_elf_symbols (FILE *file, Elf_Internal_Shdr *section)
 {
   unsigned long number;
   Elf64_External_Sym *esyms;
@@ -3543,9 +3322,8 @@ get_64bit_elf_symbols (file, section)
   Elf_Internal_Sym *psym;
   unsigned int j;
 
-  esyms = ((Elf64_External_Sym *)
-          get_data (NULL, file, section->sh_offset,
-                    section->sh_size, _("symbols")));
+  esyms = get_data (NULL, file, section->sh_offset, section->sh_size,
+                   _("symbols"));
   if (!esyms)
     return NULL;
 
@@ -3554,9 +3332,8 @@ get_64bit_elf_symbols (file, section)
       && (symtab_shndx_hdr->sh_link
          == (unsigned long) SECTION_HEADER_NUM (section - section_headers)))
     {
-      shndx = ((Elf_External_Sym_Shndx *)
-              get_data (NULL, file, symtab_shndx_hdr->sh_offset,
-                        symtab_shndx_hdr->sh_size, _("symtab shndx")));
+      shndx = get_data (NULL, file, symtab_shndx_hdr->sh_offset,
+                       symtab_shndx_hdr->sh_size, _("symtab shndx"));
       if (!shndx)
        {
          free (esyms);
@@ -3565,7 +3342,7 @@ get_64bit_elf_symbols (file, section)
     }
 
   number = section->sh_size / section->sh_entsize;
-  isyms = (Elf_Internal_Sym *) malloc (number * sizeof (Elf_Internal_Sym));
+  isyms = malloc (number * sizeof (Elf_Internal_Sym));
 
   if (isyms == NULL)
     {
@@ -3599,8 +3376,7 @@ get_64bit_elf_symbols (file, section)
 }
 
 static const char *
-get_elf_section_flags (sh_flags)
-     bfd_vma sh_flags;
+get_elf_section_flags (bfd_vma sh_flags)
 {
   static char buff[32];
 
@@ -3647,8 +3423,7 @@ get_elf_section_flags (sh_flags)
 }
 
 static int
-process_section_headers (file)
-     FILE *file;
+process_section_headers (FILE *file)
 {
   Elf_Internal_Shdr *section;
   unsigned int i;
@@ -3680,9 +3455,12 @@ process_section_headers (file)
 
   if (section->sh_size != 0)
     {
-      string_table = (char *) get_data (NULL, file, section->sh_offset,
-                                       section->sh_size, _("string table"));
+      string_table = get_data (NULL, file, section->sh_offset,
+                              section->sh_size, _("string table"));
 
+      if (string_table == NULL)
+       return 0;
+      
       string_table_length = section->sh_size;
     }
 
@@ -3719,9 +3497,8 @@ process_section_headers (file)
              continue;
            }
 
-         dynamic_strings = (char *) get_data (NULL, file, section->sh_offset,
-                                              section->sh_size,
-                                              _("dynamic strings"));
+         dynamic_strings = get_data (NULL, file, section->sh_offset,
+                                     section->sh_size, _("dynamic strings"));
        }
       else if (section->sh_type == SHT_SYMTAB_SHNDX)
        {
@@ -3896,8 +3673,7 @@ struct
 
 /* Process the reloc section.  */
 static int
-process_relocs (file)
-     FILE *file;
+process_relocs (FILE *file)
 {
   unsigned long rel_size;
   unsigned long rel_offset;
@@ -3944,7 +3720,9 @@ process_relocs (file)
                (_("\n'%s' relocation section at offset 0x%lx contains %ld bytes:\n"),
                 name, rel_offset, rel_size);
 
-             dump_relocations (file, rel_offset - loadaddr, rel_size,
+             dump_relocations (file,
+                               offset_from_vma (file, rel_offset, rel_size),
+                               rel_size,
                                dynamic_symbols, num_dynamic_syms,
                                dynamic_strings, is_rela);
            }
@@ -4004,9 +3782,8 @@ process_relocs (file)
 
                  strsec = SECTION_HEADER (symsec->sh_link);
 
-                 strtab = (char *) get_data (NULL, file, strsec->sh_offset,
-                                             strsec->sh_size,
-                                             _("string table"));
+                 strtab = get_data (NULL, file, strsec->sh_offset,
+                                    strsec->sh_size, _("string table"));
                }
              is_rela = section->sh_type == SHT_RELA;
 
@@ -4061,21 +3838,13 @@ struct unw_aux_info
     unsigned long strtab_size; /* Size of string table.  */
   };
 
-static void find_symbol_for_address
-  PARAMS ((struct unw_aux_info *, struct absaddr, const char **, bfd_vma *));
-static void dump_ia64_unwind
-  PARAMS ((struct unw_aux_info *));
-static int slurp_ia64_unwind_table
-  PARAMS ((FILE *, struct unw_aux_info *, Elf_Internal_Shdr *));
-
 static void
-find_symbol_for_address (aux, addr, symname, offset)
-     struct unw_aux_info *aux;
-     struct absaddr addr;
-     const char **symname;
-     bfd_vma *offset;
+find_symbol_for_address (struct unw_aux_info *aux,
+                        struct absaddr addr,
+                        const char **symname,
+                        bfd_vma *offset)
 {
-  bfd_vma dist = (bfd_vma) 0x100000;
+  bfd_vma dist = 0x100000;
   Elf_Internal_Sym *sym, *best = NULL;
   unsigned long i;
 
@@ -4105,8 +3874,7 @@ find_symbol_for_address (aux, addr, symname, offset)
 }
 
 static void
-dump_ia64_unwind (aux)
-     struct unw_aux_info *aux;
+dump_ia64_unwind (struct unw_aux_info *aux)
 {
   bfd_vma addr_size;
   struct unw_table_entry *tp;
@@ -4164,20 +3932,18 @@ dump_ia64_unwind (aux)
 }
 
 static int
-slurp_ia64_unwind_table (file, aux, sec)
-     FILE *file;
-     struct unw_aux_info *aux;
-     Elf_Internal_Shdr *sec;
+slurp_ia64_unwind_table (FILE *file,
+                        struct unw_aux_info *aux,
+                        Elf_Internal_Shdr *sec)
 {
   unsigned long size, addr_size, nrelas, i;
-  Elf_Internal_Phdr *prog_hdrs, *seg;
+  Elf_Internal_Phdr *seg;
   struct unw_table_entry *tep;
   Elf_Internal_Shdr *relsec;
   Elf_Internal_Rela *rela, *rp;
   unsigned char *table, *tp;
   Elf_Internal_Sym *sym;
   const char *relname;
-  int result;
 
   addr_size = is_32bit_elf ? 4 : 8;
 
@@ -4186,21 +3952,12 @@ slurp_ia64_unwind_table (file, aux, sec)
 
   if (elf_header.e_phnum)
     {
-      prog_hdrs = (Elf_Internal_Phdr *)
-       xmalloc (elf_header.e_phnum * sizeof (Elf_Internal_Phdr));
-
-      if (is_32bit_elf)
-       result = get_32bit_program_headers (file, prog_hdrs);
-      else
-       result = get_64bit_program_headers (file, prog_hdrs);
-
-      if (!result)
-       {
-         free (prog_hdrs);
+      if (! get_program_headers (file))
          return 0;
-       }
 
-      for (seg = prog_hdrs; seg < prog_hdrs + elf_header.e_phnum; ++seg)
+      for (seg = program_headers;
+          seg < program_headers + elf_header.e_phnum;
+          ++seg)
        {
          if (seg->p_type != PT_LOAD)
            continue;
@@ -4212,14 +3969,11 @@ slurp_ia64_unwind_table (file, aux, sec)
              break;
            }
        }
-
-      free (prog_hdrs);
     }
 
   /* Second, build the unwind table from the contents of the unwind section:  */
   size = sec->sh_size;
-  table = (char *) get_data (NULL, file, sec->sh_offset,
-                            size, _("unwind table"));
+  table = get_data (NULL, file, sec->sh_offset, size, _("unwind table"));
   if (!table)
     return 0;
 
@@ -4323,8 +4077,7 @@ slurp_ia64_unwind_table (file, aux, sec)
 }
 
 static int
-process_unwind (file)
-     FILE *file;
+process_unwind (FILE *file)
 {
   Elf_Internal_Shdr *sec, *unwsec = NULL, *strsec;
   unsigned long i, addr_size, unwcount = 0, unwstart = 0;
@@ -4352,8 +4105,8 @@ process_unwind (file)
 
          strsec = SECTION_HEADER (sec->sh_link);
          aux.strtab_size = strsec->sh_size;
-         aux.strtab = (char *) get_data (NULL, file, strsec->sh_offset,
-                                         aux.strtab_size, _("string table"));
+         aux.strtab = get_data (NULL, file, strsec->sh_offset,
+                                aux.strtab_size, _("string table"));
        }
       else if (sec->sh_type == SHT_IA_64_UNWIND)
        unwcount++;
@@ -4422,8 +4175,8 @@ process_unwind (file)
        {
          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"));
+         aux.info = get_data (NULL, file, sec->sh_offset, aux.info_size,
+                              _("unwind info"));
 
          printf (_("\nUnwind section "));
 
@@ -4459,8 +4212,7 @@ process_unwind (file)
 }
 
 static void
-dynamic_segment_mips_val (entry)
-     Elf_Internal_Dyn *entry;
+dynamic_segment_mips_val (Elf_Internal_Dyn *entry)
 {
   switch (entry->d_tag)
     {
@@ -4534,8 +4286,7 @@ dynamic_segment_mips_val (entry)
 
 
 static void
-dynamic_segment_parisc_val (entry)
-     Elf_Internal_Dyn *entry;
+dynamic_segment_parisc_val (Elf_Internal_Dyn *entry)
 {
   switch (entry->d_tag)
     {
@@ -4591,30 +4342,33 @@ dynamic_segment_parisc_val (entry)
 }
 
 static void
-dynamic_segment_ia64_val (entry)
-     Elf_Internal_Dyn *entry;
+dynamic_segment_ia64_val (Elf_Internal_Dyn *entry)
 {
   switch (entry->d_tag)
     {
     case DT_IA_64_PLT_RESERVE: 
-      /* First 3 bytes reserved.  */
+      /* First 3 slots reserved.  */
       print_vma (entry->d_un.d_ptr, PREFIX_HEX);
       printf (" -- ");
       print_vma (entry->d_un.d_ptr + (3 * 8), PREFIX_HEX);
-      printf ("\n");
+      break;
+
+    default:
+      print_vma (entry->d_un.d_ptr, PREFIX_HEX);
+      break;
     }
+  putchar ('\n');
 }
 
 static int
-get_32bit_dynamic_segment (file)
-     FILE *file;
+get_32bit_dynamic_segment (FILE *file)
 {
   Elf32_External_Dyn *edyn;
   Elf_Internal_Dyn *entry;
   bfd_size_type i;
 
-  edyn = (Elf32_External_Dyn *) get_data (NULL, file, dynamic_addr,
-                                         dynamic_size, _("dynamic segment"));
+  edyn = get_data (NULL, file, dynamic_addr, dynamic_size,
+                  _("dynamic segment"));
   if (!edyn)
     return 0;
 
@@ -4625,8 +4379,7 @@ get_32bit_dynamic_segment (file)
   while (*(Elf32_Word *) edyn[dynamic_size++].d_tag != DT_NULL)
     ;
 
-  dynamic_segment = (Elf_Internal_Dyn *)
-    malloc (dynamic_size * sizeof (Elf_Internal_Dyn));
+  dynamic_segment = malloc (dynamic_size * sizeof (Elf_Internal_Dyn));
 
   if (dynamic_segment == NULL)
     {
@@ -4649,15 +4402,14 @@ get_32bit_dynamic_segment (file)
 }
 
 static int
-get_64bit_dynamic_segment (file)
-     FILE *file;
+get_64bit_dynamic_segment (FILE *file)
 {
   Elf64_External_Dyn *edyn;
   Elf_Internal_Dyn *entry;
   bfd_size_type i;
 
-  edyn = (Elf64_External_Dyn *) get_data (NULL, file, dynamic_addr,
-                                         dynamic_size, _("dynamic segment"));
+  edyn = get_data (NULL, file, dynamic_addr, dynamic_size,
+                  _("dynamic segment"));
   if (!edyn)
     return 0;
 
@@ -4668,8 +4420,7 @@ get_64bit_dynamic_segment (file)
   while (*(bfd_vma *) edyn[dynamic_size++].d_tag != DT_NULL)
     ;
 
-  dynamic_segment = (Elf_Internal_Dyn *)
-    malloc (dynamic_size * sizeof (Elf_Internal_Dyn));
+  dynamic_segment = malloc (dynamic_size * sizeof (Elf_Internal_Dyn));
 
   if (dynamic_segment == NULL)
     {
@@ -4692,8 +4443,7 @@ get_64bit_dynamic_segment (file)
 }
 
 static const char *
-get_dynamic_flags (flags)
-     bfd_vma flags;
+get_dynamic_flags (bfd_vma flags)
 {
   static char buff[128];
   char *p = buff;
@@ -4726,8 +4476,7 @@ get_dynamic_flags (flags)
 
 /* Parse and display the contents of the dynamic segment.  */
 static int
-process_dynamic_segment (file)
-     FILE *file;
+process_dynamic_segment (FILE *file)
 {
   Elf_Internal_Dyn *entry;
   bfd_size_type i;
@@ -4766,12 +4515,18 @@ process_dynamic_segment (file)
             we default to reading in the entire file (!) and
             processing that.  This is overkill, I know, but it
             should work.  */
-         section.sh_offset = entry->d_un.d_val - loadaddr;
+         section.sh_offset = offset_from_vma (file, entry->d_un.d_val, 0);
 
-         if (fseek (file, 0, SEEK_END))
-           error (_("Unable to seek to end of file!"));
+         if (archive_file_offset != 0)
+           section.sh_size = archive_file_size - section.sh_offset;
+         else
+           {
+             if (fseek (file, 0, SEEK_END))
+               error (_("Unable to seek to end of file!"));
+
+             section.sh_size = ftell (file) - section.sh_offset;
+           }
 
-         section.sh_size = ftell (file) - section.sh_offset;
          if (is_32bit_elf)
            section.sh_entsize = sizeof (Elf32_External_Sym);
          else
@@ -4808,10 +4563,16 @@ process_dynamic_segment (file)
             processing that.  This is overkill, I know, but it
             should work.  */
 
-         offset = entry->d_un.d_val - loadaddr;
-         if (fseek (file, 0, SEEK_END))
-           error (_("Unable to seek to end of file\n"));
-         str_tab_len = ftell (file) - offset;
+         offset = offset_from_vma (file, entry->d_un.d_val, 0);
+
+         if (archive_file_offset != 0)
+           str_tab_len = archive_file_size - offset;
+         else
+           {
+             if (fseek (file, 0, SEEK_END))
+               error (_("Unable to seek to end of file\n"));
+             str_tab_len = ftell (file) - offset;
+           }
 
          if (str_tab_len < 1)
            {
@@ -4820,8 +4581,8 @@ process_dynamic_segment (file)
              continue;
            }
 
-         dynamic_strings = (char *) get_data (NULL, file, offset, str_tab_len,
-                                              _("dynamic string table"));
+         dynamic_strings = get_data (NULL, file, offset, str_tab_len,
+                                     _("dynamic string table"));
          break;
        }
     }
@@ -4844,7 +4605,8 @@ process_dynamic_segment (file)
          else if (entry->d_tag == DT_SYMINSZ)
            syminsz = entry->d_un.d_val;
          else if (entry->d_tag == DT_SYMINFO)
-           dynamic_syminfo_offset = entry->d_un.d_val - loadaddr;
+           dynamic_syminfo_offset = offset_from_vma (file, entry->d_un.d_val,
+                                                     syminsz);
        }
 
       if (dynamic_syminfo_offset != 0 && syminsz != 0)
@@ -4853,13 +4615,12 @@ process_dynamic_segment (file)
          Elf_Internal_Syminfo *syminfo;
 
          /* There is a syminfo section.  Read the data.  */
-         extsyminfo = ((Elf_External_Syminfo *)
-                       get_data (NULL, file, dynamic_syminfo_offset,
-                                 syminsz, _("symbol information")));
+         extsyminfo = get_data (NULL, file, dynamic_syminfo_offset, syminsz,
+                                _("symbol information"));
          if (!extsyminfo)
            return 0;
 
-         dynamic_syminfo = (Elf_Internal_Syminfo *) malloc (syminsz);
+         dynamic_syminfo = malloc (syminsz);
          if (dynamic_syminfo == NULL)
            {
              error (_("Out of memory\n"));
@@ -5272,8 +5033,7 @@ process_dynamic_segment (file)
 }
 
 static char *
-get_ver_flags (flags)
-     unsigned int flags;
+get_ver_flags (unsigned int flags)
 {
   static char buff[32];
 
@@ -5301,8 +5061,7 @@ get_ver_flags (flags)
 
 /* Display the contents of the version sections.  */
 static int
-process_version_sections (file)
-     FILE *file;
+process_version_sections (FILE *file)
 {
   Elf_Internal_Shdr *section;
   unsigned i;
@@ -5335,10 +5094,8 @@ process_version_sections (file)
                    (unsigned long) section->sh_offset, section->sh_link,
                    SECTION_NAME (SECTION_HEADER (section->sh_link)));
 
-           edefs = ((Elf_External_Verdef *)
-                    get_data (NULL, file, section->sh_offset,
-                              section->sh_size,
-                              _("version definition section")));
+           edefs = get_data (NULL, file, section->sh_offset, section->sh_size,
+                             _("version definition section"));
            if (!edefs)
              break;
 
@@ -5426,9 +5183,8 @@ process_version_sections (file)
                    (unsigned long) section->sh_offset, section->sh_link,
                    SECTION_NAME (SECTION_HEADER (section->sh_link)));
 
-           eneed = ((Elf_External_Verneed *)
-                    get_data (NULL, file, section->sh_offset,
-                              section->sh_size, _("version need section")));
+           eneed = get_data (NULL, file, section->sh_offset, section->sh_size,
+                             _("version need section"));
            if (!eneed)
              break;
 
@@ -5475,10 +5231,10 @@ process_version_sections (file)
                    aux.vna_next  = BYTE_GET (eaux->vna_next);
 
                    if (dynamic_strings)
-                     printf (_("  %#06x: Name: %s"),
+                     printf (_("  %#06x:   Name: %s"),
                              isum, dynamic_strings + aux.vna_name);
                    else
-                     printf (_("  %#06x: Name index: %lx"),
+                     printf (_("  %#06x:   Name index: %lx"),
                              isum, aux.vna_name);
 
                    printf (_("  Flags: %s  Version: %d\n"),
@@ -5505,6 +5261,7 @@ process_version_sections (file)
            char *strtab;
            Elf_Internal_Sym *symbols;
            Elf_Internal_Shdr *string_sec;
+           long off;
 
            link_section = SECTION_HEADER (section->sh_link);
            total = section->sh_size / section->sh_entsize;
@@ -5515,9 +5272,8 @@ process_version_sections (file)
 
            string_sec = SECTION_HEADER (link_section->sh_link);
 
-           strtab = (char *) get_data (NULL, file, string_sec->sh_offset,
-                                       string_sec->sh_size,
-                                       _("version string table"));
+           strtab = get_data (NULL, file, string_sec->sh_offset,
+                              string_sec->sh_size, _("version string table"));
            if (!strtab)
              break;
 
@@ -5530,18 +5286,18 @@ process_version_sections (file)
                    (unsigned long) section->sh_offset, section->sh_link,
                    SECTION_NAME (link_section));
 
-           edata =
-             ((unsigned char *)
-              get_data (NULL, file,
-                        version_info[DT_VERSIONTAGIDX (DT_VERSYM)] - loadaddr,
-                        total * sizeof (short), _("version symbol data")));
+           off = offset_from_vma (file,
+                                  version_info[DT_VERSIONTAGIDX (DT_VERSYM)],
+                                  total * sizeof (short));
+           edata = get_data (NULL, file, off, total * sizeof (short),
+                             _("version symbol data"));
            if (!edata)
              {
                free (strtab);
                break;
              }
 
-           data = (unsigned short *) malloc (total * sizeof (short));
+           data = malloc (total * sizeof (short));
 
            for (cnt = total; cnt --;)
              data[cnt] = byte_get (edata + cnt * sizeof (short),
@@ -5589,8 +5345,9 @@ process_version_sections (file)
                          Elf_Internal_Verneed ivn;
                          unsigned long offset;
 
-                         offset = version_info[DT_VERSIONTAGIDX (DT_VERNEED)]
-                           - loadaddr;
+                         offset = offset_from_vma
+                           (file, version_info[DT_VERSIONTAGIDX (DT_VERNEED)],
+                            sizeof (Elf_External_Verneed));
 
                          do
                            {
@@ -5645,8 +5402,9 @@ process_version_sections (file)
                          Elf_External_Verdef evd;
                          unsigned long offset;
 
-                         offset = (version_info[DT_VERSIONTAGIDX (DT_VERDEF)]
-                                   - loadaddr);
+                         offset = offset_from_vma
+                           (file, version_info[DT_VERSIONTAGIDX (DT_VERDEF)],
+                            sizeof evd);
 
                          do
                            {
@@ -5707,8 +5465,7 @@ process_version_sections (file)
 }
 
 static const char *
-get_symbol_binding (binding)
-     unsigned int binding;
+get_symbol_binding (unsigned int binding)
 {
   static char buff[32];
 
@@ -5729,8 +5486,7 @@ get_symbol_binding (binding)
 }
 
 static const char *
-get_symbol_type (type)
-     unsigned int type;
+get_symbol_type (unsigned int type)
 {
   static char buff[32];
 
@@ -5776,8 +5532,7 @@ get_symbol_type (type)
 }
 
 static const char *
-get_symbol_visibility (visibility)
-     unsigned int visibility;
+get_symbol_visibility (unsigned int visibility)
 {
   switch (visibility)
     {
@@ -5790,8 +5545,7 @@ get_symbol_visibility (visibility)
 }
 
 static const char *
-get_symbol_index_type (type)
-     unsigned int type;
+get_symbol_index_type (unsigned int type)
 {
   static char buff[32];
 
@@ -5801,7 +5555,11 @@ get_symbol_index_type (type)
     case SHN_ABS:      return "ABS";
     case SHN_COMMON:   return "COM";
     default:
-      if (type >= SHN_LOPROC && type <= SHN_HIPROC)
+      if (type == SHN_IA_64_ANSI_COMMON
+         && elf_header.e_machine == EM_IA_64
+         && elf_header.e_ident[EI_OSABI] == ELFOSABI_HPUX)
+       return "ANSI_COM";
+      else if (type >= SHN_LOPROC && type <= SHN_HIPROC)
        sprintf (buff, "PRC[0x%04x]", type);
       else if (type >= SHN_LOOS && type <= SHN_HIOS)
        sprintf (buff, "OS [0x%04x]", type);
@@ -5816,14 +5574,12 @@ get_symbol_index_type (type)
 }
 
 static int *
-get_dynamic_data (file, number)
-     FILE *file;
-     unsigned int number;
+get_dynamic_data (FILE *file, unsigned int number)
 {
   unsigned char *e_data;
   int *i_data;
 
-  e_data = (unsigned char *) malloc (number * 4);
+  e_data = malloc (number * 4);
 
   if (e_data == NULL)
     {
@@ -5837,7 +5593,7 @@ get_dynamic_data (file, number)
       return NULL;
     }
 
-  i_data = (int *) malloc (number * sizeof (*i_data));
+  i_data = malloc (number * sizeof (*i_data));
 
   if (i_data == NULL)
     {
@@ -5856,8 +5612,7 @@ get_dynamic_data (file, number)
 
 /* Dump the symbol table.  */
 static int
-process_symbol_table (file)
-     FILE *file;
+process_symbol_table (FILE *file)
 {
   Elf_Internal_Shdr *section;
   unsigned char nb[4];
@@ -5873,7 +5628,11 @@ process_symbol_table (file)
   if (dynamic_info[DT_HASH] && ((do_using_dynamic && dynamic_strings != NULL)
                                || do_histogram))
     {
-      if (fseek (file, dynamic_info[DT_HASH] - loadaddr, SEEK_SET))
+      if (fseek (file,
+                (archive_file_offset
+                 + offset_from_vma (file, dynamic_info[DT_HASH],
+                                    sizeof nb + sizeof nc)),
+                SEEK_SET))
        {
          error (_("Unable to seek to start of dynamic information"));
          return 0;
@@ -5976,9 +5735,8 @@ process_symbol_table (file)
 
              string_sec = SECTION_HEADER (section->sh_link);
 
-             strtab = (char *) get_data (NULL, file, string_sec->sh_offset,
-                                         string_sec->sh_size,
-                                         _("string table"));
+             strtab = get_data (NULL, file, string_sec->sh_offset,
+                                string_sec->sh_size, _("string table"));
            }
 
          for (si = 0, psym = symtab;
@@ -6004,8 +5762,9 @@ process_symbol_table (file)
                  int is_nobits;
                  int check_def;
 
-                 offset = version_info[DT_VERSIONTAGIDX (DT_VERSYM)]
-                   - loadaddr;
+                 offset = offset_from_vma
+                   (file, version_info[DT_VERSIONTAGIDX (DT_VERSYM)],
+                    sizeof data + si * sizeof (vers_data));
 
                  get_data (&data, file, offset + si * sizeof (vers_data),
                            sizeof (data), _("version data"));
@@ -6027,8 +5786,9 @@ process_symbol_table (file)
                          Elf_Internal_Vernaux ivna;
 
                          /* We must test both.  */
-                         offset = (version_info[DT_VERSIONTAGIDX (DT_VERNEED)]
-                                   - loadaddr);
+                         offset = offset_from_vma
+                           (file, version_info[DT_VERSIONTAGIDX (DT_VERNEED)],
+                            sizeof evn);
 
                          do
                            {
@@ -6088,9 +5848,10 @@ process_symbol_table (file)
                              Elf_External_Verdaux evda;
                              unsigned long offset;
 
-                             offset
-                               = (version_info[DT_VERSIONTAGIDX (DT_VERDEF)]
-                                  - loadaddr);
+                             offset = offset_from_vma
+                               (file,
+                                version_info[DT_VERSIONTAGIDX (DT_VERDEF)],
+                                sizeof (Elf_External_Verdef));
 
                              do
                                {
@@ -6151,7 +5912,7 @@ process_symbol_table (file)
              nbuckets);
       printf (_(" Length  Number     %% of total  Coverage\n"));
 
-      lengths = (int *) calloc (nbuckets, sizeof (int));
+      lengths = calloc (nbuckets, sizeof (int));
       if (lengths == NULL)
        {
          error (_("Out of memory"));
@@ -6170,7 +5931,7 @@ process_symbol_table (file)
            }
        }
 
-      counts = (int *) calloc (maxlength + 1, sizeof (int));
+      counts = calloc (maxlength + 1, sizeof (int));
       if (counts == NULL)
        {
          error (_("Out of memory"));
@@ -6207,8 +5968,7 @@ process_symbol_table (file)
 }
 
 static int
-process_syminfo (file)
-     FILE *file ATTRIBUTE_UNUSED;
+process_syminfo (FILE *file ATTRIBUTE_UNUSED)
 {
   unsigned int i;
 
@@ -6274,9 +6034,7 @@ process_syminfo (file)
 
 #ifdef SUPPORT_DISASSEMBLY
 static void
-disassemble_section (section, file)
-     Elf_Internal_Shdr *section;
-     FILE *file;
+disassemble_section (Elf_Internal_Shdr *section, FILE *file)
 {
   printf (_("\nAssembly dump of section %s\n"),
          SECTION_NAME (section));
@@ -6288,9 +6046,7 @@ disassemble_section (section, file)
 #endif
 
 static int
-dump_section (section, file)
-     Elf_Internal_Shdr *section;
-     FILE *file;
+dump_section (Elf_Internal_Shdr *section, FILE *file)
 {
   bfd_size_type bytes;
   bfd_vma addr;
@@ -6299,7 +6055,7 @@ dump_section (section, file)
 
   bytes = section->sh_size;
 
-  if (bytes == 0)
+  if (bytes == 0 || section->sh_type == SHT_NOBITS)
     {
       printf (_("\nSection '%s' has no data to dump.\n"),
              SECTION_NAME (section));
@@ -6310,8 +6066,7 @@ dump_section (section, file)
 
   addr = section->sh_addr;
 
-  start = (unsigned char *) get_data (NULL, file, section->sh_offset, bytes,
-                                     _("section data"));
+  start = get_data (NULL, file, section->sh_offset, bytes, _("section data"));
   if (!start)
     return 0;
 
@@ -6360,7 +6115,7 @@ dump_section (section, file)
       for (j = 0; j < lbytes; j++)
        {
          k = data[j];
-         if (k >= ' ' && k < 0x80)
+         if (k >= ' ' && k < 0x7f)
            printf ("%c", k);
          else
            printf (".");
@@ -6380,10 +6135,7 @@ dump_section (section, file)
 
 
 static unsigned long int
-read_leb128 (data, length_return, sign)
-     unsigned char *data;
-     int *length_return;
-     int sign;
+read_leb128 (unsigned char *data, int *length_return, int sign)
 {
   unsigned long int result = 0;
   unsigned int num_read = 0;
@@ -6428,8 +6180,7 @@ typedef struct State_Machine_Registers
 static SMR state_machine_regs;
 
 static void
-reset_state_machine (is_stmt)
-     int is_stmt;
+reset_state_machine (int is_stmt)
 {
   state_machine_regs.address = 0;
   state_machine_regs.file = 1;
@@ -6444,10 +6195,7 @@ reset_state_machine (is_stmt)
 /* Handled an extend line op.  Returns true if this is the end
    of sequence.  */
 static int
-process_extended_line_op (data, is_stmt, pointer_size)
-     unsigned char *data;
-     int is_stmt;
-     int pointer_size;
+process_extended_line_op (unsigned char *data, int is_stmt, int pointer_size)
 {
   unsigned char op_code;
   int bytes_read;
@@ -6511,10 +6259,9 @@ process_extended_line_op (data, is_stmt, pointer_size)
 static int debug_line_pointer_size = 4;
 
 static int
-display_debug_lines (section, start, file)
-     Elf_Internal_Shdr *section;
-     unsigned char * start;
-     FILE *file ATTRIBUTE_UNUSED;
+display_debug_lines (Elf_Internal_Shdr *section,
+                    unsigned char * start,
+                    FILE *file ATTRIBUTE_UNUSED)
 {
   unsigned char *hdrptr;
   DWARF2_Internal_LineInfo info;
@@ -6786,10 +6533,9 @@ display_debug_lines (section, start, file)
 }
 
 static int
-display_debug_pubnames (section, start, file)
-     Elf_Internal_Shdr *section;
-     unsigned char *start;
-     FILE *file ATTRIBUTE_UNUSED;
+display_debug_pubnames (Elf_Internal_Shdr *section,
+                       unsigned char *start,
+                       FILE *file ATTRIBUTE_UNUSED)
 {
   DWARF2_Internal_PubNames pubnames;
   unsigned char *end;
@@ -6873,8 +6619,7 @@ display_debug_pubnames (section, start, file)
 }
 
 static char *
-get_TAG_name (tag)
-     unsigned long tag;
+get_TAG_name (unsigned long tag)
 {
   switch (tag)
     {
@@ -6954,8 +6699,7 @@ get_TAG_name (tag)
 }
 
 static char *
-get_AT_name (attribute)
-     unsigned long attribute;
+get_AT_name (unsigned long attribute)
 {
   switch (attribute)
     {
@@ -7068,8 +6812,7 @@ get_AT_name (attribute)
 }
 
 static char *
-get_FORM_name (form)
-     unsigned long form;
+get_FORM_name (unsigned long form)
 {
   switch (form)
     {
@@ -7104,7 +6847,7 @@ get_FORM_name (form)
     }
 }
 
-/* FIXME:  There are better and more effiecint ways to handle
+/* FIXME:  There are better and more efficient ways to handle
    these structures.  For now though, I just want something that
    is simple to implement.  */
 typedef struct abbrev_attr
@@ -7130,7 +6873,7 @@ static abbrev_entry *first_abbrev = NULL;
 static abbrev_entry *last_abbrev = NULL;
 
 static void
-free_abbrevs ()
+free_abbrevs (void)
 {
   abbrev_entry *abbrev;
 
@@ -7155,14 +6898,11 @@ free_abbrevs ()
 }
 
 static void
-add_abbrev (number, tag, children)
-     unsigned long number;
-     unsigned long tag;
-     int children;
+add_abbrev (unsigned long number, unsigned long tag, int children)
 {
   abbrev_entry *entry;
 
-  entry = (abbrev_entry *) malloc (sizeof (*entry));
+  entry = malloc (sizeof (*entry));
 
   if (entry == NULL)
     /* ugg */
@@ -7184,13 +6924,11 @@ add_abbrev (number, tag, children)
 }
 
 static void
-add_abbrev_attr (attribute, form)
-     unsigned long attribute;
-     unsigned long form;
+add_abbrev_attr (unsigned long attribute, unsigned long form)
 {
   abbrev_attr *attr;
 
-  attr = (abbrev_attr *) malloc (sizeof (*attr));
+  attr = malloc (sizeof (*attr));
 
   if (attr == NULL)
     /* ugg */
@@ -7214,9 +6952,7 @@ add_abbrev_attr (attribute, form)
    an abbreviation set was found.  */
 
 static unsigned char *
-process_abbrev_section (start, end)
-     unsigned char *start;
-     unsigned char *end;
+process_abbrev_section (unsigned char *start, unsigned char *end)
 {
   if (first_abbrev != NULL)
     return NULL;
@@ -7266,10 +7002,9 @@ process_abbrev_section (start, end)
 
 
 static int
-display_debug_macinfo (section, start, file)
-     Elf_Internal_Shdr *section;
-     unsigned char *start;
-     FILE *file ATTRIBUTE_UNUSED;
+display_debug_macinfo (Elf_Internal_Shdr *section,
+                      unsigned char *start,
+                      FILE *file ATTRIBUTE_UNUSED)
 {
   unsigned char *end = start + section->sh_size;
   unsigned char *curr = start;
@@ -7340,10 +7075,9 @@ display_debug_macinfo (section, start, file)
 
 
 static int
-display_debug_abbrev (section, start, file)
-     Elf_Internal_Shdr *section;
-     unsigned char *start;
-     FILE *file ATTRIBUTE_UNUSED;
+display_debug_abbrev (Elf_Internal_Shdr *section,
+                     unsigned char *start,
+                     FILE *file ATTRIBUTE_UNUSED)
 {
   abbrev_entry *entry;
   unsigned char *end = start + section->sh_size;
@@ -7387,9 +7121,7 @@ display_debug_abbrev (section, start, file)
 
 
 static unsigned char *
-display_block (data, length)
-     unsigned char *data;
-     unsigned long length;
+display_block (unsigned char *data, unsigned long length)
 {
   printf (_(" %lu byte block: "), length);
 
@@ -7400,10 +7132,9 @@ display_block (data, length)
 }
 
 static void
-decode_location_expression (data, pointer_size, length)
-     unsigned char * data;
-     unsigned int pointer_size;
-     unsigned long length;
+decode_location_expression (unsigned char * data,
+                           unsigned int pointer_size,
+                           unsigned long length)
 {
   unsigned op;
   int bytes_read;
@@ -7736,8 +7467,7 @@ static const char *debug_loc_contents;
 static bfd_vma debug_loc_size;
 
 static void
-load_debug_loc (file)
-     FILE *file;
+load_debug_loc (FILE *file)
 {
   Elf_Internal_Shdr *sec;
   unsigned int i;
@@ -7758,13 +7488,12 @@ load_debug_loc (file)
 
   debug_loc_size = sec->sh_size;
 
-  debug_loc_contents = ((char *)
-                       get_data (NULL, file, sec->sh_offset, sec->sh_size,
-                                 _("debug_loc section data")));
+  debug_loc_contents = get_data (NULL, file, sec->sh_offset, sec->sh_size,
+                                _("debug_loc section data"));
 }
 
 static void
-free_debug_loc ()
+free_debug_loc (void)
 {
   if (debug_loc_contents == NULL)
     return;
@@ -7776,10 +7505,9 @@ free_debug_loc ()
 
 
 static int
-display_debug_loc (section, start, file)
-     Elf_Internal_Shdr *section;
-     unsigned char *start;
-     FILE *file ATTRIBUTE_UNUSED;
+display_debug_loc (Elf_Internal_Shdr *section,
+                  unsigned char *start,
+                  FILE *file ATTRIBUTE_UNUSED)
 {
   unsigned char *section_end;
   unsigned long bytes;
@@ -7813,7 +7541,7 @@ display_debug_loc (section, start, file)
          /* Normally, the lists in the debug_loc section are related to a
             given compilation unit, and thus, we would use the pointer size
             of that compilation unit.  However, since we are displaying it
-            seperately here, we either have to store pointer sizes of all
+            separately here, we either have to store pointer sizes of all
             compilation units, or assume they don't change.   We assume,
             like the debug_line display, that it doesn't change.  */
          begin = byte_get (start, debug_line_pointer_size);
@@ -7849,8 +7577,7 @@ static const char *debug_str_contents;
 static bfd_vma debug_str_size;
 
 static void
-load_debug_str (file)
-     FILE *file;
+load_debug_str (FILE *file)
 {
   Elf_Internal_Shdr *sec;
   unsigned int i;
@@ -7871,13 +7598,12 @@ load_debug_str (file)
 
   debug_str_size = sec->sh_size;
 
-  debug_str_contents = ((char *)
-                       get_data (NULL, file, sec->sh_offset, sec->sh_size,
-                                 _("debug_str section data")));
+  debug_str_contents = get_data (NULL, file, sec->sh_offset, sec->sh_size,
+                                _("debug_str section data"));
 }
 
 static void
-free_debug_str ()
+free_debug_str (void)
 {
   if (debug_str_contents == NULL)
     return;
@@ -7888,8 +7614,7 @@ free_debug_str ()
 }
 
 static const char *
-fetch_indirect_string (offset)
-     unsigned long offset;
+fetch_indirect_string (unsigned long offset)
 {
   if (debug_str_contents == NULL)
     return _("<no .debug_str section>");
@@ -7901,10 +7626,9 @@ fetch_indirect_string (offset)
 }
 
 static int
-display_debug_str (section, start, file)
-     Elf_Internal_Shdr *section;
-     unsigned char *start;
-     FILE *file ATTRIBUTE_UNUSED;
+display_debug_str (Elf_Internal_Shdr *section,
+                  unsigned char *start,
+                  FILE *file ATTRIBUTE_UNUSED)
 {
   unsigned long bytes;
   bfd_vma addr;
@@ -7961,15 +7685,13 @@ display_debug_str (section, start, file)
 }
 
 static unsigned char *
-read_and_display_attr_value (attribute, form, data, cu_offset, pointer_size,
-                             offset_size, dwarf_version)
-     unsigned long attribute;
-     unsigned long form;
-     unsigned char *data;
-     unsigned long cu_offset;
-     unsigned long pointer_size;
-     unsigned long offset_size;
-     int dwarf_version;
+read_and_display_attr_value (unsigned long attribute,
+                            unsigned long form,
+                            unsigned char *data,
+                            unsigned long cu_offset,
+                            unsigned long pointer_size,
+                            unsigned long offset_size,
+                            int dwarf_version)
 {
   unsigned long uvalue = 0;
   unsigned char *block_start = NULL;
@@ -8121,7 +7843,7 @@ read_and_display_attr_value (attribute, form, data, cu_offset, pointer_size,
       break;
     }
 
-  /* For some attributes we can display futher information.  */
+  /* For some attributes we can display further information.  */
 
   printf ("\t");
 
@@ -8298,15 +8020,13 @@ read_and_display_attr_value (attribute, form, data, cu_offset, pointer_size,
 }
 
 static unsigned char *
-read_and_display_attr (attribute, form, data, cu_offset, pointer_size,
-                       offset_size, dwarf_version)
-     unsigned long attribute;
-     unsigned long form;
-     unsigned char *data;
-     unsigned long cu_offset;
-     unsigned long pointer_size;
-     unsigned long offset_size;
-     int dwarf_version;
+read_and_display_attr (unsigned long attribute,
+                      unsigned long form,
+                      unsigned char *data,
+                      unsigned long cu_offset,
+                      unsigned long pointer_size,
+                      unsigned long offset_size,
+                      int dwarf_version)
 {
   printf ("     %-18s:", get_AT_name (attribute));
   data = read_and_display_attr_value (attribute, form, data, cu_offset,
@@ -8316,10 +8036,9 @@ read_and_display_attr (attribute, form, data, cu_offset, pointer_size,
 }
 
 static int
-display_debug_info (section, start, file)
-     Elf_Internal_Shdr *section;
-     unsigned char *start;
-     FILE *file;
+display_debug_info (Elf_Internal_Shdr *section,
+                   unsigned char *start,
+                   FILE *file)
 {
   unsigned char *end = start + section->sh_size;
   unsigned char *section_begin = start;
@@ -8472,9 +8191,8 @@ display_debug_info (section, start, file)
            return 0;
          }
 
-       begin = ((unsigned char *)
-                get_data (NULL, file, sec->sh_offset, sec->sh_size,
-                          _("debug_abbrev section data")));
+       begin = get_data (NULL, file, sec->sh_offset, sec->sh_size,
+                         _("debug_abbrev section data"));
        if (!begin)
          return 0;
 
@@ -8544,10 +8262,9 @@ display_debug_info (section, start, file)
 }
 
 static int
-display_debug_aranges (section, start, file)
-     Elf_Internal_Shdr *section;
-     unsigned char *start;
-     FILE *file ATTRIBUTE_UNUSED;
+display_debug_aranges (Elf_Internal_Shdr *section,
+                      unsigned char *start,
+                      FILE *file ATTRIBUTE_UNUSED)
 {
   unsigned char *end = start + section->sh_size;
 
@@ -8665,14 +8382,8 @@ 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;
-     int reg;
+frame_need_space (Frame_Chunk *fc, int reg)
 {
   int prev = fc->ncols;
 
@@ -8680,10 +8391,8 @@ frame_need_space (fc, reg)
     return;
 
   fc->ncols = reg + 1;
-  fc->col_type = (short int *) xrealloc (fc->col_type,
-                                        fc->ncols * sizeof (short int));
-  fc->col_offset = (int *) xrealloc (fc->col_offset,
-                                    fc->ncols * sizeof (int));
+  fc->col_type = xrealloc (fc->col_type, fc->ncols * sizeof (short int));
+  fc->col_offset = xrealloc (fc->col_offset, fc->ncols * sizeof (int));
 
   while (prev < fc->ncols)
     {
@@ -8694,10 +8403,7 @@ frame_need_space (fc, reg)
 }
 
 static void
-frame_display_row (fc, need_col_headers, max_regs)
-     Frame_Chunk *fc;
-     int *need_col_headers;
-     int *max_regs;
+frame_display_row (Frame_Chunk *fc, int *need_col_headers, int *max_regs)
 {
   int r;
   char tmp[100];
@@ -8762,8 +8468,7 @@ frame_display_row (fc, need_col_headers, max_regs)
 }
 
 static int
-size_of_encoded_value (encoding)
-     int encoding;
+size_of_encoded_value (int encoding)
 {
   switch (encoding & 0x7)
     {
@@ -8775,15 +8480,24 @@ size_of_encoded_value (encoding)
     }
 }
 
+static bfd_vma
+get_encoded_value (unsigned char *data, int encoding)
+{
+  int size = size_of_encoded_value (encoding);
+  if (encoding & DW_EH_PE_signed)
+    return byte_get_signed (data, size);
+  else
+    return byte_get (data, size);
+}
+
 #define GET(N) byte_get (start, N); start += N
 #define LEB()  read_leb128 (start, & length_return, 0); start += length_return
 #define SLEB() read_leb128 (start, & length_return, 1); start += length_return
 
 static int
-display_debug_frames (section, start, file)
-     Elf_Internal_Shdr *section;
-     unsigned char *start;
-     FILE *file ATTRIBUTE_UNUSED;
+display_debug_frames (Elf_Internal_Shdr *section,
+                     unsigned char *start,
+                     FILE *file ATTRIBUTE_UNUSED)
 {
   unsigned char *end = start + section->sh_size;
   unsigned char *section_start = start;
@@ -8842,15 +8556,15 @@ display_debug_frames (section, start, file)
        {
          int version;
 
-         fc = (Frame_Chunk *) xmalloc (sizeof (Frame_Chunk));
+         fc = xmalloc (sizeof (Frame_Chunk));
          memset (fc, 0, sizeof (Frame_Chunk));
 
          fc->next = chunks;
          chunks = fc;
          fc->chunk_start = saved_start;
          fc->ncols = 0;
-         fc->col_type = (short int *) xmalloc (sizeof (short int));
-         fc->col_offset = (int *) xmalloc (sizeof (int));
+         fc->col_type = xmalloc (sizeof (short int));
+         fc->col_offset = xmalloc (sizeof (int));
          frame_need_space (fc, max_regs-1);
 
          version = *start++;
@@ -8953,8 +8667,8 @@ display_debug_frames (section, start, file)
                    cie_id, saved_start);
              start = block_end;
              fc->ncols = 0;
-             fc->col_type = (short int *) xmalloc (sizeof (short int));
-             fc->col_offset = (int *) xmalloc (sizeof (int));
+             fc->col_type = xmalloc (sizeof (short int));
+             fc->col_offset = xmalloc (sizeof (int));
              frame_need_space (fc, max_regs - 1);
              cie = fc;
              fc->augmentation = "";
@@ -8963,8 +8677,8 @@ display_debug_frames (section, start, file)
          else
            {
              fc->ncols = cie->ncols;
-             fc->col_type = (short int *) xmalloc (fc->ncols * sizeof (short int));
-             fc->col_offset = (int *) xmalloc (fc->ncols * sizeof (int));
+             fc->col_type = xmalloc (fc->ncols * sizeof (short int));
+             fc->col_offset = xmalloc (fc->ncols * sizeof (int));
              memcpy (fc->col_type, cie->col_type, fc->ncols * sizeof (short int));
              memcpy (fc->col_offset, cie->col_offset, fc->ncols * sizeof (int));
              fc->augmentation = cie->augmentation;
@@ -8980,7 +8694,7 @@ display_debug_frames (section, start, file)
          if (fc->fde_encoding)
            encoded_ptr_size = size_of_encoded_value (fc->fde_encoding);
 
-         fc->pc_begin = byte_get (start, encoded_ptr_size);
+         fc->pc_begin = get_encoded_value (start, fc->fde_encoding);
          if ((fc->fde_encoding & 0x70) == DW_EH_PE_pcrel)
            fc->pc_begin += section->sh_addr + (start - section_start);
          start += encoded_ptr_size;
@@ -9011,8 +8725,12 @@ display_debug_frames (section, start, file)
 
       /* At this point, fc is the current chunk, cie (if any) is set, and we're
         about to interpret instructions for the chunk.  */
-
-      if (do_debug_frames_interp)
+      /* ??? At present we need to do this always, since this sizes the
+        fc->col_type and fc->col_offset arrays, which we write into always.
+        We should probably split the interpreted and non-interpreted bits
+        into two different routines, since there's so much that doesn't
+        really overlap between them.  */
+      if (1 || do_debug_frames_interp)
        {
          /* Start by making a pass over the chunk, allocating storage
             and taking note of what registers are used.  */
@@ -9175,7 +8893,7 @@ display_debug_frames (section, start, file)
              break;
 
            case DW_CFA_set_loc:
-             vma = byte_get (start, encoded_ptr_size);
+             vma = get_encoded_value (start, fc->fde_encoding);
              if ((fc->fde_encoding & 0x70) == DW_EH_PE_pcrel)
                vma += section->sh_addr + (start - section_start);
              start += encoded_ptr_size;
@@ -9257,7 +8975,7 @@ display_debug_frames (section, start, file)
              reg = LEB ();
              roffs = LEB ();
              if (! do_debug_frames_interp)
-               printf ("  DW_CFA_register: r%ld\n", reg);
+               printf ("  DW_CFA_register: r%ld in r%ld\n", reg, roffs);
              fc->col_type[reg] = DW_CFA_register;
              fc->col_offset[reg] = roffs;
              break;
@@ -9265,10 +8983,10 @@ display_debug_frames (section, start, file)
            case DW_CFA_remember_state:
              if (! do_debug_frames_interp)
                printf ("  DW_CFA_remember_state\n");
-             rs = (Frame_Chunk *) xmalloc (sizeof (Frame_Chunk));
+             rs = xmalloc (sizeof (Frame_Chunk));
              rs->ncols = fc->ncols;
-             rs->col_type = (short int *) xmalloc (rs->ncols * sizeof (short int));
-             rs->col_offset = (int *) xmalloc (rs->ncols * sizeof (int));
+             rs->col_type = xmalloc (rs->ncols * sizeof (short int));
+             rs->col_offset = xmalloc (rs->ncols * sizeof (int));
              memcpy (rs->col_type, fc->col_type, rs->ncols);
              memcpy (rs->col_offset, fc->col_offset, rs->ncols * sizeof (int));
              rs->next = remembered_state;
@@ -9421,10 +9139,9 @@ display_debug_frames (section, start, file)
 #undef SLEB
 
 static int
-display_debug_not_supported (section, start, file)
-     Elf_Internal_Shdr *section;
-     unsigned char *start ATTRIBUTE_UNUSED;
-     FILE *file ATTRIBUTE_UNUSED;
+display_debug_not_supported (Elf_Internal_Shdr *section,
+                            unsigned char *start ATTRIBUTE_UNUSED,
+                            FILE *file ATTRIBUTE_UNUSED)
 {
   printf (_("Displaying the debug contents of section %s is not yet supported.\n"),
            SECTION_NAME (section));
@@ -9436,10 +9153,9 @@ display_debug_not_supported (section, start, file)
    When dumping the .debug_line, we use that size information, assuming
    that all compilation units have the same address size.  */
 static int
-prescan_debug_info (section, start, file)
-     Elf_Internal_Shdr *section ATTRIBUTE_UNUSED;
-     unsigned char *start;
-     FILE *file ATTRIBUTE_UNUSED;
+prescan_debug_info (Elf_Internal_Shdr *section ATTRIBUTE_UNUSED,
+                   unsigned char *start,
+                   FILE *file ATTRIBUTE_UNUSED)
 {
   unsigned long length;
 
@@ -9486,8 +9202,8 @@ prescan_debug_info (section, start, file)
 struct
 {
   const char *const name;
-  int (*display) PARAMS ((Elf_Internal_Shdr *, unsigned char *, FILE *));
-  int (*prescan) PARAMS ((Elf_Internal_Shdr *, unsigned char *, FILE *));
+  int (*display) (Elf_Internal_Shdr *, unsigned char *, FILE *);
+  int (*prescan) (Elf_Internal_Shdr *, unsigned char *, FILE *);
 }
 debug_displays[] =
 {
@@ -9510,9 +9226,7 @@ debug_displays[] =
 };
 
 static int
-display_debug_section (section, file)
-     Elf_Internal_Shdr *section;
-     FILE *file;
+display_debug_section (Elf_Internal_Shdr *section, FILE *file)
 {
   char *name = SECTION_NAME (section);
   bfd_size_type length;
@@ -9526,8 +9240,8 @@ display_debug_section (section, file)
       return 0;
     }
 
-  start = (unsigned char *) get_data (NULL, file, section->sh_offset, length,
-                                     _("debug section data"));
+  start = get_data (NULL, file, section->sh_offset, length,
+                   _("debug section data"));
   if (!start)
     return 0;
 
@@ -9555,8 +9269,7 @@ display_debug_section (section, file)
 }
 
 static int
-process_section_contents (file)
-     FILE *file;
+process_section_contents (FILE *file)
 {
   Elf_Internal_Shdr *section;
   unsigned int i;
@@ -9587,9 +9300,8 @@ process_section_contents (file)
                unsigned char *start;
 
                length = section->sh_size;
-               start = ((unsigned char *)
-                        get_data (NULL, file, section->sh_offset, length,
-                                  _("debug section data")));
+               start = get_data (NULL, file, section->sh_offset, length,
+                                 _("debug section data"));
                if (!start)
                  return 0;
 
@@ -9623,8 +9335,7 @@ process_section_contents (file)
 }
 
 static void
-process_mips_fpe_exception (mask)
-     int mask;
+process_mips_fpe_exception (int mask)
 {
   if (mask)
     {
@@ -9645,8 +9356,7 @@ process_mips_fpe_exception (mask)
 }
 
 static int
-process_mips_specific (file)
-     FILE *file;
+process_mips_specific (FILE *file)
 {
   Elf_Internal_Dyn *entry;
   size_t liblist_offset = 0;
@@ -9664,16 +9374,20 @@ process_mips_specific (file)
     switch (entry->d_tag)
       {
       case DT_MIPS_LIBLIST:
-       liblist_offset = entry->d_un.d_val - loadaddr;
+       liblist_offset
+         = offset_from_vma (file, entry->d_un.d_val,
+                            liblistno * sizeof (Elf32_External_Lib));
        break;
       case DT_MIPS_LIBLISTNO:
        liblistno = entry->d_un.d_val;
        break;
       case DT_MIPS_OPTIONS:
-       options_offset = entry->d_un.d_val - loadaddr;
+       options_offset = offset_from_vma (file, entry->d_un.d_val, 0);
        break;
       case DT_MIPS_CONFLICT:
-       conflicts_offset = entry->d_un.d_val - loadaddr;
+       conflicts_offset
+         = offset_from_vma (file, entry->d_un.d_val,
+                            conflictsno * sizeof (Elf32_External_Conflict));
        break;
       case DT_MIPS_CONFLICTNO:
        conflictsno = entry->d_un.d_val;
@@ -9687,10 +9401,9 @@ process_mips_specific (file)
       Elf32_External_Lib *elib;
       size_t cnt;
 
-      elib = ((Elf32_External_Lib *)
-             get_data (NULL, file, liblist_offset,
-                       liblistno * sizeof (Elf32_External_Lib),
-                       _("liblist")));
+      elib = get_data (NULL, file, liblist_offset,
+                      liblistno * sizeof (Elf32_External_Lib),
+                      _("liblist"));
       if (elib)
        {
          printf ("\nSection '.liblist' contains %lu entries:\n",
@@ -9774,12 +9487,11 @@ process_mips_specific (file)
       while (sect->sh_type != SHT_MIPS_OPTIONS)
        ++sect;
 
-      eopt = (Elf_External_Options *) get_data (NULL, file, options_offset,
-                                               sect->sh_size, _("options"));
+      eopt = get_data (NULL, file, options_offset, sect->sh_size,
+                      _("options"));
       if (eopt)
        {
-         iopt = ((Elf_Internal_Options *)
-                 malloc ((sect->sh_size / sizeof (eopt)) * sizeof (*iopt)));
+         iopt = malloc ((sect->sh_size / sizeof (eopt)) * sizeof (*iopt));
          if (iopt == NULL)
            {
              error (_("Out of memory"));
@@ -9971,7 +9683,7 @@ process_mips_specific (file)
          return 0;
        }
 
-      iconf = (Elf32_Conflict *) malloc (conflictsno * sizeof (*iconf));
+      iconf = malloc (conflictsno * sizeof (*iconf));
       if (iconf == NULL)
        {
          error (_("Out of memory"));
@@ -9982,10 +9694,8 @@ process_mips_specific (file)
        {
          Elf32_External_Conflict *econf32;
 
-         econf32 = ((Elf32_External_Conflict *)
-                    get_data (NULL, file, conflicts_offset,
-                              conflictsno * sizeof (*econf32),
-                              _("conflict")));
+         econf32 = get_data (NULL, file, conflicts_offset,
+                             conflictsno * sizeof (*econf32), _("conflict"));
          if (!econf32)
            return 0;
 
@@ -9998,10 +9708,8 @@ process_mips_specific (file)
        {
          Elf64_External_Conflict *econf64;
 
-         econf64 = ((Elf64_External_Conflict *)
-                    get_data (NULL, file, conflicts_offset,
-                              conflictsno * sizeof (*econf64),
-                              _("conflict")));
+         econf64 = get_data (NULL, file, conflicts_offset,
+                             conflictsno * sizeof (*econf64), _("conflict"));
          if (!econf64)
            return 0;
 
@@ -10033,8 +9741,7 @@ process_mips_specific (file)
 }
 
 static int
-process_gnu_liblist (file)
-     FILE *file;
+process_gnu_liblist (FILE *file)
 {
   Elf_Internal_Shdr *section, *string_sec;
   Elf32_External_Lib *elib;
@@ -10052,17 +9759,15 @@ process_gnu_liblist (file)
       switch (section->sh_type)
        {
        case SHT_GNU_LIBLIST:
-         elib = ((Elf32_External_Lib *)
-                get_data (NULL, file, section->sh_offset, section->sh_size,
-                          _("liblist")));
+         elib = get_data (NULL, file, section->sh_offset, section->sh_size,
+                          _("liblist"));
 
          if (elib == NULL)
            break;
          string_sec = SECTION_HEADER (section->sh_link);
 
-         strtab = (char *) get_data (NULL, file, string_sec->sh_offset,
-                                     string_sec->sh_size,
-                                     _("liblist string table"));
+         strtab = get_data (NULL, file, string_sec->sh_offset,
+                            string_sec->sh_size, _("liblist string table"));
 
          if (strtab == NULL
              || section->sh_entsize != sizeof (Elf32_External_Lib))
@@ -10113,8 +9818,7 @@ process_gnu_liblist (file)
 }
 
 static const char *
-get_note_type (e_type)
-     unsigned e_type;
+get_note_type (unsigned e_type)
 {
   static char buff[64];
 
@@ -10138,8 +9842,7 @@ get_note_type (e_type)
 }
 
 static const char *
-get_netbsd_elfcore_note_type (e_type)
-     unsigned e_type;
+get_netbsd_elfcore_note_type (unsigned e_type)
 {
   static char buff[64];
 
@@ -10205,8 +9908,7 @@ get_netbsd_elfcore_note_type (e_type)
 
    If the value of namesz is zero, there is no name present.  */
 static int
-process_note (pnote)
-     Elf_Internal_Note *pnote;
+process_note (Elf_Internal_Note *pnote)
 {
   const char *nt;
 
@@ -10236,10 +9938,7 @@ process_note (pnote)
 
 
 static int
-process_corefile_note_segment (file, offset, length)
-     FILE *file;
-     bfd_vma offset;
-     bfd_vma length;
+process_corefile_note_segment (FILE *file, bfd_vma offset, bfd_vma length)
 {
   Elf_External_Note *pnotes;
   Elf_External_Note *external;
@@ -10248,8 +9947,7 @@ process_corefile_note_segment (file, offset, length)
   if (length <= 0)
     return 0;
 
-  pnotes = (Elf_External_Note *) get_data (NULL, file, offset, length,
-                                          _("notes"));
+  pnotes = get_data (NULL, file, offset, length, _("notes"));
   if (!pnotes)
     return 0;
 
@@ -10322,33 +10020,14 @@ process_corefile_note_segment (file, offset, length)
 }
 
 static int
-process_corefile_note_segments (file)
-     FILE *file;
+process_corefile_note_segments (FILE *file)
 {
-  Elf_Internal_Phdr *program_headers;
   Elf_Internal_Phdr *segment;
   unsigned int i;
   int res = 1;
 
-  program_headers = (Elf_Internal_Phdr *) malloc
-    (elf_header.e_phnum * sizeof (Elf_Internal_Phdr));
-
-  if (program_headers == NULL)
-    {
-      error (_("Out of memory\n"));
+  if (! get_program_headers (file))
       return 0;
-    }
-
-  if (is_32bit_elf)
-    i = get_32bit_program_headers (file, program_headers);
-  else
-    i = get_64bit_program_headers (file, program_headers);
-
-  if (i == 0)
-    {
-      free (program_headers);
-      return 0;
-    }
 
   for (i = 0, segment = program_headers;
        i < elf_header.e_phnum;
@@ -10360,14 +10039,11 @@ process_corefile_note_segments (file)
                                              (bfd_vma) segment->p_filesz);
     }
 
-  free (program_headers);
-
   return res;
 }
 
 static int
-process_corefile_contents (file)
-     FILE *file;
+process_corefile_contents (FILE *file)
 {
   /* If we have not been asked to display the notes then do nothing.  */
   if (! do_notes)
@@ -10388,8 +10064,7 @@ process_corefile_contents (file)
 }
 
 static int
-process_arch_specific (file)
-     FILE *file;
+process_arch_specific (FILE *file)
 {
   if (! do_arch)
     return 1;
@@ -10407,8 +10082,7 @@ process_arch_specific (file)
 }
 
 static int
-get_file_header (file)
-     FILE *file;
+get_file_header (FILE *file)
 {
   /* Read in the identity array.  */
   if (fread (elf_header.e_ident, EI_NIDENT, 1, file) != 1)
@@ -10461,7 +10135,7 @@ get_file_header (file)
       /* If we have been compiled with sizeof (bfd_vma) == 4, then
         we will not be able to cope with the 64bit data found in
         64 ELF files.  Detect this now and abort before we start
-        overwritting things.  */
+        overwriting things.  */
       if (sizeof (bfd_vma) < 8)
        {
          error (_("This instance of readelf has been built without support for a\n\
@@ -10500,31 +10174,18 @@ get_file_header (file)
   return 1;
 }
 
+/* Process one ELF object file according to the command line options.
+   This file may actually be stored in an archive.  The file is
+   positioned at the start of the ELF object.  */
+
 static int
-process_file (file_name)
-     char *file_name;
+process_object (char *file_name, FILE *file)
 {
-  FILE *file;
-  struct stat statbuf;
   unsigned int i;
 
-  if (stat (file_name, & statbuf) < 0)
-    {
-      error (_("Cannot stat input file %s.\n"), file_name);
-      return 1;
-    }
-
-  file = fopen (file_name, "rb");
-  if (file == NULL)
-    {
-      error (_("Input file %s not found.\n"), file_name);
-      return 1;
-    }
-
   if (! get_file_header (file))
     {
       error (_("%s: Failed to read file header\n"), file_name);
-      fclose (file);
       return 1;
     }
 
@@ -10540,10 +10201,7 @@ process_file (file_name)
     printf (_("\nFile: %s\n"), file_name);
 
   if (! process_file_header ())
-    {
-      fclose (file);
-      return 1;
-    }
+    return 1;
 
   if (! process_section_headers (file))
     {
@@ -10576,7 +10234,11 @@ process_file (file_name)
 
   process_arch_specific (file);
 
-  fclose (file);
+  if (program_headers)
+    {
+      free (program_headers);
+      program_headers = NULL;
+    }
 
   if (section_headers)
     {
@@ -10613,6 +10275,220 @@ process_file (file_name)
   return 0;
 }
 
+/* Process an ELF archive.  The file is positioned just after the
+   ARMAG string.  */
+
+static int
+process_archive (char *file_name, FILE *file)
+{
+  struct ar_hdr arhdr;
+  size_t got;
+  unsigned long size;
+  char *longnames = NULL;
+  unsigned long longnames_size = 0;
+  size_t file_name_size;
+  int ret;
+
+  show_name = 1;
+
+  got = fread (&arhdr, 1, sizeof arhdr, file);
+  if (got != sizeof arhdr)
+    {
+      if (got == 0)
+       return 0;
+
+      error (_("%s: failed to read archive header\n"), file_name);
+      return 1;
+    }
+
+  if (memcmp (arhdr.ar_name, "/               ", 16) == 0)
+    {
+      /* This is the archive symbol table.  Skip it.
+        FIXME: We should have an option to dump it.  */
+      size = strtoul (arhdr.ar_size, NULL, 10);
+      if (fseek (file, size + (size & 1), SEEK_CUR) != 0)
+       {
+         error (_("%s: failed to skip archive symbol table\n"), file_name);
+         return 1;
+       }
+
+      got = fread (&arhdr, 1, sizeof arhdr, file);
+      if (got != sizeof arhdr)
+       {
+         if (got == 0)
+           return 0;
+
+         error (_("%s: failed to read archive header\n"), file_name);
+         return 1;
+       }
+    }
+
+  if (memcmp (arhdr.ar_name, "//              ", 16) == 0)
+    {
+      /* This is the archive string table holding long member
+        names.  */
+
+      longnames_size = strtoul (arhdr.ar_size, NULL, 10);
+
+      longnames = malloc (longnames_size);
+      if (longnames == NULL)
+       {
+         error (_("Out of memory\n"));
+         return 1;
+       }
+
+      if (fread (longnames, longnames_size, 1, file) != 1)
+       {
+         free (longnames);
+         error(_("%s: failed to read string table\n"), file_name);
+         return 1;
+       }
+
+      if ((longnames_size & 1) != 0)
+       getc (file);
+
+      got = fread (&arhdr, 1, sizeof arhdr, file);
+      if (got != sizeof arhdr)
+       {
+         free (longnames);
+
+         if (got == 0)
+           return 0;
+
+         error (_("%s: failed to read archive header\n"), file_name);
+         return 1;
+       }
+    }
+
+  file_name_size = strlen (file_name);
+  ret = 0;
+
+  while (1)
+    {
+      char *name;
+      char *nameend;
+      char *namealc;
+
+      if (arhdr.ar_name[0] == '/')
+       {
+         unsigned long off;
+
+         off = strtoul (arhdr.ar_name + 1, NULL, 10);
+         if (off >= longnames_size)
+           {
+             error (_("%s: invalid archive string table offset %lu\n"), off);
+             ret = 1;
+             break;
+           }
+
+         name = longnames + off;
+         nameend = memchr (name, '/', longnames_size - off);
+       }
+      else
+       {
+         name = arhdr.ar_name;
+         nameend = memchr (name, '/', 16);
+       }
+
+      if (nameend == NULL)
+       {
+         error (_("%s: bad archive file name\n"));
+         ret = 1;
+         break;
+       }
+
+      namealc = malloc (file_name_size + (nameend - name) + 3);
+      if (namealc == NULL)
+       {
+         error (_("Out of memory\n"));
+         ret = 1;
+         break;
+       }
+
+      memcpy (namealc, file_name, file_name_size);
+      namealc[file_name_size] = '(';
+      memcpy (namealc + file_name_size + 1, name, nameend - name);
+      namealc[file_name_size + 1 + (nameend - name)] = ')';
+      namealc[file_name_size + 2 + (nameend - name)] = '\0';
+
+      archive_file_offset = ftell (file);
+      archive_file_size = strtoul (arhdr.ar_size, NULL, 10);
+
+      ret |= process_object (namealc, file);
+
+      free (namealc);
+
+      if (fseek (file,
+                (archive_file_offset
+                 + archive_file_size
+                 + (archive_file_size & 1)),
+                SEEK_SET) != 0)
+       {
+         error (_("%s: failed to seek to next archive header\n"), file_name);
+         ret = 1;
+         break;
+       }
+
+      got = fread (&arhdr, 1, sizeof arhdr, file);
+      if (got != sizeof arhdr)
+       {
+         if (got == 0)
+           break;
+
+         error (_("%s: failed to read archive header\n"), file_name);
+         ret = 1;
+         break;
+       }
+    }
+
+  if (longnames != 0)
+    free (longnames);
+
+  return ret;
+}
+
+static int
+process_file (char *file_name)
+{
+  FILE *file;
+  struct stat statbuf;
+  char armag[SARMAG];
+  int ret;
+
+  if (stat (file_name, &statbuf) < 0)
+    {
+      error (_("Cannot stat input file %s.\n"), file_name);
+      return 1;
+    }
+
+  file = fopen (file_name, "rb");
+  if (file == NULL)
+    {
+      error (_("Input file %s not found.\n"), file_name);
+      return 1;
+    }
+
+  if (fread (armag, SARMAG, 1, file) != 1)
+    {
+      error (_("%s: Failed to read file header\n"), file_name);
+      fclose (file);
+      return 1;
+    }
+
+  if (memcmp (armag, ARMAG, SARMAG) == 0)
+    ret = process_archive (file_name, file);
+  else
+    {
+      rewind (file);
+      archive_file_size = archive_file_offset = 0;
+      ret = process_object (file_name, file);
+    }
+
+  fclose (file);
+
+  return ret;
+}
+
 #ifdef SUPPORT_DISASSEMBLY
 /* Needed by the i386 disassembler.  For extra credit, someone could
    fix this so that we insert symbolic addresses here, esp for GOT/PLT
@@ -10632,12 +10508,8 @@ db_task_printsym (unsigned int addr)
 }
 #endif
 
-int main PARAMS ((int, char **));
-
 int
-main (argc, argv)
-     int argc;
-     char **argv;
+main (int argc, char **argv)
 {
   int err;
   char *cmdline_dump_sects = NULL;
This page took 0.066912 seconds and 4 git commands to generate.