This is the mail archive of the binutils@sourceware.org mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: COMMITTED: Add support for STT_IFUNC


Hi Hans-Peter, (and others who noticed this problem)

My autotester complains; it looks like this introduces a test
failure for cris-axis-elf:

That would be because old bozo brain here forgot to check in the changes in the binutils directory. I have now applied the attached patch to fix this problem.


Cheers
  Nick

binutils/ChangeLog
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.
Index: binutils/objdump.c
===================================================================
RCS file: /cvs/src/src/binutils/objdump.c,v
retrieving revision 1.148
diff -c -3 -p -r1.148 objdump.c
*** binutils/objdump.c	14 Nov 2008 14:56:51 -0000	1.148
--- binutils/objdump.c	4 Dec 2008 07:58:12 -0000
*************** dump_reloc_set (bfd *abfd, asection *sec
*** 2718,2725 ****
  	printf (" %-16s  ", q->howto->name);
        else
  	printf (" %-16d  ", q->howto->type);
        if (sym_name)
! 	objdump_print_symname (abfd, NULL, *q->sym_ptr_ptr);
        else
  	{
  	  if (section_name == NULL)
--- 2718,2730 ----
  	printf (" %-16s  ", q->howto->name);
        else
  	printf (" %-16d  ", q->howto->type);
+ 
        if (sym_name)
! 	{
! 	  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: binutils/readelf.c
===================================================================
RCS file: /cvs/src/src/binutils/readelf.c,v
retrieving revision 1.430
diff -c -3 -p -r1.430 readelf.c
*** binutils/readelf.c	18 Nov 2008 15:45:03 -0000	1.430
--- binutils/readelf.c	4 Dec 2008 07:58:14 -0000
*************** print_vma (bfd_vma vma, print_mode mode)
*** 414,448 ****
    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.  */
  
! static void
  print_symbol (int width, const char *symbol)
  {
-   const char * format_string;
    const char * c;
  
    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";
      }
  
    while (width)
--- 414,444 ----
    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.
! 
!    Returns the number of emitted characters.  */
! 
! static unsigned int
  print_symbol (int width, const char *symbol)
  {
    const char * c;
+   bfd_boolean extra_padding = FALSE;
+   unsigned int num_printed = 0;
  
    if (do_wide)
      {
        /* Set the width to a very large value.  This simplifies the code below.  */
        width = INT_MAX;
      }
    else if (width < 0)
      {
        /* Keep the width positive.  This also helps.  */
        width = - width;
!       extra_padding = TRUE;
      }
  
    while (width)
*************** print_symbol (int width, const char *sym
*** 464,472 ****
  	  if (len > width)
  	    len = width;
  
! 	  printf (format_string, len, symbol);
  
  	  width -= len;
  	}
  
        if (* c == 0 || width == 0)
--- 460,469 ----
  	  if (len > width)
  	    len = width;
  
! 	  printf ("%.*s", len, symbol);
  
  	  width -= len;
+ 	  num_printed += len;
  	}
  
        if (* c == 0 || width == 0)
*************** print_symbol (int width, const char *sym
*** 482,487 ****
--- 479,485 ----
  	  printf ("^%c", *c + 0x40);
  
  	  width -= 2;
+ 	  num_printed += 2;
  	}
        else
  	{
*************** print_symbol (int width, const char *sym
*** 491,500 ****
--- 489,508 ----
  	  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
*************** dump_relocations (FILE *file,
*** 1242,1249 ****
  	      psym = symtab + symtab_index;
  
  	      printf (" ");
! 	      print_vma (psym->st_value, LONG_HEX);
! 	      printf (is_32bit_elf ? "   " : " ");
  
  	      if (psym->st_name == 0)
  		{
--- 1250,1288 ----
  	      psym = symtab + symtab_index;
  
  	      printf (" ");
! 
! 	      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)
  		{
*************** dump_relocations (FILE *file,
*** 1294,1300 ****
  		print_symbol (22, strtab + psym->st_name);
  
  	      if (is_rela)
! 		printf (" + %lx", (unsigned long) rels[i].r_addend);
  	    }
  	}
        else if (is_rela)
--- 1333,1346 ----
  		print_symbol (22, strtab + psym->st_name);
  
  	      if (is_rela)
! 		{
! 		  long offset = (long) (bfd_signed_vma) rels[i].r_addend;
! 
! 		  if (offset < 0)
! 		    printf (" - %lx", - offset);
! 		  else
! 		    printf (" + %lx", offset);
! 		}
  	    }
  	}
        else if (is_rela)
*************** get_symbol_type (unsigned int type)
*** 7019,7024 ****
--- 7065,7078 ----
  	      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);
  	}
Index: binutils/doc/binutils.texi
===================================================================
RCS file: /cvs/src/src/binutils/doc/binutils.texi,v
retrieving revision 1.132
diff -c -3 -p -r1.132 binutils.texi
*** binutils/doc/binutils.texi	19 Nov 2008 16:22:47 -0000	1.132
--- binutils/doc/binutils.texi	4 Dec 2008 07:58:16 -0000
*************** symbol's name is a message to be display
*** 2045,2052 ****
  warning symbol is ever referenced.
  
  @item I
! The symbol is an indirect reference to another symbol (I) or a normal
! symbol (a space).
  
  @item d
  @itemx D
--- 2045,2054 ----
  warning symbol is ever referenced.
  
  @item I
! @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 Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]