* objdump.c (dump_reloc_set): Append "()" to symbol names which
authorNick Clifton <nickc@redhat.com>
Thu, 4 Dec 2008 08:04:47 +0000 (08:04 +0000)
committerNick Clifton <nickc@redhat.com>
Thu, 4 Dec 2008 08:04:47 +0000 (08:04 +0000)
  have the BSF_INDIRECT_FUNCTION type.
  * readelf.c (print_symbol): Fix handling of negative widths.
  (dump_relocations): Append "()" to symbol names which have the
  STT_IFUNC type. Display negative offsets as a positive number with
  a "-" prefix.
  (get_symbol_type): Return "IFUNC" for STT_IFUNC symbols.
  * doc/binutils.texi: Document 'i' symbol type.

binutils/ChangeLog
binutils/doc/binutils.texi
binutils/objdump.c
binutils/readelf.c

index 7d0c9a463923789d7291d2de327562b579876033..db2a7e067dd101ec437546bd98912ec04ce04e71 100644 (file)
@@ -1,3 +1,14 @@
+2008-12-04  Nick Clifton  <nickc@redhat.com>
+
+       * objdump.c (dump_reloc_set): Append "()" to symbol names which
+       have the BSF_INDIRECT_FUNCTION type.
+       * readelf.c (print_symbol): Fix handling of negative widths.
+       (dump_relocations): Append "()" to symbol names which have the
+       STT_IFUNC type. Display negative offsets as a positive number with
+       a "-" prefix.
+       (get_symbol_type): Return "IFUNC" for STT_IFUNC symbols.
+       * doc/binutils.texi: Document 'i' symbol type.
+
 2008-11-26  Jan Kratochvil  <jan.kratochvil@redhat.com>
 
        * strings.c (main): New variable `s'.  Have string_min parsing
index 2e7aa2b9c08c31718c30796bfba6340562da9732..100b0f53d92137d75ecb85a0264d6e06eecf8118 100644 (file)
@@ -2045,8 +2045,10 @@ symbol's name is a message to be displayed if the symbol following the
 warning symbol is ever referenced.
 
 @item I
-The symbol is an indirect reference to another symbol (I) or a normal
-symbol (a space).
+@item i
+The symbol is an indirect reference to another symbol (I), a function
+to be evaluated during reloc processing (i) or a normal symbol (a
+space).
 
 @item d
 @itemx D
index b1411d978a7836ff570cff1bb0fd61f3b0ee3b20..ac5fa0d4afdd1cdff7ffacc0e8f1d381d38cd715 100644 (file)
@@ -2718,8 +2718,13 @@ dump_reloc_set (bfd *abfd, asection *sec, arelent **relpp, long relcount)
        printf (" %-16s  ", q->howto->name);
       else
        printf (" %-16d  ", q->howto->type);
+
       if (sym_name)
-       objdump_print_symname (abfd, NULL, *q->sym_ptr_ptr);
+       {
+         objdump_print_symname (abfd, NULL, *q->sym_ptr_ptr);
+         if ((*q->sym_ptr_ptr)->flags & BSF_INDIRECT_FUNCTION)
+           printf ("() ");
+       }
       else
        {
          if (section_name == NULL)
index 02de84c43ad7b18043d088de02015c6bb8400809..8bf0d7674426ee754660f03b94a6ad31ebd5871c 100644 (file)
@@ -414,35 +414,31 @@ print_vma (bfd_vma vma, print_mode mode)
   return 0;
 }
 
-/* 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.  */
+/* Display a symbol on stdout.  Handles the display of non-printing characters.
 
-static void
+   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.
+
+   Returns the number of emitted characters.  */
+
+static unsigned int
 print_symbol (int width, const char *symbol)
 {
-  const char * format_string;
   const char * c;
+  bfd_boolean extra_padding = FALSE;
+  unsigned int num_printed = 0;
 
   if (do_wide)
     {
-      format_string = "%.*s";
       /* Set the width to a very large value.  This simplifies the code below.  */
       width = INT_MAX;
     }
   else if (width < 0)
     {
-      format_string = "%-*.*2s";
       /* Keep the width positive.  This also helps.  */
       width = - width;
-    }
-  else
-    {
-      format_string = "%-.*s";
+      extra_padding = TRUE;
     }
 
   while (width)
@@ -464,9 +460,10 @@ print_symbol (int width, const char *symbol)
          if (len > width)
            len = width;
 
-         printf (format_string, len, symbol);
+         printf ("%.*s", len, symbol);
 
          width -= len;
+         num_printed += len;
        }
 
       if (* c == 0 || width == 0)
@@ -482,6 +479,7 @@ print_symbol (int width, const char *symbol)
          printf ("^%c", *c + 0x40);
 
          width -= 2;
+         num_printed += 2;
        }
       else
        {
@@ -491,10 +489,20 @@ print_symbol (int width, const char *symbol)
          printf ("<0x%.2x>", *c);
 
          width -= 6;
+         num_printed += 6;
        }
 
       symbol = c + 1;
     }
+
+  if (extra_padding && width > 0)
+    {
+      /* Fill in the remaining spaces.  */
+      printf ("%-*s", width, " ");
+      num_printed += 2;
+    }
+
+  return num_printed;
 }
 
 static void
@@ -1242,8 +1250,39 @@ dump_relocations (FILE *file,
              psym = symtab + symtab_index;
 
              printf (" ");
-             print_vma (psym->st_value, LONG_HEX);
-             printf (is_32bit_elf ? "   " : " ");
+
+             if (ELF_ST_TYPE (psym->st_info) == STT_IFUNC)
+               {
+                 const char * name;
+                 unsigned int len;
+                 unsigned int width = is_32bit_elf ? 8 : 14;
+
+                 /* Relocations against IFUNC symbols do not use the value of
+                    the symbol as the address to relocate against.  Instead
+                    they invoke the function named by the symbol and use its
+                    result as the address for relocation.
+
+                    To indicate this to the user, do not display the value of
+                    the symbol in the "Symbols's Value" field.  Instead show
+                    its name followed by () as a hint that the symbol is
+                    invoked.  */
+
+                 if (strtab == NULL
+                     || psym->st_name == 0
+                     || psym->st_name >= strtablen)
+                   name = "??";
+                 else
+                   name = strtab + psym->st_name;
+
+                 len = print_symbol (width, name);
+                 printf ("()%-*s", len <= width ? (width + 1) - len : 1, " ");
+               }
+             else
+               {
+                 print_vma (psym->st_value, LONG_HEX);
+
+                 printf (is_32bit_elf ? "   " : " ");
+               }
 
              if (psym->st_name == 0)
                {
@@ -1294,7 +1333,14 @@ dump_relocations (FILE *file,
                print_symbol (22, strtab + psym->st_name);
 
              if (is_rela)
-               printf (" + %lx", (unsigned long) rels[i].r_addend);
+               {
+                 long offset = (long) (bfd_signed_vma) rels[i].r_addend;
+
+                 if (offset < 0)
+                   printf (" - %lx", - offset);
+                 else
+                   printf (" + %lx", offset);
+               }
            }
        }
       else if (is_rela)
@@ -7019,6 +7065,14 @@ get_symbol_type (unsigned int type)
              if (type == STT_HP_STUB)
                return "HP_STUB";
            }
+         else if (elf_header.e_ident[EI_OSABI] == ELFOSABI_LINUX
+                  || elf_header.e_ident[EI_OSABI] == ELFOSABI_HURD
+                  /* GNU/Linux is still using the default value 0.  */
+                  || elf_header.e_ident[EI_OSABI] == ELFOSABI_NONE)
+           {
+             if (type == STT_IFUNC)
+               return "IFUNC";
+           }
 
          snprintf (buff, sizeof (buff), _("<OS specific>: %d"), type);
        }