2009-12-07 H.J. Lu <hongjiu.lu@intel.com>
authorH.J. Lu <hjl.tools@gmail.com>
Mon, 7 Dec 2009 17:14:55 +0000 (17:14 +0000)
committerH.J. Lu <hjl.tools@gmail.com>
Mon, 7 Dec 2009 17:14:55 +0000 (17:14 +0000)
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.

gold/ChangeLog
gold/i386.cc
gold/symtab.cc
gold/symtab.h
gold/x86_64.cc

index 9de7ff2705e6b2d7a22b41b7764ea700ec5e8a3f..0affd39cc6d2a925ed77b58169c1168ec68503cd 100644 (file)
@@ -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.
index f61e168f9a8ea75f0f33733881e017f0d87f334d..4820f15aaf6ebbb2af26cc87ea992bd0dca98533 100644 (file)
@@ -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))
index 7427f8e03f9fe70f6dc84f64c274c88ff8b323c7..7e8a89021d979148128ca1aa0083f84ae8f6fd25 100644 (file)
@@ -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);
 }
index 544712db9f5e890eb2d1e72a2f7934e00db3dce0..c153150e1be42bddfebc01356c74a084f3102a49 100644 (file)
@@ -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:
index 3b37286e60878191fa50195a7ce0d0fb5e714715..e51b4ab74d2cab38fd55d0a87cd48a4f21590ab0 100644 (file)
@@ -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))
           {