Add MMIX support
[external/binutils.git] / binutils / readelf.c
index 8b8e8b6..675912f 100644 (file)
 #include "elf/mn10200.h"
 #include "elf/mn10300.h"
 #include "elf/hppa.h"
+#include "elf/h8.h"
 #include "elf/arc.h"
 #include "elf/fr30.h"
 #include "elf/mcore.h"
+#include "elf/mmix.h"
 #include "elf/i960.h"
 #include "elf/pj.h"
 #include "elf/avr.h"
@@ -110,6 +112,7 @@ int                 do_using_dynamic;
 int                    do_header;
 int                    do_dump;
 int                    do_version;
+int                    do_wide;
 int                    do_histogram;
 int                    do_debugging;
 int                     do_debug_info;
@@ -279,61 +282,27 @@ typedef int Elf32_Word;
    : get_64bit_elf_symbols (file, offset, size))
 
 
-#ifdef ANSI_PROTOTYPES
 static void
-error (const char * message, ...)
+error VPARAMS ((const char *message, ...))
 {
-  va_list args;
+  VA_OPEN (args, message);
+  VA_FIXEDARG (args, const char *, message);
 
   fprintf (stderr, _("%s: Error: "), program_name);
-  va_start (args, message);
   vfprintf (stderr, message, args);
-  va_end (args);
-  return;
+  VA_CLOSE (args);
 }
 
 static void
-warn (const char * message, ...)
+warn VPARAMS ((const char *message, ...))
 {
-  va_list args;
+  VA_OPEN (args, message);
+  VA_FIXEDARG (args, const char *, message);
 
   fprintf (stderr, _("%s: Warning: "), program_name);
-  va_start (args, message);
   vfprintf (stderr, message, args);
-  va_end (args);
-  return;
+  VA_CLOSE (args);
 }
-#else
-static void
-error (va_alist)
-     va_dcl
-{
-  char * message;
-  va_list args;
-
-  fprintf (stderr, _("%s: Error: "), program_name);
-  va_start (args);
-  message = va_arg (args, char *);
-  vfprintf (stderr, message, args);
-  va_end (args);
-  return;
-}
-
-static void
-warn (va_alist)
-     va_dcl
-{
-  char * message;
-  va_list args;
-
-  fprintf (stderr, _("%s: Warning: "), program_name);
-  va_start (args);
-  message = va_arg (args, char *);
-  vfprintf (stderr, message, args);
-  va_end (args);
-  return;
-}
-#endif
 
 static PTR get_data PARAMS ((PTR, FILE *, long, size_t, const char *));
 
@@ -472,7 +441,7 @@ print_vma (vma, mode)
          printf ("%lx", vma);
 #else
          if (_bfd_int64_high (vma))
-           printf ("%lx%lx", _bfd_int64_high (vma), _bfd_int64_low (vma));
+           printf ("%lx%8.8lx", _bfd_int64_high (vma), _bfd_int64_low (vma));
          else
            printf ("%lx", _bfd_int64_low (vma));
 #endif
@@ -581,7 +550,9 @@ guess_is_rela (e_machine)
     case EM_386:
     case EM_486:
     case EM_960:
+    case EM_M32R:
     case EM_CYGNUS_M32R:
+    case EM_D10V:
     case EM_CYGNUS_D10V:
     case EM_MIPS:
     case EM_MIPS_RS3_LE:
@@ -589,25 +560,35 @@ guess_is_rela (e_machine)
 
       /* Targets that use RELA relocations.  */
     case EM_68K:
+    case EM_H8_300:
+    case EM_H8_300H:
+    case EM_H8S:
     case EM_SPARC32PLUS:
     case EM_SPARCV9:
     case EM_SPARC:
     case EM_PPC:
+    case EM_V850:
     case EM_CYGNUS_V850:
+    case EM_D30V:
     case EM_CYGNUS_D30V:
+    case EM_MN10200:
     case EM_CYGNUS_MN10200:
+    case EM_MN10300:
     case EM_CYGNUS_MN10300:
+    case EM_FR30:
     case EM_CYGNUS_FR30:
     case EM_SH:
     case EM_ALPHA:
     case EM_MCORE:
     case EM_IA_64:
     case EM_AVR:
