This is the mail archive of the
binutils-cvs@sourceware.org
mailing list for the binutils project.
[binutils-gdb] Fix support for i386 TLS GD-to-IE optimization.
- From: Cary Coutant <ccoutant at sourceware dot org>
- To: bfd-cvs at sourceware dot org
- Date: 22 Mar 2015 18:59:35 -0000
- Subject: [binutils-gdb] Fix support for i386 TLS GD-to-IE optimization.
https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=152f702439a34bf20b74f472695490edb42ad56f
commit 152f702439a34bf20b74f472695490edb42ad56f
Author: Cary Coutant <ccoutant@gmail.com>
Date: Sun Mar 22 11:59:21 2015 -0700
Fix support for i386 TLS GD-to-IE optimization.
There are two cases to support, one with an SIB-form (6-byte) LEA,
the other with a 5-byte LEA and a NOP after the call __tls_get_addr.
Gold did not yet support the second case. This patch adds that
support.
gold/
PR gold/18106
* i386.cc (Target_i386::Relocate::tls_gd_to_ie): Fix support for
non-SIB form of lea, with nop after the call.
Diff:
---
gold/ChangeLog | 6 ++++++
gold/i386.cc | 27 ++++++++-------------------
2 files changed, 14 insertions(+), 19 deletions(-)
diff --git a/gold/ChangeLog b/gold/ChangeLog
index 7d281a9..71887d3 100644
--- a/gold/ChangeLog
+++ b/gold/ChangeLog
@@ -1,3 +1,9 @@
+2015-03-22 Cary Coutant <cary@google.com>
+
+ PR gold/18106
+ * i386.cc (Target_i386::Relocate::tls_gd_to_ie): Fix support for
+ non-SIB form of lea, with nop after the call.
+
2015-03-21 Cary Coutant <cary@google.com>
PR gold/14217
diff --git a/gold/i386.cc b/gold/i386.cc
index 24f4103..3bc3d94 100644
--- a/gold/i386.cc
+++ b/gold/i386.cc
@@ -3253,6 +3253,8 @@ Target_i386::Relocate::tls_gd_to_ie(const Relocate_info<32, false>* relinfo,
{
// leal foo(,%ebx,1),%eax; call ___tls_get_addr
// ==> movl %gs:0,%eax; addl foo@gotntpoff(%ebx),%eax
+ // leal foo(%ebx),%eax; call ___tls_get_addr; nop
+ // ==> movl %gs:0,%eax; addl foo@gotntpoff(%ebx),%eax
tls::check_range(relinfo, relnum, rel.get_r_offset(), view_size, -2);
tls::check_range(relinfo, relnum, rel.get_r_offset(), view_size, 9);
@@ -3264,10 +3266,7 @@ Target_i386::Relocate::tls_gd_to_ie(const Relocate_info<32, false>* relinfo,
op2 == 0x8d || op2 == 0x04);
tls::check_tls(relinfo, relnum, rel.get_r_offset(), view[4] == 0xe8);
- int roff = 5;
-
- // FIXME: For now, support only the first (SIB) form.
- tls::check_tls(relinfo, relnum, rel.get_r_offset(), op2 == 0x04);
+ int roff;
if (op2 == 0x04)
{
@@ -3275,28 +3274,18 @@ Target_i386::Relocate::tls_gd_to_ie(const Relocate_info<32, false>* relinfo,
tls::check_tls(relinfo, relnum, rel.get_r_offset(), view[-3] == 0x8d);
tls::check_tls(relinfo, relnum, rel.get_r_offset(),
((op1 & 0xc7) == 0x05 && op1 != (4 << 3)));
- memcpy(view - 3, "\x65\xa1\0\0\0\0\x03\x83\0\0\0", 12);
+ roff = 5;
}
else
{
+ tls::check_range(relinfo, relnum, rel.get_r_offset(), view_size, 10);
tls::check_tls(relinfo, relnum, rel.get_r_offset(),
(op1 & 0xf8) == 0x80 && (op1 & 7) != 4);
- if (rel.get_r_offset() + 9 < view_size
- && view[9] == 0x90)
- {
- // FIXME: This is not the right instruction sequence.
- // There is a trailing nop. Use the size byte subl.
- memcpy(view - 2, "\x65\xa1\0\0\0\0\x81\xe8\0\0\0", 12);
- roff = 6;
- }
- else
- {
- // FIXME: This is not the right instruction sequence.
- // Use the five byte subl.
- memcpy(view - 2, "\x65\xa1\0\0\0\0\x2d\0\0\0", 11);
- }
+ tls::check_tls(relinfo, relnum, rel.get_r_offset(), view[9] == 0x90);
+ roff = 6;
}
+ memcpy(view + roff - 8, "\x65\xa1\0\0\0\0\x03\x83\0\0\0", 12);
Relocate_functions<32, false>::rel32(view + roff, value);
// The next reloc should be a PLT32 reloc against __tls_get_addr.