aboutsummaryrefslogtreecommitdiff
path: root/gold/arm.cc
diff options
context:
space:
mode:
authorDoug Kwan <dougkwan@google.com>2011-06-27 17:53:32 +0000
committerDoug Kwan <dougkwan@google.com>2011-06-27 17:53:32 +0000
commit57eb9b5086fe082ad965e75d199dd9d536e54250 (patch)
tree78d116aaf46e45d688a667fd1d8e874adf84be09 /gold/arm.cc
parente26bd57dea76dd8d66e51f49b29a4d39edcd62b0 (diff)
downloadfsf-binutils-gdb-57eb9b5086fe082ad965e75d199dd9d536e54250.zip
fsf-binutils-gdb-57eb9b5086fe082ad965e75d199dd9d536e54250.tar.gz
fsf-binutils-gdb-57eb9b5086fe082ad965e75d199dd9d536e54250.tar.bz2
2011-06-27 Doug Kwan <dougkwan@google.com>
* arm.cc (Arm_relocate_functions::thm_jump8, Arm_relocate_functions::thm_jump11): Use a wider signed type to compute offset. * testsuite/Makefile.am: Add new tests arm_thm_jump11 and arm_thm_jump8. * testsuite/Makefile.in: Regenerate. * testsuite/arm_branch_in_range.sh: Check test results of arm_thm_jump11 and arm_thm_jump8. * testsuite/arm_thm_jump11.s: New test source file. * testsuite/arm_thm_jump11.t: New linker script. * testsuite/arm_thm_jump8.s: New test source file. * testsuite/arm_thm_jump8.t: New linker script.
Diffstat (limited to 'gold/arm.cc')
-rw-r--r--gold/arm.cc22
1 files changed, 12 insertions, 10 deletions
diff --git a/gold/arm.cc b/gold/arm.cc
index 98e82b9..c8732e0 100644
--- a/gold/arm.cc
+++ b/gold/arm.cc
@@ -3356,13 +3356,14 @@ class Arm_relocate_functions : public Relocate_functions<32, big_endian>
Arm_address address)
{
typedef typename elfcpp::Swap<16, big_endian>::Valtype Valtype;
- typedef typename elfcpp::Swap<16, big_endian>::Valtype Reltype;
Valtype* wv = reinterpret_cast<Valtype*>(view);
Valtype val = elfcpp::Swap<16, big_endian>::readval(wv);
- Reltype addend = utils::sign_extend<8>((val & 0x00ff) << 1);
- Reltype x = (psymval->value(object, addend) - address);
- elfcpp::Swap<16, big_endian>::writeval(wv, (val & 0xff00) | ((x & 0x01fe) >> 1));
- return (utils::has_overflow<8>(x)
+ int32_t addend = utils::sign_extend<8>((val & 0x00ff) << 1);
+ int32_t x = (psymval->value(object, addend) - address);
+ elfcpp::Swap<16, big_endian>::writeval(wv, ((val & 0xff00)
+ | ((x & 0x01fe) >> 1)));
+ // We do a 9-bit overflow check because x is right-shifted by 1 bit.
+ return (utils::has_overflow<9>(x)
? This::STATUS_OVERFLOW
: This::STATUS_OKAY);
}
@@ -3375,13 +3376,14 @@ class Arm_relocate_functions : public Relocate_functions<32, big_endian>
Arm_address address)
{
typedef typename elfcpp::Swap<16, big_endian>::Valtype Valtype;
- typedef typename elfcpp::Swap<16, big_endian>::Valtype Reltype;
Valtype* wv = reinterpret_cast<Valtype*>(view);
Valtype val = elfcpp::Swap<16, big_endian>::readval(wv);
- Reltype addend = utils::sign_extend<11>((val & 0x07ff) << 1);
- Reltype x = (psymval->value(object, addend) - address);
- elfcpp::Swap<16, big_endian>::writeval(wv, (val & 0xf800) | ((x & 0x0ffe) >> 1));
- return (utils::has_overflow<11>(x)
+ int32_t addend = utils::sign_extend<11>((val & 0x07ff) << 1);
+ int32_t x = (psymval->value(object, addend) - address);
+ elfcpp::Swap<16, big_endian>::writeval(wv, ((val & 0xf800)
+ | ((x & 0x0ffe) >> 1)));
+ // We do a 12-bit overflow check because x is right-shifted by 1 bit.
+ return (utils::has_overflow<12>(x)
? This::STATUS_OVERFLOW
: This::STATUS_OKAY);
}