]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blobdiff - binutils/readelf.c
merge from gcc
[thirdparty/binutils-gdb.git] / binutils / readelf.c
index f64dcb904fd79854b138aed777971089c292de21..1682e0a26ceb6af009b8bb6841f49c2b24e958fd 100644 (file)
 #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"
@@ -271,7 +272,8 @@ static void (* byte_put) (unsigned char *, bfd_vma, int);
 
 #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)        \
@@ -577,6 +579,17 @@ 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
@@ -635,6 +648,7 @@ 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:
@@ -721,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);
@@ -751,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
@@ -1119,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);
@@ -1249,7 +1267,7 @@ 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);
@@ -1372,9 +1390,7 @@ dump_relocations (FILE * file,
                               && 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
@@ -1395,12 +1411,12 @@ dump_relocations (FILE * file,
 
              if (is_rela)
                {
-                 long off = (long) (bfd_signed_vma) rels[i].r_addend;
+                 bfd_signed_vma off = rels[i].r_addend;
 
                  if (off < 0)
-                   printf (" - %lx", - off);
+                   printf (" - %" BFD_VMA_FMT "x", - off);
                  else
-                   printf (" + %lx", off);
+                   printf (" + %" BFD_VMA_FMT "x", off);
                }
            }
        }
@@ -1897,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";
@@ -2221,6 +2238,21 @@ get_machine_flags (unsigned e_flags, unsigned e_machine)
          decode_ARM_machine_flags (e_flags, buf);
          break;
 
+       case EM_BLACKFIN:
+         if (e_flags & EF_BFIN_PIC)
+           strcat (buf, ", PIC");
+
+         if (e_flags & EF_BFIN_FDPIC)
+           strcat (buf, ", FDPIC");
+
+         if (e_flags & EF_BFIN_CODE_IN_L1)
+           strcat (buf, ", code in L1");
+
+         if (e_flags & EF_BFIN_DATA_IN_L1)
+           strcat (buf, ", data in L1");
+
+         break;
+
        case EM_CYGNUS_FRV:
          switch (e_flags & EF_FRV_CPU_MASK)
            {
@@ -2294,6 +2326,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);
@@ -2312,6 +2351,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)
                {
@@ -2336,8 +2378,14 @@ get_machine_flags (unsigned e_flags, unsigned e_machine)
        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");
@@ -2394,6 +2442,7 @@ get_machine_flags (unsigned e_flags, unsigned e_machine)
            case E_MIPS_MACH_9000: strcat (buf, ", 9000"); break;
            case E_MIPS_MACH_LS2E: strcat (buf, ", loongson-2e"); break;
            case E_MIPS_MACH_LS2F: strcat (buf, ", loongson-2f"); break;
+           case E_MIPS_MACH_LS3A: strcat (buf, ", loongson-3a"); 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;
@@ -2553,6 +2602,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:
@@ -2568,7 +2638,7 @@ get_machine_flags (unsigned e_flags, unsigned e_machine)
          if (e_flags & E_FLAG_RX_64BIT_DOUBLES)
            strcat (buf, ", 64-bit doubles");
          if (e_flags & E_FLAG_RX_DSP)
-           strcat (buf, ", dsp");        
+           strcat (buf, ", dsp");
 
        case EM_S390:
          if (e_flags & EF_S390_HIGH_GPRS)
@@ -3789,7 +3859,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;
                }
 
@@ -3856,8 +3929,8 @@ process_program_headers (FILE * file)
 
          for (j = 1; j < elf_header.e_shnum; j++, section++)
            {
-             if (ELF_SECTION_SIZE (section, segment) != 0
-                 && ELF_SECTION_IN_SEGMENT (section, segment))
+             if (!ELF_TBSS_SPECIAL (section, segment)
+                 && ELF_SECTION_IN_SEGMENT_STRICT (section, segment))
                printf ("%s ", SECTION_NAME (section));
            }
 
@@ -3990,15 +4063,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;
 
