Fix version.dll binutils test on non native platforms
[binutils-gdb.git] / binutils / readelf.c
index 7b9d102af734109005d04680cdba28a1f97111ef..b9b06a1d5f42f0b990f3bc57da0f93571c2b25e5 100644 (file)
 #include "elf/moxie.h"
 #include "elf/mt.h"
 #include "elf/msp430.h"
+#include "elf/nios2.h"
 #include "elf/or32.h"
 #include "elf/pj.h"
 #include "elf/ppc.h"
 #include "elf/xstormy16.h"
 #include "elf/xtensa.h"
 
-#include "elf/nios2.h"
-
 #include "getopt.h"
 #include "libiberty.h"
 #include "safe-ctype.h"
 #include "filenames.h"
 
+#ifndef offsetof
+#define offsetof(TYPE, MEMBER) ((size_t) &(((TYPE *) 0)->MEMBER))
+#endif
+
 char * program_name = "readelf";
 static long archive_file_offset;
 static unsigned long archive_file_size;
@@ -413,7 +416,7 @@ print_symbol (int width, const char *symbol)
       /* Keep the width positive.  This also helps.  */
       width = - width;
       extra_padding = TRUE;
-    }  
+    }
 
   if (do_wide)
     /* Set the remaining width to a very large value.
@@ -539,10 +542,12 @@ find_section_in_set (const char * name, unsigned int * set)
 /* 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)
+static inline unsigned long
+read_uleb128 (unsigned char *data,
+             unsigned int *length_return,
+             const unsigned char * const end)
 {
-  return read_leb128 (data, length_return, 0);
+  return read_leb128 (data, length_return, FALSE, end);
 }
 
 /* Return true if the current file is for IA-64 machine and OpenVMS ABI.
@@ -897,6 +902,17 @@ get_reloc_symindex (bfd_vma reloc_info)
   return is_32bit_elf ? ELF32_R_SYM (reloc_info) : ELF64_R_SYM (reloc_info);
 }
 
+static inline bfd_boolean
+uses_msp430x_relocs (void)
+{
+  return
+    elf_header.e_machine == EM_MSP430 /* Paranoia.  */
+    /* GCC uses osabi == ELFOSBI_STANDALONE.  */
+    && (((elf_header.e_flags & EF_MSP430_MACH) == E_MSP430_MACH_MSP430X)
+       /* TI compiler uses ELFOSABI_NONE.  */
+       || (elf_header.e_ident[EI_OSABI] == ELFOSABI_NONE));
+}
+
 /* Display the contents of the relocation data found at the specified
    offset.  */
 
@@ -1119,6 +1135,11 @@ dump_relocations (FILE * file,
          break;
 
        case EM_MSP430:
+         if (uses_msp430x_relocs ())
+           {
+             rtype = elf_msp430x_reloc_type (type);
+             break;
+           }
        case EM_MSP430_OLD:
          rtype = elf_msp430_reloc_type (type);
          break;
@@ -1554,7 +1575,7 @@ get_ppc_dynamic_type (unsigned long type)
   switch (type)
     {
     case DT_PPC_GOT:    return "PPC_GOT";
-    case DT_PPC_TLSOPT: return "PPC_TLSOPT";
+    case DT_PPC_OPT:    return "PPC_OPT";
     default:
       return NULL;
     }
@@ -1568,7 +1589,7 @@ get_ppc64_dynamic_type (unsigned long 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_TLSOPT: return "PPC64_TLSOPT";
+    case DT_PPC64_OPT:    return "PPC64_OPT";
     default:
       return NULL;
     }
@@ -2440,10 +2461,20 @@ get_machine_flags (unsigned e_flags, unsigned e_machine)
            strcat (buf, _(", relocatable-lib"));
          break;
 
+       case EM_PPC64:
+         if (e_flags & EF_PPC64_ABI)
+           {
+             char abi[] = ", abiv0";
+
+             abi[6] += e_flags & EF_PPC64_ABI;
+             strcat (buf, abi);
+           }
+         break;
+
        case EM_V800:
          if ((e_flags & EF_RH850_ABI) == EF_RH850_ABI)
            strcat (buf, ", RH850 ABI");
-           
+
          if (e_flags & EF_V800_850E3)
            strcat (buf, ", V3 architecture");
 
@@ -2547,6 +2578,12 @@ get_machine_flags (unsigned e_flags, unsigned e_machine)
          if (e_flags & EF_MIPS_32BITMODE)
            strcat (buf, ", 32bitmode");
 
+         if (e_flags & EF_MIPS_NAN2008)
+           strcat (buf, ", nan2008");
+
+         if (e_flags & EF_MIPS_FP64)
+           strcat (buf, ", fp64");
+
          switch ((e_flags & EF_MIPS_MACH))
            {
            case E_MIPS_MACH_3900: strcat (buf, ", 3900"); break;
@@ -2755,13 +2792,18 @@ get_machine_flags (unsigned e_flags, unsigned e_machine)
            strcat (buf, ", G-Float");
          break;
 
+       case EM_RL78:
+         if (e_flags & E_FLAG_RL78_G10)
+           strcat (buf, ", G10");
+         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");
          if (e_flags & E_FLAG_RX_PID)
-           strcat (buf, ", pid");        
+           strcat (buf, ", pid");
          if (e_flags & E_FLAG_RX_ABI)
            strcat (buf, ", RX ABI");
          break;
@@ -2775,6 +2817,32 @@ get_machine_flags (unsigned e_flags, unsigned e_machine)
          if ((e_flags & EF_C6000_REL))
            strcat (buf, ", relocatable module");
          break;
+
+       case EM_MSP430:
+         strcat (buf, _(": architecture variant: "));
+         switch (e_flags & EF_MSP430_MACH)
+           {
+           case E_MSP430_MACH_MSP430x11: strcat (buf, "MSP430x11"); break;
+           case E_MSP430_MACH_MSP430x11x1 : strcat (buf, "MSP430x11x1 "); break;
+           case E_MSP430_MACH_MSP430x12: strcat (buf, "MSP430x12"); break;
+           case E_MSP430_MACH_MSP430x13: strcat (buf, "MSP430x13"); break;
+           case E_MSP430_MACH_MSP430x14: strcat (buf, "MSP430x14"); break;
+           case E_MSP430_MACH_MSP430x15: strcat (buf, "MSP430x15"); break;
+           case E_MSP430_MACH_MSP430x16: strcat (buf, "MSP430x16"); break;
+           case E_MSP430_MACH_MSP430x31: strcat (buf, "MSP430x31"); break;
+           case E_MSP430_MACH_MSP430x32: strcat (buf, "MSP430x32"); break;
+           case E_MSP430_MACH_MSP430x33: strcat (buf, "MSP430x33"); break;
+           case E_MSP430_MACH_MSP430x41: strcat (buf, "MSP430x41"); break;
+           case E_MSP430_MACH_MSP430x42: strcat (buf, "MSP430x42"); break;
+           case E_MSP430_MACH_MSP430x43: strcat (buf, "MSP430x43"); break;
+           case E_MSP430_MACH_MSP430x44: strcat (buf, "MSP430x44"); break;
+           case E_MSP430_MACH_MSP430X  : strcat (buf, "MSP430X"); break;
+           default:
+             strcat (buf, _(": unknown")); break;
+           }
+
+         if (e_flags & ~ EF_MSP430_MACH)
+           strcat (buf, _(": unknown extra flag bits also present"));
        }
     }
 
