This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
gold patch committed: Calls to __i686.get_pc_thunk.bx don't split stack
- From: Ian Lance Taylor <iant at google dot com>
- To: binutils at sourceware dot org
- Date: Wed, 10 Mar 2010 17:18:38 -0800
- Subject: gold patch committed: Calls to __i686.get_pc_thunk.bx don't split stack
When gold was changing functions to force a stack split for the i386
target, it considered a call to the function __i686.get_pc_thunk.bx to
force a stack split. That is pointless since that function, created
by gcc, does not use any stack space. Calls to that function appear
in any -fPIC code which refers to a global variable, so they are
fairly common. Committed to mainline.
Ian
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.
Index: i386.cc
===================================================================
RCS file: /cvs/src/src/gold/i386.cc,v
retrieving revision 1.115
diff -p -u -r1.115 i386.cc
--- i386.cc 4 Mar 2010 01:33:22 -0000 1.115
+++ i386.cc 11 Mar 2010 01:03:23 -0000
@@ -171,6 +171,10 @@ class Target_i386 : public Target_freebs
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,17 @@ Target_i386::do_code_fill(section_size_t
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
+ && !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: reloc.cc
===================================================================
RCS file: /cvs/src/src/gold/reloc.cc,v
retrieving revision 1.55
diff -p -u -r1.55 reloc.cc
--- reloc.cc 10 Mar 2010 17:37:11 -0000 1.55
+++ reloc.cc 11 Mar 2010 01:03:33 -0000
@@ -1106,14 +1106,17 @@ Sized_relobj<size, big_endian>::split_st
// 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: target.cc
===================================================================
RCS file: /cvs/src/src/gold/target.cc,v
retrieving revision 1.5
diff -p -u -r1.5 target.cc
--- target.cc 9 Oct 2009 23:18:19 -0000 1.5
+++ target.cc 11 Mar 2010 01:03:33 -0000
@@ -21,10 +21,11 @@
// 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,15 @@ Target::do_make_output_section(const cha
return new Output_section(name, type, flags);
}
+// Default for whether a reloc is a call to a non-split function is
+// whether the symbol is a function.
+
+bool
+Target::do_is_call_to_non_split(const Symbol* sym, unsigned int) const
+{
+ return sym->type() == elfcpp::STT_FUNC;
+}
+
// Default conversion for -fsplit-stack is to give an error.
void
Index: target.h
===================================================================
RCS file: /cvs/src/src/gold/target.h,v
retrieving revision 1.45
diff -p -u -r1.45 target.h
--- target.h 13 Feb 2010 02:04:21 -0000 1.45
+++ target.h 11 Mar 2010 01:03:34 -0000
@@ -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,