Add MMIX support
[external/binutils.git] / binutils / readelf.c
index 3457316..675912f 100644 (file)
@@ -68,6 +68,7 @@
 #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"
@@ -111,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;
@@ -280,62 +282,28 @@ 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;
-}
-#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;
+  VA_CLOSE (args);
 }
 
-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 *));
 
 static PTR
@@ -473,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
@@ -620,6 +588,7 @@ guess_is_rela (e_machine)
     case EM_X86_64:
     case EM_S390:
     case EM_S390_OLD:
+    case EM_MMIX:
       return TRUE;
 
     case EM_MMA:
@@ -974,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);
@@ -2032,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);
 
@@ -2071,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}
 };
@@ -2105,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);
 
@@ -2153,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;
@@ -2233,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
@@ -2295,6 +2274,9 @@ parse_args (argc, argv)
        case 'V':
          do_version ++;
          break;
+       case 'W':
+         do_wide ++;
+         break;
        default:
        oops:
          /* xgettext:c-format */
@@ -2578,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
@@ -2612,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);
@@ -3050,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"));
@@ -3081,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 ("  ");
@@ -3650,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);
@@ -5693,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
@@ -5921,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;
@@ -6965,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;
@@ -7115,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;
@@ -7308,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"));
@@ -7523,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;
 
@@ -7631,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;
 
@@ -8073,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 },
@@ -9002,6 +9112,8 @@ db_task_printsym (unsigned int addr)
 }
 #endif
 
+int main PARAMS ((int, char **));
+
 int
 main (argc, argv)
      int     argc;
@@ -9012,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);