[PATCH][GOLD] Fix missing cases in previous patch for gold/13362
Doug Kwan (關振德)
dougkwan@google.com
Thu Nov 10 20:20:00 GMT 2011
Hi Ian,
The previous patch missed the TLS static data relocations. The
patch addresses that. Tested on ARM hardware and x86. I also sent
this to the report of 13362 and he verified that it fixes the problem.
There are a few other regressions on ARM unrelated to this problem.
Those will be fixed in another patch.
-Doug
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.
-------------- next part --------------
Index: gold/arm.cc
===================================================================
RCS file: /cvs/src/src/gold/arm.cc,v
retrieving revision 1.141
diff -u -u -p -r1.141 arm.cc
--- gold/arm.cc 10 Nov 2011 00:41:53 -0000 1.141
+++ gold/arm.cc 10 Nov 2011 19:47:52 -0000
@@ -9348,7 +9348,7 @@ Target_arm<big_endian>::Relocate::reloca
// 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::reloca
// 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::reloca
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::reloca
// 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;
Index: gold/reloc.h
===================================================================
RCS file: /cvs/src/src/gold/reloc.h,v
retrieving revision 1.32
diff -u -u -p -r1.32 reloc.h
--- gold/reloc.h 10 Nov 2011 00:41:53 -0000 1.32
+++ gold/reloc.h 10 Nov 2011 19:47:52 -0000
@@ -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,
More information about the Binutils
mailing list