1 /* Copyright (C) 2003-2024 Free Software Foundation, Inc.
2 This file is part of the GNU C Library.
4 The GNU C Library is free software; you can redistribute it and/or
5 modify it under the terms of the GNU Lesser General Public
6 License as published by the Free Software Foundation; either
7 version 2.1 of the License, or (at your option) any later version.
9 The GNU C Library is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 Lesser General Public License for more details.
14 You should have received a copy of the GNU Lesser General Public
15 License along with the GNU C Library; if not, see
16 <https://www.gnu.org/licenses/>. */
18 /* Check alignment, overlapping and layout of TLS variables. */
24 #include <sys/param.h>
30 struct tls_obj tls_registry
[64];
33 tls_addr_cmp (const void *a
, const void *b
)
35 if (((struct tls_obj
*)a
)->addr
< ((struct tls_obj
*)b
)->addr
)
37 if (((struct tls_obj
*)a
)->addr
> ((struct tls_obj
*)b
)->addr
)
47 uintptr_t min_addr
= ~(uintptr_t) 0, max_addr
= 0;
49 for (cnt
= 0; tls_registry
[cnt
].name
; ++cnt
);
50 tls_registry
[cnt
].name
= NULL
;
51 tls_registry
[cnt
].addr
= (uintptr_t) pthread_self ();
52 tls_registry
[cnt
].size
= sizeof (struct pthread
);
53 tls_registry
[cnt
++].align
= __alignof__ (struct pthread
);
55 qsort (tls_registry
, cnt
, sizeof (struct tls_obj
), tls_addr_cmp
);
57 for (i
= 0; i
< cnt
; ++i
)
59 printf ("%s%s = %p, size %zd, align %zd",
60 tls_registry
[i
].name
? "&" : "",
61 tls_registry
[i
].name
?: "pthread_self ()",
62 (void *) tls_registry
[i
].addr
,
63 tls_registry
[i
].size
, tls_registry
[i
].align
);
64 if (tls_registry
[i
].addr
& (tls_registry
[i
].align
- 1))
66 fputs (", WRONG ALIGNMENT", stdout
);
70 && (tls_registry
[i
- 1].addr
+ tls_registry
[i
- 1].size
71 > tls_registry
[i
].addr
))
73 fputs (", ADDRESS OVERLAP", stdout
);
77 if (tls_registry
[i
].name
)
79 min_addr
= MIN (tls_registry
[i
].addr
, min_addr
);
80 max_addr
= MAX (tls_registry
[i
].addr
+ tls_registry
[i
].size
,
88 if (tls_registry
[cnt
- 1].name
)
90 puts ("pthread_self () not larger than all TLS addresses");
94 max_addr
= MAX (tls_registry
[cnt
- 1].addr
, max_addr
);
96 if (tls_registry
[0].name
)
98 puts ("pthread_self () not smaller than all TLS addresses");
104 printf ("Initial TLS used block size %zd\n",
105 (size_t) (max_addr
- min_addr
));
110 #define TEST_FUNCTION do_test ()
114 #define TEST_FUNCTION 0
118 #include "../test-skeleton.c"