@@ -3199,6 +3267,18 @@ get_tic6x_section_type_name (unsigned int sh_type)
   return NULL;
 }
 
+static const char *
+get_msp430x_section_type_name (unsigned int sh_type)
+{
+  switch (sh_type)
+    {
+    case SHT_MSP430_SEC_FLAGS:   return "MSP430_SEC_FLAGS";
+    case SHT_MSP430_SYM_ALIASES: return "MSP430_SYM_ALIASES";
+    case SHT_MSP430_ATTRIBUTES:  return "MSP430_ATTRIBUTES";
+    default: return NULL;
+    }
+}
+
 static const char *
 get_section_type_name (unsigned int sh_type)
 {
@@ -3264,6 +3344,9 @@ get_section_type_name (unsigned int sh_type)
            case EM_TI_C6000:
              result = get_tic6x_section_type_name (sh_type);
              break;
+           case EM_MSP430:
+             result = get_msp430x_section_type_name (sh_type);
+             break;
            default:
              result = NULL;
              break;
@@ -4754,7 +4837,7 @@ process_section_headers (FILE * file)
       bfd_size_type expected_entsize = is_32bit_elf ? size32 : size64;     \
       if (section->sh_entsize != expected_entsize)                         \
        {                                                               \
-         error (_("Section %d has invalid an sh_entsize of %" BFD_VMA_FMT "x\n"), \
+         error (_("Section %d has invalid sh_entsize of %" BFD_VMA_FMT "x\n"), \
                 i, section->sh_entsize);       \
          error (_("(Using the expected size of %d for the rest of this dump)\n"), \
                   (int) expected_entsize); \
@@ -4832,9 +4915,12 @@ process_section_headers (FILE * file)
              || (do_debug_info     && const_strneq (name, "info"))
              || (do_debug_info     && const_strneq (name, "types"))
              || (do_debug_abbrevs  && const_strneq (name, "abbrev"))
-             || (do_debug_lines    && const_strneq (name, "line"))
+             || (do_debug_lines    && strcmp (name, "line") == 0)
+             || (do_debug_lines    && const_strneq (name, "line."))
              || (do_debug_pubnames && const_strneq (name, "pubnames"))
              || (do_debug_pubtypes && const_strneq (name, "pubtypes"))
+             || (do_debug_pubnames && const_strneq (name, "gnu_pubnames"))
+             || (do_debug_pubtypes && const_strneq (name, "gnu_pubtypes"))
              || (do_debug_aranges  && const_strneq (name, "aranges"))
              || (do_debug_ranges   && const_strneq (name, "ranges"))
              || (do_debug_frames   && const_strneq (name, "frame"))
@@ -4935,10 +5021,10 @@ process_section_headers (FILE * file)
        {
          print_symbol (-17, SECTION_NAME (section));
        }
-      
+
       printf (do_wide ? " %-15s " : " %-15.15s ",
              get_section_type_name (section->sh_type));
-      
+
       if (is_32bit_elf)
        {
          const char * link_too_big = NULL;
@@ -5106,7 +5192,7 @@ process_section_headers (FILE * file)
   W (write), A (alloc), X (execute), M (merge), S (strings)\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;
 }
@@ -6557,7 +6643,10 @@ get_unwind_section_word (struct arm_unw_aux_info *  aux,
           ++relsec)
        {
          if (relsec->sh_info >= elf_header.e_shnum
-             || section_headers + relsec->sh_info != sec)
+             || section_headers + relsec->sh_info != sec
+             /* PR 15745: Check the section type as well.  */
+             || (relsec->sh_type != SHT_REL
+                 && relsec->sh_type != SHT_RELA))
            continue;
 
          arm_sec->rel_type = relsec->sh_type;
@@ -6567,19 +6656,15 @@ get_unwind_section_word (struct arm_unw_aux_info *  aux,
                                     relsec->sh_size,
                                     & arm_sec->rela, & arm_sec->nrelas))
                return FALSE;
-             break;
            }
-         else if (relsec->sh_type == SHT_RELA)
+         else /* relsec->sh_type == SHT_RELA */
            {
              if (!slurp_rela_relocs (aux->file, relsec->sh_offset,
                                      relsec->sh_size,
                                      & arm_sec->rela, & arm_sec->nrelas))
                return FALSE;
-             break;
            }
-         else
-           warn (_("unexpected relocation type (%d) for section %d"),
-                 relsec->sh_type, relsec->sh_info);
+         break;
        }
 
       arm_sec->next_rela = arm_sec->rela;
