* cris.h (R_CRIS_32_IE): New relocation.
[deliverable/binutils-gdb.git] / binutils / readelf.c
index bb79e0c2685ad3fe3e24f0e9033bc3a41eb88805..81cde343e593d202ddf28c1df71e444af431e864 100644 (file)
   ELF file than is provided by objdump.  In particular it can display DWARF
   debugging information which (at the moment) objdump cannot.  */
 \f
+#include "config.h"
 #include "sysdep.h"
 #include <assert.h>
 #include <sys/stat.h>
 #include <time.h>
+#ifdef HAVE_ZLIB_H
+#include <zlib.h>
+#endif
 
-/* for PATH_MAX */
+/* For PATH_MAX.  */
 #ifdef HAVE_LIMITS_H
 #include <limits.h>
 #endif
 
 #ifndef PATH_MAX
-/* for MAXPATHLEN */
+/* For MAXPATHLEN.  */
 # ifdef HAVE_SYS_PARAM_H
 #  include <sys/param.h>
 # endif
 #include "safe-ctype.h"
 
 char *program_name = "readelf";
+int do_wide;
 static long archive_file_offset;
 static unsigned long archive_file_size;
 static unsigned long dynamic_addr;
@@ -197,7 +202,6 @@ static int do_using_dynamic;
 static int do_header;
 static int do_dump;
 static int do_version;
-static int do_wide;
 static int do_histogram;
 static int do_debugging;
 static int do_arch;
@@ -306,7 +310,7 @@ get_data (void *var, FILE *file, long offset, size_t size, size_t nmemb,
   if (fseek (file, archive_file_offset + offset, SEEK_SET))
     {
       error (_("Unable to seek to 0x%lx for %s\n"),
-            archive_file_offset + offset, reason);
+            (unsigned long) archive_file_offset + offset, reason);
       return NULL;
     }
 
@@ -368,195 +372,137 @@ byte_put_little_endian (unsigned char *field, bfd_vma value, int size)
     }
 }
 
-#if defined BFD64 && !BFD_HOST_64BIT_LONG && !BFD_HOST_64BIT_LONG_LONG
+/* Print a VMA value.  */
+
 static int
-print_dec_vma (bfd_vma vma, int is_signed)
+print_vma (bfd_vma vma, print_mode mode)
 {
-  char buf[40];
-  char *bufp = buf;
   int nc = 0;
 
-  if (is_signed && (bfd_signed_vma) vma < 0)
+  switch (mode)
     {
-      vma = -vma;
-      putchar ('-');
-      nc = 1;
-    }
+    case FULL_HEX:
+      nc = printf ("0x");
+      /* Drop through.  */
 
-  do
-    {
-      *bufp++ = '0' + vma % 10;
-      vma /= 10;
-    }
-  while (vma != 0);
-  nc += bufp - buf;
+    case LONG_HEX:
+#ifdef BFD64
+      if (is_32bit_elf)
+       return nc + printf ("%8.8" BFD_VMA_FMT "x", vma);
+#endif
+      printf_vma (vma);
+      return nc + 16;
+
+    case DEC_5:
+      if (vma <= 99999)
+       return printf ("%5" BFD_VMA_FMT "d", vma);
+      /* Drop through.  */
+
+    case PREFIX_HEX:
+      nc = printf ("0x");
+      /* Drop through.  */
+
+    case HEX:
+      return nc + printf ("%" BFD_VMA_FMT "x", vma);
+
+    case DEC:
+      return printf ("%" BFD_VMA_FMT "d", vma);
 
-  while (bufp > buf)
-    putchar (*--bufp);
-  return nc;
+    case UNSIGNED:
+      return printf ("%" BFD_VMA_FMT "u", vma);
+    }
+  return 0;
 }
 
-static int
-print_hex_vma (bfd_vma vma)
+/* Display a symbol on stdout.  Handles the display of non-printing characters.
+
+   If DO_WIDE is not true then format the symbol to be at most WIDTH characters,
+   truncating as necessary.  If WIDTH is negative then format the string to be
+   exactly - WIDTH characters, truncating or padding as necessary.
+
+   Returns the number of emitted characters.  */
+
+static unsigned int
+print_symbol (int width, const char *symbol)
 {
-  char buf[32];
-  char *bufp = buf;
-  int nc;
+  const char * c;
+  bfd_boolean extra_padding = FALSE;
+  unsigned int num_printed = 0;
 
-  do
+  if (do_wide)
     {
-      char digit = '0' + (vma & 0x0f);
-      if (digit > '9')
-       digit += 'a' - '0' - 10;
-      *bufp++ = digit;
-      vma >>= 4;
+      /* Set the width to a very large value.  This simplifies the code below.  */
+      width = INT_MAX;
+    }
+  else if (width < 0)
+    {
+      /* Keep the width positive.  This also helps.  */
+      width = - width;
+      extra_padding = TRUE;
     }
-  while (vma != 0);
-  nc = bufp - buf;
-
-  while (bufp > buf)
-    putchar (*--bufp);
-  return nc;
-}
-#endif
 
