PATCH: Optimize x86 TLS access for forced local symbols

H.J. Lu hjl@lucon.org
Mon Aug 20 20:42:00 GMT 2007


Hi Jakub,

Is there a particular reason we don't optimize x86 TLS access for
forced local symbols? Also, both elf_i386_gc_sweep_hook and
elf64_x86_64_gc_sweep_hook call the TLS transition function with
h != NULL to indicate that a global symbols is local.  Am I missing
something? Some comments will be very nice if it is intentional.

This patch optimizes x86 TLS access for forced local symbols. It
also changes the way how the TLS transition function is called
from elf_i386_gc_sweep_hook and elf64_x86_64_gc_sweep_hook.

There are no regressions for Linux/ia32 and Linux/x86-64. Can you
take a look?

Thanks.


H.J.
----
2007-08-20  H.J. Lu  <hongjiu.lu@intel.com>

	* elf32-i386.c (elf_i386_tls_transition): Accept a pointer
	to ELF hash entry instead of an integer for local test.  Use
	SYMBOL_REFERENCES_LOCAL to check if a symbol should be bound
	locally.
	(elf_i386_check_relocs): Updated.
	(elf_i386_gc_sweep_hook): Likewise.
	(elf_i386_relocate_section): Likewise.

	* elf64-x86-64.c  (elf64_x86_64_tls_transition): Accept a
	pointer to ELF hash entry instead of an integer for local
	test.  Use SYMBOL_REFERENCES_LOCAL to check if a symbol
	should be bound locally.
	(elf64_x86_64_check_relocs): Updated.
	(elf64_x86_64_gc_sweep_hook): Likewise.
	(elf64_x86_64_relocate_section): Likewise.

--- bfd/elf32-i386.c.tls	2007-08-20 12:13:29.000000000 -0700
+++ bfd/elf32-i386.c	2007-08-20 12:29:54.000000000 -0700
@@ -908,7 +908,7 @@ elf_i386_copy_indirect_symbol (struct bf
 
 static int
 elf_i386_tls_transition (struct bfd_link_info *info, int r_type,
-			 int is_local)
+			 struct elf_link_hash_entry *h)
 {
   if (info->shared)
     return r_type;
@@ -919,12 +919,12 @@ elf_i386_tls_transition (struct bfd_link
     case R_386_TLS_GOTDESC:
     case R_386_TLS_DESC_CALL:
     case R_386_TLS_IE_32:
-      if (is_local)
+      if (SYMBOL_REFERENCES_LOCAL (info, h))
 	return R_386_TLS_LE_32;
       return R_386_TLS_IE_32;
     case R_386_TLS_IE:
     case R_386_TLS_GOTIE:
-      if (is_local)
+      if (SYMBOL_REFERENCES_LOCAL (info, h))
 	return R_386_TLS_LE_32;
       return r_type;
     case R_386_TLS_LDM:
@@ -988,7 +988,7 @@ elf_i386_check_relocs (bfd *abfd,
 	    h = (struct elf_link_hash_entry *) h->root.u.i.link;
 	}
 
-      r_type = elf_i386_tls_transition (info, r_type, h == NULL);
+      r_type = elf_i386_tls_transition (info, r_type, h);
 
       switch (r_type)
 	{
@@ -1377,7 +1377,7 @@ elf_i386_gc_sweep_hook (bfd *abfd,
 	}
 
       r_type = ELF32_R_TYPE (rel->r_info);
-      r_type = elf_i386_tls_transition (info, r_type, h != NULL);
+      r_type = elf_i386_tls_transition (info, r_type, h);
       switch (r_type)
 	{
 	case R_386_TLS_LDM:
@@ -2644,7 +2644,7 @@ elf_i386_relocate_section (bfd *output_b
 	case R_386_TLS_DESC_CALL:
 	case R_386_TLS_IE_32:
 	case R_386_TLS_GOTIE:
-	  r_type = elf_i386_tls_transition (info, r_type, h == NULL);
+	  r_type = elf_i386_tls_transition (info, r_type, h);
 	  tls_type = GOT_UNKNOWN;
 	  if (h == NULL && local_got_offsets)
 	    tls_type = elf_i386_local_got_tls_type (input_bfd) [r_symndx];
--- bfd/elf64-x86-64.c.tls	2007-08-20 12:13:29.000000000 -0700
+++ bfd/elf64-x86-64.c	2007-08-20 12:27:28.000000000 -0700
@@ -727,7 +727,7 @@ elf64_x86_64_elf_object_p (bfd *abfd)
 
 static int
 elf64_x86_64_tls_transition (struct bfd_link_info *info, int r_type,
-			     int is_local)
+			     struct elf_link_hash_entry *h)
 {
   if (info->shared)
     return r_type;
@@ -738,7 +738,7 @@ elf64_x86_64_tls_transition (struct bfd_
     case R_X86_64_GOTPC32_TLSDESC:
     case R_X86_64_TLSDESC_CALL:
     case R_X86_64_GOTTPOFF:
-      if (is_local)
+      if (SYMBOL_REFERENCES_LOCAL (info, h))
 	return R_X86_64_TPOFF32;
       return R_X86_64_GOTTPOFF;
     case R_X86_64_TLSLD:
@@ -799,7 +799,7 @@ elf64_x86_64_check_relocs (bfd *abfd, st
 	    h = (struct elf_link_hash_entry *) h->root.u.i.link;
 	}
 
-      r_type = elf64_x86_64_tls_transition (info, r_type, h == NULL);
+      r_type = elf64_x86_64_tls_transition (info, r_type, h);
       switch (r_type)
 	{
 	case R_X86_64_TLSLD:
@@ -1229,7 +1229,7 @@ elf64_x86_64_gc_sweep_hook (bfd *abfd, s
 	}
 
       r_type = ELF64_R_TYPE (rel->r_info);
-      r_type = elf64_x86_64_tls_transition (info, r_type, h != NULL);
+      r_type = elf64_x86_64_tls_transition (info, r_type, h);
       switch (r_type)
 	{
 	case R_X86_64_TLSLD:
@@ -2522,7 +2522,7 @@ elf64_x86_64_relocate_section (bfd *outp
 	case R_X86_64_GOTPC32_TLSDESC:
 	case R_X86_64_TLSDESC_CALL:
 	case R_X86_64_GOTTPOFF:
-	  r_type = elf64_x86_64_tls_transition (info, r_type, h == NULL);
+	  r_type = elf64_x86_64_tls_transition (info, r_type, h);
 	  tls_type = GOT_UNKNOWN;
 	  if (h == NULL && local_got_offsets)
 	    tls_type = elf64_x86_64_local_got_tls_type (input_bfd) [r_symndx];



More information about the Binutils mailing list