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::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(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,