-/* Print a VMA value.  */
-static int
-print_vma (bfd_vma vma, print_mode mode)
-{
-#ifdef BFD64
-  if (is_32bit_elf)
-#endif
+  while (width)
     {
-      switch (mode)
-       {
-       case FULL_HEX:
-         return printf ("0x%8.8lx", (unsigned long) vma);
+      int len;
 
-       case LONG_HEX:
-         return printf ("%8.8lx", (unsigned long) vma);
+      c = symbol;
 
-       case DEC_5:
-         if (vma <= 99999)
-           return printf ("%5ld", (long) vma);
-         /* Drop through.  */
+      /* Look for non-printing symbols inside the symbol's name.
+        This test is triggered in particular by the names generated
+        by the assembler for local labels.  */
+      while (ISPRINT (* c))
+       c++;
 
-       case PREFIX_HEX:
-         return printf ("0x%lx", (unsigned long) vma);
+      len = c - symbol;
 
-       case HEX:
-         return printf ("%lx", (unsigned long) vma);
+      if (len)
+       {
+         if (len > width)
+           len = width;
 
-       case DEC:
-         return printf ("%ld", (unsigned long) vma);
+         printf ("%.*s", len, symbol);
 
-       case UNSIGNED:
-         return printf ("%lu", (unsigned long) vma);
+         width -= len;
+         num_printed += len;
        }
-    }
-#ifdef BFD64
-  else
-    {
-      int nc = 0;
 
-      switch (mode)
+      if (* c == 0 || width == 0)
+       break;
+
+      /* Now display the non-printing character, if
+        there is room left in which to dipslay it.  */
+      if (*c < 32)
        {
-       case FULL_HEX:
-         nc = printf ("0x");
-         /* Drop through.  */
+         if (width < 2)
+           break;
 
-       case LONG_HEX:
-         printf_vma (vma);
-         return nc + 16;
+         printf ("^%c", *c + 0x40);
 
-       case PREFIX_HEX:
-         nc = printf ("0x");
-         /* Drop through.  */
-
-       case HEX:
-#if BFD_HOST_64BIT_LONG
-         return nc + printf ("%lx", vma);
-#elif BFD_HOST_64BIT_LONG_LONG
-#ifndef __MSVCRT__
-         return nc + printf ("%llx", vma);
-#else
-         return nc + printf ("%I64x", vma);
-#endif
-#else
-         return nc + print_hex_vma (vma);
-#endif
+         width -= 2;
+         num_printed += 2;
+       }
+      else
+       {
+         if (width < 6)
+           break;
 
-       case DEC:
-#if BFD_HOST_64BIT_LONG
-         return printf ("%ld", vma);
-#elif BFD_HOST_64BIT_LONG_LONG
-#ifndef __MSVCRT__
-         return printf ("%lld", vma);
-#else
-         return printf ("%I64d", vma);
-#endif
-#else
-         return print_dec_vma (vma, 1);
-#endif
+         printf ("<0x%.2x>", *c);
 
-       case DEC_5:
-#if BFD_HOST_64BIT_LONG
-         if (vma <= 99999)
-           return printf ("%5ld", vma);
-         else
-           return printf ("%#lx", vma);
-#elif BFD_HOST_64BIT_LONG_LONG
-#ifndef __MSVCRT__
-         if (vma <= 99999)
-           return printf ("%5lld", vma);
-         else
-           return printf ("%#llx", vma);
-#else
-         if (vma <= 99999)
-           return printf ("%5I64d", vma);
-         else
-           return printf ("%#I64x", vma);
-#endif
-#else
-         if (vma <= 99999)
-           return printf ("%5ld", _bfd_int64_low (vma));
-         else
-           return print_hex_vma (vma);
-#endif
-
-       case UNSIGNED:
-#if BFD_HOST_64BIT_LONG
-         return printf ("%lu", vma);
-#elif BFD_HOST_64BIT_LONG_LONG
-#ifndef __MSVCRT__
-         return printf ("%llu", vma);
-#else
-         return printf ("%I64u", vma);
-#endif
-#else
-         return print_dec_vma (vma, 0);
-#endif
+         width -= 6;
+         num_printed += 6;
        }
+
+      symbol = c + 1;
     }
-#endif
-  return 0;
-}
 
-/* Display a symbol on stdout.  If do_wide is not true then
-   format the symbol to be at most WIDTH characters,
-   truncating as necessary.  If WIDTH is negative then
-   format the string to be exactly - WIDTH characters,
-   truncating or padding as necessary.  */
+  if (extra_padding && width > 0)
+    {
+      /* Fill in the remaining spaces.  */
+      printf ("%-*s", width, " ");
+      num_printed += 2;
+    }
 
-static void
-print_symbol (int width, const char *symbol)
-{
-  if (do_wide)
-    printf ("%s", symbol);
-  else if (width < 0)
-    printf ("%-*.*s", width, width, symbol);
-  else
-    printf ("%-.*s", width, symbol);
+  return num_printed;
 }
 
 static void
@@ -637,6 +583,7 @@ guess_is_rela (unsigned int e_machine)
     case EM_AVR_OLD:
     case EM_BLACKFIN:
     case EM_CR16:
+    case EM_CR16_OLD:
     case EM_CRIS:
     case EM_CRX:
     case EM_D30V:
@@ -651,6 +598,7 @@ guess_is_rela (unsigned int e_machine)
     case EM_IP2K:
     case EM_IP2K_OLD:
     case EM_IQ2000:
+    case EM_M32C_OLD:
     case EM_M32C:
     case EM_M32R:
     case EM_MCORE:
@@ -768,6 +716,28 @@ slurp_rela_relocs (FILE *file,
          relas[i].r_offset = BYTE_GET (erelas[i].r_offset);
          relas[i].r_info   = BYTE_GET (erelas[i].r_info);
          relas[i].r_addend = BYTE_GET (erelas[i].r_addend);
+
+         /* The #ifdef BFD64 below is to prevent a compile time
+            warning.  We know that if we do not have a 64 bit data
+            type that we will never execute this code anyway.  */
+#ifdef BFD64
+         if (elf_header.e_machine == EM_MIPS
+             && elf_header.e_ident[EI_DATA] != ELFDATA2MSB)
+           {
+             /* In little-endian objects, r_info isn't really a
+                64-bit little-endian value: it has a 32-bit
+                little-endian symbol index followed by four
+                individual byte fields.  Reorder INFO
+                accordingly.  */
+             bfd_vma info = relas[i].r_info;
+             info = (((info & 0xffffffff) << 32)
+                     | ((info >> 56) & 0xff)
+                     | ((info >> 40) & 0xff00)
+                     | ((info >> 24) & 0xff0000)
+                     | ((info >> 8) & 0xff000000));
+             relas[i].r_info = info;
+           }
+#endif /* BFD64 */
        }
 
       free (erelas);
@@ -840,6 +810,28 @@ slurp_rel_relocs (FILE *file,
          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;
+
+         /* The #ifdef BFD64 below is to prevent a compile time
+            warning.  We know that if we do not have a 64 bit data
+            type that we will never execute this code anyway.  */
+#ifdef BFD64
+         if (elf_header.e_machine == EM_MIPS
+             && elf_header.e_ident[EI_DATA] != ELFDATA2MSB)
+           {
+             /* In little-endian objects, r_info isn't really a
+                64-bit little-endian value: it has a 32-bit
+                little-endian symbol index followed by four
+                individual byte fields.  Reorder INFO
+                accordingly.  */
+             bfd_vma info = rels[i].r_info;
+             info = (((info & 0xffffffff) << 32)
+                     | ((info >> 56) & 0xff)
+                     | ((info >> 40) & 0xff00)
+                     | ((info >> 24) & 0xff0000)
+                     | ((info >> 8) & 0xff000000));
+             rels[i].r_info = info;
+           }
+#endif /* BFD64 */
        }
 
       free (erels);
@@ -956,26 +948,6 @@ dump_relocations (FILE *file,
       offset = rels[i].r_offset;
       info   = rels[i].r_info;
 
-      /* The #ifdef BFD64 below is to prevent a compile time warning.
-        We know that if we do not have a 64 bit data type that we
-        will never execute this code anyway.  */
-#ifdef BFD64
-      if (!is_32bit_elf
-         && elf_header.e_machine == EM_MIPS
-         && elf_header.e_ident[EI_DATA] != ELFDATA2MSB)
-       {
-         /* In little-endian objects, r_info isn't really a 64-bit
-            little-endian value: it has a 32-bit little-endian
-            symbol index followed by four individual byte fields.
-            Reorder INFO accordingly.  */
-         info = (((info & 0xffffffff) << 32)
-                 | ((info >> 56) & 0xff)
-                 | ((info >> 40) & 0xff00)
-                 | ((info >> 24) & 0xff0000)
-                 | ((info >> 8) & 0xff000000));
-       }
-#endif /* BFD64 */
-
       type = get_reloc_type (info);
       symtab_index = get_reloc_symindex  (info);
 
@@ -1214,6 +1186,7 @@ dump_relocations (FILE *file,
          rtype = elf_xtensa_reloc_type (type);
          break;
 
+       case EM_M32C_OLD:
        case EM_M32C:
          rtype = elf_m32c_reloc_type (type);
          break;
@@ -1231,6 +1204,7 @@ dump_relocations (FILE *file,
          break;
 
        case EM_CR16:
+       case EM_CR16_OLD:
          rtype = elf_cr16_reloc_type (type);
          break;
        }
@@ -1276,8 +1250,39 @@ dump_relocations (FILE *file,
              psym = symtab + symtab_index;
 
              printf (" ");
-             print_vma (psym->st_value, LONG_HEX);
-             printf (is_32bit_elf ? "   " : " ");
+
+             if (ELF_ST_TYPE (psym->st_info) == STT_IFUNC)
+               {
+                 const char * name;
+                 unsigned int len;
+                 unsigned int width = is_32bit_elf ? 8 : 14;
+
+                 /* Relocations against IFUNC symbols do not use the value of
+                    the symbol as the address to relocate against.  Instead
+                    they invoke the function named by the symbol and use its
+                    result as the address for relocation.
+
+                    To indicate this to the user, do not display the value of
+                    the symbol in the "Symbols's Value" field.  Instead show
+                    its name followed by () as a hint that the symbol is
+                    invoked.  */
+
+                 if (strtab == NULL
+                     || psym->st_name == 0
+                     || psym->st_name >= strtablen)
+                   name = "??";
+                 else
+                   name = strtab + psym->st_name;
+
+                 len = print_symbol (width, name);
+                 printf ("()%-*s", len <= width ? (width + 1) - len : 1, " ");
+               }
+             else
+               {
+                 print_vma (psym->st_value, LONG_HEX);
+
+                 printf (is_32bit_elf ? "   " : " ");
+               }
 
              if (psym->st_name == 0)
                {
@@ -1307,7 +1312,7 @@ dump_relocations (FILE *file,
                               && psym->st_shndx == SHN_IA_64_ANSI_COMMON)
                        sec_name = "ANSI_COM";
                      else if (elf_header.e_machine == EM_IA_64
-                              && (elf_header.e_ident[EI_OSABI] 
+                              && (elf_header.e_ident[EI_OSABI]
                                   == ELFOSABI_OPENVMS)
                               && psym->st_shndx == SHN_IA_64_VMS_SYMVEC)
                        sec_name = "VMS_SYMVEC";
@@ -1328,7 +1333,14 @@ dump_relocations (FILE *file,
                print_symbol (22, strtab + psym->st_name);
 
              if (is_rela)
-               printf (" + %lx", (unsigned long) rels[i].r_addend);
+               {
+                 long offset = (long) (bfd_signed_vma) rels[i].r_addend;
+
+                 if (offset < 0)
+                   printf (" - %lx", - offset);
+                 else
+                   printf (" + %lx", offset);
+               }
            }
        }
       else if (is_rela)
@@ -1425,6 +1437,8 @@ get_mips_dynamic_type (unsigned long type)
     case DT_MIPS_COMPACT_SIZE: return "MIPS_COMPACT_SIZE";
     case DT_MIPS_GP_VALUE: return "MIPS_GP_VALUE";
     case DT_MIPS_AUX_DYNAMIC: return "MIPS_AUX_DYNAMIC";
+    case DT_MIPS_PLTGOT: return "MIPS_PLTGOT";
+    case DT_MIPS_RWPLT: return "MIPS_RWPLT";
     default:
       return NULL;
     }
@@ -1848,6 +1862,7 @@ get_machine_name (unsigned e_machine)
     case EM_IQ2000:            return "Vitesse IQ2000";
     case EM_XTENSA_OLD:
     case EM_XTENSA:            return "Tensilica Xtensa Processor";
+    case EM_M32C_OLD:
     case EM_M32C:              return "Renesas M32c";
     case EM_MT:                 return "Morpho Techologies MT processor";
     case EM_BLACKFIN:          return "Analog Devices Blackfin";
@@ -1855,7 +1870,8 @@ get_machine_name (unsigned e_machine)
     case EM_ALTERA_NIOS2:      return "Altera Nios II";
     case EM_XC16X:             return "Infineon Technologies xc16x";
     case EM_CYGNUS_MEP:         return "Toshiba MeP Media Engine";
-    case EM_CR16:              return "National Semiconductor's CR16";
+    case EM_CR16:
+    case EM_CR16_OLD:          return "National Semiconductor's CR16";
     default:
       snprintf (buff, sizeof (buff), _("<unknown>: 0x%x"), e_machine);
       return buff;
@@ -2426,7 +2442,7 @@ get_osabi_name (unsigned int osabi)
     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_AROS:                return "AROS";
     case ELFOSABI_STANDALONE:  return _("Standalone App");
     case ELFOSABI_ARM:         return "ARM";
     default:
@@ -2880,8 +2896,8 @@ usage (FILE *stream)
                          Dump the contents of section <number|name> as bytes\n\
   -p --string-dump=<number|name>\n\
                          Dump the contents of section <number|name> as strings\n\
-  -w[liaprmfFsoR] or\n\
-  --debug-dump[=line,=info,=abbrev,=pubnames,=aranges,=macro,=frames,=str,=loc,=Ranges]\n\
+  -w[lLiaprmfFsoR] or\n\
+  --debug-dump[=rawline,=decodedline,=info,=abbrev,=pubnames,=aranges,=macro,=frames,=str,=loc,=Ranges]\n\
                          Display the contents of DWARF2 debug sections\n"));
 #ifdef SUPPORT_DISASSEMBLY
   fprintf (stream, _("\
@@ -3083,6 +3099,10 @@ parse_args (int argc, char **argv)
                    do_debug_lines = 1;
                    break;
 
+                 case 'L':
+                   do_debug_lines_decoded = 1;
+                   break;
+
                  case 'p':
                    do_debug_pubnames = 1;
                    break;
@@ -3141,7 +3161,9 @@ parse_args (int argc, char **argv)
                  { "frames", & do_debug_frames },
                  { "frames-interp", & do_debug_frames_interp },
                  { "info", & do_debug_info },
-                 { "line", & do_debug_lines },
+                 { "line", & do_debug_lines }, /* For backwards compatibility.  */
+                 { "rawline", & do_debug_lines },
+                 { "decodedline", & do_debug_lines_decoded },
                  { "loc",  & do_debug_loc },
                  { "macro", & do_debug_macinfo },
                  { "pubnames", & do_debug_pubnames },
@@ -3676,7 +3698,7 @@ process_program_headers (FILE *file)
          Elf_Internal_Shdr *section;
 
          segment = program_headers + i;
-         section = section_headers;
+         section = section_headers + 1;
 
          printf ("   %2.2d     ", i);
 
@@ -3720,7 +3742,7 @@ offset_from_vma (FILE *file, bfd_vma vma, bfd_size_type size)
     }
 
   warn (_("Virtual address 0x%lx not located in any PT_LOAD segment.\n"),
-       (long) vma);
+       (unsigned long) vma);
   return (long) vma;
 }
 
@@ -4228,6 +4250,7 @@ process_section_headers (FILE *file)
        }
       break;
 
+    case EM_M32C_OLD:
     case EM_M32C:
       switch (elf_header.e_flags & EF_M32C_CPU_MASK)
        {
@@ -4303,17 +4326,22 @@ process_section_headers (FILE *file)
       else if (section->sh_type == SHT_RELA)
        CHECK_ENTSIZE (section, i, Rela);
       else if ((do_debugging || do_debug_info || do_debug_abbrevs
-               || do_debug_lines || do_debug_pubnames || do_debug_aranges
-               || do_debug_frames || do_debug_macinfo || do_debug_str
-               || do_debug_loc || do_debug_ranges)
-              && const_strneq (name, ".debug_"))
+               || do_debug_lines || do_debug_lines_decoded || do_debug_pubnames
+               || do_debug_aranges || do_debug_frames || do_debug_macinfo
+               || do_debug_str || do_debug_loc || do_debug_ranges)
+              && (const_strneq (name, ".debug_")
+                   || const_strneq (name, ".zdebug_")))
        {
-         name += 7;
+          if (name[1] == 'z')
+            name += sizeof (".zdebug_") - 1;
+          else
+            name += sizeof (".debug_") - 1;
 
          if (do_debugging
              || (do_debug_info     && streq (name, "info"))
              || (do_debug_abbrevs  && streq (name, "abbrev"))
-             || (do_debug_lines    && streq (name, "line"))
+             || ((do_debug_lines || do_debug_lines_decoded)
+                 && streq (name, "line"))
              || (do_debug_pubnames && streq (name, "pubnames"))
              || (do_debug_aranges  && streq (name, "aranges"))
              || (do_debug_ranges   && streq (name, "ranges"))
@@ -4324,7 +4352,7 @@ process_section_headers (FILE *file)
              )
            request_dump_bynumber (i, DEBUG_DUMP);
        }
-      /* linkonce section to be combined with .debug_info at link time.  */
+      /* Linkonce section to be combined with .debug_info at link time.  */
       else if ((do_debugging || do_debug_info)
               && const_strneq (name, ".gnu.linkonce.wi."))
        request_dump_bynumber (i, DEBUG_DUMP);
@@ -4394,7 +4422,8 @@ process_section_headers (FILE *file)
                    get_section_type_name (section->sh_type));
        }
       else
