diff options
Diffstat (limited to 'linuxthreads')
-rw-r--r-- | linuxthreads/ChangeLog | 19 | ||||
-rw-r--r-- | linuxthreads/tst-tls1.c | 91 | ||||
-rw-r--r-- | linuxthreads/tst-tls1.h | 28 | ||||
-rw-r--r-- | linuxthreads/tst-tls1mod.c | 6 | ||||
-rw-r--r-- | linuxthreads/tst-tls1moda.c | 6 | ||||
-rw-r--r-- | linuxthreads/tst-tls1modb.c | 6 | ||||
-rw-r--r-- | linuxthreads/tst-tls1modc.c | 6 | ||||
-rw-r--r-- | linuxthreads/tst-tls1modd.c | 6 | ||||
-rw-r--r-- | linuxthreads/tst-tls1mode.c | 8 | ||||
-rw-r--r-- | linuxthreads/tst-tls1modf.c | 9 | ||||
-rw-r--r-- | linuxthreads/tst-tls2.sh | 53 |
11 files changed, 238 insertions, 0 deletions
diff --git a/linuxthreads/ChangeLog b/linuxthreads/ChangeLog index df07ad11d3..b6a79ea45e 100644 --- a/linuxthreads/ChangeLog +++ b/linuxthreads/ChangeLog @@ -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, diff --git a/linuxthreads/tst-tls1.c b/linuxthreads/tst-tls1.c new file mode 100644 index 0000000000..3638b75455 --- /dev/null +++ b/linuxthreads/tst-tls1.c @@ -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" diff --git a/linuxthreads/tst-tls1.h b/linuxthreads/tst-tls1.h new file mode 100644 index 0000000000..b7c14eb82c --- /dev/null +++ b/linuxthreads/tst-tls1.h @@ -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 diff --git a/linuxthreads/tst-tls1mod.c b/linuxthreads/tst-tls1mod.c new file mode 100644 index 0000000000..a93d2cb9e6 --- /dev/null +++ b/linuxthreads/tst-tls1mod.c @@ -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 diff --git a/linuxthreads/tst-tls1moda.c b/linuxthreads/tst-tls1moda.c new file mode 100644 index 0000000000..a652ef981f --- /dev/null +++ b/linuxthreads/tst-tls1moda.c @@ -0,0 +1,6 @@ +#include <tst-tls1.h> + +#ifdef TLS_REGISTER +static __thread char a [32] __attribute__ ((aligned (64))); +TLS_REGISTER (a) +#endif diff --git a/linuxthreads/tst-tls1modb.c b/linuxthreads/tst-tls1modb.c new file mode 100644 index 0000000000..be8c95b486 --- /dev/null +++ b/linuxthreads/tst-tls1modb.c @@ -0,0 +1,6 @@ +#include <tst-tls1.h> + +#ifdef TLS_REGISTER +static __thread int b; +TLS_REGISTER (b) +#endif diff --git a/linuxthreads/tst-tls1modc.c b/linuxthreads/tst-tls1modc.c new file mode 100644 index 0000000000..e1094bf7aa --- /dev/null +++ b/linuxthreads/tst-tls1modc.c @@ -0,0 +1,6 @@ +#include <tst-tls1.h> + +#ifdef TLS_REGISTER +static __thread int c; +TLS_REGISTER (c) +#endif diff --git a/linuxthreads/tst-tls1modd.c b/linuxthreads/tst-tls1modd.c new file mode 100644 index 0000000000..cd68e0c26a --- /dev/null +++ b/linuxthreads/tst-tls1modd.c @@ -0,0 +1,6 @@ +#include <tst-tls1.h> + +#ifdef TLS_REGISTER +static __thread int d; +TLS_REGISTER (d) +#endif diff --git a/linuxthreads/tst-tls1mode.c b/linuxthreads/tst-tls1mode.c new file mode 100644 index 0000000000..845d31a4e4 --- /dev/null +++ b/linuxthreads/tst-tls1mode.c @@ -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 diff --git a/linuxthreads/tst-tls1modf.c b/linuxthreads/tst-tls1modf.c new file mode 100644 index 0000000000..a292e56c57 --- /dev/null +++ b/linuxthreads/tst-tls1modf.c @@ -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 diff --git a/linuxthreads/tst-tls2.sh b/linuxthreads/tst-tls2.sh new file mode 100644 index 0000000000..0d13963d5e --- /dev/null +++ b/linuxthreads/tst-tls2.sh @@ -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 |