* reloc.cc (Sized_relobj::split_stack_adjust_reltype): Call the
authorIan Lance Taylor <ian@airs.com>
Thu, 11 Mar 2010 01:10:53 +0000 (01:10 +0000)
committerIan Lance Taylor <ian@airs.com>
Thu, 11 Mar 2010 01:10:53 +0000 (01:10 +0000)
target to ask whether a reference to a symbol requires a stack
split.
* target.h (Target::is_call_to_non_split): New function.
(Target::do_is_call_to_non_split): Declare virtual function.
* target.cc: Include "symtab.h".
(Target::do_is_call_to_non_split): New function.
* i386.cc (Target_i386::do_is_call_to_non_split): New function.

gold/ChangeLog
gold/i386.cc
gold/reloc.cc
gold/target.cc
gold/target.h

index 3c2e610c9d5196c40deee2294d41519d3d7320c8..8a1aa23040b50e4dfec29361398f7adb0281712b 100644 (file)
@@ -1,3 +1,14 @@
+2010-03-10  Ian Lance Taylor  <iant@google.com>
+
+       * reloc.cc (Sized_relobj::split_stack_adjust_reltype): Call the
+       target to ask whether a reference to a symbol requires a stack
+       split.
+       * target.h (Target::is_call_to_non_split): New function.
+       (Target::do_is_call_to_non_split): Declare virtual function.
+       * target.cc: Include "symtab.h".
+       (Target::do_is_call_to_non_split): New function.
+       * i386.cc (Target_i386::do_is_call_to_non_split): New function.
+
 2010-03-10  Cary Coutant  <ccoutant@google.com>
 
        * fileread.cc (File_read::~File_read): Don't delete whole_file_view_.
index e7b700c37f41c63bd2b80884d1cc1ea437c7c108..822cc7c341238e844b2ed25c847d3ddd2f98515d 100644 (file)
@@ -171,6 +171,10 @@ class Target_i386 : public Target_freebsd<32, false>
     return Target::do_is_local_label_name(name);
   }
 
+  // Return whether SYM is call to a non-split function.
+  bool
+  do_is_call_to_non_split(const Symbol* sym, unsigned int) const;
+
   // Adjust -fstack-split code which calls non-stack-split code.
   void
   do_calls_non_split(Relobj* object, unsigned int shndx,
@@ -2776,6 +2780,18 @@ Target_i386::do_code_fill(section_size_type length) const
   return std::string(nops[length], length);
 }
 
+// Return whether SYM should be treated as a call to a non-split
+// function.  We don't want that to be true of a call to a
+// get_pc_thunk function.
+
+bool
+Target_i386::do_is_call_to_non_split(const Symbol* sym, unsigned int) const
+{
+  return (sym->type() == elfcpp::STT_FUNC
+         && !this->is_defined_by_abi(sym)
+         && !is_prefix_of("__i686.get_pc_thunk.", sym->name()));
+}
+
 // FNOFFSET in section SHNDX in OBJECT is the start of a function
 // compiled with -fstack-split.  The function calls non-stack-split
 // code.  We have to change the function so that it always ensures
index 617573d4f6726094221bbb847b5723f39a49390e..8879f0a5042703d72256ee82eb792e1d134e520d 100644 (file)
@@ -1106,14 +1106,17 @@ Sized_relobj<size, big_endian>::split_stack_adjust_reltype(
       // cases we will ask for a large stack unnecessarily, but this
       // is not fatal.  FIXME: Some targets have symbols which are
       // functions but are not type STT_FUNC, e.g., STT_ARM_TFUNC.
-      if (gsym->type() == elfcpp::STT_FUNC
-         && !gsym->is_undefined()
+      if (!gsym->is_undefined()
          && gsym->source() == Symbol::FROM_OBJECT
          && !gsym->object()->uses_split_stack())
        {
-         section_offset_type offset =
-           convert_to_section_size_type(reloc.get_r_offset());
-         non_split_refs.push_back(offset);
+         unsigned int r_type = elfcpp::elf_r_type<size>(reloc.get_r_info());
+         if (parameters->target().is_call_to_non_split(gsym, r_type))
+           {
+             section_offset_type offset =
+               convert_to_section_size_type(reloc.get_r_offset());
+             non_split_refs.push_back(offset);
+           }
        }
     }
 
index 0ddc13d68ed91b0a67afa6d8f60d187e705cd733..e774f63cea338d5cb99d870b9b513a549b7b37c5 100644 (file)
 // MA 02110-1301, USA.
 
 #include "gold.h"
-#include "target.h"
+#include "elfcpp.h"
 #include "dynobj.h"
+#include "symtab.h"
 #include "output.h"
-#include "elfcpp.h"
+#include "target.h"
 
 namespace gold
 {
@@ -144,6 +145,16 @@ Target::do_make_output_section(const char* name, elfcpp::Elf_Word type,
   return new Output_section(name, type, flags);
 }
 
+// Default for whether a reloc is a call to a non-split function is if
+// the symbol is a function not defined by the ABI.
+
+bool
+Target::do_is_call_to_non_split(const Symbol* sym, unsigned int) const
+{
+  return (sym->type() == elfcpp::STT_FUNC
+         && !this->is_defined_by_abi(sym));
+}
+
 // Default conversion for -fsplit-stack is to give an error.
 
 void
index 673153ff9368deb2bd6998ed3d778af4fe7ae4ca..007b16d0dec4232b790f1013f2a2f3bbf5b60776 100644 (file)
@@ -247,6 +247,14 @@ class Target
   reloc_addend(void* arg, unsigned int type, uint64_t addend) const
   { return this->do_reloc_addend(arg, type, addend); }
 
+  // Return true if a reference to SYM from a reloc of type R_TYPE
+  // means that the current function may call an object compiled
+  // without -fsplit-stack.  SYM is known to be defined in an object
+  // compiled without -fsplit-stack.
+  bool
+  is_call_to_non_split(const Symbol* sym, unsigned int r_type) const
+  { return this->do_is_call_to_non_split(sym, r_type); }
+
   // A function starts at OFFSET in section SHNDX in OBJECT.  That
   // function was compiled with -fsplit-stack, but it refers to a
   // function which was compiled without -fsplit-stack.  VIEW is a
@@ -440,6 +448,12 @@ class Target
   do_reloc_addend(void*, unsigned int, uint64_t) const
   { gold_unreachable(); }
 
+  // Virtual function which may be overridden by the child class.  The
+  // default implementation is that any function not defined by the
+  // ABI is a call to a non-split function.
+  virtual bool
+  do_is_call_to_non_split(const Symbol* sym, unsigned int) const;
+
   // Virtual function which may be overridden by the child class.
   virtual void
   do_calls_non_split(Relobj* object, unsigned int, section_offset_type,