-       printf ("  [%2u] %-17.17s %-15.15s ",
+       printf ((do_wide ? "  [%2u] %-17s %-15s "
+                        : "  [%2u] %-17.17s %-15.15s "),
                i,
                SECTION_NAME (section),
                get_section_type_name (section->sh_type));
@@ -5731,7 +5760,7 @@ dynamic_section_mips_val (Elf_Internal_Dyn *entry)
       break;
 
     default:
-      printf ("%#lx\n", (long) entry->d_un.d_ptr);
+      printf ("%#lx\n", (unsigned long) entry->d_un.d_ptr);
     }
 }
 
@@ -7036,6 +7065,14 @@ get_symbol_type (unsigned int type)
              if (type == STT_HP_STUB)
                return "HP_STUB";
            }
+         else if (elf_header.e_ident[EI_OSABI] == ELFOSABI_LINUX
+                  || elf_header.e_ident[EI_OSABI] == ELFOSABI_HURD
+                  /* GNU/Linux is still using the default value 0.  */
+                  || elf_header.e_ident[EI_OSABI] == ELFOSABI_NONE)
+           {
+             if (type == STT_IFUNC)
+               return "IFUNC";
+           }
 
          snprintf (buff, sizeof (buff), _("<OS specific>: %d"), type);
        }
