mirror of
https://github.com/darlinghq/darling-gdb.git
synced 2025-01-09 13:40:47 +00:00
Fix incorrect x32 overflow checking for refs to weak undef symbols.
On x32, a pc-relative reference to an undef weak symbol (value 0) with a negative addend (typically -4) generates a spurious overflow error because Symbol_value::value() returns a 32-bit negative number as an unsigned number, which gets zero-extended before subtracting the PC value. This patch fixes the problem by special-casing the negative addend, and adding it to the value after widening it to 64 bits. Symbol_value::value() does not need the addend if it's negative, since it is only important when processing section symbols for merge sections, where a positive addend provides the input section offset of the merged constant. gold/ * x86_64.cc (X86_64_relocate_functions::pcrela32_check): Fix x32 overflow checking when symbol value + addend < 0.
This commit is contained in:
parent
30914ca8c0
commit
7c8b700c92
@ -1,3 +1,8 @@
|
||||
2016-02-06 Cary Coutant <ccoutant@gmail.com>
|
||||
|
||||
* x86_64.cc (X86_64_relocate_functions::pcrela32_check): Fix x32
|
||||
overflow checking when symbol value + addend < 0.
|
||||
|
||||
2016-02-06 Cary Coutant <ccoutant@gmail.com>
|
||||
|
||||
PR gold/19577
|
||||
|
@ -3385,8 +3385,17 @@ class X86_64_relocate_functions : public Relocate_functions<size, false>
|
||||
{
|
||||
typedef typename elfcpp::Swap<32, false>::Valtype Valtype;
|
||||
Valtype* wv = reinterpret_cast<Valtype*>(view);
|
||||
typename elfcpp::Elf_types<64>::Elf_Addr value =
|
||||
psymval->value(object, addend) - address;
|
||||
typename elfcpp::Elf_types<64>::Elf_Addr value;
|
||||
if (addend >= 0)
|
||||
value = psymval->value(object, addend);
|
||||
else
|
||||
{
|
||||
// For negative addends, get the symbol value without
|
||||
// the addend, then add the addend using 64-bit arithmetic.
|
||||
value = psymval->value(object, 0);
|
||||
value += addend;
|
||||
}
|
||||
value -= address;
|
||||
elfcpp::Swap<32, false>::writeval(wv, value);
|
||||
return (Bits<32>::has_overflow(value)
|
||||
? Base::RELOC_OVERFLOW : Base::RELOC_OK);
|
||||
|
Loading…
Reference in New Issue
Block a user