daily update
[deliverable/binutils-gdb.git] / binutils / readelf.c
index a71bf94cf3e3439a84f4b604680fca67198edce7..0568a673eb82a893d0d2a67b17b1ef467264b3a7 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"
@@ -903,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.  */
 
@@ -1125,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;
@@ -2553,6 +2568,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;
@@ -2761,6 +2782,11 @@ 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");
@@ -2781,6 +2807,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"));
        }
     }
 
@@ -3205,6 +3257,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)
 {
@@ -3270,6 +3334,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;
@@ -6564,7 +6631,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;
@@ -6574,19 +6644,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;
@@ -7432,7 +7498,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));
@@ -8994,8 +9063,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";
@@ -9961,6 +10035,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:
       {
@@ -10100,7 +10228,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:
@@ -10352,6 +10480,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:
@@ -11615,19 +11745,19 @@ display_mips_gnu_attribute (unsigned char * p,
 
       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:
@@ -11905,6 +12035,79 @@ display_raw_attribute (unsigned char * p, unsigned char * end)
   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)
+    {
+    case OFBA_MSPABI_Tag_ISA:
+      val = read_uleb128 (p, &len, end);
+      p += len;
+      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;
+}
+
 static int
 process_attributes (FILE * file,
                    const char * public_name,
@@ -12076,6 +12279,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.  */
@@ -13554,6 +13764,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;
     }
This page took 0.032591 seconds and 4 git commands to generate.