@@ -7065,6 +7102,8 @@ get_mips_symbol_other (unsigned int other)
     {
     case STO_OPTIONAL:  return "OPTIONAL";
     case STO_MIPS16:    return "MIPS16";
+    case STO_MIPS_PLT: return "MIPS PLT";
+    case STO_MIPS_PIC: return "MIPS PIC";
     default:           return NULL;
     }
 }
@@ -8044,7 +8083,7 @@ is_32bit_abs_reloc (unsigned int reloc_type)
       return reloc_type == 1; /* R_ARC_32.  */
     case EM_ARM:
       return reloc_type == 2; /* R_ARM_ABS32 */
-    case EM_AVR_OLD: 
+    case EM_AVR_OLD:
     case EM_AVR:
       return reloc_type == 1;
     case EM_BLACKFIN:
@@ -8052,6 +8091,7 @@ is_32bit_abs_reloc (unsigned int reloc_type)
     case EM_CRIS:
       return reloc_type == 3; /* R_CRIS_32.  */
     case EM_CR16:
+    case EM_CR16_OLD:
       return reloc_type == 3; /* R_CR16_NUM32.  */
     case EM_CRX:
       return reloc_type == 15; /* R_CRX_NUM32.  */
@@ -8079,6 +8119,7 @@ is_32bit_abs_reloc (unsigned int reloc_type)
       return reloc_type == 2; /* R_IP2K_32.  */
     case EM_IQ2000:
       return reloc_type == 2; /* R_IQ2000_32.  */
+    case EM_M32C_OLD:
     case EM_M32C:
       return reloc_type == 3; /* R_M32C_32.  */
     case EM_M32R:
@@ -8171,7 +8212,7 @@ is_32bit_pcrel_reloc (unsigned int reloc_type)
     case EM_ARM:
       return reloc_type == 3;  /* R_ARM_REL32 */
     case EM_PARISC:
-      return reloc_type == 0;  /* R_PARISC_NONE.  *//* FIXME: This reloc is generated, but it may be a bug.  */
+      return reloc_type == 9;  /* R_PARISC_PCREL32.  */
     case EM_PPC:
       return reloc_type == 26; /* R_PPC_REL32.  */
     case EM_PPC64:
@@ -8227,6 +8268,38 @@ is_64bit_abs_reloc (unsigned int reloc_type)
     case EM_S390_OLD:
     case EM_S390:
       return reloc_type == 22; /* R_S390_64 */
