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-2022 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 *
fn(void * p)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
check_dlopen_failure(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
do_test(int argc,char * argv[])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>
88