2009-12-07 H.J. Lu <hongjiu.lu@intel.com>

PR gold/10893
	* i386.cc (Target_i386::Scan::globa): Use is_func instead of
	checking elfcpp::STT_FUNC.
	(Target_i386::Relocate::relocate): Likewise.
	* x86_64.cc (Target_x86_64::Scan::global): Likewise.

	* symtab.cc (Symbol_table::sized_write_symbol): Turn IFUNC
	symbols from shared libraries into normal FUNC symbols.

	* symtab.h (Symbol): Add is_func and use it.
This commit is contained in:
H.J. Lu
2009-12-07 17:14:55 +00:00
parent f43525316b
commit 53d7974cd8
5 changed files with 36 additions and 10 deletions

@ -1,3 +1,16 @@
2009-12-07 H.J. Lu <hongjiu.lu@intel.com>
PR gold/10893
* i386.cc (Target_i386::Scan::globa): Use is_func instead of
checking elfcpp::STT_FUNC.
(Target_i386::Relocate::relocate): Likewise.
* x86_64.cc (Target_x86_64::Scan::global): Likewise.
* symtab.cc (Symbol_table::sized_write_symbol): Turn IFUNC
symbols from shared libraries into normal FUNC symbols.
* symtab.h (Symbol): Add is_func and use it.
2009-12-05 Doug Kwan <dougkwan@google.com> 2009-12-05 Doug Kwan <dougkwan@google.com>
* arm.cc (Target_arm::arm_info): Initialize new fields * arm.cc (Target_arm::arm_info): Initialize new fields

