[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.
This commit is contained in:
Alan Modra 2019-08-01 17:43:29 +09:30
parent 97c0a07968
commit 6a010cf67a
2 changed files with 17 additions and 4 deletions

View File

@ -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

View File

@ -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: