summaryrefslogtreecommitdiffstats
path: root/gold/x86_64.cc
diff options
context:
space:
mode:
authorH.J. Lu <hjl.tools@gmail.com>2012-01-27 23:29:54 +0000
committerH.J. Lu <hjl.tools@gmail.com>2012-01-27 23:29:54 +0000
commit41194d9f4762608b162f05c05705e79e5a07879d (patch)
treefd6a80682790c964890cf98abbbf56d5da8f76a5 /gold/x86_64.cc
parent1bae613c85d3266ff261e36da1625582dd5d2655 (diff)
downloadppe42-binutils-41194d9f4762608b162f05c05705e79e5a07879d.tar.gz
ppe42-binutils-41194d9f4762608b162f05c05705e79e5a07879d.zip
Support x32 GD->IE and GD->LE optimizations
2012-01-27 H.J. Lu <hongjiu.lu@intel.com> * x86_64.cc (Relocate::tls_gd_to_ie): Support x32. (Relocate::tls_gd_to_le): Likewise.
Diffstat (limited to 'gold/x86_64.cc')
-rw-r--r--gold/x86_64.cc71
1 files changed, 54 insertions, 17 deletions
diff --git a/gold/x86_64.cc b/gold/x86_64.cc
index 029f89c008..3962e1ea36 100644
--- a/gold/x86_64.cc
+++ b/gold/x86_64.cc
@@ -3534,19 +3534,37 @@ Target_x86_64<size>::Relocate::tls_gd_to_ie(
typename elfcpp::Elf_types<size>::Elf_Addr address,
section_size_type view_size)
{
- // .byte 0x66; leaq foo@tlsgd(%rip),%rdi;
- // .word 0x6666; rex64; call __tls_get_addr
- // ==> movq %fs:0,%rax; addq x@gottpoff(%rip),%rax
+ // For SIZE == 64:
+ // .byte 0x66; leaq foo@tlsgd(%rip),%rdi;
+ // .word 0x6666; rex64; call __tls_get_addr
+ // ==> movq %fs:0,%rax; addq x@gottpoff(%rip),%rax
+ // For SIZE == 32:
+ // leaq foo@tlsgd(%rip),%rdi;
+ // .word 0x6666; rex64; call __tls_get_addr
+ // ==> movl %fs:0,%eax; addq x@gottpoff(%rip),%rax
- tls::check_range(relinfo, relnum, rela.get_r_offset(), view_size, -4);
tls::check_range(relinfo, relnum, rela.get_r_offset(), view_size, 12);
-
- tls::check_tls(relinfo, relnum, rela.get_r_offset(),
- (memcmp(view - 4, "\x66\x48\x8d\x3d", 4) == 0));
tls::check_tls(relinfo, relnum, rela.get_r_offset(),
(memcmp(view + 4, "\x66\x66\x48\xe8", 4) == 0));
- memcpy(view - 4, "\x64\x48\x8b\x04\x25\0\0\0\0\x48\x03\x05\0\0\0\0", 16);
+ if (size == 64)
+ {
+ tls::check_range(relinfo, relnum, rela.get_r_offset(), view_size,
+ -4);
+ tls::check_tls(relinfo, relnum, rela.get_r_offset(),
+ (memcmp(view - 4, "\x66\x48\x8d\x3d", 4) == 0));
+ memcpy(view - 4, "\x64\x48\x8b\x04\x25\0\0\0\0\x48\x03\x05\0\0\0\0",
+ 16);
+ }
+ else
+ {
+ tls::check_range(relinfo, relnum, rela.get_r_offset(), view_size,
+ -3);
+ tls::check_tls(relinfo, relnum, rela.get_r_offset(),
+ (memcmp(view - 3, "\x48\x8d\x3d", 3) == 0));
+ memcpy(view - 3, "\x64\x8b\x04\x25\0\0\0\0\x48\x03\x05\0\0\0\0",
+ 15);
+ }
const elfcpp::Elf_Xword addend = rela.get_r_addend();
Relocate_functions<size, false>::pcrela32(view + 8, value, addend - 8,
@@ -3572,19 +3590,38 @@ Target_x86_64<size>::Relocate::tls_gd_to_le(
unsigned char* view,
section_size_type view_size)
{
- // .byte 0x66; leaq foo@tlsgd(%rip),%rdi;
- // .word 0x6666; rex64; call __tls_get_addr
- // ==> movq %fs:0,%rax; leaq x@tpoff(%rax),%rax
+ // For SIZE == 64:
+ // .byte 0x66; leaq foo@tlsgd(%rip),%rdi;
+ // .word 0x6666; rex64; call __tls_get_addr
+ // ==> movq %fs:0,%rax; leaq x@tpoff(%rax),%rax
+ // For SIZE == 32:
+ // leaq foo@tlsgd(%rip),%rdi;
+ // .word 0x6666; rex64; call __tls_get_addr
+ // ==> movl %fs:0,%eax; leaq x@tpoff(%rax),%rax
- tls::check_range(relinfo, relnum, rela.get_r_offset(), view_size, -4);
tls::check_range(relinfo, relnum, rela.get_r_offset(), view_size, 12);
-
tls::check_tls(relinfo, relnum, rela.get_r_offset(),
- (memcmp(view - 4, "\x66\x48\x8d\x3d", 4) == 0));
- tls::check_tls(relinfo, relnum, rela.get_r_offset(),
- (memcmp(view + 4, "\x66\x66\x48\xe8", 4) == 0));
+ (memcmp(view + 4, "\x66\x66\x48\xe8", 4) == 0));
+
+ if (size == 64)
+ {
+ tls::check_range(relinfo, relnum, rela.get_r_offset(), view_size,
+ -4);
+ tls::check_tls(relinfo, relnum, rela.get_r_offset(),
+ (memcmp(view - 4, "\x66\x48\x8d\x3d", 4) == 0));
+ memcpy(view - 4, "\x64\x48\x8b\x04\x25\0\0\0\0\x48\x8d\x80\0\0\0\0",
+ 16);
+ }
+ else
+ {
+ tls::check_range(relinfo, relnum, rela.get_r_offset(), view_size,
+ -3);
+ tls::check_tls(relinfo, relnum, rela.get_r_offset(),
+ (memcmp(view - 3, "\x48\x8d\x3d", 3) == 0));
- memcpy(view - 4, "\x64\x48\x8b\x04\x25\0\0\0\0\x48\x8d\x80\0\0\0\0", 16);
+ memcpy(view - 3, "\x64\x8b\x04\x25\0\0\0\0\x48\x8d\x80\0\0\0\0",
+ 15);
+ }
value -= tls_segment->memsz();
Relocate_functions<size, false>::rela32(view + 8, value, 0);
OpenPOWER on IntegriCloud