diff mbox

Add hidden __tls_get_addr/___tls_get_addr alias

Message ID 20141221173111.GA18366@gmail.com
State Committed
Headers show

Commit Message

H.J. Lu Dec. 21, 2014, 5:31 p.m. UTC
On Sun, Dec 21, 2014 at 12:05:38PM -0500, Chris Metcalf wrote:
> On 12/20/2014 4:10 PM, H.J. Lu wrote:
> >index d7d6734..1a40cf9 100644
> >--- a/sysdeps/generic/localplt.data
> >+++ b/sysdeps/generic/localplt.data
> >@@ -7,10 +7,9 @@ libc.so: malloc
> >  libc.so: memalign
> >  libc.so: realloc
> >  libm.so: matherr
> >-# The dynamic loader needs __tls_get_addr for TLS, and uses __libc_memalign
> >-# internally to allocate aligned TLS storage. The other malloc family of
> >-# functions are expected to allow user symbol interposition.
> >-ld.so: __tls_get_addr
> >+# The dynamic loader uses __libc_memalign internally to allocate aligned
> >+# TLS storage. The other malloc family of functions are expected to allow
> >+# user symbol interposition.
> >  ld.so: __libc_memalign
> >  ld.so: malloc
> >  ld.so: calloc
> 
> Great, thanks.  I will remove the tile-specific version when this is pushed.
> 

This is what I checked in.

Thanks.

H.J.
--
From 050f7298e1ecc39887c329037575ccd972071255 Mon Sep 17 00:00:00 2001
From: "H.J. Lu" <hjl.tools@gmail.com>
Date: Sun, 21 Dec 2014 09:12:04 -0800
Subject: [PATCH] Add hidden __tls_get_addr/___tls_get_addr alias

__tls_get_addr/___tls_get_addr is always defined in ld.so.  There is
no need to call them via PLT inside ld.so.  This patch adds the hidden
__tls_get_addr/___tls_get_addr aliases and calls them directly from
_dl_tlsdesc_dynamic.  There is no need to set up the EBX register in
i386 _dl_tlsdesc_dynamic when calling the hidden ___tls_get_addr.

	* elf/dl-tls.c (__tls_get_addr): Provide the hidden definition
	if not defined.
	* sysdeps/i386/dl-tls.h (___tls_get_addr): Provide the hidden
	definition.
	* sysdeps/i386/dl-tlsdesc.S (_dl_tlsdesc_dynamic): Call the
	hidden ___tls_get_addr.
	* sysdeps/x86_64/dl-tlsdesc.S (_dl_tlsdesc_dynamic): Call the
	hidden __tls_get_addr.
	* sysdeps/generic/localplt.data (__tls_get_addr): Removed.
	* sysdeps/unix/sysv/linux/i386/localplt.data (___tls_get_addr):
	Likewise.
---
 ChangeLog                                  | 14 ++++++++++++++
 elf/dl-tls.c                               | 10 ++++++++++
 sysdeps/generic/localplt.data              |  7 +++----
 sysdeps/i386/dl-tls.h                      |  2 ++
 sysdeps/i386/dl-tlsdesc.S                  |  5 +----
 sysdeps/unix/sysv/linux/i386/localplt.data |  9 +++------
 sysdeps/x86_64/dl-tlsdesc.S                |  2 +-
 7 files changed, 34 insertions(+), 15 deletions(-)
diff mbox

Patch

diff --git a/ChangeLog b/ChangeLog
index 078af75..28c293d 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,17 @@ 
+2014-12-21  H.J. Lu  <hongjiu.lu@intel.com>
+
+	* elf/dl-tls.c (__tls_get_addr): Provide the hidden definition
+	if not defined.
+	* sysdeps/i386/dl-tls.h (___tls_get_addr): Provide the hidden
+	definition.
+	* sysdeps/i386/dl-tlsdesc.S (_dl_tlsdesc_dynamic): Call the
+	hidden ___tls_get_addr.
+	* sysdeps/x86_64/dl-tlsdesc.S (_dl_tlsdesc_dynamic): Call the
+	hidden __tls_get_addr.
+	* sysdeps/generic/localplt.data (__tls_get_addr): Removed.
+	* sysdeps/unix/sysv/linux/i386/localplt.data (___tls_get_addr):
+	Likewise.
+
 2014-12-21  Andreas Schwab  <schwab@linux-m68k.org>
 
 	* sysdeps/m68k/dl-machine.h (RTLD_START): Remove @PLTPC from
diff --git a/elf/dl-tls.c b/elf/dl-tls.c
index 76b8b36..0abb024 100644
--- a/elf/dl-tls.c
+++ b/elf/dl-tls.c
@@ -809,6 +809,16 @@  update_get_addr (GET_ADDR_ARGS)
   return (void *) p + GET_ADDR_OFFSET;
 }
 
