b1dca6
commit 07ed32f920f0bcb1ddb400e4ed606104756dee32
b1dca6
Author: Florian Weimer <fweimer@redhat.com>
b1dca6
Date:   Mon Jul 20 13:30:45 2020 +0200
b1dca6
b1dca6
    elf: Change TLS static surplus default back to 1664
b1dca6
    
b1dca6
    Make the computation in elf/dl-tls.c more transparent, and add
b1dca6
    an explicit test for the historic value.
b1dca6
    
b1dca6
    Reviewed-by: Carlos O'Donell <carlos@redhat.com>
b1dca6
b1dca6
Conflicts:
b1dca6
	elf/Makefile
b1dca6
	  (Missing test backports.)
b1dca6
	elf/dl-tls.c
b1dca6
	  (Missing backport of rseq and its revert.)
b1dca6
b1dca6
diff --git a/elf/Makefile b/elf/Makefile
b1dca6
index 8b96bfefd852b79f..82b5b4a07495c805 100644
b1dca6
--- a/elf/Makefile
b1dca6
+++ b/elf/Makefile
b1dca6
@@ -204,7 +204,7 @@ tests-internal += loadtest unload unload2 circleload1 \
b1dca6
 	 neededtest neededtest2 neededtest3 neededtest4 \
b1dca6
 	 tst-tls3 tst-tls6 tst-tls7 tst-tls8 tst-dlmopen2 \
b1dca6
 	 tst-ptrguard1 tst-stackguard1 tst-libc_dlvsym \
b1dca6
-	 tst-create_format1
b1dca6
+	 tst-create_format1 tst-tls-surplus
b1dca6
 tests-container += tst-pldd
b1dca6
 ifeq ($(build-hardcoded-path-in-tests),yes)
b1dca6
 tests += tst-dlopen-aout
b1dca6
@@ -1714,3 +1714,5 @@ $(objpfx)tst-tls-ie-dlmopen.out: \
b1dca6
   $(objpfx)tst-tls-ie-mod4.so \
b1dca6
   $(objpfx)tst-tls-ie-mod5.so \
b1dca6
   $(objpfx)tst-tls-ie-mod6.so
b1dca6
+
b1dca6
+$(objpfx)tst-tls-surplus: $(libdl)
b1dca6
diff --git a/elf/dl-tls.c b/elf/dl-tls.c
b1dca6
index 4f8c35b7d37bfc18..cccf74b33481b866 100644
b1dca6
--- a/elf/dl-tls.c
b1dca6
+++ b/elf/dl-tls.c
b1dca6
@@ -54,13 +54,37 @@
b1dca6
    Audit modules use their own namespaces, they are not included in rtld.nns,
b1dca6
    but come on top when computing the number of namespaces.  */
b1dca6
 
b1dca6
-/* Size of initial-exec TLS in libc.so.  */
b1dca6
-#define LIBC_IE_TLS 192
b1dca6
+/* Size of initial-exec TLS in libc.so.  This should be the maximum of
b1dca6
+   observed PT_GNU_TLS sizes across all architectures.  Some
b1dca6
+   architectures have lower values due to differences in type sizes
b1dca6
+   and link editor capabilities.  */
b1dca6
+#define LIBC_IE_TLS 144
b1dca6
+
b1dca6
 /* Size of initial-exec TLS in libraries other than libc.so.
b1dca6
    This should be large enough to cover runtime libraries of the
b1dca6
    compiler such as libgomp and libraries in libc other than libc.so.  */
b1dca6
 #define OTHER_IE_TLS 144
b1dca6
 
b1dca6
+/* Default number of namespaces.  */
b1dca6
+#define DEFAULT_NNS 4
b1dca6
+
b1dca6
+/* Default for dl_tls_static_optional.  */
b1dca6
+#define OPTIONAL_TLS 512
b1dca6
+
b1dca6
+/* Compute the static TLS surplus based on the namespace count and the
b1dca6
+   TLS space that can be used for optimizations.  */
b1dca6
+static inline int
b1dca6
+tls_static_surplus (int nns, int opt_tls)
b1dca6
+{
b1dca6
+  return (nns - 1) * LIBC_IE_TLS + nns * OTHER_IE_TLS + opt_tls;
b1dca6
+}
b1dca6
+
b1dca6
+/* This value is chosen so that with default values for the tunables,
b1dca6
+   the computation of dl_tls_static_surplus in
b1dca6
+   _dl_tls_static_surplus_init yields the historic value 1664, for
b1dca6
+   backwards compatibility.  */
b1dca6
+#define LEGACY_TLS (1664 - tls_static_surplus (DEFAULT_NNS, OPTIONAL_TLS))
b1dca6
+
b1dca6
 /* Calculate the size of the static TLS surplus, when the given
b1dca6
    number of audit modules are loaded.  Must be called after the
b1dca6
    number of audit modules is known and before static TLS allocation.  */
