From: Doug Kwan Date: Thu, 10 Nov 2011 20:53:36 +0000 (+0000) Subject: 2011-11-10 Doug Kwan X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=29ab395d2b246f993e8fd06f71a1fe165d2f3985;p=binutils-gdb.git 2011-11-10 Doug Kwan 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. --- diff --git a/gold/ChangeLog b/gold/ChangeLog index f3707ae9107..0b17438b8b8 100644 --- a/gold/ChangeLog +++ b/gold/ChangeLog @@ -1,3 +1,13 @@ +2011-11-10 Doug Kwan + + 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. + 2011-11-09 Doug Kwan PR gold/13362 diff --git a/gold/arm.cc b/gold/arm.cc index a17469b2c9f..3ee2224d631 100644 --- a/gold/arm.cc +++ b/gold/arm.cc @@ -9348,7 +9348,7 @@ Target_arm::Relocate::relocate_tls( // Relocate the field with the PC relative offset of the pair of // GOT entries. - RelocFuncs::pcrel32(view, got_entry, address); + RelocFuncs::pcrel32_unaligned(view, got_entry, address); return ArmRelocFuncs::STATUS_OKAY; } } @@ -9367,13 +9367,13 @@ Target_arm::Relocate::relocate_tls( // Relocate the field with the PC relative offset of the pair of // GOT entries. - RelocFuncs::pcrel32(view, got_entry, address); + RelocFuncs::pcrel32_unaligned(view, got_entry, address); return ArmRelocFuncs::STATUS_OKAY; } break; case elfcpp::R_ARM_TLS_LDO32: // Alternate local-dynamic - RelocFuncs::rel32(view, value); + RelocFuncs::rel32_unaligned(view, value); return ArmRelocFuncs::STATUS_OKAY; case elfcpp::R_ARM_TLS_IE32: // Initial-exec @@ -9402,7 +9402,7 @@ Target_arm::Relocate::relocate_tls( target->got_plt_section()->address() + got_offset; // Relocate the field with the PC relative offset of the GOT entry. - RelocFuncs::pcrel32(view, got_entry, address); + RelocFuncs::pcrel32_unaligned(view, got_entry, address); return ArmRelocFuncs::STATUS_OKAY; } break; @@ -9418,7 +9418,7 @@ Target_arm::Relocate::relocate_tls( // need to add TCB size to the offset. Arm_address aligned_tcb_size = align_address(ARM_TCB_SIZE, tls_segment->maximum_alignment()); - RelocFuncs::rel32(view, value + aligned_tcb_size); + RelocFuncs::rel32_unaligned(view, value + aligned_tcb_size); } return ArmRelocFuncs::STATUS_OKAY; diff --git a/gold/reloc.h b/gold/reloc.h index fefcb3f1e28..02f91a43353 100644 --- a/gold/reloc.h +++ b/gold/reloc.h @@ -333,6 +333,18 @@ private: elfcpp::Swap::writeval(wv, x + value); } + // Like the above but for relocs at unaligned addresses. + template + static inline void + rel_unaligned(unsigned char* view, + typename elfcpp::Swap::Valtype value) + { + typedef typename elfcpp::Swap_unaligned::Valtype + Valtype; + Valtype x = elfcpp::Swap_unaligned::readval(view); + elfcpp::Swap_unaligned::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::writeval(wv, x + value - address); } + // Like the above but for relocs at unaligned addresses. + template + static inline void + pcrel_unaligned(unsigned char* view, + typename elfcpp::Swap::Valtype value, + typename elfcpp::Elf_types::Elf_Addr address) + { + typedef typename elfcpp::Swap::Valtype Valtype; + Valtype x = elfcpp::Swap_unaligned::readval(view); + elfcpp::Swap_unaligned::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* object, @@ -600,6 +630,12 @@ public: typename elfcpp::Elf_types::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::Elf_Addr address) + { This::template pcrel_unaligned<32>(view, value, address); } + static inline void pcrel32(unsigned char* view, const Sized_relobj_file* object,