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:
Cary Coutant 2016-02-06 22:42:16 -08:00
parent 30914ca8c0
commit 7c8b700c92
2 changed files with 16 additions and 2 deletions

View File

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

View File

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