Remove "[Add new features here]" for 2.27
[glibc.git] / sysdeps / powerpc / tst-tlsifunc.c
blob0a8bdbf0c456e9074a1a1c415a8b6608942e948e
1 /* Test if an executable can read from the TLS from an STT_GNU_IFUNC resolver.
2 Copyright (C) 2017 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/>. */
19 #include <stdio.h>
20 #include <stdlib.h>
21 #include <stdint.h>
22 #include <inttypes.h>
23 #include <libc-symbols.h>
24 #include <tls-macros.h>
26 __thread int bar;
27 static int *bar_ptr = NULL;
29 static uint32_t resolver_platform = 0;
31 int foo (void);
33 int tcb_test (void);
35 /* Offsets copied from tcb-offsets.h. */
36 #ifdef __powerpc64__
37 # define __TPREG "r13"
38 # define __ATPLATOFF -28764
39 #else
40 # define __TPREG "r2"
41 # define __ATPLATOFF -28724
42 #endif
44 uint32_t
45 get_platform (void)
47 register unsigned long tp __asm__ (__TPREG);
48 uint32_t tmp;
50 __asm__ ("lwz %0,%1(%2)\n"
51 : "=r" (tmp)
52 : "i" (__ATPLATOFF), "b" (tp));
54 return tmp;
57 void
58 init_foo (void)
60 bar_ptr = TLS_GD (bar);
63 int
64 my_foo (void)
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);
72 void
73 init_tcb_test (void)
75 resolver_platform = get_platform ();
78 int
79 my_tcb_test (void)
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);
89 static int
90 do_test (void)
92 int ret = 0;
94 if (foo ())
95 printf ("PASS: foo IFUNC resolver called once.\n");
96 else
98 printf ("FAIL: foo IFUNC resolver not called once.\n");
99 ret = 1;
102 if (&bar == bar_ptr)
103 printf ("PASS: bar address read from IFUNC resolver is correct.\n");
104 else
106 printf ("FAIL: bar address read from IFUNC resolver is incorrect.\n");
107 ret = 1;
110 if (tcb_test ())
111 printf ("PASS: tcb_test IFUNC resolver called once.\n");
112 else
114 printf ("FAIL: tcb_test IFUNC resolver not called once.\n");
115 ret = 1;
118 if (resolver_platform == get_platform ())
119 printf ("PASS: platform read from IFUNC resolver is correct.\n");
120 else
122 printf ("FAIL: platform read from IFUNC resolver is incorrect.\n");
123 ret = 1;
126 return ret;
129 #include <support/test-driver.c>