From 5b3463d9ee95e3b9631851ef51dd37377949b06d Mon Sep 17 00:00:00 2001 From: Ian Lance Taylor Date: Mon, 1 Oct 2007 21:25:23 +0000 Subject: [PATCH] Add Signed_valtype and use it for sign extension. Fix names of rela8. --- elfcpp/elfcpp_swap.h | 10 +++++++--- gold/reloc.h | 20 +++++++++++++------- 2 files changed, 20 insertions(+), 10 deletions(-) diff --git a/elfcpp/elfcpp_swap.h b/elfcpp/elfcpp_swap.h index 24ffccd0879..329ed163831 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 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 1ad8f256156..bc538c561f8 100644 --- a/gold/reloc.h +++ b/gold/reloc.h @@ -228,14 +228,20 @@ private: const Symbol_value* psymval) { typedef typename elfcpp::Swap::Valtype Valtype; + typedef typename elfcpp::Swap::Signed_valtype + Signed_valtype; typedef typename elfcpp::Swap::Valtype Sizetype; + typedef typename elfcpp::Swap::Signed_valtype + Signed_sizetype; Valtype* wv = reinterpret_cast(view); Valtype x = elfcpp::Swap::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(x); + Signed_sizetype signed_extended_x = static_cast(signed_x); + Sizetype unsigned_extended_x = static_cast(signed_extended_x); + + x = psymval->value(object, unsigned_extended_x); elfcpp::Swap::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* object, const Symbol_value* psymval, unsigned char addend) -- 2.30.2