+    case EM_AVR_OLD:
     case EM_CRIS:
     case EM_860:
     case EM_X86_64:
     case EM_S390:
     case EM_S390_OLD:
+    case EM_MMIX:
       return TRUE;
 
     case EM_MMA:
@@ -894,6 +875,7 @@ dump_relocations (file, rel_offset, rel_size, symtab, nsyms, strtab, is_rela)
          rtype = NULL;
          break;
 
+       case EM_M32R:
        case EM_CYGNUS_M32R:
          rtype = elf_m32r_reloc_type (type);
          break;
@@ -912,6 +894,7 @@ dump_relocations (file, rel_offset, rel_size, symtab, nsyms, strtab, is_rela)
          break;
 
        case EM_AVR:
+       case EM_AVR_OLD:
          rtype = elf_avr_reloc_type (type);
          break;
 
@@ -922,14 +905,17 @@ dump_relocations (file, rel_offset, rel_size, symtab, nsyms, strtab, is_rela)
          rtype = elf_sparc_reloc_type (type);
          break;
 
+       case EM_V850:
        case EM_CYGNUS_V850:
          rtype = v850_reloc_type (type);
          break;
 
+       case EM_D10V:
        case EM_CYGNUS_D10V:
          rtype = elf_d10v_reloc_type (type);
          break;
 
+       case EM_D30V:
        case EM_CYGNUS_D30V:
          rtype = elf_d30v_reloc_type (type);
          break;
@@ -938,14 +924,17 @@ dump_relocations (file, rel_offset, rel_size, symtab, nsyms, strtab, is_rela)
          rtype = elf_sh_reloc_type (type);
          break;
 
+       case EM_MN10300:
        case EM_CYGNUS_MN10300:
          rtype = elf_mn10300_reloc_type (type);
          break;
 
+       case EM_MN10200:
        case EM_CYGNUS_MN10200:
          rtype = elf_mn10200_reloc_type (type);
          break;
 
+       case EM_FR30:
        case EM_CYGNUS_FR30:
          rtype = elf_fr30_reloc_type (type);
          break;
@@ -954,6 +943,10 @@ dump_relocations (file, rel_offset, rel_size, symtab, nsyms, strtab, is_rela)
          rtype = elf_mcore_reloc_type (type);
          break;
 
+       case EM_MMIX:
+         rtype = elf_mmix_reloc_type (type);
+         break;
+
        case EM_PPC:
        case EM_PPC64:
          rtype = elf_ppc_reloc_type (type);
@@ -972,7 +965,6 @@ dump_relocations (file, rel_offset, rel_size, symtab, nsyms, strtab, is_rela)
          rtype = elf_arm_reloc_type (type);
          break;
 
-       case EM_CYGNUS_ARC:
        case EM_ARC:
          rtype = elf_arc_reloc_type (type);
          break;
@@ -981,7 +973,14 @@ dump_relocations (file, rel_offset, rel_size, symtab, nsyms, strtab, is_rela)
          rtype = elf_hppa_reloc_type (type);
          break;
 
+       case EM_H8_300:
+       case EM_H8_300H:
+       case EM_H8S:
+         rtype = elf_h8_reloc_type (type);
+         break;
+
        case EM_PJ:
+       case EM_PJ_OLD:
          rtype = elf_pj_reloc_type (type);
          break;
        case EM_IA_64:
@@ -1345,14 +1344,21 @@ get_machine_name (e_machine)
     case EM_COLDFIRE:          return "Motorola Coldfire";
     case EM_68HC12:            return "Motorola M68HC12";
     case EM_ALPHA:             return "Alpha";
