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>
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
// 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<big_endian>::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<big_endian>::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<big_endian>::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;

View File

@ -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,