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.
This commit is contained in:
Doug Kwan 2011-11-10 20:53:36 +00:00
parent 50f182aa66
commit 29ab395d2b
3 changed files with 51 additions and 5 deletions

View File

@ -1,3 +1,13 @@
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.
2011-11-09 Doug Kwan <dougkwan@google.com> 2011-11-09 Doug Kwan <dougkwan@google.com>
PR gold/13362 PR gold/13362

View File

@ -9348,7 +9348,7 @@ Target_arm<big_endian>::Relocate::relocate_tls(
// Relocate the field with the PC relative offset of the pair of // Relocate the field with the PC relative offset of the pair of
// GOT entries. // GOT entries.
RelocFuncs::pcrel32(view, got_entry, address); RelocFuncs::pcrel32_unaligned(view, got_entry, address);
return ArmRelocFuncs::STATUS_OKAY; return ArmRelocFuncs::STATUS_OKAY;
} }
} }
@ -9367,13 +9367,13 @@ Target_arm<big_endian>::Relocate::relocate_tls(
// Relocate the field with the PC relative offset of the pair of // Relocate the field with the PC relative offset of the pair of
// GOT entries. // GOT entries.
RelocFuncs::pcrel32(view, got_entry, address); RelocFuncs::pcrel32_unaligned(view, got_entry, address);
return ArmRelocFuncs::STATUS_OKAY; return ArmRelocFuncs::STATUS_OKAY;
} }
break; break;
case elfcpp::R_ARM_TLS_LDO32: // Alternate local-dynamic case elfcpp::R_ARM_TLS_LDO32: // Alternate local-dynamic
RelocFuncs::rel32(view, value); RelocFuncs::rel32_unaligned(view, value);
return ArmRelocFuncs::STATUS_OKAY; return ArmRelocFuncs::STATUS_OKAY;
case elfcpp::R_ARM_TLS_IE32: // Initial-exec case elfcpp::R_ARM_TLS_IE32: // Initial-exec
@ -9402,7 +9402,7 @@ Target_arm<big_endian>::Relocate::relocate_tls(
target->got_plt_section()->address() + got_offset; target->got_plt_section()->address() + got_offset;
// Relocate the field with the PC relative offset of the GOT entry. // 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; return ArmRelocFuncs::STATUS_OKAY;
} }
break; break;
@ -9418,7 +9418,7 @@ Target_arm<big_endian>::Relocate::relocate_tls(
// need to add TCB size to the offset. // need to add TCB size to the offset.
Arm_address aligned_tcb_size = Arm_address aligned_tcb_size =
align_address(ARM_TCB_SIZE, tls_segment->maximum_alignment()); 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; return ArmRelocFuncs::STATUS_OKAY;

View File

@ -333,6 +333,18 @@ private:
elfcpp::Swap<valsize, big_endian>::writeval(wv, x + value); 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 // Do a simple relocation using a Symbol_value with the addend in
// the section contents. VALSIZE is the size of the value to // the section contents. VALSIZE is the size of the value to
// relocate. // relocate.
@ -405,6 +417,19 @@ private:
elfcpp::Swap<valsize, big_endian>::writeval(wv, x + value - address); 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 // Do a simple PC relative relocation with a Symbol_value with the
// addend in the section contents. VALSIZE is the size of the // addend in the section contents. VALSIZE is the size of the
// value. // value.
@ -568,6 +593,11 @@ public:
rel32(unsigned char* view, elfcpp::Elf_Word value) rel32(unsigned char* view, elfcpp::Elf_Word value)
{ This::template rel<32>(view, 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 static inline void
rel32(unsigned char* view, rel32(unsigned char* view,
const Sized_relobj_file<size, big_endian>* object, const Sized_relobj_file<size, big_endian>* object,
@ -600,6 +630,12 @@ public:
typename elfcpp::Elf_types<size>::Elf_Addr address) typename elfcpp::Elf_types<size>::Elf_Addr address)
{ This::template pcrel<32>(view, value, 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 static inline void
pcrel32(unsigned char* view, pcrel32(unsigned char* view,
const Sized_relobj_file<size, big_endian>* object, const Sized_relobj_file<size, big_endian>* object,