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.
This commit is contained in:
Ulrich Drepper 2003-09-02 00:33:28 +00:00
parent e3a88560b9
commit c874a32e88
24 changed files with 494 additions and 3 deletions

View file

@ -1,3 +1,22 @@
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.
2003-08-27 Ulrich Drepper <drepper@redhat.com>
* sysdeps/pthread/pthread.h: Don't mark pthread_exit,

91
linuxthreads/tst-tls1.c Normal file
View file

@ -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"

28
linuxthreads/tst-tls1.h Normal file
View file

@ -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

View file

@ -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

View file

@ -0,0 +1,6 @@
#include <tst-tls1.h>
#ifdef TLS_REGISTER
static __thread char a [32] __attribute__ ((aligned (64)));
TLS_REGISTER (a)
#endif

View file

@ -0,0 +1,6 @@
#include <tst-tls1.h>
#ifdef TLS_REGISTER
static __thread int b;
TLS_REGISTER (b)
#endif

View file

@ -0,0 +1,6 @@
#include <tst-tls1.h>
#ifdef TLS_REGISTER
static __thread int c;
TLS_REGISTER (c)
#endif

View file

@ -0,0 +1,6 @@
#include <tst-tls1.h>
#ifdef TLS_REGISTER
static __thread int d;
TLS_REGISTER (d)
#endif

View file

@ -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

View file

@ -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

53
linuxthreads/tst-tls2.sh Normal file
View file

@ -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

View file

@ -1,3 +1,26 @@
2003-09-01 Jakub Jelinek <jakub@redhat.com>
* Makefile (tests): Add tst-tls5.
(module-names): Add tst-tls5mod{,a,b,c,d,e,f}.
($(objpfx)tst-tls5mod{,a,b,c,d,e,f}.so-no-z-defs): Set to yes.
($(objpfx)tst-tls5): New.
($(objpfx)tst-tls6.out): Likewise.
(tests): Depend on $(objpfx)tst-tls6.out.
* tst-tls3.c: Include stdint.h and pthreaddef.h.
(do_test): Check pthread_self () return value alignment.
* tst-tls3mod.c: Include stdint.h and pthreaddef.h.
(tf): Check pthread_self () return value alignment.
* tst-tls5.c: New test.
* tst-tls5.h: New.
* tst-tls5mod.c: New.
* tst-tls5moda.c: New.
* tst-tls5modb.c: New.
* tst-tls5modc.c: New.
* tst-tls5modd.c: New.
* tst-tls5mode.c: New.
* tst-tls5modf.c: New.
* tst-tls6.sh: New test.
2003-09-01 Jakub Jelinek <jakub@redhat.com>
* sysdeps/unix/sysv/linux/alpha/timer_create.c: New file.

View file

