+ public:
+ typedef typename elfcpp::Elf_types<size>::Elf_Addr Address;
+ typedef typename elfcpp::Elf_types<size>::Elf_Swxword Addendtype;
+
+ enum Overflow_check
+ {
+ // No overflow checking.
+ CHECK_NONE,
+ // Check for overflow of a signed value.
+ CHECK_SIGNED,
+ // Check for overflow of an unsigned value.
+ CHECK_UNSIGNED,
+ // Check for overflow of a signed or unsigned value.
+ // (i.e., no error if either signed or unsigned fits.)
+ CHECK_SIGNED_OR_UNSIGNED
+ };
+
+ enum Reloc_status
+ {
+ RELOC_OK,
+ RELOC_OVERFLOW
+ };
+
+ private:
+ // Check for overflow.
+ template<int valsize>
+ static inline Reloc_status
+ check_overflow(Address value, Overflow_check check)
+ {
+ switch (check)
+ {
+ case CHECK_SIGNED:
+ if (size == 32)
+ return (Bits<valsize>::has_overflow32(value)
+ ? RELOC_OVERFLOW
+ : RELOC_OK);
+ else
+ return (Bits<valsize>::has_overflow(value)
+ ? RELOC_OVERFLOW
+ : RELOC_OK);
+ case CHECK_UNSIGNED:
+ if (size == 32)
+ return (Bits<valsize>::has_unsigned_overflow32(value)
+ ? RELOC_OVERFLOW
+ : RELOC_OK);
+ else
+ return (Bits<valsize>::has_unsigned_overflow(value)
+ ? RELOC_OVERFLOW
+ : RELOC_OK);
+ case CHECK_SIGNED_OR_UNSIGNED:
+ if (size == 32)
+ return (Bits<valsize>::has_signed_unsigned_overflow32(value)
+ ? RELOC_OVERFLOW
+ : RELOC_OK);
+ else
+ return (Bits<valsize>::has_signed_unsigned_overflow64(value)
+ ? RELOC_OVERFLOW
+ : RELOC_OK);
+ case CHECK_NONE:
+ default:
+ return RELOC_OK;
+ }
+ }
+