mirror of https://gitee.com/Nocallback/glibc.git
Browse Source
2003-09-01 Jakub Jelinek <jakub@redhat.com>
* Makefile (tests): Add tst-tls1.
(module-names): Add tst-tls1mod{,a,b,c,d,e,f}.
($(objpfx)tst-tls1mod{,a,b,c,d,e,f}.so-no-z-defs): Set to yes.
($(objpfx)tst-tls1): New.
($(objpfx)tst-tls2.out): Likewise.
(tests): Depend on $(objpfx)tst-tls2.out.
* tst-tls1.c: New test.
* tst-tls1.h: New.
* tst-tls1mod.c: New.
* tst-tls1moda.c: New.
* tst-tls1modb.c: New.
* tst-tls1modc.c: New.
* tst-tls1modd.c: New.
* tst-tls1mode.c: New.
* tst-tls1modf.c: New.
* tst-tls2.sh: New test.
cvs/fedora-2_3-branch
24 changed files with 494 additions and 3 deletions
@ -0,0 +1,91 @@ |
|||
/* Copyright (C) 2003 Free Software Foundation, Inc.
|
|||
This file is part of the GNU C Library. |
|||
Contributed by Jakub Jelinek <jakub@redhat.com>, 2003. |
|||
|
|||
The GNU C Library is free software; you can redistribute it and/or |
|||
modify it under the terms of the GNU Lesser General Public |
|||
License as published by the Free Software Foundation; either |
|||
version 2.1 of the License, or (at your option) any later version. |
|||
|
|||
The GNU C Library is distributed in the hope that it will be useful, |
|||
but WITHOUT ANY WARRANTY; without even the implied warranty of |
|||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
|||
Lesser General Public License for more details. |
|||
|
|||
You should have received a copy of the GNU Lesser General Public |
|||
License along with the GNU C Library; if not, write to the Free |
|||
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA |
|||
02111-1307 USA. */ |
|||
|
|||
/* Check alignment, overlapping and layout of TLS variables. */ |
|||
#include <stdint.h> |
|||
#include <stdio.h> |
|||
#include <stdlib.h> |
|||
#include <pthread.h> |
|||
#include <sys/param.h> |
|||
|
|||
#include "tst-tls1.h" |
|||
|
|||
#ifdef TLS_REGISTER |
|||
|
|||
struct tls_obj tls_registry[64]; |
|||
|
|||
static int |
|||
tls_addr_cmp (const void *a, const void *b) |
|||
{ |
|||
if (((struct tls_obj *)a)->addr < ((struct tls_obj *)b)->addr) |
|||
return -1; |
|||
if (((struct tls_obj *)a)->addr > ((struct tls_obj *)b)->addr) |
|||
return 1; |
|||
return 0; |
|||
} |
|||
|
|||
static int |
|||
do_test (void) |
|||
{ |
|||
size_t cnt, i; |
|||
int res = 0; |
|||
uintptr_t min_addr = ~(uintptr_t) 0, max_addr = 0; |
|||
|
|||
for (cnt = 0; tls_registry[cnt].name; ++cnt); |
|||
|
|||
qsort (tls_registry, cnt, sizeof (struct tls_obj), tls_addr_cmp); |
|||
|
|||
for (i = 0; i < cnt; ++i) |
|||
{ |
|||
printf ("%s = %p, size %zd, align %zd", |
|||
tls_registry[i].name, (void *) tls_registry[i].addr, |
|||
tls_registry[i].size, tls_registry[i].align); |
|||
if (tls_registry[i].addr & (tls_registry[i].align - 1)) |
|||
{ |
|||
fputs (", WRONG ALIGNMENT", stdout); |
|||
res = 1; |
|||
} |
|||
if (i > 0 |
|||
&& (tls_registry[i - 1].addr + tls_registry[i - 1].size |
|||
> tls_registry[i].addr)) |
|||
{ |
|||
fputs (", ADDRESS OVERLAP", stdout); |
|||
res = 1; |
|||
} |
|||
puts (""); |
|||
min_addr = MIN (tls_registry[i].addr, min_addr); |
|||
max_addr = MAX (tls_registry[i].addr + tls_registry[i].size, |
|||
max_addr); |
|||
} |
|||
|
|||
if (cnt > 1) |
|||
printf ("Initial TLS used block size %zd\n", |
|||
(size_t) (max_addr - min_addr)); |
|||
return res; |
|||
} |
|||
|
|||
#define TEST_FUNCTION do_test () |
|||
|
|||
#else |
|||
|
|||
#define TEST_FUNCTION 0 |
|||
|
|||
#endif |
|||
|
|||
#include "../test-skeleton.c" |
|||
@ -0,0 +1,28 @@ |
|||
#include <stdint.h> |
|||
#include <stdlib.h> |
|||
#include <tls.h> |
|||
|
|||
#if USE_TLS && HAVE___THREAD |
|||
|
|||
struct tls_obj |
|||
{ |
|||
const char *name; |
|||
uintptr_t addr; |
|||
size_t size; |
|||
size_t align; |
|||
}; |
|||
extern struct tls_obj tls_registry[]; |
|||
|
|||
#define TLS_REGISTER(x) \ |
|||
static void __attribute__((constructor)) \ |
|||
tls_register_##x (void) \ |
|||
{ \ |
|||
size_t i; \ |
|||
for (i = 0; tls_registry[i].name; ++i); \ |
|||
tls_registry[i].name = #x; \ |
|||
tls_registry[i].addr = (uintptr_t) &x; \ |
|||
tls_registry[i].size = sizeof (x); \ |
|||
tls_registry[i].align = __alignof__ (x); \ |
|||
} |
|||
|
|||
#endif |
|||
@ -0,0 +1,6 @@ |
|||
#include <tst-tls1.h> |
|||
|
|||
#ifdef TLS_REGISTER |
|||
/* Ensure tls_registry is exported from the binary. */ |
|||
void *tst_tls1mod attribute_hidden = tls_registry; |
|||
#endif |
|||
@ -0,0 +1,6 @@ |
|||
#include <tst-tls1.h> |
|||
|
|||
#ifdef TLS_REGISTER |
|||
static __thread char a [32] __attribute__ ((aligned (64))); |
|||
TLS_REGISTER (a) |
|||
#endif |
|||
@ -0,0 +1,6 @@ |
|||
#include <tst-tls1.h> |
|||
|
|||
#ifdef TLS_REGISTER |
|||
static __thread int b; |
|||
TLS_REGISTER (b) |
|||
#endif |
|||
@ -0,0 +1,6 @@ |
|||
#include <tst-tls1.h> |
|||
|
|||
#ifdef TLS_REGISTER |
|||
static __thread int c; |
|||
TLS_REGISTER (c) |
|||
#endif |
|||
@ -0,0 +1,6 @@ |
|||
#include <tst-tls1.h> |
|||
|
|||
#ifdef TLS_REGISTER |
|||
static __thread int d; |
|||
TLS_REGISTER (d) |
|||
#endif |
|||
@ -0,0 +1,8 @@ |
|||
#include <tst-tls1.h> |
|||
|
|||
#ifdef TLS_REGISTER |
|||
static __thread int e1 = 24; |
|||
static __thread char e2 [32] __attribute__ ((aligned (64))); |
|||
TLS_REGISTER (e1) |
|||
TLS_REGISTER (e2) |
|||
#endif |
|||
@ -0,0 +1,9 @@ |
|||
#include <tst-tls1.h> |
|||
|
|||
#ifdef TLS_REGISTER |
|||
char tst_tls1modf[60] attribute_hidden = { 26 }; |
|||
static __thread int f1 = 24; |
|||
static __thread char f2 [32] __attribute__ ((aligned (64))); |
|||
TLS_REGISTER (f1) |
|||
TLS_REGISTER (f2) |
|||
#endif |
|||
@ -0,0 +1,53 @@ |
|||
#!/bin/sh |
|||
|
|||
common_objpfx=$1; shift |
|||
elf_objpfx=$1; shift |
|||
rtld_installed_name=$1; shift |
|||
logfile=$common_objpfx/linuxthreads/tst-tls2.out |
|||
|
|||
# We have to find libc and linuxthreads |
|||
library_path=${common_objpfx}:${common_objpfx}linuxthreads |
|||
tst_tls1="${elf_objpfx}${rtld_installed_name} --library-path ${library_path} \ |
|||
${common_objpfx}/linuxthreads/tst-tls1" |
|||
|
|||
LC_ALL=C |
|||
export LC_ALL |
|||
LANG=C |
|||
export LANG |
|||
|
|||
> $logfile |
|||
fail=0 |
|||
|
|||
for aligned in a e f; do |
|||
echo "preload tst-tls1mod{$aligned,b,c,d}.so" >> $logfile |
|||
echo "===============" >> $logfile |
|||
LD_PRELOAD=`echo ${common_objpfx}linuxthreads/tst-tls1mod{$aligned,b,c,d}.so \ |
|||
| sed 's/:$//;s/: /:/g'` ${tst_tls1} >> $logfile || fail=1 |
|||
echo >> $logfile |
|||
|
|||
echo "preload tst-tls1mod{b,$aligned,c,d}.so" >> $logfile |
|||
echo "===============" >> $logfile |
|||
LD_PRELOAD=`echo ${common_objpfx}linuxthreads/tst-tls1mod{b,$aligned,c,d}.so \ |
|||
| sed 's/:$//;s/: /:/g'` ${tst_tls1} >> $logfile || fail=1 |
|||
echo >> $logfile |
|||
|
|||
echo "preload tst-tls1mod{b,c,d,$aligned}.so" >> $logfile |
|||
echo "===============" >> $logfile |
|||
LD_PRELOAD=`echo ${common_objpfx}linuxthreads/tst-tls1mod{b,c,d,$aligned}.so \ |
|||
| sed 's/:$//;s/: /:/g'` ${tst_tls1} >> $logfile || fail=1 |
|||
echo >> $logfile |
|||
done |
|||
|
|||
echo "preload tst-tls1mod{d,a,b,c,e}" >> $logfile |
|||
echo "===============" >> $logfile |
|||
LD_PRELOAD=`echo ${common_objpfx}linuxthreads/tst-tls1mod{d,a,b,c,e}.so \ |
|||
| sed 's/:$//;s/: /:/g'` ${tst_tls1} >> $logfile || fail=1 |
|||
echo >> $logfile |
|||
|
|||
echo "preload tst-tls1mod{d,a,b,e,f}" >> $logfile |
|||
echo "===============" >> $logfile |
|||
LD_PRELOAD=`echo ${common_objpfx}linuxthreads/tst-tls1mod{d,a,b,e,f}.so \ |
|||
| sed 's/:$//;s/: /:/g'` ${tst_tls1} >> $logfile || fail=1 |
|||
echo >> $logfile |
|||
|
|||
exit $fail |
|||
@ -0,0 +1,120 @@ |
|||
/* Copyright (C) 2003 Free Software Foundation, Inc.
|
|||
This file is part of the GNU C Library. |
|||
Contributed by Jakub Jelinek <jakub@redhat.com>, 2003. |
|||
|
|||
The GNU C Library is free software; you can redistribute it and/or |
|||
modify it under the terms of the GNU Lesser General Public |
|||
License as published by the Free Software Foundation; either |
|||
version 2.1 of the License, or (at your option) any later version. |
|||
|
|||
The GNU C Library is distributed in the hope that it will be useful, |
|||
but WITHOUT ANY WARRANTY; without even the implied warranty of |
|||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
|||
Lesser General Public License for more details. |
|||
|
|||
You should have received a copy of the GNU Lesser General Public |
|||
License along with the GNU C Library; if not, write to the Free |
|||
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA |
|||
02111-1307 USA. */ |
|||
|
|||
/* Check alignment, overlapping and layout of TLS variables. */ |
|||
#include <stdint.h> |
|||
#include <stdio.h> |
|||
#include <stdlib.h> |
|||
#include <pthread.h> |
|||
#include <pthreadP.h> |
|||
#include <sys/param.h> |
|||
|
|||
#include "tst-tls5.h" |
|||
|
|||
#ifdef TLS_REGISTER |
|||
|
|||
struct tls_obj tls_registry[64]; |
|||
|
|||
static int |
|||
tls_addr_cmp (const void *a, const void *b) |
|||
{ |
|||
if (((struct tls_obj *)a)->addr < ((struct tls_obj *)b)->addr) |
|||
return -1; |
|||
if (((struct tls_obj *)a)->addr > ((struct tls_obj *)b)->addr) |
|||
return 1; |
|||
return 0; |
|||
} |
|||
|
|||
static int |
|||
do_test (void) |
|||
{ |
|||
size_t cnt, i; |
|||
int res = 0; |
|||
uintptr_t min_addr = ~(uintptr_t) 0, max_addr = 0; |
|||
|
|||
for (cnt = 0; tls_registry[cnt].name; ++cnt); |
|||
tls_registry[cnt].name = NULL; |
|||
tls_registry[cnt].addr = (uintptr_t) pthread_self (); |
|||
tls_registry[cnt].size = sizeof (struct pthread); |
|||
tls_registry[cnt++].align = __alignof__ (struct pthread); |
|||
|
|||
qsort (tls_registry, cnt, sizeof (struct tls_obj), tls_addr_cmp); |
|||
|
|||
for (i = 0; i < cnt; ++i) |
|||
{ |
|||
printf ("%s%s = %p, size %zd, align %zd", |
|||
tls_registry[i].name ? "&" : "", |
|||
tls_registry[i].name ?: "pthread_self ()", |
|||
(void *) tls_registry[i].addr, |
|||
tls_registry[i].size, tls_registry[i].align); |
|||
if (tls_registry[i].addr & (tls_registry[i].align - 1)) |
|||
{ |
|||
fputs (", WRONG ALIGNMENT", stdout); |
|||
res = 1; |
|||
} |
|||
if (i > 0 |
|||
&& (tls_registry[i - 1].addr + tls_registry[i - 1].size |
|||
> tls_registry[i].addr)) |
|||
{ |
|||
fputs (", ADDRESS OVERLAP", stdout); |
|||
res = 1; |
|||
} |
|||
puts (""); |
|||
if (tls_registry[i].name) |
|||
{ |
|||
min_addr = MIN (tls_registry[i].addr, min_addr); |
|||
max_addr = MAX (tls_registry[i].addr + tls_registry[i].size, |
|||
max_addr); |
|||
} |
|||
} |
|||
|
|||
if (cnt > 1) |
|||
{ |
|||
#if TLS_TCB_AT_TP |
|||
if (tls_registry[cnt - 1].name) |
|||
{ |
|||
puts ("pthread_self () not larger than all TLS addresses"); |
|||
res = 1; |
|||
} |
|||
else |
|||
max_addr = MAX (tls_registry[cnt - 1].addr, max_addr); |
|||
#elif TLS_DTV_AT_TP |
|||
if (tls_registry[0].name) |
|||
{ |
|||
puts ("pthread_self () not smaller than all TLS addresses"); |
|||
res = 1; |
|||
} |
|||
#else |
|||
abort (); |
|||
#endif |
|||
printf ("Initial TLS used block size %zd\n", |
|||
(size_t) (max_addr - min_addr)); |
|||
} |
|||
return res; |
|||
} |
|||
|
|||
#define TEST_FUNCTION do_test () |
|||
|
|||
#else |
|||
|
|||
#define TEST_FUNCTION 0 |
|||
|
|||
#endif |
|||
|
|||
#include "../test-skeleton.c" |
|||
@ -0,0 +1,28 @@ |
|||
#include <stdint.h> |
|||
#include <stdlib.h> |
|||
#include <tls.h> |
|||
|
|||
#if USE_TLS && HAVE___THREAD |
|||
|
|||
struct tls_obj |
|||
{ |
|||
const char *name; |
|||
uintptr_t addr; |
|||
size_t size; |
|||
size_t align; |
|||
}; |
|||
extern struct tls_obj tls_registry[]; |
|||
|
|||
#define TLS_REGISTER(x) \ |
|||
static void __attribute__((constructor)) \ |
|||
tls_register_##x (void) \ |
|||
{ \ |
|||
size_t i; \ |
|||
for (i = 0; tls_registry[i].name; ++i); \ |
|||
tls_registry[i].name = #x; \ |
|||
tls_registry[i].addr = (uintptr_t) &x; \ |
|||
tls_registry[i].size = sizeof (x); \ |
|||
tls_registry[i].align = __alignof__ (x); \ |
|||
} |
|||
|
|||
#endif |
|||
@ -0,0 +1,6 @@ |
|||
#include <tst-tls5.h> |
|||
|
|||
#ifdef TLS_REGISTER |
|||
/* Ensure tls_registry is exported from the binary. */ |
|||
void *tst_tls5mod attribute_hidden = tls_registry; |
|||
#endif |
|||
@ -0,0 +1,6 @@ |
|||
#include <tst-tls5.h> |
|||
|
|||
#ifdef TLS_REGISTER |
|||
static __thread char a [32] __attribute__ ((aligned (64))); |
|||
TLS_REGISTER (a) |
|||
#endif |
|||
@ -0,0 +1,6 @@ |
|||
#include <tst-tls5.h> |
|||
|
|||
#ifdef TLS_REGISTER |
|||
static __thread int b; |
|||
TLS_REGISTER (b) |
|||
#endif |
|||
@ -0,0 +1,6 @@ |
|||
#include <tst-tls5.h> |
|||
|
|||
#ifdef TLS_REGISTER |
|||
static __thread int c; |
|||
TLS_REGISTER (c) |
|||
#endif |
|||
@ -0,0 +1,6 @@ |
|||
#include <tst-tls5.h> |
|||
|
|||
#ifdef TLS_REGISTER |
|||
static __thread int d; |
|||
TLS_REGISTER (d) |
|||
#endif |
|||
@ -0,0 +1,8 @@ |
|||
#include <tst-tls5.h> |
|||
|
|||
#ifdef TLS_REGISTER |
|||
static __thread int e1 = 24; |
|||
static __thread char e2 [32] __attribute__ ((aligned (64))); |
|||
TLS_REGISTER (e1) |
|||
TLS_REGISTER (e2) |
|||
#endif |
|||
@ -0,0 +1,9 @@ |
|||
#include <tst-tls5.h> |
|||
|
|||
#ifdef TLS_REGISTER |
|||
char tst_tls5modf[60] attribute_hidden = { 26 }; |
|||
static __thread int f1 = 24; |
|||
static __thread char f2 [32] __attribute__ ((aligned (64))); |
|||
TLS_REGISTER (f1) |
|||
TLS_REGISTER (f2) |
|||
#endif |
|||
Loading…
Reference in new issue