aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--elfcpp/elfcpp_swap.h10
-rw-r--r--gold/reloc.h20
2 files changed, 20 insertions, 10 deletions
diff --git a/elfcpp/elfcpp_swap.h b/elfcpp/elfcpp_swap.h
index 24ffccd..329ed16 100644
--- a/elfcpp/elfcpp_swap.h
+++ b/elfcpp/elfcpp_swap.h
@@ -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
diff --git a/gold/reloc.h b/gold/reloc.h
index 1ad8f25..bc538c5 100644
--- a/gold/reloc.h
+++ b/gold/reloc.h
@@ -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)