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