From: Alan Modra Date: Thu, 1 Aug 2019 08:13:29 +0000 (+0930) Subject: [GOLD] PowerPC relocation signed overflow check X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=6a010cf67a96adcaf80c74f926df6b42ce13e7df;p=binutils-gdb.git [GOLD] PowerPC relocation signed overflow check Relocations with right shifts were calculating wrong overflow status. Since the addr34 split-field reloc is implemented as an 18-bit high part with value shifted right by 16 and a 16-bit low part, most of the pc-relative relocs were affected. * powerpc.cc (Powerpc_relocate_functions::rela, rela_ua): Perform signed right shift for signed overflow check. --- diff --git a/gold/ChangeLog b/gold/ChangeLog index 754d0e3eb20..b2961d72f21 100644 --- a/gold/ChangeLog +++ b/gold/ChangeLog @@ -1,3 +1,8 @@ +2019-08-02 Alan Modra + + * powerpc.cc (Powerpc_relocate_functions::rela, rela_ua): Perform + signed right shift for signed overflow check. + 2019-07-29 Martin Liska PR 24768 diff --git a/gold/powerpc.cc b/gold/powerpc.cc index 688f7243d32..67c3061bb3e 100644 --- a/gold/powerpc.cc +++ b/gold/powerpc.cc @@ -1996,11 +1996,15 @@ private: typedef typename elfcpp::Swap::Valtype Valtype; Valtype* wv = reinterpret_cast(view); Valtype val = elfcpp::Swap::readval(wv); - Valtype reloc = value >> right_shift; + if (overflow == CHECK_SIGNED) + value = static_cast(value) >> right_shift; + else + value = value >> right_shift; + Valtype reloc = value; val &= ~dst_mask; reloc &= dst_mask; elfcpp::Swap::writeval(wv, val | reloc); - return overflowed(value >> right_shift, overflow); + return overflowed(value, overflow); } // Do a simple RELA relocation, unaligned. @@ -2023,11 +2027,15 @@ private: typedef typename elfcpp::Swap_unaligned::Valtype Valtype; Valtype val = elfcpp::Swap::readval(view); - Valtype reloc = value >> right_shift; + if (overflow == CHECK_SIGNED) + value = static_cast(value) >> right_shift; + else + value = value >> right_shift; + Valtype reloc = value; val &= ~dst_mask; reloc &= dst_mask; elfcpp::Swap_unaligned::writeval(view, val | reloc); - return overflowed(value >> right_shift, overflow); + return overflowed(value, overflow); } public: