This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
[gold patch ob] Fix PPC overflow checking for CHECK_LOW_INSN
- From: Cary Coutant <ccoutant at google dot com>
- To: Binutils <binutils at sourceware dot org>
- Cc: Austin Clements <austin at google dot com>, Ian Lance Taylor <iant at google dot com>, Alan Modra <amodra at gmail dot com>
- Date: Mon, 22 Dec 2014 10:17:08 -0800
- Subject: [gold patch ob] Fix PPC overflow checking for CHECK_LOW_INSN
- Authentication-results: sourceware.org; auth=none
> On Mon, Dec 22, 2014 at 8:19 AM, Austin Clements <austin@google.com> wrote:
>>
>> Under some situations, Target_powerpc<size, big_endian>::Relocate::relocate
>> will do a signed 16-bit overflow check instead of an unsigned 16-bit
>> overflow check. Specifically, when transforming overflow == CHECK_LOW_INSN
>> to CHECK_SIGNED/CHECK_UNSIGNED (line 7528 in binutils HEAD), relocate sets
>> overflow to CHECK_SIGNED *before* testing whether it's CHECK_LOW_INSN or
>> not. As a result, it will treat both CHECK_LOW_INSN and CHECK_HIGH_INSN as
>> CHECK_HIGH_INSN, resulting in a signed check for addi, ori, and xori
>> instructions rather than an unsigned check.
>>
>> I suspect this isn't causing trouble in practice simply because only a
>> handful of relocations need low 16-bit overflow checks and GCC probably
>> never generates an addi, ori, or xori instruction in conjunction with these
>> relocations. But it's also easy to fix.
I've committed the following patch.
Thanks, Austin!
-cary
2014-12-22 Cary Coutant <ccoutant@google.com>
gold/
* powerpc.cc (Target_powerpc::relocate): Fix overflow check.
diff --git a/gold/powerpc.cc b/gold/powerpc.cc
index 1407a0e..e456c85 100644
--- a/gold/powerpc.cc
+++ b/gold/powerpc.cc
@@ -7531,7 +7531,6 @@ Target_powerpc<size, big_endian>::Relocate::relocate(
Insn* iview = reinterpret_cast<Insn*>(view - 2 * big_endian);
Insn insn = elfcpp::Swap<32, big_endian>::readval(iview);
- overflow = Reloc::CHECK_SIGNED;
if ((insn & (0x3f << 26)) == 10u << 26 /* cmpli */)
overflow = Reloc::CHECK_BITFIELD;
else if (overflow == Reloc::CHECK_LOW_INSN
@@ -7542,6 +7541,8 @@ Target_powerpc<size, big_endian>::Relocate::relocate(
|| (insn & (0x3f << 26)) == 25u << 26 /* oris */
|| (insn & (0x3f << 26)) == 27u << 26 /* xoris */))
overflow = Reloc::CHECK_UNSIGNED;
+ else
+ overflow = Reloc::CHECK_SIGNED;
}
typename Powerpc_relocate_functions<size, big_endian>::Status status