-    case EM_CYGNUS_D10V:        return "d10v";
-    case EM_CYGNUS_D30V:        return "d30v";
-    case EM_CYGNUS_ARC:                return "ARC";
-    case EM_CYGNUS_M32R:       return "Mitsubishi M32r";
-    case EM_CYGNUS_V850:       return "NEC v850";
-    case EM_CYGNUS_MN10300:    return "mn10300";
-    case EM_CYGNUS_MN10200:    return "mn10200";
-    case EM_CYGNUS_FR30:       return "Fujitsu FR30";
+    case EM_CYGNUS_D10V:
+    case EM_D10V:              return "d10v";
+    case EM_CYGNUS_D30V:
+    case EM_D30V:              return "d30v";
+    case EM_CYGNUS_M32R:
+    case EM_M32R:              return "Mitsubishi M32r";
+    case EM_CYGNUS_V850:
+    case EM_V850:              return "NEC v850";
+    case EM_CYGNUS_MN10300:
+    case EM_MN10300:           return "mn10300";
+    case EM_CYGNUS_MN10200:
+    case EM_MN10200:           return "mn10200";
+    case EM_CYGNUS_FR30:
+    case EM_FR30:              return "Fujitsu FR30";
+    case EM_PJ_OLD:
     case EM_PJ:                 return "picoJava";
     case EM_MMA:               return "Fujitsu Multimedia Accelerator";
     case EM_PCP:               return "Siemens PCP";
@@ -1372,6 +1378,7 @@ get_machine_name (e_machine)
     case EM_SVX:               return "Silicon Graphics SVx";
     case EM_ST19:              return "STMicroelectronics ST19 8-bit microcontroller";
     case EM_VAX:               return "Digital VAX";
+    case EM_AVR_OLD:
     case EM_AVR:                return "Atmel AVR 8-bit microcontroller";
     case EM_CRIS:              return "Axis Communications 32-bit embedded processor";
     case EM_JAVELIN:           return "Infineon Technologies 32-bit embedded cpu";
@@ -1567,6 +1574,7 @@ get_machine_flags (e_flags, e_machine)
            strcat (buf, ", relocatable-lib");
          break;
 
+       case EM_V850:
        case EM_CYGNUS_V850:
          switch (e_flags & EF_V850_ARCH)
            {
@@ -1585,6 +1593,7 @@ get_machine_flags (e_flags, e_machine)
            }
          break;
 
+       case EM_M32R:
        case EM_CYGNUS_M32R:
          if ((e_flags & EF_M32R_ARCH) == E_M32R_ARCH)
            strcat (buf, ", m32r");
@@ -1700,6 +1709,7 @@ get_machine_flags (e_flags, e_machine)
          break;
 
        case EM_PJ:
+       case EM_PJ_OLD:
          if ((e_flags & EF_PICOJAVA_NEWCALLS) == EF_PICOJAVA_NEWCALLS)
            strcat (buf, ", new calling convention");
 
@@ -1995,12 +2005,12 @@ get_section_type_name (sh_type)
          if (result != NULL)
            return result;
 
-         sprintf (buff, "SHT_LOPROC+%x", sh_type - SHT_LOPROC);
+         sprintf (buff, "LOPROC+%x", sh_type - SHT_LOPROC);
        }
       else if ((sh_type >= SHT_LOOS) && (sh_type <= SHT_HIOS))
-       sprintf (buff, "SHT_LOOS+%x", sh_type - SHT_LOOS);
+       sprintf (buff, "LOOS+%x", sh_type - SHT_LOOS);
       else if ((sh_type >= SHT_LOUSER) && (sh_type <= SHT_HIUSER))
-       sprintf (buff, "SHT_LOUSER+%x", sh_type - SHT_LOUSER);
+       sprintf (buff, "LOUSER+%x", sh_type - SHT_LOUSER);
       else
        sprintf (buff, _("<unknown>: %x"), sh_type);
 
@@ -2034,6 +2044,7 @@ struct option options [] =
 #endif
 
   {"version",          no_argument, 0, 'v'},
+  {"wide",             no_argument, 0, 'W'},
   {"help",             no_argument, 0, 'H'},
   {0,                  no_argument, 0, 0}
 };
@@ -2068,6 +2079,7 @@ usage ()
 #endif
   fprintf (stdout, _("  -I or --histogram         Display histogram of bucket list lengths\n"));
   fprintf (stdout, _("  -v or --version           Display the version number of readelf\n"));
+  fprintf (stdout, _("  -W or --wide              Don't split lines to fit into 80 columns\n"));
   fprintf (stdout, _("  -H or --help              Display this information\n"));
   fprintf (stdout, _("Report bugs to %s\n"), REPORT_BUGS_TO);
 