+    case EM_MIPS:
+      return reloc_type == 18; /* R_MIPS_64 */
+    default:
+      return FALSE;
+    }
+}
+
+/* Like is_32bit_pcrel_reloc except that it returns TRUE iff RELOC_TYPE is
+   a 64-bit pc-relative RELA relocation used in DWARF debug sections.  */
+
+static bfd_boolean
+is_64bit_pcrel_reloc (unsigned int reloc_type)
+{
+  switch (elf_header.e_machine)
+    {
+    case EM_ALPHA:
+      return reloc_type == 11; /* R_ALPHA_SREL64 */
+    case EM_IA_64:
+      return reloc_type == 0x4f; /* R_IA64_PCREL64LSB */
+    case EM_PARISC:
+      return reloc_type == 72; /* R_PARISC_PCREL64 */
+    case EM_PPC64:
+      return reloc_type == 44; /* R_PPC64_REL64 */
+    case EM_SPARC32PLUS:
+    case EM_SPARCV9:
+    case EM_SPARC:
+      return reloc_type == 46; /* R_SPARC_DISP64 */
+    case EM_X86_64:
+      return reloc_type == 24; /* R_X86_64_PC64 */
+    case EM_S390_OLD:
+    case EM_S390:
+      return reloc_type == 23; /* R_S390_PC64 */
     default:
       return FALSE;
     }
@@ -8253,6 +8326,7 @@ is_16bit_abs_reloc (unsigned int reloc_type)
     case EM_IP2K_OLD:
     case EM_IP2K:
       return reloc_type == 1; /* R_IP2K_16.  */
+    case EM_M32C_OLD:
     case EM_M32C:
       return reloc_type == 1; /* R_M32C_16 */
     case EM_MSP430_OLD:
@@ -8266,6 +8340,111 @@ is_16bit_abs_reloc (unsigned int reloc_type)
     }
 }
 
+/* Returns TRUE iff RELOC_TYPE is a NONE relocation used for discarded
+   relocation entries (possibly formerly used for SHT_GROUP sections).  */
+
+static bfd_boolean
+is_none_reloc (unsigned int reloc_type)
+{
+  switch (elf_header.e_machine)
+    {
+    case EM_68K:     /* R_68K_NONE.  */
+    case EM_386:     /* R_386_NONE.  */
+    case EM_SPARC32PLUS:
+    case EM_SPARCV9:
+    case EM_SPARC:   /* R_SPARC_NONE.  */
+    case EM_MIPS:    /* R_MIPS_NONE.  */
+    case EM_PARISC:  /* R_PARISC_NONE.  */
+    case EM_ALPHA:   /* R_ALPHA_NONE.  */
+    case EM_PPC:     /* R_PPC_NONE.  */
+    case EM_PPC64:   /* R_PPC64_NONE.  */
+    case EM_ARM:     /* R_ARM_NONE.  */
+    case EM_IA_64:   /* R_IA64_NONE.  */
+    case EM_SH:      /* R_SH_NONE.  */
+    case EM_S390_OLD:
+    case EM_S390:    /* R_390_NONE.  */
+    case EM_CRIS:    /* R_CRIS_NONE.  */
+    case EM_X86_64:  /* R_X86_64_NONE.  */
+    case EM_MN10300: /* R_MN10300_NONE.  */
+    case EM_M32R:    /* R_M32R_NONE.  */
+      return reloc_type == 0;
+    }
+  return FALSE;
+}
+
+/* Uncompresses a section that was compressed using zlib, in place.
+   This is a copy of bfd_uncompress_section_contents, in bfd/compress.c  */
+
+static int
+uncompress_section_contents (unsigned char **buffer, dwarf_size_type *size)
+{
+#ifndef HAVE_ZLIB_H
+  /* These are just to quiet gcc.  */
+  buffer = 0;
+  size = 0;
+  return FALSE;
+#else
+  dwarf_size_type compressed_size = *size;
+  unsigned char * compressed_buffer = *buffer;
+  dwarf_size_type uncompressed_size;
+  unsigned char * uncompressed_buffer;
+  z_stream strm;
+  int rc;
+  dwarf_size_type header_size = 12;
+
+  /* Read the zlib header.  In this case, it should be "ZLIB" followed
+     by the uncompressed section size, 8 bytes in big-endian order.  */
+  if (compressed_size < header_size
+      || ! streq ((char *) compressed_buffer, "ZLIB"))
+    return 0;
+
+  uncompressed_size = compressed_buffer[4]; uncompressed_size <<= 8;
+  uncompressed_size += compressed_buffer[5]; uncompressed_size <<= 8;
+  uncompressed_size += compressed_buffer[6]; uncompressed_size <<= 8;
+  uncompressed_size += compressed_buffer[7]; uncompressed_size <<= 8;
+  uncompressed_size += compressed_buffer[8]; uncompressed_size <<= 8;
+  uncompressed_size += compressed_buffer[9]; uncompressed_size <<= 8;
+  uncompressed_size += compressed_buffer[10]; uncompressed_size <<= 8;
+  uncompressed_size += compressed_buffer[11];
+
+  /* It is possible the section consists of several compressed
+     buffers concatenated together, so we uncompress in a loop.  */
+  strm.zalloc = NULL;
+  strm.zfree = NULL;
+  strm.opaque = NULL;
+  strm.avail_in = compressed_size - header_size;
+  strm.next_in = (Bytef *) compressed_buffer + header_size;
+  strm.avail_out = uncompressed_size;
+  uncompressed_buffer = xmalloc (uncompressed_size);
+
+  rc = inflateInit (& strm);
+  while (strm.avail_in > 0)
+    {
+      if (rc != Z_OK)
+        goto fail;
+      strm.next_out = ((Bytef *) uncompressed_buffer
+                       + (uncompressed_size - strm.avail_out));
+      rc = inflate (&strm, Z_FINISH);
+      if (rc != Z_STREAM_END)
+        goto fail;
+      rc = inflateReset (& strm);
+    }
+  rc = inflateEnd (& strm);
+  if (rc != Z_OK
+      || strm.avail_out != 0)
+    goto fail;
+
+  free (compressed_buffer);
+  *buffer = uncompressed_buffer;
+  *size = uncompressed_size;
+  return 1;
+
+ fail:
+  free (uncompressed_buffer);
+  return 0;
+#endif  /* HAVE_ZLIB_H */
+}
+
 /* Apply relocations to a debug section.  */
 
 static void
