[GOLD][PATCH] Addend reader struct for stubs.

View: New views
2 Messages — Rating Filter:   Alert me  

[GOLD][PATCH] Addend reader struct for stubs.

by Doug Kwan (關振德) :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Hi,

   This is a helper struct to read relocation addends.  It is
partially specialized for REL and RELA sections.   This is the last
new class added for stub generation.

-Doug

2009-10-30  Doug Kwan  <dougkwan@...>

        * arm.cc (Stub_addend_reader): New struct template definition
        and partial specializations.
        (Stub_addend_reader::operator()): New method definition for a
        partially specialized template.

Index: gold/arm.cc
===================================================================
RCS file: /cvs/src/src/gold/arm.cc,v
retrieving revision 1.24
diff -u -p -r1.24 arm.cc
--- gold/arm.cc 30 Oct 2009 18:49:59 -0000 1.24
+++ gold/arm.cc 30 Oct 2009 19:44:38 -0000
@@ -1029,6 +1029,52 @@ class Arm_dynobj : public Sized_dynobj<3
   elfcpp::Elf_Word processor_specific_flags_;
 };
 
+// Functor to read reloc addends during stub generation.
+
+template<int sh_type, bool big_endian>
+struct Stub_addend_reader
+{
+  // Return the addend for a relocation of a particular type.  Depending
+  // on whether this is a REL or RELA relocation, read the addend from a
+  // view or from a Reloc object.
+  elfcpp::Elf_types<32>::Elf_Swxword
+  operator()(
+    unsigned int /* r_type */,
+    const unsigned char* /* view */,
+    const typename Reloc_types<sh_type,
+       32, big_endian>::Reloc& /* reloc */) const
+  { gold_unreachable(); }
+};
+
+// Specialized Stub_addend_reader for SHT_REL type relocation sections.
+
+template<bool big_endian>
+struct Stub_addend_reader<elfcpp::SHT_REL, big_endian>
+{
+  elfcpp::Elf_types<32>::Elf_Swxword
+  operator()(
+    unsigned int,
+    const unsigned char*,
+    const typename Reloc_types<elfcpp::SHT_REL, 32, big_endian>::Reloc&) const;
+};
+
+// Specialized Stub_addend_reader for RELA type relocation sections.
+// We currently do not handle RELA type relocation sections but it is trivial
+// to implement the addend reader.  This is provided for completeness and to
+// make it easier to add support for RELA relocation sections in the future.
+
+template<bool big_endian>
+struct Stub_addend_reader<elfcpp::SHT_RELA, big_endian>
+{
+  elfcpp::Elf_types<32>::Elf_Swxword
+  operator()(
+    unsigned int,
+    const unsigned char*,
+    const typename Reloc_types<elfcpp::SHT_RELA, 32,
+       big_endian>::Reloc& reloc) const
+  { return reloc.get_r_addend(); }
+};
+
 // Utilities for manipulating integers of up to 32-bits
 
 namespace utils
@@ -3367,6 +3413,75 @@ Arm_dynobj<big_endian>::do_read_symbols(
   this->processor_specific_flags_ = ehdr.get_e_flags();
 }
 
