PR binutils/12058
[deliverable/binutils-gdb.git] / binutils / readelf.c
index f56e6c2f26746f2725c2e5aa296e98746fa76ee5..f1ecd208be451d85f4f447326abcf0efc6082bd1 100644 (file)
@@ -1,6 +1,7 @@
 /* readelf.c -- display contents of an ELF format file
    Copyright 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007,
-   2008, 2009  Free Software Foundation, Inc.
+   2008, 2009, 2010
+   Free Software Foundation, Inc.
 
    Originally developed by Eric Youngdale <eric@andante.jic.com>
    Modifications by Nick Clifton <nickc@redhat.com>
 #include "elf/m68hc11.h"
 #include "elf/mcore.h"
 #include "elf/mep.h"
+#include "elf/microblaze.h"
 #include "elf/mips.h"
 #include "elf/mmix.h"
 #include "elf/mn10200.h"
 #include "elf/mn10300.h"
+#include "elf/moxie.h"
 #include "elf/mt.h"
 #include "elf/msp430.h"
 #include "elf/or32.h"
 #include "elf/pj.h"
 #include "elf/ppc.h"
 #include "elf/ppc64.h"
+#include "elf/rx.h"
 #include "elf/s390.h"
 #include "elf/score.h"
 #include "elf/sh.h"
 #include "elf/sparc.h"
 #include "elf/spu.h"
+#include "elf/tic6x.h"
 #include "elf/v850.h"
 #include "elf/vax.h"
 #include "elf/x86-64.h"
+#include "elf/xc16x.h"
 #include "elf/xstormy16.h"
 #include "elf/xtensa.h"
 
 #include "filenames.h"
 
 char * program_name = "readelf";
-int do_wide;
 static long archive_file_offset;
 static unsigned long archive_file_size;
 static unsigned long dynamic_addr;
@@ -164,7 +169,7 @@ static Elf_Internal_Syminfo * dynamic_syminfo;
 static unsigned long dynamic_syminfo_offset;
 static unsigned int dynamic_syminfo_nent;
 static char program_interpreter[PATH_MAX];
-static bfd_vma dynamic_info[DT_JMPREL + 1];
+static bfd_vma dynamic_info[DT_ENCODING];
 static bfd_vma dynamic_info_DT_GNU_HASH;
 static bfd_vma version_info[16];
 static Elf_Internal_Ehdr elf_header;
@@ -175,6 +180,7 @@ static Elf_Internal_Shdr * symtab_shndx_hdr;
 static int show_name;
 static int do_dynamic;
 static int do_syms;
+static int do_dyn_syms;
 static int do_reloc;
 static int do_sections;
 static int do_section_groups;
@@ -258,15 +264,16 @@ static void (* byte_put) (unsigned char *, bfd_vma, int);
 
 #define UNKNOWN -1
 
-#define SECTION_NAME(X)        \
-  ((X) == NULL ? "<none>" \
-  : string_table == NULL ? "<no-name>" \
-  : ((X)->sh_name >= string_table_length ? "<corrupt>" \
+#define SECTION_NAME(X)                                                \
+  ((X) == NULL ? _("<none>")                                   \
+   : string_table == NULL ? _("<no-name>")                     \
+   : ((X)->sh_name >= string_table_length ? _("<corrupt>")     \
   : string_table + (X)->sh_name))
 
 #define DT_VERSIONTAGIDX(tag)  (DT_VERNEEDNUM - (tag)) /* Reverse order!  */
 
-#define BYTE_GET(field)        byte_get (field, sizeof (field))
+#define BYTE_GET(field)                byte_get (field, sizeof (field))
+#define BYTE_GET_SIGNED(field) byte_get_signed (field, sizeof (field))
 
 #define GET_ELF_SYMBOLS(file, section)                 \
   (is_32bit_elf ? get_32bit_elf_symbols (file, section)        \
@@ -281,6 +288,11 @@ static void (* byte_put) (unsigned char *, bfd_vma, int);
 #define streq(a,b)       (strcmp ((a), (b)) == 0)
 #define strneq(a,b,n)    (strncmp ((a), (b), (n)) == 0)
 #define const_strneq(a,b) (strncmp ((a), (b), sizeof (b) - 1) == 0)
+
+#define REMOVE_ARCH_BITS(ADDR) do {            \
+    if (elf_header.e_machine == EM_ARM)                \
+      (ADDR) &= ~1;                            \
+  } while (0)
 \f
 static void *
 get_data (void * var, FILE * file, long offset, size_t size, size_t nmemb,
@@ -341,6 +353,8 @@ byte_put_little_endian (unsigned char * field, bfd_vma value, int size)
       /* Fall through.  */
     case 4:
       field[3] = (value >> 24) & 0xff;
+      /* Fall through.  */
+    case 3:
       field[2] = (value >> 16) & 0xff;
       /* Fall through.  */
     case 2:
@@ -504,8 +518,11 @@ byte_put_big_endian (unsigned char * field, bfd_vma value, int size)
       /* Fall through.  */
     case 4:
       field[3] = value & 0xff;
-      field[2] = (value >> 8) & 0xff;
-      value >>= 16;
+      value >>= 8;
+      /* Fall through.  */
+    case 3:
+      field[2] = value & 0xff;
+      value >>= 8;
       /* Fall through.  */
     case 2:
       field[1] = value & 0xff;
@@ -535,6 +552,44 @@ find_section (const char * name)
   return NULL;
 }
 
+/* Return a pointer to a section containing ADDR, or NULL if no such
+   section exists.  */
+
+static Elf_Internal_Shdr *
+find_section_by_address (bfd_vma addr)
+{
+  unsigned int i;
+
+  for (i = 0; i < elf_header.e_shnum; i++)
+    {
+      Elf_Internal_Shdr *sec = section_headers + i;
+      if (addr >= sec->sh_addr && addr < sec->sh_addr + sec->sh_size)
+       return sec;
+    }
+
+  return NULL;
+}
+
+/* Read an unsigned LEB128 encoded value from p.  Set *PLEN to the number of
+   bytes read.  */
+
+static unsigned long
+read_uleb128 (unsigned char *data, unsigned int *length_return)
+{
+  return read_leb128 (data, length_return, 0);
+}
+
+/* Return true if the current file is for IA-64 machine and OpenVMS ABI.
+   This OS has so many departures from the ELF standard that we test it at
+   many places.  */
+
+static inline int
+is_ia64_vms (void)
+{
+  return elf_header.e_machine == EM_IA_64
+    && elf_header.e_ident[EI_OSABI] == ELFOSABI_OPENVMS;
+}
+
 /* Guess the relocation size commonly used by the specific machines.  */
 
 static int
@@ -593,12 +648,14 @@ guess_is_rela (unsigned int e_machine)
     case EM_CYGNUS_MN10200:
     case EM_MN10300:
     case EM_CYGNUS_MN10300:
+    case EM_MOXIE:
     case EM_MSP430:
     case EM_MSP430_OLD:
     case EM_MT:
     case EM_NIOS32:
     case EM_PPC64:
     case EM_PPC:
+    case EM_RX:
     case EM_S390:
     case EM_S390_OLD:
     case EM_SH:
@@ -606,13 +663,17 @@ guess_is_rela (unsigned int e_machine)
     case EM_SPARC32PLUS:
     case EM_SPARCV9:
     case EM_SPU:
+    case EM_TI_C6000:
     case EM_V850:
     case EM_CYGNUS_V850:
     case EM_VAX:
     case EM_X86_64:
+    case EM_L1OM:
     case EM_XSTORMY16:
     case EM_XTENSA:
     case EM_XTENSA_OLD:
+    case EM_MICROBLAZE:
+    case EM_MICROBLAZE_OLD:
       return TRUE;
 
     case EM_68HC05:
