aboutsummaryrefslogtreecommitdiff
path: root/gold/target-reloc.h
diff options
context:
space:
mode:
authorAlan Modra <amodra@gmail.com>2015-12-09 10:18:30 +1030
committerAlan Modra <amodra@gmail.com>2015-12-09 10:36:43 +1030
commit91a65d2fe88fabe2d553a0362b2f76034f820175 (patch)
treeafa6f7c0717f26c9cd56038d3c42eeacbcbc7002 /gold/target-reloc.h
parentb7a5f21d4f98e006ac98df0c3494a6b8380917bd (diff)
downloadgdb-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/target-reloc.h')
-rw-r--r--gold/target-reloc.h14
1 files changed, 6 insertions, 8 deletions
diff --git a/gold/target-reloc.h b/gold/target-reloc.h
index 89906af..63b884f 100644
--- a/gold/target-reloc.h
+++ b/gold/target-reloc.h
@@ -297,7 +297,6 @@ relocate_section(
typename elfcpp::Elf_types<size>::Elf_WXword r_info = reloc.get_r_info();
unsigned int r_sym = elfcpp::elf_r_sym<size>(r_info);
- unsigned int r_type = elfcpp::elf_r_type<size>(r_info);
const Sized_symbol<size>* sym;
@@ -400,9 +399,9 @@ relocate_section(
if (offset < 0 || static_cast<section_size_type>(offset) >= view_size)
v = NULL;
- if (!relocate.relocate(relinfo, target, output_section, i, reloc,
- r_type, sym, psymval, v, view_address + offset,
- view_size))
+ if (!relocate.relocate(relinfo, sh_type, target, output_section,
+ i, prelocs, sym, psymval,
+ v, view_address + offset, view_size))
continue;
if (v == NULL)
@@ -443,7 +442,6 @@ apply_relocation(const Relocate_info<size, big_endian>* relinfo,
// Construct the ELF relocation in a temporary buffer.
const int reloc_size = elfcpp::Elf_sizes<size>::rela_size;
unsigned char relbuf[reloc_size];
- elfcpp::Rela<size, big_endian> rel(relbuf);
elfcpp::Rela_write<size, big_endian> orel(relbuf);
orel.put_r_offset(r_offset);
orel.put_r_info(elfcpp::elf_r_info<size>(0, r_type));
@@ -461,7 +459,8 @@ apply_relocation(const Relocate_info<size, big_endian>* relinfo,
symval.set_is_ifunc_symbol();
Relocate relocate;
- relocate.relocate(relinfo, target, NULL, -1U, rel, r_type, sym, &symval,
+ relocate.relocate(relinfo, elfcpp::SHT_RELA, target, NULL,
+ -1U, relbuf, sym, &symval,
view + r_offset, address + r_offset, view_size);
}
@@ -619,7 +618,6 @@ relocate_relocs(
size_t reloc_count,
Output_section* output_section,
typename elfcpp::Elf_types<size>::Elf_Off offset_in_output_section,
- const Relocatable_relocs* rr,
unsigned char* view,
typename elfcpp::Elf_types<size>::Elf_Addr view_address,
section_size_type view_size,
@@ -640,7 +638,7 @@ relocate_relocs(
for (size_t i = 0; i < reloc_count; ++i, prelocs += reloc_size)
{
- Relocatable_relocs::Reloc_strategy strategy = rr->strategy(i);
+ Relocatable_relocs::Reloc_strategy strategy = relinfo->rr->strategy(i);
if (strategy == Relocatable_relocs::RELOC_DISCARD)
continue;