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:
parent
50f182aa66
commit
29ab395d2b
@ -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
|
||||||
|
10
gold/arm.cc
10
gold/arm.cc
@ -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;
|
||||||
|
36
gold/reloc.h
36
gold/reloc.h
@ -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,
|
||||||
|
Loading…
Reference in New Issue
Block a user