@ -1248,7 +1248,7 @@ Target_i386::Scan::global(Symbol_table* symtab,
} }
// Make a dynamic relocation if necessary. // Make a dynamic relocation if necessary.
int flags = Symbol::NON_PIC_REF; int flags = Symbol::NON_PIC_REF;
if (gsym->type() == elfcpp::STT_FUNC) if (gsym->is_func())
flags |= Symbol::FUNCTION_CALL; flags |= Symbol::FUNCTION_CALL;
if (gsym->needs_dynamic_reloc(flags)) if (gsym->needs_dynamic_reloc(flags))
{ {
@ -1727,7 +1727,7 @@ Target_i386::Relocate::relocate(const Relocate_info<32, false>* relinfo,
case elfcpp::R_386_PC32: case elfcpp::R_386_PC32:
{ {
int ref_flags = Symbol::NON_PIC_REF; int ref_flags = Symbol::NON_PIC_REF;
if (gsym != NULL && gsym->type() == elfcpp::STT_FUNC) if (gsym != NULL && gsym->is_func())
ref_flags |= Symbol::FUNCTION_CALL; ref_flags |= Symbol::FUNCTION_CALL;
if (should_apply_static_reloc(gsym, ref_flags, true, output_section)) if (should_apply_static_reloc(gsym, ref_flags, true, output_section))
Relocate_functions<32, false>::pcrel32(view, object, psymval, address); Relocate_functions<32, false>::pcrel32(view, object, psymval, address);
@ -1743,7 +1743,7 @@ Target_i386::Relocate::relocate(const Relocate_info<32, false>* relinfo,
case elfcpp::R_386_PC16: case elfcpp::R_386_PC16:
{ {
int ref_flags = Symbol::NON_PIC_REF; int ref_flags = Symbol::NON_PIC_REF;
if (gsym != NULL && gsym->type() == elfcpp::STT_FUNC) if (gsym != NULL && gsym->is_func())
ref_flags |= Symbol::FUNCTION_CALL; ref_flags |= Symbol::FUNCTION_CALL;
if (should_apply_static_reloc(gsym, ref_flags, false, output_section)) if (should_apply_static_reloc(gsym, ref_flags, false, output_section))
Relocate_functions<32, false>::pcrel16(view, object, psymval, address); Relocate_functions<32, false>::pcrel16(view, object, psymval, address);
@ -1759,7 +1759,7 @@ Target_i386::Relocate::relocate(const Relocate_info<32, false>* relinfo,
case elfcpp::R_386_PC8: case elfcpp::R_386_PC8:
{ {
int ref_flags = Symbol::NON_PIC_REF; int ref_flags = Symbol::NON_PIC_REF;
if (gsym != NULL && gsym->type() == elfcpp::STT_FUNC) if (gsym != NULL && gsym->is_func())
ref_flags |= Symbol::FUNCTION_CALL; ref_flags |= Symbol::FUNCTION_CALL;
if (should_apply_static_reloc(gsym, ref_flags, false, if (should_apply_static_reloc(gsym, ref_flags, false,
output_section)) output_section))

@ -2810,11 +2810,16 @@ Symbol_table::sized_write_symbol(
osym.put_st_size(0); osym.put_st_size(0);
else else
osym.put_st_size(sym->symsize()); osym.put_st_size(sym->symsize());
elfcpp::STT type = sym->type();
// Turn IFUNC symbols from shared libraries into normal FUNC symbols.
if (type == elfcpp::STT_GNU_IFUNC
&& sym->is_from_dynobj())
type = elfcpp::STT_FUNC;
// A version script may have overridden the default binding. // A version script may have overridden the default binding.
if (sym->is_forced_local()) if (sym->is_forced_local())
osym.put_st_info(elfcpp::elf_st_info(elfcpp::STB_LOCAL, sym->type())); osym.put_st_info(elfcpp::elf_st_info(elfcpp::STB_LOCAL, type));
else else
osym.put_st_info(elfcpp::elf_st_info(sym->binding(), sym->type())); osym.put_st_info(elfcpp::elf_st_info(sym->binding(), type));
osym.put_st_other(elfcpp::elf_st_other(sym->visibility(), sym->nonvis())); osym.put_st_other(elfcpp::elf_st_other(sym->visibility(), sym->nonvis()));
osym.put_st_shndx(shndx); osym.put_st_shndx(shndx);
} }

@ -205,6 +205,14 @@ class Symbol
type() const type() const
{ return this->type_; } { return this->type_; }
// Return true for function symbol.
bool
is_func() const
{
return (this->type_ == elfcpp::STT_FUNC
|| this->type_ == elfcpp::STT_GNU_IFUNC);
}
// Return the symbol visibility. // Return the symbol visibility.
elfcpp::STV elfcpp::STV
visibility() const visibility() const
@ -543,7 +551,7 @@ class Symbol
return (!parameters->doing_static_link() return (!parameters->doing_static_link()
&& !parameters->options().pie() && !parameters->options().pie()
&& this->type() == elfcpp::STT_FUNC && this->is_func()
&& (this->is_from_dynobj() && (this->is_from_dynobj()
|| this->is_undefined() || this->is_undefined()
|| this->is_preemptible())); || this->is_preemptible()));
@ -734,7 +742,7 @@ class Symbol
return (!parameters->options().shared() return (!parameters->options().shared()
&& parameters->options().copyreloc() && parameters->options().copyreloc()
&& this->is_from_dynobj() && this->is_from_dynobj()
&& this->type() != elfcpp::STT_FUNC); && !this->is_func());
} }
protected: protected:

@ -1352,7 +1352,7 @@ Target_x86_64::Scan::global(Symbol_table* symtab,
target->make_plt_entry(symtab, layout, gsym); target->make_plt_entry(symtab, layout, gsym);
// Make a dynamic relocation if necessary. // Make a dynamic relocation if necessary.
int flags = Symbol::NON_PIC_REF; int flags = Symbol::NON_PIC_REF;
if (gsym->type() == elfcpp::STT_FUNC) if (gsym->is_func())
flags |= Symbol::FUNCTION_CALL; flags |= Symbol::FUNCTION_CALL;
if (gsym->needs_dynamic_reloc(flags)) if (gsym->needs_dynamic_reloc(flags))
{ {