Index: arm.cc =================================================================== RCS file: /cvs/src/src/gold/arm.cc,v retrieving revision 1.8 diff -u -p -r1.8 arm.cc --- arm.cc 11 Aug 2009 17:09:14 -0000 1.8 +++ arm.cc 18 Sep 2009 00:42:51 -0000 @@ -117,6 +117,23 @@ namespace utils return as_signed > max || as_signed < min; } + // Detects overflow of an NO_BITS integer stored in a uint32_t when it + // fits in the given number of bits as either a signed or unsigned value. + // For example, has_signed_unsigned_overflow<8> would check + // -128 <= bits <= 255 + template + static inline bool + has_signed_unsigned_overflow(uint32_t bits) + { + gold_assert(no_bits >= 2 && no_bits <= 32); + if (no_bits == 32) + return false; + int32_t max = static_cast((1U << no_bits) - 1); + int32_t min = -(1 << (no_bits - 1)); + int32_t as_signed = static_cast(bits); + return as_signed > max || as_signed < min; + } + // Select bits from A and B using bits in MASK. For each n in [0..31], // the n-th bit in the result is chosen from the n-th bits of A and B. // A zero selects A and a one selects B. @@ -555,6 +572,26 @@ class Arm_relocate_functions : public Re } public: + + // R_ARM_ABS8: S + A + static inline typename This::Status + abs8(unsigned char *view, + const Sized_relobj<32, big_endian>* object, + const Symbol_value<32>* psymval, bool has_thumb_bit) + { + typedef typename elfcpp::Swap<8, big_endian>::Valtype Valtype; + typedef typename elfcpp::Swap<32, big_endian>::Valtype Reltype; + Valtype* wv = reinterpret_cast(view); + Valtype val = elfcpp::Swap<8, big_endian>::readval(wv); + Reltype addend = utils::sign_extend<8>(val); + Reltype x = This::arm_symbol_value(object, psymval, addend, has_thumb_bit); + val = utils::bit_select(val, x, 0xffU); + elfcpp::Swap<8, big_endian>::writeval(wv, val); + return (utils::has_signed_unsigned_overflow<8>(x) + ? This::STATUS_OVERFLOW + : This::STATUS_OKAY); + } + // R_ARM_ABS32: (S + A) | T static inline typename This::Status abs32(unsigned char *view, @@ -1074,6 +1111,15 @@ Target_arm::Scan::local(cons case elfcpp::R_ARM_NONE: break; + case elfcpp::R_ARM_ABS8: + if (parameters->options().output_is_position_independent()) + { + // FIXME: Create a dynamic relocation for this location. + gold_error(_("%s: gold bug: need dynamic ABS8 reloc"), + object->name().c_str()); + } + break; + case elfcpp::R_ARM_ABS32: // If building a shared library (or a position-independent // executable), we need to create a dynamic relocation for @@ -1187,6 +1233,16 @@ Target_arm::Scan::global(con case elfcpp::R_ARM_NONE: break; + case elfcpp::R_ARM_ABS8: + // Make a dynamic relocation if necessary. + if (gsym->needs_dynamic_reloc(Symbol::ABSOLUTE_REF)) + { + // FIXME: Create a dynamic relocation for this location. + gold_error(_("%s: gold bug: need dynamic ABS8 reloc for %s"), + object->name().c_str(), gsym->demangled_name().c_str()); + } + break; + case elfcpp::R_ARM_ABS32: { // Make a dynamic relocation if necessary. @@ -1595,6 +1651,13 @@ Target_arm::Relocate::reloca case elfcpp::R_ARM_NONE: break; + case elfcpp::R_ARM_ABS8: + if (should_apply_static_reloc(gsym, Symbol::ABSOLUTE_REF, false, + output_section)) + reloc_status = Arm_relocate_functions::abs8(view, object, psymval, + has_thumb_bit); + break; + case elfcpp::R_ARM_ABS32: if (should_apply_static_reloc(gsym, Symbol::ABSOLUTE_REF, true, output_section)) @@ -1764,6 +1827,9 @@ Target_arm::Relocatable_size case elfcpp::R_ARM_NONE: return 0; + case elfcpp::R_ARM_ABS8: + return 1; + case elfcpp::R_ARM_ABS32: case elfcpp::R_ARM_REL32: case elfcpp::R_ARM_THM_CALL: