Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 30 Oct 2023 17:42:28 GMT
From:      "Stephen J. Kiernan" <stevek@FreeBSD.org>
To:        src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org
Subject:   git: 95335dd3c19e - main - rtld: introduce STATIC_TLS_EXTRA
Message-ID:  <202310301742.39UHgSPp011580@gitrepo.freebsd.org>

next in thread | raw e-mail | index | archive | help
The branch main has been updated by stevek:

URL: https://cgit.FreeBSD.org/src/commit/?id=95335dd3c19e0ade161bb4dc8462fc3d045ce4f8

commit 95335dd3c19e0ade161bb4dc8462fc3d045ce4f8
Author:     Stephen J. Kiernan <stevek@FreeBSD.org>
AuthorDate: 2023-10-29 21:13:10 +0000
Commit:     Stephen J. Kiernan <stevek@FreeBSD.org>
CommitDate: 2023-10-30 17:42:05 +0000

    rtld: introduce STATIC_TLS_EXTRA
    
    The new STATIC_TLS_EXTRA variable provides a means for applications
    to increases the size of the extra static TLS space allocated by
    rtld beyond the default of '128'. This extra static TLS space is used
    for objects loaded with dlopen.
    
    The value specified in the variable must be no less than the default
    value and no greater than the maximum allowed value for size_t type.
    
    If an invalid value is specified, rtld will ignore it and just use
    the default value.
    
    The rtld(1) man page is updated to document this new option.
    
    Obtained from:  Juniper Networks, Inc.
    Differential Revision:  https://reviews.freebsd.org/D42025
---
 libexec/rtld-elf/aarch64/reloc.c   |  2 +-
 libexec/rtld-elf/amd64/reloc.c     |  2 +-
 libexec/rtld-elf/arm/reloc.c       |  3 ++-
 libexec/rtld-elf/i386/reloc.c      |  2 +-
 libexec/rtld-elf/powerpc/reloc.c   |  3 ++-
 libexec/rtld-elf/powerpc64/reloc.c |  3 ++-
 libexec/rtld-elf/riscv/reloc.c     |  2 +-
 libexec/rtld-elf/rtld.1            |  8 +++++++-
 libexec/rtld-elf/rtld.c            | 21 +++++++++++++++++----
 libexec/rtld-elf/rtld.h            |  1 +
 10 files changed, 35 insertions(+), 12 deletions(-)

diff --git a/libexec/rtld-elf/aarch64/reloc.c b/libexec/rtld-elf/aarch64/reloc.c
index c8f09d797215..907377f2619a 100644
--- a/libexec/rtld-elf/aarch64/reloc.c
+++ b/libexec/rtld-elf/aarch64/reloc.c
@@ -521,7 +521,7 @@ allocate_initial_tls(Obj_Entry *objs)
 	* use.
 	*/
 	tls_static_space = tls_last_offset + tls_last_size +
-	    RTLD_STATIC_TLS_EXTRA;
+	    ld_static_tls_extra;
 
 	_tcb_set(allocate_tls(objs, NULL, TLS_TCB_SIZE, TLS_TCB_ALIGN));
 }
diff --git a/libexec/rtld-elf/amd64/reloc.c b/libexec/rtld-elf/amd64/reloc.c
index ce74c54cc5c3..9c5887def356 100644
--- a/libexec/rtld-elf/amd64/reloc.c
+++ b/libexec/rtld-elf/amd64/reloc.c
@@ -527,7 +527,7 @@ allocate_initial_tls(Obj_Entry *objs)
 	 * offset allocated so far and adding a bit for dynamic
 	 * modules to use.
 	 */
-	tls_static_space = tls_last_offset + RTLD_STATIC_TLS_EXTRA;
+	tls_static_space = tls_last_offset + ld_static_tls_extra;
 
 	addr = allocate_tls(objs, 0, TLS_TCB_SIZE, TLS_TCB_ALIGN);
 
diff --git a/libexec/rtld-elf/arm/reloc.c b/libexec/rtld-elf/arm/reloc.c
index b2fb3fdad2c7..c3e95940be74 100644
--- a/libexec/rtld-elf/arm/reloc.c
+++ b/libexec/rtld-elf/arm/reloc.c
@@ -454,7 +454,8 @@ allocate_initial_tls(Obj_Entry *objs)
 	* use.
 	*/
 
-	tls_static_space = tls_last_offset + tls_last_size + RTLD_STATIC_TLS_EXTRA;
+	tls_static_space = tls_last_offset + tls_last_size +
+	    ld_static_tls_extra;
 
 	_tcb_set(allocate_tls(objs, NULL, TLS_TCB_SIZE, TLS_TCB_ALIGN));
 }
