From 6a010cf67a96adcaf80c74f926df6b42ce13e7df Mon Sep 17 00:00:00 2001 From: Alan Modra Date: Thu, 1 Aug 2019 17:43:29 +0930 Subject: [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. --- gold/ChangeLog | 5 +++++ gold/powerpc.cc | 16 ++++++++++++---- 2 files changed, 17 insertions(+), 4 deletions(-) (limited to 'gold') diff --git a/gold/ChangeLog b/gold/ChangeLog index 754d0e3..b2961d7 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 688f724..67c3061 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: -- cgit v1.1