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

x86 binutils fail on big-endian hosts


I noticed today that building an x86 or x86_64 targeted binutils on a
big-endian host results in some testsuite failures.

+i586-linux  FAIL: TLS descriptor -fpic -shared transitions
+i586-linux  FAIL: TLS descriptor -fpic and -fno-pic exec transitions
+i586-linux  FAIL: TLS with global dynamic and descriptors
+x86_64-linux  FAIL: TLS descriptor -fpic -shared transitions
+x86_64-linux  FAIL: TLS descriptor -fpic and -fno-pic exec transitions
+x86_64-linux  FAIL: TLS with global dynamic and descriptors
+x86_64-linux  FAIL: TLS -fpic -shared transitions
+x86_64-linux  FAIL: TLS descriptor -fpic -shared transitions
+x86_64-linux  FAIL: TLS -fpic and -fno-pic exec transitions
+x86_64-linux  FAIL: TLS descriptor -fpic and -fno-pic exec transitions
+x86_64-linux  FAIL: TLS with global dynamic and descriptors
+x86_64-linux  FAIL: TLS GD->LE transition
+x86_64-linux  FAIL: TLS LD->LE transition
+x86_64-linux  FAIL: TLS X32 GD->LE transition
+x86_64-linux  FAIL: TLS GD->IE transition
+x86_64-linux  FAIL: TLS X32 GD->IE transition
+x86_64-linux  FAIL: TLS X32 LD->LE transition
+x86_64-linux  FAIL: TLS with PIE

bfd_get_16/32 read in the target endian order, messing with unions
gets you the host endian order or even something entirely unexpected.
Fixed as follows.  OK to apply?

	* elf32-i386.c (i386_opcode16): Delete.
	(elf_i386_check_tls_transition): Use memcmp to compare contents.
	* elf64-x86-64.c (x86_64_opcode16, x86_64_opcode32): Delete.
	(elf_x86_64_check_tls_transition): Use memcmp to compare contents.

Index: bfd/elf32-i386.c
===================================================================
RCS file: /cvs/src/src/bfd/elf32-i386.c,v
retrieving revision 1.261
diff -u -p -r1.261 elf32-i386.c
--- bfd/elf32-i386.c	19 Oct 2011 07:17:13 -0000	1.261
+++ bfd/elf32-i386.c	19 Oct 2011 07:26:19 -0000
@@ -1094,13 +1094,6 @@ elf_i386_copy_indirect_symbol (struct bf
     _bfd_elf_link_hash_copy_indirect (info, dir, ind);
 }
 
-typedef union
-  {
-    unsigned char c[2];
-    uint16_t i;
-  }
-i386_opcode16;
-
 /* Return TRUE if the TLS access code sequence support transition
    from R_TYPE.  */
 
@@ -1271,8 +1264,8 @@ elf_i386_check_tls_transition (bfd *abfd
       if (offset + 2 <= sec->size)
 	{
 	  /* Make sure that it's a call *x@tlsdesc(%rax).  */
-	  static i386_opcode16 call = { { 0xff, 0x10 } };
-	  return bfd_get_16 (abfd, contents + offset) == call.i;
+	  static unsigned char call[] = { 0xff, 0x10 };
+	  return memcmp (contents + offset, call, 2) == 0;
 	}
 
       return FALSE;
Index: bfd/elf64-x86-64.c
===================================================================
RCS file: /cvs/src/src/bfd/elf64-x86-64.c,v
retrieving revision 1.240
diff -u -p -r1.240 elf64-x86-64.c
--- bfd/elf64-x86-64.c	19 Oct 2011 07:17:19 -0000	1.240
+++ bfd/elf64-x86-64.c	19 Oct 2011 07:26:20 -0000
@@ -1007,20 +1007,6 @@ elf64_x86_64_elf_object_p (bfd *abfd)
   return TRUE;
 }
 
-typedef union
-  {
-    unsigned char c[2];
-    uint16_t i;
-  }
-x86_64_opcode16;
-
-typedef union
-  {
-    unsigned char c[4];
-    uint32_t i;
-  }
-x86_64_opcode32;
-
 /* Return TRUE if the TLS access code sequence support transition
    from R_TYPE.  */
 
@@ -1076,24 +1062,23 @@ elf_x86_64_check_tls_transition (bfd *ab
 		.word 0x6666; rex64; call __tls_get_addr
 	     can transit to different access model.  */
 
-	  static x86_64_opcode32 call = { { 0x66, 0x66, 0x48, 0xe8 } };
+	  static unsigned char call[] = { 0x66, 0x66, 0x48, 0xe8 };
+	  static unsigned char leaq[] = { 0x66, 0x48, 0x8d, 0x3d };
+
 	  if ((offset + 12) > sec->size
-	      || bfd_get_32 (abfd, contents + offset + 4) != call.i)
+	      || memcmp (contents + offset + 4, call, 4) != 0)
 	    return FALSE;
 
 	  if (ABI_64_P (abfd))
 	    {
-	      static x86_64_opcode32 leaq = { { 0x66, 0x48, 0x8d, 0x3d } };
 	      if (offset < 4
-		  || bfd_get_32 (abfd, contents + offset - 4) != leaq.i)
+		  || memcmp (contents + offset - 4, leaq, 4) != 0)
 		return FALSE;
 	    }
 	  else
 	    {
-	      static x86_64_opcode16 lea = { { 0x8d, 0x3d } };
 	      if (offset < 3
-		  || bfd_get_8 (abfd, contents + offset - 3) != 0x48
-		  || bfd_get_16 (abfd, contents + offset - 2) != lea.i)
+		  || memcmp (contents + offset - 3, leaq + 1, 3) != 0)
 		return FALSE;
 	    }
 	}
@@ -1104,15 +1089,13 @@ elf_x86_64_check_tls_transition (bfd *ab
 		call __tls_get_addr
 	     can transit to different access model.  */
 
-	  static x86_64_opcode32 ld = { { 0x48, 0x8d, 0x3d, 0xe8 } };
-	  x86_64_opcode32 op;
+	  static unsigned char lea[] = { 0x48, 0x8d, 0x3d };
 
 	  if (offset < 3 || (offset + 9) > sec->size)
 	    return FALSE;
 
-	  op.i = bfd_get_32 (abfd, contents + offset - 3);
-	  op.c[3] = bfd_get_8 (abfd, contents + offset + 4);
-	  if (op.i != ld.i)
+	  if (memcmp (contents + offset - 3, lea, 3) != 0
+	      || 0xe8 != *(contents + offset + 4))
 	    return FALSE;
 	}
 
@@ -1191,8 +1174,8 @@ elf_x86_64_check_tls_transition (bfd *ab
       if (offset + 2 <= sec->size)
 	{
 	  /* Make sure that it's a call *x@tlsdesc(%rax).  */
-	  static x86_64_opcode16 call = { { 0xff, 0x10 } };
-	  return bfd_get_16 (abfd, contents + offset) == call.i;
+	  static unsigned char call[] = { 0xff, 0x10 };
+	  return memcmp (contents + offset, call, 2) == 0;
 	}
 
       return FALSE;

-- 
Alan Modra
Australia Development Lab, IBM


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