@ -252,10 +252,12 @@ tests += tst-cancelx2 tst-cancelx3 tst-cancelx4 tst-cancelx5 \
tst-oncex3 tst-oncex4
endif
ifeq ($(build-shared),yes)
tests += tst-atfork2 tst-tls3 tst-tls4 tst-_res1
tests += tst-atfork2 tst-tls3 tst-tls4 tst-tls5 tst-_res1
endif
modules-names = tst-atfork2mod tst-tls3mod tst-tls4moda tst-tls4modb \
tst-tls5mod tst-tls5moda tst-tls5modb tst-tls5modc \
tst-tls5modd tst-tls5mode tst-tls5modf \
tst-_res1mod1 tst-_res1mod2
extra-objs += $(addsuffix .os,$(strip $(modules-names)))
test-extras += $(modules-names)
@ -263,6 +265,13 @@ test-modules = $(addprefix $(objpfx),$(addsuffix .so,$(modules-names)))
tst-atfork2mod.so-no-z-defs = yes
tst-tls3mod.so-no-z-defs = yes
tst-tls5mod.so-no-z-defs = yes
tst-tls5moda.so-no-z-defs = yes
tst-tls5modb.so-no-z-defs = yes
tst-tls5modc.so-no-z-defs = yes
tst-tls5modd.so-no-z-defs = yes
tst-tls5mode.so-no-z-defs = yes
tst-tls5modf.so-no-z-defs = yes
$(test-modules): $(objpfx)%.so: $(objpfx)%.os $(common-objpfx)shlib.lds
$(build-module)
@ -400,6 +409,18 @@ $(objpfx)tst-tls3mod.so: $(shared-thread-library)
$(objpfx)tst-tls4: $(libdl) $(shared-thread-library)
$(objpfx)tst-tls4.out: $(objpfx)tst-tls4moda.so $(objpfx)tst-tls4modb.so
$(objpfx)tst-tls5: $(objpfx)tst-tls5mod.so $(shared-thread-library)
ifeq ($(build-shared),yes)
tests: $(objpfx)tst-tls6.out
$(objpfx)tst-tls6.out: tst-tls6.sh $(objpfx)tst-tls5 \
$(objpfx)tst-tls5moda.so $(objpfx)tst-tls5modb.so \
$(objpfx)tst-tls5modc.so $(objpfx)tst-tls5modd.so \
$(objpfx)tst-tls5mode.so $(objpfx)tst-tls5modf.so
$(SHELL) -e tst-tls6.sh $(common-objpfx) $(elf-objpfx) \
$(rtld-installed-name)
endif
$(objpfx)tst-dlsym1: $(libdl) $(shared-thread-library)
ifeq (yes,$(build-shared))

View file

@ -22,10 +22,11 @@
#include <pthread.h>
#include <signal.h>
#include <semaphore.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthreaddef.h>
#define THE_SIG SIGUSR1
@ -79,6 +80,12 @@ do_test (void)
return 0;
#else
if ((uintptr_t) pthread_self () & (TCB_ALIGNMENT - 1))
{
puts ("initial thread's struct pthread not aligned enough");
exit (1);
}
if (pthread_barrier_init (&b, NULL, N + 1) != 0)
{
puts ("barrier_init failed");

View file

@ -20,10 +20,11 @@
#include <pthread.h>
#include <semaphore.h>
#include <signal.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthreaddef.h>
#if HAVE___THREAD
@ -61,6 +62,12 @@ handler (int sig)
void *
tf (void *arg)
{
if ((uintptr_t) pthread_self () & (TCB_ALIGNMENT - 1))
{
puts ("thread's struct pthread not aligned enough");
exit (1);
}
if (fp != NULL)
{
puts ("fp not initially NULL");

120
nptl/tst-tls5.c Normal file
View file

@ -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"

28
nptl/tst-tls5.h Normal file
View file

@ -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

6
nptl/tst-tls5mod.c Normal file
View file

@ -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

6
nptl/tst-tls5moda.c Normal file
View file

@ -0,0 +1,6 @@
#include <tst-tls5.h>
#ifdef TLS_REGISTER
static __thread char a [32] __attribute__ ((aligned (64)));
TLS_REGISTER (a)
#endif

6
nptl/tst-tls5modb.c Normal file
View file

@ -0,0 +1,6 @@
#include <tst-tls5.h>
#ifdef TLS_REGISTER
static __thread int b;
TLS_REGISTER (b)
#endif

6
nptl/tst-tls5modc.c Normal file
View file

@ -0,0 +1,6 @@
#include <tst-tls5.h>
#ifdef TLS_REGISTER
static __thread int c;
TLS_REGISTER (c)
#endif

6
nptl/tst-tls5modd.c Normal file
View file

@ -0,0 +1,6 @@
#include <tst-tls5.h>
#ifdef TLS_REGISTER
static __thread int d;
TLS_REGISTER (d)
#endif

8
nptl/tst-tls5mode.c Normal file
View file

@ -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

9
nptl/tst-tls5modf.c Normal file
View file

@ -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