diff options
author | Alan Modra <amodra@gmail.com> | 2015-12-09 10:18:30 +1030 |
---|---|---|
committer | Alan Modra <amodra@gmail.com> | 2015-12-09 10:36:43 +1030 |
commit | 91a65d2fe88fabe2d553a0362b2f76034f820175 (patch) | |
tree | afa6f7c0717f26c9cd56038d3c42eeacbcbc7002 /gold/mips.cc | |
parent | b7a5f21d4f98e006ac98df0c3494a6b8380917bd (diff) | |
download | gdb-91a65d2fe88fabe2d553a0362b2f76034f820175.zip gdb-91a65d2fe88fabe2d553a0362b2f76034f820175.tar.gz gdb-91a65d2fe88fabe2d553a0362b2f76034f820175.tar.bz2 |
[GOLD] Relocate::relocate() params
Some linker code editing needs to change multiple insns. In some
cases multiple relocations are involved and it is not sufficient to
make the changes independently as relocations are processed, because
doing so might lead to a partial edit. So in order to safely edit we
need all the relocations available in relocate(). Also, to emit
edited relocs corresponding to the edited code sequence we need some
way to pass information from relocate() to relocate_relocs(),
particularly if the edit depends on insns. We can't modify input
relocs in relocate() as they are mmapped PROT_READ, nor it is
particularly clean to write relocs to the output at that stage. So
add a Relocatable_relocs* field to relinfo to mark edited relocs.
Given that relocate is passed the raw reloc pointer, it makes sense to
remove the rel/rela parameter and r_type too. However, that means the
mips relocate() needs to know whether SHT_REL or SHT_RELA relocs are
being processed. So add a rel_type for mips, which also has the
benefit of removing relocate() overloading there.
This patch adds the infrastructure without making use of it.
Note that relinfo->rr will be NULL if not outputting relocations.
* object.h (struct Relocate_info): Add "rr".
* reloc.h (Relocatable_relocs::set_strategy): New accessor.
* reloc.cc (Sized_relobj_file::do_relocate_sections): Init
relinfo.rr for relocate_section and relocate_relocs.
* powerpc.cc (relocate): Add rel_type and preloc parameters.
Delete rela and r_type params, instead recalculate these from
preloc.
(relocate_relocs): Delete Relocatable_relocs* param, instead
use relinfo->rr.
* aarch64.cc: Likewise.
* arm.cc: Likewise.
* i386.cc: Likewise.
* mips.cc: Likewise.
* s390.cc: Likewise.
* sparc.cc: Likewise.
* target.h: Likewise.
* tilegx.cc: Likewise.
* x86_64.cc: Likewise.
* testsuite/testfile.cc: Likewise.
* target-reloc.h (relocate_section): Adjust to suit.
(apply_relocation, relocate_relocs): Likewise.
Diffstat (limited to 'gold/mips.cc')
-rw-r--r-- | gold/mips.cc | 120 |
1 files changed, 15 insertions, 105 deletions
diff --git a/gold/mips.cc b/gold/mips.cc index 051d49a..af4c9af 100644 --- a/gold/mips.cc +++ b/gold/mips.cc @@ -2964,7 +2964,6 @@ class Target_mips : public Sized_target<size, big_endian> Output_section* output_section, typename elfcpp::Elf_types<size>::Elf_Off offset_in_output_section, - const Relocatable_relocs*, unsigned char* view, Mips_address view_address, section_size_type view_size, @@ -3392,36 +3391,10 @@ class Target_mips : public Sized_target<size, big_endian> // Do a relocation. Return false if the caller should not issue // any warnings about this relocation. inline bool - relocate(const Relocate_info<size, big_endian>*, Target_mips*, - Output_section*, size_t relnum, - const elfcpp::Rela<size, big_endian>*, - const elfcpp::Rel<size, big_endian>*, - unsigned int, - unsigned int, const Sized_symbol<size>*, - const Symbol_value<size>*, - unsigned char*, - Mips_address, - section_size_type); - - inline bool - relocate(const Relocate_info<size, big_endian>*, Target_mips*, - Output_section*, size_t relnum, - const elfcpp::Rel<size, big_endian>&, - unsigned int, const Sized_symbol<size>*, - const Symbol_value<size>*, - unsigned char*, - Mips_address, - section_size_type); - - inline bool - relocate(const Relocate_info<size, big_endian>*, Target_mips*, - Output_section*, size_t relnum, - const elfcpp::Rela<size, big_endian>&, - unsigned int, const Sized_symbol<size>*, - const Symbol_value<size>*, - unsigned char*, - Mips_address, - section_size_type); + relocate(const Relocate_info<size, big_endian>*, unsigned int, + Target_mips*, Output_section*, size_t, const unsigned char*, + const Sized_symbol<size>*, const Symbol_value<size>*, + unsigned char*, Mips_address, section_size_type); }; // A class which returns the size required for a relocation type, @@ -8278,7 +8251,7 @@ Target_mips<size, big_endian>::relocate_section( view, address, view_size, - reloc_symbol_changes); + reloc_symbol_changes); } // Return the size of a relocation while scanning during a relocatable @@ -8403,7 +8376,6 @@ Target_mips<size, big_endian>::relocate_relocs( Output_section* output_section, typename elfcpp::Elf_types<size>::Elf_Off offset_in_output_section, - const Relocatable_relocs* rr, unsigned char* view, Mips_address view_address, section_size_type view_size, @@ -8418,7 +8390,6 @@ Target_mips<size, big_endian>::relocate_relocs( reloc_count, output_section, offset_in_output_section, - rr, view, view_address, view_size, @@ -9563,13 +9534,11 @@ template<int size, bool big_endian> inline bool Target_mips<size, big_endian>::Relocate::relocate( const Relocate_info<size, big_endian>* relinfo, + unsigned int rel_type, Target_mips* target, Output_section* output_section, size_t relnum, - const elfcpp::Rela<size, big_endian>* rela, - const elfcpp::Rel<size, big_endian>* rel, - unsigned int rel_type, - unsigned int r_type, + const unsigned char* preloc, const Sized_symbol<size>* gsym, const Symbol_value<size>* psymval, unsigned char* view, @@ -9582,16 +9551,19 @@ Target_mips<size, big_endian>::Relocate::relocate( if (rel_type == elfcpp::SHT_RELA) { - r_offset = rela->get_r_offset(); - r_info = rela->get_r_info(); - r_addend = rela->get_r_addend(); + const elfcpp::Rela<size, big_endian> rela(preloc); + r_offset = rela.get_r_offset(); + r_info = rela.get_r_info(); + r_addend = rela.get_r_addend(); } else { - r_offset = rel->get_r_offset(); - r_info = rel->get_r_info(); + const elfcpp::Rel<size, big_endian> rel(preloc); + r_offset = rel.get_r_offset(); + r_info = rel.get_r_info(); r_addend = 0; } + unsigned int r_type = elfcpp::elf_r_type<size>(r_info); typedef Mips_relocate_functions<size, big_endian> Reloc_funcs; typename Reloc_funcs::Status reloc_status = Reloc_funcs::STATUS_OKAY; @@ -10188,68 +10160,6 @@ Target_mips<size, big_endian>::Relocate::relocate( return true; } -template<int size, bool big_endian> -inline bool -Target_mips<size, big_endian>::Relocate::relocate( - const Relocate_info<size, big_endian>* relinfo, - Target_mips* target, - Output_section* output_section, - size_t relnum, - const elfcpp::Rela<size, big_endian>& reloc, - unsigned int r_type, - const Sized_symbol<size>* gsym, - const Symbol_value<size>* psymval, - unsigned char* view, - Mips_address address, - section_size_type view_size) -{ - return relocate( - relinfo, - target, - output_section, - relnum, - &reloc, - (const elfcpp::Rel<size, big_endian>*) NULL, - elfcpp::SHT_RELA, - r_type, - gsym, - psymval, - view, - address, - view_size); -} - -template<int size, bool big_endian> -inline bool -Target_mips<size, big_endian>::Relocate::relocate( - const Relocate_info<size, big_endian>* relinfo, - Target_mips* target, - Output_section* output_section, - size_t relnum, - const elfcpp::Rel<size, big_endian>& reloc, - unsigned int r_type, - const Sized_symbol<size>* gsym, - const Symbol_value<size>* psymval, - unsigned char* view, - Mips_address address, - section_size_type view_size) -{ - return relocate( - relinfo, - target, - output_section, - relnum, - (const elfcpp::Rela<size, big_endian>*) NULL, - &reloc, - elfcpp::SHT_REL, - r_type, - gsym, - psymval, - view, - address, - view_size); -} - // Get the Reference_flags for a particular relocation. template<int size, bool big_endian> |