diff options
-rw-r--r-- | gold/ChangeLog | 5 | ||||
-rw-r--r-- | gold/powerpc.cc | 16 |
2 files changed, 17 insertions, 4 deletions
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 <amodra@gmail.com> + + * powerpc.cc (Powerpc_relocate_functions::rela, rela_ua): Perform + signed right shift for signed overflow check. + 2019-07-29 Martin Liska <mliska@suse.cz> 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<fieldsize, big_endian>::Valtype Valtype; Valtype* wv = reinterpret_cast<Valtype*>(view); Valtype val = elfcpp::Swap<fieldsize, big_endian>::readval(wv); - Valtype reloc = value >> right_shift; + if (overflow == CHECK_SIGNED) + value = static_cast<SignedAddress>(value) >> right_shift; + else + value = value >> right_shift; + Valtype reloc = value; val &= ~dst_mask; reloc &= dst_mask; elfcpp::Swap<fieldsize, big_endian>::writeval(wv, val | reloc); - return overflowed<valsize>(value >> right_shift, overflow); + return overflowed<valsize>(value, overflow); } // Do a simple RELA relocation, unaligned. @@ -2023,11 +2027,15 @@ private: typedef typename elfcpp::Swap_unaligned<fieldsize, big_endian>::Valtype Valtype; Valtype val = elfcpp::Swap<fieldsize, big_endian>::readval(view); - Valtype reloc = value >> right_shift; + if (overflow == CHECK_SIGNED) + value = static_cast<SignedAddress>(value) >> right_shift; + else + value = value >> right_shift; + Valtype reloc = value; val &= ~dst_mask; reloc &= dst_mask; elfcpp::Swap_unaligned<fieldsize, big_endian>::writeval(view, val | reloc); - return overflowed<valsize>(value >> right_shift, overflow); + return overflowed<valsize>(value, overflow); } public: |