diff --git a/libexec/rtld-elf/i386/reloc.c b/libexec/rtld-elf/i386/reloc.c
index 8e8966926839..04a8354343bc 100644
--- a/libexec/rtld-elf/i386/reloc.c
+++ b/libexec/rtld-elf/i386/reloc.c
@@ -510,7 +510,7 @@ allocate_initial_tls(Obj_Entry *objs)
      * offset allocated so far and adding a bit for dynamic modules to
      * use.
      */
-    tls_static_space = tls_last_offset + RTLD_STATIC_TLS_EXTRA;
+    tls_static_space = tls_last_offset + ld_static_tls_extra;
     tls = allocate_tls(objs, NULL, TLS_TCB_SIZE, TLS_TCB_ALIGN);
     _tcb_set(tls);
 }
diff --git a/libexec/rtld-elf/powerpc/reloc.c b/libexec/rtld-elf/powerpc/reloc.c
index 8254f21a3ce6..73a1c89991e2 100644
--- a/libexec/rtld-elf/powerpc/reloc.c
+++ b/libexec/rtld-elf/powerpc/reloc.c
@@ -817,7 +817,8 @@ allocate_initial_tls(Obj_Entry *list)
 	* use.
 	*/
 
-	tls_static_space = tls_last_offset + tls_last_size + RTLD_STATIC_TLS_EXTRA;
+	tls_static_space = tls_last_offset + tls_last_size +
+	    ld_static_tls_extra;
 
 	_tcb_set(allocate_tls(list, NULL, TLS_TCB_SIZE, TLS_TCB_ALIGN));
 }
diff --git a/libexec/rtld-elf/powerpc64/reloc.c b/libexec/rtld-elf/powerpc64/reloc.c
index 5bfb05116315..70928829aeda 100644
--- a/libexec/rtld-elf/powerpc64/reloc.c
+++ b/libexec/rtld-elf/powerpc64/reloc.c
@@ -714,7 +714,8 @@ allocate_initial_tls(Obj_Entry *list)
 	* use.
 	*/
 
-	tls_static_space = tls_last_offset + tls_last_size + RTLD_STATIC_TLS_EXTRA;
+	tls_static_space = tls_last_offset + tls_last_size +
+	    ld_static_tls_extra;
 
 	_tcb_set(allocate_tls(list, NULL, TLS_TCB_SIZE, TLS_TCB_ALIGN));
 }
diff --git a/libexec/rtld-elf/riscv/reloc.c b/libexec/rtld-elf/riscv/reloc.c
index 5ed516bc4337..d806e1ec3d63 100644
--- a/libexec/rtld-elf/riscv/reloc.c
+++ b/libexec/rtld-elf/riscv/reloc.c
@@ -392,7 +392,7 @@ allocate_initial_tls(Obj_Entry *objs)
 	 * use.
 	 */
 	tls_static_space = tls_last_offset + tls_last_size +
-	    RTLD_STATIC_TLS_EXTRA;
+	    ld_static_tls_extra;
 
 	_tcb_set(allocate_tls(objs, NULL, TLS_TCB_SIZE, TLS_TCB_ALIGN));
 }
diff --git a/libexec/rtld-elf/rtld.1 b/libexec/rtld-elf/rtld.1
index 807ecb31ad7c..4d97159b0aaf 100644
--- a/libexec/rtld-elf/rtld.1
+++ b/libexec/rtld-elf/rtld.1
@@ -26,7 +26,7 @@
 .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 .\"
-.Dd November 10, 2022
+.Dd October 29, 2023
 .Dt RTLD 1
 .Os
 .Sh NAME
@@ -320,6 +320,12 @@ If set, causes
 .Nm
 to dump content of the aux vector to standard output, before passing
 control to any user code.
+.It Ev LD_STATIC_TLS_EXTRA
+If the variable is specified and has a numeric value,
+.Nm
+will set the size of the static TLS extra space to the specified number
+of bytes. The static TLS extra space is used when loading objects with
+dlopen. The minimum value that can be specified is \'128\'.
 .El
 .Sh DIRECT EXECUTION MODE
 .Nm
