Blame elf/tst-tls-ie-dlmopen.c

Packit Service a2413a
/* Test dlopen of modules with initial-exec TLS after dlmopen.
Packit Service a2413a
   Copyright (C) 2016-2020 Free Software Foundation, Inc.
Packit Service a2413a
   This file is part of the GNU C Library.
Packit Service a2413a
Packit Service a2413a
   The GNU C Library is free software; you can redistribute it and/or
Packit Service a2413a
   modify it under the terms of the GNU Lesser General Public
Packit Service a2413a
   License as published by the Free Software Foundation; either
Packit Service a2413a
   version 2.1 of the License, or (at your option) any later version.
Packit Service a2413a
Packit Service a2413a
   The GNU C Library is distributed in the hope that it will be useful,
Packit Service a2413a
   but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit Service a2413a
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Packit Service a2413a
   Lesser General Public License for more details.
Packit Service a2413a
Packit Service a2413a
   You should have received a copy of the GNU Lesser General Public
Packit Service a2413a
   License along with the GNU C Library; if not, see
Packit Service a2413a
   <https://www.gnu.org/licenses/>.  */
Packit Service a2413a
Packit Service a2413a
/* This test tries to check that surplus static TLS is not used up for
Packit Service a2413a
   dynamic TLS optimizations and 4*144 = 576 bytes of static TLS is
Packit Service a2413a
   still available for dlopening modules with initial-exec TLS after 3
Packit Service a2413a
   new dlmopen namespaces are created.  It depends on rtld.nns=4 and
Packit Service a2413a
   rtld.optional_static_tls=512 tunable settings.  */
Packit Service a2413a
Packit Service a2413a
#include <errno.h>
Packit Service a2413a
#include <pthread.h>
Packit Service a2413a
#include <stdio.h>
Packit Service a2413a
#include <stdlib.h>
Packit Service a2413a
#include <string.h>
Packit Service a2413a
Packit Service a2413a
static int do_test (void);
Packit Service a2413a
#include <support/xthread.h>
Packit Service a2413a
#include <support/xdlfcn.h>
Packit Service a2413a
#include <support/check.h>
Packit Service a2413a
#include <support/test-driver.c>
Packit Service a2413a
Packit Service a2413a
/* Have some big TLS in the main exe: should not use surplus TLS.  */
Packit Service a2413a
__thread char maintls[1000];
Packit Service a2413a
Packit Service a2413a
static pthread_barrier_t barrier;
Packit Service a2413a
Packit Service a2413a
/* Forces multi-threaded behaviour.  */
Packit Service a2413a
static void *
Packit Service a2413a
blocked_thread_func (void *closure)
Packit Service a2413a
{
Packit Service a2413a
  xpthread_barrier_wait (&barrier);
Packit Service a2413a
  /* TLS load and access tests run here in the main thread.  */
Packit Service a2413a
  xpthread_barrier_wait (&barrier);
Packit Service a2413a
  return NULL;
Packit Service a2413a
}
Packit Service a2413a
Packit Service a2413a
static void *
Packit Service a2413a
load_and_access (Lmid_t lmid, const char *mod, const char *func)
Packit Service a2413a
{
Packit Service a2413a
  /* Load module with TLS.  */
Packit Service a2413a
  void *p = xdlmopen (lmid, mod, RTLD_NOW);
Packit Service a2413a
  /* Access the TLS variable to ensure it is allocated.  */
Packit Service a2413a
  void (*f) (void) = (void (*) (void))xdlsym (p, func);
Packit Service a2413a
  f ();
Packit Service a2413a
  return p;
Packit Service a2413a
}
Packit Service a2413a
Packit Service a2413a
static int
Packit Service a2413a
do_test (void)
Packit Service a2413a
{
Packit Service a2413a
  void *mods[5];
Packit Service a2413a
Packit Service a2413a
  {
Packit Service a2413a
    int ret = pthread_barrier_init (&barrier, NULL, 2);
Packit Service a2413a
    if (ret != 0)
Packit Service a2413a
      {
Packit Service a2413a
        errno = ret;
Packit Service a2413a
        printf ("error: pthread_barrier_init: %m\n");
Packit Service a2413a
        exit (1);
Packit Service a2413a
      }
Packit Service a2413a
  }
Packit Service a2413a
Packit Service a2413a
  pthread_t blocked_thread = xpthread_create (NULL, blocked_thread_func, NULL);
Packit Service a2413a
  xpthread_barrier_wait (&barrier);
Packit Service a2413a
Packit Service a2413a
  printf ("maintls[%zu]:\t %p .. %p\n",
Packit Service a2413a
	   sizeof maintls, maintls, maintls + sizeof maintls);
Packit Service a2413a
  memset (maintls, 1, sizeof maintls);
Packit Service a2413a
Packit Service a2413a
  /* Load modules with dynamic TLS (use surplus static TLS for libc
Packit Service a2413a
     in new namespaces and may be for TLS optimizations too).  */
Packit Service a2413a
  mods[0] = load_and_access (LM_ID_BASE, "tst-tls-ie-mod0.so", "access0");
Packit Service a2413a
  mods[1] = load_and_access (LM_ID_NEWLM, "tst-tls-ie-mod1.so", "access1");
Packit Service a2413a
  mods[2] = load_and_access (LM_ID_NEWLM, "tst-tls-ie-mod2.so", "access2");
Packit Service a2413a
  mods[3] = load_and_access (LM_ID_NEWLM, "tst-tls-ie-mod3.so", "access3");
Packit Service a2413a
  /* Load modules with initial-exec TLS (can only use surplus static TLS).  */
Packit Service a2413a
  mods[4] = load_and_access (LM_ID_BASE, "tst-tls-ie-mod6.so", "access6");
Packit Service a2413a
Packit Service a2413a
  /* Here 576 bytes + 3 * libc use of surplus static TLS is in use so less
Packit Service a2413a
     than 1024 bytes are available (exact number depends on TLS optimizations
Packit Service a2413a
     and the libc TLS use).  */
Packit Service a2413a
  printf ("The next dlmopen should fail...\n");
Packit Service a2413a
  void *p = dlmopen (LM_ID_BASE, "tst-tls-ie-mod4.so", RTLD_NOW);
Packit Service a2413a
  if (p != NULL)
Packit Service a2413a
    FAIL_EXIT1 ("error: expected dlmopen to fail because there is "
Packit Service a2413a
		"not enough surplus static TLS.\n");
Packit Service a2413a
  printf ("...OK failed with: %s.\n", dlerror ());
Packit Service a2413a
Packit Service a2413a
  xpthread_barrier_wait (&barrier);
Packit Service a2413a
  xpthread_join (blocked_thread);
Packit Service a2413a
Packit Service a2413a
  /* Close the modules.  */
Packit Service a2413a
  for (int i = 0; i < 5; ++i)
Packit Service a2413a
    xdlclose (mods[i]);
Packit Service a2413a
Packit Service a2413a
  return 0;
Packit Service a2413a
}