Add Signed_valtype and use it for sign extension. Fix names of rela8.

This commit is contained in:
Ian Lance Taylor 2007-10-01 21:25:23 +00:00
parent 3a9eaa7da6
commit 5b3463d9ee
2 changed files with 20 additions and 10 deletions

View File

@ -53,8 +53,8 @@ struct Endian
};
// Valtype_base is a template based on size (8, 16, 32, 64) which
// defines the type Valtype as the unsigned integer of the specified
// size.
// defines the type Valtype as the unsigned integer, and
// Signed_valtype as the signed integer, of the specified size.
template<int size>
struct Valtype_base;
@ -62,25 +62,29 @@ struct Valtype_base;
template<>
struct Valtype_base<8>
{
typedef unsigned char Valtype;
typedef uint8_t Valtype;
typedef int8_t Signed_valtype;
};
template<>
struct Valtype_base<16>
{
typedef uint16_t Valtype;
typedef int16_t Signed_valtype;
};
template<>
struct Valtype_base<32>
{
typedef uint32_t Valtype;
typedef int32_t Signed_valtype;
};
template<>
struct Valtype_base<64>
{
typedef uint64_t Valtype;
typedef int64_t Signed_valtype;
};
// Convert_endian is a template based on size and on whether the host

View File

@ -228,14 +228,20 @@ private:
const Symbol_value<size>* psymval)
{
typedef typename elfcpp::Swap<valsize, big_endian>::Valtype Valtype;
typedef typename elfcpp::Swap<valsize, big_endian>::Signed_valtype
Signed_valtype;
typedef typename elfcpp::Swap<size, big_endian>::Valtype Sizetype;
typedef typename elfcpp::Swap<size, big_endian>::Signed_valtype
Signed_sizetype;
Valtype* wv = reinterpret_cast<Valtype*>(view);
Valtype x = elfcpp::Swap<valsize, big_endian>::readval(wv);
// Fancy formula to sign-extend x to size.
const Sizetype mask = 1U << (sizeof(valsize) * 8 - 1);
Sizetype sign_extended_x = x;
sign_extended_x = (sign_extended_x ^ mask) - mask;
x = psymval->value(object, sign_extended_x);
// Sign extend the value.
Signed_valtype signed_x = static_cast<Signed_valtype>(x);
Signed_sizetype signed_extended_x = static_cast<Signed_sizetype>(signed_x);
Sizetype unsigned_extended_x = static_cast<Sizetype>(signed_extended_x);
x = psymval->value(object, unsigned_extended_x);
elfcpp::Swap<valsize, big_endian>::writeval(wv, x);
}
@ -317,11 +323,11 @@ public:
// Do an 8-bit RELA relocation with the addend in the relocation.
static inline void
rel8a(unsigned char* view, unsigned char value, unsigned char addend)
rela8(unsigned char* view, unsigned char value, unsigned char addend)
{ This::template rela<8>(view, value, addend); }
static inline void
rel8a(unsigned char* view,
rela8(unsigned char* view,
const Sized_relobj<size, big_endian>* object,
const Symbol_value<size>* psymval,
unsigned char addend)