aboutsummaryrefslogtreecommitdiff
path: root/gold
diff options
context:
space:
mode:
authorAlan Modra <amodra@gmail.com>2015-08-20 12:02:45 +0930
committerAlan Modra <amodra@gmail.com>2015-08-20 12:02:45 +0930
commit9215b98bb27c071386a277f5578dbb17569a1471 (patch)
tree62014c06b7d3255ba6b1833c41aa654a8c6056b6 /gold
parent9d1f51209437ebee8f0a930b9613d59759ea8dc0 (diff)
downloadbinutils-9215b98bb27c071386a277f5578dbb17569a1471.zip
binutils-9215b98bb27c071386a277f5578dbb17569a1471.tar.gz
binutils-9215b98bb27c071386a277f5578dbb17569a1471.tar.bz2
gold --emit-relocs
A symbol value in an ELF final linked binary is absolute, in contrast to a relocatable object file where the value is section relative. For --emit-relocs it is therefore incorrect to use the value of a section symbol as the addend when adjusting relocs against input section symbols to output section symbols. PR gold/18846 * target-reloc.h (relocate_relocs <RELOC_ADJUST_FOR_SECTION_RELA>): Subtract os->address() from addend. * powerpc.cc (relocate_relocs): Likewise.
Diffstat (limited to 'gold')
-rw-r--r--gold/ChangeLog7
-rw-r--r--gold/powerpc.cc6
-rw-r--r--gold/target-reloc.h6
3 files changed, 15 insertions, 4 deletions
diff --git a/gold/ChangeLog b/gold/ChangeLog
index 0c5a40c..b3417b2 100644
--- a/gold/ChangeLog
+++ b/gold/ChangeLog
@@ -1,3 +1,10 @@
+2015-08-20 Alan Modra <amodra@gmail.com>
+
+ PR gold/18846
+ * target-reloc.h (relocate_relocs <RELOC_ADJUST_FOR_SECTION_RELA>):
+ Subtract os->address() from addend.
+ * powerpc.cc (relocate_relocs): Likewise.
+
2015-08-12 Simon Dardis <simon.dardis@imgtec.com>
* mips.cc (plt0_entry_o32, plt0_entry_n32, plt0_entry_n64,
diff --git a/gold/powerpc.cc b/gold/powerpc.cc
index 540e197..3311a1d 100644
--- a/gold/powerpc.cc
+++ b/gold/powerpc.cc
@@ -8110,6 +8110,7 @@ Target_powerpc<size, big_endian>::relocate_relocs(
}
// Get the new symbol index.
+ Output_section* os = NULL;
if (r_sym < local_count)
{
switch (strategy)
@@ -8134,7 +8135,7 @@ Target_powerpc<size, big_endian>::relocate_relocs(
unsigned int shndx =
object->local_symbol_input_shndx(r_sym, &is_ordinary);
gold_assert(is_ordinary);
- Output_section* os = object->output_section(shndx);
+ os = object->output_section(shndx);
gold_assert(os != NULL);
gold_assert(os->needs_symtab_index());
r_sym = os->symtab_index();
@@ -8187,7 +8188,8 @@ Target_powerpc<size, big_endian>::relocate_relocs(
else if (strategy == Relocatable_relocs::RELOC_ADJUST_FOR_SECTION_RELA)
{
const Symbol_value<size>* psymval = object->local_symbol(orig_r_sym);
- addend = psymval->value(object, addend);
+ gold_assert(os != NULL);
+ addend = psymval->value(object, addend) - os->address();
}
else if (strategy == Relocatable_relocs::RELOC_SPECIAL)
{
diff --git a/gold/target-reloc.h b/gold/target-reloc.h
index c135459..89906af 100644
--- a/gold/target-reloc.h
+++ b/gold/target-reloc.h
@@ -666,6 +666,7 @@ relocate_relocs(
// Get the new symbol index.
+ Output_section* os = NULL;
unsigned int new_symndx;
if (r_sym < local_count)
{
@@ -698,7 +699,7 @@ relocate_relocs(
unsigned int shndx =
object->local_symbol_input_shndx(r_sym, &is_ordinary);
gold_assert(is_ordinary);
- Output_section* os = object->output_section(shndx);
+ os = object->output_section(shndx);
gold_assert(os != NULL);
gold_assert(os->needs_symtab_index());
new_symndx = os->symtab_index();
@@ -780,7 +781,8 @@ relocate_relocs(
typename elfcpp::Elf_types<size>::Elf_Swxword addend;
addend = Reloc_types<sh_type, size, big_endian>::
get_reloc_addend(&reloc);
- addend = psymval->value(object, addend);
+ gold_assert(os != NULL);
+ addend = psymval->value(object, addend) - os->address();
Reloc_types<sh_type, size, big_endian>::
set_reloc_addend(&reloc_write, addend);
}