The branch stable/14 has been updated by kib:

URL: 
https://cgit.FreeBSD.org/src/commit/?id=0b56acfc498ed2cc325f6b8debfc7fdc3b03d676

commit 0b56acfc498ed2cc325f6b8debfc7fdc3b03d676
Author:     Stephen J. Kiernan <[email protected]>
AuthorDate: 2023-10-29 21:13:10 +0000
Commit:     Konstantin Belousov <[email protected]>
CommitDate: 2024-04-20 13:52:16 +0000

    rtld: introduce STATIC_TLS_EXTRA
    
    (cherry picked from commit 95335dd3c19e0ade161bb4dc8462fc3d045ce4f8)
---
 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 07068dff0b62..d5e702652058 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);
 
@@ -6165,13 +6176,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 c9e0d4ab0525..6311b3e6cc7f 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;

Reply via email to