This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
PATCH: Optimize x86 TLS access for forced local symbols
- From: "H.J. Lu" <hjl at lucon dot org>
- To: binutils at sources dot redhat dot com
- Cc: jakub at redhat dot com
- Date: Mon, 20 Aug 2007 12:51:51 -0700
- Subject: PATCH: Optimize x86 TLS access for forced local symbols
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];