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