These files removed.
[deliverable/binutils-gdb.git] / binutils / readelf.c
index ae13b3ebc1d7c6c8344f5122431b4a0d090006cb..3498b30ba64bb755d0b4be72d4914e484d562021 100644 (file)
 #include "safe-ctype.h"
 
 char *program_name = "readelf";
+int do_wide;
 static long archive_file_offset;
 static unsigned long archive_file_size;
 static unsigned long dynamic_addr;
@@ -197,7 +198,6 @@ static int do_using_dynamic;
 static int do_header;
 static int do_dump;
 static int do_version;
-static int do_wide;
 static int do_histogram;
 static int do_debugging;
 static int do_arch;
@@ -542,21 +542,87 @@ print_vma (bfd_vma vma, print_mode mode)
   return 0;
 }
 
-/* Display a symbol on stdout.  If do_wide is not true then
-   format the symbol to be at most WIDTH characters,
-   truncating as necessary.  If WIDTH is negative then
-   format the string to be exactly - WIDTH characters,
-   truncating or padding as necessary.  */
+/* Display a symbol on stdout.  Handles the display of
+   non-printing characters.
+   If DO_WIDE is not true then format the symbol to be
+   at most WIDTH characters, truncating as necessary.
+   If WIDTH is negative then format the string to be
+   exactly - WIDTH characters, truncating or padding
+   as necessary.  */
 
 static void
 print_symbol (int width, const char *symbol)
 {
+  const char * format_string;
+  const char * c;
+
   if (do_wide)
-    printf ("%s", symbol);
+    {
+      format_string = "%.*s";
+      /* Set the width to a very large value.  This simplifies the code below.  */
+      width = INT_MAX;
+    }
   else if (width < 0)
-    printf ("%-*.*s", width, width, symbol);
+    {
+      format_string = "%-*.*2s";
+      /* Keep the width positive.  This also helps.  */
+      width = - width;
+    }
   else
-    printf ("%-.*s", width, symbol);
+    {
+      format_string = "%-.*s";
+    }
+
+  while (width)
+    {
+      int len;
+
+      c = symbol;
+
+      /* Look for non-printing symbols inside the symbol's name.
+        This test is triggered in particular by the names generated
+        by the assembler for local labels.  */
+      while (ISPRINT (* c))
+       c++;
+
+      len = c - symbol;
+
+      if (len)
+       {
+         if (len > width)
+           len = width;
+         
+         printf (format_string, len, symbol);
+
+         width -= len;
+       }
+
+      if (* c == 0 || width == 0)
+       break;
+
+      /* Now display the non-printing character, if
+        there is room left in which to dipslay it.  */
+      if (*c < 32)
+       {
+         if (width < 2)
+           break;
+
+         printf ("^%c", *c + 0x40);
+
+         width -= 2;
+       }
+      else
+       {
+         if (width < 6)
+           break;
+         
+         printf ("<0x%.2x>", *c);
+
+         width -= 6;
+       }
+
+      symbol = c + 1;
+    }
 }
 
 static void
@@ -2880,8 +2946,8 @@ usage (FILE *stream)
                          Dump the contents of section <number|name> as bytes\n\
   -p --string-dump=<number|name>\n\
                          Dump the contents of section <number|name> as strings\n\
