aboutsummaryrefslogtreecommitdiff
path: root/gold/powerpc.cc
diff options
context:
space:
mode:
Diffstat (limited to 'gold/powerpc.cc')
-rw-r--r--gold/powerpc.cc17
1 files changed, 13 insertions, 4 deletions
diff --git a/gold/powerpc.cc b/gold/powerpc.cc
index 244c221..d529519 100644
--- a/gold/powerpc.cc
+++ b/gold/powerpc.cc
@@ -9734,6 +9734,8 @@ Target_powerpc<size, big_endian>::relocate_relocs(
gold_assert(got2_addend != invalid_address);
}
+ const bool relocatable = parameters->options().relocatable();
+
unsigned char* pwrite = reloc_view;
bool zap_next = false;
for (size_t i = 0; i < reloc_count; ++i, prelocs += reloc_size)
@@ -9829,7 +9831,7 @@ Target_powerpc<size, big_endian>::relocate_relocs(
// In an object file, r_offset is an offset within the section.
// In an executable or dynamic object, generated by
// --emit-relocs, r_offset is an absolute address.
- if (!parameters->options().relocatable())
+ if (!relocatable)
{
offset += view_address;
if (static_cast<Address>(offset_in_output_section) != invalid_address)
@@ -9842,8 +9844,15 @@ 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);
- gold_assert(os != NULL);
- addend = psymval->value(object, addend) - os->address();
+ addend = psymval->value(object, addend);
+ // In a relocatable link, the symbol value is relative to
+ // the start of the output section. For a non-relocatable
+ // link, we need to adjust the addend.
+ if (!relocatable)
+ {
+ gold_assert(os != NULL);
+ addend -= os->address();
+ }
}
else if (strategy == Relocatable_relocs::RELOC_SPECIAL)
{
@@ -9866,7 +9875,7 @@ Target_powerpc<size, big_endian>::relocate_relocs(
else
gold_unreachable();
- if (!parameters->options().relocatable())
+ if (!relocatable)
{
if (r_type == elfcpp::R_POWERPC_GOT_TLSGD16
|| r_type == elfcpp::R_POWERPC_GOT_TLSGD16_LO