(root)/
glibc-2.38/
elf/
tst-dlopen-tlsmodid.h
       1  /* Common code for tst-dlopen-tlsmodid, tst-dlopen-tlsmodid-pie,
       2     tst-dlopen-tlsmodid-container.
       3  
       4     Verify that incorrectly dlopen()ing an executable without
       5     __RTLD_OPENEXEC does not cause assertion in ld.so, and that it
       6     actually results in an error.
       7  
       8     Copyright (C) 2014-2023 Free Software Foundation, Inc.
       9     This file is part of the GNU C Library.
      10  
      11     The GNU C Library is free software; you can redistribute it and/or
      12     modify it under the terms of the GNU Lesser General Public
      13     License as published by the Free Software Foundation; either
      14     version 2.1 of the License, or (at your option) any later version.
      15  
      16     The GNU C Library is distributed in the hope that it will be useful,
      17     but WITHOUT ANY WARRANTY; without even the implied warranty of
      18     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      19     Lesser General Public License for more details.
      20  
      21     You should have received a copy of the GNU Lesser General Public
      22     License along with the GNU C Library; if not, see
      23     <https://www.gnu.org/licenses/>.  */
      24  
      25  /* Before including this file, the macro TST_DLOPEN_TLSMODID_PATH must
      26     be defined, to specify the path used for the open operation.  */
      27  
      28  #include <dlfcn.h>
      29  #include <pthread.h>
      30  #include <stdio.h>
      31  #include <stdlib.h>
      32  #include <string.h>
      33  #include <support/check.h>
      34  #include <support/support.h>
      35  #include <support/xthread.h>
      36  
      37  __thread int x;
      38  
      39  void *
      40  fn (void *p)
      41  {
      42    return p;
      43  }
      44  
      45  /* Call dlopen and check that fails with an error message indicating
      46     an attempt to open an ET_EXEC or PIE object.  */
      47  static void
      48  check_dlopen_failure (void)
      49  {
      50    void *handle = dlopen (TST_DLOPEN_TLSMODID_PATH, RTLD_LAZY);
      51    if (handle != NULL)
      52      FAIL_EXIT1 ("dlopen succeeded unexpectedly: %s", TST_DLOPEN_TLSMODID_PATH);
      53  
      54    const char *message = dlerror ();
      55    TEST_VERIFY_EXIT (message != NULL);
      56    if ((strstr (message,
      57  	       "cannot dynamically load position-independent executable")
      58         == NULL)
      59        && strstr (message, "cannot dynamically load executable") == NULL)
      60      FAIL_EXIT1 ("invalid dlopen error message: \"%s\"", message);
      61  }
      62  
      63  static int
      64  do_test (int argc, char *argv[])
      65  {
      66    int j;
      67  
      68    for (j = 0; j < 100; ++j)
      69      {
      70        pthread_t thr;
      71  
      72        check_dlopen_failure ();
      73  
      74        /* We create threads to force TLS allocation, which triggers
      75  	 the original bug i.e. running out of surplus slotinfo entries
      76  	 for TLS.  */
      77        thr = xpthread_create (NULL, fn, NULL);
      78        xpthread_join (thr);
      79      }
      80  
      81    check_dlopen_failure ();
      82  
      83    return 0;
      84  }
      85  
      86  #define TEST_FUNCTION_ARGV do_test
      87  #include <support/test-driver.c>