-  -w[liaprmfFsoR] or\n\
-  --debug-dump[=line,=info,=abbrev,=pubnames,=aranges,=macro,=frames,=str,=loc,=Ranges]\n\
+  -w[lLiaprmfFsoR] or\n\
+  --debug-dump[=rawline,=decodedline,=info,=abbrev,=pubnames,=aranges,=macro,=frames,=str,=loc,=Ranges]\n\
                          Display the contents of DWARF2 debug sections\n"));
 #ifdef SUPPORT_DISASSEMBLY
   fprintf (stream, _("\
@@ -3083,6 +3149,10 @@ parse_args (int argc, char **argv)
                    do_debug_lines = 1;
                    break;
 
+                 case 'L':
+                   do_debug_lines_decoded = 1;
+                   break;
+
                  case 'p':
                    do_debug_pubnames = 1;
                    break;
@@ -3141,7 +3211,9 @@ parse_args (int argc, char **argv)
                  { "frames", & do_debug_frames },
                  { "frames-interp", & do_debug_frames_interp },
                  { "info", & do_debug_info },
-                 { "line", & do_debug_lines },
+                 { "line", & do_debug_lines }, /* For backwards compatibility.  */
+                 { "rawline", & do_debug_lines },
+                 { "decodedline", & do_debug_lines_decoded },
                  { "loc",  & do_debug_loc },
                  { "macro", & do_debug_macinfo },
                  { "pubnames", & do_debug_pubnames },
@@ -3340,7 +3412,7 @@ process_file_header (void)
              (long) elf_header.e_shstrndx);
       if (section_headers != NULL
          && elf_header.e_shstrndx == (SHN_XINDEX & 0xffff))
-       printf (" (%ld)", (long) section_headers[0].sh_link);
+       printf (" (%u)", section_headers[0].sh_link);
       else if (elf_header.e_shstrndx >= elf_header.e_shnum)
        printf (" <corrupt: out of range>");
       putc ('\n', stdout);
@@ -3676,7 +3748,7 @@ process_program_headers (FILE *file)
          Elf_Internal_Shdr *section;
 
          segment = program_headers + i;
-         section = section_headers;
+         section = section_headers + 1;
 
          printf ("   %2.2d     ", i);
 
@@ -4303,9 +4375,9 @@ process_section_headers (FILE *file)
       else if (section->sh_type == SHT_RELA)
        CHECK_ENTSIZE (section, i, Rela);
       else if ((do_debugging || do_debug_info || do_debug_abbrevs
-               || do_debug_lines || do_debug_pubnames || do_debug_aranges
-               || do_debug_frames || do_debug_macinfo || do_debug_str
-               || do_debug_loc || do_debug_ranges)
+               || do_debug_lines || do_debug_lines_decoded || do_debug_pubnames 
+               || do_debug_aranges || do_debug_frames || do_debug_macinfo 
+               || do_debug_str || do_debug_loc || do_debug_ranges)
               && const_strneq (name, ".debug_"))
        {
          name += 7;
@@ -4313,7 +4385,8 @@ process_section_headers (FILE *file)
          if (do_debugging
              || (do_debug_info     && streq (name, "info"))
              || (do_debug_abbrevs  && streq (name, "abbrev"))
-             || (do_debug_lines    && streq (name, "line"))
+             || ((do_debug_lines || do_debug_lines_decoded) 
+                 && streq (name, "line"))
              || (do_debug_pubnames && streq (name, "pubnames"))
              || (do_debug_aranges  && streq (name, "aranges"))
              || (do_debug_ranges   && streq (name, "ranges"))
@@ -4324,7 +4397,7 @@ process_section_headers (FILE *file)
              )
            request_dump_bynumber (i, DEBUG_DUMP);
        }
-      /* linkonce section to be combined with .debug_info at link time.  */
+      /* Linkonce section to be combined with .debug_info at link time.  */
       else if ((do_debugging || do_debug_info)
               && const_strneq (name, ".gnu.linkonce.wi."))
        request_dump_bynumber (i, DEBUG_DUMP);
@@ -4413,9 +4486,9 @@ process_section_headers (FILE *file)
          else
            printf (" %3s ", get_elf_section_flags (section->sh_flags));
 
-         printf ("%2ld %3lu %2ld\n",
-                 (unsigned long) section->sh_link,
-                 (unsigned long) section->sh_info,
+         printf ("%2u %3u %2lu\n",
+                 section->sh_link,
+                 section->sh_info,
                  (unsigned long) section->sh_addralign);
        }
       else if (do_wide)
@@ -4451,12 +4524,10 @@ process_section_headers (FILE *file)
          else
            printf (" %3s ", get_elf_section_flags (section->sh_flags));
 
-         printf ("%2ld %3lu ",
-                 (unsigned long) section->sh_link,
-                 (unsigned long) section->sh_info);
+         printf ("%2u %3u ", section->sh_link, section->sh_info);
 
          if ((unsigned long) section->sh_addralign == section->sh_addralign)
-           printf ("%2ld\n", (unsigned long) section->sh_addralign);
+           printf ("%2lu\n", (unsigned long) section->sh_addralign);
          else
            {
              print_vma (section->sh_addralign, DEC);
@@ -4475,13 +4546,13 @@ process_section_headers (FILE *file)
              printf ("  ");
              print_vma (section->sh_offset, LONG_HEX);
            }
-         printf ("  %ld\n       ", (unsigned long) section->sh_link);
+         printf ("  %u\n       ", section->sh_link);
          print_vma (section->sh_size, LONG_HEX);
          putchar (' ');
          print_vma (section->sh_entsize, LONG_HEX);
 
