1 /* Test if an executable can read from the TLS from an STT_GNU_IFUNC resolver.
2 Copyright (C) 2017-2023 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 <https://www.gnu.org/licenses/>. */
23 #include <libc-symbols.h>
26 extern __thread
int bar_gd
asm ("bar") __attribute__ ((tls_model("global-dynamic")));
27 static int *bar_ptr
= NULL
;
29 static uint32_t resolver_platform
= 0;
35 /* Offsets copied from tcb-offsets.h. */
37 # define __TPREG "r13"
38 # define __ATPLATOFF -28764
41 # define __ATPLATOFF -28724
47 register unsigned long tp
__asm__ (__TPREG
);
50 __asm__ ("lwz %0,%1(%2)\n"
52 : "n" (__ATPLATOFF
), "b" (tp
));
66 printf ("&bar = %p and bar_ptr = %p.\n", &bar
, bar_ptr
);
67 return bar_ptr
!= NULL
;
70 __ifunc (foo
, foo
, my_foo
, void, init_foo
);
75 resolver_platform
= get_platform ();
81 printf ("resolver_platform = 0x%"PRIx32
82 " and current platform = 0x%"PRIx32
".\n",
83 resolver_platform
, get_platform ());
84 return resolver_platform
!= 0;
87 __ifunc (tcb_test
, tcb_test
, my_tcb_test
, void, init_tcb_test
);
95 printf ("PASS: foo IFUNC resolver called once.\n");
98 printf ("FAIL: foo IFUNC resolver not called once.\n");
103 printf ("PASS: bar address read from IFUNC resolver is correct.\n");
104 #if !defined TST_TLSIFUNC_STATIC || !defined PIC \
105 || defined HIDDEN_VAR_NEEDS_DYNAMIC_RELOC
108 printf ("FAIL: bar address read from IFUNC resolver is incorrect.\n");
114 printf ("PASS: tcb_test IFUNC resolver called once.\n");
117 printf ("FAIL: tcb_test IFUNC resolver not called once.\n");
121 if (resolver_platform
== get_platform ())
122 printf ("PASS: platform read from IFUNC resolver is correct.\n");
125 printf ("FAIL: platform read from IFUNC resolver is incorrect.\n");
132 #include <support/test-driver.c>