+// Stub_addend_reader methods.
+
+// Read the addend of a REL relocation of type R_TYPE at VIEW.
+
+template<bool big_endian>
+elfcpp::Elf_types<32>::Elf_Swxword
+Stub_addend_reader<elfcpp::SHT_REL, big_endian>::operator()(
+    unsigned int r_type,
+    const unsigned char* view,
+    const typename Reloc_types<elfcpp::SHT_REL, 32, big_endian>::Reloc&) const
+{
+  switch(r_type)
+    {
+    case elfcpp::R_ARM_CALL:
+    case elfcpp::R_ARM_JUMP24:
+    case elfcpp::R_ARM_PLT32:
+      {
+ typedef typename elfcpp::Swap<32, big_endian>::Valtype Valtype;
+ const Valtype* wv = reinterpret_cast<const Valtype*>(view);
+ Valtype val = elfcpp::Swap<32, big_endian>::readval(wv);
+ return utils::sign_extend<26>(val << 2);
+      }
+
+    case elfcpp::R_ARM_THM_CALL:
+    case elfcpp::R_ARM_THM_JUMP24:
+    case elfcpp::R_ARM_THM_XPC22:
+      {
+ // Fetch the addend.  We use the Thumb-2 encoding (backwards
+ // compatible with Thumb-1) involving the J1 and J2 bits.
+ typedef typename elfcpp::Swap<16, big_endian>::Valtype Valtype;
+ const Valtype* wv = reinterpret_cast<const Valtype*>(view);
+ Valtype upper_insn = elfcpp::Swap<16, big_endian>::readval(wv);
+ Valtype lower_insn = elfcpp::Swap<16, big_endian>::readval(wv + 1);
+
+ uint32_t s = (upper_insn & (1 << 10)) >> 10;
+ uint32_t upper = upper_insn & 0x3ff;
+ uint32_t lower = lower_insn & 0x7ff;
+ uint32_t j1 = (lower_insn & (1 << 13)) >> 13;
+ uint32_t j2 = (lower_insn & (1 << 11)) >> 11;
+ uint32_t i1 = j1 ^ s ? 0 : 1;
+ uint32_t i2 = j2 ^ s ? 0 : 1;
+
+ return utils::sign_extend<25>((s << 24) | (i1 << 23) | (i2 << 22)
+      | (upper << 12) | (lower << 1));
+      }
+
+    case elfcpp::R_ARM_THM_JUMP19:
+      {
+ typedef typename elfcpp::Swap<16, big_endian>::Valtype Valtype;
+ const Valtype* wv = reinterpret_cast<const Valtype*>(view);
+ Valtype upper_insn = elfcpp::Swap<16, big_endian>::readval(wv);
+ Valtype lower_insn = elfcpp::Swap<16, big_endian>::readval(wv + 1);
+
+ // Reconstruct the top three bits and squish the two 11 bit pieces
+ // together.
+ uint32_t S = (upper_insn & 0x0400) >> 10;
+ uint32_t J1 = (lower_insn & 0x2000) >> 13;
+ uint32_t J2 = (lower_insn & 0x0800) >> 11;
+ uint32_t upper =
+  (S << 8) | (J2 << 7) | (J1 << 6) | (upper_insn & 0x003f);
+ uint32_t lower = (lower_insn & 0x07ff);
+ return utils::sign_extend<23>((upper << 12) | (lower << 1));
+      }
+
+    default:
+      gold_unreachable();
+    }
+}
+
 // A class to handle the PLT data.
 
 template<bool big_endian>

Re: [GOLD][PATCH] Addend reader struct for stubs.

by Ian Lance Taylor-3 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

"Doug Kwan (關振德)" <dougkwan@...> writes:

> +// Functor to read reloc addends during stub generation.
> +
> +template<int sh_type, bool big_endian>
> +struct Stub_addend_reader
> +{
> +  // Return the addend for a relocation of a particular type.  Depending
> +  // on whether this is a REL or RELA relocation, read the addend from a
> +  // view or from a Reloc object.
> +  elfcpp::Elf_types<32>::Elf_Swxword
> +  operator()(
> +    unsigned int /* r_type */,
> +    const unsigned char* /* view */,
> +    const typename Reloc_types<sh_type,
> +       32, big_endian>::Reloc& /* reloc */) const
> +  { gold_unreachable(); }
> +};

You don't have to define this operator() -- nothing will call it.  It
should suffice to do

template<int sh_type, bool big_endian>
struct Stub_addend_reader;

All the actual uses will use the specializations.


> +// Stub_addend_reader methods.
> +
> +// Read the addend of a REL relocation of type R_TYPE at VIEW.
> +
> +template<bool big_endian>
> +elfcpp::Elf_types<32>::Elf_Swxword
> +Stub_addend_reader<elfcpp::SHT_REL, big_endian>::operator()(
> +    unsigned int r_type,
> +    const unsigned char* view,
> +    const typename Reloc_types<elfcpp::SHT_REL, 32, big_endian>::Reloc&) const
> +{
> +  switch(r_type)

s/switch(/switch (/


This is OK with those changes.

Thanks.

Ian