-         printf ("  %-16lu  %ld\n",
-                 (unsigned long) section->sh_info,
+         printf ("  %-16u  %lu\n",
+                 section->sh_info,
                  (unsigned long) section->sh_addralign);
        }
       else
@@ -4502,9 +4573,9 @@ process_section_headers (FILE *file)
 
          printf (" %3s ", get_elf_section_flags (section->sh_flags));
 
-         printf ("     %2ld   %3lu     %ld\n",
-                 (unsigned long) section->sh_link,
-                 (unsigned long) section->sh_info,
+         printf ("     %2u   %3u     %lu\n",
+                 section->sh_link,
+                 section->sh_info,
                  (unsigned long) section->sh_addralign);
        }
 
@@ -6559,12 +6630,12 @@ process_version_sections (FILE *file)
            found = 1;
 
            printf
-             (_("\nVersion definition section '%s' contains %ld entries:\n"),
+             (_("\nVersion definition section '%s' contains %u entries:\n"),
               SECTION_NAME (section), section->sh_info);
 
            printf (_("  Addr: 0x"));
            printf_vma (section->sh_addr);
-           printf (_("  Offset: %#08lx  Link: %lx (%s)\n"),
+           printf (_("  Offset: %#08lx  Link: %u (%s)\n"),
                    (unsigned long) section->sh_offset, section->sh_link,
                    section->sh_link < elf_header.e_shnum
                    ? SECTION_NAME (section_headers + section->sh_link)
@@ -6661,12 +6732,12 @@ process_version_sections (FILE *file)
 
            found = 1;
 
-           printf (_("\nVersion needs section '%s' contains %ld entries:\n"),
+           printf (_("\nVersion needs section '%s' contains %u entries:\n"),
                    SECTION_NAME (section), section->sh_info);
 
            printf (_(" Addr: 0x"));
            printf_vma (section->sh_addr);
-           printf (_("  Offset: %#08lx  Link to section: %ld (%s)\n"),
+           printf (_("  Offset: %#08lx  Link: %u (%s)\n"),
                    (unsigned long) section->sh_offset, section->sh_link,
                    section->sh_link < elf_header.e_shnum
                    ? SECTION_NAME (section_headers + section->sh_link)
@@ -6787,7 +6858,7 @@ process_version_sections (FILE *file)
 
            printf (_(" Addr: "));
            printf_vma (section->sh_addr);
-           printf (_("  Offset: %#08lx  Link: %lx (%s)\n"),
+           printf (_("  Offset: %#08lx  Link: %u (%s)\n"),
                    (unsigned long) section->sh_offset, section->sh_link,
                    SECTION_NAME (link_section));
 
@@ -9127,6 +9198,33 @@ process_power_specific (FILE *file)
                             display_power_gnu_attribute);
 }
 
+/* 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.  */
+
+static bfd_vma
+print_mips_got_entry (unsigned char *data, bfd_vma pltgot, bfd_vma addr)
+{
+  printf ("  ");
+  print_vma (addr, LONG_HEX);
+  printf (" ");
+  if (addr < pltgot + 0xfff0)
+    printf ("%6d(gp)", (int) (addr - pltgot - 0x7ff0));
+  else
+    printf ("%10s", "");
+  printf (" ");
+  if (data == NULL)
+    printf ("%*s", is_32bit_elf ? 8 : 16, "<unknown>");
+  else
+    {
+      bfd_vma entry;
+
+      entry = byte_get (data + addr - pltgot, is_32bit_elf ? 4 : 8);
+      print_vma (entry, LONG_HEX);
+    }
+  return addr + (is_32bit_elf ? 4 : 8);
+}
+
 static int
 process_mips_specific (FILE *file)
 {
@@ -9136,6 +9234,10 @@ process_mips_specific (FILE *file)
   size_t conflictsno = 0;
   size_t options_offset = 0;
   size_t conflicts_offset = 0;
+  bfd_vma pltgot = 0;
+  bfd_vma local_gotno = 0;
+  bfd_vma gotsym = 0;
+  bfd_vma symtabno = 0;
 
   process_attributes (file, NULL, SHT_GNU_ATTRIBUTES, NULL,
                      display_mips_gnu_attribute);
@@ -9167,6 +9269,17 @@ process_mips_specific (FILE *file)
       case DT_MIPS_CONFLICTNO:
        conflictsno = entry->d_un.d_val;
        break;
+      case DT_PLTGOT:
+       pltgot = entry->d_un.d_val;
+      case DT_MIPS_LOCAL_GOTNO:
+       local_gotno = entry->d_un.d_val;
+       break;
+      case DT_MIPS_GOTSYM:
+       gotsym = entry->d_un.d_val;
+       break;
+      case DT_MIPS_SYMTABNO:
+       symtabno = entry->d_un.d_val;
+       break;
       default:
        break;
       }
@@ -9517,6 +9630,88 @@ process_mips_specific (FILE *file)
       free (iconf);
     }
 
+  if (pltgot != 0 && local_gotno != 0)
+    {
+      bfd_vma entry, local_end, global_end;
+      size_t i, offset;
+      unsigned char *data;
+      int addr_size;
+
+      entry = pltgot;
+      addr_size = (is_32bit_elf ? 4 : 8);
+      local_end = pltgot + local_gotno * addr_size;
+      global_end = local_end + (symtabno - gotsym) * addr_size;
+
+      offset = offset_from_vma (file, pltgot, global_end - pltgot);
+      data = get_data (NULL, file, offset, global_end - pltgot, 1, _("GOT"));
+      printf (_("\nPrimary GOT:\n"));
+      printf (_(" Canonical gp value: "));
+      print_vma (pltgot + 0x7ff0, LONG_HEX);
+      printf ("\n\n");
+
+      printf (_(" Reserved entries:\n"));
+      printf (_("  %*s %10s %*s Purpose\n"),
+             addr_size * 2, "Address", "Access",
+             addr_size * 2, "Initial");
+      entry = print_mips_got_entry (data, pltgot, entry);
+      printf (" Lazy resolver\n");
+      if (data
+         && (byte_get (data + entry - pltgot, addr_size)
+             >> (addr_size * 8 - 1)) != 0)
+       {
+         entry = print_mips_got_entry (data, pltgot, entry);
+         printf (" Module pointer (GNU extension)\n");
+       }
+      printf ("\n");
+
+      if (entry < local_end)
+       {
+         printf (_(" Local entries:\n"));
+         printf (_("  %*s %10s %*s\n"),
+                 addr_size * 2, "Address", "Access",
+                 addr_size * 2, "Initial");
+         while (entry < local_end)
+           {
+             entry = print_mips_got_entry (data, pltgot, entry);
+             printf ("\n");
+           }
+         printf ("\n");
+       }
+
+      if (gotsym < symtabno)
+       {
+         int sym_width;
+
+         printf (_(" Global entries:\n"));
+         printf (_("  %*s %10s %*s %*s %-7s %3s %s\n"),
+                 addr_size * 2, "Address", "Access",
+                 addr_size * 2, "Initial",
+                 addr_size * 2, "Sym.Val.", "Type", "Ndx", "Name");
+         sym_width = (is_32bit_elf ? 80 : 160) - 28 - addr_size * 6 - 1;
+         for (i = gotsym; i < symtabno; i++)
+           {
+             Elf_Internal_Sym *psym;
+
+             psym = dynamic_symbols + i;
+             entry = print_mips_got_entry (data, pltgot, entry);
+             printf (" ");
+             print_vma (psym->st_value, LONG_HEX);
+             printf (" %-7s %3s ",
+                     get_symbol_type (ELF_ST_TYPE (psym->st_info)),
+                     get_symbol_index_type (psym->st_shndx));
+             if (VALID_DYNAMIC_NAME (psym->st_name))
+               print_symbol (sym_width, GET_DYNAMIC_NAME (psym->st_name));
+             else
+               printf ("<corrupt: %14ld>", psym->st_name);
+             printf ("\n");
+           }
+         printf ("\n");
+       }
+
+      if (data)
+       free (data);
+    }
+
   return 1;
 }
 
@@ -9670,6 +9865,8 @@ get_gnu_elf_note_type (unsigned e_type)
       return _("NT_GNU_HWCAP (DSO-supplied software HWCAP info)");
     case NT_GNU_BUILD_ID:
       return _("NT_GNU_BUILD_ID (unique build ID bitstring)");
+    case NT_GNU_GOLD_VERSION:
+      return _("NT_GNU_GOLD_VERSION (gold version)");
     default:
       break;
     }
This page took 0.030492 seconds and 4 git commands to generate.