diff --git a/libexec/rtld-elf/rtld.c b/libexec/rtld-elf/rtld.c
index f8c4c18b5d5e..831a854cffb8 100644
--- a/libexec/rtld-elf/rtld.c
+++ b/libexec/rtld-elf/rtld.c
@@ -225,6 +225,8 @@ static Obj_Entry *obj_main;	/* The main program shared object */
 static Obj_Entry obj_rtld;	/* The dynamic linker shared object */
 static unsigned int obj_count;	/* Number of objects in obj_list */
 static unsigned int obj_loads;	/* Number of loads of objects (gen count) */
+size_t ld_static_tls_extra =	/* Static TLS extra space (bytes) */
+  RTLD_STATIC_TLS_EXTRA;
 
 static Objlist list_global =	/* Objects dlopened with RTLD_GLOBAL */
   STAILQ_HEAD_INITIALIZER(list_global);
@@ -365,6 +367,7 @@ enum {
 	LD_TRACE_LOADED_OBJECTS_FMT2,
 	LD_TRACE_LOADED_OBJECTS_ALL,
 	LD_SHOW_AUXV,
+	LD_STATIC_TLS_EXTRA,
 };
 
 struct ld_env_var_desc {
@@ -398,6 +401,7 @@ static struct ld_env_var_desc ld_env_vars[] = {
 	LD_ENV_DESC(TRACE_LOADED_OBJECTS_FMT2, false),
 	LD_ENV_DESC(TRACE_LOADED_OBJECTS_ALL, false),
 	LD_ENV_DESC(SHOW_AUXV, false),
+	LD_ENV_DESC(STATIC_TLS_EXTRA, false),
 };
 
 static const char *
@@ -515,7 +519,7 @@ _rtld(Elf_Addr *sp, func_ptr_type *exit_proc, Obj_Entry **objp)
     struct stat st;
     Elf_Addr *argcp;
     char **argv, **env, **envp, *kexecpath;
-    const char *argv0, *binpath, *library_path_rpath;
+    const char *argv0, *binpath, *library_path_rpath, *static_tls_extra;
     struct ld_env_var_desc *lvd;
     caddr_t imgentry;
     char buf[MAXPATHLEN];
@@ -738,9 +742,16 @@ _rtld(Elf_Addr *sp, func_ptr_type *exit_proc, Obj_Entry **objp)
 	    else
 		    ld_library_path_rpath = false;
     }
+    static_tls_extra = ld_get_env_var(LD_STATIC_TLS_EXTRA);
+    if (static_tls_extra != NULL && static_tls_extra[0] != '\0') {
+	sz = parse_integer(static_tls_extra);
+	if (sz >= RTLD_STATIC_TLS_EXTRA && sz <= SIZE_T_MAX)
+	    ld_static_tls_extra = sz;
+    }
     dangerous_ld_env = libmap_disable || libmap_override != NULL ||
 	ld_library_path != NULL || ld_preload != NULL ||
-	ld_elf_hints_path != NULL || ld_loadfltr || !ld_dynamic_weak;
+	ld_elf_hints_path != NULL || ld_loadfltr || !ld_dynamic_weak ||
+	static_tls_extra != NULL;
     ld_tracing = ld_get_env_var(LD_TRACE_LOADED_OBJECTS);
     ld_utrace = ld_get_env_var(LD_UTRACE);
 
@@ -6105,13 +6116,15 @@ parse_args(char* argv[], int argc, bool *use_pathp, int *fdp,
 				    "Env prefix %s\n"
 				    "Default hint file %s\n"
 				    "Hint file %s\n"
-				    "libmap file %s\n",
+				    "libmap file %s\n"
+				    "Optional static TLS size %zd bytes\n",
 				    machine,
 				    __FreeBSD_version, ld_standard_library_path,
 				    gethints(false),
 				    ld_env_prefix, ld_elf_hints_default,
 				    ld_elf_hints_path,
-				    ld_path_libmap_conf);
+				    ld_path_libmap_conf,
+				    ld_static_tls_extra);
 				_exit(0);
 			} else {
 				_rtld_error("Invalid argument: '%s'", arg);
diff --git a/libexec/rtld-elf/rtld.h b/libexec/rtld-elf/rtld.h
index 7fe9d837d6f1..c7c17426b38a 100644
--- a/libexec/rtld-elf/rtld.h
+++ b/libexec/rtld-elf/rtld.h
@@ -50,6 +50,7 @@ extern size_t tls_last_size;
 extern size_t tls_static_space;
 extern Elf_Addr tls_dtv_generation;
 extern int tls_max_index;
+extern size_t ld_static_tls_extra;
 
 extern int npagesizes;
 extern size_t *pagesizes;



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202310301742.39UHgSPp011580>