@@ -2116,7 +2128,7 @@ parse_args (argc, argv)
     usage ();
 
   while ((c = getopt_long
-         (argc, argv, "ersuahnldSDAIw::x:i:vV", options, NULL)) != EOF)
+         (argc, argv, "ersuahnldSDAIw::x:i:vVW", options, NULL)) != EOF)
     {
       char *    cp;
       int      section;
@@ -2196,49 +2208,53 @@ parse_args (argc, argv)
            do_debugging = 1;
          else
            {
+             unsigned int index = 0;
+             
              do_debugging = 0;
-             switch (optarg[0])
-               {
-               case 'i':
-               case 'I':
-                 do_debug_info = 1;
-                 break;
 
-               case 'a':
-               case 'A':
-                 do_debug_abbrevs = 1;
-                 break;
+             while (optarg[index])
+               switch (optarg[index++])
+                 {
+                 case 'i':
+                 case 'I':
+                   do_debug_info = 1;
+                   break;
 
-               case 'l':
-               case 'L':
-                 do_debug_lines = 1;
-                 break;
+                 case 'a':
+                 case 'A':
+                   do_debug_abbrevs = 1;
+                   break;
 
-               case 'p':
-               case 'P':
-                 do_debug_pubnames = 1;
-                 break;
+                 case 'l':
+                 case 'L':
+                   do_debug_lines = 1;
+                   break;
 
-               case 'r':
-               case 'R':
-                 do_debug_aranges = 1;
-                 break;
+                 case 'p':
+                 case 'P':
+                   do_debug_pubnames = 1;
+                   break;
 
-               case 'F':
-                 do_debug_frames_interp = 1;
-               case 'f':
-                 do_debug_frames = 1;
-                 break;
+                 case 'r':
+                 case 'R':
+                   do_debug_aranges = 1;
+                   break;
 
-               case 'm':
-               case 'M':
-                 do_debug_macinfo = 1;
-                 break;
+                 case 'F':
+                   do_debug_frames_interp = 1;
+                 case 'f':
+                   do_debug_frames = 1;
+                   break;
 
-               default:
-                 warn (_("Unrecognised debug option '%s'\n"), optarg);
-                 break;
-               }
+                 case 'm':
+                 case 'M':
+                   do_debug_macinfo = 1;
+                   break;
+
+                 default:
+                   warn (_("Unrecognised debug option '%s'\n"), optarg);
+                   break;
+                 }
            }
          break;
 #ifdef SUPPORT_DISASSEMBLY
@@ -2258,6 +2274,9 @@ parse_args (argc, argv)
        case 'V':
          do_version ++;
          break;
+       case 'W':
+         do_wide ++;
+         break;
        default:
        oops:
          /* xgettext:c-format */
@@ -2541,6 +2560,9 @@ process_program_headers (file)
       if (is_32bit_elf)
        printf
          (_("  Type           Offset   VirtAddr   PhysAddr   FileSiz MemSiz  Flg Align\n"));
+      else if (do_wide)
+       printf
+         (_("  Type           Offset   VirtAddr           PhysAddr           FileSiz  MemSiz   Flg Align\n"));
       else
        {
          printf
@@ -2575,6 +2597,48 @@ process_program_headers (file)
                      (segment->p_flags & PF_X ? 'E' : ' '));
              printf ("%#lx", (unsigned long) segment->p_align);
            }