+/* For all machines that have a non-macro version of __tls_get_addr, we
+   want to use rtld_hidden_proto/rtld_hidden_def in order to call the
+   internal alias for __tls_get_addr from ld.so. This avoids a PLT entry
+   in ld.so for __tls_get_addr.  */
+
+#ifndef __tls_get_addr
+extern void * __tls_get_addr (GET_ADDR_ARGS);
+rtld_hidden_proto (__tls_get_addr)
+rtld_hidden_def (__tls_get_addr)
+#endif
 
 /* The generic dynamic and local dynamic model cannot be used in
    statically linked applications.  */
diff --git a/sysdeps/generic/localplt.data b/sysdeps/generic/localplt.data
index d7d6734..1a40cf9 100644
--- a/sysdeps/generic/localplt.data
+++ b/sysdeps/generic/localplt.data
@@ -7,10 +7,9 @@  libc.so: malloc
 libc.so: memalign
 libc.so: realloc
 libm.so: matherr
-# The dynamic loader needs __tls_get_addr for TLS, and uses __libc_memalign
-# internally to allocate aligned TLS storage. The other malloc family of
-# functions are expected to allow user symbol interposition.
-ld.so: __tls_get_addr
+# The dynamic loader uses __libc_memalign internally to allocate aligned
+# TLS storage. The other malloc family of functions are expected to allow
+# user symbol interposition.
 ld.so: __libc_memalign
 ld.so: malloc
 ld.so: calloc
diff --git a/sysdeps/i386/dl-tls.h b/sysdeps/i386/dl-tls.h
index 48809a5..99b86f9 100644
--- a/sysdeps/i386/dl-tls.h
+++ b/sysdeps/i386/dl-tls.h
@@ -50,6 +50,8 @@  __tls_get_addr (tls_index *ti)
    version of this file.  */
 # define __tls_get_addr __attribute__ ((__regparm__ (1))) ___tls_get_addr
 strong_alias (___tls_get_addr, ___tls_get_addr_internal)
+rtld_hidden_proto (___tls_get_addr)
+rtld_hidden_def (___tls_get_addr)
 #else
 
 /* Users should get the better interface.  */
diff --git a/sysdeps/i386/dl-tlsdesc.S b/sysdeps/i386/dl-tlsdesc.S
index e6753e9..570b180 100644
--- a/sysdeps/i386/dl-tlsdesc.S
+++ b/sysdeps/i386/dl-tlsdesc.S
@@ -126,10 +126,7 @@  _dl_tlsdesc_dynamic:
 	.p2align 4,,7
 .Lslow:
 	cfi_adjust_cfa_offset (28)
-	movl	%ebx, 16(%esp)
-	LOAD_PIC_REG (bx)
-	call	___tls_get_addr@PLT
-	movl	16(%esp), %ebx
+	call	HIDDEN_JUMPTARGET (___tls_get_addr)
 	jmp	.Lret
 	cfi_endproc
 	.size	_dl_tlsdesc_dynamic, .-_dl_tlsdesc_dynamic
diff --git a/sysdeps/unix/sysv/linux/i386/localplt.data b/sysdeps/unix/sysv/linux/i386/localplt.data
index 009797b..b25abf8 100644
--- a/sysdeps/unix/sysv/linux/i386/localplt.data
+++ b/sysdeps/unix/sysv/linux/i386/localplt.data
@@ -5,12 +5,9 @@  libc.so: malloc
 libc.so: memalign
 libc.so: realloc
 libm.so: matherr
-# The dynamic loader needs ___tls_get_addr for TLS, and uses __libc_memalign
-# internally to allocate aligned TLS storage. The other malloc family of
-# functions are expected to allow user symbol interposition.
-# Note that it is triple underscore for ___tls_get_addr e.g. the alternate
-# ABI.
-ld.so: ___tls_get_addr
+# The dynamic loader uses __libc_memalign internally to allocate aligned
+# TLS storage. The other malloc family of functions are expected to allow
+# user symbol interposition.
 ld.so: __libc_memalign
 ld.so: malloc
 ld.so: calloc
diff --git a/sysdeps/x86_64/dl-tlsdesc.S b/sysdeps/x86_64/dl-tlsdesc.S
index 92e18a5..03f5ca4 100644
--- a/sysdeps/x86_64/dl-tlsdesc.S
+++ b/sysdeps/x86_64/dl-tlsdesc.S
@@ -128,7 +128,7 @@  _dl_tlsdesc_dynamic:
 	movq	%r10, 40(%rsp)
 	movq	%r11, 48(%rsp)
 	/* %rdi already points to the tlsinfo data structure.  */
-	call	__tls_get_addr@PLT
+	call	HIDDEN_JUMPTARGET (__tls_get_addr)
 	movq	8(%rsp), %rdx
 	movq	16(%rsp), %rcx
 	movq	24(%rsp), %r8