* readelf.c Replace occurrences of Elf32_Internal_* and
[binutils-gdb.git] / binutils / readelf.c
index d1c23daf1cf42917ad9632cdcff3785472da5862..ba9529a4899edf09c51dad034bd281221616b79f 100644 (file)
@@ -62,6 +62,7 @@
 #include "elf/h8.h"
 #include "elf/hppa.h"
 #include "elf/i386.h"
+#include "elf/i370.h"
 #include "elf/i860.h"
 #include "elf/i960.h"
 #include "elf/ia64.h"
@@ -160,7 +161,7 @@ print_mode;
 
 /* Forward declarations for dumb compilers.  */
 static void              print_vma                   PARAMS ((bfd_vma, print_mode));
-static void              print_symbol                PARAMS ((int, char *));
+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));
@@ -170,7 +171,7 @@ static const char *       get_ppc64_dynamic_type      PARAMS ((unsigned long));
 static const char *       get_parisc_dynamic_type     PARAMS ((unsigned long));
 static const char *       get_dynamic_type            PARAMS ((unsigned long));
 static int               slurp_rela_relocs           PARAMS ((FILE *, unsigned long, unsigned long, Elf_Internal_Rela **, unsigned long *));
-static int               slurp_rel_relocs            PARAMS ((FILE *, unsigned long, unsigned long, Elf_Internal_Rel **, unsigned long *));
+static int               slurp_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));
@@ -219,21 +220,21 @@ static int *              get_dynamic_data            PARAMS ((FILE *, unsigned
 static int                get_32bit_dynamic_segment   PARAMS ((FILE *));
 static int                get_64bit_dynamic_segment   PARAMS ((FILE *));
 #ifdef SUPPORT_DISASSEMBLY
-static int               disassemble_section         PARAMS ((Elf32_Internal_Shdr *, FILE *));
+static int               disassemble_section         PARAMS ((Elf_Internal_Shdr *, FILE *));
 #endif
-static int               dump_section                PARAMS ((Elf32_Internal_Shdr *, FILE *));
-static int               display_debug_section       PARAMS ((Elf32_Internal_Shdr *, FILE *));
-static int                display_debug_info          PARAMS ((Elf32_Internal_Shdr *, unsigned char *, FILE *));
-static int                display_debug_not_supported PARAMS ((Elf32_Internal_Shdr *, unsigned char *, FILE *));
-static int                prescan_debug_info          PARAMS ((Elf32_Internal_Shdr *, unsigned char *, FILE *));
-static int                display_debug_lines         PARAMS ((Elf32_Internal_Shdr *, unsigned char *, FILE *));
-static int                display_debug_pubnames      PARAMS ((Elf32_Internal_Shdr *, unsigned char *, FILE *));
-static int                display_debug_abbrev        PARAMS ((Elf32_Internal_Shdr *, unsigned char *, FILE *));
-static int                display_debug_aranges       PARAMS ((Elf32_Internal_Shdr *, unsigned char *, FILE *));
-static int                display_debug_frames        PARAMS ((Elf32_Internal_Shdr *, unsigned char *, FILE *));
-static int                display_debug_macinfo       PARAMS ((Elf32_Internal_Shdr *, unsigned char *, FILE *));
-static int                display_debug_str           PARAMS ((Elf32_Internal_Shdr *, unsigned char *, FILE *));
-static int                display_debug_loc           PARAMS ((Elf32_Internal_Shdr *, unsigned char *, FILE *));
+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));
@@ -260,7 +261,7 @@ 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 ((Elf32_Internal_Note *));
+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 *));
@@ -405,7 +406,7 @@ byte_get_little_endian (field, size)
     case 8:
       /* We want to extract data from an 8 byte wide field and
         place it into a 4 byte wide field.  Since this is a little
-        endian source we can juts use the 4 byte extraction code.  */
+        endian source we can just use the 4 byte extraction code.  */
       /* Fall through.  */
 #endif
     case 4:
@@ -534,10 +535,10 @@ print_vma (vma, mode)
 static void
 print_symbol (width, symbol)
      int width;