+         else if (do_wide)
+           {
+             if ((unsigned long) segment->p_offset == segment->p_offset)
+               printf ("0x%6.6lx ", (unsigned long) segment->p_offset);
+             else
+               {
+                 print_vma (segment->p_offset, FULL_HEX);
+                 putchar (' ');
+               }
+
+             print_vma (segment->p_vaddr, FULL_HEX);
+             putchar (' ');
+             print_vma (segment->p_paddr, FULL_HEX);
+             putchar (' ');
+
+             if ((unsigned long) segment->p_filesz == segment->p_filesz)
+               printf ("0x%6.6lx ", (unsigned long) segment->p_filesz);
+             else
+               {
+                 print_vma (segment->p_filesz, FULL_HEX);
+                 putchar (' ');
+               }
+
+             if ((unsigned long) segment->p_memsz == segment->p_memsz)
+               printf ("0x%6.6lx", (unsigned long) segment->p_memsz);
+             else
+               {
+                 print_vma (segment->p_offset, FULL_HEX);
+               }
+
+             printf (" %c%c%c ",
+                     (segment->p_flags & PF_R ? 'R' : ' '),
+                     (segment->p_flags & PF_W ? 'W' : ' '),
+                     (segment->p_flags & PF_X ? 'E' : ' '));
+
+             if ((unsigned long) segment->p_align == segment->p_align)
+               printf ("%#lx", (unsigned long) segment->p_align);
+             else
+               {
+                 print_vma (segment->p_align, PREFIX_HEX);
+               }
+           }
          else
            {
              print_vma (segment->p_offset, FULL_HEX);
@@ -3013,6 +3077,9 @@ process_section_headers (file)
   if (is_32bit_elf)
     printf
       (_("  [Nr] Name              Type            Addr     Off    Size   ES Flg Lk Inf Al\n"));
+  else if (do_wide)
+    printf
+      (_("  [Nr] Name              Type            Address          Off    Size   ES Flg Lk Inf Al\n"));
   else
     {
       printf (_("  [Nr] Name              Type             Address           Offset\n"));
@@ -3044,11 +3111,59 @@ process_section_headers (file)
                  (unsigned long) section->sh_info,
                  (unsigned long) section->sh_addralign);
        }
