* 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.
This commit is contained in:
Nick Clifton 2008-12-04 08:04:47 +00:00
parent 77a4f04d80
commit 171191bac5
4 changed files with 94 additions and 22 deletions

View 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

View 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

View 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)

View 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);
}