Add Signed_valtype and use it for sign extension. Fix names of rela8.
authorIan Lance Taylor <iant@google.com>
Mon, 1 Oct 2007 21:25:23 +0000 (21:25 +0000)
committerIan Lance Taylor <iant@google.com>
Mon, 1 Oct 2007 21:25:23 +0000 (21:25 +0000)
elfcpp/elfcpp_swap.h
gold/reloc.h

index 24ffccd0879fb6b6d3c19aeb3da1d5b2fe8a3337..329ed163831af55aef3767164b80ec74c51d9923 100644 (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
index 1ad8f2561562f02f6bd5711f35ea800f93bbf83d..bc538c561f86d8a70445b4e7053aea47ae9ca8de 100644 (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)