From: Alan Modra Date: Thu, 20 Aug 2015 02:32:45 +0000 (+0930) Subject: gold --emit-relocs X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=9215b98bb27c071386a277f5578dbb17569a1471;p=binutils-gdb.git 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 ): Subtract os->address() from addend. * powerpc.cc (relocate_relocs): Likewise. --- diff --git a/gold/ChangeLog b/gold/ChangeLog index 0c5a40c3e29..b3417b2149d 100644 --- a/gold/ChangeLog +++ b/gold/ChangeLog @@ -1,3 +1,10 @@ +2015-08-20 Alan Modra + + PR gold/18846 + * target-reloc.h (relocate_relocs ): + Subtract os->address() from addend. + * powerpc.cc (relocate_relocs): Likewise. + 2015-08-12 Simon Dardis * mips.cc (plt0_entry_o32, plt0_entry_n32, plt0_entry_n64, diff --git a/gold/powerpc.cc b/gold/powerpc.cc index 540e1977c62..3311a1d5126 100644 --- a/gold/powerpc.cc +++ b/gold/powerpc.cc @@ -8110,6 +8110,7 @@ Target_powerpc::relocate_relocs( } // Get the new symbol index. + Output_section* os = NULL; if (r_sym < local_count) { switch (strategy) @@ -8134,7 +8135,7 @@ Target_powerpc::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::relocate_relocs( else if (strategy == Relocatable_relocs::RELOC_ADJUST_FOR_SECTION_RELA) { const Symbol_value* 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 c13545942aa..89906af2b4a 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::Elf_Swxword addend; addend = Reloc_types:: get_reloc_addend(&reloc); - addend = psymval->value(object, addend); + gold_assert(os != NULL); + addend = psymval->value(object, addend) - os->address(); Reloc_types:: set_reloc_addend(&reloc_write, addend); }