* options.h (class General_options): Define

split_stack_adjust_size parameter.
	* object.h (class Object): Add uses_split_stack_ and
	has_no_split_stack_ fields.  Add uses_split_stack and
	has_no_split_stack accessor functions.  Declare
	handle_split_stack_section.
	(class Reloc_symbol_changes): Define.
	(class Sized_relobj): Define Function_offsets.  Declare
	split_stack_adjust, split_stack_adjust_reltype, and
	find_functions.
	* object.cc (Object::handle_split_stack_section): New function.
	(Sized_relobj::do_layout): Call handle_split_stack_section.
	* dynobj.cc (Sized_dynobj::do_layout): Call
	handle_split_stack_section.
	* reloc.cc (Sized_relobj::relocate_sections): Call
	split_stack_adjust for executable sections in split_stack
	objects.  Pass reloc_map to relocate_section.
	(Sized_relobj::split_stack_adjust): New function.
	(Sized_relobj::split_stack_adjust_reltype): New function.
	(Sized_relobj::find_functions): New function.
	* target-reloc.h: Include "object.h".
	(relocate_section): Add reloc_symbol_changes parameter.  Change
	all callers.
	* target.h (class Target): Add calls_non_split method.  Declare
	do_calls_non_split virtual method.  Declare match_view and
	set_view_to_nop.
	* target.cc: Include "elfcpp.h".
	(Target::do_calls_non_split): New function.
	(Target::match_view): New function.
	(Target::set_view_to_nop): New function.
	* gold.cc (queue_middle_tasks): Give an error if mixing
	split-stack and non-split-stack objects with -r.
	* i386.cc (Target_i386::relocate_section): Add
	reloc_symbol_changes parameter.
	(Target_i386::do_calls_non_split): New function.
	* x86_64.cc (Target_x86_64::relocate_section): Add
	reloc_symbol_changes parameter.
	(Target_x86_64::do_calls_non_split): New function.
	* arm.cc (Target_arm::relocate_section): Add reloc_symbol_changes
	parameter.
	* powerpc.cc (Target_powerpc::relocate_section): Add
	reloc_symbol_changes parameter.
	* sparc.cc (Target_sparc::relocate_section): Add
	reloc_symbol_changes parameter.
	* configure.ac: Call AM_CONDITIONAL for the default target.
	* configure: Rebuild.
	* testsuite/Makefile.am (TEST_AS): New variable.
	(check_SCRIPTS): Add split_i386.sh and split_x86_64.sh.
	(check_DATA): Add split_i386 and split_x86_64 files.
	(SPLIT_DEFSYMS): Define.
	(split_i386_[1234n].o): New targets.
	(split_i386_[124]): New targets.
	(split_i386_[1234r].stdout): New targets.
	(split_x86_64_[1234n].o): New targets.
	(split_x86_64_[124]): New targets.
	(split_x86_64_[1234r].stdout): New targets.
	(MOSTLYCLEANFILES): Add new executables.
	* testsuite/split_i386.sh: New file.
	* testsuite/split_x86_64.sh: New file.
	* testsuite/split_i386_1.s: New file.
	* testsuite/split_i386_2.s: New file.
	* testsuite/split_i386_3.s: New file.
	* testsuite/split_i386_4.s: New file.
	* testsuite/split_i386_n.s: New file.
	* testsuite/split_x86_64_1.s: New file.
	* testsuite/split_x86_64_2.s: New file.
	* testsuite/split_x86_64_3.s: New file.
	* testsuite/split_x86_64_4.s: New file.
	* testsuite/split_x86_64_n.s: New file.
	* testsuite/testfile.cc (Target_test): Update relocation_section
	function.
	* testsuite/Makefile.in: Rebuild.
This commit is contained in:
Ian Lance Taylor
2009-10-06 22:58:27 +00:00
parent 5aafa1cc49
commit 364c7fa5c9
32 changed files with 1321 additions and 63 deletions

View File

@@ -25,6 +25,7 @@
#include "elfcpp.h"
#include "symtab.h"
#include "object.h"
#include "reloc.h"
#include "reloc-types.h"
@@ -163,6 +164,12 @@ get_comdat_behavior(const char* name)
// NEEDS_SPECIAL_OFFSET_HANDLING is true, in which case they refer to
// the output section.
// RELOC_SYMBOL_CHANGES is used for -fsplit-stack support. If it is
// not NULL, it is a vector indexed by relocation index. If that
// entry is not NULL, it points to a global symbol which used as the
// symbol for the relocation, ignoring the symbol index in the
// relocation.
template<int size, bool big_endian, typename Target_type, int sh_type,
typename Relocate>
inline void
@@ -175,7 +182,8 @@ relocate_section(
bool needs_special_offset_handling,
unsigned char* view,
typename elfcpp::Elf_types<size>::Elf_Addr view_address,
section_size_type view_size)
section_size_type view_size,
const Reloc_symbol_changes* reloc_symbol_changes)
{
typedef typename Reloc_types<sh_type, size, big_endian>::Reloc Reltype;
const int reloc_size = Reloc_types<sh_type, size, big_endian>::reloc_size;
@@ -210,7 +218,9 @@ relocate_section(
Symbol_value<size> symval;
const Symbol_value<size> *psymval;
if (r_sym < local_count)
if (r_sym < local_count
&& (reloc_symbol_changes == NULL
|| (*reloc_symbol_changes)[i] == NULL))
{
sym = NULL;
psymval = object->local_symbol(r_sym);
@@ -246,7 +256,7 @@ relocate_section(
{
if (comdat_behavior == CB_WARNING)
gold_warning_at_location(relinfo, i, offset,
_("Relocation refers to discarded "
_("relocation refers to discarded "
"comdat section"));
symval.set_output_value(0);
}
@@ -256,10 +266,17 @@ relocate_section(
}
else
{
const Symbol* gsym = object->global_symbol(r_sym);
gold_assert(gsym != NULL);
if (gsym->is_forwarder())
gsym = relinfo->symtab->resolve_forwards(gsym);
const Symbol* gsym;
if (reloc_symbol_changes != NULL
&& (*reloc_symbol_changes)[i] != NULL)
gsym = (*reloc_symbol_changes)[i];
else
{
gsym = object->global_symbol(r_sym);
gold_assert(gsym != NULL);
if (gsym->is_forwarder())
gsym = relinfo->symtab->resolve_forwards(gsym);
}
sym = static_cast<const Sized_symbol<size>*>(gsym);
if (sym->has_symtab_index())