aboutsummaryrefslogtreecommitdiff
path: root/gold
diff options
context:
space:
mode:
authorAlan Modra <amodra@gmail.com>2014-12-04 21:10:40 +1030
committerAlan Modra <amodra@gmail.com>2014-12-04 21:17:54 +1030
commitcbcb23fa01027a7fe1be938d58ef8e7a60b5fb7e (patch)
tree38d9034618f627b69f3305d7fb740e7fd8eb5306 /gold
parentba715d7fe49c8a59660fbd571b935b29eb7cfbdb (diff)
downloadfsf-binutils-gdb-cbcb23fa01027a7fe1be938d58ef8e7a60b5fb7e.zip
fsf-binutils-gdb-cbcb23fa01027a7fe1be938d58ef8e7a60b5fb7e.tar.gz
fsf-binutils-gdb-cbcb23fa01027a7fe1be938d58ef8e7a60b5fb7e.tar.bz2
PowerPC gold, fix 32-bit branch address arithmetic
Mixing 64-bit and 32-bit types led to the wrong promotions. Keep calculation in same type. Also fix a case where PLTREL25 reloc addend should be ignored. * Powerpc.cc (Target_powerpc::Branch_info::make_stub): Ignore addend of PLTREL24 reloc when not generating a plt stub. Make max_branch_offset an "Address". (Stub_table::can_read_stub): Make max_branch_offset an "Address". (Target_powerpc::Relocate::relocate): Likewise.
Diffstat (limited to 'gold')
-rw-r--r--gold/ChangeLog8
-rw-r--r--gold/powerpc.cc11
2 files changed, 14 insertions, 5 deletions
diff --git a/gold/ChangeLog b/gold/ChangeLog
index 8ab8387..503198e 100644
--- a/gold/ChangeLog
+++ b/gold/ChangeLog
@@ -1,5 +1,13 @@
2014-12-04 Alan Modra <amodra@gmail.com>
+ * powerpc.cc (Target_powerpc::Branch_info::make_stub): Ignore
+ addend of PLTREL24 reloc when not generating a plt stub. Make
+ max_branch_offset an "Address".
+ (Stub_table::can_read_stub): Make max_branch_offset an "Address".
+ (Target_powerpc::Relocate::relocate): Likewise.
+
+2014-12-04 Alan Modra <amodra@gmail.com>
+
PR 17670
* symtab.cc (Symbol::set_undefined): Remove assertion.
* powerpc.cc (Target_powerpc::symval_for_branch): Don't assert
diff --git a/gold/powerpc.cc b/gold/powerpc.cc
index 0da355f..1407a0e 100644
--- a/gold/powerpc.cc
+++ b/gold/powerpc.cc
@@ -2657,7 +2657,7 @@ Target_powerpc<size, big_endian>::Branch_info::make_stub(
}
else
{
- unsigned long max_branch_offset = max_branch_delta(this->r_type_);
+ Address max_branch_offset = max_branch_delta(this->r_type_);
if (max_branch_offset == 0)
return true;
Address from = this->object_->get_output_section_offset(this->shndx_);
@@ -2711,7 +2711,8 @@ Target_powerpc<size, big_endian>::Branch_info::make_stub(
if (size == 64)
to += this->object_->ppc64_local_entry_offset(this->r_sym_);
}
- to += this->addend_;
+ if (!(size == 32 && this->r_type_ == elfcpp::R_PPC_PLTREL24))
+ to += this->addend_;
if (stub_table == NULL)
stub_table = this->object_->stub_table(this->shndx_);
if (size == 64 && target->abiversion() < 2)
@@ -3627,7 +3628,7 @@ class Stub_table : public Output_relaxed_input_section
bool
can_reach_stub(Address from, unsigned int off, unsigned int r_type)
{
- unsigned long max_branch_offset = max_branch_delta(r_type);
+ Address max_branch_offset = max_branch_delta(r_type);
if (max_branch_offset == 0)
return true;
gold_assert(from != invalid_address);
@@ -7197,7 +7198,7 @@ Target_powerpc<size, big_endian>::Relocate::relocate(
else if (!has_stub_value)
{
Address addend = 0;
- if (r_type != elfcpp::R_PPC_PLTREL24)
+ if (!(size == 32 && r_type == elfcpp::R_PPC_PLTREL24))
addend = rela.get_r_addend();
value = psymval->value(object, addend);
if (size == 64 && is_branch_reloc(r_type))
@@ -7216,7 +7217,7 @@ Target_powerpc<size, big_endian>::Relocate::relocate(
&value, &dest_shndx);
}
}
- unsigned long max_branch_offset = max_branch_delta(r_type);
+ Address max_branch_offset = max_branch_delta(r_type);
if (max_branch_offset != 0
&& value - address + max_branch_offset >= 2 * max_branch_offset)
{