@@ -8327,25 +8506,16 @@ debug_apply_relocations (void *file,
          unsigned int    reloc_size;
          unsigned char * loc;
 
-         /* In MIPS little-endian objects, r_info isn't really a
-            64-bit little-endian value: it has a 32-bit little-endian
-            symbol index followed by four individual byte fields.
-            Reorder INFO accordingly.  */
-         if (!is_32bit_elf
-             && elf_header.e_machine == EM_MIPS
-             && elf_header.e_ident[EI_DATA] != ELFDATA2MSB)
-           rp->r_info = (((rp->r_info & 0xffffffff) << 32)
-                         | ((rp->r_info >> 56) & 0xff)
-                         | ((rp->r_info >> 40) & 0xff00)
-                         | ((rp->r_info >> 24) & 0xff0000)
-                         | ((rp->r_info >> 8) & 0xff000000));
-
          reloc_type = get_reloc_type (rp->r_info);
 
+         if (is_none_reloc (reloc_type))
+           continue;
+
          if (is_32bit_abs_reloc (reloc_type)
              || is_32bit_pcrel_reloc (reloc_type))
            reloc_size = 4;
-         else if (is_64bit_abs_reloc (reloc_type))
+         else if (is_64bit_abs_reloc (reloc_type)
+                  || is_64bit_pcrel_reloc (reloc_type))
            reloc_size = 8;
          else if (is_16bit_abs_reloc (reloc_type))
            reloc_size = 2;
@@ -8388,10 +8558,16 @@ debug_apply_relocations (void *file,
            }
 
          addend = is_rela ? rp->r_addend : byte_get (loc, reloc_size);
-         
-         if (is_32bit_pcrel_reloc (reloc_type))
-           byte_put (loc, (addend + sym->st_value) - rp->r_offset,
-                     reloc_size);
+
+         if (is_32bit_pcrel_reloc (reloc_type)
+             || is_64bit_pcrel_reloc (reloc_type))
+           {
+             /* On HPPA, all pc-relative relocations are biased by 8.  */
+             if (elf_header.e_machine == EM_PARISC)
+               addend -= 8;
+             byte_put (loc, (addend + sym->st_value) - rp->r_offset,
+                       reloc_size);
+           }
          else
            byte_put (loc, addend + sym->st_value, reloc_size);
        }
@@ -8402,32 +8578,58 @@ debug_apply_relocations (void *file,
     }
 }
 
-int
-load_debug_section (enum dwarf_section_display_enum debug, void *file)
+static int
+load_specific_debug_section (enum dwarf_section_display_enum debug,
+                            Elf_Internal_Shdr *sec, void *file)
 {
   struct dwarf_section *section = &debug_displays [debug].section;
-  Elf_Internal_Shdr *sec;
   char buf [64];
+  int section_is_compressed;
 
   /* If it is already loaded, do nothing.  */
   if (section->start != NULL)
     return 1;
 
-  /* Locate the debug section.  */
-  sec = find_section (section->name);
-  if (sec == NULL)
-    return 0;
+  section_is_compressed = section->name == section->compressed_name;
 
   snprintf (buf, sizeof (buf), _("%s section data"), section->name);
   section->address = sec->sh_addr;
   section->size = sec->sh_size;
   section->start = get_data (NULL, file, sec->sh_offset, 1,
                             sec->sh_size, buf);
+  if (section->start == NULL)
+    return 0;
+
+  if (section_is_compressed)
+    if (! uncompress_section_contents (&section->start, &section->size))
+      return 0;
 
   if (debug_displays [debug].relocate)
     debug_apply_relocations (file, sec, section->start);
 
-  return section->start != NULL;
+  return 1;
+}
+
+int
+load_debug_section (enum dwarf_section_display_enum debug, void *file)
+{
+  struct dwarf_section *section = &debug_displays [debug].section;
+  Elf_Internal_Shdr *sec;
+
+  /* Locate the debug section.  */
+  sec = find_section (section->uncompressed_name);
+  if (sec != NULL)
+    section->name = section->uncompressed_name;
+  else
+    {
+      sec = find_section (section->compressed_name);
+      if (sec != NULL)
+       section->name = section->compressed_name;
+    }
+  if (sec == NULL)
+    return 0;
+
+  return load_specific_debug_section (debug, sec, file);
 }
 
 void
@@ -8464,15 +8666,24 @@ display_debug_section (Elf_Internal_Shdr *section, FILE *file)
 
   /* See if we know how to display the contents of this section.  */
   for (i = 0; i < max; i++)
-    if (streq (debug_displays[i].section.name, name))
+    if (streq (debug_displays[i].section.uncompressed_name, name)
+        || streq (debug_displays[i].section.compressed_name, name))
       {
        struct dwarf_section *sec = &debug_displays [i].section;
+       int secondary = (section != find_section (name));
+
+       if (secondary)
+         free_debug_section (i);
 
-       if (load_debug_section (i, file))
+       if (streq (debug_displays[i].section.uncompressed_name, name))
+         sec->name = sec->uncompressed_name;
+       else
+         sec->name = sec->compressed_name;
+       if (load_specific_debug_section (i, section, file))
          {
            result &= debug_displays[i].display (sec, file);
 
-           if (i != info && i != abbrev)
+           if (secondary || (i != info && i != abbrev))
              free_debug_section (i);
          }
 
@@ -8583,29 +8794,30 @@ typedef struct
 
 static const char *arm_attr_tag_CPU_arch[] =
   {"Pre-v4", "v4", "v4T", "v5T", "v5TE", "v5TEJ", "v6", "v6KZ", "v6T2",
-   "v6K", "v7"};
+   "v6K", "v7", "v6-M", "v6S-M"};
 static const char *arm_attr_tag_ARM_ISA_use[] = {"No", "Yes"};
 static const char *arm_attr_tag_THUMB_ISA_use[] =
   {"No", "Thumb-1", "Thumb-2"};
 static const char *arm_attr_tag_VFP_arch[] =
   {"No", "VFPv1", "VFPv2", "VFPv3", "VFPv3-D16"};
-static const char *arm_attr_tag_WMMX_arch[] = {"No", "WMMXv1"};
-static const char *arm_attr_tag_NEON_arch[] = {"No", "NEONv1"};
-static const char *arm_attr_tag_ABI_PCS_config[] =
+static const char *arm_attr_tag_WMMX_arch[] = {"No", "WMMXv1", "WMMXv2"};
+static const char *arm_attr_tag_Advanced_SIMD_arch[] = {"No", "NEONv1"};
+static const char *arm_attr_tag_PCS_config[] =
   {"None", "Bare platform", "Linux application", "Linux DSO", "PalmOS 2004",
    "PalmOS (reserved)", "SymbianOS 2004", "SymbianOS (reserved)"};
 static const char *arm_attr_tag_ABI_PCS_R9_use[] =
   {"V6", "SB", "TLS", "Unused"};
 static const char *arm_attr_tag_ABI_PCS_RW_data[] =
   {"Absolute", "PC-relative", "SB-relative", "None"};
-static const char *arm_attr_tag_ABI_PCS_RO_DATA[] =
+static const char *arm_attr_tag_ABI_PCS_RO_data[] =
   {"Absolute", "PC-relative", "None"};
 static const char *arm_attr_tag_ABI_PCS_GOT_use[] =
   {"None", "direct", "GOT-indirect"};
 static const char *arm_attr_tag_ABI_PCS_wchar_t[] =
   {"None", "??? 1", "2", "??? 3", "4"};
 static const char *arm_attr_tag_ABI_FP_rounding[] = {"Unused", "Needed"};