@@ -6639,7 +6724,7 @@ get_unwind_section_word (struct arm_unw_aux_info *  aux,
 
          if (streq (relname, "R_ARM_NONE"))
              continue;
-         
+
          if (! streq (relname, "R_ARM_PREL31"))
            {
              warn (_("Skipping unexpected relocation type %s\n"), relname);
@@ -6649,7 +6734,7 @@ get_unwind_section_word (struct arm_unw_aux_info *  aux,
       else if (elf_header.e_machine == EM_TI_C6000)
        {
          relname = elf_tic6x_reloc_type (ELF32_R_TYPE (rp->r_info));
-         
+
          if (streq (relname, "R_C6000_NONE"))
            continue;
 
@@ -6681,8 +6766,8 @@ get_unwind_section_word (struct arm_unw_aux_info *  aux,
 
 static const char *tic6x_unwind_regnames[16] =
 {
-  "A15", "B15", "B14", "B13", "B12", "B11", "B10", "B3", 
-  "A14", "A13", "A12", "A11", "A10", 
+  "A15", "B15", "B14", "B13", "B12", "B11", "B10", "B3",
+  "A14", "A13", "A12", "A11", "A10",
   "[invalid reg 13]", "[invalid reg 14]", "[invalid reg 15]"
 };
 
@@ -6856,7 +6941,7 @@ decode_arm_unwind_bytecode (struct arm_unw_aux_info *aux,
                break;
            }
          assert (i < sizeof (buf));
-         offset = read_uleb128 (buf, &len);
+         offset = read_uleb128 (buf, &len, buf + i + 1);
          assert (len == i + 1);
          offset = offset * 4 + 0x204;
          printf ("vsp = vsp + %ld", offset);
@@ -7052,7 +7137,7 @@ decode_tic6x_unwind_bytecode (struct arm_unw_aux_info *aux,
                break;
            }
          assert (i < sizeof (buf));
-         offset = read_uleb128 (buf, &len);
+         offset = read_uleb128 (buf, &len, buf + i + 1);
          assert (len == i + 1);
          offset = offset * 8 + 0x408;
          printf (_("sp = sp + %ld"), offset);
@@ -7167,9 +7252,9 @@ decode_arm_unwind (struct arm_unw_aux_info *  aux,
   else
     {
       /* ARM EHABI Section 6.3:
-        
+
         An exception-handling table entry for the compact model looks like:
-        
+
            31 30-28 27-24 23-0
           -- ----- ----- ----
             1   0   index Data for personalityRoutine[index]    */
@@ -7353,7 +7438,7 @@ arm_process_unwind (FILE *file)
       sec_type = SHT_C6000_UNWIND;
       break;
 
-    default: 
+    default:
       error (_("Unsupported architecture type %d encountered when processing unwind table"),
             elf_header.e_machine);
       return;
@@ -7425,7 +7510,10 @@ process_unwind (FILE * file)
 
   for (i = 0; handlers[i].handler != NULL; i++)
     if (elf_header.e_machine == handlers[i].machtype)
-      return handlers[i].handler (file);
+      {
+       handlers[i].handler (file);
+       return;
+      }
 
   printf (_("\nThe decoding of unwind sections for machine type %s is not currently supported.\n"),
          get_machine_name (elf_header.e_machine));
@@ -8813,7 +8901,7 @@ process_version_sections (FILE * file)
                              if (get_data (&evn, file, offset, sizeof (evn), 1,
                                            _("version need")) == NULL)
                                break;
-                             
+
                              ivn.vn_aux  = BYTE_GET (evn.vn_aux);
                              ivn.vn_next = BYTE_GET (evn.vn_next);
 
@@ -8987,8 +9075,13 @@ get_symbol_type (unsigned int type)
     default:
       if (type >= STT_LOPROC && type <= STT_HIPROC)
        {
-         if (elf_header.e_machine == EM_ARM && type == STT_ARM_TFUNC)
-           return "THUMB_FUNC";
+         if (elf_header.e_machine == EM_ARM)
+           {
+             if (type == STT_ARM_TFUNC)
+               return "THUMB_FUNC";
+             if (type == STT_ARM_16BIT)
+               return "THUMB_LABEL";
+           }
 
          if (elf_header.e_machine == EM_SPARCV9 && type == STT_REGISTER)
            return "REGISTER";
@@ -9119,6 +9212,19 @@ get_ia64_symbol_other (unsigned int other)
   return NULL;
 }
 
+static const char *
+get_ppc64_symbol_other (unsigned int other)
+{
+  if (PPC64_LOCAL_ENTRY_OFFSET (other) != 0)
+    {
+      static char buf[32];
+      snprintf (buf, sizeof buf, _("<localentry>: %d"),
+               PPC64_LOCAL_ENTRY_OFFSET (other));
+      return buf;
+    }
+  return NULL;
+}
+
 static const char *
 get_symbol_other (unsigned int other)
 {
@@ -9136,6 +9242,9 @@ get_symbol_other (unsigned int other)
     case EM_IA_64:
       result = get_ia64_symbol_other (other);
       break;
+    case EM_PPC64:
+      result = get_ppc64_symbol_other (other);
+      break;
     default:
       break;
     }
@@ -9238,7 +9347,7 @@ print_dynamic_symbol (bfd_vma si, unsigned long hn)
 
   n = print_vma (si, DEC_5);
   if (n < 5)
-    fputs ("     " + n, stdout);
+    fputs (&"     "[n], stdout);
   printf (" %3lu: ", hn);
   print_vma (psym->st_value, LONG_HEX);
   putchar (' ');
@@ -9777,6 +9886,7 @@ process_symbol_table (FILE * file)
       counts = (unsigned long *) calloc (maxlength + 1, sizeof (*counts));
       if (counts == NULL)
        {
+         free (lengths);
          error (_("Out of memory\n"));
          return 0;
        }
@@ -9845,6 +9955,7 @@ process_symbol_table (FILE * file)
       counts = (unsigned long *) calloc (maxlength + 1, sizeof (*counts));
       if (counts == NULL)
        {
+         free (lengths);
          error (_("Out of memory\n"));
          return 0;
        }
@@ -9954,6 +10065,60 @@ target_specific_reloc_handling (Elf_Internal_Rela * reloc,
 
   switch (elf_header.e_machine)
     {
+    case EM_MSP430:
+    case EM_MSP430_OLD:
+      {
+       static Elf_Internal_Sym * saved_sym = NULL;
+
+       switch (reloc_type)
+         {
+         case 10: /* R_MSP430_SYM_DIFF */
+           if (uses_msp430x_relocs ())
+             break;
+         case 21: /* R_MSP430X_SYM_DIFF */
+           saved_sym = symtab + get_reloc_symindex (reloc->r_info);
+           return TRUE;
+
+         case 1: /* R_MSP430_32 or R_MSP430_ABS32 */
+         case 3: /* R_MSP430_16 or R_MSP430_ABS8 */
+           goto handle_sym_diff;
+
+         case 5: /* R_MSP430_16_BYTE */
+         case 9: /* R_MSP430_8 */
+           if (uses_msp430x_relocs ())
+             break;
+           goto handle_sym_diff;
+
+         case 2: /* R_MSP430_ABS16 */
+         case 15: /* R_MSP430X_ABS16 */
+           if (! uses_msp430x_relocs ())
+             break;
+           goto handle_sym_diff;
+
+         handle_sym_diff:
+           if (saved_sym != NULL)
+             {
+               bfd_vma value;
+
+               value = reloc->r_addend
+                 + (symtab[get_reloc_symindex (reloc->r_info)].st_value
+                    - saved_sym->st_value);
+
+               byte_put (start + reloc->r_offset, value, reloc_type == 1 ? 4 : 2);
+
+               saved_sym = NULL;
+               return TRUE;
+             }
+           break;
+
+         default:
+           if (saved_sym != NULL)
+             error (_("Unhandled MSP430 reloc type found after SYM_DIFF reloc"));
+           break;
+         }
+       break;
+      }
+
     case EM_MN10300:
     case EM_CYGNUS_MN10300:
       {
@@ -10093,7 +10258,7 @@ is_32bit_abs_reloc (unsigned int reloc_type)
       return reloc_type == 1; /* R_MOXIE_32.  */
     case EM_MSP430_OLD:
     case EM_MSP430:
-      return reloc_type == 1; /* R_MSP43_32.  */
+      return reloc_type == 1; /* R_MSP430_32 or R_MSP320_ABS32.  */
     case EM_MT:
       return reloc_type == 2; /* R_MT_32.  */
     case EM_ALTERA_NIOS2:
@@ -10345,6 +10510,8 @@ is_16bit_abs_reloc (unsigned int reloc_type)
     case EM_M32C:
       return reloc_type == 1; /* R_M32C_16 */
     case EM_MSP430:
+      if (uses_msp430x_relocs ())
+       return reloc_type == 2; /* R_MSP430_ABS16.  */
     case EM_MSP430_OLD:
       return reloc_type == 5; /* R_MSP430_16_BYTE.  */
     case EM_ALTERA_NIOS2:
@@ -10513,7 +10680,7 @@ apply_relocations (void * file,
            }
 
          rloc = start + rp->r_offset;
-         if ((rloc + reloc_size) > end)
+         if ((rloc + reloc_size) > end || (rloc < start))
            {
              warn (_("skipping invalid relocation offset 0x%lx in section %s\n"),
                    (unsigned long) rp->r_offset,
@@ -10966,6 +11133,7 @@ display_debug_section (int shndx, Elf_Internal_Shdr * section, FILE * file)
   /* See if we know how to display the contents of this section.  */
   for (i = 0; i < max; i++)
     if (streq (debug_displays[i].section.uncompressed_name, name)
+       || (i == line && const_strneq (name, ".debug_line."))
         || streq (debug_displays[i].section.compressed_name, name))
       {
        struct dwarf_section * sec = &debug_displays [i].section;
@@ -10974,7 +11142,9 @@ display_debug_section (int shndx, Elf_Internal_Shdr * section, FILE * file)
        if (secondary)
          free_debug_section ((enum dwarf_section_display_enum) i);
 
-       if (streq (sec->uncompressed_name, name))
+       if (i == line && const_strneq (name, ".debug_line."))
+         sec->name = name;
+       else if (streq (sec->uncompressed_name, name))
          sec->name = sec->uncompressed_name;
        else
          sec->name = sec->compressed_name;
@@ -11091,6 +11261,52 @@ process_mips_fpe_exception (int mask)
     fputs ("0", stdout);
 }
 
+/* Display's the value of TAG at location P.  If TAG is
+   greater than 0 it is assumed to be an unknown tag, and
+   a message is printed to this effect.  Otherwise it is
+   assumed that a message has already been printed.
+
+   If the bottom bit of TAG is set it assumed to have a
+   string value, otherwise it is assumed to have an integer
+   value.
+
+   Returns an updated P pointing to the first unread byte
+   beyond the end of TAG's value.
+
+   Reads at or beyond END will not be made.  */
+
+static unsigned char *
+display_tag_value (int tag,
+                  unsigned char * p,
+                  const unsigned char * const end)
+{
+  unsigned long val;
+
+  if (tag > 0)
+    printf ("  Tag_unknown_%d: ", tag);
+
+  if (p >= end)
+    {
+      warn (_("corrupt tag\n"));
+    }
+  else if (tag & 1)
+    {
+      /* FIXME: we could read beyond END here.  */
+      printf ("\"%s\"\n", p);
+      p += strlen ((char *) p) + 1;
+    }
+  else
+    {
+      unsigned int len;
+
+      val = read_uleb128 (p, &len, end);
+      p += len;
+      printf ("%ld (0x%lx)\n", val, val);
+    }
+
+  return p;
+}
+
 /* ARM EABI attributes section.  */
 typedef struct
 {
@@ -11212,7 +11428,8 @@ static arm_attr_public_tag arm_attr_public_tags[] =
 #undef LOOKUP
 
 static unsigned char *
-display_arm_attribute (unsigned char * p)
+display_arm_attribute (unsigned char * p,
+                      const unsigned char * const end)
 {
   int tag;
   unsigned int len;
@@ -11221,7 +11438,7 @@ display_arm_attribute (unsigned char * p)
   unsigned i;
   int type;
 
-  tag = read_uleb128 (p, &len);
+  tag = read_uleb128 (p, &len, end);
   p += len;
   attr = NULL;
   for (i = 0; i < ARRAY_SIZE (arm_attr_public_tags); i++)
@@ -11242,7 +11459,7 @@ display_arm_attribute (unsigned char * p)
          switch (tag)
            {
            case 7: /* Tag_CPU_arch_profile.  */
-             val = read_uleb128 (p, &len);
+             val = read_uleb128 (p, &len, end);
              p += len;
              switch (val)
                {
@@ -11256,7 +11473,7 @@ display_arm_attribute (unsigned char * p)
              break;
 
            case 24: /* Tag_align_needed.  */
-             val = read_uleb128 (p, &len);
+             val = read_uleb128 (p, &len, end);
              p += len;
              switch (val)
                {
@@ -11275,7 +11492,7 @@ display_arm_attribute (unsigned char * p)
              break;
 
            case 25: /* Tag_align_preserved.  */
-             val = read_uleb128 (p, &len);
+             val = read_uleb128 (p, &len, end);
              p += len;
              switch (val)
                {
@@ -11294,7 +11511,7 @@ display_arm_attribute (unsigned char * p)
              break;
 
            case 32: /* Tag_compatibility.  */
-             val = read_uleb128 (p, &len);
+             val = read_uleb128 (p, &len, end);
              p += len;
              printf (_("flag = %d, vendor = %s\n"), val, p);
              p += strlen ((char *) p) + 1;
@@ -11306,11 +11523,11 @@ display_arm_attribute (unsigned char * p)
              break;
 
            case 65: /* Tag_also_compatible_with.  */
-             val = read_uleb128 (p, &len);
+             val = read_uleb128 (p, &len, end);
              p += len;
              if (val == 6 /* Tag_CPU_arch.  */)
                {
-                 val = read_uleb128 (p, &len);
+                 val = read_uleb128 (p, &len, end);
                  p += len;
                  if ((unsigned int)val >= ARRAY_SIZE (arm_attr_tag_CPU_arch))
                    printf ("??? (%d)\n", val);
@@ -11328,13 +11545,13 @@ display_arm_attribute (unsigned char * p)
          return p;
 
        case 1:
+         return display_tag_value (-1, p, end);
        case 2:
-         type = attr->type;
-         break;
+         return display_tag_value (0, p, end);
 
        default:
          assert (attr->type & 0x80);
-         val = read_uleb128 (p, &len);
+         val = read_uleb128 (p, &len, end);
          p += len;
          type = attr->type & 0x7f;
          if (val >= type)
@@ -11344,87 +11561,58 @@ display_arm_attribute (unsigned char * p)
          return p;
        }
     }
-  else
-    {
-      if (tag & 1)
-       type = 1; /* String.  */
-      else
-       type = 2; /* uleb128.  */
-      printf ("  Tag_unknown_%d: ", tag);
-    }
-
-  if (type == 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;
+  return display_tag_value (tag, p, end);
 }
 
 static unsigned char *
 display_gnu_attribute (unsigned char * p,
-                      unsigned char * (* display_proc_gnu_attribute) (unsigned char *, int))
+                      unsigned char * (* display_proc_gnu_attribute) (unsigned char *, int, const unsigned char * const),
+                      const unsigned char * const end)
 {
   int tag;
   unsigned int len;
   int val;
-  int type;
 
-  tag = read_uleb128 (p, &len);
+  tag = read_uleb128 (p, &len, end);
   p += len;
 
   /* Tag_compatibility is the only generic GNU attribute defined at
      present.  */
   if (tag == 32)
     {
-      val = read_uleb128 (p, &len);
+      val = read_uleb128 (p, &len, end);
       p += len;
-      printf (_("flag = %d, vendor = %s\n"), val, p);
-      p += strlen ((char *) p) + 1;
+      if (p == end)
+       {
+         printf (_("flag = %d, vendor = <corrupt>\n"), val);
+         warn (_("corrupt vendor attribute\n"));
+       }
+      else
+       {
+         printf (_("flag = %d, vendor = %s\n"), val, p);
+         p += strlen ((char *) p) + 1;
+       }
       return p;
     }
 
   if ((tag & 2) == 0 && display_proc_gnu_attribute)
-    return display_proc_gnu_attribute (p, tag);
-
-  if (tag & 1)
-    type = 1; /* String.  */
-  else
-    type = 2; /* uleb128.  */
-  printf ("  Tag_unknown_%d: ", tag);
-
-  if (type == 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 display_proc_gnu_attribute (p, tag, end);
 
-  return p;
+  return display_tag_value (tag, p, end);
 }
 
 static unsigned char *
-display_power_gnu_attribute (unsigned char * p, int tag)
+display_power_gnu_attribute (unsigned char * p,
+                            int tag,
+                            const unsigned char * const end)
 {
-  int type;
   unsigned int len;
   int val;
 
   if (tag == Tag_GNU_Power_ABI_FP)
     {
-      val = read_uleb128 (p, &len);
+      val = read_uleb128 (p, &len, end);
       p += len;
       printf ("  Tag_GNU_Power_ABI_FP: ");
 
@@ -11451,7 +11639,7 @@ display_power_gnu_attribute (unsigned char * p, int tag)
 
   if (tag == Tag_GNU_Power_ABI_Vector)
     {
-      val = read_uleb128 (p, &len);
+      val = read_uleb128 (p, &len, end);
       p += len;
       printf ("  Tag_GNU_Power_ABI_Vector: ");
       switch (val)
@@ -11477,7 +11665,13 @@ display_power_gnu_attribute (unsigned char * p, int tag)
 
   if (tag == Tag_GNU_Power_ABI_Struct_Return)
     {
-      val = read_uleb128 (p, &len);
+      if (p == end)
+       {
+         warn (_("corrupt Tag_GNU_Power_ABI_Struct_Return"));
+         return p;
+       }
+
+      val = read_uleb128 (p, &len, end);
       p += len;
       printf ("  Tag_GNU_Power_ABI_Struct_Return: ");
       switch (val)
@@ -11498,25 +11692,7 @@ display_power_gnu_attribute (unsigned char * p, int tag)
       return p;
     }
 
-  if (tag & 1)
-    type = 1; /* String.  */
-  else
-    type = 2; /* uleb128.  */
-  printf ("  Tag_unknown_%d: ", tag);
-
-  if (type == 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;
+  return display_tag_value (tag & 1, p, end);
 }
 
 static void
@@ -11564,71 +11740,54 @@ display_sparc_hwcaps (int mask)
 }
 
 static unsigned char *
-display_sparc_gnu_attribute (unsigned char * p, int tag)
+display_sparc_gnu_attribute (unsigned char * p,
+                            int tag,
+                            const unsigned char * const end)
 {
-  int type;
-  unsigned int len;
-  int val;
-
   if (tag == Tag_GNU_Sparc_HWCAPS)
     {
-      val = read_uleb128 (p, &len);
+      unsigned int len;
+      int val;
+
+      val = read_uleb128 (p, &len, end);
       p += len;
       printf ("  Tag_GNU_Sparc_HWCAPS: ");
-
       display_sparc_hwcaps (val);
       return p;
    }
 
-  if (tag & 1)
-    type = 1; /* String.  */
-  else
-    type = 2; /* uleb128.  */
-  printf ("  Tag_unknown_%d: ", tag);
-
-  if (type == 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;
+  return display_tag_value (tag, p, end);
 }
 
 static unsigned char *
-display_mips_gnu_attribute (unsigned char * p, int tag)
+display_mips_gnu_attribute (unsigned char * p,
+                           int tag,
+                           const unsigned char * const end)
 {
-  int type;
-  unsigned int len;
-  int val;
-
   if (tag == Tag_GNU_MIPS_ABI_FP)
     {
-      val = read_uleb128 (p, &len);
+      unsigned int len;
+      int val;
+
+      val = read_uleb128 (p, &len, end);
       p += len;
       printf ("  Tag_GNU_MIPS_ABI_FP: ");
 
       switch (val)
        {
-       case 0:
+       case Val_GNU_MIPS_ABI_FP_ANY:
          printf (_("Hard or soft float\n"));
          break;
-       case 1:
+       case Val_GNU_MIPS_ABI_FP_DOUBLE:
          printf (_("Hard float (double precision)\n"));
          break;
-       case 2:
+       case Val_GNU_MIPS_ABI_FP_SINGLE:
          printf (_("Hard float (single precision)\n"));
          break;
-       case 3:
+       case Val_GNU_MIPS_ABI_FP_SOFT:
          printf (_("Soft float\n"));
          break;
-       case 4:
+       case Val_GNU_MIPS_ABI_FP_64:
          printf (_("Hard float (MIPS32r2 64-bit FPU)\n"));
          break;
        default:
@@ -11638,41 +11797,48 @@ display_mips_gnu_attribute (unsigned char * p, int tag)
       return p;
    }
 
-  if (tag & 1)
-    type = 1; /* String.  */
-  else
-    type = 2; /* uleb128.  */
-  printf ("  Tag_unknown_%d: ", tag);
-
-  if (type == 1)
-    {
-      printf ("\"%s\"\n", p);
-      p += strlen ((char *) p) + 1;
-    }
-  else
+  if (tag == Tag_GNU_MIPS_ABI_MSA)
     {
-      val = read_uleb128 (p, &len);
+      unsigned int len;
+      int val;
+
+      val = read_uleb128 (p, &len, end);
       p += len;
-      printf ("%d (0x%x)\n", val, val);
+      printf ("  Tag_GNU_MIPS_ABI_MSA: ");
+
+      switch (val)
+       {
+       case Val_GNU_MIPS_ABI_MSA_ANY:
+         printf (_("Any MSA or not\n"));
+         break;
+       case Val_GNU_MIPS_ABI_MSA_128:
+         printf (_("128-bit MSA\n"));
+         break;
+       default:
+         printf ("??? (%d)\n", val);
+         break;
+       }
+      return p;
     }
 
-  return p;
+  return display_tag_value (tag & 1, p, end);
 }
 
 static unsigned char *
-display_tic6x_attribute (unsigned char * p)
+display_tic6x_attribute (unsigned char * p,
+                        const unsigned char * const end)
 {
   int tag;
   unsigned int len;
   int val;
 
-  tag = read_uleb128 (p, &len);
+  tag = read_uleb128 (p, &len, end);
   p += len;
 
   switch (tag)
     {
     case Tag_ISA:
-      val = read_uleb128 (p, &len);
+      val = read_uleb128 (p, &len, end);
       p += len;
       printf ("  Tag_ISA: ");
 
@@ -11706,7 +11872,7 @@ display_tic6x_attribute (unsigned char * p)
       return p;
 
     case Tag_ABI_wchar_t:
-      val = read_uleb128 (p, &len);
+      val = read_uleb128 (p, &len, end);
       p += len;
       printf ("  Tag_ABI_wchar_t: ");
       switch (val)
@@ -11727,7 +11893,7 @@ display_tic6x_attribute (unsigned char * p)
       return p;
 
     case Tag_ABI_stack_align_needed:
-      val = read_uleb128 (p, &len);
+      val = read_uleb128 (p, &len, end);
       p += len;
       printf ("  Tag_ABI_stack_align_needed: ");
       switch (val)
@@ -11745,7 +11911,7 @@ display_tic6x_attribute (unsigned char * p)
       return p;
 
     case Tag_ABI_stack_align_preserved:
-      val = read_uleb128 (p, &len);
+      val = read_uleb128 (p, &len, end);
       p += len;
       printf ("  Tag_ABI_stack_align_preserved: ");
       switch (val)
@@ -11763,7 +11929,7 @@ display_tic6x_attribute (unsigned char * p)
       return p;
 
     case Tag_ABI_DSBT:
-      val = read_uleb128 (p, &len);
+      val = read_uleb128 (p, &len, end);
       p += len;
       printf ("  Tag_ABI_DSBT: ");
       switch (val)
@@ -11781,7 +11947,7 @@ display_tic6x_attribute (unsigned char * p)
       return p;
 
     case Tag_ABI_PID:
-      val = read_uleb128 (p, &len);
+      val = read_uleb128 (p, &len, end);
       p += len;
       printf ("  Tag_ABI_PID: ");
       switch (val)
@@ -11802,7 +11968,7 @@ display_tic6x_attribute (unsigned char * p)
       return p;
 
     case Tag_ABI_PIC:
-      val = read_uleb128 (p, &len);
+      val = read_uleb128 (p, &len, end);
       p += len;
       printf ("  Tag_ABI_PIC: ");
       switch (val)
@@ -11820,7 +11986,7 @@ display_tic6x_attribute (unsigned char * p)
       return p;
 
     case Tag_ABI_array_object_alignment:
-      val = read_uleb128 (p, &len);
+      val = read_uleb128 (p, &len, end);
       p += len;
       printf ("  Tag_ABI_array_object_alignment: ");
       switch (val)
@@ -11841,7 +12007,7 @@ display_tic6x_attribute (unsigned char * p)
       return p;
 
     case Tag_ABI_array_object_align_expected:
-      val = read_uleb128 (p, &len);
+      val = read_uleb128 (p, &len, end);
       p += len;
       printf ("  Tag_ABI_array_object_align_expected: ");
       switch (val)
@@ -11862,7 +12028,7 @@ display_tic6x_attribute (unsigned char * p)
       return p;
 
     case Tag_ABI_compatibility:
-      val = read_uleb128 (p, &len);
+      val = read_uleb128 (p, &len, end);
       p += len;
       printf ("  Tag_ABI_compatibility: ");
       printf (_("flag = %d, vendor = %s\n"), val, p);
@@ -11876,19 +12042,122 @@ display_tic6x_attribute (unsigned char * p)
       return p;
     }
 
-  printf ("  Tag_unknown_%d: ", tag);
+  return display_tag_value (tag, p, end);
+}
+
+static void
+display_raw_attribute (unsigned char * p, unsigned char * end)
+{
+  unsigned long addr = 0;
+  size_t bytes = end - p;
 
-  if (tag & 1)
+  while (bytes)
     {
-      printf ("\"%s\"\n", p);
-      p += strlen ((char *) p) + 1;
+      int j;
+      int k;
+      int lbytes = (bytes > 16 ? 16 : bytes);
+
+      printf ("  0x%8.8lx ", addr);
+
+      for (j = 0; j < 16; j++)
+       {
+         if (j < lbytes)
+           printf ("%2.2x", p[j]);
+         else
+           printf ("  ");
+
+         if ((j & 3) == 3)
+           printf (" ");
+       }
+
+      for (j = 0; j < lbytes; j++)
+       {
+         k = p[j];
+         if (k >= ' ' && k < 0x7f)
+           printf ("%c", k);
+         else
+           printf (".");
+       }
+
+      putchar ('\n');
+
+      p  += lbytes;
+      bytes -= lbytes;
+      addr += lbytes;
     }
-  else
+
+  putchar ('\n');
+}
+
+static unsigned char *
+display_msp430x_attribute (unsigned char * p,
+                          const unsigned char * const end)
+{
+  unsigned int len;
+  int val;
+  int tag;
+
+  tag = read_uleb128 (p, & len, end);
+  p += len;
+
+  switch (tag)
     {
-      val = read_uleb128 (p, &len);
+    case OFBA_MSPABI_Tag_ISA:
+      val = read_uleb128 (p, &len, end);
       p += len;
-      printf ("%d (0x%x)\n", val, val);
-    }
+      printf ("  Tag_ISA: ");
+      switch (val)
+       {
+       case 0: printf (_("None\n")); break;
+       case 1: printf (_("MSP430\n")); break;
+       case 2: printf (_("MSP430X\n")); break;
+       default: printf ("??? (%d)\n", val); break;
+       }
+      break;
+
+    case OFBA_MSPABI_Tag_Code_Model:
+      val = read_uleb128 (p, &len, end);
+      p += len;
+      printf ("  Tag_Code_Model: ");
+      switch (val)
+       {
+       case 0: printf (_("None\n")); break;
+       case 1: printf (_("Small\n")); break;
+       case 2: printf (_("Large\n")); break;
+       default: printf ("??? (%d)\n", val); break;
+       }
+      break;
+
+    case OFBA_MSPABI_Tag_Data_Model:
+      val = read_uleb128 (p, &len, end);
+      p += len;
+      printf ("  Tag_Data_Model: ");
+      switch (val)
+       {
+       case 0: printf (_("None\n")); break;
+       case 1: printf (_("Small\n")); break;
+       case 2: printf (_("Large\n")); break;
+       case 3: printf (_("Restricted Large\n")); break;
+       default: printf ("??? (%d)\n", val); break;
+       }
+      break;
+
+    default:
+      printf (_("  <unknown tag %d>: "), tag);
+
+      if (tag & 1)
+       {
+         printf ("\"%s\"\n", p);
+         p += strlen ((char *) p) + 1;
+       }
+      else
+       {
+         val = read_uleb128 (p, &len, end);
+         p += len;
+         printf ("%d (0x%x)\n", val, val);
+       }
+      break;
+   }
 
   return p;
 }
@@ -11897,8 +12166,8 @@ static int
 process_attributes (FILE * file,
                    const char * public_name,
                    unsigned int proc_type,
-                   unsigned char * (* display_pub_attribute) (unsigned char *),
-                   unsigned char * (* display_proc_gnu_attribute) (unsigned char *, int))
+                   unsigned char * (* display_pub_attribute) (unsigned char *, const unsigned char * const),
+                   unsigned char * (* display_proc_gnu_attribute) (unsigned char *, int, const unsigned char * const))
 {
   Elf_Internal_Shdr * sect;
   unsigned char * contents;
@@ -11993,7 +12262,7 @@ process_attributes (FILE * file,
                        {
                          unsigned int j;
 
-                         val = read_uleb128 (p, &j);
+                         val = read_uleb128 (p, &j, end);
                          p += j;
                          if (val == 0)
                            break;
@@ -12010,18 +12279,19 @@ process_attributes (FILE * file,
                  if (public_section)
                    {
                      while (p < end)
-                       p = display_pub_attribute (p);
+                       p = display_pub_attribute (p, end);
                    }
                  else if (gnu_section)
                    {
                      while (p < end)
                        p = display_gnu_attribute (p,
-                                                  display_proc_gnu_attribute);
+                                                  display_proc_gnu_attribute,
+                                                  end);
                    }
                  else
                    {
-                     /* ??? Do something sensible, like dump hex.  */
                      printf (_("  Unknown section contexts\n"));
+                     display_raw_attribute (p, end);
                      p = end;
                    }
                }
@@ -12063,6 +12333,13 @@ process_tic6x_specific (FILE * file)
                             display_tic6x_attribute, NULL);
 }
 
+static int
+process_msp430x_specific (FILE * file)
+{
+  return process_attributes (file, "mspabi", SHT_MSP430_ATTRIBUTES,
+                            display_msp430x_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.  */
@@ -12604,7 +12881,7 @@ process_mips_specific (FILE * file)
                  _("Type"),
                  /* Note for translators: "Ndx" = abbreviated form of "Index".  */
                  _("Ndx"), _("Name"));
-         
+
          sym_width = (is_32bit_elf ? 80 : 160) - 28 - addr_size * 6 - 1;
          for (i = gotsym; i < symtabno; i++)
            {
@@ -12839,6 +13116,8 @@ get_note_type (unsigned e_type)
        return _("NT_S390_LAST_BREAK (s390 last breaking event address)");
       case NT_S390_SYSTEM_CALL:
        return _("NT_S390_SYSTEM_CALL (s390 system call restart data)");
+      case NT_S390_TDB:
+       return _("NT_S390_TDB (s390 transaction diagnostic block)");
       case NT_ARM_VFP:
        return _("NT_ARM_VFP (arm VFP registers)");
       case NT_ARM_TLS:
@@ -13340,13 +13619,12 @@ process_corefile_note_segment (FILE * file, bfd_vma offset, bfd_vma length)
   Elf_External_Note * pnotes;
   Elf_External_Note * external;
   int res = 1;
-  bfd_signed_vma data_remaining;
 
   if (length <= 0)
     return 0;
 
   pnotes = (Elf_External_Note *) get_data (NULL, file, offset, 1, length,
-                                           _("notes"));
+                                          _("notes"));
   if (pnotes == NULL)
     return 0;
 
@@ -13356,79 +13634,69 @@ process_corefile_note_segment (FILE * file, bfd_vma offset, bfd_vma length)
          (unsigned long) offset, (unsigned long) length);
   printf (_("  %-20s %10s\tDescription\n"), _("Owner"), _("Data size"));
 
-  data_remaining = length;
-  while (external < (Elf_External_Note *) ((char *) pnotes + length))
+  while ((char *) external < (char *) pnotes + length)
     {
-      Elf_External_Note * next;
       Elf_Internal_Note inote;
+      size_t min_notesz;
+      char *next;
       char * temp = NULL;
+      size_t data_remaining = ((char *) pnotes + length) - (char *) external;
 
       if (!is_ia64_vms ())
-        {
+       {
          /* PR binutils/15191
             Make sure that there is enough data to read.  */
-         if (data_remaining < sizeof * next)
+         min_notesz = offsetof (Elf_External_Note, name);
+         if (data_remaining < min_notesz)
            {
              warn (_("Corrupt note: only %d bytes remain, not enough for a full note\n"),
                    (int) data_remaining);
              break;
            }
-          inote.type     = BYTE_GET (external->type);
-          inote.namesz   = BYTE_GET (external->namesz);
-          inote.namedata = external->name;
-          inote.descsz   = BYTE_GET (external->descsz);
-          inote.descdata = inote.namedata + align_power (inote.namesz, 2);
-          inote.descpos  = offset + (inote.descdata - (char *) pnotes);
-
-          next = (Elf_External_Note *) (inote.descdata + align_power (inote.descsz, 2));
-        }
+         inote.type     = BYTE_GET (external->type);
+         inote.namesz   = BYTE_GET (external->namesz);
+         inote.namedata = external->name;
+         inote.descsz   = BYTE_GET (external->descsz);
+         inote.descdata = inote.namedata + align_power (inote.namesz, 2);
+         inote.descpos  = offset + (inote.descdata - (char *) pnotes);
+         next = inote.descdata + align_power (inote.descsz, 2);
+       }
       else
-        {
-          Elf64_External_VMS_Note *vms_external;
+       {
+         Elf64_External_VMS_Note *vms_external;
 
          /* PR binutils/15191
             Make sure that there is enough data to read.  */
-         if (data_remaining < sizeof * vms_external)
+         min_notesz = offsetof (Elf64_External_VMS_Note, name);
+         if (data_remaining < min_notesz)
            {
              warn (_("Corrupt note: only %d bytes remain, not enough for a full note\n"),
                    (int) data_remaining);
              break;
            }
-         
-          vms_external = (Elf64_External_VMS_Note *) external;
-          inote.type     = BYTE_GET (vms_external->type);
-          inote.namesz   = BYTE_GET (vms_external->namesz);
-          inote.namedata = vms_external->name;
-          inote.descsz   = BYTE_GET (vms_external->descsz);
-          inote.descdata = inote.namedata + align_power (inote.namesz, 3);
-          inote.descpos  = offset + (inote.descdata - (char *) pnotes);
-
-          next = (Elf_External_Note *)
-            (inote.descdata + align_power (inote.descsz, 3));
-        }
 
-      data_remaining -= ((char *) next - (char *) external);
-      if (data_remaining < 0)
+         vms_external = (Elf64_External_VMS_Note *) external;
+         inote.type     = BYTE_GET (vms_external->type);
+         inote.namesz   = BYTE_GET (vms_external->namesz);
+         inote.namedata = vms_external->name;
+         inote.descsz   = BYTE_GET (vms_external->descsz);
+         inote.descdata = inote.namedata + align_power (inote.namesz, 3);
+         inote.descpos  = offset + (inote.descdata - (char *) pnotes);
+         next = inote.descdata + align_power (inote.descsz, 3);
+       }
+
+      if (inote.descdata < (char *) external + min_notesz
+         || next < (char *) external + min_notesz
+         || data_remaining < (size_t)(next - (char *) external))
        {
-         warn (_("note with invalid namesz &/or descsz found at offset 0x%lx\n"),
+         warn (_("note with invalid namesz and/or descsz found at offset 0x%lx\n"),
                (unsigned long) ((char *) external - (char *) pnotes));
          warn (_(" type: 0x%lx, namesize: 0x%08lx, descsize: 0x%08lx\n"),
                inote.type, inote.namesz, inote.descsz);
          break;
        }
 
-      external = next;
-
-      /* Prevent out-of-bounds indexing.  */
-      if (inote.namedata + inote.namesz > (char *) pnotes + length
-         || inote.namedata + inote.namesz < inote.namedata)
-        {
-          warn (_("note with invalid namesz found at offset 0x%lx\n"),
-                (unsigned long) ((char *) external - (char *) pnotes));
-          warn (_(" type: 0x%lx, namesize: 0x%08lx, descsize: 0x%08lx\n"),
-                inote.type, inote.namesz, inote.descsz);
-          break;
-        }
+      external = (Elf_External_Note *) next;
 
       /* Verify that name is null terminated.  It appears that at least
         one version of Linux (RedHat 6.0) generates corefiles that don't
@@ -13550,6 +13818,8 @@ process_arch_specific (FILE * file)
     case EM_TI_C6000:
       return process_tic6x_specific (file);
       break;
+    case EM_MSP430:
+      return process_msp430x_specific (file);
     default:
       break;
     }