* 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.
This commit is contained in:
parent
e469c7fb68
commit
b6848d3c09
5 changed files with 63 additions and 8 deletions
|
@ -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_.
|
||||
|
|
16
gold/i386.cc
16
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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -21,10 +21,11 @@
|
|||
// MA 02110-1301, USA.
|
||||
|
||||
#include "gold.h"
|
||||
#include "target.h"
|
||||
#include "dynobj.h"
|
||||
#include "output.h"
|
||||
#include "elfcpp.h"
|
||||
#include "dynobj.h"
|
||||
#include "symtab.h"
|
||||
#include "output.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
|
||||
|
|
|
@ -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,
|
||||
|
|
Loading…
Add table
Reference in a new issue