This is the mail archive of the binutils@sources.redhat.com 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]

[PATCH] Change x86-64 TLSGD sequences


Hi!

x86-64 prefers to have at most 3 prefixes for an instruction, so TLSGD
sequence was changed from
.long 0x666666; leaq foo@tlsgd(%rip), %rdi
call __tls_get_addr@plt
to
.byte 0x66; leaq foo@tlsgd(%rip), %rdi
.word 0x6666; rex64; call __tls_get_addr@plt
Ok to commit?

2002-10-01  Jakub Jelinek  <jakub@redhat.com>

bfd/
	* elf64-x86-64.c (elf64_x86_64_relocate_section): Change TLSGD
	sequence and its transitions.
ld/testsuite/
	* ld-x86-64/tlspic1.s: Change TLSGD sequences.
	* ld-x86-64/tlsbinpic.s: Likewise.
	* ld-x86-64/tlspic.dd: Adjust.

--- bfd/elf64-x86-64.c.jj	2002-10-01 10:29:06.000000000 +0200
+++ bfd/elf64-x86-64.c	2002-10-01 10:30:25.000000000 +0200
@@ -2224,31 +2224,32 @@ elf64_x86_64_relocate_section (output_bf
 	      if (ELF64_R_TYPE (rel->r_info) == R_X86_64_TLSGD)
 		{
 		  unsigned int i;
-		  static unsigned char tlsgd[7]
-		    = { 0x66, 0x66, 0x66, 0x66, 0x48, 0x8d, 0x3d };
+		  static unsigned char tlsgd[8]
+		    = { 0x66, 0x48, 0x8d, 0x3d, 0x66, 0x66, 0x48, 0xe8 };
 
 		  /* GD->LE transition.
-		     .long 0x66666666; leaq foo@tlsgd(%rip), %rdi
-		     callq __tls_get_addr@plt
+		     .byte 0x66; leaq foo@tlsgd(%rip), %rdi
+		     .word 0x6666; rex64; call __tls_get_addr@plt
 		     Change it into:
 		     movq %fs:0, %rax
 		     leaq foo@tpoff(%rax), %rax */
-		  BFD_ASSERT (rel->r_offset >= 7);
-		  for (i = 0; i < 7; i++)
+		  BFD_ASSERT (rel->r_offset >= 4);
+		  for (i = 0; i < 4; i++)
 		    BFD_ASSERT (bfd_get_8 (input_bfd,
-					   contents + rel->r_offset - 7 + i)
+					   contents + rel->r_offset - 4 + i)
 				== tlsgd[i]);
-		  BFD_ASSERT (rel->r_offset + 9 <= input_section->_raw_size);
-		  BFD_ASSERT (bfd_get_8 (input_bfd,
-					 contents + rel->r_offset + 4)
-			      == 0xe8);
+		  BFD_ASSERT (rel->r_offset + 12 <= input_section->_raw_size);
+		  for (i = 0; i < 4; i++)
+		    BFD_ASSERT (bfd_get_8 (input_bfd,
+					   contents + rel->r_offset + 4 + i)
+				== tlsgd[i+4]);
 		  BFD_ASSERT (rel + 1 < relend);
 		  BFD_ASSERT (ELF64_R_TYPE (rel[1].r_info) == R_X86_64_PLT32);
-		  memcpy (contents + rel->r_offset - 7,
+		  memcpy (contents + rel->r_offset - 4,
 			  "\x64\x48\x8b\x04\x25\0\0\0\0\x48\x8d\x80\0\0\0",
 			  16);
 		  bfd_put_32 (output_bfd, tpoff (info, relocation),
-			      contents + rel->r_offset + 5);
+			      contents + rel->r_offset + 8);
 		  /* Skip R_X86_64_PLT32.  */
 		  rel++;
 		  continue;
@@ -2397,27 +2398,28 @@ elf64_x86_64_relocate_section (output_bf
 	  else
 	    {
 	      unsigned int i;
-	      static unsigned char tlsgd[7]
-		= { 0x66, 0x66, 0x66, 0x66, 0x48, 0x8d, 0x3d };
+	      static unsigned char tlsgd[8]
+		= { 0x66, 0x48, 0x8d, 0x3d, 0x66, 0x66, 0x48, 0xe8 };
 
 	      /* GD->IE transition.
-		 .long 0x66666666; leaq foo@tlsgd(%rip), %rdi
-		 callq __tls_get_addr@plt
+		 .byte 0x66; leaq foo@tlsgd(%rip), %rdi
+		 .word 0x6666; rex64; call __tls_get_addr@plt
 		 Change it into:
 		 movq %fs:0, %rax
 		 addq foo@gottpoff(%rip), %rax */
-	      BFD_ASSERT (rel->r_offset >= 7);
-	      for (i = 0; i < 7; i++)
+	      BFD_ASSERT (rel->r_offset >= 4);
+	      for (i = 0; i < 4; i++)
 	        BFD_ASSERT (bfd_get_8 (input_bfd,
-				       contents + rel->r_offset - 7 + i)
+				       contents + rel->r_offset - 4 + i)
 			    == tlsgd[i]);
-	      BFD_ASSERT (rel->r_offset + 9 <= input_section->_raw_size);
-	      BFD_ASSERT (bfd_get_8 (input_bfd,
-				     contents + rel->r_offset + 4)
-			  == 0xe8);
+	      BFD_ASSERT (rel->r_offset + 12 <= input_section->_raw_size);
+	      for (i = 0; i < 4; i++)
+	        BFD_ASSERT (bfd_get_8 (input_bfd,
+				       contents + rel->r_offset + 4 + i)
+			    == tlsgd[i+4]);
 	      BFD_ASSERT (rel + 1 < relend);
 	      BFD_ASSERT (ELF64_R_TYPE (rel[1].r_info) == R_X86_64_PLT32);
-	      memcpy (contents + rel->r_offset - 7,
+	      memcpy (contents + rel->r_offset - 4,
 		      "\x64\x48\x8b\x04\x25\0\0\0\0\x48\x03\x05\0\0\0",
 		      16);
 
@@ -2426,9 +2428,9 @@ elf64_x86_64_relocate_section (output_bf
 			    - rel->r_offset
 			    - input_section->output_section->vma
 			    - input_section->output_offset
-			    - 9);
+			    - 12);
 	      bfd_put_32 (output_bfd, relocation,
-			  contents + rel->r_offset + 5);
+			  contents + rel->r_offset + 8);
 	      /* Skip R_X86_64_PLT32.  */
 	      rel++;
 	      continue;
--- ld/testsuite/ld-x86-64/tlspic1.s.jj	2002-09-26 16:11:31.000000000 +0200
+++ ld/testsuite/ld-x86-64/tlspic1.s	2002-10-01 10:30:25.000000000 +0200
@@ -41,52 +41,68 @@ fn1:
 	nop;nop;nop;nop
 
 	/* GD */
-	.long	0x66666666
+	.byte	0x66
 	leaq	sg1@tlsgd(%rip), %rdi
+	.word	0x6666
+	rex64
 	call	__tls_get_addr@plt
 	nop;nop;nop;nop
 
 	/* GD -> IE because variable is referenced through IE too */
-	.long	0x66666666
+	.byte	0x66
 	leaq	sg2@tlsgd(%rip), %rdi
+	.word	0x6666
+	rex64
 	call	__tls_get_addr@plt
 	nop;nop;nop;nop
 
 	/* GD against local variable */
-	.long	0x66666666
+	.byte	0x66
 	leaq	sl1@tlsgd(%rip), %rdi
+	.word	0x6666
+	rex64
 	call	__tls_get_addr@plt
 	nop;nop;nop;nop
 
 	/* GD -> IE against local variable referenced through IE too */
-	.long	0x66666666
+	.byte	0x66
 	leaq	sl2@tlsgd(%rip), %rdi
+	.word	0x6666
+	rex64
 	call	__tls_get_addr@plt
 	nop;nop;nop;nop
 
 	/* GD against hidden and local variable */
-	.long	0x66666666
+	.byte	0x66
 	leaq	sh1@tlsgd(%rip), %rdi
+	.word	0x6666
+	rex64
 	call	__tls_get_addr@plt
 	nop;nop;nop;nop
 
 	/* GD -> IE against hidden and local variable referenced through
 	   IE too */
-	.long	0x66666666
+	.byte	0x66
 	leaq	sh2@tlsgd(%rip), %rdi
+	.word	0x6666
+	rex64
 	call	__tls_get_addr@plt
 	nop;nop;nop;nop
 
 	/* GD against hidden but not local variable */
-	.long	0x66666666
+	.byte	0x66
 	leaq	sH1@tlsgd(%rip), %rdi
+	.word	0x6666
+	rex64
 	call	__tls_get_addr@plt
 	nop;nop;nop;nop
 
 	/* GD -> IE against hidden but not local variable referenced through
 	   IE too */
-	.long	0x66666666
+	.byte	0x66
 	leaq	sH2@tlsgd(%rip), %rdi
+	.word	0x6666
+	rex64
 	call	__tls_get_addr@plt
 	nop;nop;nop;nop
 
--- ld/testsuite/ld-x86-64/tlsbinpic.s.jj	2002-10-01 10:29:06.000000000 +0200
+++ ld/testsuite/ld-x86-64/tlsbinpic.s	2002-10-01 10:30:25.000000000 +0200
@@ -40,33 +40,43 @@ fn2:
 	movq	%rsp, %rbp
 
 	/* GD -> IE because variable is not defined in executable */
-	.long	0x66666666
+	.byte	0x66
 	leaq	sG1@tlsgd(%rip), %rdi
+	.word	0x6666
+	rex64
 	call	__tls_get_addr@plt
 	nop;nop;nop;nop
 
 	/* GD -> IE because variable is not defined in executable where
 	   the variable is referenced through IE too */
-	.long	0x66666666
+	.byte	0x66
 	leaq	sG2@tlsgd(%rip), %rdi
+	.word	0x6666
+	rex64
 	call	__tls_get_addr@plt
 	nop;nop;nop;nop
 
 	/* GD -> LE with global variable defined in executable */
-	.long	0x66666666
+	.byte	0x66
 	leaq	sg1@tlsgd(%rip), %rdi
+	.word	0x6666
+	rex64
 	call	__tls_get_addr@plt
 	nop;nop;nop;nop
 
 	/* GD -> LE with local variable defined in executable */
-	.long	0x66666666
+	.byte	0x66
 	leaq	sl1@tlsgd(%rip), %rdi
+	.word	0x6666
+	rex64
 	call	__tls_get_addr@plt
 	nop;nop;nop;nop
 
 	/* GD -> LE with hidden variable defined in executable */
-	.long	0x66666666
+	.byte	0x66
 	leaq	sh1@tlsgd(%rip), %rdi
+	.word	0x6666
+	rex64
 	call	__tls_get_addr@plt
 	nop;nop;nop;nop
 
--- ld/testsuite/ld-x86-64/tlspic.dd.jj	2002-09-26 16:20:08.000000000 +0200
+++ ld/testsuite/ld-x86-64/tlspic.dd	2002-10-01 10:30:25.000000000 +0200
@@ -17,10 +17,12 @@ Disassembly of section .text:
  +1006:	90[ 	]+nop *
  +1007:	90[ 	]+nop *
 #  GD
- +1008:	66 66 66 66 48 8d 3d[ 	]+lea    1053165\(%rip\),%rdi +# 102200 <_GLOBAL_OFFSET_TABLE_\+0x70>
- +100f:	ed 11 10 00 *
+ +1008:	66 48 8d 3d f0 11 10[ 	]+lea    1053168\(%rip\),%rdi +# 102200 <_GLOBAL_OFFSET_TABLE_\+0x70>
+ +100f:	00 *
 #				-> R_X86_64_DTPMOD64	sg1
- +1013:	e8 68 f6 ff ff[ 	]+callq  [0-9a-f]+ <.*>
+ +1010:	66[ 	]+data16
+ +1011:	66[ 	]+data16
+ +1012:	48 e8 68 f6 ff ff[ 	]+rex64 callq  [0-9a-f]+ <.*>
 #				-> R_X86_64_JUMP_SLOT	__tls_get_addr
  +1018:	90[ 	]+nop *
  +1019:	90[ 	]+nop *
@@ -36,10 +38,12 @@ Disassembly of section .text:
  +102e:	90[ 	]+nop *
  +102f:	90[ 	]+nop *
 #  GD against local variable
- +1030:	66 66 66 66 48 8d 3d[ 	]+lea    1053045\(%rip\),%rdi +# 1021b0 <_GLOBAL_OFFSET_TABLE_\+0x20>
- +1037:	75 11 10 00 *
+ +1030:	66 48 8d 3d 78 11 10[ 	]+lea    1053048\(%rip\),%rdi +# 1021b0 <_GLOBAL_OFFSET_TABLE_\+0x20>
+ +1037:	00 *
 #				-> R_X86_64_DTPMOD64	[0 0x2000000000000000]
- +103b:	e8 40 f6 ff ff[ 	]+callq  [0-9a-f]+ <.*>
+ +1038:	66[ 	]+data16
+ +1039:	66[ 	]+data16
+ +103a:	48 e8 40 f6 ff ff[ 	]+rex64 callq  [0-9a-f]+ <.*>
 #				-> R_X86_64_JUMP_SLOT	__tls_get_addr
  +1040:	90[ 	]+nop *
  +1041:	90[ 	]+nop *
@@ -55,10 +59,12 @@ Disassembly of section .text:
  +1056:	90[ 	]+nop *
  +1057:	90[ 	]+nop *
 #  GD against hidden and local variable
- +1058:	66 66 66 66 48 8d 3d[ 	]+lea    1053125\(%rip\),%rdi +# 102228 <_GLOBAL_OFFSET_TABLE_\+0x98>
- +105f:	c5 11 10 00 *
+ +1058:	66 48 8d 3d c8 11 10[ 	]+lea    1053128\(%rip\),%rdi +# 102228 <_GLOBAL_OFFSET_TABLE_\+0x98>
+ +105f:	00 *
 #				-> R_X86_64_DTPMOD64	[0 0x4000000000000000]
- +1063:	e8 18 f6 ff ff[ 	]+callq  [0-9a-f]+ <.*>
+ +1060:	66[ 	]+data16
+ +1061:	66[ 	]+data16
+ +1062:	48 e8 18 f6 ff ff[ 	]+rex64 callq  [0-9a-f]+ <.*>
 #				-> R_X86_64_JUMP_SLOT	__tls_get_addr
  +1068:	90[ 	]+nop *
  +1069:	90[ 	]+nop *
@@ -74,10 +80,12 @@ Disassembly of section .text:
  +107e:	90[ 	]+nop *
  +107f:	90[ 	]+nop *
 #  GD against hidden but not local variable
- +1080:	66 66 66 66 48 8d 3d[ 	]+lea    1053013\(%rip\),%rdi +# 1021e0 <_GLOBAL_OFFSET_TABLE_\+0x50>
- +1087:	55 11 10 00 *
+ +1080:	66 48 8d 3d 58 11 10[ 	]+lea    1053016\(%rip\),%rdi +# 1021e0 <_GLOBAL_OFFSET_TABLE_\+0x50>
+ +1087:	00 *
 #				-> R_X86_64_DTPMOD64	[0 0x6000000000000000]
- +108b:	e8 f0 f5 ff ff[ 	]+callq  [0-9a-f]+ <.*>
+ +1088:	66[ 	]+data16
+ +1089:	66[ 	]+data16
+ +108a:	48 e8 f0 f5 ff ff[ 	]+rex64 callq  [0-9a-f]+ <.*>
 #				-> R_X86_64_JUMP_SLOT	__tls_get_addr
  +1090:	90[ 	]+nop *
  +1091:	90[ 	]+nop *

	Jakub


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