aboutsummaryrefslogtreecommitdiff
path: root/gold/sparc.cc
diff options
context:
space:
mode:
authorCary Coutant <ccoutant@gmail.com>2015-10-06 14:43:49 -0700
committerCary Coutant <ccoutant@gmail.com>2015-10-06 14:44:10 -0700
commit9eacb935acd69f6532135ec1353630db5111467c (patch)
tree5a40ad555d9ab1241c1e0c20884eda83b6f0feba /gold/sparc.cc
parent8c6da3dfbc65354975680bf7d8e273dbdca5de87 (diff)
downloadfsf-binutils-gdb-9eacb935acd69f6532135ec1353630db5111467c.zip
fsf-binutils-gdb-9eacb935acd69f6532135ec1353630db5111467c.tar.gz
fsf-binutils-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.cc16
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. */