@@ -653,13 +714,15 @@ slurp_rela_relocs (FILE * file,
     {
       Elf32_External_Rela * erelas;
 
-      erelas = get_data (NULL, file, rel_offset, 1, rel_size, _("relocs"));
+      erelas = (Elf32_External_Rela *) get_data (NULL, file, rel_offset, 1,
+                                                 rel_size, _("relocs"));
       if (!erelas)
        return 0;
 
       nrelas = rel_size / sizeof (Elf32_External_Rela);
 
-      relas = cmalloc (nrelas, sizeof (Elf_Internal_Rela));
+      relas = (Elf_Internal_Rela *) cmalloc (nrelas,
+                                             sizeof (Elf_Internal_Rela));
 
       if (relas == NULL)
        {
@@ -672,7 +735,7 @@ 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);
+         relas[i].r_addend = BYTE_GET_SIGNED (erelas[i].r_addend);
        }
 
       free (erelas);
@@ -681,13 +744,15 @@ slurp_rela_relocs (FILE * file,
     {
       Elf64_External_Rela * erelas;
 
-      erelas = get_data (NULL, file, rel_offset, 1, rel_size, _("relocs"));
+      erelas = (Elf64_External_Rela *) get_data (NULL, file, rel_offset, 1,
+                                                 rel_size, _("relocs"));
       if (!erelas)
        return 0;
 
       nrelas = rel_size / sizeof (Elf64_External_Rela);
 
-      relas = cmalloc (nrelas, sizeof (Elf_Internal_Rela));
+      relas = (Elf_Internal_Rela *) cmalloc (nrelas,
+                                             sizeof (Elf_Internal_Rela));
 
       if (relas == NULL)
        {
@@ -700,7 +765,7 @@ 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);
+         relas[i].r_addend = BYTE_GET_SIGNED (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
@@ -714,13 +779,13 @@ slurp_rela_relocs (FILE * file,
                 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;
+             bfd_vma inf = relas[i].r_info;
+             inf = (((inf & 0xffffffff) << 32)
+                     | ((inf >> 56) & 0xff)
+                     | ((inf >> 40) & 0xff00)
+                     | ((inf >> 24) & 0xff0000)
+                     | ((inf >> 8) & 0xff000000));
+             relas[i].r_info = inf;
            }
 #endif /* BFD64 */
        }
@@ -747,13 +812,14 @@ slurp_rel_relocs (FILE * file,
     {
       Elf32_External_Rel * erels;
 
-      erels = get_data (NULL, file, rel_offset, 1, rel_size, _("relocs"));
+      erels = (Elf32_External_Rel *) get_data (NULL, file, rel_offset, 1,
+                                               rel_size, _("relocs"));
       if (!erels)
        return 0;
 
       nrels = rel_size / sizeof (Elf32_External_Rel);
 
-      rels = cmalloc (nrels, sizeof (Elf_Internal_Rela));
+      rels = (Elf_Internal_Rela *) cmalloc (nrels, sizeof (Elf_Internal_Rela));
 
       if (rels == NULL)
        {
@@ -775,13 +841,14 @@ slurp_rel_relocs (FILE * file,
     {
       Elf64_External_Rel * erels;
 
-      erels = get_data (NULL, file, rel_offset, 1, rel_size, _("relocs"));
+      erels = (Elf64_External_Rel *) get_data (NULL, file, rel_offset, 1,
+                                               rel_size, _("relocs"));
       if (!erels)
        return 0;
 
       nrels = rel_size / sizeof (Elf64_External_Rel);
 
-      rels = cmalloc (nrels, sizeof (Elf_Internal_Rela));
+      rels = (Elf_Internal_Rela *) cmalloc (nrels, sizeof (Elf_Internal_Rela));
 
       if (rels == NULL)
        {
@@ -808,13 +875,13 @@ slurp_rel_relocs (FILE * file,
                 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;
+             bfd_vma inf = rels[i].r_info;
+             inf = (((inf & 0xffffffff) << 32)
+                    | ((inf >> 56) & 0xff)
+                    | ((inf >> 40) & 0xff00)
+                    | ((inf >> 24) & 0xff0000)
+                    | ((inf >> 8) & 0xff000000));
+             rels[i].r_info = inf;
            }
 #endif /* BFD64 */
        }
@@ -925,21 +992,21 @@ dump_relocations (FILE * file,
     {
       const char * rtype;
       bfd_vma offset;
-      bfd_vma info;
+      bfd_vma inf;
       bfd_vma symtab_index;
       bfd_vma type;
 
       offset = rels[i].r_offset;
-      info   = rels[i].r_info;
+      inf    = rels[i].r_info;
 
-      type = get_reloc_type (info);
-      symtab_index = get_reloc_symindex  (info);
+      type = get_reloc_type (inf);
+      symtab_index = get_reloc_symindex  (inf);
 
       if (is_32bit_elf)
        {
          printf ("%8.8lx  %8.8lx ",
                  (unsigned long) offset & 0xffffffff,
-                 (unsigned long) info & 0xffffffff);
+                 (unsigned long) inf & 0xffffffff);
        }
       else
        {
@@ -947,18 +1014,18 @@ dump_relocations (FILE * file,
          printf (do_wide
                  ? "%16.16lx  %16.16lx "
                  : "%12.12lx  %12.12lx ",
-                 offset, info);
+                 offset, inf);
 #elif BFD_HOST_64BIT_LONG_LONG
 #ifndef __MSVCRT__
          printf (do_wide
                  ? "%16.16llx  %16.16llx "
                  : "%12.12llx  %12.12llx ",
-                 offset, info);
+                 offset, inf);
 #else
          printf (do_wide
                  ? "%16.16I64x  %16.16I64x "
                  : "%12.12I64x  %12.12I64x ",
-                 offset, info);
+                 offset, inf);
 #endif
 #else
          printf (do_wide
@@ -966,8 +1033,8 @@ dump_relocations (FILE * file,
                  : "%4.4lx%8.8lx  %4.4lx%8.8lx ",
                  _bfd_int64_high (offset),
                  _bfd_int64_low (offset),
-                 _bfd_int64_high (info),
-                 _bfd_int64_low (info));
+                 _bfd_int64_high (inf),
+                 _bfd_int64_low (inf));
 #endif
        }
 
@@ -1066,6 +1133,10 @@ dump_relocations (FILE * file,
          rtype = elf_mmix_reloc_type (type);
          break;
 
+       case EM_MOXIE:
+         rtype = elf_moxie_reloc_type (type);
+         break;
+
        case EM_MSP430:
        case EM_MSP430_OLD:
          rtype = elf_msp430_reloc_type (type);
@@ -1128,6 +1199,7 @@ dump_relocations (FILE * file,
          break;
 
        case EM_X86_64:
+       case EM_L1OM:
          rtype = elf_x86_64_reloc_type (type);
          break;
 
@@ -1195,6 +1267,24 @@ dump_relocations (FILE * file,
        case EM_CR16_OLD:
          rtype = elf_cr16_reloc_type (type);
          break;
+
+       case EM_MICROBLAZE:
+       case EM_MICROBLAZE_OLD:
+         rtype = elf_microblaze_reloc_type (type);
+         break;
+
+       case EM_RX:
+         rtype = elf_rx_reloc_type (type);
+         break;
+
+       case EM_XC16X:
+       case EM_C166:
+         rtype = elf_xc16x_reloc_type (type);
+         break;
+
+       case EM_TI_C6000:
+         rtype = elf_tic6x_reloc_type (type);
+         break;
        }
 
       if (rtype == NULL)
@@ -1230,7 +1320,7 @@ dump_relocations (FILE * file,
       else if (symtab_index)
        {
          if (symtab == NULL || symtab_index >= nsyms)
-           printf (" bad symbol index: %08lx", (unsigned long) symtab_index);
+           printf (_(" bad symbol index: %08lx"), (unsigned long) symtab_index);
          else
            {
              Elf_Internal_Sym * psym;
@@ -1292,16 +1382,15 @@ dump_relocations (FILE * file,
                      else if (elf_header.e_machine == EM_MIPS
                               && psym->st_shndx == SHN_MIPS_SUNDEFINED)
                        sec_name = "SUNDEF";
-                     else if (elf_header.e_machine == EM_X86_64
+                     else if ((elf_header.e_machine == EM_X86_64
+                               || elf_header.e_machine == EM_L1OM)
                               && psym->st_shndx == SHN_X86_64_LCOMMON)
                        sec_name = "LARGE_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 if (elf_header.e_machine == EM_IA_64
-                              && (elf_header.e_ident[EI_OSABI]
-                                  == ELFOSABI_OPENVMS)
+                     else if (is_ia64_vms ()
                               && psym->st_shndx == SHN_IA_64_VMS_SYMVEC)
                        sec_name = "VMS_SYMVEC";
                      else
@@ -1322,12 +1411,12 @@ dump_relocations (FILE * file,
 
              if (is_rela)
                {
-                 long offset = (long) (bfd_signed_vma) rels[i].r_addend;
+                 bfd_signed_vma off = rels[i].r_addend;
 
-                 if (offset < 0)
-                   printf (" - %lx", - offset);
+                 if (off < 0)
+                   printf (" - %" BFD_VMA_FMT "x", - off);
                  else
-                   printf (" + %lx", offset);
+                   printf (" + %" BFD_VMA_FMT "x", off);
                }
            }
        }
@@ -1341,15 +1430,15 @@ dump_relocations (FILE * file,
       if (elf_header.e_machine == EM_SPARCV9
          && rtype != NULL
          && streq (rtype, "R_SPARC_OLO10"))
-       printf (" + %lx", (unsigned long) ELF64_R_TYPE_DATA (info));
+       printf (" + %lx", (unsigned long) ELF64_R_TYPE_DATA (inf));
 
       putchar ('\n');
 
 #ifdef BFD64
       if (! is_32bit_elf && elf_header.e_machine == EM_MIPS)
        {
-         bfd_vma type2 = ELF64_MIPS_R_TYPE2 (info);
-         bfd_vma type3 = ELF64_MIPS_R_TYPE3 (info);
+         bfd_vma type2 = ELF64_MIPS_R_TYPE2 (inf);
+         bfd_vma type3 = ELF64_MIPS_R_TYPE3 (inf);
          const char * rtype2 = elf_mips_reloc_type (type2);
          const char * rtype3 = elf_mips_reloc_type (type3);
 
@@ -1448,7 +1537,8 @@ get_ppc_dynamic_type (unsigned long type)
 {
   switch (type)
     {
-    case DT_PPC_GOT: return "PPC_GOT";
+    case DT_PPC_GOT:    return "PPC_GOT";
+    case DT_PPC_TLSOPT: return "PPC_TLSOPT";
     default:
       return NULL;
     }
@@ -1459,9 +1549,10 @@ get_ppc64_dynamic_type (unsigned long type)
 {
   switch (type)
     {
-    case DT_PPC64_GLINK: return "PPC64_GLINK";
-    case DT_PPC64_OPD:   return "PPC64_OPD";
-    case DT_PPC64_OPDSZ: return "PPC64_OPDSZ";
+    case DT_PPC64_GLINK:  return "PPC64_GLINK";
+    case DT_PPC64_OPD:    return "PPC64_OPD";
+    case DT_PPC64_OPDSZ:  return "PPC64_OPDSZ";
+    case DT_PPC64_TLSOPT: return "PPC64_TLSOPT";
     default:
       return NULL;
     }
@@ -1569,6 +1660,21 @@ get_score_dynamic_type (unsigned long type)
     }
 }
 
+static const char *
+get_tic6x_dynamic_type (unsigned long type)
+{
+  switch (type)
+    {
+    case DT_C6000_GSYM_OFFSET: return "C6000_GSYM_OFFSET";
+    case DT_C6000_GSTR_OFFSET: return "C6000_GSTR_OFFSET";
+    case DT_C6000_DSBT_BASE:   return "C6000_DSBT_BASE";
+    case DT_C6000_DSBT_SIZE:   return "C6000_DSBT_SIZE";
+    case DT_C6000_PREEMPTMAP:  return "C6000_PREEMPTMAP";
+    case DT_C6000_DSBT_INDEX:  return "C6000_DSBT_INDEX";
+    default:
+      return NULL;
+    }
+}
 
 static const char *
 get_dynamic_type (unsigned long type)
@@ -1681,6 +1787,9 @@ get_dynamic_type (unsigned long type)
            case EM_SCORE:
              result = get_score_dynamic_type (type);
              break;
+           case EM_TI_C6000:
+             result = get_tic6x_dynamic_type (type);
+             break;
            default:
              result = NULL;
              break;
@@ -1804,6 +1913,7 @@ get_machine_name (unsigned e_machine)
     case EM_MN10300:           return "mn10300";
     case EM_CYGNUS_MN10200:
     case EM_MN10200:           return "mn10200";
+    case EM_MOXIE:             return "Moxie";
     case EM_CYGNUS_FR30:
     case EM_FR30:              return "Fujitsu FR30";
     case EM_CYGNUS_FRV:                return "Fujitsu FR-V";
@@ -1817,6 +1927,9 @@ get_machine_name (unsigned e_machine)
     case EM_ME16:              return "Toyota ME16 processor";
     case EM_ST100:             return "STMicroelectronics ST100 processor";
     case EM_TINYJ:             return "Advanced Logic Corp. TinyJ embedded processor";
+    case EM_PDSP:              return "Sony DSP processor";
+    case EM_PDP10:             return "Digital Equipment Corp. PDP-10";
+    case EM_PDP11:             return "Digital Equipment Corp. PDP-11";
     case EM_FX66:              return "Siemens FX66 microcontroller";
     case EM_ST9PLUS:           return "STMicroelectronics ST9+ 8/16 bit microcontroller";
     case EM_ST7:               return "STMicroelectronics ST7 8-bit microcontroller";
@@ -1837,12 +1950,14 @@ get_machine_name (unsigned e_machine)
     case EM_HUANY:             return "Harvard Universitys's machine-independent object format";
     case EM_PRISM:             return "Vitesse Prism";
     case EM_X86_64:            return "Advanced Micro Devices X86-64";
+    case EM_L1OM:              return "Intel L1OM";
     case EM_S390_OLD:
     case EM_S390:              return "IBM S/390";
     case EM_SCORE:             return "SUNPLUS S+Core";
     case EM_XSTORMY16:         return "Sanyo Xstormy16 CPU core";
     case EM_OPENRISC:
     case EM_OR32:              return "OpenRISC";
+    case EM_ARC_A5:            return "ARC International ARCompact processor";
     case EM_CRX:               return "National Semiconductor CRX microprocessor";
     case EM_DLX:               return "OpenDLX";
     case EM_IP2K_OLD:
@@ -1850,17 +1965,71 @@ 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_VIDEOCORE:         return "Alphamosaic VideoCore processor";
+    case EM_TMM_GPP:           return "Thompson Multimedia General Purpose Processor";
+    case EM_NS32K:             return "National Semiconductor 32000 series";
+    case EM_TPC:               return "Tenor Network TPC processor";
+    case EM_ST200:             return "STMicroelectronics ST200 microcontroller";
+    case EM_MAX:               return "MAX Processor";
+    case EM_CR:                        return "National Semiconductor CompactRISC";
+    case EM_F2MC16:            return "Fujitsu F2MC16";
+    case EM_MSP430:            return "Texas Instruments msp430 microcontroller";
     case EM_LATTICEMICO32:     return "Lattice Mico32";
     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";
+    case EM_SE_C33:            return "S1C33 Family of Seiko Epson processors";
+    case EM_SEP:               return "Sharp embedded microprocessor";
+    case EM_ARCA:              return "Arca RISC microprocessor";
+    case EM_UNICORE:           return "Unicore";
+    case EM_EXCESS:            return "eXcess 16/32/64-bit configurable embedded CPU";
+    case EM_DXP:               return "Icera Semiconductor Inc. Deep Execution Processor";
     case EM_NIOS32:            return "Altera Nios";
     case EM_ALTERA_NIOS2:      return "Altera Nios II";
+    case EM_C166:
     case EM_XC16X:             return "Infineon Technologies xc16x";
+    case EM_M16C:              return "Renesas M16C series microprocessors";
+    case EM_DSPIC30F:          return "Microchip Technology dsPIC30F Digital Signal Controller";
+    case EM_CE:                        return "Freescale Communication Engine RISC core";
+    case EM_TSK3000:           return "Altium TSK3000 core";
+    case EM_RS08:              return "Freescale RS08 embedded processor";
+    case EM_ECOG2:             return "Cyan Technology eCOG2 microprocessor";
+    case EM_DSP24:             return "New Japan Radio (NJR) 24-bit DSP Processor";
+    case EM_VIDEOCORE3:                return "Broadcom VideoCore III processor";
+    case EM_SE_C17:            return "Seiko Epson C17 family";
+    case EM_TI_C6000:          return "Texas Instruments TMS320C6000 DSP family";
+    case EM_TI_C2000:          return "Texas Instruments TMS320C2000 DSP family";
+    case EM_TI_C5500:          return "Texas Instruments TMS320C55x DSP family";
+    case EM_MMDSP_PLUS:                return "STMicroelectronics 64bit VLIW Data Signal Processor";
+    case EM_CYPRESS_M8C:       return "Cypress M8C microprocessor";
+    case EM_R32C:              return "Renesas R32C series microprocessors";
+    case EM_TRIMEDIA:          return "NXP Semiconductors TriMedia architecture family";
+    case EM_QDSP6:             return "QUALCOMM DSP6 Processor";
+    case EM_8051:              return "Intel 8051 and variants";
+    case EM_STXP7X:            return "STMicroelectronics STxP7x family";
+    case EM_NDS32:             return "Andes Technology compact code size embedded RISC processor family";
+    case EM_ECOG1X:            return "Cyan Technology eCOG1X family";
+    case EM_MAXQ30:            return "Dallas Semiconductor MAXQ30 Core microcontrollers";
+    case EM_XIMO16:            return "New Japan Radio (NJR) 16-bit DSP Processor";
+    case EM_MANIK:             return "M2000 Reconfigurable RISC Microprocessor";
+    case EM_CRAYNV2:           return "Cray Inc. NV2 vector architecture";
     case EM_CYGNUS_MEP:         return "Toshiba MeP Media Engine";
     case EM_CR16:
     case EM_CR16_OLD:          return "National Semiconductor's CR16";
+    case EM_MICROBLAZE:                return "Xilinx MicroBlaze";
+    case EM_MICROBLAZE_OLD:    return "Xilinx MicroBlaze";
+    case EM_RX:                        return "Renesas RX";
+    case EM_METAG:             return "Imagination Technologies META processor architecture";
+    case EM_MCST_ELBRUS:       return "MCST Elbrus general purpose hardware architecture";
+    case EM_ECOG16:            return "Cyan Technology eCOG16 family";
+    case EM_ETPU:              return "Freescale Extended Time Processing Unit";
+    case EM_SLE9X:             return "Infineon Technologies SLE9X core";
+    case EM_AVR32:             return "Atmel Corporation 32-bit microprocessor family";
+    case EM_STM8:              return "STMicroeletronics STM8 8-bit microcontroller";
+    case EM_TILE64:            return "Tilera TILE64 multicore architecture family";
+    case EM_TILEPRO:           return "Tilera TILEPro multicore architecture family";
+    case EM_CUDA:              return "NVIDIA CUDA architecture";
     default:
       snprintf (buff, sizeof (buff), _("<unknown>: 0x%x"), e_machine);
       return buff;
@@ -2048,7 +2217,7 @@ decode_ARM_machine_flags (unsigned e_flags, char buf[])
     }
 
   if (unknown)
-    strcat (buf,", <unknown>");
+    strcat (buf,_(", <unknown>"));
 }
 
 static char *
@@ -2142,6 +2311,13 @@ get_machine_flags (unsigned e_flags, unsigned e_machine)
                case EF_M68K_CF_ISA_B:
                  isa = "B";
                  break;
+               case EF_M68K_CF_ISA_C:
+                 isa = "C";
+                 break;
+               case EF_M68K_CF_ISA_C_NODIV:
+                 isa = "C";
+                 additional = ", nodiv";
+                 break;
                }
              strcat (buf, ", cf, isa ");
              strcat (buf, isa);
@@ -2160,6 +2336,9 @@ get_machine_flags (unsigned e_flags, unsigned e_machine)
                case EF_M68K_CF_EMAC:
                  mac = "emac";
                  break;
+               case EF_M68K_CF_EMAC_B:
+                 mac = "emac_b";
+                 break;
                }
              if (mac)
                {
@@ -2174,18 +2353,24 @@ get_machine_flags (unsigned e_flags, unsigned e_machine)
            strcat (buf, ", emb");
 
          if (e_flags & EF_PPC_RELOCATABLE)
-           strcat (buf, ", relocatable");
+           strcat (buf, _(", relocatable"));
 
          if (e_flags & EF_PPC_RELOCATABLE_LIB)
-           strcat (buf, ", relocatable-lib");
+           strcat (buf, _(", relocatable-lib"));
          break;
 
        case EM_V850:
        case EM_CYGNUS_V850:
          switch (e_flags & EF_V850_ARCH)
            {
-           case E_V850E1_ARCH:
-             strcat (buf, ", v850e1");
+           case E_V850E2V3_ARCH:
+             strcat (buf, ", v850e2v3");
+             break;
+           case E_V850E2_ARCH:
+             strcat (buf, ", v850e2");
+             break;
+            case E_V850E1_ARCH:
+              strcat (buf, ", v850e1");
              break;
            case E_V850E_ARCH:
              strcat (buf, ", v850e");
@@ -2194,7 +2379,7 @@ get_machine_flags (unsigned e_flags, unsigned e_machine)
              strcat (buf, ", v850");
              break;
            default:
-             strcat (buf, ", unknown v850 architecture variant");
+             strcat (buf, _(", unknown v850 architecture variant"));
              break;
            }
          break;
@@ -2243,13 +2428,14 @@ get_machine_flags (unsigned e_flags, unsigned e_machine)
            case E_MIPS_MACH_LS2E: strcat (buf, ", loongson-2e"); break;
            case E_MIPS_MACH_LS2F: strcat (buf, ", loongson-2f"); break;
            case E_MIPS_MACH_OCTEON: strcat (buf, ", octeon"); break;
+           case E_MIPS_MACH_OCTEON2: strcat (buf, ", octeon2"); break;
            case E_MIPS_MACH_XLR:  strcat (buf, ", xlr"); break;
            case 0:
            /* We simply ignore the field in this case to avoid confusion:
               MIPS ELF does not specify EF_MIPS_MACH, it is a GNU
               extension.  */
              break;
-           default: strcat (buf, ", unknown CPU"); break;
+           default: strcat (buf, _(", unknown CPU")); break;
            }
 
          switch ((e_flags & EF_MIPS_ABI))
@@ -2264,7 +2450,7 @@ get_machine_flags (unsigned e_flags, unsigned e_machine)
               This means it is likely to be an o32 file, but not for
               sure.  */
              break;
-           default: strcat (buf, ", unknown ABI"); break;
+           default: strcat (buf, _(", unknown ABI")); break;
            }
 
          if (e_flags & EF_MIPS_ARCH_ASE_MDMX)
@@ -2284,9 +2470,14 @@ get_machine_flags (unsigned e_flags, unsigned e_machine)
            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;
+           default: strcat (buf, _(", unknown ISA")); break;
            }
 
+         if (e_flags & EF_SH_PIC)
+           strcat (buf, ", pic");
+
+         if (e_flags & EF_SH_FDPIC)
+           strcat (buf, ", fdpic");
          break;
 
        case EM_SH:
@@ -2313,7 +2504,7 @@ get_machine_flags (unsigned e_flags, unsigned e_machine)
            case EF_SH2A_SH3_NOFPU: strcat (buf, ", sh2a-nofpu-or-sh3-nommu"); break;
            case EF_SH2A_SH4: strcat (buf, ", sh2a-or-sh4"); break;
            case EF_SH2A_SH3E: strcat (buf, ", sh2a-or-sh3e"); break;
-           default: strcat (buf, ", unknown ISA"); break;
+           default: strcat (buf, _(", unknown ISA")); break;
            }
 
          break;
@@ -2395,6 +2586,27 @@ get_machine_flags (unsigned e_flags, unsigned e_machine)
            strcat (buf, ", constant gp");
          if ((e_flags & EF_IA_64_ABSOLUTE))
            strcat (buf, ", absolute");
+          if (elf_header.e_ident[EI_OSABI] == ELFOSABI_OPENVMS)
+            {
+              if ((e_flags & EF_IA_64_VMS_LINKAGES))
+                strcat (buf, ", vms_linkages");
+              switch ((e_flags & EF_IA_64_VMS_COMCOD))
+                {
+                case EF_IA_64_VMS_COMCOD_SUCCESS:
+                  break;
+                case EF_IA_64_VMS_COMCOD_WARNING:
+                  strcat (buf, ", warning");
+                  break;
+                case EF_IA_64_VMS_COMCOD_ERROR:
+                  strcat (buf, ", error");
+                  break;
+                case EF_IA_64_VMS_COMCOD_ABORT:
+                  strcat (buf, ", abort");
+                  break;
+                default:
+                  abort ();
+                }
+            }
          break;
 
        case EM_VAX:
@@ -2405,6 +2617,20 @@ get_machine_flags (unsigned e_flags, unsigned e_machine)
          if ((e_flags & EF_VAX_GFLOAT))
            strcat (buf, ", G-Float");
          break;
+
+       case EM_RX:
+         if (e_flags & E_FLAG_RX_64BIT_DOUBLES)
+           strcat (buf, ", 64-bit doubles");
+         if (e_flags & E_FLAG_RX_DSP)
+           strcat (buf, ", dsp");
+
+       case EM_S390:
+         if (e_flags & EF_S390_HIGH_GPRS)
+           strcat (buf, ", highgprs");
+
+       case EM_TI_C6000:
+         if ((e_flags & EF_C6000_REL))
+           strcat (buf, ", relocatable module");
        }
     }
 
@@ -2433,9 +2659,43 @@ get_osabi_name (unsigned int osabi)
     case ELFOSABI_OPENVMS:     return "VMS - OpenVMS";
     case ELFOSABI_NSK:         return "HP - Non-Stop Kernel";
     case ELFOSABI_AROS:                return "AROS";
-    case ELFOSABI_STANDALONE:  return _("Standalone App");
-    case ELFOSABI_ARM:         return "ARM";
+    case ELFOSABI_FENIXOS:     return "FenixOS";
     default:
+      if (osabi >= 64)
+       switch (elf_header.e_machine)
+         {
+         case EM_ARM:
+           switch (osabi)
+             {
+             case ELFOSABI_ARM:        return "ARM";
+             default:
+               break;
+             }
+           break;
+
+         case EM_MSP430:
+         case EM_MSP430_OLD:
+           switch (osabi)
+             {
+             case ELFOSABI_STANDALONE: return _("Standalone App");
+             default:
+               break;
+             }
+           break;
+
+         case EM_TI_C6000:
+           switch (osabi)
+             {
+             case ELFOSABI_C6000_ELFABI:       return _("Bare-metal C6000");
+             case ELFOSABI_C6000_LINUX:        return "Linux C6000";
+             default:
+               break;
+             }
+           break;
+
+         default:
+           break;
+         }
       snprintf (buff, sizeof (buff), _("<unknown: %x>"), osabi);
       return buff;
     }
@@ -2522,6 +2782,19 @@ get_ia64_segment_type (unsigned long type)
   return NULL;
 }
 
+static const char *
+get_tic6x_segment_type (unsigned long type)
+{
+  switch (type)
+    {
+    case PT_C6000_PHATTR:      return "C6000_PHATTR";
+    default:
+      break;
+    }
+
+  return NULL;
+}
+
 static const char *
 get_segment_type (unsigned long p_type)
 {
@@ -2563,6 +2836,9 @@ get_segment_type (unsigned long p_type)
            case EM_IA_64:
              result = get_ia64_segment_type (p_type);
              break;
+           case EM_TI_C6000:
+             result = get_tic6x_segment_type (p_type);
+             break;
            default:
              result = NULL;
              break;
@@ -2712,12 +2988,38 @@ get_arm_section_type_name (unsigned int sh_type)
 {
   switch (sh_type)
     {
-    case SHT_ARM_EXIDX:
-      return "ARM_EXIDX";
-    case SHT_ARM_PREEMPTMAP:
-      return "ARM_PREEMPTMAP";
-    case SHT_ARM_ATTRIBUTES:
-      return "ARM_ATTRIBUTES";
+    case SHT_ARM_EXIDX:           return "ARM_EXIDX";
+    case SHT_ARM_PREEMPTMAP:      return "ARM_PREEMPTMAP";
+    case SHT_ARM_ATTRIBUTES:      return "ARM_ATTRIBUTES";
+    case SHT_ARM_DEBUGOVERLAY:    return "ARM_DEBUGOVERLAY";
+    case SHT_ARM_OVERLAYSECTION:  return "ARM_OVERLAYSECTION";
+    default:
+      break;
+    }
+  return NULL;
+}
+
+static const char *
+get_tic6x_section_type_name (unsigned int sh_type)
+{
+  switch (sh_type)
+    {
+    case SHT_C6000_UNWIND:
+      return "C6000_UNWIND";
+    case SHT_C6000_PREEMPTMAP:
+      return "C6000_PREEMPTMAP";
+    case SHT_C6000_ATTRIBUTES:
+      return "C6000_ATTRIBUTES";
+    case SHT_TI_ICODE:
+      return "TI_ICODE";
+    case SHT_TI_XREF:
+      return "TI_XREF";
+    case SHT_TI_HANDLER:
+      return "TI_HANDLER";
+    case SHT_TI_INITINFO:
+      return "TI_INITINFO";
+    case SHT_TI_PHATTRS:
+      return "TI_PHATTRS";
     default:
       break;
     }
@@ -2776,11 +3078,15 @@ get_section_type_name (unsigned int sh_type)
              result = get_ia64_section_type_name (sh_type);
              break;
            case EM_X86_64:
+           case EM_L1OM:
              result = get_x86_64_section_type_name (sh_type);
              break;
            case EM_ARM:
              result = get_arm_section_type_name (sh_type);
              break;
+           case EM_TI_C6000:
+             result = get_tic6x_section_type_name (sh_type);
+             break;
            default:
              result = NULL;
              break;
@@ -2820,6 +3126,7 @@ get_section_type_name (unsigned int sh_type)
 }
 
 #define OPTION_DEBUG_DUMP      512
+#define OPTION_DYN_SYMS                513
 
 static struct option options[] =
 {
@@ -2836,6 +3143,7 @@ static struct option options[] =
   {"full-section-name",no_argument, 0, 'N'},
   {"symbols",         no_argument, 0, 's'},
   {"syms",            no_argument, 0, 's'},
+  {"dyn-syms",        no_argument, 0, OPTION_DYN_SYMS},
   {"relocs",          no_argument, 0, 'r'},
   {"notes",           no_argument, 0, 'n'},
   {"dynamic",         no_argument, 0, 'd'},
@@ -2874,7 +3182,8 @@ usage (FILE * stream)
   -t --section-details   Display the section details\n\
   -e --headers           Equivalent to: -h -l -S\n\
   -s --syms              Display the symbol table\n\
-      --symbols          An alias for --syms\n\
+     --symbols           An alias for --syms\n\
+  --dyn-syms             Display the dynamic symbol table\n\
   -n --notes             Display the core notes (if present)\n\
   -r --relocs            Display the relocations (if present)\n\
   -u --unwind            Display the unwind info (if present)\n\
@@ -2889,8 +3198,10 @@ usage (FILE * stream)
                          Dump the contents of section <number|name> as strings\n\
   -R --relocated-dump=<number|name>\n\
                          Dump the contents of section <number|name> as relocated bytes\n\
-  -w[lLiaprmfFsoR] or\n\
-  --debug-dump[=rawline,=decodedline,=info,=abbrev,=pubnames,=aranges,=macro,=frames,=str,=loc,=Ranges]\n\
+  -w[lLiaprmfFsoRt] or\n\
+  --debug-dump[=rawline,=decodedline,=info,=abbrev,=pubnames,=aranges,=macro,=frames,\n\
+               =frames-interp,=str,=loc,=Ranges,=pubtypes,\n\
+               =trace_info,=trace_abbrev,=trace_aranges]\n\
                          Display the contents of DWARF2 debug sections\n"));
 #ifdef SUPPORT_DISASSEMBLY
   fprintf (stream, _("\
@@ -2922,7 +3233,8 @@ request_dump_bynumber (unsigned int section, dump_type type)
     {
       dump_type * new_dump_sects;
 
-      new_dump_sects = calloc (section + 1, sizeof (* dump_sects));
+      new_dump_sects = (dump_type *) calloc (section + 1,
+                                             sizeof (* dump_sects));
 
       if (new_dump_sects == NULL)
        error (_("Out of memory allocating dump request table.\n"));
@@ -2951,7 +3263,8 @@ request_dump_byname (const char * section, dump_type type)
 {
   struct dump_list_entry * new_request;
 
-  new_request = malloc (sizeof (struct dump_list_entry));
+  new_request = (struct dump_list_entry *)
+      malloc (sizeof (struct dump_list_entry));
   if (!new_request)
     error (_("Out of memory allocating dump request table.\n"));
 
@@ -3096,6 +3409,9 @@ parse_args (int argc, char ** argv)
              dwarf_select_sections_by_names (optarg);
            }
          break;
+       case OPTION_DYN_SYMS:
+         do_dyn_syms++;
+         break;
 #ifdef SUPPORT_DISASSEMBLY
        case 'i':
          request_dump (DISASS_DUMP);
@@ -3122,7 +3438,8 @@ parse_args (int argc, char ** argv)
   if (!do_dynamic && !do_syms && !do_reloc && !do_unwind && !do_sections
       && !do_segments && !do_header && !do_dump && !do_version
       && !do_histogram && !do_debugging && !do_arch && !do_notes
-      && !do_section_groups && !do_archive_index)
+      && !do_section_groups && !do_archive_index
+      && !do_dyn_syms)
     usage (stderr);
   else if (argc < 3)
     {
@@ -3198,7 +3515,7 @@ process_file_header (void)
              (elf_header.e_ident[EI_VERSION] == EV_CURRENT
               ? "(current)"
               : (elf_header.e_ident[EI_VERSION] != EV_NONE
-                 ? "<unknown: %lx>"
+                 ? _("<unknown: %lx>")
                  : "")));
       printf (_("  OS/ABI:                            %s\n"),
              get_osabi_name (elf_header.e_ident[EI_OSABI]));
@@ -3226,8 +3543,13 @@ process_file_header (void)
              (long) elf_header.e_ehsize);
       printf (_("  Size of program headers:           %ld (bytes)\n"),
              (long) elf_header.e_phentsize);
-      printf (_("  Number of program headers:         %ld\n"),
+      printf (_("  Number of program headers:         %ld"),
              (long) elf_header.e_phnum);
+      if (section_headers != NULL
+         && elf_header.e_phnum == PN_XNUM
+         && section_headers[0].sh_info != 0)
+       printf (_(" (%ld)"), (long) section_headers[0].sh_info);
+      putc ('\n', stdout);
       printf (_("  Size of section headers:           %ld (bytes)\n"),
              (long) elf_header.e_shentsize);
       printf (_("  Number of section headers:         %ld"),
@@ -3242,12 +3564,15 @@ process_file_header (void)
        printf (" (%u)", section_headers[0].sh_link);
       else if (elf_header.e_shstrndx != SHN_UNDEF
               && elf_header.e_shstrndx >= elf_header.e_shnum)
-       printf (" <corrupt: out of range>");
+       printf (_(" <corrupt: out of range>"));
       putc ('\n', stdout);
     }
 
   if (section_headers != NULL)
     {
+      if (elf_header.e_phnum == PN_XNUM
+         && section_headers[0].sh_info != 0)
+       elf_header.e_phnum = section_headers[0].sh_info;
       if (elf_header.e_shnum == SHN_UNDEF)
        elf_header.e_shnum = section_headers[0].sh_size;
       if (elf_header.e_shstrndx == (SHN_XINDEX & 0xffff))
@@ -3263,20 +3588,21 @@ process_file_header (void)
 
 
 static int
-get_32bit_program_headers (FILE * file, Elf_Internal_Phdr * program_headers)
+get_32bit_program_headers (FILE * file, Elf_Internal_Phdr * pheaders)
 {
   Elf32_External_Phdr * phdrs;
   Elf32_External_Phdr * external;
   Elf_Internal_Phdr *   internal;
   unsigned int i;
 
-  phdrs = get_data (NULL, file, elf_header.e_phoff,
-                   elf_header.e_phentsize, elf_header.e_phnum,
-                   _("program headers"));
+  phdrs = (Elf32_External_Phdr *) get_data (NULL, file, elf_header.e_phoff,
+                                            elf_header.e_phentsize,
+                                            elf_header.e_phnum,
+                                            _("program headers"));
   if (!phdrs)
     return 0;
 
-  for (i = 0, internal = program_headers, external = phdrs;
+  for (i = 0, internal = pheaders, external = phdrs;
        i < elf_header.e_phnum;
        i++, internal++, external++)
     {
@@ -3296,20 +3622,21 @@ get_32bit_program_headers (FILE * file, Elf_Internal_Phdr * program_headers)
 }
 
 static int
-get_64bit_program_headers (FILE * file, Elf_Internal_Phdr * program_headers)
+get_64bit_program_headers (FILE * file, Elf_Internal_Phdr * pheaders)
 {
   Elf64_External_Phdr * phdrs;
   Elf64_External_Phdr * external;
   Elf_Internal_Phdr *   internal;
   unsigned int i;
 
-  phdrs = get_data (NULL, file, elf_header.e_phoff,
-                   elf_header.e_phentsize, elf_header.e_phnum,
-                   _("program headers"));
+  phdrs = (Elf64_External_Phdr *) get_data (NULL, file, elf_header.e_phoff,
+                                            elf_header.e_phentsize,
+                                            elf_header.e_phnum,
+                                            _("program headers"));
   if (!phdrs)
     return 0;
 
-  for (i = 0, internal = program_headers, external = phdrs;
+  for (i = 0, internal = pheaders, external = phdrs;
        i < elf_header.e_phnum;
        i++, internal++, external++)
     {
@@ -3339,7 +3666,8 @@ get_program_headers (FILE * file)
   if (program_headers != NULL)
     return 1;
 
-  phdrs = cmalloc (elf_header.e_phnum, sizeof (Elf_Internal_Phdr));
+  phdrs = (Elf_Internal_Phdr *) cmalloc (elf_header.e_phnum,
+                                         sizeof (Elf_Internal_Phdr));
 
   if (phdrs == NULL)
     {
@@ -3515,7 +3843,10 @@ process_program_headers (FILE * file)
              sec = find_section (".dynamic");
              if (sec == NULL || sec->sh_size == 0)
                {
-                 error (_("no .dynamic section in the dynamic segment\n"));
+                  /* A corresponding .dynamic section is expected, but on
+                     IA-64/OpenVMS it is OK for it to be missing.  */
+                  if (!is_ia64_vms ())
+                    error (_("no .dynamic section in the dynamic segment\n"));
                  break;
                }
 
@@ -3582,7 +3913,8 @@ process_program_headers (FILE * file)
 
          for (j = 1; j < elf_header.e_shnum; j++, section++)
            {
-             if (ELF_IS_SECTION_IN_SEGMENT_MEMORY (section, segment))
+             if (!ELF_TBSS_SPECIAL (section, segment)
+                 && ELF_SECTION_IN_SEGMENT_STRICT (section, segment))
                printf ("%s ", SECTION_NAME (section));
            }
 
@@ -3632,12 +3964,14 @@ get_32bit_section_headers (FILE * file, unsigned int num)
   Elf_Internal_Shdr *   internal;
   unsigned int i;
 
-  shdrs = get_data (NULL, file, elf_header.e_shoff,
-                   elf_header.e_shentsize, num, _("section headers"));
+  shdrs = (Elf32_External_Shdr *) get_data (NULL, file, elf_header.e_shoff,
+                                            elf_header.e_shentsize, num,
+                                            _("section headers"));
   if (!shdrs)
     return 0;
 
-  section_headers = cmalloc (num, sizeof (Elf_Internal_Shdr));
+  section_headers = (Elf_Internal_Shdr *) cmalloc (num,
+                                                   sizeof (Elf_Internal_Shdr));
 
   if (section_headers == NULL)
     {
@@ -3673,12 +4007,14 @@ get_64bit_section_headers (FILE * file, unsigned int num)
   Elf_Internal_Shdr *   internal;
   unsigned int i;
 
-  shdrs = get_data (NULL, file, elf_header.e_shoff,
-                   elf_header.e_shentsize, num, _("section headers"));
+  shdrs = (Elf64_External_Shdr *) get_data (NULL, file, elf_header.e_shoff,
+                                            elf_header.e_shentsize, num,
+                                            _("section headers"));
   if (!shdrs)
     return 0;
 
-  section_headers = cmalloc (num, sizeof (Elf_Internal_Shdr));
+  section_headers = (Elf_Internal_Shdr *) cmalloc (num,
+                                                   sizeof (Elf_Internal_Shdr));
 
   if (section_headers == NULL)
     {
@@ -3711,15 +4047,30 @@ static Elf_Internal_Sym *
 get_32bit_elf_symbols (FILE * file, Elf_Internal_Shdr * section)
 {
   unsigned long number;
-  Elf32_External_Sym * esyms;
+  Elf32_External_Sym * esyms = NULL;
   Elf_External_Sym_Shndx * shndx;
-  Elf_Internal_Sym * isyms;
+  Elf_Internal_Sym * isyms = NULL;
   Elf_Internal_Sym * psym;
   unsigned int j;
 
-  esyms = get_data (NULL, file, section->sh_offset, 1, section->sh_size,
-                   _("symbols"));
-  if (!esyms)
+  /* Run some sanity checks first.  */
+  if (section->sh_entsize == 0)
+    {
+      error (_("sh_entsize is zero\n"));
+      return NULL;
+    }
+
+  number = section->sh_size / section->sh_entsize;
+
+  if (number * sizeof (Elf32_External_Sym) > section->sh_size + 1)
+    {
+      error (_("Invalid sh_entsize\n"));
+      return NULL;
+    }
+
+  esyms = (Elf32_External_Sym *) get_data (NULL, file, section->sh_offset, 1,
+                                           section->sh_size, _("symbols"));
+  if (esyms == NULL)
     return NULL;
 
   shndx = NULL;
@@ -3727,30 +4078,23 @@ get_32bit_elf_symbols (FILE * file, Elf_Internal_Shdr * section)
       && (symtab_shndx_hdr->sh_link
          == (unsigned long) (section - section_headers)))
     {
-      shndx = get_data (NULL, file, symtab_shndx_hdr->sh_offset,
-                       1, symtab_shndx_hdr->sh_size, _("symtab shndx"));
-      if (!shndx)
-       {
-         free (esyms);
-         return NULL;
-       }
+      shndx = (Elf_External_Sym_Shndx *) get_data (NULL, file,
+                                                   symtab_shndx_hdr->sh_offset,
+                                                   1, symtab_shndx_hdr->sh_size,
+                                                   _("symtab shndx"));
+      if (shndx == NULL)
+       goto exit_point;
     }
 
-  number = section->sh_size / section->sh_entsize;
-  isyms = cmalloc (number, sizeof (Elf_Internal_Sym));
+  isyms = (Elf_Internal_Sym *) cmalloc (number, sizeof (Elf_Internal_Sym));
 
   if (isyms == NULL)
     {
       error (_("Out of memory\n"));
-      if (shndx)
-       free (shndx);
-      free (esyms);
-      return NULL;
+      goto exit_point;
     }
 
-  for (j = 0, psym = isyms;
-       j < number;
-       j++, psym++)
+  for (j = 0, psym = isyms; j < number; j++, psym++)
     {
       psym->st_name  = BYTE_GET (esyms[j].st_name);
       psym->st_value = BYTE_GET (esyms[j].st_value);
@@ -3765,9 +4109,11 @@ get_32bit_elf_symbols (FILE * file, Elf_Internal_Shdr * section)
       psym->st_other = BYTE_GET (esyms[j].st_other);
     }
 
+ exit_point:
   if (shndx)
     free (shndx);
-  free (esyms);
+  if (esyms)
+    free (esyms);
 
   return isyms;
 }
@@ -3782,8 +4128,23 @@ get_64bit_elf_symbols (FILE * file, Elf_Internal_Shdr * section)
   Elf_Internal_Sym * psym;
   unsigned int j;
 
-  esyms = get_data (NULL, file, section->sh_offset, 1, section->sh_size,
-                   _("symbols"));
+  /* Run some sanity checks first.  */
+  if (section->sh_entsize == 0)
+    {
+      error (_("sh_entsize is zero\n"));
+      return NULL;
+    }
+
+  number = section->sh_size / section->sh_entsize;
+
+  if (number * sizeof (Elf64_External_Sym) > section->sh_size + 1)
+    {
+      error (_("Invalid sh_entsize\n"));
+      return NULL;
+    }
+
+  esyms = (Elf64_External_Sym *) get_data (NULL, file, section->sh_offset, 1,
+                                           section->sh_size, _("symbols"));
   if (!esyms)
     return NULL;
 
@@ -3792,8 +4153,10 @@ get_64bit_elf_symbols (FILE * file, Elf_Internal_Shdr * section)
       && (symtab_shndx_hdr->sh_link
          == (unsigned long) (section - section_headers)))
     {
-      shndx = get_data (NULL, file, symtab_shndx_hdr->sh_offset,
-                       1, symtab_shndx_hdr->sh_size, _("symtab shndx"));
+      shndx = (Elf_External_Sym_Shndx *) get_data (NULL, file,
+                                                   symtab_shndx_hdr->sh_offset,
+                                                   1, symtab_shndx_hdr->sh_size,
+                                                   _("symtab shndx"));
       if (!shndx)
        {
          free (esyms);
@@ -3801,8 +4164,7 @@ get_64bit_elf_symbols (FILE * file, Elf_Internal_Shdr * section)
        }
     }
 
-  number = section->sh_size / section->sh_entsize;
-  isyms = cmalloc (number, sizeof (Elf_Internal_Sym));
+  isyms = (Elf_Internal_Sym *) cmalloc (number, sizeof (Elf_Internal_Sym));
 
   if (isyms == NULL)
     {
@@ -3843,7 +4205,8 @@ get_elf_section_flags (bfd_vma sh_flags)
   static char buff[1024];
   char * p = buff;
   int field_size = is_32bit_elf ? 8 : 16;
-  int index, size = sizeof (buff) - (field_size + 4 + 1);
+  int sindex;
+  int size = sizeof (buff) - (field_size + 4 + 1);
   bfd_vma os_flags = 0;
   bfd_vma proc_flags = 0;
   bfd_vma unknown_flags = 0;
@@ -3854,26 +4217,30 @@ get_elf_section_flags (bfd_vma sh_flags)
     }
   flags [] =
     {
-       { "WRITE", 5 },
-       { "ALLOC", 5 },
-       { "EXEC", 4 },
-       { "MERGE", 5 },
-       { "STRINGS", 7 },
-       { "INFO LINK", 9 },
-       { "LINK ORDER", 10 },
-       { "OS NONCONF", 10 },
-       { "GROUP", 5 },
-       { "TLS", 3 },
-       /* IA-64 specific.  */
-       { "SHORT", 5 },
-       { "NORECOV", 7 },
-       /* IA-64 OpenVMS specific.  */
-       { "VMS_GLOBAL", 10 },
-       { "VMS_OVERLAID", 12 },
-       { "VMS_SHARED", 10 },
-       { "VMS_VECTOR", 10 },
-       { "VMS_ALLOC_64BIT", 15 },
-       { "VMS_PROTECTED", 13}
+      /*  0 */ { STRING_COMMA_LEN ("WRITE") },
+      /*  1 */ { STRING_COMMA_LEN ("ALLOC") },
+      /*  2 */ { STRING_COMMA_LEN ("EXEC") },
+      /*  3 */ { STRING_COMMA_LEN ("MERGE") },
+      /*  4 */ { STRING_COMMA_LEN ("STRINGS") },
+      /*  5 */ { STRING_COMMA_LEN ("INFO LINK") },
+      /*  6 */ { STRING_COMMA_LEN ("LINK ORDER") },
+      /*  7 */ { STRING_COMMA_LEN ("OS NONCONF") },
+      /*  8 */ { STRING_COMMA_LEN ("GROUP") },
+      /*  9 */ { STRING_COMMA_LEN ("TLS") },
+      /* IA-64 specific.  */
+      /* 10 */ { STRING_COMMA_LEN ("SHORT") },
+      /* 11 */ { STRING_COMMA_LEN ("NORECOV") },
+      /* IA-64 OpenVMS specific.  */
+      /* 12 */ { STRING_COMMA_LEN ("VMS_GLOBAL") },
+      /* 13 */ { STRING_COMMA_LEN ("VMS_OVERLAID") },
+      /* 14 */ { STRING_COMMA_LEN ("VMS_SHARED") },
+      /* 15 */ { STRING_COMMA_LEN ("VMS_VECTOR") },
+      /* 16 */ { STRING_COMMA_LEN ("VMS_ALLOC_64BIT") },
+      /* 17 */ { STRING_COMMA_LEN ("VMS_PROTECTED") },
+      /* Generic.  */
+      /* 18 */ { STRING_COMMA_LEN ("EXCLUDE") },
+      /* SPARC specific.  */
+      /* 19 */ { STRING_COMMA_LEN ("ORDERED") }
     };
 
   if (do_section_details)
@@ -3894,43 +4261,59 @@ get_elf_section_flags (bfd_vma sh_flags)
        {
          switch (flag)
            {
-           case SHF_WRITE:             index = 0; break;
-           case SHF_ALLOC:             index = 1; break;
-           case SHF_EXECINSTR:         index = 2; break;
-           case SHF_MERGE:             index = 3; break;
-           case SHF_STRINGS:           index = 4; break;
-           case SHF_INFO_LINK:         index = 5; break;
-           case SHF_LINK_ORDER:        index = 6; break;
-           case SHF_OS_NONCONFORMING:  index = 7; break;
-           case SHF_GROUP:             index = 8; break;
-           case SHF_TLS:               index = 9; break;
+           case SHF_WRITE:             sindex = 0; break;
+           case SHF_ALLOC:             sindex = 1; break;
+           case SHF_EXECINSTR:         sindex = 2; break;
+           case SHF_MERGE:             sindex = 3; break;
+           case SHF_STRINGS:           sindex = 4; break;
+           case SHF_INFO_LINK:         sindex = 5; break;
+           case SHF_LINK_ORDER:        sindex = 6; break;
+           case SHF_OS_NONCONFORMING:  sindex = 7; break;
+           case SHF_GROUP:             sindex = 8; break;
+           case SHF_TLS:               sindex = 9; break;
+           case SHF_EXCLUDE:           sindex = 18; break;
 
            default:
-             index = -1;
-             if (elf_header.e_machine == EM_IA_64)
+             sindex = -1;
+             switch (elf_header.e_machine)
                {
+               case EM_IA_64:
                  if (flag == SHF_IA_64_SHORT)
-                   index = 10;
+                   sindex = 10;
                  else if (flag == SHF_IA_64_NORECOV)
-                   index = 11;
+                   sindex = 11;
 #ifdef BFD64
                  else if (elf_header.e_ident[EI_OSABI] == ELFOSABI_OPENVMS)
                    switch (flag)
                      {
-                     case SHF_IA_64_VMS_GLOBAL:      index = 12; break;
-                     case SHF_IA_64_VMS_OVERLAID:    index = 13; break;
-                     case SHF_IA_64_VMS_SHARED:      index = 14; break;
-                     case SHF_IA_64_VMS_VECTOR:      index = 15; break;
-                     case SHF_IA_64_VMS_ALLOC_64BIT: index = 16; break;
-                     case SHF_IA_64_VMS_PROTECTED:   index = 17; break;
+                     case SHF_IA_64_VMS_GLOBAL:      sindex = 12; break;
+                     case SHF_IA_64_VMS_OVERLAID:    sindex = 13; break;
+                     case SHF_IA_64_VMS_SHARED:      sindex = 14; break;
+                     case SHF_IA_64_VMS_VECTOR:      sindex = 15; break;
+                     case SHF_IA_64_VMS_ALLOC_64BIT: sindex = 16; break;
+                     case SHF_IA_64_VMS_PROTECTED:   sindex = 17; break;
                      default:                        break;
                      }
 #endif
+                 break;
+
+               case EM_386:
+               case EM_486:
+               case EM_X86_64:
+               case EM_L1OM:
+               case EM_OLD_SPARCV9:
+               case EM_SPARC32PLUS:
+               case EM_SPARCV9:
+               case EM_SPARC:
+                 if (flag == SHF_ORDERED)
+                   sindex = 19;
+                 break;
+               default:
+                 break;
                }
-             break;
            }
 
-         if (index != -1)
+         if (sindex != -1)
            {
              if (p != buff + field_size + 4)
                {
@@ -3941,8 +4324,8 @@ get_elf_section_flags (bfd_vma sh_flags)
                  *p++ = ' ';
                }
 
-             size -= flags [index].len;
-             p = stpcpy (p, flags [index].str);
+             size -= flags [sindex].len;
+             p = stpcpy (p, flags [sindex].str);
            }
          else if (flag & SHF_MASKOS)
            os_flags |= flag;
@@ -3965,9 +4348,11 @@ get_elf_section_flags (bfd_vma sh_flags)
            case SHF_OS_NONCONFORMING:  *p = 'O'; break;
            case SHF_GROUP:             *p = 'G'; break;
            case SHF_TLS:               *p = 'T'; break;
+           case SHF_EXCLUDE:           *p = 'E'; break;
 
            default:
-             if (elf_header.e_machine == EM_X86_64
+             if ((elf_header.e_machine == EM_X86_64
+                  || elf_header.e_machine == EM_L1OM)
                  && flag == SHF_X86_64_LARGE)
                *p = 'l';
              else if (flag & SHF_MASKOS)
@@ -4031,7 +4416,7 @@ get_elf_section_flags (bfd_vma sh_flags)
              *p++ = ',';
              *p++ = ' ';
            }
-         sprintf (p, "UNKNOWN (%*.*lx)", field_size, field_size,
+         sprintf (p, _("UNKNOWN (%*.*lx)"), field_size, field_size,
                   (unsigned long) unknown_flags);
          p += 10 + field_size;
        }
@@ -4077,8 +4462,9 @@ process_section_headers (FILE * file)
 
       if (section->sh_size != 0)
        {
-         string_table = get_data (NULL, file, section->sh_offset,
-                                  1, section->sh_size, _("string table"));
+         string_table = (char *) get_data (NULL, file, section->sh_offset,
+                                            1, section->sh_size,
+                                            _("string table"));
 
          string_table_length = string_table != NULL ? section->sh_size : 0;
        }
@@ -4182,8 +4568,9 @@ process_section_headers (FILE * file)
              continue;
            }
 
-         dynamic_strings = get_data (NULL, file, section->sh_offset,
-                                     1, section->sh_size, _("dynamic strings"));
+         dynamic_strings = (char *) get_data (NULL, file, section->sh_offset,
+                                               1, section->sh_size,
+                                               _("dynamic strings"));
          dynamic_strings_length = section->sh_size;
        }
       else if (section->sh_type == SHT_SYMTAB_SHNDX)
@@ -4204,7 +4591,7 @@ 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_lines || do_debug_pubnames || do_debug_pubtypes
                || do_debug_aranges || do_debug_frames || do_debug_macinfo
                || do_debug_str || do_debug_loc || do_debug_ranges)
               && (const_strneq (name, ".debug_")
@@ -4217,9 +4604,11 @@ process_section_headers (FILE * file)
 
          if (do_debugging
              || (do_debug_info     && streq (name, "info"))
+             || (do_debug_info     && streq (name, "types"))
              || (do_debug_abbrevs  && streq (name, "abbrev"))
              || (do_debug_lines    && streq (name, "line"))
              || (do_debug_pubnames && streq (name, "pubnames"))
+             || (do_debug_pubtypes && streq (name, "pubtypes"))
              || (do_debug_aranges  && streq (name, "aranges"))
              || (do_debug_ranges   && streq (name, "ranges"))
              || (do_debug_frames   && streq (name, "frame"))
@@ -4235,6 +4624,21 @@ process_section_headers (FILE * file)
        request_dump_bynumber (i, DEBUG_DUMP);
       else if (do_debug_frames && streq (name, ".eh_frame"))
        request_dump_bynumber (i, DEBUG_DUMP);
+      /* Trace sections for Itanium VMS.  */
+      else if ((do_debugging || do_trace_info || do_trace_abbrevs
+                || do_trace_aranges)
+              && const_strneq (name, ".trace_"))
+       {
+          name += sizeof (".trace_") - 1;
+
+         if (do_debugging
+             || (do_trace_info     && streq (name, "info"))
+             || (do_trace_abbrevs  && streq (name, "abbrev"))
+             || (do_trace_aranges  && streq (name, "aranges"))
+             )
+           request_dump_bynumber (i, DEBUG_DUMP);
+       }
+
     }
 
   if (! do_sections)
@@ -4307,6 +4711,8 @@ process_section_headers (FILE * file)
 
       if (is_32bit_elf)
        {
+         const char * link_too_big = NULL;
+
          print_vma (section->sh_addr, LONG_HEX);
 
          printf ( " %6.6lx %6.6lx %2.2lx",
@@ -4319,10 +4725,49 @@ process_section_headers (FILE * file)
          else
            printf (" %3s ", get_elf_section_flags (section->sh_flags));
 
-         printf ("%2u %3u %2lu\n",
-                 section->sh_link,
-                 section->sh_info,
-                 (unsigned long) section->sh_addralign);
+         if (section->sh_link >= elf_header.e_shnum)
+           {
+             link_too_big = "";
+             /* The sh_link value is out of range.  Normally this indicates
+                an error but it can have special values in Solaris binaries.  */
+             switch (elf_header.e_machine)
+               {
+               case EM_386:
+               case EM_486:
+               case EM_X86_64:
+               case EM_L1OM:
+               case EM_OLD_SPARCV9:
+               case EM_SPARC32PLUS:
+               case EM_SPARCV9:
+               case EM_SPARC:
+                 if (section->sh_link == (SHN_BEFORE & 0xffff))
+                   link_too_big = "BEFORE";
+                 else if (section->sh_link == (SHN_AFTER & 0xffff))
+                   link_too_big = "AFTER";
+                 break;
+               default:
+                 break;
+               }
+           }
+
+         if (do_section_details)
+           {
+             if (link_too_big != NULL && * link_too_big)
+               printf ("<%s> ", link_too_big);
+             else
+               printf ("%2u ", section->sh_link);
+             printf ("%3u %2lu\n", section->sh_info,
+                     (unsigned long) section->sh_addralign);
+           }
+         else
+           printf ("%2u %3u %2lu\n",
+                   section->sh_link,
+                   section->sh_info,
+                   (unsigned long) section->sh_addralign);
+
+         if (link_too_big && ! * link_too_big)
+           warn (_("section %u: sh_link value of %u is larger than the number of sections\n"),
+                 i, section->sh_link);
        }
       else if (do_wide)
        {
@@ -4417,10 +4862,19 @@ process_section_headers (FILE * file)
     }
 
   if (!do_section_details)
-    printf (_("Key to Flags:\n\
+    {
+      if (elf_header.e_machine == EM_X86_64
+         || elf_header.e_machine == EM_L1OM)
+       printf (_("Key to Flags:\n\
+  W (write), A (alloc), X (execute), M (merge), S (strings), l (large)\n\
+  I (info), L (link order), G (group), T (TLS), E (exclude), x (unknown)\n\
+  O (extra OS processing required) o (OS specific), p (processor specific)\n"));
+      else
+       printf (_("Key to Flags:\n\
   W (write), A (alloc), X (execute), M (merge), S (strings)\n\
-  I (info), L (link order), G (group), x (unknown)\n\
+  I (info), L (link order), G (group), T (TLS), E (exclude), x (unknown)\n\
   O (extra OS processing required) o (OS specific), p (processor specific)\n"));
+    }  
 
   return 1;
 }
@@ -4431,11 +4885,14 @@ get_group_flags (unsigned int flags)
   static char buff[32];
   switch (flags)
     {
+    case 0:
+      return "";
+
     case GRP_COMDAT:
-      return "COMDAT";
+      return "COMDAT ";
 
    default:
-      snprintf (buff, sizeof (buff), _("[<unknown>: 0x%x]"), flags);
+      snprintf (buff, sizeof (buff), _("[<unknown>: 0x%x] "), flags);
       break;
     }
   return buff;
@@ -4471,8 +4928,8 @@ process_section_groups (FILE * file)
       abort ();
     }
 
-  section_headers_groups = calloc (elf_header.e_shnum,
-                                  sizeof (struct group *));
+  section_headers_groups = (struct group **) calloc (elf_header.e_shnum,
+                                                     sizeof (struct group *));
 
   if (section_headers_groups == NULL)
     {
@@ -4496,7 +4953,7 @@ process_section_groups (FILE * file)
       return 1;
     }
 
-  section_groups = calloc (group_count, sizeof (struct group));
+  section_groups = (struct group *) calloc (group_count, sizeof (struct group));
 
   if (section_groups == NULL)
     {
@@ -4540,6 +4997,12 @@ process_section_groups (FILE * file)
              symtab = GET_ELF_SYMBOLS (file, symtab_sec);
            }
 
+         if (symtab == NULL)
+           {
+             error (_("Corrupt header in group section `%s'\n"), name);
+             continue;
+           }
+
          sym = symtab + section->sh_info;
 
          if (ELF_ST_TYPE (sym->st_info) == STT_SECTION)
@@ -4575,17 +5038,18 @@ process_section_groups (FILE * file)
                  strtab_sec = sec;
                  if (strtab)
                    free (strtab);
-                 strtab = get_data (NULL, file, strtab_sec->sh_offset,
-                                    1, strtab_sec->sh_size,
-                                    _("string table"));
+                 strtab = (char *) get_data (NULL, file, strtab_sec->sh_offset,
+                                              1, strtab_sec->sh_size,
+                                              _("string table"));
                  strtab_size = strtab != NULL ? strtab_sec->sh_size : 0;
                }
              group_name = sym->st_name < strtab_size
-                          ? strtab + sym->st_name : "<corrupt>";
+               ? strtab + sym->st_name : _("<corrupt>");
            }
 
-         start = get_data (NULL, file, section->sh_offset,
-                           1, section->sh_size, _("section data"));
+         start = (unsigned char *) get_data (NULL, file, section->sh_offset,
+                                              1, section->sh_size,
+                                              _("section data"));
 
          indices = start;
          size = (section->sh_size / section->sh_entsize) - 1;
@@ -4594,7 +5058,7 @@ process_section_groups (FILE * file)
 
          if (do_section_groups)
            {
-             printf ("\n%s group section [%5u] `%s' [%s] contains %u sections:\n",
+             printf (_("\n%sgroup section [%5u] `%s' [%s] contains %u sections:\n"),
                      get_group_flags (entry), i, name, group_name, size);
 
              printf (_("   [Index]    Name\n"));
@@ -4648,7 +5112,7 @@ process_section_groups (FILE * file)
                  printf ("   [%5u]   %s\n", entry, SECTION_NAME (sec));
                }
 
-             g = xmalloc (sizeof (struct group_list));
+             g = (struct group_list *) xmalloc (sizeof (struct group_list));
              g->section_index = entry;
              g->next = group->root;
              group->root = g;
@@ -4668,77 +5132,261 @@ process_section_groups (FILE * file)
   return 1;
 }
 
-static struct
+/* Data used to display dynamic fixups.  */
+
+struct ia64_vms_dynfixup
 {
-  const char * name;
-  int reloc;
-  int size;
-  int rela;
-} dynamic_relocations [] =
+  bfd_vma needed_ident;                /* Library ident number.  */
+  bfd_vma needed;              /* Index in the dstrtab of the library name.  */
+  bfd_vma fixup_needed;                /* Index of the library.  */
+  bfd_vma fixup_rela_cnt;      /* Number of fixups.  */
+  bfd_vma fixup_rela_off;      /* Fixups offset in the dynamic segment.  */
+};
+
+/* Data used to display dynamic relocations.  */
+
+struct ia64_vms_dynimgrela
 {
-    { "REL", DT_REL, DT_RELSZ, FALSE },
-    { "RELA", DT_RELA, DT_RELASZ, TRUE },
-    { "PLT", DT_JMPREL, DT_PLTRELSZ, UNKNOWN }
+  bfd_vma img_rela_cnt;                /* Number of relocations.  */
+  bfd_vma img_rela_off;                /* Reloc offset in the dynamic segment.  */
 };
 
-/* Process the reloc section.  */
+/* Display IA-64 OpenVMS dynamic fixups (used to dynamically link a shared
+   library).  */
 
-static int
-process_relocs (FILE * file)
+static void
+dump_ia64_vms_dynamic_fixups (FILE *file, struct ia64_vms_dynfixup *fixup,
+                              const char *strtab, unsigned int strtab_sz)
 {
-  unsigned long rel_size;
-  unsigned long rel_offset;
+  Elf64_External_VMS_IMAGE_FIXUP *imfs;
+  long i;
+  const char *lib_name;
 
+  imfs = get_data (NULL, file, dynamic_addr + fixup->fixup_rela_off,
+                  1, fixup->fixup_rela_cnt * sizeof (*imfs),
+                  _("dynamic section image fixups"));
+  if (!imfs)
+    return;
 
-  if (!do_reloc)
-    return 1;
+  if (fixup->needed < strtab_sz)
+    lib_name = strtab + fixup->needed;
+  else
+    {
+      warn ("corrupt library name index of 0x%lx found in dynamic entry",
+            (unsigned long) fixup->needed);
+      lib_name = "???";
+    }
+  printf (_("\nImage fixups for needed library #%d: %s - ident: %lx\n"),
+         (int) fixup->fixup_needed, lib_name, (long) fixup->needed_ident);
+  printf
+    (_("Seg Offset           Type                             SymVec DataType\n"));
 
-  if (do_using_dynamic)
+  for (i = 0; i < (long) fixup->fixup_rela_cnt; i++)
     {
-      int is_rela;
-      const char * name;
-      int has_dynamic_reloc;
-      unsigned int i;
+      unsigned int type;
+      const char *rtype;
 
-      has_dynamic_reloc = 0;
+      printf ("%3u ", (unsigned) BYTE_GET (imfs [i].fixup_seg));
+      printf_vma ((bfd_vma) BYTE_GET (imfs [i].fixup_offset));
+      type = BYTE_GET (imfs [i].type);
+      rtype = elf_ia64_reloc_type (type);
+      if (rtype == NULL)
+        printf (" 0x%08x                       ", type);
+      else
+        printf (" %-32s ", rtype);
+      printf ("%6u ", (unsigned) BYTE_GET (imfs [i].symvec_index));
+      printf ("0x%08x\n", (unsigned) BYTE_GET (imfs [i].data_type));
+    }
 
-      for (i = 0; i < ARRAY_SIZE (dynamic_relocations); i++)
-       {
-         is_rela = dynamic_relocations [i].rela;
-         name = dynamic_relocations [i].name;
-         rel_size = dynamic_info [dynamic_relocations [i].size];
-         rel_offset = dynamic_info [dynamic_relocations [i].reloc];
+  free (imfs);
+}
 
-         has_dynamic_reloc |= rel_size;
+/* Display IA-64 OpenVMS dynamic relocations (used to relocate an image).  */
 
-         if (is_rela == UNKNOWN)
-           {
-             if (dynamic_relocations [i].reloc == DT_JMPREL)
-               switch (dynamic_info[DT_PLTREL])
-                 {
-                 case DT_REL:
-                   is_rela = FALSE;
-                   break;
-                 case DT_RELA:
-                   is_rela = TRUE;
-                   break;
-                 }
-           }
+static void
+dump_ia64_vms_dynamic_relocs (FILE *file, struct ia64_vms_dynimgrela *imgrela)
+{
+  Elf64_External_VMS_IMAGE_RELA *imrs;
+  long i;
 
-         if (rel_size)
-           {
-             printf
-               (_("\n'%s' relocation section at offset 0x%lx contains %ld bytes:\n"),
-                name, rel_offset, rel_size);
+  imrs = get_data (NULL, file, dynamic_addr + imgrela->img_rela_off,
+                  1, imgrela->img_rela_cnt * sizeof (*imrs),
+                  _("dynamic section image relas"));
+  if (!imrs)
+    return;
 
-             dump_relocations (file,
-                               offset_from_vma (file, rel_offset, rel_size),
-                               rel_size,
-                               dynamic_symbols, num_dynamic_syms,
-                               dynamic_strings, dynamic_strings_length, is_rela);
+  printf (_("\nImage relocs\n"));
+  printf
+    (_("Seg Offset   Type                            Addend            Seg Sym Off\n"));
+
+  for (i = 0; i < (long) imgrela->img_rela_cnt; i++)
+    {
+      unsigned int type;
+      const char *rtype;
+
+      printf ("%3u ", (unsigned) BYTE_GET (imrs [i].rela_seg));
+      printf ("%08" BFD_VMA_FMT "x ",
+              (bfd_vma) BYTE_GET (imrs [i].rela_offset));
+      type = BYTE_GET (imrs [i].type);
+      rtype = elf_ia64_reloc_type (type);
+      if (rtype == NULL)
+        printf ("0x%08x                      ", type);
+      else
+        printf ("%-31s ", rtype);
+      print_vma (BYTE_GET (imrs [i].addend), FULL_HEX);
+      printf ("%3u ", (unsigned) BYTE_GET (imrs [i].sym_seg));
+      printf ("%08" BFD_VMA_FMT "x\n",
+              (bfd_vma) BYTE_GET (imrs [i].sym_offset));
+    }
+
+  free (imrs);
+}
+
+/* Display IA-64 OpenVMS dynamic relocations and fixups.  */
+
+static int
+process_ia64_vms_dynamic_relocs (FILE *file)
+{
+  struct ia64_vms_dynfixup fixup;
+  struct ia64_vms_dynimgrela imgrela;
+  Elf_Internal_Dyn *entry;
+  int res = 0;
+  bfd_vma strtab_off = 0;
+  bfd_vma strtab_sz = 0;
+  char *strtab = NULL;
+
+  memset (&fixup, 0, sizeof (fixup));
+  memset (&imgrela, 0, sizeof (imgrela));
+
+  /* Note: the order of the entries is specified by the OpenVMS specs.  */
+  for (entry = dynamic_section;
+       entry < dynamic_section + dynamic_nent;
+       entry++)
+    {
+      switch (entry->d_tag)
+        {
+        case DT_IA_64_VMS_STRTAB_OFFSET:
+          strtab_off = entry->d_un.d_val;
+          break;
+        case DT_STRSZ:
+          strtab_sz = entry->d_un.d_val;
+          if (strtab == NULL)
+            strtab = get_data (NULL, file, dynamic_addr + strtab_off,
+                               1, strtab_sz, _("dynamic string section"));
+          break;
+
+        case DT_IA_64_VMS_NEEDED_IDENT:
+          fixup.needed_ident = entry->d_un.d_val;
+          break;
+        case DT_NEEDED:
+          fixup.needed = entry->d_un.d_val;
+          break;
+        case DT_IA_64_VMS_FIXUP_NEEDED:
+          fixup.fixup_needed = entry->d_un.d_val;
+          break;
+        case DT_IA_64_VMS_FIXUP_RELA_CNT:
+          fixup.fixup_rela_cnt = entry->d_un.d_val;
+          break;
+        case DT_IA_64_VMS_FIXUP_RELA_OFF:
+          fixup.fixup_rela_off = entry->d_un.d_val;
+          res++;
+          dump_ia64_vms_dynamic_fixups (file, &fixup, strtab, strtab_sz);
+          break;
+
+        case DT_IA_64_VMS_IMG_RELA_CNT:
+         imgrela.img_rela_cnt = entry->d_un.d_val;
+          break;
+        case DT_IA_64_VMS_IMG_RELA_OFF:
+         imgrela.img_rela_off = entry->d_un.d_val;
+          res++;
+          dump_ia64_vms_dynamic_relocs (file, &imgrela);
+          break;
+
+        default:
+          break;
+       }
+    }
+
+  if (strtab != NULL)
+    free (strtab);
+
+  return res;
+}
+
+static struct
+{
+  const char * name;
+  int reloc;
+  int size;
+  int rela;
+} dynamic_relocations [] =
+{
+    { "REL", DT_REL, DT_RELSZ, FALSE },
+    { "RELA", DT_RELA, DT_RELASZ, TRUE },
+    { "PLT", DT_JMPREL, DT_PLTRELSZ, UNKNOWN }
+};
+
+/* Process the reloc section.  */
+
+static int
+process_relocs (FILE * file)
+{
+  unsigned long rel_size;
+  unsigned long rel_offset;
+
+
+  if (!do_reloc)
+    return 1;
+
+  if (do_using_dynamic)
+    {
+      int is_rela;
+      const char * name;
+      int has_dynamic_reloc;
+      unsigned int i;
+
+      has_dynamic_reloc = 0;
+
+      for (i = 0; i < ARRAY_SIZE (dynamic_relocations); i++)
+       {
+         is_rela = dynamic_relocations [i].rela;
+         name = dynamic_relocations [i].name;
+         rel_size = dynamic_info [dynamic_relocations [i].size];
+         rel_offset = dynamic_info [dynamic_relocations [i].reloc];
+
+         has_dynamic_reloc |= rel_size;
+
+         if (is_rela == UNKNOWN)
+           {
+             if (dynamic_relocations [i].reloc == DT_JMPREL)
+               switch (dynamic_info[DT_PLTREL])
+                 {
+                 case DT_REL:
+                   is_rela = FALSE;
+                   break;
+                 case DT_RELA:
+                   is_rela = TRUE;
+                   break;
+                 }
+           }
+
+         if (rel_size)
+           {
+             printf
+               (_("\n'%s' relocation section at offset 0x%lx contains %ld bytes:\n"),
+                name, rel_offset, rel_size);
+
+             dump_relocations (file,
+                               offset_from_vma (file, rel_offset, rel_size),
+                               rel_size,
+                               dynamic_symbols, num_dynamic_syms,
+                               dynamic_strings, dynamic_strings_length, is_rela);
            }
        }
 
+      if (is_ia64_vms ())
+        has_dynamic_reloc |= process_ia64_vms_dynamic_relocs (file);
+
       if (! has_dynamic_reloc)
        printf (_("\nThere are no dynamic relocations in this file.\n"));
     }
@@ -4801,9 +5449,9 @@ process_relocs (FILE * file)
                    {
                      strsec = section_headers + symsec->sh_link;
 
-                     strtab = get_data (NULL, file, strsec->sh_offset,
-                                        1, strsec->sh_size,
-                                        _("string table"));
+                     strtab = (char *) get_data (NULL, file, strsec->sh_offset,
+                                                  1, strsec->sh_size,
+                                                  _("string table"));
                      strtablen = strtab == NULL ? 0 : strsec->sh_size;
                    }
 
@@ -4847,15 +5495,17 @@ struct absaddr
    ? section_headers [(a).section].sh_addr + (a).offset \
    : (a).offset)
 
+struct ia64_unw_table_entry
+  {
+    struct absaddr start;
+    struct absaddr end;
+    struct absaddr info;
+  };
+
 struct ia64_unw_aux_info
   {
-    struct ia64_unw_table_entry
-      {
-       struct absaddr start;
-       struct absaddr end;
-       struct absaddr info;
-      }
-    *table;                    /* Unwind table.  */
+
+    struct ia64_unw_table_entry *table;        /* Unwind table.  */
     unsigned long table_len;   /* Length of unwind table.  */
     unsigned char * info;      /* Unwind info.  */
     unsigned long info_size;   /* Size of unwind info.  */
@@ -4881,16 +5531,22 @@ find_symbol_for_address (Elf_Internal_Sym * symtab,
   Elf_Internal_Sym * best = NULL;
   unsigned long i;
 
+  REMOVE_ARCH_BITS (addr.offset);
+
   for (i = 0, sym = symtab; i < nsyms; ++i, ++sym)
     {
+      bfd_vma value = sym->st_value;
+
+      REMOVE_ARCH_BITS (value);
+
       if (ELF_ST_TYPE (sym->st_info) == STT_FUNC
          && sym->st_name != 0
          && (addr.section == SHN_UNDEF || addr.section == sym->st_shndx)
-         && addr.offset >= sym->st_value
-         && addr.offset - sym->st_value < dist)
+         && addr.offset >= value
+         && addr.offset - value < dist)
        {
          best = sym;
-         dist = addr.offset - sym->st_value;
+         dist = addr.offset - value;
          if (!dist)
            break;
        }
@@ -4898,7 +5554,7 @@ find_symbol_for_address (Elf_Internal_Sym * symtab,
   if (best)
     {
       *symname = (best->st_name >= strtab_size
-                 ? "<corrupt>" : strtab + best->st_name);
+                 ? _("<corrupt>") : strtab + best->st_name);
       *offset = dist;
       return;
     }
@@ -4952,7 +5608,7 @@ dump_ia64_unwind (struct ia64_unw_aux_info * aux)
 
       if (UNW_VER (stamp) != 1)
        {
-         printf ("\tUnknown version.\n");
+         printf (_("\tUnknown version.\n"));
          continue;
        }
 
@@ -5004,11 +5660,13 @@ slurp_ia64_unwind_table (FILE * file,
 
   /* Second, build the unwind table from the contents of the unwind section:  */
   size = sec->sh_size;
-  table = get_data (NULL, file, sec->sh_offset, 1, size, _("unwind table"));
+  table = (unsigned char *) get_data (NULL, file, sec->sh_offset, 1, size,
+                                      _("unwind table"));
   if (!table)
     return 0;
 
-  aux->table = xcmalloc (size / (3 * eh_addr_size), sizeof (aux->table[0]));
+  aux->table = (struct ia64_unw_table_entry *)
+      xcmalloc (size / (3 * eh_addr_size), sizeof (aux->table[0]));
   tep = aux->table;
   for (tp = table; tp < table + size; ++tep)
     {
@@ -5055,15 +5713,15 @@ slurp_ia64_unwind_table (FILE * file,
            {
            case 0:
              aux->table[i].start.section = sym->st_shndx;
-             aux->table[i].start.offset += rp->r_addend + sym->st_value;
+             aux->table[i].start.offset  = rp->r_addend + sym->st_value;
              break;
            case 1:
              aux->table[i].end.section   = sym->st_shndx;
-             aux->table[i].end.offset   += rp->r_addend + sym->st_value;
+             aux->table[i].end.offset    = rp->r_addend + sym->st_value;
              break;
            case 2:
              aux->table[i].info.section  = sym->st_shndx;
-             aux->table[i].info.offset  += rp->r_addend + sym->st_value;
+             aux->table[i].info.offset   = rp->r_addend + sym->st_value;
              break;
            default:
              break;
@@ -5097,8 +5755,9 @@ ia64_process_unwind (FILE * file)
          aux.symtab = GET_ELF_SYMBOLS (file, sec);
 
          strsec = section_headers + sec->sh_link;
-         aux.strtab = get_data (NULL, file, strsec->sh_offset,
-                                1, strsec->sh_size, _("string table"));
+         aux.strtab = (char *) get_data (NULL, file, strsec->sh_offset,
+                                          1, strsec->sh_size,
+                                          _("string table"));
          aux.strtab_size = aux.strtab != NULL ? strsec->sh_size : 0;
        }
       else if (sec->sh_type == SHT_IA_64_UNWIND)
@@ -5180,8 +5839,9 @@ ia64_process_unwind (FILE * file)
        {
          aux.info_size = sec->sh_size;
          aux.info_addr = sec->sh_addr;
-         aux.info = get_data (NULL, file, sec->sh_offset, 1, aux.info_size,
-                              _("unwind info"));
+         aux.info = (unsigned char *) get_data (NULL, file, sec->sh_offset, 1,
+                                                 aux.info_size,
+                                                 _("unwind info"));
 
          printf (_("\nUnwind section "));
 
@@ -5216,45 +5876,46 @@ ia64_process_unwind (FILE * file)
   return 1;
 }
 
+struct hppa_unw_table_entry
+  {
+    struct absaddr start;
+    struct absaddr end;
+    unsigned int Cannot_unwind:1;                      /* 0 */
+    unsigned int Millicode:1;                  /* 1 */
+    unsigned int Millicode_save_sr0:1;         /* 2 */
+    unsigned int Region_description:2;         /* 3..4 */
+    unsigned int reserved1:1;                  /* 5 */
+    unsigned int Entry_SR:1;                   /* 6 */
+    unsigned int Entry_FR:4;     /* number saved */    /* 7..10 */
+    unsigned int Entry_GR:5;     /* number saved */    /* 11..15 */
+    unsigned int Args_stored:1;                        /* 16 */
+    unsigned int Variable_Frame:1;                     /* 17 */
+    unsigned int Separate_Package_Body:1;              /* 18 */
+    unsigned int Frame_Extension_Millicode:1;  /* 19 */
+    unsigned int Stack_Overflow_Check:1;               /* 20 */
+    unsigned int Two_Instruction_SP_Increment:1;       /* 21 */
+    unsigned int Ada_Region:1;                 /* 22 */
+    unsigned int cxx_info:1;                   /* 23 */
+    unsigned int cxx_try_catch:1;                      /* 24 */
+    unsigned int sched_entry_seq:1;                    /* 25 */
+    unsigned int reserved2:1;                  /* 26 */
+    unsigned int Save_SP:1;                            /* 27 */
+    unsigned int Save_RP:1;                            /* 28 */
+    unsigned int Save_MRP_in_frame:1;          /* 29 */
+    unsigned int extn_ptr_defined:1;           /* 30 */
+    unsigned int Cleanup_defined:1;                    /* 31 */
+
+    unsigned int MPE_XL_interrupt_marker:1;            /* 0 */
+    unsigned int HP_UX_interrupt_marker:1;             /* 1 */
+    unsigned int Large_frame:1;                        /* 2 */
+    unsigned int Pseudo_SP_Set:1;                      /* 3 */
+    unsigned int reserved4:1;                  /* 4 */
+    unsigned int Total_frame_size:27;          /* 5..31 */
+  };
+
 struct hppa_unw_aux_info
   {
-    struct hppa_unw_table_entry
-      {
-       struct absaddr start;
-       struct absaddr end;
-       unsigned int Cannot_unwind:1;                   /* 0 */
-       unsigned int Millicode:1;                       /* 1 */
-       unsigned int Millicode_save_sr0:1;              /* 2 */
-       unsigned int Region_description:2;              /* 3..4 */
-       unsigned int reserved1:1;                       /* 5 */
-       unsigned int Entry_SR:1;                        /* 6 */
-       unsigned int Entry_FR:4;     /* number saved */ /* 7..10 */
-       unsigned int Entry_GR:5;     /* number saved */ /* 11..15 */
-       unsigned int Args_stored:1;                     /* 16 */
-       unsigned int Variable_Frame:1;                  /* 17 */
-       unsigned int Separate_Package_Body:1;           /* 18 */
-       unsigned int Frame_Extension_Millicode:1;       /* 19 */
-       unsigned int Stack_Overflow_Check:1;            /* 20 */
-       unsigned int Two_Instruction_SP_Increment:1;    /* 21 */
-       unsigned int Ada_Region:1;                      /* 22 */
-       unsigned int cxx_info:1;                        /* 23 */
-       unsigned int cxx_try_catch:1;                   /* 24 */
-       unsigned int sched_entry_seq:1;                 /* 25 */
-       unsigned int reserved2:1;                       /* 26 */
-       unsigned int Save_SP:1;                         /* 27 */
-       unsigned int Save_RP:1;                         /* 28 */
-       unsigned int Save_MRP_in_frame:1;               /* 29 */
-       unsigned int extn_ptr_defined:1;                /* 30 */
-       unsigned int Cleanup_defined:1;                 /* 31 */
-
-       unsigned int MPE_XL_interrupt_marker:1;         /* 0 */
-       unsigned int HP_UX_interrupt_marker:1;          /* 1 */
-       unsigned int Large_frame:1;                     /* 2 */
-       unsigned int Pseudo_SP_Set:1;                   /* 3 */
-       unsigned int reserved4:1;                       /* 4 */
-       unsigned int Total_frame_size:27;               /* 5..31 */
-      }
-    *table;                    /* Unwind table.  */
+    struct hppa_unw_table_entry *table;        /* Unwind table.  */
     unsigned long table_len;   /* Length of unwind table.  */
     bfd_vma seg_base;          /* Starting address of segment.  */
     Elf_Internal_Sym * symtab; /* The symbol table.  */
@@ -5372,7 +6033,8 @@ slurp_hppa_unwind_table (FILE * file,
   /* Second, build the unwind table from the contents of the unwind
      section.  */
   size = sec->sh_size;
-  table = get_data (NULL, file, sec->sh_offset, 1, size, _("unwind table"));
+  table = (unsigned char *) get_data (NULL, file, sec->sh_offset, 1, size,
+                                      _("unwind table"));
   if (!table)
     return 0;
 
@@ -5380,7 +6042,8 @@ slurp_hppa_unwind_table (FILE * file,
   nentries = size / unw_ent_size;
   size = unw_ent_size * nentries;
 
-  tep = aux->table = xcmalloc (nentries, sizeof (aux->table[0]));
+  tep = aux->table = (struct hppa_unw_table_entry *)
+      xcmalloc (nentries, sizeof (aux->table[0]));
 
   for (tp = table; tp < table + size; tp += unw_ent_size, ++tep)
     {
@@ -5445,61 +6108,643 @@ slurp_hppa_unwind_table (FILE * file,
                              & rela, & nrelas))
        return 0;
 
-      for (rp = rela; rp < rela + nrelas; ++rp)
+      for (rp = rela; rp < rela + nrelas; ++rp)
+       {
+         relname = elf_hppa_reloc_type (get_reloc_type (rp->r_info));
+         sym = aux->symtab + get_reloc_symindex (rp->r_info);
+
+         /* R_PARISC_SEGREL32 or R_PARISC_SEGREL64.  */
+         if (! const_strneq (relname, "R_PARISC_SEGREL"))
+           {
+             warn (_("Skipping unexpected relocation type %s\n"), relname);
+             continue;
+           }
+
+         i = rp->r_offset / unw_ent_size;
+
+         switch ((rp->r_offset % unw_ent_size) / eh_addr_size)
+           {
+           case 0:
+             aux->table[i].start.section = sym->st_shndx;
+             aux->table[i].start.offset  = sym->st_value + rp->r_addend;
+             break;
+           case 1:
+             aux->table[i].end.section   = sym->st_shndx;
+             aux->table[i].end.offset    = sym->st_value + rp->r_addend;
+             break;
+           default:
+             break;
+           }
+       }
+
+      free (rela);
+    }
+
+  aux->table_len = nentries;
+
+  return 1;
+}
+
+static int
+hppa_process_unwind (FILE * file)
+{
+  struct hppa_unw_aux_info aux;
+  Elf_Internal_Shdr * unwsec = NULL;
+  Elf_Internal_Shdr * strsec;
+  Elf_Internal_Shdr * sec;
+  unsigned long i;
+
+  memset (& aux, 0, sizeof (aux));
+
+  if (string_table == NULL)
+    return 1;
+
+  for (i = 0, sec = section_headers; i < elf_header.e_shnum; ++i, ++sec)
+    {
+      if (sec->sh_type == SHT_SYMTAB
+         && sec->sh_link < elf_header.e_shnum)
+       {
+         aux.nsyms = sec->sh_size / sec->sh_entsize;
+         aux.symtab = GET_ELF_SYMBOLS (file, sec);
+
+         strsec = section_headers + sec->sh_link;
+         aux.strtab = (char *) get_data (NULL, file, strsec->sh_offset,
+                                          1, strsec->sh_size,
+                                          _("string table"));
+         aux.strtab_size = aux.strtab != NULL ? strsec->sh_size : 0;
+       }
+      else if (streq (SECTION_NAME (sec), ".PARISC.unwind"))
+       unwsec = sec;
+    }
+
+  if (!unwsec)
+    printf (_("\nThere are no unwind sections in this file.\n"));
+
+  for (i = 0, sec = section_headers; i < elf_header.e_shnum; ++i, ++sec)
+    {
+      if (streq (SECTION_NAME (sec), ".PARISC.unwind"))
+       {
+         printf (_("\nUnwind section "));
+         printf (_("'%s'"), SECTION_NAME (sec));
+
+         printf (_(" at offset 0x%lx contains %lu entries:\n"),
+                 (unsigned long) sec->sh_offset,
+                 (unsigned long) (sec->sh_size / (2 * eh_addr_size + 8)));
+
+          slurp_hppa_unwind_table (file, &aux, sec);
+         if (aux.table_len > 0)
+           dump_hppa_unwind (&aux);
+
+         if (aux.table)
+           free ((char *) aux.table);
+         aux.table = NULL;
+       }
+    }
+
+  if (aux.symtab)
+    free (aux.symtab);
+  if (aux.strtab)
+    free ((char *) aux.strtab);
+
+  return 1;
+}
+
+struct arm_section
+{
+  unsigned char *data;
+
+  Elf_Internal_Shdr *sec;
+  Elf_Internal_Rela *rela;
+  unsigned long nrelas;
+  unsigned int rel_type;
+
+  Elf_Internal_Rela *next_rela;
+};
+
+struct arm_unw_aux_info
+{
+  FILE *file;
+
+  Elf_Internal_Sym *symtab;    /* The symbol table.  */
+  unsigned long nsyms;         /* Number of symbols.  */
+  char *strtab;                        /* The string table.  */
+  unsigned long strtab_size;   /* Size of string table.  */
+};
+
+static const char *
+arm_print_vma_and_name (struct arm_unw_aux_info *aux,
+                       bfd_vma fn, struct absaddr addr)
+{
+  const char *procname;
+  bfd_vma sym_offset;
+
+  if (addr.section == SHN_UNDEF)
+    addr.offset = fn;
+
+  find_symbol_for_address (aux->symtab, aux->nsyms, aux->strtab,
+                          aux->strtab_size, addr, &procname,
+                          &sym_offset);
+
+  print_vma (fn, PREFIX_HEX);
+
+  if (procname)
+    {
+      fputs (" <", stdout);
+      fputs (procname, stdout);
+
+      if (sym_offset)
+       printf ("+0x%lx", (unsigned long) sym_offset);
+      fputc ('>', stdout);
+    }
+
+  return procname;
+}
+
+static void
+arm_free_section (struct arm_section *arm_sec)
+{
+  if (arm_sec->data != NULL)
+    free (arm_sec->data);
+
+  if (arm_sec->rela != NULL)
+    free (arm_sec->rela);
+}
+
+static int
+arm_section_get_word (struct arm_unw_aux_info *aux,
+                     struct arm_section *arm_sec,
+                     Elf_Internal_Shdr *sec, bfd_vma word_offset,
+                     unsigned int *wordp, struct absaddr *addr)
+{
+  Elf_Internal_Rela *rp;
+  Elf_Internal_Sym *sym;
+  const char * relname;
+  unsigned int word;
+  bfd_boolean wrapped;
+
+  addr->section = SHN_UNDEF;
+  addr->offset = 0;
+
+  if (sec != arm_sec->sec)
+    {
+      Elf_Internal_Shdr *relsec;
+
+      arm_free_section (arm_sec);
+
+      arm_sec->sec = sec;
+      arm_sec->data = get_data (NULL, aux->file, sec->sh_offset, 1,
+                               sec->sh_size, _("unwind data"));
+
+      arm_sec->rela = NULL;
+      arm_sec->nrelas = 0;
+
+      for (relsec = section_headers;
+          relsec < section_headers + elf_header.e_shnum;
+          ++relsec)
+       {
+         if (relsec->sh_info >= elf_header.e_shnum
+             || section_headers + relsec->sh_info != sec)
+           continue;
+
+         if (relsec->sh_type == SHT_REL)
+           {
+             if (!slurp_rel_relocs (aux->file, relsec->sh_offset,
+                                    relsec->sh_size,
+                                    & arm_sec->rela, & arm_sec->nrelas))
+               return 0;
+             break;
+           }
+         else if (relsec->sh_type == SHT_RELA)
+           {
+             if (!slurp_rela_relocs (aux->file, relsec->sh_offset,
+                                     relsec->sh_size,
+                                     & arm_sec->rela, & arm_sec->nrelas))
+               return 0;
+             break;
+           }
+       }
+
+      arm_sec->next_rela = arm_sec->rela;
+    }
+
+  if (arm_sec->data == NULL)
+    return 0;
+
+  word = byte_get (arm_sec->data + word_offset, 4);
+
+  wrapped = FALSE;
+  for (rp = arm_sec->next_rela; rp != arm_sec->rela + arm_sec->nrelas; rp++)
+    {
+      bfd_vma prelval, offset;
+
+      if (rp->r_offset > word_offset && !wrapped)
+       {
+         rp = arm_sec->rela;
+         wrapped = TRUE;
+       }
+      if (rp->r_offset > word_offset)
+       break;
+
+      if (rp->r_offset & 3)
+       {
+         warn (_("Skipping unexpected relocation at offset 0x%lx\n"),
+               (unsigned long) rp->r_offset);
+         continue;
+       }
+
+      if (rp->r_offset < word_offset)
+       continue;
+
+      relname = elf_arm_reloc_type (ELF32_R_TYPE (rp->r_info));
+
+      if (streq (relname, "R_ARM_NONE"))
+       continue;
+
+      if (! streq (relname, "R_ARM_PREL31"))
+       {
+         warn (_("Skipping unexpected relocation type %s\n"), relname);
+         continue;
+       }
+
+      sym = aux->symtab + ELF32_R_SYM (rp->r_info);
+
+      if (arm_sec->rel_type == SHT_REL)
+       {
+         offset = word & 0x7fffffff;
+         if (offset & 0x40000000)
+           offset |= ~ (bfd_vma) 0x7fffffff;
+       }
+      else
+       offset = rp->r_addend;
+
+      offset += sym->st_value;
+      prelval = offset - (arm_sec->sec->sh_addr + rp->r_offset);
+
+      word = (word & ~ (bfd_vma) 0x7fffffff) | (prelval & 0x7fffffff);
+      addr->section = sym->st_shndx;
+      addr->offset = offset;
+      break;
+    }
+
+  *wordp = word;
+  arm_sec->next_rela = rp;
+
+  return 1;
+}
+
+static void
+decode_arm_unwind (struct arm_unw_aux_info *aux,
+                  unsigned int word, unsigned int remaining,
+                  bfd_vma data_offset, Elf_Internal_Shdr *data_sec,
+                  struct arm_section *data_arm_sec)
+{
+  int per_index;
+  unsigned int more_words;
+  struct absaddr addr;
+
+#define ADVANCE                                                        \
+  if (remaining == 0 && more_words)                            \
+    {                                                          \
+      data_offset += 4;                                                \
+      if (!arm_section_get_word (aux, data_arm_sec, data_sec,  \
+                                data_offset, &word, &addr))    \
+       return;                                                 \
+      remaining = 4;                                           \
+      more_words--;                                            \
+    }                                                          \
+
+#define GET_OP(OP)                     \
+  ADVANCE;                             \
+  if (remaining)                       \
+    {                                  \
+      remaining--;                     \
+      (OP) = word >> 24;               \
+      word <<= 8;                      \
+    }                                  \
+  else                                 \
+    {                                  \
+      printf (_("[Truncated opcode]\n"));      \
+      return;                          \
+    }                                  \
+  printf (_("0x%02x "), OP)
+
+  if (remaining == 0)
+    {
+      /* Fetch the first word.  */
+      if (!arm_section_get_word (aux, data_arm_sec, data_sec, data_offset,
+                                &word, &addr))
+       return;
+      remaining = 4;
+    }
+
+  if ((word & 0x80000000) == 0)
+    {
+      /* Expand prel31 for personality routine.  */
+      bfd_vma fn;
+      const char *procname;
+
+      fn = word;
+      if (fn & 0x40000000)
+       fn |= ~ (bfd_vma) 0x7fffffff;
+      fn = fn + data_sec->sh_addr + data_offset;
+
+      printf (_("  Personality routine: "));
+      procname = arm_print_vma_and_name (aux, fn, addr);
+      fputc ('\n', stdout);
+
+      /* The GCC personality routines use the standard compact
+        encoding, starting with one byte giving the number of
+        words.  */
+      if (procname != NULL
+         && (const_strneq (procname, "__gcc_personality_v0")
+             || const_strneq (procname, "__gxx_personality_v0")
+             || const_strneq (procname, "__gcj_personality_v0")
+             || const_strneq (procname, "__gnu_objc_personality_v0")))
+       {
+         remaining = 0;
+         more_words = 1;
+         ADVANCE;
+         if (!remaining)
+           {
+             printf (_("  [Truncated data]\n"));
+             return;
+           }
+         more_words = word >> 24;
+         word <<= 8;
+         remaining--;
+       }
+      else
+       return;
+    }
+  else
+    {
+      per_index = (word >> 24) & 0x7f;
+      if (per_index != 0 && per_index != 1 && per_index != 2)
+       {
+         printf (_("  [reserved compact index %d]\n"), per_index);
+         return;
+       }
+
+      printf (_("  Compact model %d\n"), per_index);
+      if (per_index == 0)
+       {
+         more_words = 0;
+         word <<= 8;
+         remaining--;
+       }
+      else
+       {
+         more_words = (word >> 16) & 0xff;
+         word <<= 16;
+         remaining -= 2;
+       }
+    }
+
+  /* Decode the unwinding instructions.  */
+  while (1)
+    {
+      unsigned int op, op2;
+
+      ADVANCE;
+      if (remaining == 0)
+       break;
+      remaining--;
+      op = word >> 24;
+      word <<= 8;
+
+      printf (_("  0x%02x "), op);
+
+      if ((op & 0xc0) == 0x00)
+       {
+         int offset = ((op & 0x3f) << 2) + 4;
+         printf (_("     vsp = vsp + %d"), offset);
+       }
+      else if ((op & 0xc0) == 0x40)
+       {
+         int offset = ((op & 0x3f) << 2) + 4;
+         printf (_("     vsp = vsp - %d"), offset);
+       }
+      else if ((op & 0xf0) == 0x80)
+       {
+         GET_OP (op2);
+         if (op == 0x80 && op2 == 0)
+           printf (_("Refuse to unwind"));
+         else
+           {
+             unsigned int mask = ((op & 0x0f) << 8) | op2;
+             int first = 1;
+             int i;
+
+             printf ("pop {");
+             for (i = 0; i < 12; i++)
+               if (mask & (1 << i))
+                 {
+                   if (first)
+                     first = 0;
+                   else
+                     printf (", ");
+                   printf ("r%d", 4 + i);
+                 }
+             printf ("}");
+           }
+       }
+      else if ((op & 0xf0) == 0x90)
+       {
+         if (op == 0x9d || op == 0x9f)
+           printf (_("     [Reserved]"));
+         else
+           printf (_("     vsp = r%d"), op & 0x0f);
+       }
+      else if ((op & 0xf0) == 0xa0)
+       {
+         int end = 4 + (op & 0x07);
+         int first = 1;
+         int i;
+         printf ("     pop {");
+         for (i = 4; i <= end; i++)
+           {
+             if (first)
+               first = 0;
+             else
+               printf (", ");
+             printf ("r%d", i);
+           }
+         if (op & 0x08)
+           {
+             if (first)
+               printf (", ");
+             printf ("r14");
+           }
+         printf ("}");
+       }
+      else if (op == 0xb0)
+       printf (_("     finish"));
+      else if (op == 0xb1)
+       {
+         GET_OP (op2);
+         if (op2 == 0 || (op2 & 0xf0) != 0)
+           printf (_("[Spare]"));
+         else
+           {
+             unsigned int mask = op2 & 0x0f;
+             int first = 1;
+             int i;
+             printf ("pop {");
+             for (i = 0; i < 12; i++)
+               if (mask & (1 << i))
+                 {
+                   if (first)
+                     first = 0;
+                   else
+                     printf (", ");
+                   printf ("r%d", i);
+                 }
+             printf ("}");
+           }
+       }
+      else if (op == 0xb2)
+       {
+         unsigned char buf[9];
+         unsigned int i, len;
+         unsigned long offset;
+         for (i = 0; i < sizeof (buf); i++)
+           {
+             GET_OP (buf[i]);
+             if ((buf[i] & 0x80) == 0)
+               break;
+           }
+         assert (i < sizeof (buf));
+         offset = read_uleb128 (buf, &len);
+         assert (len == i + 1);
+         offset = offset * 4 + 0x204;
+         printf (_("vsp = vsp + %ld"), offset);
+       }
+      else
+       {
+         if (op == 0xb3 || op == 0xc6 || op == 0xc7 || op == 0xc8 || op == 0xc9)
+           {
+             GET_OP (op2);
+             printf (_("[unsupported two-byte opcode]"));
+           }
+         else
+           {
+             printf (_("     [unsupported opcode]"));
+           }
+       }
+      printf ("\n");
+    }
+
+  /* Decode the descriptors.  Not implemented.  */
+}
+
+static void
+dump_arm_unwind (struct arm_unw_aux_info *aux, Elf_Internal_Shdr *exidx_sec)
+{
+  struct arm_section exidx_arm_sec, extab_arm_sec;
+  unsigned int i, exidx_len;
+
+  memset (&exidx_arm_sec, 0, sizeof (exidx_arm_sec));
+  memset (&extab_arm_sec, 0, sizeof (extab_arm_sec));
+  exidx_len = exidx_sec->sh_size / 8;
+
+  for (i = 0; i < exidx_len; i++)
+    {
+      unsigned int exidx_fn, exidx_entry;
+      struct absaddr fn_addr, entry_addr;
+      bfd_vma fn;
+
+      fputc ('\n', stdout);
+
+      if (!arm_section_get_word (aux, &exidx_arm_sec, exidx_sec,
+                                8 * i, &exidx_fn, &fn_addr)
+         || !arm_section_get_word (aux, &exidx_arm_sec, exidx_sec,
+                                   8 * i + 4, &exidx_entry, &entry_addr))
+       {
+         arm_free_section (&exidx_arm_sec);
+         arm_free_section (&extab_arm_sec);
+         return;
+       }
+
+      fn = exidx_fn & 0x7fffffff;
+      if (fn & 0x40000000)
+       fn |= ~ (bfd_vma) 0x7fffffff;
+      fn = fn + exidx_sec->sh_addr + 8 * i;
+
+      arm_print_vma_and_name (aux, fn, entry_addr);
+      fputs (": ", stdout);
+
+      if (exidx_entry == 1)
        {
-         relname = elf_hppa_reloc_type (get_reloc_type (rp->r_info));
-         sym = aux->symtab + get_reloc_symindex (rp->r_info);
+         print_vma (exidx_entry, PREFIX_HEX);
+         fputs (" [cantunwind]\n", stdout);
+       }
+      else if (exidx_entry & 0x80000000)
+       {
+         print_vma (exidx_entry, PREFIX_HEX);
+         fputc ('\n', stdout);
+         decode_arm_unwind (aux, exidx_entry, 4, 0, NULL, NULL);
+       }
+      else
+       {
+         bfd_vma table, table_offset = 0;
+         Elf_Internal_Shdr *table_sec;
 
-         /* R_PARISC_SEGREL32 or R_PARISC_SEGREL64.  */
-         if (! const_strneq (relname, "R_PARISC_SEGREL"))
+         fputs ("@", stdout);
+         table = exidx_entry;
+         if (table & 0x40000000)
+           table |= ~ (bfd_vma) 0x7fffffff;
+         table = table + exidx_sec->sh_addr + 8 * i + 4;
+         print_vma (table, PREFIX_HEX);
+         printf ("\n");
+
+         /* Locate the matching .ARM.extab.  */
+         if (entry_addr.section != SHN_UNDEF
+             && entry_addr.section < elf_header.e_shnum)
            {
-             warn (_("Skipping unexpected relocation type %s\n"), relname);
-             continue;
+             table_sec = section_headers + entry_addr.section;
+             table_offset = entry_addr.offset;
            }
-
-         i = rp->r_offset / unw_ent_size;
-
-         switch ((rp->r_offset % unw_ent_size) / eh_addr_size)
+         else
            {
-           case 0:
-             aux->table[i].start.section = sym->st_shndx;
-             aux->table[i].start.offset += sym->st_value + rp->r_addend;
-             break;
-           case 1:
-             aux->table[i].end.section   = sym->st_shndx;
-             aux->table[i].end.offset   += sym->st_value + rp->r_addend;
-             break;
-           default:
-             break;
+             table_sec = find_section_by_address (table);
+             if (table_sec != NULL)
+               table_offset = table - table_sec->sh_addr;
+           }
+         if (table_sec == NULL)
+           {
+             warn (_("Could not locate .ARM.extab section containing 0x%lx.\n"),
+                   (unsigned long) table);
+             continue;
            }
+         decode_arm_unwind (aux, 0, 0, table_offset, table_sec,
+                            &extab_arm_sec);
        }
-
-      free (rela);
     }
 
-  aux->table_len = nentries;
+  printf ("\n");
 
-  return 1;
+  arm_free_section (&exidx_arm_sec);
+  arm_free_section (&extab_arm_sec);
 }
 
 static int
-hppa_process_unwind (FILE * file)
+arm_process_unwind (FILE *file)
 {
-  struct hppa_unw_aux_info aux;
-  Elf_Internal_Shdr * unwsec = NULL;
-  Elf_Internal_Shdr * strsec;
-  Elf_Internal_Shdr * sec;
+  struct arm_unw_aux_info aux;
+  Elf_Internal_Shdr *unwsec = NULL;
+  Elf_Internal_Shdr *strsec;
+  Elf_Internal_Shdr *sec;
   unsigned long i;
 
   memset (& aux, 0, sizeof (aux));
+  aux.file = file;
 
   if (string_table == NULL)
     return 1;
 
   for (i = 0, sec = section_headers; i < elf_header.e_shnum; ++i, ++sec)
     {
-      if (sec->sh_type == SHT_SYMTAB
-         && sec->sh_link < elf_header.e_shnum)
+      if (sec->sh_type == SHT_SYMTAB && sec->sh_link < elf_header.e_shnum)
        {
          aux.nsyms = sec->sh_size / sec->sh_entsize;
          aux.symtab = GET_ELF_SYMBOLS (file, sec);
@@ -5509,7 +6754,7 @@ hppa_process_unwind (FILE * file)
                                 1, strsec->sh_size, _("string table"));
          aux.strtab_size = aux.strtab != NULL ? strsec->sh_size : 0;
        }
-      else if (streq (SECTION_NAME (sec), ".PARISC.unwind"))
+      else if (sec->sh_type == SHT_ARM_EXIDX)
        unwsec = sec;
     }
 
@@ -5518,22 +6763,14 @@ hppa_process_unwind (FILE * file)
 
   for (i = 0, sec = section_headers; i < elf_header.e_shnum; ++i, ++sec)
     {
-      if (streq (SECTION_NAME (sec), ".PARISC.unwind"))
+      if (sec->sh_type == SHT_ARM_EXIDX)
        {
-         printf (_("\nUnwind section "));
-         printf (_("'%s'"), SECTION_NAME (sec));
-
-         printf (_(" at offset 0x%lx contains %lu entries:\n"),
+         printf (_("\nUnwind table index '%s' at offset 0x%lx contains %lu entries:\n"),
+                 SECTION_NAME (sec),
                  (unsigned long) sec->sh_offset,
-                 (unsigned long) (sec->sh_size / (2 * eh_addr_size + 8)));
-
-          slurp_hppa_unwind_table (file, &aux, sec);
-         if (aux.table_len > 0)
-           dump_hppa_unwind (&aux);
+                 (unsigned long) (sec->sh_size / (2 * eh_addr_size)));
 
-         if (aux.table)
-           free ((char *) aux.table);
-         aux.table = NULL;
+         dump_arm_unwind (&aux, sec);
        }
     }
 
@@ -5554,6 +6791,7 @@ process_unwind (FILE * file)
     int (* handler)(FILE *);
   } handlers[] =
   {
+    { EM_ARM, arm_process_unwind },
     { EM_IA_64, ia64_process_unwind },
     { EM_PARISC, hppa_process_unwind },
     { 0, 0 }
@@ -5578,7 +6816,7 @@ dynamic_section_mips_val (Elf_Internal_Dyn * entry)
     {
     case DT_MIPS_FLAGS:
       if (entry->d_un.d_val == 0)
-       printf ("NONE\n");
+       printf (_("NONE\n"));
       else
        {
          static const char * opts[] =
@@ -5591,6 +6829,7 @@ dynamic_section_mips_val (Elf_Internal_Dyn * entry)
          };
          unsigned int cnt;
          int first = 1;
+
          for (cnt = 0; cnt < ARRAY_SIZE (opts); ++cnt)
            if (entry->d_un.d_val & (1 << cnt))
              {
@@ -5603,9 +6842,9 @@ dynamic_section_mips_val (Elf_Internal_Dyn * entry)
 
     case DT_MIPS_IVERSION:
       if (VALID_DYNAMIC_NAME (entry->d_un.d_val))
-       printf ("Interface Version: %s\n", GET_DYNAMIC_NAME (entry->d_un.d_val));
+       printf (_("Interface Version: %s\n"), GET_DYNAMIC_NAME (entry->d_un.d_val));
       else
-       printf ("<corrupt: %ld>\n", (long) entry->d_un.d_ptr);
+       printf (_("<corrupt: %ld>\n"), (long) entry->d_un.d_ptr);
       break;
 
     case DT_MIPS_TIME_STAMP:
@@ -5613,12 +6852,12 @@ dynamic_section_mips_val (Elf_Internal_Dyn * entry)
        char timebuf[20];
        struct tm * tmp;
 
-       time_t time = entry->d_un.d_val;
-       tmp = gmtime (&time);
+       time_t atime = entry->d_un.d_val;
+       tmp = gmtime (&atime);
        snprintf (timebuf, sizeof (timebuf), "%04u-%02u-%02uT%02u:%02u:%02u",
                  tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
                  tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
-       printf ("Time Stamp: %s\n", timebuf);
+       printf (_("Time Stamp: %s\n"), timebuf);
       }
       break;
 
@@ -5643,7 +6882,6 @@ dynamic_section_mips_val (Elf_Internal_Dyn * entry)
     }
 }
 
-
 static void
 dynamic_section_parisc_val (Elf_Internal_Dyn * entry)
 {
@@ -5706,6 +6944,29 @@ dynamic_section_parisc_val (Elf_Internal_Dyn * entry)
   putchar ('\n');
 }
 
+#ifdef BFD64
+
+/* VMS vs Unix time offset and factor.  */
+
+#define VMS_EPOCH_OFFSET 35067168000000000LL
+#define VMS_GRANULARITY_FACTOR 10000000
+
+/* Display a VMS time in a human readable format.  */
+
+static void
+print_vms_time (bfd_int64_t vmstime)
+{
+  struct tm *tm;
+  time_t unxtime;
+
+  unxtime = (vmstime - VMS_EPOCH_OFFSET) / VMS_GRANULARITY_FACTOR;
+  tm = gmtime (&unxtime);
+  printf ("%04u-%02u-%02uT%02u:%02u:%02u",
+          tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
+          tm->tm_hour, tm->tm_min, tm->tm_sec);
+}
+#endif /* BFD64 */
+
 static void
 dynamic_section_ia64_val (Elf_Internal_Dyn * entry)
 {
@@ -5718,6 +6979,46 @@ dynamic_section_ia64_val (Elf_Internal_Dyn * entry)
       print_vma (entry->d_un.d_ptr + (3 * 8), PREFIX_HEX);
       break;
 
+    case DT_IA_64_VMS_LINKTIME:
+#ifdef BFD64
+      print_vms_time (entry->d_un.d_val);
+#endif
+      break;
+
+    case DT_IA_64_VMS_LNKFLAGS:
+      print_vma (entry->d_un.d_ptr, PREFIX_HEX);
+      if (entry->d_un.d_val & VMS_LF_CALL_DEBUG)
+        printf (" CALL_DEBUG");
+      if (entry->d_un.d_val & VMS_LF_NOP0BUFS)
+        printf (" NOP0BUFS");
+      if (entry->d_un.d_val & VMS_LF_P0IMAGE)
+        printf (" P0IMAGE");
+      if (entry->d_un.d_val & VMS_LF_MKTHREADS)
+        printf (" MKTHREADS");
+      if (entry->d_un.d_val & VMS_LF_UPCALLS)
+        printf (" UPCALLS");
+      if (entry->d_un.d_val & VMS_LF_IMGSTA)
+        printf (" IMGSTA");
+      if (entry->d_un.d_val & VMS_LF_INITIALIZE)
+        printf (" INITIALIZE");
+      if (entry->d_un.d_val & VMS_LF_MAIN)
+        printf (" MAIN");
+      if (entry->d_un.d_val & VMS_LF_EXE_INIT)
+        printf (" EXE_INIT");
+      if (entry->d_un.d_val & VMS_LF_TBK_IN_IMG)
+        printf (" TBK_IN_IMG");
+      if (entry->d_un.d_val & VMS_LF_DBG_IN_IMG)
+        printf (" DBG_IN_IMG");
+      if (entry->d_un.d_val & VMS_LF_TBK_IN_DSF)
+        printf (" TBK_IN_DSF");
+      if (entry->d_un.d_val & VMS_LF_DBG_IN_DSF)
+        printf (" DBG_IN_DSF");
+      if (entry->d_un.d_val & VMS_LF_SIGNATURES)
+        printf (" SIGNATURES");
+      if (entry->d_un.d_val & VMS_LF_REL_SEG_OFF)
+        printf (" REL_SEG_OFF");
+      break;
+
     default:
       print_vma (entry->d_un.d_ptr, PREFIX_HEX);
       break;
@@ -5732,8 +7033,8 @@ get_32bit_dynamic_section (FILE * file)
   Elf32_External_Dyn * ext;
   Elf_Internal_Dyn * entry;
 
-  edyn = get_data (NULL, file, dynamic_addr, 1, dynamic_size,
-                  _("dynamic section"));
+  edyn = (Elf32_External_Dyn *) get_data (NULL, file, dynamic_addr, 1,
+                                          dynamic_size, _("dynamic section"));
   if (!edyn)
     return 0;
 
@@ -5749,7 +7050,8 @@ get_32bit_dynamic_section (FILE * file)
        break;
     }
 
-  dynamic_section = cmalloc (dynamic_nent, sizeof (* entry));
+  dynamic_section = (Elf_Internal_Dyn *) cmalloc (dynamic_nent,
+                                                  sizeof (* entry));
   if (dynamic_section == NULL)
     {
       error (_("Out of memory\n"));
@@ -5777,8 +7079,8 @@ get_64bit_dynamic_section (FILE * file)
   Elf64_External_Dyn * ext;
   Elf_Internal_Dyn * entry;
 
-  edyn = get_data (NULL, file, dynamic_addr, 1, dynamic_size,
-                  _("dynamic section"));
+  edyn = (Elf64_External_Dyn *) get_data (NULL, file, dynamic_addr, 1,
+                                          dynamic_size, _("dynamic section"));
   if (!edyn)
     return 0;
 
@@ -5794,7 +7096,8 @@ get_64bit_dynamic_section (FILE * file)
        break;
     }
 
-  dynamic_section = cmalloc (dynamic_nent, sizeof (* entry));
+  dynamic_section = (Elf_Internal_Dyn *) cmalloc (dynamic_nent,
+                                                  sizeof (* entry));
   if (dynamic_section == NULL)
     {
       error (_("Out of memory\n"));
@@ -5839,7 +7142,7 @@ print_dynamic_flags (bfd_vma flags)
        case DF_TEXTREL:        fputs ("TEXTREL", stdout); break;
        case DF_BIND_NOW:       fputs ("BIND_NOW", stdout); break;
        case DF_STATIC_TLS:     fputs ("STATIC_TLS", stdout); break;
-       default:                fputs ("unknown", stdout); break;
+       default:                fputs (_("unknown"), stdout); break;
        }
     }
   puts ("");
@@ -5952,8 +7255,9 @@ process_dynamic_section (FILE * file)
              continue;
            }
 
-         dynamic_strings = get_data (NULL, file, offset, 1, str_tab_len,
-                                     _("dynamic string table"));
+         dynamic_strings = (char *) get_data (NULL, file, offset, 1,
+                                               str_tab_len,
+                                               _("dynamic string table"));
          dynamic_strings_length = str_tab_len;
          break;
        }
@@ -5988,12 +7292,13 @@ process_dynamic_section (FILE * file)
          Elf_Internal_Syminfo * syminfo;
 
          /* There is a syminfo section.  Read the data.  */
-         extsyminfo = get_data (NULL, file, dynamic_syminfo_offset, 1,
-                                syminsz, _("symbol information"));
+         extsyminfo = (Elf_External_Syminfo *)
+              get_data (NULL, file, dynamic_syminfo_offset, 1, syminsz,
+                        _("symbol information"));
          if (!extsyminfo)
            return 0;
 
-         dynamic_syminfo = malloc (syminsz);
+         dynamic_syminfo = (Elf_Internal_Syminfo *) malloc (syminsz);
          if (dynamic_syminfo == NULL)
            {
              error (_("Out of memory\n"));
@@ -6314,7 +7619,7 @@ process_dynamic_section (FILE * file)
          if (do_dynamic)
            {
              print_vma (entry->d_un.d_val, UNSIGNED);
-             printf (" (bytes)\n");
+             printf (_(" (bytes)\n"));
            }
          break;
 
@@ -6364,9 +7669,9 @@ process_dynamic_section (FILE * file)
          if (do_dynamic)
            {
              struct tm * tmp;
-             time_t time = entry->d_un.d_val;
+             time_t atime = entry->d_un.d_val;
 
-             tmp = gmtime (&time);
+             tmp = gmtime (&atime);
              printf ("%04u-%02u-%02uT%02u:%02u:%02u\n",
                      tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
                      tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
@@ -6435,8 +7740,16 @@ get_ver_flags (unsigned int flags)
       strcat (buff, "WEAK ");
     }
 
-  if (flags & ~(VER_FLG_BASE | VER_FLG_WEAK))
-    strcat (buff, "| <unknown>");
+  if (flags & VER_FLG_INFO)
+    {
+      if (flags & (VER_FLG_BASE|VER_FLG_WEAK))
+       strcat (buff, "| ");
+
+      strcat (buff, "INFO ");
+    }
+
+  if (flags & ~(VER_FLG_BASE | VER_FLG_WEAK | VER_FLG_INFO))
+    strcat (buff, _("| <unknown>"));
 
   return buff;
 }
@@ -6478,11 +7791,11 @@ process_version_sections (FILE * file)
                    (unsigned long) section->sh_offset, section->sh_link,
                    section->sh_link < elf_header.e_shnum
                    ? SECTION_NAME (section_headers + section->sh_link)
-                   : "<corrupt>");
+                   : _("<corrupt>"));
 
-           edefs = get_data (NULL, file, section->sh_offset, 1,
-                             section->sh_size,
-                             _("version definition section"));
+           edefs = (Elf_External_Verdef *)
+                get_data (NULL, file, section->sh_offset, 1,section->sh_size,
+                          _("version definition section"));
            endbuf = (char *) edefs + section->sh_size;
            if (!edefs)
              break;
@@ -6497,6 +7810,10 @@ process_version_sections (FILE * file)
                int j;
                int isum;
 
+               /* Check for negative or very large indicies.  */
+               if ((unsigned char *) edefs + idx < (unsigned char *) edefs)
+                 break;
+
                vstart = ((char *) edefs) + idx;
                if (vstart + sizeof (*edef) > endbuf)
                  break;
@@ -6517,6 +7834,11 @@ process_version_sections (FILE * file)
                printf (_("  Index: %d  Cnt: %d  "),
                        ent.vd_ndx, ent.vd_cnt);
 
+               /* Check for overflow.  */
+               if ((unsigned char *)(vstart + ent.vd_aux) < (unsigned char *) vstart
+                   || (unsigned char *)(vstart + ent.vd_aux) > (unsigned char *) endbuf)
+                 break;
+
                vstart += ent.vd_aux;
 
                eaux = (Elf_External_Verdaux *) vstart;
@@ -6533,6 +7855,11 @@ process_version_sections (FILE * file)
 
                for (j = 1; j < ent.vd_cnt; j++)
                  {
+                   /* Check for overflow.  */
+                   if ((unsigned char *)(vstart + aux.vda_next) < (unsigned char *) vstart
+                       || (unsigned char *)(vstart + aux.vda_next) > (unsigned char *) endbuf)
+                     break;
+
                    isum   += aux.vda_next;
                    vstart += aux.vda_next;
 
@@ -6550,11 +7877,13 @@ process_version_sections (FILE * file)
                      printf (_("  %#06x: Parent %d, name index: %ld\n"),
                              isum, j, aux.vda_name);
                  }
+
                if (j < ent.vd_cnt)
                  printf (_("  Version def aux past end of section\n"));
 
                idx += ent.vd_next;
              }
+
            if (cnt < section->sh_info)
              printf (_("  Version definition past end of section\n"));
 
@@ -6580,11 +7909,12 @@ process_version_sections (FILE * file)
                    (unsigned long) section->sh_offset, section->sh_link,
                    section->sh_link < elf_header.e_shnum
                    ? SECTION_NAME (section_headers + section->sh_link)
-                   : "<corrupt>");
+                   : _("<corrupt>"));
 
-           eneed = get_data (NULL, file, section->sh_offset, 1,
-                             section->sh_size,
-                             _("version need section"));
+           eneed = (Elf_External_Verneed *) get_data (NULL, file,
+                                                       section->sh_offset, 1,
+                                                       section->sh_size,
+                                                       _("version need section"));
            endbuf = (char *) eneed + section->sh_size;
            if (!eneed)
              break;
@@ -6597,6 +7927,9 @@ process_version_sections (FILE * file)
                int isum;
                char * vstart;
 
+               if ((unsigned char *) eneed + idx < (unsigned char *) eneed)
+                 break;
+
                vstart = ((char *) eneed) + idx;
                if (vstart + sizeof (*entry) > endbuf)
                  break;
@@ -6618,6 +7951,11 @@ process_version_sections (FILE * file)
 
                printf (_("  Cnt: %d\n"), ent.vn_cnt);
 
+               /* Check for overflow.  */
+               if ((unsigned char *)(vstart + ent.vn_aux) < (unsigned char *) vstart
+                   || (unsigned char *)(vstart + ent.vn_aux) > (unsigned char *) endbuf)
+                 break;
+
                vstart += ent.vn_aux;
 
                for (j = 0, isum = idx + ent.vn_aux; j < ent.vn_cnt; ++j)
@@ -6645,6 +7983,11 @@ process_version_sections (FILE * file)
                    printf (_("  Flags: %s  Version: %d\n"),
                            get_ver_flags (aux.vna_flags), aux.vna_other);
 
+                   /* Check for overflow.  */
+                   if ((unsigned char *)(vstart + aux.vna_next) < (unsigned char *) vstart
+                       || (unsigned char *)(vstart + aux.vna_next) > (unsigned char *) endbuf)
+                     break;
+
                    isum   += aux.vna_next;
                    vstart += aux.vna_next;
                  }
@@ -6684,11 +8027,14 @@ process_version_sections (FILE * file)
            found = 1;
 
            symbols = GET_ELF_SYMBOLS (file, link_section);
+           if (symbols == NULL)
+             break;
 
            string_sec = section_headers + link_section->sh_link;
 
-           strtab = get_data (NULL, file, string_sec->sh_offset, 1,
-                              string_sec->sh_size, _("version string table"));
+           strtab = (char *) get_data (NULL, file, string_sec->sh_offset, 1,
+                                        string_sec->sh_size,
+                                        _("version string table"));
            if (!strtab)
              break;
 
@@ -6704,15 +8050,16 @@ process_version_sections (FILE * file)
            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"));
+           edata = (unsigned char *) get_data (NULL, file, off, total,
+                                                sizeof (short),
+                                                _("version symbol data"));
            if (!edata)
              {
                free (strtab);
                break;
              }
 
-           data = cmalloc (total, sizeof (short));
+           data = (short unsigned int *) cmalloc (total, sizeof (short));
 
            for (cnt = total; cnt --;)
              data[cnt] = byte_get (edata + cnt * sizeof (short),
@@ -6740,8 +8087,18 @@ process_version_sections (FILE * file)
                      break;
 
                    default:
-                     nn = printf ("%4x%c", data[cnt + j] & 0x7fff,
-                                  data[cnt + j] & 0x8000 ? 'h' : ' ');
+                     nn = printf ("%4x%c", data[cnt + j] & VERSYM_VERSION,
+                                  data[cnt + j] & VERSYM_HIDDEN ? 'h' : ' ');
+
+                     /* If this index value is greater than the size of the symbols
+                        array, break to avoid an out-of-bounds read,  */
+                     if ((unsigned long)(cnt + j) >=
+                        ((unsigned long)link_section->sh_size /
+                         (unsigned long)link_section->sh_entsize))
+                       {
+                         warn (_("invalid index into symbol array\n"));
+                         break;
+                       }
 
                      check_def = 1;
                      check_need = 1;
@@ -6835,10 +8192,10 @@ process_version_sections (FILE * file)
 
                              offset += ivd.vd_next;
                            }
-                         while (ivd.vd_ndx != (data[cnt + j] & 0x7fff)
+                         while (ivd.vd_ndx != (data[cnt + j] & VERSYM_VERSION)
                                 && ivd.vd_next != 0);
 
-                         if (ivd.vd_ndx == (data[cnt + j] & 0x7fff))
+                         if (ivd.vd_ndx == (data[cnt + j] & VERSYM_VERSION))
                            {
                              Elf_External_Verdaux evda;
                              Elf_Internal_Verdaux ivda;
@@ -6996,6 +8353,67 @@ get_mips_symbol_other (unsigned int other)
     }
 }
 
+static const char *
+get_ia64_symbol_other (unsigned int other)
+{
+  if (is_ia64_vms ())
+    {
+      static char res[32];
+
+      res[0] = 0;
+
+      /* Function types is for images and .STB files only.  */
+      switch (elf_header.e_type)
+        {
+        case ET_DYN:
+        case ET_EXEC:
+          switch (VMS_ST_FUNC_TYPE (other))
+            {
+            case VMS_SFT_CODE_ADDR:
+              strcat (res, " CA");
+              break;
+            case VMS_SFT_SYMV_IDX:
+              strcat (res, " VEC");
+              break;
+            case VMS_SFT_FD:
+              strcat (res, " FD");
+              break;
+            case VMS_SFT_RESERVE:
+              strcat (res, " RSV");
+              break;
+            default:
+              abort ();
+            }
+          break;
+        default:
+          break;
+        }
+      switch (VMS_ST_LINKAGE (other))
+        {
+        case VMS_STL_IGNORE:
+          strcat (res, " IGN");
+          break;
+        case VMS_STL_RESERVE:
+          strcat (res, " RSV");
+          break;
+        case VMS_STL_STD:
+          strcat (res, " STD");
+          break;
+        case VMS_STL_LNK:
+          strcat (res, " LNK");
+          break;
+        default:
+          abort ();
+        }
+
+      if (res[0] != 0)
+        return res + 1;
+      else
+        return res;
+    }
+  return NULL;
+}
+
 static const char *
 get_symbol_other (unsigned int other)
 {
@@ -7009,6 +8427,10 @@ get_symbol_other (unsigned int other)
     {
     case EM_MIPS:
       result = get_mips_symbol_other (other);
+      break;
+    case EM_IA_64:
+      result = get_ia64_symbol_other (other);
+      break;
     default:
       break;
     }
@@ -7035,7 +8457,8 @@ get_symbol_index_type (unsigned int type)
          && elf_header.e_machine == EM_IA_64
          && elf_header.e_ident[EI_OSABI] == ELFOSABI_HPUX)
        return "ANSI_COM";
-      else if (elf_header.e_machine == EM_X86_64
+      else if ((elf_header.e_machine == EM_X86_64
+               || elf_header.e_machine == EM_L1OM)
               && type == SHN_X86_64_LCOMMON)
        return "LARGE_COM";
       else if (type == SHN_MIPS_SCOMMON
@@ -7064,7 +8487,7 @@ get_dynamic_data (FILE * file, unsigned int number, unsigned int ent_size)
   unsigned char * e_data;
   bfd_vma * i_data;
 
-  e_data = cmalloc (number, ent_size);
+  e_data = (unsigned char *) cmalloc (number, ent_size);
 
   if (e_data == NULL)
     {
@@ -7078,7 +8501,7 @@ get_dynamic_data (FILE * file, unsigned int number, unsigned int ent_size)
       return NULL;
     }
 
-  i_data = cmalloc (number, sizeof (*i_data));
+  i_data = (bfd_vma *) cmalloc (number, sizeof (*i_data));
 
   if (i_data == NULL)
     {
@@ -7111,9 +8534,9 @@ print_dynamic_symbol (bfd_vma si, unsigned long hn)
   putchar (' ');
   print_vma (psym->st_size, DEC_5);
 
-  printf ("  %6s", get_symbol_type (ELF_ST_TYPE (psym->st_info)));
-  printf (" %6s",  get_symbol_binding (ELF_ST_BIND (psym->st_info)));
-  printf (" %3s",  get_symbol_visibility (ELF_ST_VISIBILITY (psym->st_other)));
+  printf (" %-7s", get_symbol_type (ELF_ST_TYPE (psym->st_info)));
+  printf (" %-6s",  get_symbol_binding (ELF_ST_BIND (psym->st_info)));
+  printf (" %-7s",  get_symbol_visibility (ELF_ST_VISIBILITY (psym->st_other)));
   /* Check to see if any other bits in the st_other field are set.
      Note - displaying this information disrupts the layout of the
      table being generated, but for the moment this case is very
@@ -7124,7 +8547,7 @@ print_dynamic_symbol (bfd_vma si, unsigned long hn)
   if (VALID_DYNAMIC_NAME (psym->st_name))
     print_symbol (25, GET_DYNAMIC_NAME (psym->st_name));
   else
-    printf (" <corrupt: %14ld>", psym->st_name);
+    printf (_(" <corrupt: %14ld>"), psym->st_name);
   putchar ('\n');
 }
 
@@ -7142,12 +8565,14 @@ process_symbol_table (FILE * file)
   bfd_vma * gnuchains = NULL;
   bfd_vma gnusymidx = 0;
 
-  if (! do_syms && !do_histogram)
+  if (!do_syms && !do_dyn_syms && !do_histogram)
     return 1;
 
   if (dynamic_info[DT_HASH]
       && (do_histogram
-         || (do_using_dynamic && dynamic_strings != NULL)))
+         || (do_using_dynamic
+             && !do_dyn_syms
+             && dynamic_strings != NULL)))
     {
       unsigned char nb[8];
       unsigned char nc[8];
@@ -7203,7 +8628,9 @@ process_symbol_table (FILE * file)
 
   if (dynamic_info_DT_GNU_HASH
       && (do_histogram
-         || (do_using_dynamic && dynamic_strings != NULL)))
+         || (do_using_dynamic
+             && !do_dyn_syms
+             && dynamic_strings != NULL)))
     {
       unsigned char nb[16];
       bfd_vma i, maxchain = 0xffffffff, bitmaskwords;
@@ -7360,7 +8787,7 @@ process_symbol_table (FILE * file)
              }
        }
     }
-  else if (do_syms && !do_using_dynamic)
+  else if (do_dyn_syms || (do_syms && !do_using_dynamic))
     {
       unsigned int i;
 
@@ -7374,13 +8801,23 @@ process_symbol_table (FILE * file)
          Elf_Internal_Sym * symtab;
          Elf_Internal_Sym * psym;
 
-         if (   section->sh_type != SHT_SYMTAB
-             && section->sh_type != SHT_DYNSYM)
+         if ((section->sh_type != SHT_SYMTAB
+              && section->sh_type != SHT_DYNSYM)
+             || (!do_syms
+                 && section->sh_type == SHT_SYMTAB))
            continue;
 
+         if (section->sh_entsize == 0)
+           {
+             printf (_("\nSymbol table '%s' has a sh_entsize of zero!\n"),
+                     SECTION_NAME (section));
+             continue;
+           }
+
          printf (_("\nSymbol table '%s' contains %lu entries:\n"),
                  SECTION_NAME (section),
                  (unsigned long) (section->sh_size / section->sh_entsize));
+
          if (is_32bit_elf)
            printf (_("   Num:    Value  Size Type    Bind   Vis      Ndx Name\n"));
          else
@@ -7401,8 +8838,9 @@ process_symbol_table (FILE * file)
 
              string_sec = section_headers + section->sh_link;
 
-             strtab = get_data (NULL, file, string_sec->sh_offset,
-                                1, string_sec->sh_size, _("string table"));
+             strtab = (char *) get_data (NULL, file, string_sec->sh_offset,
+                                          1, string_sec->sh_size,
+                                          _("string table"));
              strtab_size = strtab != NULL ? string_sec->sh_size : 0;
            }
 
@@ -7416,7 +8854,7 @@ process_symbol_table (FILE * file)
              print_vma (psym->st_size, DEC_5);
              printf (" %-7s", get_symbol_type (ELF_ST_TYPE (psym->st_info)));
              printf (" %-6s", get_symbol_binding (ELF_ST_BIND (psym->st_info)));
-             printf (" %-3s", get_symbol_visibility (ELF_ST_VISIBILITY (psym->st_other)));
+             printf (" %-7s", get_symbol_visibility (ELF_ST_VISIBILITY (psym->st_other)));
              /* Check to see if any other bits in the st_other field are set.
                 Note - displaying this information disrupts the layout of the
                 table being generated, but for the moment this case is very rare.  */
@@ -7424,7 +8862,7 @@ process_symbol_table (FILE * file)
                printf (" [%s] ", get_symbol_other (psym->st_other ^ ELF_ST_VISIBILITY (psym->st_other)));
              printf (" %4s ", get_symbol_index_type (psym->st_shndx));
              print_symbol (25, psym->st_name < strtab_size
-                           ? strtab + psym->st_name : "<corrupt>");
+                           ? strtab + psym->st_name : _("<corrupt>"));
 
              if (section->sh_type == SHT_DYNSYM &&
                  version_info[DT_VERSIONTAGIDX (DT_VERSYM)] != 0)
@@ -7450,7 +8888,7 @@ process_symbol_table (FILE * file)
 
                  check_def = (psym->st_shndx != SHN_UNDEF);
 
-                 if ((vers_data & 0x8000) || vers_data > 1)
+                 if ((vers_data & VERSYM_HIDDEN) || vers_data > 1)
                    {
                      if (version_info[DT_VERSIONTAGIDX (DT_VERNEED)]
                          && (is_nobits || ! check_def))
@@ -7504,7 +8942,7 @@ process_symbol_table (FILE * file)
                            {
                              printf ("@%s (%d)",
                                      ivna.vna_name < strtab_size
-                                     ? strtab + ivna.vna_name : "<corrupt>",
+                                     ? strtab + ivna.vna_name : _("<corrupt>"),
                                      ivna.vna_other);
                              check_def = 0;
                            }
@@ -7522,9 +8960,9 @@ process_symbol_table (FILE * file)
                              Elf_Internal_Verdef ivd;
                              Elf_Internal_Verdaux ivda;
                              Elf_External_Verdaux evda;
-                             unsigned long offset;
+                             unsigned long off;
 
-                             offset = offset_from_vma
+                             off = offset_from_vma
                                (file,
                                 version_info[DT_VERSIONTAGIDX (DT_VERDEF)],
                                 sizeof (Elf_External_Verdef));
@@ -7533,31 +8971,31 @@ process_symbol_table (FILE * file)
                                {
                                  Elf_External_Verdef evd;
 
-                                 get_data (&evd, file, offset, sizeof (evd),
+                                 get_data (&evd, file, off, sizeof (evd),
                                            1, _("version def"));
 
                                  ivd.vd_ndx = BYTE_GET (evd.vd_ndx);
                                  ivd.vd_aux = BYTE_GET (evd.vd_aux);
                                  ivd.vd_next = BYTE_GET (evd.vd_next);
 
-                                 offset += ivd.vd_next;
+                                 off += ivd.vd_next;
                                }
-                             while (ivd.vd_ndx != (vers_data & 0x7fff)
+                             while (ivd.vd_ndx != (vers_data & VERSYM_VERSION)
                                     && ivd.vd_next != 0);
 
-                             offset -= ivd.vd_next;
-                             offset += ivd.vd_aux;
+                             off -= ivd.vd_next;
+                             off += ivd.vd_aux;
 
-                             get_data (&evda, file, offset, sizeof (evda),
+                             get_data (&evda, file, off, sizeof (evda),
                                        1, _("version def aux"));
 
                              ivda.vda_name = BYTE_GET (evda.vda_name);
 
                              if (psym->st_name != ivda.vda_name)
-                               printf ((vers_data & 0x8000)
+                               printf ((vers_data & VERSYM_HIDDEN)
                                        ? "@%s" : "@@%s",
                                        ivda.vda_name < strtab_size
-                                       ? strtab + ivda.vda_name : "<corrupt>");
+                                       ? strtab + ivda.vda_name : _("<corrupt>"));
                            }
                        }
                    }
@@ -7589,7 +9027,7 @@ process_symbol_table (FILE * file)
              (unsigned long) nbuckets);
       printf (_(" Length  Number     %% of total  Coverage\n"));
 
-      lengths = calloc (nbuckets, sizeof (*lengths));
+      lengths = (unsigned long *) calloc (nbuckets, sizeof (*lengths));
       if (lengths == NULL)
        {
          error (_("Out of memory\n"));
@@ -7605,7 +9043,7 @@ process_symbol_table (FILE * file)
            }
        }
 
-      counts = calloc (maxlength + 1, sizeof (*counts));
+      counts = (unsigned long *) calloc (maxlength + 1, sizeof (*counts));
       if (counts == NULL)
        {
          error (_("Out of memory\n"));
@@ -7648,7 +9086,7 @@ process_symbol_table (FILE * file)
       unsigned long nzero_counts = 0;
       unsigned long nsyms = 0;
 
-      lengths = calloc (ngnubuckets, sizeof (*lengths));
+      lengths = (unsigned long *) calloc (ngnubuckets, sizeof (*lengths));
       if (lengths == NULL)
        {
          error (_("Out of memory\n"));
@@ -7673,7 +9111,7 @@ process_symbol_table (FILE * file)
            nsyms += length;
          }
 
-      counts = calloc (maxlength + 1, sizeof (*counts));
+      counts = (unsigned long *) calloc (maxlength + 1, sizeof (*counts));
       if (counts == NULL)
        {
          error (_("Out of memory\n"));
@@ -7733,7 +9171,7 @@ process_syminfo (FILE * file ATTRIBUTE_UNUSED)
       if (VALID_DYNAMIC_NAME (dynamic_symbols[i].st_name))
        print_symbol (30, GET_DYNAMIC_NAME (dynamic_symbols[i].st_name));
       else
-       printf ("<corrupt: %19ld>", dynamic_symbols[i].st_name);
+       printf (_("<corrupt: %19ld>"), dynamic_symbols[i].st_name);
       putchar (' ');
 
       switch (dynamic_syminfo[i].si_boundto)
@@ -7848,8 +9286,10 @@ is_32bit_abs_reloc (unsigned int reloc_type)
       return reloc_type == 1; /* R_68K_32.  */
     case EM_860:
       return reloc_type == 1; /* R_860_32.  */
+    case EM_960:
+      return reloc_type == 2; /* R_960_32.  */
     case EM_ALPHA:
-      return reloc_type == 1; /* XXX Is this right ?  */
+      return reloc_type == 1; /* R_ALPHA_REFLONG.  */
     case EM_ARC:
       return reloc_type == 1; /* R_ARC_32.  */
     case EM_ARM:
@@ -7901,6 +9341,8 @@ is_32bit_abs_reloc (unsigned int reloc_type)
       return reloc_type == 1; /* R_MCORE_ADDR32.  */
     case EM_CYGNUS_MEP:
       return reloc_type == 4; /* R_MEP_32.  */
+    case EM_MICROBLAZE:
+      return reloc_type == 1; /* R_MICROBLAZE_32.  */
     case EM_MIPS:
       return reloc_type == 2; /* R_MIPS_32.  */
     case EM_MMIX:
@@ -7911,6 +9353,8 @@ is_32bit_abs_reloc (unsigned int reloc_type)
     case EM_CYGNUS_MN10300:
     case EM_MN10300:
       return reloc_type == 1; /* R_MN10300_32.  */
+    case EM_MOXIE:
+      return reloc_type == 1; /* R_MOXIE_32.  */
     case EM_MSP430_OLD:
     case EM_MSP430:
       return reloc_type == 1; /* R_MSP43_32.  */
@@ -7923,7 +9367,8 @@ is_32bit_abs_reloc (unsigned int reloc_type)
     case EM_OR32:
       return reloc_type == 1; /* R_OR32_32.  */
     case EM_PARISC:
-      return reloc_type == 1; /* R_PARISC_DIR32.  */
+      return (reloc_type == 1 /* R_PARISC_DIR32.  */
+             || reloc_type == 41); /* R_PARISC_SECREL32.  */
     case EM_PJ:
     case EM_PJ_OLD:
       return reloc_type == 1; /* R_PJ_DATA_DIR32.  */
@@ -7931,6 +9376,8 @@ is_32bit_abs_reloc (unsigned int reloc_type)
       return reloc_type == 1; /* R_PPC64_ADDR32.  */
     case EM_PPC:
       return reloc_type == 1; /* R_PPC_ADDR32.  */
+    case EM_RX:
+      return reloc_type == 1; /* R_RX_DIR32.  */
     case EM_S370:
       return reloc_type == 1; /* R_I370_ADDR31.  */
     case EM_S390_OLD:
@@ -7947,19 +9394,24 @@ is_32bit_abs_reloc (unsigned int reloc_type)
        || reloc_type == 23; /* R_SPARC_UA32.  */
     case EM_SPU:
       return reloc_type == 6; /* R_SPU_ADDR32 */
+    case EM_TI_C6000:
+      return reloc_type == 1; /* R_C6000_ABS32.  */
     case EM_CYGNUS_V850:
     case EM_V850:
       return reloc_type == 6; /* R_V850_ABS32.  */
     case EM_VAX:
       return reloc_type == 1; /* R_VAX_32.  */
     case EM_X86_64:
+    case EM_L1OM:
       return reloc_type == 10; /* R_X86_64_32.  */
+    case EM_XC16X:
+    case EM_C166:
+      return reloc_type == 3; /* R_XC16C_ABS_32.  */
     case EM_XSTORMY16:
       return reloc_type == 1; /* R_XSTROMY16_32.  */
     case EM_XTENSA_OLD:
     case EM_XTENSA:
       return reloc_type == 1; /* R_XTENSA_32.  */
-
     default:
       error (_("Missing knowledge of 32-bit reloc types used in DWARF sections of machine number %d\n"),
             elf_header.e_machine);
@@ -7984,6 +9436,8 @@ is_32bit_pcrel_reloc (unsigned int reloc_type)
       return reloc_type == 10; /* R_ALPHA_SREL32.  */
     case EM_ARM:
       return reloc_type == 3;  /* R_ARM_REL32 */
+    case EM_MICROBLAZE:
+      return reloc_type == 2;  /* R_MICROBLAZE_32_PCREL.  */
     case EM_PARISC:
       return reloc_type == 9;  /* R_PARISC_PCREL32.  */
     case EM_PPC:
@@ -8002,6 +9456,7 @@ is_32bit_pcrel_reloc (unsigned int reloc_type)
     case EM_SPU:
       return reloc_type == 13; /* R_SPU_REL32.  */
     case EM_X86_64:
+    case EM_L1OM:
       return reloc_type == 2;  /* R_X86_64_PC32.  */
     case EM_XTENSA_OLD:
     case EM_XTENSA:
@@ -8037,6 +9492,7 @@ is_64bit_abs_reloc (unsigned int reloc_type)
     case EM_SPARC:
       return reloc_type == 54; /* R_SPARC_UA64.  */
     case EM_X86_64:
+    case EM_L1OM:
       return reloc_type == 1; /* R_X86_64_64.  */
     case EM_S390_OLD:
     case EM_S390:
@@ -8069,6 +9525,7 @@ is_64bit_pcrel_reloc (unsigned int reloc_type)
     case EM_SPARC:
       return reloc_type == 46; /* R_SPARC_DISP64 */
     case EM_X86_64:
+    case EM_L1OM:
       return reloc_type == 24; /* R_X86_64_PC64 */
     case EM_S390_OLD:
     case EM_S390:
@@ -8078,6 +9535,22 @@ is_64bit_pcrel_reloc (unsigned int reloc_type)
     }
 }
 
+/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
+   a 24-bit absolute RELA relocation used in DWARF debug sections.  */
+
+static bfd_boolean
+is_24bit_abs_reloc (unsigned int reloc_type)
+{
+  switch (elf_header.e_machine)
+    {
+    case EM_CYGNUS_MN10200:
+    case EM_MN10200:
+      return reloc_type == 4; /* R_MN10200_24.  */
+    default:
+      return FALSE;
+    }
+}
+
 /* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
    a 16-bit absolute RELA relocation used in DWARF debug sections.  */
 
@@ -8108,6 +9581,11 @@ is_16bit_abs_reloc (unsigned int reloc_type)
     case EM_ALTERA_NIOS2:
     case EM_NIOS32:
       return reloc_type == 9; /* R_NIOS_16.  */
+    case EM_TI_C6000:
+      return reloc_type == 2; /* R_C6000_ABS16.  */
+    case EM_XC16X:
+    case EM_C166:
+      return reloc_type == 2; /* R_XC16C_ABS_16.  */
     default:
       return FALSE;
     }
@@ -8138,9 +9616,20 @@ is_none_reloc (unsigned int reloc_type)
     case EM_S390:    /* R_390_NONE.  */
     case EM_CRIS:    /* R_CRIS_NONE.  */
     case EM_X86_64:  /* R_X86_64_NONE.  */
+    case EM_L1OM:    /* R_X86_64_NONE.  */
     case EM_MN10300: /* R_MN10300_NONE.  */
+    case EM_MOXIE:   /* R_MOXIE_NONE.  */
     case EM_M32R:    /* R_M32R_NONE.  */
+    case EM_TI_C6000:/* R_C6000_NONE.  */
+    case EM_XC16X:
+    case EM_C166:    /* R_XC16X_NONE.  */
       return reloc_type == 0;
+    case EM_XTENSA_OLD:
+    case EM_XTENSA:
+      return (reloc_type == 0      /* R_XTENSA_NONE.  */
+             || reloc_type == 17  /* R_XTENSA_DIFF8.  */
+             || reloc_type == 18  /* R_XTENSA_DIFF16.  */
+             || reloc_type == 19  /* R_XTENSA_DIFF32.  */);
     }
   return FALSE;
 }
@@ -8185,14 +9674,14 @@ apply_relocations (void * file,
 
       if (is_rela)
        {
-         if (!slurp_rela_relocs (file, relsec->sh_offset, relsec->sh_size,
-                                 & relocs, & num_relocs))
+         if (!slurp_rela_relocs ((FILE *) file, relsec->sh_offset,
+                                  relsec->sh_size, & relocs, & num_relocs))
            return;
        }
       else
        {
-         if (!slurp_rel_relocs (file, relsec->sh_offset, relsec->sh_size,
-                                & relocs, & num_relocs))
+         if (!slurp_rel_relocs ((FILE *) file, relsec->sh_offset,
+                                 relsec->sh_size, & relocs, & num_relocs))
            return;
        }
 
@@ -8201,14 +9690,14 @@ apply_relocations (void * file,
        is_rela = FALSE;
 
       symsec = section_headers + relsec->sh_link;
-      symtab = GET_ELF_SYMBOLS (file, symsec);
+      symtab = GET_ELF_SYMBOLS ((FILE *) file, symsec);
 
       for (rp = relocs; rp < relocs + num_relocs; ++rp)
        {
          bfd_vma         addend;
          unsigned int    reloc_type;
          unsigned int    reloc_size;
-         unsigned char * loc;
+         unsigned char * rloc;
 
          reloc_type = get_reloc_type (rp->r_info);
 
@@ -8222,6 +9711,8 @@ apply_relocations (void * file,
          else if (is_64bit_abs_reloc (reloc_type)
                   || is_64bit_pcrel_reloc (reloc_type))
            reloc_size = 8;
+         else if (is_24bit_abs_reloc (reloc_type))
+           reloc_size = 3;
          else if (is_16bit_abs_reloc (reloc_type))
            reloc_size = 2;
          else
@@ -8231,8 +9722,8 @@ apply_relocations (void * file,
              continue;
            }
 
-         loc = start + rp->r_offset;
-         if ((loc + reloc_size) > end)
+         rloc = start + rp->r_offset;
+         if ((rloc + reloc_size) > end)
            {
              warn (_("skipping invalid relocation offset 0x%lx in section %s\n"),
                    (unsigned long) rp->r_offset,
@@ -8265,7 +9756,21 @@ apply_relocations (void * file,
              continue;
            }
 
-         addend = is_rela ? rp->r_addend : byte_get (loc, reloc_size);
+         addend = 0;
+         if (is_rela)
+           addend += rp->r_addend;
+         /* R_XTENSA_32, R_PJ_DATA_DIR32 and R_D30V_32_NORMAL are
+            partial_inplace.  */
+         if (!is_rela
+             || (elf_header.e_machine == EM_XTENSA
+                 && reloc_type == 1)
+             || ((elf_header.e_machine == EM_PJ
+                  || elf_header.e_machine == EM_PJ_OLD)
+                 && reloc_type == 1)
+             || ((elf_header.e_machine == EM_D30V
+                  || elf_header.e_machine == EM_CYGNUS_D30V)
+                 && reloc_type == 12))
+           addend += byte_get (rloc, reloc_size);
 
          if (is_32bit_pcrel_reloc (reloc_type)
              || is_64bit_pcrel_reloc (reloc_type))
@@ -8273,11 +9778,11 @@ apply_relocations (void * file,
              /* 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,
+             byte_put (rloc, (addend + sym->st_value) - rp->r_offset,
                        reloc_size);
            }
          else
-           byte_put (loc, addend + sym->st_value, reloc_size);
+           byte_put (rloc, addend + sym->st_value, reloc_size);
        }
 
       free (symtab);
@@ -8316,17 +9821,16 @@ get_section_contents (Elf_Internal_Shdr * section, FILE * file)
       return NULL;
     }
 
-  return get_data (NULL, file, section->sh_offset, 1, num_bytes,
-                  _("section contents"));
+  return  (char *) get_data (NULL, file, section->sh_offset, 1, num_bytes,
+                             _("section contents"));
 }
 
-                     
+
 static void
 dump_section_as_strings (Elf_Internal_Shdr * section, FILE * file)
 {
   Elf_Internal_Shdr * relsec;
   bfd_size_type num_bytes;
-  bfd_vma addr;
   char * data;
   char * end;
   char * start;
@@ -8360,7 +9864,6 @@ dump_section_as_strings (Elf_Internal_Shdr * section, FILE * file)
     }
 
   num_bytes = section->sh_size;
-  addr = section->sh_addr;
   data = start;
   end  = start + num_bytes;
   some_strings_shown = FALSE;
@@ -8374,7 +9877,10 @@ dump_section_as_strings (Elf_Internal_Shdr * section, FILE * file)
       if (data < end)
        {
 #ifndef __MSVCRT__
-         printf ("  [%6tx]  %s\n", data - start, data);
+         /* PR 11128: Use two separate invocations in order to work
+             around bugs in the Solaris 8 implementation of printf.  */
+         printf ("  [%6tx]  ", data - start);
+         printf ("%s\n", data);
 #else
          printf ("  [%6Ix]  %s\n", (size_t) (data - start), data);
 #endif
@@ -8485,12 +9991,10 @@ dump_section_as_bytes (Elf_Internal_Shdr * section,
    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)
+uncompress_section_contents (unsigned char **buffer ATTRIBUTE_UNUSED,
+                            dwarf_size_type *size ATTRIBUTE_UNUSED)
 {
 #ifndef HAVE_ZLIB_H
-  /* These are just to quiet gcc.  */
-  buffer = 0;
-  size = 0;
   return FALSE;
 #else
   dwarf_size_type compressed_size = *size;
@@ -8524,7 +10028,7 @@ uncompress_section_contents (unsigned char ** buffer, dwarf_size_type * size)
   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);
+  uncompressed_buffer = (unsigned char *) xmalloc (uncompressed_size);
 
   rc = inflateInit (& strm);
   while (strm.avail_in > 0)
@@ -8571,17 +10075,21 @@ load_specific_debug_section (enum dwarf_section_display_enum debug,
   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);
+  section->start = (unsigned char *) get_data (NULL, (FILE *) 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 (! uncompress_section_contents (&section->start, &section->size))
+        return 0;
+      sec->sh_size = section->size;
+    }
 
   if (debug_displays [debug].relocate)
-    apply_relocations (file, sec, section->start);
+    apply_relocations ((FILE *) file, sec, section->start);
 
   return 1;
 }
@@ -8605,7 +10113,7 @@ load_debug_section (enum dwarf_section_display_enum debug, void * file)
   if (sec == NULL)
     return 0;
 
-  return load_specific_debug_section (debug, sec, file);
+  return load_specific_debug_section (debug, sec, (FILE *) file);
 }
 
 void
@@ -8628,7 +10136,7 @@ display_debug_section (Elf_Internal_Shdr * section, FILE * file)
   char * name = SECTION_NAME (section);
   bfd_size_type length;
   int result = 1;
-  enum dwarf_section_display_enum i;
+  int i;
 
   length = section->sh_size;
   if (length == 0)
@@ -8658,18 +10166,19 @@ display_debug_section (Elf_Internal_Shdr * section, FILE * file)
        int secondary = (section != find_section (name));
 
        if (secondary)
-         free_debug_section (i);
+         free_debug_section ((enum dwarf_section_display_enum) i);
 
-       if (streq (debug_displays[i].section.uncompressed_name, name))
+       if (streq (sec->uncompressed_name, name))
          sec->name = sec->uncompressed_name;
        else
          sec->name = sec->compressed_name;
-       if (load_specific_debug_section (i, section, file))
+       if (load_specific_debug_section ((enum dwarf_section_display_enum) i,
+                                         section, file))
          {
            result &= debug_displays[i].display (sec, file);
 
            if (secondary || (i != info && i != abbrev))
-             free_debug_section (i);
+             free_debug_section ((enum dwarf_section_display_enum) i);
          }
 
        break;
@@ -8782,14 +10291,15 @@ typedef struct
 
 static const char * arm_attr_tag_CPU_arch[] =
   {"Pre-v4", "v4", "v4T", "v5T", "v5TE", "v5TEJ", "v6", "v6KZ", "v6T2",
-   "v6K", "v7", "v6-M", "v6S-M"};
+   "v6K", "v7", "v6-M", "v6S-M", "v7E-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_FP_arch[] =
+  {"No", "VFPv1", "VFPv2", "VFPv3", "VFPv3-D16", "VFPv4", "VFPv4-D16"};
 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_Advanced_SIMD_arch[] =
+  {"No", "NEONv1", "NEONv1 with Fused-MAC"};
 static const char * arm_attr_tag_PCS_config[] =
   {"None", "Bare platform", "Linux application", "Linux DSO", "PalmOS 2004",
    "PalmOS (reserved)", "SymbianOS 2004", "SymbianOS (reserved)"};
@@ -8810,13 +10320,10 @@ 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[] =
   {"Unused", "Finite", "RTABI", "IEEE 754"};
-static const char * arm_attr_tag_ABI_align8_needed[] = {"No", "Yes", "4-byte"};
-static const char * arm_attr_tag_ABI_align8_preserved[] =
-  {"No", "Yes, except leaf SP", "Yes"};
 static const char * arm_attr_tag_ABI_enum_size[] =
   {"Unused", "small", "int", "forced to int"};
 static const char * arm_attr_tag_ABI_HardFP_use[] =
-  {"As Tag_VFP_arch", "SP only", "DP only", "SP and DP"};
+  {"As Tag_FP_arch", "SP only", "DP only", "SP and DP"};
 static const char * arm_attr_tag_ABI_VFP_args[] =
   {"AAPCS", "VFP registers", "custom"};
 static const char * arm_attr_tag_ABI_WMMX_args[] =
@@ -8828,14 +10335,21 @@ 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[] =
+static const char * arm_attr_tag_FP_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_MPextension_use[] =
+  {"Not Allowed", "Allowed"};
+static const char * arm_attr_tag_DIV_use[] =
+  {"Allowed in Thumb-ISA, v7-R or v7-M", "Not allowed",
+    "Allowed in v7-A with integer division extension"};
 static const char * arm_attr_tag_T2EE_use[] = {"Not Allowed", "Allowed"};
 static const char * arm_attr_tag_Virtualization_use[] =
+  {"Not Allowed", "TrustZone", "Virtualization Extensions",
+    "TrustZone and Virtualization Extensions"};
+static const char * arm_attr_tag_MPextension_use_legacy[] =
   {"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}
@@ -8847,7 +10361,7 @@ static arm_attr_public_tag arm_attr_public_tags[] =
   {7, "CPU_arch_profile", 0, NULL},
   LOOKUP(8, ARM_ISA_use),
   LOOKUP(9, THUMB_ISA_use),
-  LOOKUP(10, VFP_arch),
+  LOOKUP(10, FP_arch),
   LOOKUP(11, WMMX_arch),
   LOOKUP(12, Advanced_SIMD_arch),
   LOOKUP(13, PCS_config),
@@ -8861,8 +10375,8 @@ static arm_attr_public_tag arm_attr_public_tags[] =
   LOOKUP(21, ABI_FP_exceptions),
   LOOKUP(22, ABI_FP_user_exceptions),
   LOOKUP(23, ABI_FP_number_model),
-  LOOKUP(24, ABI_align8_needed),
-  LOOKUP(25, ABI_align8_preserved),
+  {24, "ABI_align_needed", 0, NULL},
+  {25, "ABI_align_preserved", 0, NULL},
   LOOKUP(26, ABI_enum_size),
   LOOKUP(27, ABI_HardFP_use),
   LOOKUP(28, ABI_VFP_args),
@@ -8871,44 +10385,19 @@ static arm_attr_public_tag arm_attr_public_tags[] =
   LOOKUP(31, ABI_FP_optimization_goals),
   {32, "compatibility", 0, NULL},
   LOOKUP(34, CPU_unaligned_access),
-  LOOKUP(36, VFP_HP_extension),
+  LOOKUP(36, FP_HP_extension),
   LOOKUP(38, ABI_FP_16bit_format),
+  LOOKUP(42, MPextension_use),
+  LOOKUP(44, DIV_use),
   {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)
+  LOOKUP(70, MPextension_use_legacy)
 };
 #undef LOOKUP
 
-/* Read an unsigned LEB128 encoded value from p.  Set *PLEN to the number of
-   bytes read.  */
-
-static unsigned int
-read_uleb128 (unsigned char * p, unsigned int * plen)
-{
-  unsigned char c;
-  unsigned int val;
-  int shift;
-  int len;
-
-  val = 0;
-  shift = 0;
-  len = 0;
-  do
-    {
-      c = *(p++);
-      len++;
-      val |= ((unsigned int)c & 0x7f) << shift;
-      shift += 7;
-    }
-  while (c & 0x80);
-
-  *plen = len;
-  return val;
-}
-
 static unsigned char *
 display_arm_attribute (unsigned char * p)
 {
@@ -8944,24 +10433,63 @@ display_arm_attribute (unsigned char * p)
              p += len;
              switch (val)
                {
-               case 0: printf ("None\n"); break;
-               case 'A': printf ("Application\n"); break;
-               case 'R': printf ("Realtime\n"); break;
-               case 'M': printf ("Microcontroller\n"); break;
+               case 0: printf (_("None\n")); break;
+               case 'A': printf (_("Application\n")); break;
+               case 'R': printf (_("Realtime\n")); break;
+               case 'M': printf (_("Microcontroller\n")); break;
+               case 'S': printf (_("Application or Realtime\n")); break;
                default: printf ("??? (%d)\n", val); break;
                }
              break;
 
+           case 24: /* Tag_align_needed.  */
+             val = read_uleb128 (p, &len);
+             p += len;
+             switch (val)
+               {
+               case 0: printf (_("None\n")); break;
+               case 1: printf (_("8-byte\n")); break;
+               case 2: printf (_("4-byte\n")); break;
+               case 3: printf ("??? 3\n"); break;
+               default:
+                 if (val <= 12)
+                   printf (_("8-byte and up to %d-byte extended\n"),
+                           1 << val);
+                 else
+                   printf ("??? (%d)\n", val);
+                 break;
+               }
+             break;
+
+           case 25: /* Tag_align_preserved.  */
+             val = read_uleb128 (p, &len);
+             p += len;
+             switch (val)
+               {
+               case 0: printf (_("None\n")); break;
+               case 1: printf (_("8-byte, except leaf SP\n")); break;
+               case 2: printf (_("8-byte\n")); break;
+               case 3: printf ("??? 3\n"); break;
+               default:
+                 if (val <= 12)
+                   printf (_("8-byte and up to %d-byte extended\n"),
+                           1 << val);
+                 else
+                   printf ("??? (%d)\n", val);
+                 break;
+               }
+             break;
+
            case 32: /* Tag_compatibility.  */
              val = read_uleb128 (p, &len);
              p += len;
-             printf ("flag = %d, vendor = %s\n", val, p);
+             printf (_("flag = %d, vendor = %s\n"), val, p);
              p += strlen ((char *) p) + 1;
              break;
 
            case 64: /* Tag_nodefaults.  */
              p++;
-             printf ("True\n");
+             printf (_("True\n"));
              break;
 
            case 65: /* Tag_also_compatible_with.  */
@@ -9045,7 +10573,7 @@ display_gnu_attribute (unsigned char * p,
     {
       val = read_uleb128 (p, &len);
       p += len;
-      printf ("flag = %d, vendor = %s\n", val, p);
+      printf (_("flag = %d, vendor = %s\n"), val, p);
       p += strlen ((char *) p) + 1;
       return p;
     }
@@ -9090,16 +10618,16 @@ display_power_gnu_attribute (unsigned char * p, int tag)
       switch (val)
        {
        case 0:
-         printf ("Hard or soft float\n");
+         printf (_("Hard or soft float\n"));
          break;
        case 1:
-         printf ("Hard float\n");
+         printf (_("Hard float\n"));
          break;
        case 2:
-         printf ("Soft float\n");
+         printf (_("Soft float\n"));
          break;
        case 3:
-         printf ("Single-precision hard float\n");
+         printf (_("Single-precision hard float\n"));
          break;
        default:
          printf ("??? (%d)\n", val);
@@ -9116,10 +10644,10 @@ display_power_gnu_attribute (unsigned char * p, int tag)
       switch (val)
        {
        case 0:
-         printf ("Any\n");
+         printf (_("Any\n"));
          break;
        case 1:
-         printf ("Generic\n");
+         printf (_("Generic\n"));
          break;
        case 2:
          printf ("AltiVec\n");
@@ -9142,13 +10670,13 @@ display_power_gnu_attribute (unsigned char * p, int tag)
       switch (val)
        {
        case 0:
-         printf ("Any\n");
+         printf (_("Any\n"));
          break;
        case 1:
          printf ("r3/r4\n");
          break;
        case 2:
-         printf ("Memory\n");
+         printf (_("Memory\n"));
          break;
        default:
          printf ("??? (%d)\n", val);
@@ -9194,19 +10722,19 @@ display_mips_gnu_attribute (unsigned char * p, int tag)
       switch (val)
        {
        case 0:
-         printf ("Hard or soft float\n");
+         printf (_("Hard or soft float\n"));
          break;
        case 1:
-         printf ("Hard float (-mdouble-float)\n");
+         printf (_("Hard float (double precision)\n"));
          break;
        case 2:
-         printf ("Hard float (-msingle-float)\n");
+         printf (_("Hard float (single precision)\n"));
          break;
        case 3:
-         printf ("Soft float\n");
+         printf (_("Soft float\n"));
          break;
        case 4:
-         printf ("64-bit float (-mips32r2 -mfp64)\n");
+         printf (_("Hard float (MIPS32r2 64-bit FPU)\n"));
          break;
        default:
          printf ("??? (%d)\n", val);
@@ -9236,6 +10764,91 @@ display_mips_gnu_attribute (unsigned char * p, int tag)
   return p;
 }
 
+static unsigned char *
+display_tic6x_attribute (unsigned char * p)
+{
+  int tag;
+  unsigned int len;
+  int val;
+
+  tag = read_uleb128 (p, &len);
+  p += len;
+
+  switch (tag)
+    {
+    case Tag_ISA:
+      val = read_uleb128 (p, &len);
+      p += len;
+      printf ("  Tag_ISA: ");
+
+      switch (val)
+       {
+       case C6XABI_Tag_ISA_none:
+         printf (_("None\n"));
+         break;
+       case C6XABI_Tag_ISA_C62X:
+         printf ("C62x\n");
+         break;
+       case C6XABI_Tag_ISA_C67X:
+         printf ("C67x\n");
+         break;
+       case C6XABI_Tag_ISA_C67XP:
+         printf ("C67x+\n");
+         break;
+       case C6XABI_Tag_ISA_C64X:
+         printf ("C64x\n");
+         break;
+       case C6XABI_Tag_ISA_C64XP:
+         printf ("C64x+\n");
+         break;
+       case C6XABI_Tag_ISA_C674X:
+         printf ("C674x\n");
+         break;
+       default:
+         printf ("??? (%d)\n", val);
+         break;
+       }
+      return p;
+
+    case Tag_ABI_DSBT:
+      val = read_uleb128 (p, &len);
+      p += len;
+      printf ("  Tag_ABI_DSBT: ");
+      switch (val)
+       {
+       case 0:
+         printf (_("DSBT addressing not used\n"));
+         break;
+       case 1:
+         printf (_("DSBT addressing used\n"));
+         break;
+       default:
+         printf ("??? (%d)\n", val);
+         break;
+       }
+      return p;
+
+    case 32:
+      /* Tag_compatibility - treated as generic by binutils for now
+        although not currently specified for C6X.  */
+      val = read_uleb128 (p, &len);
+      p += len;
+      printf (_("flag = %d, vendor = %s\n"), val, p);
+      p += strlen ((char *) p) + 1;
+      return p;
+    }
+
+  printf ("  Tag_unknown_%d: ", tag);
+
+  /* No general documentation of handling unknown attributes, treat as
+     ULEB128 for now.  */
+  val = read_uleb128 (p, &len);
+  p += len;
+  printf ("%d (0x%x)\n", val, val);
+
+  return p;
+}
+
 static int
 process_attributes (FILE * file,
                    const char * public_name,
@@ -9259,8 +10872,8 @@ process_attributes (FILE * file,
       if (sect->sh_type != proc_type && sect->sh_type != SHT_GNU_ATTRIBUTES)
        continue;
 
-      contents = get_data (NULL, file, sect->sh_offset, 1, sect->sh_size,
-                          _("attributes"));
+      contents = (unsigned char *) get_data (NULL, file, sect->sh_offset, 1,
+                                             sect->sh_size, _("attributes"));
       if (contents == NULL)
        continue;
 
@@ -9287,7 +10900,7 @@ process_attributes (FILE * file,
                }
 
              len -= section_len;
-             printf ("Attribute Section: %s\n", p);
+             printf (_("Attribute Section: %s\n"), p);
 
              if (public_name && streq ((char *) p, public_name))
                public_section = TRUE;
@@ -9324,20 +10937,20 @@ process_attributes (FILE * file,
                  switch (tag)
                    {
                    case 1:
-                     printf ("File Attributes\n");
+                     printf (_("File Attributes\n"));
                      break;
                    case 2:
-                     printf ("Section Attributes:");
+                     printf (_("Section Attributes:"));
                      goto do_numlist;
                    case 3:
-                     printf ("Symbol Attributes:");
+                     printf (_("Symbol Attributes:"));
                    do_numlist:
                      for (;;)
                        {
-                         unsigned int i;
+                         unsigned int j;
 
-                         val = read_uleb128 (p, &i);
-                         p += i;
+                         val = read_uleb128 (p, &j);
+                         p += j;
                          if (val == 0)
                            break;
                          printf (" %d", val);
@@ -9345,7 +10958,7 @@ process_attributes (FILE * file,
                      printf ("\n");
                      break;
                    default:
-                     printf ("Unknown tag: %d\n", tag);
+                     printf (_("Unknown tag: %d\n"), tag);
                      public_section = FALSE;
                      break;
                    }
@@ -9364,7 +10977,7 @@ process_attributes (FILE * file,
                  else
                    {
                      /* ??? Do something sensible, like dump hex.  */
-                     printf ("  Unknown section contexts\n");
+                     printf (_("  Unknown section contexts\n"));
                      p = end;
                    }
                }
@@ -9392,6 +11005,13 @@ process_power_specific (FILE * file)
                             display_power_gnu_attribute);
 }
 
+static int
+process_tic6x_specific (FILE * file)
+{
+  return process_attributes (file, "c6xabi", SHT_C6000_ATTRIBUTES,
+                            display_tic6x_attribute, NULL);
+}
+
 /* DATA points to the contents of a MIPS GOT that starts at VMA PLTGOT.
    Print the Address, Access and Initial fields of an entry at VMA ADDR
    and return the VMA of the next entry.  */
@@ -9408,7 +11028,7 @@ print_mips_got_entry (unsigned char * data, bfd_vma pltgot, bfd_vma addr)
     printf ("%10s", "");
   printf (" ");
   if (data == NULL)
-    printf ("%*s", is_32bit_elf ? 8 : 16, "<unknown>");
+    printf ("%*s", is_32bit_elf ? 8 : 16, _("<unknown>"));
   else
     {
       bfd_vma entry;
@@ -9430,7 +11050,7 @@ print_mips_pltgot_entry (unsigned char * data, bfd_vma pltgot, bfd_vma addr)
   print_vma (addr, LONG_HEX);
   printf (" ");
   if (data == NULL)
-    printf ("%*s", is_32bit_elf ? 8 : 16, "<unknown>");
+    printf ("%*s", is_32bit_elf ? 8 : 16, _("<unknown>"));
   else
     {
       bfd_vma entry;
@@ -9522,30 +11142,31 @@ process_mips_specific (FILE * file)
       Elf32_External_Lib * elib;
       size_t cnt;
 
-      elib = get_data (NULL, file, liblist_offset,
-                      liblistno, sizeof (Elf32_External_Lib),
-                      _("liblist"));
+      elib = (Elf32_External_Lib *) get_data (NULL, file, liblist_offset,
+                                              liblistno,
+                                              sizeof (Elf32_External_Lib),
+                                              _("liblist"));
       if (elib)
        {
-         printf ("\nSection '.liblist' contains %lu entries:\n",
+         printf (_("\nSection '.liblist' contains %lu entries:\n"),
                  (unsigned long) liblistno);
-         fputs ("     Library              Time Stamp          Checksum   Version Flags\n",
+         fputs (_("     Library              Time Stamp          Checksum   Version Flags\n"),
                 stdout);
 
          for (cnt = 0; cnt < liblistno; ++cnt)
            {
              Elf32_Lib liblist;
-             time_t time;
+             time_t atime;
              char timebuf[20];
              struct tm * tmp;
 
              liblist.l_name = BYTE_GET (elib[cnt].l_name);
-             time = BYTE_GET (elib[cnt].l_time_stamp);
+             atime = BYTE_GET (elib[cnt].l_time_stamp);
              liblist.l_checksum = BYTE_GET (elib[cnt].l_checksum);
              liblist.l_version = BYTE_GET (elib[cnt].l_version);
              liblist.l_flags = BYTE_GET (elib[cnt].l_flags);
 
-             tmp = gmtime (&time);
+             tmp = gmtime (&atime);
              snprintf (timebuf, sizeof (timebuf),
                        "%04u-%02u-%02uT%02u:%02u:%02u",
                        tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
@@ -9555,12 +11176,12 @@ process_mips_specific (FILE * file)
              if (VALID_DYNAMIC_NAME (liblist.l_name))
                print_symbol (20, GET_DYNAMIC_NAME (liblist.l_name));
              else
-               printf ("<corrupt: %9ld>", liblist.l_name);
+               printf (_("<corrupt: %9ld>"), liblist.l_name);
              printf (" %s %#10lx %-7ld", timebuf, liblist.l_checksum,
                      liblist.l_version);
 
              if (liblist.l_flags == 0)
-               puts (" NONE");
+               puts (_(" NONE"));
              else
                {
                  static const struct
@@ -9610,11 +11231,12 @@ process_mips_specific (FILE * file)
       while (sect->sh_type != SHT_MIPS_OPTIONS)
        ++sect;
 
-      eopt = get_data (NULL, file, options_offset, 1, sect->sh_size,
-                      _("options"));
+      eopt = (Elf_External_Options *) get_data (NULL, file, options_offset, 1,
+                                                sect->sh_size, _("options"));
       if (eopt)
        {
-         iopt = cmalloc ((sect->sh_size / sizeof (eopt)), sizeof (* iopt));
+         iopt = (Elf_Internal_Options *)
+              cmalloc ((sect->sh_size / sizeof (eopt)), sizeof (* iopt));
          if (iopt == NULL)
            {
              error (_("Out of memory\n"));
@@ -9806,7 +11428,7 @@ process_mips_specific (FILE * file)
          return 0;
        }
 
-      iconf = cmalloc (conflictsno, sizeof (* iconf));
+      iconf = (Elf32_Conflict *) cmalloc (conflictsno, sizeof (* iconf));
       if (iconf == NULL)
        {
          error (_("Out of memory\n"));
@@ -9817,8 +11439,9 @@ process_mips_specific (FILE * file)
        {
          Elf32_External_Conflict * econf32;
 
-         econf32 = get_data (NULL, file, conflicts_offset,
-                             conflictsno, sizeof (* econf32), _("conflict"));
+         econf32 = (Elf32_External_Conflict *)
+              get_data (NULL, file, conflicts_offset, conflictsno,
+                        sizeof (* econf32), _("conflict"));
          if (!econf32)
            return 0;
 
@@ -9831,8 +11454,9 @@ process_mips_specific (FILE * file)
        {
          Elf64_External_Conflict * econf64;
 
-         econf64 = get_data (NULL, file, conflicts_offset,
-                             conflictsno, sizeof (* econf64), _("conflict"));
+         econf64 = (Elf64_External_Conflict *)
+              get_data (NULL, file, conflicts_offset, conflictsno,
+                        sizeof (* econf64), _("conflict"));
          if (!econf64)
            return 0;
 
@@ -9856,7 +11480,7 @@ process_mips_specific (FILE * file)
          if (VALID_DYNAMIC_NAME (psym->st_name))
            print_symbol (25, GET_DYNAMIC_NAME (psym->st_name));
          else
-           printf ("<corrupt: %14ld>", psym->st_name);
+           printf (_("<corrupt: %14ld>"), psym->st_name);
          putchar ('\n');
        }
 
@@ -9865,18 +11489,19 @@ process_mips_specific (FILE * file)
 
   if (pltgot != 0 && local_gotno != 0)
     {
-      bfd_vma entry, local_end, global_end;
+      bfd_vma ent, local_end, global_end;
       size_t i, offset;
       unsigned char * data;
       int addr_size;
 
-      entry = pltgot;
+      ent = pltgot;
       addr_size = (is_32bit_elf ? 4 : 8);
       local_end = pltgot + local_gotno * addr_size;
       global_end = local_end + (symtabno - gotsym) * addr_size;
 
       offset = offset_from_vma (file, pltgot, global_end - pltgot);
-      data = get_data (NULL, file, offset, global_end - pltgot, 1, _("GOT"));
+      data = (unsigned char *) get_data (NULL, file, offset,
+                                         global_end - pltgot, 1, _("GOT"));
       printf (_("\nPrimary GOT:\n"));
       printf (_(" Canonical gp value: "));
       print_vma (pltgot + 0x7ff0, LONG_HEX);
@@ -9884,28 +11509,28 @@ process_mips_specific (FILE * file)
 
       printf (_(" Reserved entries:\n"));
       printf (_("  %*s %10s %*s Purpose\n"),
-             addr_size * 2, "Address", "Access",
-             addr_size * 2, "Initial");
-      entry = print_mips_got_entry (data, pltgot, entry);
-      printf (" Lazy resolver\n");
+             addr_size * 2, _("Address"), _("Access"),
+             addr_size * 2, _("Initial"));
+      ent = print_mips_got_entry (data, pltgot, ent);
+      printf (_(" Lazy resolver\n"));
       if (data
-         && (byte_get (data + entry - pltgot, addr_size)
+         && (byte_get (data + ent - pltgot, addr_size)
              >> (addr_size * 8 - 1)) != 0)
        {
-         entry = print_mips_got_entry (data, pltgot, entry);
-         printf (" Module pointer (GNU extension)\n");
+         ent = print_mips_got_entry (data, pltgot, ent);
+         printf (_(" Module pointer (GNU extension)\n"));
        }
       printf ("\n");
 
-      if (entry < local_end)
+      if (ent < local_end)
        {
          printf (_(" Local entries:\n"));
          printf (_("  %*s %10s %*s\n"),
-                 addr_size * 2, "Address", "Access",
-                 addr_size * 2, "Initial");
-         while (entry < local_end)
+                 addr_size * 2, _("Address"), _("Access"),
+                 addr_size * 2, _("Initial"));
+         while (ent < local_end)
            {
-             entry = print_mips_got_entry (data, pltgot, entry);
+             ent = print_mips_got_entry (data, pltgot, ent);
              printf ("\n");
            }
          printf ("\n");
@@ -9917,16 +11542,16 @@ process_mips_specific (FILE * file)
 
          printf (_(" Global entries:\n"));
          printf (_("  %*s %10s %*s %*s %-7s %3s %s\n"),
-                 addr_size * 2, "Address", "Access",
-                 addr_size * 2, "Initial",
-                 addr_size * 2, "Sym.Val.", "Type", "Ndx", "Name");
+                 addr_size * 2, _("Address"), _("Access"),
+                 addr_size * 2, _("Initial"),
+                 addr_size * 2, _("Sym.Val."), _("Type"), _("Ndx"), _("Name"));
          sym_width = (is_32bit_elf ? 80 : 160) - 28 - addr_size * 6 - 1;
          for (i = gotsym; i < symtabno; i++)
            {
              Elf_Internal_Sym * psym;
 
              psym = dynamic_symbols + i;
-             entry = print_mips_got_entry (data, pltgot, entry);
+             ent = print_mips_got_entry (data, pltgot, ent);
              printf (" ");
              print_vma (psym->st_value, LONG_HEX);
              printf (" %-7s %3s ",
@@ -9935,7 +11560,7 @@ process_mips_specific (FILE * file)
              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 (_("<corrupt: %14ld>"), psym->st_name);
              printf ("\n");
            }
          printf ("\n");
@@ -9947,7 +11572,7 @@ process_mips_specific (FILE * file)
 
   if (mips_pltgot != 0 && jmprel != 0 && pltrel != 0 && pltrelsz != 0)
     {
-      bfd_vma entry, end;
+      bfd_vma ent, end;
       size_t offset, rel_offset;
       unsigned long count, i;
       unsigned char * data;
@@ -9966,34 +11591,35 @@ process_mips_specific (FILE * file)
            return 0;
        }
 
-      entry = mips_pltgot;
+      ent = 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"));
+      data = (unsigned char *) 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");
+             addr_size * 2, _("Address"), addr_size * 2, _("Initial"));
+      ent = print_mips_pltgot_entry (data, mips_pltgot, ent);
+      printf (_(" PLT lazy resolver\n"));
+      ent = print_mips_pltgot_entry (data, mips_pltgot, ent);
+      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");
+             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);
+         ent = print_mips_pltgot_entry (data, mips_pltgot, ent);
          printf (" ");
          print_vma (psym->st_value, LONG_HEX);
          printf (" %-7s %3s ",
@@ -10002,7 +11628,7 @@ process_mips_specific (FILE * file)
          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 (_("<corrupt: %14ld>"), psym->st_name);
          printf ("\n");
        }
       printf ("\n");
@@ -10039,15 +11665,17 @@ process_gnu_liblist (FILE * file)
          if (section->sh_link >= elf_header.e_shnum)
            break;
 
-         elib = get_data (NULL, file, section->sh_offset, 1, section->sh_size,
-                          _("liblist"));
+         elib = (Elf32_External_Lib *)
+              get_data (NULL, file, section->sh_offset, 1, section->sh_size,
+                        _("liblist"));
 
          if (elib == NULL)
            break;
          string_sec = section_headers + section->sh_link;
 
-         strtab = get_data (NULL, file, string_sec->sh_offset, 1,
-                            string_sec->sh_size, _("liblist string table"));
+         strtab = (char *) get_data (NULL, file, string_sec->sh_offset, 1,
+                                      string_sec->sh_size,
+                                      _("liblist string table"));
          strtab_size = string_sec->sh_size;
 
          if (strtab == NULL
@@ -10061,23 +11689,23 @@ process_gnu_liblist (FILE * file)
                  SECTION_NAME (section),
                  (unsigned long) (section->sh_size / sizeof (Elf32_External_Lib)));
 
-         puts ("     Library              Time Stamp          Checksum   Version Flags");
+         puts (_("     Library              Time Stamp          Checksum   Version Flags"));
 
          for (cnt = 0; cnt < section->sh_size / sizeof (Elf32_External_Lib);
               ++cnt)
            {
              Elf32_Lib liblist;
-             time_t time;
+             time_t atime;
              char timebuf[20];
              struct tm * tmp;
 
              liblist.l_name = BYTE_GET (elib[cnt].l_name);
-             time = BYTE_GET (elib[cnt].l_time_stamp);
+             atime = BYTE_GET (elib[cnt].l_time_stamp);
              liblist.l_checksum = BYTE_GET (elib[cnt].l_checksum);
              liblist.l_version = BYTE_GET (elib[cnt].l_version);
              liblist.l_flags = BYTE_GET (elib[cnt].l_flags);
 
-             tmp = gmtime (&time);
+             tmp = gmtime (&atime);
              snprintf (timebuf, sizeof (timebuf),
                        "%04u-%02u-%02uT%02u:%02u:%02u",
                        tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
@@ -10086,10 +11714,10 @@ process_gnu_liblist (FILE * file)
              printf ("%3lu: ", (unsigned long) cnt);
              if (do_wide)
                printf ("%-20s", liblist.l_name < strtab_size
-                                ? strtab + liblist.l_name : "<corrupt>");
+                       ? strtab + liblist.l_name : _("<corrupt>"));
              else
                printf ("%-20.20s", liblist.l_name < strtab_size
-                                   ? strtab + liblist.l_name : "<corrupt>");
+                       ? strtab + liblist.l_name : _("<corrupt>"));
              printf (" %s %#010lx %-7ld %-7ld\n", timebuf, liblist.l_checksum,
                      liblist.l_version, liblist.l_flags);
            }
@@ -10125,6 +11753,20 @@ get_note_type (unsigned e_type)
        return _("NT_PPC_VMX (ppc Altivec registers)");
       case NT_PPC_VSX:
        return _("NT_PPC_VSX (ppc VSX registers)");
+      case NT_X86_XSTATE:
+       return _("NT_X86_XSTATE (x86 XSAVE extended state)");
+      case NT_S390_HIGH_GPRS:
+       return _("NT_S390_HIGH_GPRS (s390 upper register halves)");
+      case NT_S390_TIMER:
+       return _("NT_S390_TIMER (s390 timer register)");
+      case NT_S390_TODCMP:
+       return _("NT_S390_TODCMP (s390 TOD comparator register)");
+      case NT_S390_TODPREG:
+       return _("NT_S390_TODPREG (s390 TOD programmable register)");
+      case NT_S390_CTRS:
+       return _("NT_S390_CTRS (s390 control registers)");
+      case NT_S390_PREFIX:
+       return _("NT_S390_PREFIX (s390 prefix register)");
       case NT_PSTATUS:
        return _("NT_PSTATUS (pstatus structure)");
       case NT_FPREGS:
@@ -10212,9 +11854,9 @@ get_netbsd_elfcore_note_type (unsigned e_type)
     case EM_SPARCV9:
       switch (e_type)
        {
-       case NT_NETBSDCORE_FIRSTMACH+0:
+       case NT_NETBSDCORE_FIRSTMACH + 0:
          return _("PT_GETREGS (reg structure)");
-       case NT_NETBSDCORE_FIRSTMACH+2:
+       case NT_NETBSDCORE_FIRSTMACH + 2:
          return _("PT_GETFPREGS (fpreg structure)");
        default:
          break;
@@ -10226,9 +11868,9 @@ get_netbsd_elfcore_note_type (unsigned e_type)
     default:
       switch (e_type)
        {
-       case NT_NETBSDCORE_FIRSTMACH+1:
+       case NT_NETBSDCORE_FIRSTMACH + 1:
          return _("PT_GETREGS (reg structure)");
-       case NT_NETBSDCORE_FIRSTMACH+3:
+       case NT_NETBSDCORE_FIRSTMACH + 3:
          return _("PT_GETFPREGS (fpreg structure)");
        default:
          break;
@@ -10291,8 +11933,9 @@ process_corefile_note_segment (FILE * file, bfd_vma offset, bfd_vma length)
   if (length <= 0)
     return 0;
 
-  pnotes = get_data (NULL, file, offset, 1, length, _("notes"));
-  if (!pnotes)
+  pnotes = (Elf_External_Note *) get_data (NULL, file, offset, 1, length,
+                                           _("notes"));
+  if (pnotes == NULL)
     return 0;
 
   external = pnotes;
@@ -10316,7 +11959,8 @@ process_corefile_note_segment (FILE * file, bfd_vma offset, bfd_vma length)
 
       next = (Elf_External_Note *) (inote.descdata + align_power (inote.descsz, 2));
 
-      if (((char *) next) > (((char *) pnotes) + length))
+      if (   ((char *) next > ((char *) pnotes) + length)
+         || ((char *) next <  (char *) pnotes))
        {
          warn (_("corrupt note found at offset %lx into core notes\n"),
                (unsigned long) ((char *) external - (char *) pnotes));
@@ -10327,13 +11971,24 @@ process_corefile_note_segment (FILE * file, bfd_vma offset, bfd_vma length)
 
       external = next;
 
+      /* Prevent out-of-bounds indexing.  */
+      if (inote.namedata + inote.namesz >= (char *) pnotes + length
+         || inote.namedata + inote.namesz < inote.namedata)
+        {
+          warn (_("corrupt note found at offset %lx into core notes\n"),
+                (unsigned long) ((char *) external - (char *) pnotes));
+          warn (_(" type: %lx, namesize: %08lx, descsize: %08lx\n"),
+                inote.type, inote.namesz, inote.descsz);
+          break;
+        }
+
       /* Verify that name is null terminated.  It appears that at least
         one version of Linux (RedHat 6.0) generates corefiles that don't
         comply with the ELF spec by failing to include the null byte in
         namesz.  */
       if (inote.namedata[inote.namesz] != '\0')
        {
-         temp = malloc (inote.namesz + 1);
+         temp = (char *) malloc (inote.namesz + 1);
 
          if (temp == NULL)
            {
@@ -10439,6 +12094,9 @@ process_arch_specific (FILE * file)
     case EM_PPC:
       return process_power_specific (file);
       break;
+    case EM_TI_C6000:
+      return process_tic6x_specific (file);
+      break;
     default:
       break;
     }
@@ -10592,7 +12250,7 @@ process_object (char * file_name, FILE * file)
       do_unwind = do_version = do_dump = do_arch = 0;
 
       if (! do_using_dynamic)
-       do_syms = do_reloc = 0;
+       do_syms = do_dyn_syms = do_reloc = 0;
     }
 
   if (! process_section_groups (file))
@@ -10708,7 +12366,7 @@ adjust_relative_path (char * file_name, char * name, int name_len)
      archive is located.  */
   if (IS_ABSOLUTE_PATH (name) || base_name == file_name)
     {
-      member_file_name = malloc (name_len + 1);
+      member_file_name = (char *) malloc (name_len + 1);
       if (member_file_name == NULL)
         {
           error (_("Out of memory\n"));
@@ -10722,7 +12380,7 @@ adjust_relative_path (char * file_name, char * name, int name_len)
       /* Concatenate the path components of the archive file name
          to the relative path name from the extended name table.  */
       size_t prefix_len = base_name - file_name;
-      member_file_name = malloc (prefix_len + name_len + 1);
+      member_file_name = (char *) malloc (prefix_len + name_len + 1);
       if (member_file_name == NULL)
         {
           error (_("Out of memory\n"));
@@ -10832,7 +12490,8 @@ setup_archive (struct archive_info * arch, char * file_name, FILE * file,
                     file_name, arch->index_num);
              return 1;
            }
-         index_buffer = malloc (arch->index_num * SIZEOF_AR_INDEX_NUMBERS);
+         index_buffer = (unsigned char *)
+              malloc (arch->index_num * SIZEOF_AR_INDEX_NUMBERS);
          if (index_buffer == NULL)
            {
              error (_("Out of memory whilst trying to read archive symbol index\n"));
@@ -10848,7 +12507,8 @@ setup_archive (struct archive_info * arch, char * file_name, FILE * file,
          size -= arch->index_num * SIZEOF_AR_INDEX_NUMBERS;
 
          /* Convert the index numbers into the host's numeric format.  */
-         arch->index_array = malloc (arch->index_num * sizeof (* arch->index_array));
+         arch->index_array = (long unsigned int *)
+              malloc (arch->index_num * sizeof (* arch->index_array));
          if (arch->index_array == NULL)
            {
              free (index_buffer);
@@ -10867,7 +12527,7 @@ setup_archive (struct archive_info * arch, char * file_name, FILE * file,
              error (_("%s: the archive has an index but no symbols\n"), file_name);
              return 1;
            }
-         arch->sym_table = malloc (size);
+         arch->sym_table = (char *) malloc (size);
          arch->sym_size = size;
          if (arch->sym_table == NULL)
            {
@@ -10909,7 +12569,7 @@ setup_archive (struct archive_info * arch, char * file_name, FILE * file,
       arch->longnames_size = strtoul (arch->arhdr.ar_size, NULL, 10);
       arch->next_arhdr_offset += sizeof arch->arhdr + arch->longnames_size;
 
-      arch->longnames = malloc (arch->longnames_size);
+      arch->longnames = (char *) malloc (arch->longnames_size);
       if (arch->longnames == NULL)
        {
          error (_("Out of memory reading long symbol names in archive\n"));
@@ -11028,7 +12688,8 @@ get_archive_member_name (struct archive_info *  arch,
 
   /* We have a normal (short) name.  */
   j = 0;
-  while ((arch->arhdr.ar_name[j] != '/') && (j < 16))
+  while ((arch->arhdr.ar_name[j] != '/')
+        && (j < sizeof (arch->arhdr.ar_name) - 1))
     j++;
   arch->arhdr.ar_name[j] = '\0';
   return arch->arhdr.ar_name;
@@ -11081,7 +12742,7 @@ make_qualified_name (struct archive_info * arch,
   if (arch->is_thin_archive && arch->nested_member_origin != 0)
     len += strlen (nested_arch->file_name) + 2;
 
-  name = malloc (len);
+  name = (char *) malloc (len);
   if (name == NULL)
     {
       error (_("Out of memory\n"));
@@ -11107,7 +12768,6 @@ process_archive (char * file_name, FILE * file, bfd_boolean is_thin_archive)
   struct archive_info arch;
   struct archive_info nested_arch;
   size_t got;
-  size_t file_name_size;
   int ret;
 
   show_name = 1;
@@ -11194,14 +12854,13 @@ process_archive (char * file_name, FILE * file, bfd_boolean is_thin_archive)
       if (!do_dynamic && !do_syms && !do_reloc && !do_unwind && !do_sections
          && !do_segments && !do_header && !do_dump && !do_version
          && !do_histogram && !do_debugging && !do_arch && !do_notes
-         && !do_section_groups)
+         && !do_section_groups && !do_dyn_syms)
        {
          ret = 0; /* Archive index only.  */
          goto out;
        }
     }
 
-  file_name_size = strlen (file_name);
   ret = 0;
 
   while (1)
@@ -11416,7 +13075,8 @@ main (int argc, char ** argv)
   if (num_dump_sects > 0)
     {
       /* Make a copy of the dump_sects array.  */
-      cmdline_dump_sects = malloc (num_dump_sects * sizeof (* dump_sects));
+      cmdline_dump_sects = (dump_type *)
+          malloc (num_dump_sects * sizeof (* dump_sects));
       if (cmdline_dump_sects == NULL)
        error (_("Out of memory allocating dump request table.\n"));
       else
This page took 0.095871 seconds and 4 git commands to generate.