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]

Re: PATCH: Optimize x86 TLS access for forced local symbols


On Mon, Aug 20, 2007 at 04:24:57PM -0400, Jakub Jelinek wrote:
> On Mon, Aug 20, 2007 at 12:51:51PM -0700, H.J. Lu wrote:
> > 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?
> 
> I'm ok with this if it works, just wondering, can't a symbol change

I am working on some testcases.

> it's SYMBOL_REFERENCES_LOCALness in between check_relocs and/or gc_sweep_hook
> and size_dynamic_sections/relocate_section?  If it does, the
> TLS transitions can change after your patch, but we wouldn't update
> the counters accordingly.
> 

Since the TLS transition has

  if (info->shared)
    return r_type;

my change only affects forced local symbols in executables. I am not
sure if we should bother with them. Here is an updated patch. The
only difference is now elf_i386_gc_sweep_hook and
elf64_x86_64_gc_sweep_hook call the TLS transition like h === NULL
instead of h != NULL originally.


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.
	(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.
	(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 13:37:18.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 (h == NULL)
 	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 (h == NULL)
 	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 13:37:25.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 (h == NULL)
 	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];


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