This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
Re: PATCH: Optimize x86 TLS access for forced local symbols
- From: "H.J. Lu" <hjl at lucon dot org>
- To: Jakub Jelinek <jakub at redhat dot com>
- Cc: binutils at sources dot redhat dot com
- Date: Mon, 20 Aug 2007 13:42:15 -0700
- Subject: Re: PATCH: Optimize x86 TLS access for forced local symbols
- References: <20070820195151.GA11871@lucon.org> <20070820202457.GZ2063@devserv.devel.redhat.com>
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];