From b6848d3c09394cfc3ce9efd4847e1e33a43d51dd Mon Sep 17 00:00:00 2001 From: Ian Lance Taylor Date: Thu, 11 Mar 2010 01:10:53 +0000 Subject: [PATCH] * 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. --- gold/ChangeLog | 11 +++++++++++ gold/i386.cc | 16 ++++++++++++++++ gold/reloc.cc | 13 ++++++++----- gold/target.cc | 15 +++++++++++++-- gold/target.h | 14 ++++++++++++++ 5 files changed, 62 insertions(+), 7 deletions(-) diff --git a/gold/ChangeLog b/gold/ChangeLog index 3c2e610c9d5..8a1aa23040b 100644 --- a/gold/ChangeLog +++ b/gold/ChangeLog @@ -1,3 +1,14 @@ +2010-03-10 Ian Lance Taylor + + * 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 * fileread.cc (File_read::~File_read): Don't delete whole_file_view_. diff --git a/gold/i386.cc b/gold/i386.cc index e7b700c37f4..822cc7c3412 100644 --- a/gold/i386.cc +++ b/gold/i386.cc @@ -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 diff --git a/gold/reloc.cc b/gold/reloc.cc index 617573d4f67..8879f0a5042 100644 --- a/gold/reloc.cc +++ b/gold/reloc.cc @@ -1106,14 +1106,17 @@ Sized_relobj::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(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); + } } } diff --git a/gold/target.cc b/gold/target.cc index 0ddc13d68ed..e774f63cea3 100644 --- a/gold/target.cc +++ b/gold/target.cc @@ -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,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 diff --git a/gold/target.h b/gold/target.h index 673153ff936..007b16d0dec 100644 --- a/gold/target.h +++ b/gold/target.h @@ -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, -- 2.30.2