This is the mail archive of the binutils-cvs@sourceware.org mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[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.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]