forked from Imagelibrary/binutils-gdb
[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:
@@ -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:
|
||||
|
||||
Reference in New Issue
Block a user