-static const char *arm_attr_tag_ABI_FP_denormal[] = {"Unused", "Needed"};
+static const char *arm_attr_tag_ABI_FP_denormal[] =
+  {"Unused", "Needed", "Sign only"};
 static const char *arm_attr_tag_ABI_FP_exceptions[] = {"Unused", "Needed"};
 static const char *arm_attr_tag_ABI_FP_user_exceptions[] = {"Unused", "Needed"};
 static const char *arm_attr_tag_ABI_FP_number_model[] =
@@ -8627,6 +8839,15 @@ static const char *arm_attr_tag_ABI_optimization_goals[] =
 static const char *arm_attr_tag_ABI_FP_optimization_goals[] =
   {"None", "Prefer Speed", "Aggressive Speed", "Prefer Size",
     "Aggressive Size", "Prefer Accuracy", "Aggressive Accuracy"};
+static const char *arm_attr_tag_CPU_unaligned_access[] = {"None", "v6"};
+static const char *arm_attr_tag_VFP_HP_extension[] =
+  {"Not Allowed", "Allowed"};
+static const char *arm_attr_tag_ABI_FP_16bit_format[] =
+  {"None", "IEEE 754", "Alternative Format"};
+static const char *arm_attr_tag_T2EE_use[] = {"Not Allowed", "Allowed"};
+static const char *arm_attr_tag_Virtualization_use[] =
+  {"Not Allowed", "Allowed"};
+static const char *arm_attr_tag_MPextension_use[] = {"Not Allowed", "Allowed"};
 
 #define LOOKUP(id, name) \
   {id, #name, 0x80 | ARRAY_SIZE(arm_attr_tag_##name), arm_attr_tag_##name}
@@ -8640,11 +8861,11 @@ static arm_attr_public_tag arm_attr_public_tags[] =
   LOOKUP(9, THUMB_ISA_use),
   LOOKUP(10, VFP_arch),
   LOOKUP(11, WMMX_arch),
-  LOOKUP(12, NEON_arch),
-  LOOKUP(13, ABI_PCS_config),
+  LOOKUP(12, Advanced_SIMD_arch),
+  LOOKUP(13, PCS_config),
   LOOKUP(14, ABI_PCS_R9_use),
   LOOKUP(15, ABI_PCS_RW_data),
-  LOOKUP(16, ABI_PCS_RO_DATA),
+  LOOKUP(16, ABI_PCS_RO_data),
   LOOKUP(17, ABI_PCS_GOT_use),
   LOOKUP(18, ABI_PCS_wchar_t),
   LOOKUP(19, ABI_FP_rounding),
@@ -8660,7 +8881,16 @@ static arm_attr_public_tag arm_attr_public_tags[] =
   LOOKUP(29, ABI_WMMX_args),
   LOOKUP(30, ABI_optimization_goals),
   LOOKUP(31, ABI_FP_optimization_goals),
-  {32, "compatibility", 0, NULL}
+  {32, "compatibility", 0, NULL},
+  LOOKUP(34, CPU_unaligned_access),
+  LOOKUP(36, VFP_HP_extension),
+  LOOKUP(38, ABI_FP_16bit_format),
+  {64, "nodefaults", 0, NULL},
+  {65, "also_compatible_with", 0, NULL},
+  LOOKUP(66, T2EE_use),
+  {67, "conformance", 1, NULL},
+  LOOKUP(68, Virtualization_use),
+  LOOKUP(70, MPextension_use)
 };
 #undef LOOKUP
 
@@ -8740,6 +8970,28 @@ display_arm_attribute (unsigned char *p)
              p += strlen((char *)p) + 1;
              break;
 
+           case 64: /* Tag_nodefaults.  */
+             p++;
+             printf ("True\n");
+             break;
+
+           case 65: /* Tag_also_compatible_with.  */
+             val = read_uleb128 (p, &len);
+             p += len;
+             if (val == 6 /* Tag_CPU_arch.  */)
+               {
+                 val = read_uleb128 (p, &len);
+                 p += len;
+                 if ((unsigned int)val >= ARRAY_SIZE(arm_attr_tag_CPU_arch))
+                   printf ("??? (%d)\n", val);
+                 else
+                   printf ("%s\n", arm_attr_tag_CPU_arch[val]);
+               }
+             else
+               printf ("???\n");
+             while (*(p++) != '\0' /* NUL terminator.  */);
+             break;
+
            default:
              abort();
            }
@@ -8857,6 +9109,9 @@ display_power_gnu_attribute (unsigned char *p, int tag)
        case 2:
          printf ("Soft float\n");
          break;
+       case 3:
+         printf ("Single-precision hard float\n");
+         break;
        default:
          printf ("??? (%d)\n", val);
          break;
@@ -8890,6 +9145,29 @@ display_power_gnu_attribute (unsigned char *p, int tag)
       return p;
    }
 
+  if (tag == Tag_GNU_Power_ABI_Struct_Return)
+    {
+      val = read_uleb128 (p, &len);
+      p += len;
+      printf ("  Tag_GNU_Power_ABI_Struct_Return: ");
+      switch (val)
+       {
+       case 0:
+         printf ("Any\n");
+         break;
+       case 1:
+         printf ("r3/r4\n");
+         break;
+       case 2:
+         printf ("Memory\n");
+         break;
+       default:
+         printf ("??? (%d)\n", val);
+         break;
+       }
+      return p;
+    }
+
   if (tag & 1)
     type = 1; /* String.  */
   else
@@ -9152,6 +9430,28 @@ print_mips_got_entry (unsigned char *data, bfd_vma pltgot, bfd_vma addr)
   return addr + (is_32bit_elf ? 4 : 8);
 }
 
+/* DATA points to the contents of a MIPS PLT GOT that starts at VMA
+   PLTGOT.  Print the Address and Initial fields of an entry at VMA
+   ADDR and return the VMA of the next entry.  */
+
+static bfd_vma
+print_mips_pltgot_entry (unsigned char *data, bfd_vma pltgot, bfd_vma addr)
+{
+  printf ("  ");
+  print_vma (addr, LONG_HEX);
+  printf (" ");
+  if (data == NULL)
+    printf ("%*s", is_32bit_elf ? 8 : 16, "<unknown>");
+  else
+    {
+      bfd_vma entry;
+
+      entry = byte_get (data + addr - pltgot, is_32bit_elf ? 4 : 8);
+      print_vma (entry, LONG_HEX);
+    }
+  return addr + (is_32bit_elf ? 4 : 8);
+}
+
 static int
 process_mips_specific (FILE *file)
 {
@@ -9161,7 +9461,11 @@ process_mips_specific (FILE *file)
   size_t conflictsno = 0;
   size_t options_offset = 0;
   size_t conflicts_offset = 0;
+  size_t pltrelsz = 0;
+  size_t pltrel = 0;
   bfd_vma pltgot = 0;
+  bfd_vma mips_pltgot = 0;
+  bfd_vma jmprel = 0;
   bfd_vma local_gotno = 0;
   bfd_vma gotsym = 0;
   bfd_vma symtabno = 0;
@@ -9197,7 +9501,8 @@ process_mips_specific (FILE *file)
        conflictsno = entry->d_un.d_val;
        break;
       case DT_PLTGOT:
-       pltgot = entry->d_un.d_val;
+       pltgot = entry->d_un.d_ptr;
+       break;
       case DT_MIPS_LOCAL_GOTNO:
        local_gotno = entry->d_un.d_val;
        break;
@@ -9207,6 +9512,18 @@ process_mips_specific (FILE *file)
       case DT_MIPS_SYMTABNO:
        symtabno = entry->d_un.d_val;
        break;
+      case DT_MIPS_PLTGOT:
+       mips_pltgot = entry->d_un.d_ptr;
+       break;
+      case DT_PLTREL:
+       pltrel = entry->d_un.d_val;
+       break;
+      case DT_PLTRELSZ:
+       pltrelsz = entry->d_un.d_val;
+       break;
+      case DT_JMPREL:
+       jmprel = entry->d_un.d_ptr;
+       break;
       default:
        break;
       }