+  /* 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)
+  if (esyms == NULL)
     return NULL;
 
   shndx = NULL;
@@ -4010,28 +4098,19 @@ get_32bit_elf_symbols (FILE * file, Elf_Internal_Shdr * section)
                                                    symtab_shndx_hdr->sh_offset,
                                                    1, symtab_shndx_hdr->sh_size,
                                                    _("symtab shndx"));
-      if (!shndx)
-       {
-         free (esyms);
-         return NULL;
-       }
+      if (shndx == NULL)
+       goto exit_point;
     }
 
-  number = section->sh_size / section->sh_entsize;
   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);
@@ -4046,9 +4125,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;
 }
@@ -4063,6 +4144,21 @@ get_64bit_elf_symbols (FILE * file, Elf_Internal_Shdr * section)
   Elf_Internal_Sym * psym;
   unsigned int j;
 
+  /* 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)
@@ -4084,7 +4180,6 @@ get_64bit_elf_symbols (FILE * file, Elf_Internal_Shdr * section)
        }
     }
 
-  number = section->sh_size / section->sh_entsize;
   isyms = (Elf_Internal_Sym *) cmalloc (number, sizeof (Elf_Internal_Sym));
 
   if (isyms == NULL)
@@ -4783,10 +4878,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;
 }
@@ -4909,6 +5013,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)
@@ -5038,6 +5148,187 @@ process_section_groups (FILE * file)
   return 1;
 }
 
+/* Data used to display dynamic fixups.  */
+
+struct ia64_vms_dynfixup
+{
+  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
+{
+  bfd_vma img_rela_cnt;                /* Number of relocations.  */
+  bfd_vma img_rela_off;                /* Reloc offset in the dynamic segment.  */
+};
+
+/* Display IA-64 OpenVMS dynamic fixups (used to dynamically link a shared
+   library).  */
+
+static void
+dump_ia64_vms_dynamic_fixups (FILE *file, struct ia64_vms_dynfixup *fixup,
+                              const char *strtab, unsigned int strtab_sz)
+{
+  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 (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"));
+
+  for (i = 0; i < (long) fixup->fixup_rela_cnt; i++)
+    {
+      unsigned int type;
+      const char *rtype;
+
+      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));
+    }
+
+  free (imfs);
+}
+
+/* Display IA-64 OpenVMS dynamic relocations (used to relocate an image).  */
+
+static void
+dump_ia64_vms_dynamic_relocs (FILE *file, struct ia64_vms_dynimgrela *imgrela)
+{
+  Elf64_External_VMS_IMAGE_RELA *imrs;
+  long i;
+
+  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;
+
+  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;
@@ -5109,6 +5400,9 @@ process_relocs (FILE * file)
            }
        }
 
+      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"));
     }
@@ -5435,15 +5729,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;
@@ -6200,7 +6494,6 @@ decode_arm_unwind (struct arm_unw_aux_info *aux,
     }
   else
     {
-      
       per_index = (word >> 24) & 0x7f;
       if (per_index != 0 && per_index != 1 && per_index != 2)
        {
@@ -6667,6 +6960,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)
 {
@@ -6679,6 +6995,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;
@@ -7470,6 +7826,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;
@@ -7490,6 +7850,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;
@@ -7506,6 +7871,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;
 
@@ -7523,11 +7893,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"));
 
@@ -7571,6 +7943,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;
@@ -7592,6 +7967,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)
@@ -7619,6 +7999,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;
                  }
@@ -7658,6 +8043,8 @@ 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;
 
@@ -7719,6 +8106,16 @@ process_version_sections (FILE * file)
                      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;
                      if (symbols[cnt + j].st_shndx >= elf_header.e_shnum
@@ -7972,6 +8369,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)
 {
@@ -7985,6 +8443,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;
     }
@@ -8361,9 +8823,17 @@ process_symbol_table (FILE * file)
                  && 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
@@ -8832,8 +9302,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:
@@ -8885,6 +9357,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:
@@ -8895,6 +9369,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.  */
@@ -8976,6 +9452,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:
@@ -9156,6 +9634,7 @@ is_none_reloc (unsigned int reloc_type)
     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:
