1 /* Test TLSDESC relocation.
2 Copyright (C) 2024 Free Software Foundation, Inc.
3 This file is part of the GNU C Library.
5 The GNU C Library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public
7 License as published by the Free Software Foundation; either
8 version 2.1 of the License, or (at your option) any later version.
10 The GNU C Library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Lesser General Public License for more details.
15 You should have received a copy of the GNU Lesser General Public
16 License along with the GNU C Library; if not, see
17 <http://www.gnu.org/licenses/>. */
24 #include <support/xdlfcn.h>
25 #include <support/xthread.h>
26 #include <support/check.h>
27 #include <support/test-driver.h>
28 #include "tst-gnu2-tls2.h"
31 # define IS_SUPPORTED() true
34 /* An architecture can define it to clobber caller-saved registers in
35 malloc below to verify that the implicit TLSDESC call won't change
36 caller-saved registers. */
37 #ifndef PREPARE_MALLOC
38 # define PREPARE_MALLOC()
41 extern void * __libc_malloc (size_t);
43 size_t malloc_counter
= 0;
50 return __libc_malloc (n
);
55 # define MOD(i) "tst-gnu2-tls2mod" #i ".so"
57 static const char *modname
[3] = { MOD(0), MOD(1), MOD(2) };
63 mod
[i
] = xdlopen (modname
[i
], RTLD_LAZY
);
64 printf ("open %s\n", modname
[i
]);
72 printf ("close %s\n", modname
[i
]);
76 access_mod (int i
, const char *sym
)
78 struct tls var
= { -1, -1, -1, -1 };
79 struct tls
*(*f
) (struct tls
*) = xdlsym (mod
[i
], sym
);
80 /* Check that our malloc is called. */
82 struct tls
*p
= f (&var
);
83 TEST_VERIFY (malloc_counter
!= 0);
84 printf ("access %s: %s() = %p\n", modname
[i
], sym
, p
);
85 TEST_VERIFY_EXIT (memcmp (p
, &var
, sizeof (var
)) == 0);
92 /* The DTV generation is at the last dlopen of mod0 and the
93 entry for mod1 is NULL. */
95 open_mod (1); /* Reuse modid of mod1. Uses dynamic TLS. */
97 /* Force the slow path in GNU2 TLS descriptor call. */
98 access_mod (1, "apply_tls");
106 if (!IS_SUPPORTED ())
107 return EXIT_UNSUPPORTED
;
113 close_mod (1); /* Create modid gap at mod1. */
114 open_mod (0); /* Reuse modid of mod0, bump generation count. */
116 /* Create a thread where DTV of mod1 is NULL. */
117 pthread_t t
= xpthread_create (NULL
, start
, NULL
);
122 #include <support/test-driver.c>