@@ -9639,6 +9956,73 @@ process_mips_specific (FILE *file)
        free (data);
     }
 
+  if (mips_pltgot != 0 && jmprel != 0 && pltrel != 0 && pltrelsz != 0)
+    {
+      bfd_vma entry, end;
+      size_t offset, rel_offset;
+      unsigned long count, i;
+      unsigned char *data;
+      int addr_size, sym_width;
+      Elf_Internal_Rela *rels;
+
+      rel_offset = offset_from_vma (file, jmprel, pltrelsz);
+      if (pltrel == DT_RELA)
+       {
+         if (!slurp_rela_relocs (file, rel_offset, pltrelsz, &rels, &count))
+           return 0;
+       }
+      else
+       {
+         if (!slurp_rel_relocs (file, rel_offset, pltrelsz, &rels, &count))
+           return 0;
+       }
+
+      entry = mips_pltgot;
+      addr_size = (is_32bit_elf ? 4 : 8);
+      end = mips_pltgot + (2 + count) * addr_size;
+
+      offset = offset_from_vma (file, mips_pltgot, end - mips_pltgot);
+      data = get_data (NULL, file, offset, end - mips_pltgot, 1, _("PLT GOT"));
+      printf (_("\nPLT GOT:\n\n"));
+      printf (_(" Reserved entries:\n"));
+      printf (_("  %*s %*s Purpose\n"),
+             addr_size * 2, "Address", addr_size * 2, "Initial");
+      entry = print_mips_pltgot_entry (data, mips_pltgot, entry);
+      printf (" PLT lazy resolver\n");
+      entry = print_mips_pltgot_entry (data, mips_pltgot, entry);
+      printf (" Module pointer\n");
+      printf ("\n");
+
+      printf (_(" Entries:\n"));
+      printf (_("  %*s %*s %*s %-7s %3s %s\n"),
+             addr_size * 2, "Address",
+             addr_size * 2, "Initial",
+             addr_size * 2, "Sym.Val.", "Type", "Ndx", "Name");
+      sym_width = (is_32bit_elf ? 80 : 160) - 17 - addr_size * 6 - 1;
+      for (i = 0; i < count; i++)
+       {
+         Elf_Internal_Sym *psym;
+
+         psym = dynamic_symbols + get_reloc_symindex (rels[i].r_info);
+         entry = print_mips_pltgot_entry (data, mips_pltgot, entry);
+         printf (" ");
+         print_vma (psym->st_value, LONG_HEX);
+         printf (" %-7s %3s ",
+                 get_symbol_type (ELF_ST_TYPE (psym->st_info)),
+                 get_symbol_index_type (psym->st_shndx));
+         if (VALID_DYNAMIC_NAME (psym->st_name))
+           print_symbol (sym_width, GET_DYNAMIC_NAME (psym->st_name));
+         else
+           printf ("<corrupt: %14ld>", psym->st_name);
+         printf ("\n");
+       }
+      printf ("\n");
+
+      if (data)
+       free (data);
+      free (rels);
+    }
+
   return 1;
 }
 
@@ -9685,7 +10069,7 @@ process_gnu_liblist (FILE *file)
 
          printf (_("\nLibrary list section '%s' contains %lu entries:\n"),
                  SECTION_NAME (section),
-                 (long) (section->sh_size / sizeof (Elf32_External_Lib)));
+                 (unsigned long) (section->sh_size / sizeof (Elf32_External_Lib)));
 
          puts ("     Library              Time Stamp          Checksum   Version Flags");
 
@@ -9749,6 +10133,8 @@ get_note_type (unsigned e_type)
        return _("NT_PRXFPREG (user_xfpregs structure)");
       case NT_PPC_VMX:
        return _("NT_PPC_VMX (ppc Altivec registers)");
+      case NT_PPC_VSX:
+       return _("NT_PPC_VSX (ppc VSX registers)");
       case NT_PSTATUS:
        return _("NT_PSTATUS (pstatus structure)");
       case NT_FPREGS:
@@ -9792,6 +10178,8 @@ get_gnu_elf_note_type (unsigned e_type)
       return _("NT_GNU_HWCAP (DSO-supplied software HWCAP info)");
     case NT_GNU_BUILD_ID:
       return _("NT_GNU_BUILD_ID (unique build ID bitstring)");
+    case NT_GNU_GOLD_VERSION:
+      return _("NT_GNU_GOLD_VERSION (gold version)");
     default:
       break;
     }
@@ -9941,7 +10329,7 @@ process_corefile_note_segment (FILE *file, bfd_vma offset, bfd_vma length)
       if (((char *) next) > (((char *) pnotes) + length))
        {
          warn (_("corrupt note found at offset %lx into core notes\n"),
-               (long)((char *)external - (char *)pnotes));
+               (unsigned long) ((char *) external - (char *) pnotes));
          warn (_(" type: %lx, namesize: %08lx, descsize: %08lx\n"),
                inote.type, inote.namesz, inote.descsz);
          break;
@@ -10398,7 +10786,7 @@ process_archive (char *file_name, FILE *file)
          size -= index_num * SIZEOF_AR_INDEX_NUMBERS;
 
          /* Convert the index numbers into the host's numeric format.  */
-         index_array = malloc (index_num * sizeof (* index_array));      
+         index_array = malloc (index_num * sizeof (* index_array));
          if (index_array == NULL)
            {
              free (index_buffer);
@@ -10432,7 +10820,7 @@ process_archive (char *file_name, FILE *file)
              error (_("%s: failed to read archive index symbol table\n"), file_name);
              ret = 1;
              goto out;
-           }     
+           }
        }
       else
        {
@@ -10554,7 +10942,7 @@ process_archive (char *file_name, FILE *file)
                {
                  error (_("%s: end of the symbol table reached before the end of the index\n"),
                         file_name);
-                 break;                         
+                 break;
                }
              printf ("\t%s\n", sym_table + l);
              l += strlen (sym_table + l) + 1;
This page took 0.047697 seconds and 4 git commands to generate.