aboutsummaryrefslogtreecommitdiff
path: root/gold/reloc.h
diff options
context:
space:
mode:
authorDoug Kwan <dougkwan@google.com>2011-11-10 20:53:36 +0000
committerDoug Kwan <dougkwan@google.com>2011-11-10 20:53:36 +0000
commit29ab395d2b246f993e8fd06f71a1fe165d2f3985 (patch)
tree91ec0d782dad8f14333e645c618dc3494675588d /gold/reloc.h
parent50f182aa6671dea0fdcf063d5974c623332f3e63 (diff)
downloadgdb-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.h36
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,