diff options
author | Cary Coutant <ccoutant@gmail.com> | 2015-10-06 14:43:49 -0700 |
---|---|---|
committer | Cary Coutant <ccoutant@gmail.com> | 2015-10-06 14:44:10 -0700 |
commit | 9eacb935acd69f6532135ec1353630db5111467c (patch) | |
tree | 5a40ad555d9ab1241c1e0c20884eda83b6f0feba /gold/sparc.cc | |
parent | 8c6da3dfbc65354975680bf7d8e273dbdca5de87 (diff) | |
download | gdb-9eacb935acd69f6532135ec1353630db5111467c.zip gdb-9eacb935acd69f6532135ec1353630db5111467c.tar.gz gdb-9eacb935acd69f6532135ec1353630db5111467c.tar.bz2 |
Fix bug when applying R_SPARC_GOTDATA_OP* relocations to local symbols.
When applying a GOTDATA_OP* relocation to a local symbol, the addend
is being applied after getting the value of the symbol. When the
relocation refers to a merge section, however, the addend must be
provided when computing the symbol value, since the contents of
the section may have been rearranged.
gold/
PR gold/18855
* sparc.cc (Sparc_relocate_functions::gdop_hix22): Remove addend
parameter.
(Sparc_relocate_functions::gdop_lox10): Likewise.
(Target_sparc::Relocate::relocate): Use addend when computing
symbol value for R_SPARC_GOTDATA_OP*.
Diffstat (limited to 'gold/sparc.cc')
-rw-r--r-- | gold/sparc.cc | 16 |
1 files changed, 7 insertions, 9 deletions
diff --git a/gold/sparc.cc b/gold/sparc.cc index d34585a..db845b7 100644 --- a/gold/sparc.cc +++ b/gold/sparc.cc @@ -1107,13 +1107,12 @@ public: // R_SPARC_GOTDATA_OP_HIX22: @gdopoff(Symbol + Addend) >> 10 static inline void gdop_hix22(unsigned char* view, - typename elfcpp::Elf_types<size>::Elf_Addr value, - typename elfcpp::Elf_types<size>::Elf_Addr addend) + typename elfcpp::Elf_types<size>::Elf_Addr value) { typedef typename elfcpp::Swap<32, true>::Valtype Valtype; Valtype* wv = reinterpret_cast<Valtype*>(view); Valtype val = elfcpp::Swap<32, true>::readval(wv); - int32_t reloc = static_cast<int32_t>(value + addend); + int32_t reloc = static_cast<int32_t>(value); val &= ~0x3fffff; @@ -1170,13 +1169,12 @@ public: // R_SPARC_GOTDATA_OP_LOX10: (@gdopoff(Symbol + Addend) & 0x3ff) | 0x1c00 static inline void gdop_lox10(unsigned char* view, - typename elfcpp::Elf_types<size>::Elf_Addr value, - typename elfcpp::Elf_types<size>::Elf_Addr addend) + typename elfcpp::Elf_types<size>::Elf_Addr value) { typedef typename elfcpp::Swap<32, true>::Valtype Valtype; Valtype* wv = reinterpret_cast<Valtype*>(view); Valtype val = elfcpp::Swap<32, true>::readval(wv); - int32_t reloc = static_cast<int32_t>(value + addend); + int32_t reloc = static_cast<int32_t>(value); if (reloc < 0) reloc = (reloc & 0x3ff) | 0x1c00; @@ -3244,7 +3242,7 @@ Target_sparc<size, big_endian>::Relocate::relocate( && !gsym->is_preemptible() && !orig_is_ifunc)) { - got_offset = psymval->value(object, 0) - target->got_address(); + got_offset = psymval->value(object, addend) - target->got_address(); gdop_valid = true; break; } @@ -3384,7 +3382,7 @@ Target_sparc<size, big_endian>::Relocate::relocate( case elfcpp::R_SPARC_GOTDATA_OP_LOX10: if (gdop_valid) { - Reloc::gdop_lox10(view, got_offset, addend); + Reloc::gdop_lox10(view, got_offset); break; } /* Fall through. */ @@ -3395,7 +3393,7 @@ Target_sparc<size, big_endian>::Relocate::relocate( case elfcpp::R_SPARC_GOTDATA_OP_HIX22: if (gdop_valid) { - Reloc::gdop_hix22(view, got_offset, addend); + Reloc::gdop_hix22(view, got_offset); break; } /* Fall through. */ |