@@ -9296,13 +9775,17 @@ apply_relocations (void * file,
          addend = 0;
          if (is_rela)
            addend += rp->r_addend;
-         /* R_XTENSA_32 and R_PJ_DATA_DIR32 are partial_inplace.  */
+         /* 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))
+                 && 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)
@@ -9358,7 +9841,7 @@ get_section_contents (Elf_Internal_Shdr * section, FILE * file)
                              _("section contents"));
 }
 
-                     
+
 static void
 dump_section_as_strings (Elf_Internal_Shdr * section, FILE * file)
 {
@@ -9520,16 +10003,13 @@ dump_section_as_bytes (Elf_Internal_Shdr * section,
   putchar ('\n');
 }
 
-/* Uncompresses a section that was compressed using zlib, in place.
-   This is a copy of bfd_uncompress_section_contents, in bfd/compress.c  */
+/* Uncompresses a section that was compressed using zlib, in place.  */
 
 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;
@@ -9589,6 +10069,8 @@ uncompress_section_contents (unsigned char ** buffer, dwarf_size_type * size)
 
  fail:
   free (uncompressed_buffer);
+  /* Indicate decompression failure.  */
+  *buffer = NULL;
   return 0;
 #endif  /* HAVE_ZLIB_H */
 }
@@ -9599,27 +10081,23 @@ load_specific_debug_section (enum dwarf_section_display_enum debug,
 {
   struct dwarf_section * section = &debug_displays [debug].section;
   char buf [64];
-  int section_is_compressed;
 
   /* If it is already loaded, do nothing.  */
   if (section->start != NULL)
     return 1;
 
-  section_is_compressed = section->name == section->compressed_name;
-
   snprintf (buf, sizeof (buf), _("%s section data"), section->name);
   section->address = sec->sh_addr;
   section->size = sec->sh_size;
   section->start = (unsigned char *) get_data (NULL, (FILE *) file,
                                                sec->sh_offset, 1,
                                                sec->sh_size, buf);
+  if (uncompress_section_contents (&section->start, &section->size))
+    sec->sh_size = section->size;
+
   if (section->start == NULL)
     return 0;
 
-  if (section_is_compressed)
-    if (! uncompress_section_contents (&section->start, &section->size))
-      return 0;
-
   if (debug_displays [debug].relocate)
     apply_relocations ((FILE *) file, sec, section->start);
 
@@ -9830,7 +10308,7 @@ static const char * arm_attr_tag_THUMB_ISA_use[] =
 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[] = 
+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",
@@ -9871,16 +10349,16 @@ 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[] = 
+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 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", 
+  {"Not Allowed", "TrustZone", "Virtualization Extensions",
     "TrustZone and Virtualization Extensions"};
-static const char * arm_attr_tag_MPextension_use_legacy[] = 
+static const char * arm_attr_tag_MPextension_use_legacy[] =
   {"Not Allowed", "Allowed"};
 
 #define LOOKUP(id, name) \
@@ -9985,7 +10463,7 @@ display_arm_attribute (unsigned char * p)
                case 3: printf ("??? 3\n"); break;
                default:
                  if (val <= 12)
-                   printf (_("8-byte and up to %d-byte extended\n"), 
+                   printf (_("8-byte and up to %d-byte extended\n"),
                            1 << val);
                  else
                    printf ("??? (%d)\n", val);
@@ -10004,7 +10482,7 @@ display_arm_attribute (unsigned char * p)
                case 3: printf ("??? 3\n"); break;
                default:
                  if (val <= 12)
-                   printf (_("8-byte and up to %d-byte extended\n"), 
+                   printf (_("8-byte and up to %d-byte extended\n"),
                            1 << val);
                  else
                    printf ("??? (%d)\n", val);
@@ -10266,7 +10744,7 @@ display_mips_gnu_attribute (unsigned char * p, int tag)
          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);
@@ -10296,6 +10774,240 @@ 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_wchar_t:
+      val = read_uleb128 (p, &len);
+      p += len;
+      printf ("  Tag_ABI_wchar_t: ");
+      switch (val)
+       {
+       case 0:
+         printf (_("Not used\n"));
+         break;
+       case 1:
+         printf (_("2 bytes\n"));
+         break;
+       case 2:
+         printf (_("4 bytes\n"));
+         break;
+       default:
+         printf ("??? (%d)\n", val);
+         break;
+       }
+      return p;
+
+    case Tag_ABI_stack_align_needed:
+      val = read_uleb128 (p, &len);
+      p += len;
+      printf ("  Tag_ABI_stack_align_needed: ");
+      switch (val)
+       {
+       case 0:
+         printf (_("8-byte\n"));
+         break;
+       case 1:
+         printf (_("16-byte\n"));
+         break;
+       default:
+         printf ("??? (%d)\n", val);
+         break;
+       }
+      return p;
+
+    case Tag_ABI_stack_align_preserved:
+      val = read_uleb128 (p, &len);
+      p += len;
+      printf ("  Tag_ABI_stack_align_preserved: ");
+      switch (val)
+       {
+       case 0:
+         printf (_("8-byte\n"));
+         break;
+       case 1:
+         printf (_("16-byte\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 Tag_ABI_PID:
+      val = read_uleb128 (p, &len);
+      p += len;
+      printf ("  Tag_ABI_PID: ");
+      switch (val)
+       {
+       case 0:
+         printf (_("Data addressing position-dependent\n"));
+         break;
+       case 1:
+         printf (_("Data addressing position-independent, GOT near DP\n"));
+         break;
+       case 2:
+         printf (_("Data addressing position-independent, GOT far from DP\n"));
+         break;
+       default:
+         printf ("??? (%d)\n", val);
+         break;
+       }
+      return p;
+
+    case Tag_ABI_PIC:
+      val = read_uleb128 (p, &len);
+      p += len;
+      printf ("  Tag_ABI_PIC: ");
+      switch (val)
+       {
+       case 0:
+         printf (_("Code addressing position-dependent\n"));
+         break;
+       case 1:
+         printf (_("Code addressing position-independent\n"));
+         break;
+       default:
+         printf ("??? (%d)\n", val);
+         break;
+       }
+      return p;
+
+    case Tag_ABI_array_object_alignment:
+      val = read_uleb128 (p, &len);
+      p += len;
+      printf ("  Tag_ABI_array_object_alignment: ");
+      switch (val)
+       {
+       case 0:
+         printf (_("8-byte\n"));
+         break;
+       case 1:
+         printf (_("4-byte\n"));
+         break;
+       case 2:
+         printf (_("16-byte\n"));
+         break;
+       default:
+         printf ("??? (%d)\n", val);
+         break;
+       }
+      return p;
+
+    case Tag_ABI_array_object_align_expected:
+      val = read_uleb128 (p, &len);
+      p += len;
+      printf ("  Tag_ABI_array_object_align_expected: ");
+      switch (val)
+       {
+       case 0:
+         printf (_("8-byte\n"));
+         break;
+       case 1:
+         printf (_("4-byte\n"));
+         break;
+       case 2:
+         printf (_("16-byte\n"));
+         break;
+       default:
+         printf ("??? (%d)\n", val);
+         break;
+       }
+      return p;
+
+    case Tag_ABI_compatibility:
+      val = read_uleb128 (p, &len);
+      p += len;
+      printf ("  Tag_ABI_compatibility: ");
+      printf (_("flag = %d, vendor = %s\n"), val, p);
+      p += strlen ((char *) p) + 1;
+      return p;
+
+    case Tag_ABI_conformance:
+      printf ("  Tag_ABI_conformance: ");
+      printf ("\"%s\"\n", p);
+      p += strlen ((char *) p) + 1;
+      return p;
+    }
+
+  printf ("  Tag_unknown_%d: ", tag);
+
+  if (tag & 1)
+    {
+      printf ("\"%s\"\n", p);
+      p += strlen ((char *) p) + 1;
+    }
+  else
+    {
+      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,
@@ -10452,6 +11164,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.  */
@@ -11375,7 +12094,7 @@ process_corefile_note_segment (FILE * file, bfd_vma offset, bfd_vma length)
 
   pnotes = (Elf_External_Note *) get_data (NULL, file, offset, 1, length,
                                            _("notes"));
-  if (!pnotes)
+  if (pnotes == NULL)
     return 0;
 
   external = pnotes;
@@ -11399,7 +12118,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));
@@ -11410,6 +12130,17 @@ 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
@@ -11522,6 +12253,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;
     }
@@ -12113,7 +12847,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;