aboutsummaryrefslogtreecommitdiff
path: root/gold/target-reloc.h
diff options
context:
space:
mode:
authorIan Lance Taylor <ian@airs.com>2009-10-06 22:58:27 +0000
committerIan Lance Taylor <ian@airs.com>2009-10-06 22:58:27 +0000
commit364c7fa5c98a7e2d75fe33ecb1ec4f7260849731 (patch)
tree2cfca9a55836527ac65fea760844754fe93f01a9 /gold/target-reloc.h
parent5aafa1cc49c9a87aeb3e0aeaede8155fdf9f1645 (diff)
downloadfsf-binutils-gdb-364c7fa5c98a7e2d75fe33ecb1ec4f7260849731.zip
fsf-binutils-gdb-364c7fa5c98a7e2d75fe33ecb1ec4f7260849731.tar.gz
fsf-binutils-gdb-364c7fa5c98a7e2d75fe33ecb1ec4f7260849731.tar.bz2
* 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.
Diffstat (limited to 'gold/target-reloc.h')
-rw-r--r--gold/target-reloc.h31
1 files changed, 24 insertions, 7 deletions
diff --git a/gold/target-reloc.h b/gold/target-reloc.h
index d93e755..bc00123 100644
--- a/gold/target-reloc.h
+++ b/gold/target-reloc.h
@@ -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())