diff options
author | Doug Kwan <dougkwan@google.com> | 2011-11-10 20:53:36 +0000 |
---|---|---|
committer | Doug Kwan <dougkwan@google.com> | 2011-11-10 20:53:36 +0000 |
commit | 29ab395d2b246f993e8fd06f71a1fe165d2f3985 (patch) | |
tree | 91ec0d782dad8f14333e645c618dc3494675588d /gold/reloc.h | |
parent | 50f182aa6671dea0fdcf063d5974c623332f3e63 (diff) | |
download | gdb-29ab395d2b246f993e8fd06f71a1fe165d2f3985.zip gdb-29ab395d2b246f993e8fd06f71a1fe165d2f3985.tar.gz gdb-29ab395d2b246f993e8fd06f71a1fe165d2f3985.tar.bz2 |
2011-11-10 Doug Kwan <dougkwan@google.com>
PR gold/13362
* arm.cc (Target_arm::Relocate::relocate_tls): Do unaligned accesses
when processing data relocs.
* reloc.h (Relocate_functions::rel_unaligned): New method.
(Relocate_functions::pcrel_unaligned): Ditto.
(Relocate_functions::rel32_unaligned): Ditto.
(Relocate_functions::pcrel32_unaligned): Ditto.
Diffstat (limited to 'gold/reloc.h')
-rw-r--r-- | gold/reloc.h | 36 |
1 files changed, 36 insertions, 0 deletions
diff --git a/gold/reloc.h b/gold/reloc.h index fefcb3f..02f91a4 100644 --- a/gold/reloc.h +++ b/gold/reloc.h @@ -333,6 +333,18 @@ private: elfcpp::Swap<valsize, big_endian>::writeval(wv, x + value); } + // Like the above but for relocs at unaligned addresses. + template<int valsize> + static inline void + rel_unaligned(unsigned char* view, + typename elfcpp::Swap<valsize, big_endian>::Valtype value) + { + typedef typename elfcpp::Swap_unaligned<valsize, big_endian>::Valtype + Valtype; + Valtype x = elfcpp::Swap_unaligned<valsize, big_endian>::readval(view); + elfcpp::Swap_unaligned<valsize, big_endian>::writeval(view, x + value); + } + // Do a simple relocation using a Symbol_value with the addend in // the section contents. VALSIZE is the size of the value to // relocate. @@ -405,6 +417,19 @@ private: elfcpp::Swap<valsize, big_endian>::writeval(wv, x + value - address); } + // Like the above but for relocs at unaligned addresses. + template<int valsize> + static inline void + pcrel_unaligned(unsigned char* view, + typename elfcpp::Swap<valsize, big_endian>::Valtype value, + typename elfcpp::Elf_types<size>::Elf_Addr address) + { + typedef typename elfcpp::Swap<valsize, big_endian>::Valtype Valtype; + Valtype x = elfcpp::Swap_unaligned<valsize, big_endian>::readval(view); + elfcpp::Swap_unaligned<valsize, big_endian>::writeval(view, + x + value - address); + } + // Do a simple PC relative relocation with a Symbol_value with the // addend in the section contents. VALSIZE is the size of the // value. @@ -568,6 +593,11 @@ public: rel32(unsigned char* view, elfcpp::Elf_Word value) { This::template rel<32>(view, value); } + // Like above but for relocs at unaligned addresses. + static inline void + rel32_unaligned(unsigned char* view, elfcpp::Elf_Word value) + { This::template rel_unaligned<32>(view, value); } + static inline void rel32(unsigned char* view, const Sized_relobj_file<size, big_endian>* object, @@ -600,6 +630,12 @@ public: typename elfcpp::Elf_types<size>::Elf_Addr address) { This::template pcrel<32>(view, value, address); } + // Unaligned version of the above. + static inline void + pcrel32_unaligned(unsigned char* view, elfcpp::Elf_Word value, + typename elfcpp::Elf_types<size>::Elf_Addr address) + { This::template pcrel_unaligned<32>(view, value, address); } + static inline void pcrel32(unsigned char* view, const Sized_relobj_file<size, big_endian>* object, |