b1dca6
@@ -74,8 +98,8 @@ _dl_tls_static_surplus_init (size_t naudit)
b1dca6
   opt_tls = TUNABLE_GET (optional_static_tls, size_t, NULL);
b1dca6
 #else
b1dca6
   /* Default values of the tunables.  */
b1dca6
-  nns = 4;
b1dca6
-  opt_tls = 512;
b1dca6
+  nns = DEFAULT_NNS;
b1dca6
+  opt_tls = OPTIONAL_TLS;
b1dca6
 #endif
b1dca6
   if (nns > DL_NNS)
b1dca6
     nns = DL_NNS;
b1dca6
@@ -85,9 +109,8 @@ _dl_tls_static_surplus_init (size_t naudit)
b1dca6
   nns += naudit;
b1dca6
 
b1dca6
   GL(dl_tls_static_optional) = opt_tls;
b1dca6
-  GLRO(dl_tls_static_surplus) = ((nns - 1) * LIBC_IE_TLS
b1dca6
-				 + nns * OTHER_IE_TLS
b1dca6
-				 + opt_tls);
b1dca6
+  assert (LEGACY_TLS >= 0);
b1dca6
+  GLRO(dl_tls_static_surplus) = tls_static_surplus (nns, opt_tls) + LEGACY_TLS;
b1dca6
 }
b1dca6
 
b1dca6
 /* Out-of-memory handler.  */
b1dca6
diff --git a/elf/tst-tls-surplus.c b/elf/tst-tls-surplus.c
b1dca6
new file mode 100644
b1dca6
index 0000000000000000..b0dea0b5ee178ddd
b1dca6
--- /dev/null
b1dca6
+++ b/elf/tst-tls-surplus.c
b1dca6
@@ -0,0 +1,42 @@
b1dca6
+/* Test size of the static TLS surplus reservation for backwards compatibility.
b1dca6
+   Copyright (C) 2020 Free Software Foundation, Inc.
b1dca6
+   This file is part of the GNU C Library.
b1dca6
+
b1dca6
+   The GNU C Library is free software; you can redistribute it and/or
b1dca6
+   modify it under the terms of the GNU Lesser General Public
b1dca6
+   License as published by the Free Software Foundation; either
b1dca6
+   version 2.1 of the License, or (at your option) any later version.
b1dca6
+
b1dca6
+   The GNU C Library is distributed in the hope that it will be useful,
b1dca6
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
b1dca6
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
b1dca6
+   Lesser General Public License for more details.
b1dca6
+
b1dca6
+   You should have received a copy of the GNU Lesser General Public
b1dca6
+   License along with the GNU C Library; if not, see
b1dca6
+   <https://www.gnu.org/licenses/>.  */
b1dca6
+
b1dca6
+#include <stdio.h>
b1dca6
+#include <support/check.h>
b1dca6
+#include <support/xdlfcn.h>
b1dca6
+
b1dca6
+static int do_test (void);
b1dca6
+#include <support/test-driver.c>
b1dca6
+
b1dca6
+/* This hack results in a definition of struct rtld_global_ro.  Do
b1dca6
+   this after all the other header inclusions, to minimize the
b1dca6
+   impact.  */
b1dca6
+#define SHARED
b1dca6
+#include <ldsodefs.h>
b1dca6
+
b1dca6
+static
b1dca6
+int do_test (void)
b1dca6
+{
b1dca6
+  /* Avoid introducing a copy relocation due to the hidden alias in
b1dca6
+     ld.so.  */
b1dca6
+  struct rtld_global_ro *glro = xdlsym (NULL, "_rtld_global_ro");
b1dca6
+  printf ("info: _dl_tls_static_surplus: %zu\n", glro->_dl_tls_static_surplus);
b1dca6
+  /* Hisoric value: 16 * 100 + 64.  */
b1dca6
+  TEST_VERIFY (glro->_dl_tls_static_surplus >= 1664);
b1dca6
+  return 0;
b1dca6
+}