aboutsummaryrefslogtreecommitdiff
path: root/gold
diff options
context:
space:
mode:
Diffstat (limited to 'gold')
-rw-r--r--gold/ChangeLog15
-rw-r--r--gold/i386.cc8
-rw-r--r--gold/symtab.cc9
-rw-r--r--gold/symtab.h12
-rw-r--r--gold/x86_64.cc2
5 files changed, 36 insertions, 10 deletions
diff --git a/gold/ChangeLog b/gold/ChangeLog
index 9de7ff2..0affd39 100644
--- a/gold/ChangeLog
+++ b/gold/ChangeLog
@@ -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>
* arm.cc (Target_arm::arm_info): Initialize new fields
@@ -6,7 +19,7 @@
* object.cc (Sized_relobj::do_layout): Skip attribute section.
* gold/powerpc.cc (Target_powerpc::powerpc_info): Initialize new
fields attributes_section and attributes_vendor.
- * sparc.cc (Target_sparc::sparc_info): Same.
+ * sparc.cc (Target_sparc::sparc_info): Same.
* target.h (Target::attributes_section, Target::attributes_vendor,
Target::is_attributes_section, Target::attribute_arg_type,
Target::attributes_order): New method definitions.
diff --git a/gold/i386.cc b/gold/i386.cc
index f61e168..4820f15 100644
--- a/gold/i386.cc
+++ b/gold/i386.cc
@@ -1248,7 +1248,7 @@ Target_i386::Scan::global(Symbol_table* symtab,
}
// Make a dynamic relocation if necessary.
int flags = Symbol::NON_PIC_REF;
- if (gsym->type() == elfcpp::STT_FUNC)
+ if (gsym->is_func())
flags |= Symbol::FUNCTION_CALL;
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:
{
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;
if (should_apply_static_reloc(gsym, ref_flags, true, output_section))
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:
{
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;
if (should_apply_static_reloc(gsym, ref_flags, false, output_section))
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:
{
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;
if (should_apply_static_reloc(gsym, ref_flags, false,
output_section))
diff --git a/gold/symtab.cc b/gold/symtab.cc
index 7427f8e..7e8a890 100644
--- a/gold/symtab.cc
+++ b/gold/symtab.cc
@@ -2810,11 +2810,16 @@ Symbol_table::sized_write_symbol(
osym.put_st_size(0);
else
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.
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
- 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_shndx(shndx);
}
diff --git a/gold/symtab.h b/gold/symtab.h
index 544712d..c153150 100644
--- a/gold/symtab.h
+++ b/gold/symtab.h
@@ -205,6 +205,14 @@ class Symbol
type() const
{ 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.
elfcpp::STV
visibility() const
@@ -543,7 +551,7 @@ class Symbol
return (!parameters->doing_static_link()
&& !parameters->options().pie()
- && this->type() == elfcpp::STT_FUNC
+ && this->is_func()
&& (this->is_from_dynobj()
|| this->is_undefined()
|| this->is_preemptible()));
@@ -734,7 +742,7 @@ class Symbol
return (!parameters->options().shared()
&& parameters->options().copyreloc()
&& this->is_from_dynobj()
- && this->type() != elfcpp::STT_FUNC);
+ && !this->is_func());
}
protected:
diff --git a/gold/x86_64.cc b/gold/x86_64.cc
index 3b37286..e51b4ab 100644
--- a/gold/x86_64.cc
+++ b/gold/x86_64.cc
@@ -1352,7 +1352,7 @@ Target_x86_64::Scan::global(Symbol_table* symtab,
target->make_plt_entry(symtab, layout, gsym);
// Make a dynamic relocation if necessary.
int flags = Symbol::NON_PIC_REF;
- if (gsym->type() == elfcpp::STT_FUNC)
+ if (gsym->is_func())
flags |= Symbol::FUNCTION_CALL;
if (gsym->needs_dynamic_reloc(flags))
{