+      else if (do_wide)
+       {
+         print_vma (section->sh_addr, LONG_HEX);
+
+         if ((long) section->sh_offset == section->sh_offset)
+           printf (" %6.6lx", (unsigned long) section->sh_offset);
+         else
+           {
+             putchar (' ');
+             print_vma (section->sh_offset, LONG_HEX);
+           }
+
+         if ((unsigned long) section->sh_size == section->sh_size)
+           printf (" %6.6lx", (unsigned long) section->sh_size);
+         else
+           {
+             putchar (' ');
+             print_vma (section->sh_size, LONG_HEX);
+           }
+
+         if ((unsigned long) section->sh_entsize == section->sh_entsize)
+           printf (" %2.2lx", (unsigned long) section->sh_entsize);
+         else
+           {
+             putchar (' ');
+             print_vma (section->sh_entsize, LONG_HEX);
+           }
+
+         printf (" %3s ", get_elf_section_flags (section->sh_flags));
+
+         printf ("%2ld %3lx ",
+                 (unsigned long) section->sh_link,
+                 (unsigned long) section->sh_info);
+
+         if ((unsigned long) section->sh_addralign == section->sh_addralign)
+           printf ("%2ld\n", (unsigned long) section->sh_addralign);
+         else
+           {
+             print_vma (section->sh_addralign, DEC);
+             putchar ('\n');
+           }
+       }
       else
        {
          putchar (' ');
          print_vma (section->sh_addr, LONG_HEX);
-         printf ("  %8.8lx", section->sh_offset);
+         if ((long) section->sh_offset == section->sh_offset)
+           printf ("  %8.8lx", (unsigned long) section->sh_offset);
+         else
+           {
+             printf ("  ");
+             print_vma (section->sh_offset, LONG_HEX);
+           }
          printf ("\n       ");
          print_vma (section->sh_size, LONG_HEX);
          printf ("  ");
@@ -3613,7 +3728,7 @@ process_unwind (file)
            printf ("'%s'", SECTION_NAME (unwsec));
 
          printf (_(" at offset 0x%lx contains %lu entries:\n"),
-                 unwsec->sh_offset,
+                 (unsigned long) unwsec->sh_offset,
                  (unsigned long) (unwsec->sh_size / (3 * addr_size)));
 
          (void) slurp_ia64_unwind_table (file, & aux, unwsec);
@@ -5656,6 +5771,13 @@ display_debug_lines (section, start, file)
 
       /* Check the length of the block.  */
       info.li_length = BYTE_GET (external->li_length);
+
+      if (info.li_length == 0xffffffff)
+       {
+         warn (_("64-bit DWARF line info is not supported yet.\n"));
+         break;
+       }
+
       if (info.li_length + sizeof (external->li_length) > section->sh_size)
        {
          warn
@@ -5884,6 +6006,12 @@ display_debug_pubnames (section, start, file)
       data   = start + sizeof (* external);
       start += pubnames.pn_length + sizeof (external->pn_length);
 
+      if (pubnames.pn_length == 0xffffffff)
+       {
+         warn (_("64-bit DWARF pubnames are not supported yet.\n"));
+         break;
+       }
+
       if (pubnames.pn_version != 2)
        {
          static int warned = 0;
@@ -6928,7 +7056,7 @@ read_and_display_attr (attribute, form, data, cu_offset, pointer_size)
          /* DWARF 2.1 values.  */
        case DW_LANG_C99:            printf ("(ANSI C99)"); break;
        case DW_LANG_Ada95:          printf ("(ADA 95)"); break;
-       case DW_LANG_Fortran95:       printf ("(Fortran 95)"); break;
+       case DW_LANG_Fortran95:      printf ("(Fortran 95)"); break;
          /* MIPS extension.  */
        case DW_LANG_Mips_Assembler: printf ("(MIPS assembler)"); break;
        default:                     printf ("(Unknown: %lx)", uvalue); break;
@@ -7078,6 +7206,12 @@ display_debug_info (section, start, file)
       compunit.cu_abbrev_offset = BYTE_GET (external->cu_abbrev_offset);
       compunit.cu_pointer_size  = BYTE_GET (external->cu_pointer_size);
 
+      if (compunit.cu_length == 0xffffffff)
+       {
+         warn (_("64-bit DWARF debug info is not supported yet.\n"));
+         break;
+       }
+
       /* Check for RELA relocations in the abbrev_offset address, and
          apply them.  */
       for (relsec = section_headers;
@@ -7271,6 +7405,12 @@ display_debug_aranges (section, start, file)
       arange.ar_pointer_size = BYTE_GET (external->ar_pointer_size);
       arange.ar_segment_size = BYTE_GET (external->ar_segment_size);
 
+      if (arange.ar_length == 0xffffffff)
+       {
+         warn (_("64-bit DWARF aranges are not supported yet.\n"));
+         break;
+       }
+
       if (arange.ar_version != 2)
        {
          warn (_("Only DWARF 2 aranges are currently supported.\n"));
@@ -7486,6 +7626,12 @@ display_debug_frames (section, start, file)
       if (length == 0)
        return 1;
 
+      if (length == 0xffffffff)
+       {
+         warn (_("64-bit DWARF format frames are not supported yet.\n"));
+         break;
+       }
+
       block_end = saved_start + length + 4;
       cie_id = byte_get (start, 4); start += 4;
 
@@ -7594,7 +7740,7 @@ display_debug_frames (section, start, file)
 
          look_for = is_eh ? start - 4 - cie_id : section_start + cie_id;
 
-         for (cie=chunks; cie ; cie = cie->next)
+         for (cie = chunks; cie ; cie = cie->next)
            if (cie->chunk_start == look_for)
              break;
 
@@ -8036,6 +8182,7 @@ debug_displays[] =
   { ".debug_frame",       display_debug_frames, NULL },
   { ".eh_frame",          display_debug_frames, NULL },
   { ".debug_macinfo",     display_debug_macinfo, NULL },
+  { ".debug_pubtypes",    display_debug_not_supported, NULL },
   { ".debug_str",         display_debug_not_supported, NULL },
   { ".debug_static_func", display_debug_not_supported, NULL },
   { ".debug_static_vars", display_debug_not_supported, NULL },
@@ -8965,6 +9112,8 @@ db_task_printsym (unsigned int addr)
 }
 #endif
 
+int main PARAMS ((int, char **));
+
 int
 main (argc, argv)
      int     argc;
@@ -8975,6 +9124,9 @@ main (argc, argv)
 #if defined (HAVE_SETLOCALE) && defined (HAVE_LC_MESSAGES)
   setlocale (LC_MESSAGES, "");
 #endif
+#if defined (HAVE_SETLOCALE)
+  setlocale (LC_CTYPE, "");
+#endif
   bindtextdomain (PACKAGE, LOCALEDIR);
   textdomain (PACKAGE);