-     char * symbol;
+     const char * symbol;
 {
   if (do_wide)
-    printf (symbol);
+    printf ("%s", symbol);
   else if (width < 0)
     printf ("%-*.*s", width, width, symbol);
   else
@@ -760,10 +761,10 @@ slurp_rel_relocs (file, rel_offset, rel_size, relsp, nrelsp)
      FILE *file;
      unsigned long rel_offset;
      unsigned long rel_size;
-     Elf_Internal_Rel **relsp;
+     Elf_Internal_Rela **relsp;
      unsigned long *nrelsp;
 {
-  Elf_Internal_Rel *rels;
+  Elf_Internal_Rela *rels;
   unsigned long nrels;
   unsigned int i;
 
@@ -778,7 +779,7 @@ slurp_rel_relocs (file, rel_offset, rel_size, relsp, nrelsp)
 
       nrels = rel_size / sizeof (Elf32_External_Rel);
 
-      rels = (Elf_Internal_Rel *) malloc (nrels * sizeof (Elf_Internal_Rel));
+      rels = (Elf_Internal_Rela *) malloc (nrels * sizeof (Elf_Internal_Rela));
 
       if (rels == NULL)
        {
@@ -790,6 +791,7 @@ slurp_rel_relocs (file, rel_offset, rel_size, relsp, nrelsp)
        {
          rels[i].r_offset = BYTE_GET (erels[i].r_offset);
          rels[i].r_info   = BYTE_GET (erels[i].r_info);
+         rels[i].r_addend = 0;
        }
 
       free (erels);
@@ -805,7 +807,7 @@ slurp_rel_relocs (file, rel_offset, rel_size, relsp, nrelsp)
 
       nrels = rel_size / sizeof (Elf64_External_Rel);
 
-      rels = (Elf_Internal_Rel *) malloc (nrels * sizeof (Elf_Internal_Rel));
+      rels = (Elf_Internal_Rela *) malloc (nrels * sizeof (Elf_Internal_Rela));
 
       if (rels == NULL)
        {
@@ -817,6 +819,7 @@ slurp_rel_relocs (file, rel_offset, rel_size, relsp, nrelsp)
        {
          rels[i].r_offset = BYTE_GET8 (erels[i].r_offset);
          rels[i].r_info   = BYTE_GET8 (erels[i].r_info);
+         rels[i].r_addend = 0;
        }
 
       free (erels);
@@ -838,8 +841,7 @@ dump_relocations (file, rel_offset, rel_size, symtab, nsyms, strtab, is_rela)
      int                is_rela;
 {
   unsigned int        i;
-  Elf_Internal_Rel *  rels;
-  Elf_Internal_Rela * relas;
+  Elf_Internal_Rela * rels;
 
 
   if (is_rela == UNKNOWN)
@@ -847,7 +849,7 @@ dump_relocations (file, rel_offset, rel_size, symtab, nsyms, strtab, is_rela)
 
   if (is_rela)
     {
-      if (!slurp_rela_relocs (file, rel_offset, rel_size, &relas, &rel_size))
+      if (!slurp_rela_relocs (file, rel_offset, rel_size, &rels, &rel_size))
        return 0;
     }
   else
@@ -903,16 +905,8 @@ dump_relocations (file, rel_offset, rel_size, symtab, nsyms, strtab, is_rela)
       bfd_vma      type2 = (bfd_vma) NULL;
       bfd_vma      type3 = (bfd_vma) NULL;
 
-      if (is_rela)
-       {
-         offset = relas [i].r_offset;
-         info   = relas [i].r_info;
-       }
-      else
-       {
-         offset = rels [i].r_offset;
-         info   = rels [i].r_info;
-       }
+      offset = rels [i].r_offset;
+      info   = rels [i].r_info;
 
       if (is_32bit_elf)
        {
@@ -1118,6 +1112,10 @@ dump_relocations (file, rel_offset, rel_size, symtab, nsyms, strtab, is_rela)
          rtype = elf_x86_64_reloc_type (type);
          break;
 
+       case EM_S370:
+         rtype = i370_reloc_type (type);
+         break;
+
        case EM_S390_OLD:
        case EM_S390:
          rtype = elf_s390_reloc_type (type);
@@ -1161,20 +1159,48 @@ dump_relocations (file, rel_offset, rel_size, symtab, nsyms, strtab, is_rela)
              printf (is_32bit_elf ? "   " : " ");
 
              if (psym->st_name == 0)
-               print_symbol (22, SECTION_NAME (section_headers + psym->st_shndx));
+               {
+                 const char *sec_name = "<null>";
+                 char name_buf[40];
+
+                 if (ELF_ST_TYPE (psym->st_info) == STT_SECTION)
+                   {
+                     bfd_vma sec_index = (bfd_vma) -1;
+
+                     if (psym->st_shndx < SHN_LORESERVE)
+                       sec_index = psym->st_shndx;
+                     else if (psym->st_shndx > SHN_LORESERVE)
+                       sec_index = psym->st_shndx - (SHN_HIRESERVE + 1
+                                                     - SHN_LORESERVE);
+
+                     if (sec_index != (bfd_vma) -1)
+                       sec_name = SECTION_NAME (section_headers + sec_index);
+                     else if (psym->st_shndx == SHN_ABS)
+                       sec_name = "ABS";
+                     else if (psym->st_shndx == SHN_COMMON)
+                       sec_name = "COMMON";
+                     else
+                       {
+                         sprintf (name_buf, "<section 0x%x>",
+                                  (unsigned int) psym->st_shndx);
+                         sec_name = name_buf;
+                       }
+                   }
+                 print_symbol (22, sec_name);
+               }
              else if (strtab == NULL)
                printf (_("<string table index %3ld>"), psym->st_name);
              else
                print_symbol (22, strtab + psym->st_name);
 
              if (is_rela)
-               printf (" + %lx", (unsigned long) relas [i].r_addend);
+               printf (" + %lx", (unsigned long) rels [i].r_addend);
            }
        }
       else if (is_rela)
        {
          printf ("%*c", is_32bit_elf ? (do_wide ? 34 : 28) : (do_wide ? 26 : 20), ' ');
-         print_vma (relas[i].r_addend, LONG_HEX);
+         print_vma (rels[i].r_addend, LONG_HEX);
        }
 
       if (elf_header.e_machine == EM_SPARCV9
@@ -1211,10 +1237,7 @@ dump_relocations (file, rel_offset, rel_size, symtab, nsyms, strtab, is_rela)
        }
     }
 
-  if (is_rela)
-    free (relas);
-  else
-    free (rels);
+  free (rels);
 
   return 1;
 }
@@ -1772,9 +1795,6 @@ get_machine_flags (e_flags, e_machine)
            case E_V850E_ARCH:
              strcat (buf, ", v850e");
              break;
-           case E_V850EA_ARCH:
-             strcat (buf, ", v850ea");
-             break;
            case E_V850_ARCH:
              strcat (buf, ", v850");
              break;
@@ -1819,8 +1839,11 @@ get_machine_flags (e_flags, e_machine)
            case E_MIPS_MACH_3900: strcat (buf, ", 3900"); break;
            case E_MIPS_MACH_4010: strcat (buf, ", 4010"); break;
            case E_MIPS_MACH_4100: strcat (buf, ", 4100"); break;
-           case E_MIPS_MACH_4650: strcat (buf, ", 4650"); break;
            case E_MIPS_MACH_4111: strcat (buf, ", 4111"); break;
+           case E_MIPS_MACH_4120: strcat (buf, ", 4120"); break;
+           case E_MIPS_MACH_4650: strcat (buf, ", 4650"); break;
+           case E_MIPS_MACH_5400: strcat (buf, ", 5400"); break;
+           case E_MIPS_MACH_5500: strcat (buf, ", 5500"); break;
            case E_MIPS_MACH_SB1:  strcat (buf, ", sb1");  break;
            case 0:
            /* We simply ignore the field in this case to avoid confusion:
@@ -2512,7 +2535,7 @@ parse_args (argc, argv)
            do_debugging = 1;
          else
            {
-             const char *debug_dump_opt[]
+             static const char *debug_dump_opt[]
                = { "line", "info", "abbrev", "pubnames", "ranges",
                    "macro", "frames", "frames-interp", "str", "loc", NULL };
              unsigned int index;
@@ -2788,7 +2811,7 @@ get_32bit_program_headers (file, program_headers)
 {
   Elf32_External_Phdr * phdrs;
   Elf32_External_Phdr * external;
-  Elf32_Internal_Phdr * internal;
+  Elf_Internal_Phdr *   internal;
   unsigned int          i;
 
   phdrs = ((Elf32_External_Phdr *)
@@ -2824,7 +2847,7 @@ get_64bit_program_headers (file, program_headers)
 {
   Elf64_External_Phdr * phdrs;
   Elf64_External_Phdr * external;
-  Elf64_Internal_Phdr * internal;
+  Elf_Internal_Phdr *   internal;
   unsigned int          i;
 
   phdrs = ((Elf64_External_Phdr *)
@@ -2853,6 +2876,8 @@ get_64bit_program_headers (file, program_headers)
   return 1;
 }
 
+/* Returns 1 if the program headers were loaded.  */
+
 static int
 process_program_headers (file)
      FILE * file;
@@ -2865,7 +2890,7 @@ process_program_headers (file)
     {
       if (do_segments)
        printf (_("\nThere are no program headers in this file.\n"));
-      return 1;
+      return 0;
     }
 
   if (do_segments && !do_header)
@@ -3096,7 +3121,7 @@ get_32bit_section_headers (file, num)
      unsigned int num;
 {
   Elf32_External_Shdr * shdrs;
-  Elf32_Internal_Shdr * internal;
+  Elf_Internal_Shdr *   internal;
   unsigned int          i;
 
   shdrs = ((Elf32_External_Shdr *)
@@ -3142,7 +3167,7 @@ get_64bit_section_headers (file, num)
      unsigned int num;
 {
   Elf64_External_Shdr * shdrs;
-  Elf64_Internal_Shdr * internal;
+  Elf_Internal_Shdr *   internal;
   unsigned int          i;
 
   shdrs = ((Elf64_External_Shdr *)
@@ -3409,6 +3434,7 @@ process_section_headers (file)
   dynamic_symbols = NULL;
   dynamic_strings = NULL;
   dynamic_syminfo = NULL;
+  symtab_shndx_hdr = NULL;
 
   for (i = 0, section = section_headers;
        i < elf_header.e_shnum;
@@ -3662,7 +3688,7 @@ process_relocs (file)
     }
   else
     {
-      Elf32_Internal_Shdr *     section;
+      Elf_Internal_Shdr *      section;
       unsigned long            i;
       int              found = 0;
 
@@ -3679,11 +3705,11 @@ process_relocs (file)
 
          if (rel_size)
            {
-             Elf32_Internal_Shdr * strsec;
-             Elf_Internal_Sym *    symtab;
-             char *                strtab;
-             int                   is_rela;
-             unsigned long         nsyms;
+             Elf_Internal_Shdr * strsec;
+             Elf_Internal_Sym *  symtab;
+             char *              strtab;
+             int                 is_rela;
+             unsigned long       nsyms;
 
              printf (_("\nRelocation section "));
 
@@ -3700,7 +3726,7 @@ process_relocs (file)
              nsyms = 0;
              if (section->sh_link)
                {
-                 Elf32_Internal_Shdr * symsec;
+                 Elf_Internal_Shdr * symsec;
 
                  symsec = SECTION_HEADER (section->sh_link);
                  nsyms = symsec->sh_size / symsec->sh_entsize;
@@ -3773,7 +3799,7 @@ static void find_symbol_for_address PARAMS ((struct unw_aux_info *,
                                             bfd_vma *));
 static void dump_ia64_unwind PARAMS ((struct unw_aux_info *));
 static int  slurp_ia64_unwind_table PARAMS ((FILE *, struct unw_aux_info *,
-                                           Elf32_Internal_Shdr *));
+                                           Elf_Internal_Shdr *));
 
 static void
 find_symbol_for_address (aux, addr, symname, offset)
@@ -3845,13 +3871,13 @@ dump_ia64_unwind (aux)
       print_vma (tp->start.offset, PREFIX_HEX);
       fputc ('-', stdout);
       print_vma (tp->end.offset, PREFIX_HEX);
-      printf ("), info at +0x%lx\n",
+      printf ("], info at +0x%lx\n",
              (unsigned long) (tp->info.offset - aux->seg_base));
 
       head = aux->info + (tp->info.offset - aux->info_addr);
       stamp = BYTE_GET8 ((unsigned char *) head);
 
-      printf ("  v%u, flags=0x%lx (%s%s ), len=%lu bytes\n",
+      printf ("  v%u, flags=0x%lx (%s%s), len=%lu bytes\n",
              (unsigned) UNW_VER (stamp),
              (unsigned long) ((stamp & UNW_FLAG_MASK) >> 32),
              UNW_FLAG_EHANDLER (stamp) ? " ehandler" : "",
@@ -3874,12 +3900,12 @@ static int
 slurp_ia64_unwind_table (file, aux, sec)
      FILE *file;
      struct unw_aux_info *aux;
-     Elf32_Internal_Shdr *sec;
+     Elf_Internal_Shdr *sec;
 {
   unsigned long size, addr_size, nrelas, i;
   Elf_Internal_Phdr *prog_hdrs, *seg;
   struct unw_table_entry *tep;
-  Elf32_Internal_Shdr *relsec;
+  Elf_Internal_Shdr *relsec;
   Elf_Internal_Rela *rela, *rp;
   unsigned char *table, *tp;
   Elf_Internal_Sym *sym;
@@ -4033,7 +4059,7 @@ static int
 process_unwind (file)
      FILE * file;
 {
-  Elf32_Internal_Shdr *sec, *unwsec = NULL, *strsec;
+  Elf_Internal_Shdr *sec, *unwsec = NULL, *strsec;
   unsigned long i, addr_size, unwcount = 0, unwstart = 0;
   struct unw_aux_info aux;
 
@@ -4294,6 +4320,7 @@ dynamic_segment_parisc_val (entry)
       print_vma (entry->d_un.d_ptr, PREFIX_HEX);
       break;
     }
+  putchar ('\n');
 }
 
 static int
@@ -4446,7 +4473,7 @@ process_dynamic_segment (file)
           i < dynamic_size;
           ++i, ++ entry)
        {
-         Elf32_Internal_Shdr section;
+         Elf_Internal_Shdr section;
 
          if (entry->d_tag != DT_SYMTAB)
            continue;
@@ -4644,11 +4671,13 @@ process_dynamic_segment (file)
          if (do_dynamic)
            {
              printf (_("Flags:"));
+
              if (entry->d_un.d_val == 0)
                printf (_(" None\n"));
              else
                {
                  unsigned long int val = entry->d_un.d_val;
+
                  if (val & DTF_1_PARINIT)
                    {
                      printf (" PARINIT");
@@ -4670,11 +4699,13 @@ process_dynamic_segment (file)
          if (do_dynamic)
            {
              printf (_("Flags:"));
+
              if (entry->d_un.d_val == 0)
                printf (_(" None\n"));
              else
                {
                  unsigned long int val = entry->d_un.d_val;
+
                  if (val & DF_P1_LAZYLOAD)
                    {
                      printf (" LAZYLOAD");
@@ -4701,6 +4732,7 @@ process_dynamic_segment (file)
              else
                {
                  unsigned long int val = entry->d_un.d_val;
+
                  if (val & DF_1_NOW)
                    {
                      printf (" NOW");
@@ -4906,6 +4938,8 @@ process_dynamic_segment (file)
 
        case DT_BIND_NOW:
          /* The value of this entry is ignored.  */
+         if (do_dynamic)
+           putchar ('\n');
          break;
 
        case DT_GNU_PRELINKED:
@@ -4983,7 +5017,7 @@ static int
 process_version_sections (file)
      FILE * file;
 {
-  Elf32_Internal_Shdr * section;
+  Elf_Internal_Shdr * section;
   unsigned   i;
   int        found = 0;
 
@@ -5176,14 +5210,14 @@ process_version_sections (file)
 
        case SHT_GNU_versym:
          {
-           Elf32_Internal_Shdr *       link_section;
+           Elf_Internal_Shdr *         link_section;
            int                         total;
            int                         cnt;
            unsigned char *             edata;
            unsigned short *            data;
            char *                      strtab;
            Elf_Internal_Sym *          symbols;
-           Elf32_Internal_Shdr *       string_sec;
+           Elf_Internal_Shdr *         string_sec;
 
            link_section = SECTION_HEADER (section->sh_link);
            total = section->sh_size / section->sh_entsize;
@@ -5472,6 +5506,8 @@ static const char *
 get_symbol_index_type (type)
      unsigned int type;
 {
+  static char buff [32];
+
   switch (type)
     {
     case SHN_UNDEF:  return "UND";
@@ -5479,19 +5515,17 @@ get_symbol_index_type (type)
     case SHN_COMMON: return "COM";
     default:
       if (type >= SHN_LOPROC && type <= SHN_HIPROC)
-       return "PRC";
+       sprintf (buff, "PRC[0x%04x]", type);
       else if (type >= SHN_LOOS && type <= SHN_HIOS)
-       return "OS ";
+       sprintf (buff, "OS [0x%04x]", type);
       else if (type >= SHN_LORESERVE && type <= SHN_HIRESERVE)
-       return "RSV";
+       sprintf (buff, "RSV[0x%04x]", type);
       else
-       {
-         static char buff [32];
-
-         sprintf (buff, "%3d", type);
-         return buff;
-       }
+       sprintf (buff, "%3d", type);
+      break;
     }
+
+  return buff;
 }
 
 static int *
@@ -5538,7 +5572,7 @@ static int
 process_symbol_table (file)
      FILE * file;
 {
-  Elf32_Internal_Shdr *   section;
+  Elf_Internal_Shdr * section;
   unsigned char   nb [4];
   unsigned char   nc [4];
   int    nbuckets = 0;
@@ -5651,7 +5685,7 @@ process_symbol_table (file)
            strtab = string_table;
          else
            {
-             Elf32_Internal_Shdr * string_sec;
+             Elf_Internal_Shdr * string_sec;
 
              string_sec = SECTION_HEADER (section->sh_link);
 
@@ -5953,7 +5987,7 @@ process_syminfo (file)
 #ifdef SUPPORT_DISASSEMBLY
 static void
 disassemble_section (section, file)
-     Elf32_Internal_Shdr * section;
+     Elf_Internal_Shdr * section;
      FILE * file;
 {
   printf (_("\nAssembly dump of section %s\n"),
@@ -5967,7 +6001,7 @@ disassemble_section (section, file)
 
 static int
 dump_section (section, file)
-     Elf32_Internal_Shdr * section;
+     Elf_Internal_Shdr * section;
      FILE * file;
 {
   bfd_size_type   bytes;
@@ -6190,7 +6224,7 @@ static int debug_line_pointer_size = 4;
 
 static int
 display_debug_lines (section, start, file)
-     Elf32_Internal_Shdr * section;
+     Elf_Internal_Shdr *   section;
      unsigned char *       start;
      FILE *                file ATTRIBUTE_UNUSED;
 {
@@ -6447,7 +6481,7 @@ display_debug_lines (section, start, file)
 
 static int
 display_debug_pubnames (section, start, file)
-     Elf32_Internal_Shdr * section;
+     Elf_Internal_Shdr *   section;
      unsigned char *       start;
      FILE *                file ATTRIBUTE_UNUSED;
 {
@@ -6910,7 +6944,7 @@ process_abbrev_section (start, end)
 
 static int
 display_debug_macinfo (section, start, file)
-     Elf32_Internal_Shdr * section;
+     Elf_Internal_Shdr *   section;
      unsigned char *       start;
      FILE *                file ATTRIBUTE_UNUSED;
 {
@@ -6984,7 +7018,7 @@ display_debug_macinfo (section, start, file)
 
 static int
 display_debug_abbrev (section, start, file)
-     Elf32_Internal_Shdr * section;
+     Elf_Internal_Shdr *   section;
      unsigned char *       start;
      FILE *                file ATTRIBUTE_UNUSED;
 {
@@ -7338,7 +7372,7 @@ decode_location_expression (data, pointer_size, length)
          printf ("DW_OP_nop");
          break;
 
-         /* DWARF 2.1 extensions.  */
+         /* DWARF 3 extensions.  */
        case DW_OP_push_object_address:
          printf ("DW_OP_push_object_address");
          break;
@@ -7350,8 +7384,13 @@ decode_location_expression (data, pointer_size, length)
          printf ("DW_OP_call4: <%lx>", (long) byte_get (data, 4));
          data += 4;
          break;
-       case DW_OP_calli:
-         printf ("DW_OP_calli");
+       case DW_OP_call_ref:
+         printf ("DW_OP_call_ref");
+         break;
+
+         /* GNU extensions.  */
+       case DW_OP_GNU_push_tls_address:
+         printf ("DW_OP_GNU_push_tls_address");
          break;
 
        default:
@@ -7376,8 +7415,8 @@ static void
 load_debug_loc (file)
      FILE * file;
 {
-  Elf32_Internal_Shdr * sec;
-  unsigned int          i;
+  Elf_Internal_Shdr * sec;
+  unsigned int        i;
 
   /* If it is already loaded, do nothing.  */
   if (debug_loc_contents != NULL)
@@ -7414,7 +7453,7 @@ free_debug_loc ()
 
 static int
 display_debug_loc (section, start, file)
-     Elf32_Internal_Shdr * section;
+     Elf_Internal_Shdr * section;
      unsigned char * start;
      FILE * file ATTRIBUTE_UNUSED;
 {
@@ -7426,13 +7465,16 @@ display_debug_loc (section, start, file)
   addr = section->sh_addr;
   bytes = section->sh_size;
   section_end = start + bytes;
+
   if (bytes == 0)
     {
       printf (_("\nThe .debug_loc section is empty.\n"));
       return 0;
     }
+
   printf (_("Contents of the .debug_loc section:\n\n"));
   printf (_("\n    Offset   Begin    End      Expression\n"));
+
   while (start < section_end)
     {
       unsigned long begin;
@@ -7483,8 +7525,8 @@ static void
 load_debug_str (file)
      FILE * file;
 {
-  Elf32_Internal_Shdr * sec;
-  unsigned int          i;
+  Elf_Internal_Shdr * sec;
+  unsigned int        i;
 
   /* If it is already loaded, do nothing.  */
   if (debug_str_contents != NULL)
@@ -7531,10 +7573,9 @@ fetch_indirect_string (offset)
   return debug_str_contents + offset;
 }
 
-
 static int
 display_debug_str (section, start, file)
-     Elf32_Internal_Shdr * section;
+     Elf_Internal_Shdr * section;
      unsigned char *       start;
      FILE *                file ATTRIBUTE_UNUSED;
 {
@@ -7592,7 +7633,6 @@ display_debug_str (section, start, file)
   return 1;
 }
 
-
 static unsigned char *
 read_and_display_attr_value (attribute, form, data, cu_offset, pointer_size)
      unsigned long   attribute;
@@ -7721,8 +7761,8 @@ read_and_display_attr_value (attribute, form, data, cu_offset, pointer_size)
       break;
 
     case DW_FORM_strp:
-      printf (_(" (indirect string, offset: 0x%lx): "), uvalue);
-      printf (fetch_indirect_string (uvalue));
+      printf (_(" (indirect string, offset: 0x%lx): %s"),
+             uvalue, fetch_indirect_string (uvalue));
       break;
 
     case DW_FORM_indirect:
@@ -7911,7 +7951,7 @@ read_and_display_attr (attribute, form, data, cu_offset, pointer_size)
 
 static int
 display_debug_info (section, start, file)
-     Elf32_Internal_Shdr * section;
+     Elf_Internal_Shdr *   section;
      unsigned char *       start;
      FILE *                file;
 {
@@ -7927,7 +7967,7 @@ display_debug_info (section, start, file)
     {
       DWARF2_External_CompUnit * external;
       DWARF2_Internal_CompUnit   compunit;
-      Elf32_Internal_Shdr *      relsec;
+      Elf_Internal_Shdr *        relsec;
       unsigned char *            tags;
       unsigned int               i;
       int                       level;
@@ -7946,20 +7986,21 @@ display_debug_info (section, start, file)
          break;
        }
 
-      /* Check for RELA relocations in the abbrev_offset address, and
-         apply them.  */
+      /* Check for RELA relocations in the
+        abbrev_offset address, and apply them.  */
       for (relsec = section_headers;
           relsec < section_headers + elf_header.e_shnum;
           ++relsec)
        {
          unsigned long nrelas;
          Elf_Internal_Rela *rela, *rp;
-         Elf32_Internal_Shdr *symsec;
+         Elf_Internal_Shdr *symsec;
          Elf_Internal_Sym *symtab;
          Elf_Internal_Sym *sym;
 
          if (relsec->sh_type != SHT_RELA
-             || SECTION_HEADER (relsec->sh_info) != section)
+             || SECTION_HEADER (relsec->sh_info) != section
+             || relsec->sh_size == 0)
            continue;
 
          if (!slurp_rela_relocs (file, relsec->sh_offset, relsec->sh_size,
@@ -7980,7 +8021,8 @@ display_debug_info (section, start, file)
                {
                  sym = symtab + ELF32_R_SYM (rp->r_info);
 
-                 if (ELF32_ST_TYPE (sym->st_info) != STT_SECTION)
+                 if (ELF32_R_SYM (rp->r_info) != 0
+                     && ELF32_ST_TYPE (sym->st_info) != STT_SECTION)
                    {
                      warn (_("Skipping unexpected symbol type %u\n"),
                            ELF32_ST_TYPE (sym->st_info));
@@ -7991,7 +8033,8 @@ display_debug_info (section, start, file)
                {
                  sym = symtab + ELF64_R_SYM (rp->r_info);
 
-                 if (ELF64_ST_TYPE (sym->st_info) != STT_SECTION)
+                 if (ELF64_R_SYM (rp->r_info) != 0
+                     && ELF64_ST_TYPE (sym->st_info) != STT_SECTION)
                    {
                      warn (_("Skipping unexpected symbol type %u\n"),
                            ELF64_ST_TYPE (sym->st_info));
@@ -7999,7 +8042,7 @@ display_debug_info (section, start, file)
                    }
                }
 
-             compunit.cu_abbrev_offset += rp->r_addend;
+             compunit.cu_abbrev_offset = rp->r_addend;
              break;
            }
 
@@ -8026,10 +8069,9 @@ display_debug_info (section, start, file)
       free_abbrevs ();
 
       /* Read in the abbrevs used by this compilation unit.  */
-
       {
-       Elf32_Internal_Shdr * sec;
-       unsigned char *       begin;
+       Elf_Internal_Shdr * sec;
+       unsigned char *     begin;
 
        /* Locate the .debug_abbrev section and process it.  */
        for (i = 0, sec = section_headers;
@@ -8115,7 +8157,7 @@ display_debug_info (section, start, file)
 
 static int
 display_debug_aranges (section, start, file)
-     Elf32_Internal_Shdr * section;
+     Elf_Internal_Shdr *   section;
      unsigned char *       start;
      FILE *                file ATTRIBUTE_UNUSED;
 {
@@ -8326,7 +8368,7 @@ size_of_encoded_value (encoding)
 
 static int
 display_debug_frames (section, start, file)
-     Elf32_Internal_Shdr * section;
+     Elf_Internal_Shdr * section;
      unsigned char *       start;
      FILE *                file ATTRIBUTE_UNUSED;
 {
@@ -8359,7 +8401,11 @@ display_debug_frames (section, start, file)
       length = byte_get (start, 4); start += 4;
 
       if (length == 0)
-       return 1;
+       {
+         printf ("\n%08lx ZERO terminator\n\n",
+                   (unsigned long)(saved_start - section_start));
+         return 1;
+       }
 
       if (length == 0xffffffff)
        {
@@ -8513,6 +8559,8 @@ display_debug_frames (section, start, file)
            encoded_ptr_size = size_of_encoded_value (fc->fde_encoding);
 
          fc->pc_begin = byte_get (start, encoded_ptr_size);
+         if ((fc->fde_encoding & 0x70) == DW_EH_PE_pcrel)
+           fc->pc_begin += section->sh_addr + (start - section_start);
          start += encoded_ptr_size;
          fc->pc_range = byte_get (start, encoded_ptr_size);
          start += encoded_ptr_size;
@@ -8692,6 +8740,8 @@ display_debug_frames (section, start, file)
 
            case DW_CFA_set_loc:
              vma = byte_get (start, encoded_ptr_size);
+             if ((fc->fde_encoding & 0x70) == DW_EH_PE_pcrel)
+               vma += section->sh_addr + (start - section_start);
              start += encoded_ptr_size;
              if (do_debug_frames_interp)
                frame_display_row (fc, &need_col_headers, &max_regs);
@@ -8908,9 +8958,9 @@ display_debug_frames (section, start, file)
 
 static int
 display_debug_not_supported (section, start, file)
-     Elf32_Internal_Shdr * section;
-     unsigned char *       start ATTRIBUTE_UNUSED;
-     FILE *                file ATTRIBUTE_UNUSED;
+     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));
@@ -8923,9 +8973,9 @@ display_debug_not_supported (section, start, file)
    that all compilation units have the same address size.  */
 static int
 prescan_debug_info (section, start, file)
-     Elf32_Internal_Shdr * section ATTRIBUTE_UNUSED;
-     unsigned char *       start;
-     FILE *                file ATTRIBUTE_UNUSED;
+     Elf_Internal_Shdr * section ATTRIBUTE_UNUSED;
+     unsigned char *     start;
+     FILE *              file ATTRIBUTE_UNUSED;
 {
   DWARF2_External_CompUnit * external;
 
@@ -8942,8 +8992,8 @@ prescan_debug_info (section, start, file)
 struct
 {
   const char * const name;
-  int (* display) PARAMS ((Elf32_Internal_Shdr *, unsigned char *, FILE *));
-  int (* prescan) PARAMS ((Elf32_Internal_Shdr *, unsigned char *, FILE *));
+  int (* display) PARAMS ((Elf_Internal_Shdr *, unsigned char *, FILE *));
+  int (* prescan) PARAMS ((Elf_Internal_Shdr *, unsigned char *, FILE *));
 }
 debug_displays[] =
 {
@@ -8967,7 +9017,7 @@ debug_displays[] =
 
 static int
 display_debug_section (section, file)
-     Elf32_Internal_Shdr * section;
+     Elf_Internal_Shdr * section;
      FILE * file;
 {
   char *          name = SECTION_NAME (section);
@@ -9014,7 +9064,7 @@ static int
 process_section_contents (file)
      FILE * file;
 {
-  Elf32_Internal_Shdr * section;
+  Elf_Internal_Shdr * section;
   unsigned int i;
 
   if (! do_dump)
@@ -9662,7 +9712,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)
-     Elf32_Internal_Note * pnote;
+     Elf_Internal_Note * pnote;
 {
   const char *nt;
 
@@ -9718,7 +9768,7 @@ process_corefile_note_segment (file, offset, length)
   while (external < (Elf_External_Note *)((char *) pnotes + length))
     {
       Elf_External_Note * next;
-      Elf32_Internal_Note inote;
+      Elf_Internal_Note   inote;
       char * temp = NULL;
 
       inote.type     = BYTE_GET (external->type);
@@ -9995,11 +10045,18 @@ process_file (file_name)
       return 1;
     }
 
-  process_section_headers (file);
+  if (! process_section_headers (file))
+    {
+      /* Without loaded section headers we
+        cannot process lots of things.  */
+      do_unwind = do_version = do_dump = do_arch = 0;
 
-  process_program_headers (file);
+      if (! do_using_dynamic)
+       do_syms = do_reloc = 0;
+    }
 
-  process_dynamic_segment (file);
+  if (process_program_headers (file))
+    process_dynamic_segment (file);
 
   process_relocs (file);