1 /* Test if an executable can read from the TLS from an STT_GNU_IFUNC resolver.
2 Copyright (C) 2017-2018 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/>. */
23 #include <libc-symbols.h>
24 #include <tls-macros.h>
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 : "i" (__ATPLATOFF
), "b" (tp
));
60 bar_ptr
= TLS_GD (bar
);
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");
106 printf ("FAIL: bar address read from IFUNC resolver is incorrect.\n");
111 printf ("PASS: tcb_test IFUNC resolver called once.\n");
114 printf ("FAIL: tcb_test IFUNC resolver not called once.\n");
118 if (resolver_platform
== get_platform ())
119 printf ("PASS: platform read from IFUNC resolver is correct.\n");
122 printf ("FAIL: platform read from IFUNC resolver is incorrect.\n");
129 #include <support/test-driver.c>