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
39void *
40fn (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. */
47static void
48check_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 (haystack: message,
57 needle: "cannot dynamically load position-independent executable")
58 == NULL)
59 && strstr (haystack: message, needle: "cannot dynamically load executable") == NULL)
60 FAIL_EXIT1 ("invalid dlopen error message: \"%s\"", message);
61}
62
63static int
64do_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, thread_func: 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

source code of glibc/elf/tst-dlopen-tlsmodid.h