This is the mail archive of the binutils@sourceware.org mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[gold patch ob] Fix PPC overflow checking for CHECK_LOW_INSN


> 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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]