diff options
| author | Ulrich Drepper <drepper@redhat.com> | 2003-09-17 18:23:49 +0000 |
|---|---|---|
| committer | Ulrich Drepper <drepper@redhat.com> | 2003-09-17 18:23:49 +0000 |
| commit | 06f6ca9019897f5d1799c0ae8d7293ed249c0f97 (patch) | |
| tree | 9a04e5058de47ce0898cf279205c8e58735efb96 | |
| parent | 65af7e61427ce9bbbc0e43b2ad44e5b4678a37fc (diff) | |
| download | glibc-06f6ca9019897f5d1799c0ae8d7293ed249c0f97.tar.xz glibc-06f6ca9019897f5d1799c0ae8d7293ed249c0f97.zip | |
Update.
2003-09-17 Philip Blundell <philb@gnu.org>
* sysdeps/unix/sysv/linux/arm/vfork.S: Branch to fork if
libpthread is loaded. Elide backwards compatibility code when not
required.
| -rw-r--r-- | elf/Makefile | 12 | ||||
| -rw-r--r-- | elf/tst-align.c | 54 | ||||
| -rw-r--r-- | elf/tst-alignmod.c | 53 | ||||
| -rw-r--r-- | libio/memstream.c | 78 | ||||
| -rw-r--r-- | linuxthreads/ChangeLog | 6 | ||||
| -rw-r--r-- | linuxthreads/attr.c | 9 | ||||
| -rw-r--r-- | linuxthreads/sysdeps/unix/sysv/linux/arm/vfork.S | 39 | ||||
| -rw-r--r-- | misc/Makefile | 1 | ||||
| -rw-r--r-- | misc/tst-tsearch.c | 22 | ||||
| -rw-r--r-- | nptl/Banner | 2 | ||||
| -rw-r--r-- | nptl/ChangeLog | 11 | ||||
| -rw-r--r-- | nptl/Makefile | 2 | ||||
| -rw-r--r-- | nptl/pthreadP.h | 4 | ||||
| -rw-r--r-- | nptl/pthread_getattr_np.c | 22 | ||||
| -rw-r--r-- | nptl/sysdeps/unix/sysv/linux/pthread_attr_getaffinity.c | 5 | ||||
| -rw-r--r-- | nptl/sysdeps/unix/sysv/linux/pthread_getaffinity.c | 1 | ||||
| -rw-r--r-- | nptl/tst-attr3.c | 414 | ||||
| -rw-r--r-- | stdlib/Makefile | 1 | ||||
| -rw-r--r-- | stdlib/tst-qsort.c | 13 | ||||
| -rw-r--r-- | sysdeps/arm/dl-machine.h | 72 | ||||
| -rw-r--r-- | sysdeps/arm/sysdep.h | 9 | ||||
| -rw-r--r-- | sysdeps/i386/i686/Makefile | 2 | ||||
| -rw-r--r-- | sysdeps/unix/sysv/linux/arm/vfork.S | 5 | ||||
| -rw-r--r-- | sysdeps/x86_64/tst-stack-align.h | 47 |
24 files changed, 746 insertions, 138 deletions
diff --git a/elf/Makefile b/elf/Makefile index 734b7854e8..c292cfa283 100644 --- a/elf/Makefile +++ b/elf/Makefile @@ -71,7 +71,7 @@ distribute := rtld-Rules \ tst-tlsmod1.c tst-tlsmod2.c tst-tlsmod3.c tst-tlsmod4.c \ tst-tlsmod5.c tst-tlsmod6.c tst-tlsmod7.c tst-tlsmod8.c \ tst-tlsmod9.c tst-tlsmod10.c tst-tlsmod11.c \ - tst-tlsmod12.c tst-tls10.h \ + tst-tlsmod12.c tst-tls10.h tst-alignmod.c \ circlemod1.c circlemod1a.c circlemod2.c circlemod2a.c \ circlemod3.c circlemod3a.c nodlopenmod2.c \ tls-macros.h \ @@ -150,7 +150,7 @@ tests += loadtest restest1 preloadtest loadfail multiload origtest resolvfail \ neededtest3 neededtest4 unload2 lateglobal initfirst global \ restest2 next dblload dblunload reldep5 reldep6 reldep7 reldep8 \ circleload1 tst-tls3 tst-tls4 tst-tls5 tst-tls6 tst-tls7 tst-tls8 \ - tst-tls10 tst-tls11 tst-tls12 tst-tls13 tst-tls14 + tst-tls10 tst-tls11 tst-tls12 tst-tls13 tst-tls14 tst-align # reldep9 test-srcs = tst-pathopt tests-vis-yes = vismain @@ -177,7 +177,8 @@ modules-names = testobj1 testobj2 testobj3 testobj4 testobj5 testobj6 \ circlemod1 circlemod1a circlemod2 circlemod2a \ circlemod3 circlemod3a \ reldep8mod1 reldep8mod2 reldep8mod3 \ - reldep9mod1 reldep9mod2 reldep9mod3 + reldep9mod1 reldep9mod2 reldep9mod3 \ + tst-alignmod ifeq (yes,$(have-initfini-array)) modules-names += tst-array2dep endif @@ -648,6 +649,11 @@ $(objpfx)tst-tls13.out: $(objpfx)tst-tlsmod13a.so $(objpfx)tst-tls14: $(objpfx)tst-tlsmod14a.so $(libdl) $(objpfx)tst-tls14.out:$(objpfx)tst-tlsmod14b.so +CFLAGS-tst-align.c = $(stack-align-test-flags) +CFLAGS-tst-alignmod.c = $(stack-align-test-flags) +$(objpfx)tst-align: $(libdl) +$(objpfx)tst-align.out: $(objpfx)tst-alignmod.so + ifdef libdl $(objpfx)tst-tls9-static: $(common-objpfx)dlfcn/libdl.a $(objpfx)tst-tls9-static.out: $(objpfx)tst-tlsmod5.so $(objpfx)tst-tlsmod6.so diff --git a/elf/tst-align.c b/elf/tst-align.c new file mode 100644 index 0000000000..e4d77763cd --- /dev/null +++ b/elf/tst-align.c @@ -0,0 +1,54 @@ +/* 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. */ + +#include <dlfcn.h> +#include <stdio.h> +#include <stdlib.h> + +static int +do_test (void) +{ + static const char modname[] = "tst-alignmod.so"; + int result = 0; + void (*fp) (int *); + void *h; + + h = dlopen (modname, RTLD_LAZY); + if (h == NULL) + { + printf ("cannot open '%s': %s\n", modname, dlerror ()); + exit (1); + } + + fp = dlsym (h, "in_dso"); + if (fp == NULL) + { + printf ("cannot get symbol 'in_dso': %s\n", dlerror ()); + exit (1); + } + + fp (&result); + + dlclose (h); + + return result; +} + +#define TEST_FUNCTION do_test () +#include "../test-skeleton.c" diff --git a/elf/tst-alignmod.c b/elf/tst-alignmod.c new file mode 100644 index 0000000000..d1305c1a6c --- /dev/null +++ b/elf/tst-alignmod.c @@ -0,0 +1,53 @@ +/* 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. */ + +#include <stdio.h> +#include <tst-stack-align.h> + +static int res, *resp; + +static void __attribute__((constructor)) +con (void) +{ + res = TEST_STACK_ALIGN () ? -1 : 1; +} + +void +in_dso (int *result) +{ + if (!res) + { + puts ("constructor has not been run"); + *result = 1; + } + else if (res != 1) + { + puts ("constructor has been run without sufficient alignment"); + *result = 1; + } + + resp = result; +} + +static void __attribute__((destructor)) +des (void) +{ + if (TEST_STACK_ALIGN ()) + *resp = 1; +} diff --git a/libio/memstream.c b/libio/memstream.c index 68645fa829..d09b8ab920 100644 --- a/libio/memstream.c +++ b/libio/memstream.c @@ -32,8 +32,6 @@ struct _IO_FILE_memstream static int _IO_mem_sync __P ((_IO_FILE* fp)); static void _IO_mem_finish __P ((_IO_FILE* fp, int)); -static int _IO_wmem_sync __P ((_IO_FILE* fp)); -static void _IO_wmem_finish __P ((_IO_FILE* fp, int)); static struct _IO_jump_t _IO_mem_jumps = @@ -60,30 +58,6 @@ static struct _IO_jump_t _IO_mem_jumps = JUMP_INIT(imbue, _IO_default_imbue) }; -static struct _IO_jump_t _IO_wmem_jumps = -{ - JUMP_INIT_DUMMY, - JUMP_INIT (finish, (_IO_finish_t) _IO_wmem_finish), - JUMP_INIT (overflow, (_IO_overflow_t) _IO_wstr_overflow), - JUMP_INIT (underflow, (_IO_underflow_t) _IO_wstr_underflow), - JUMP_INIT (uflow, (_IO_underflow_t) INTUSE(_IO_wdefault_uflow)), - JUMP_INIT (pbackfail, (_IO_pbackfail_t) _IO_wstr_pbackfail), - JUMP_INIT (xsputn, (_IO_xsputn_t) INTUSE(_IO_wdefault_xsputn)), - JUMP_INIT (xsgetn, (_IO_xsgetn_t) INTUSE(_IO_wdefault_xsgetn)), - JUMP_INIT (seekoff, _IO_wstr_seekoff), - JUMP_INIT (seekpos, _IO_default_seekpos), - JUMP_INIT (setbuf, _IO_default_setbuf), - JUMP_INIT (sync, (_IO_sync_t) _IO_wmem_sync), - JUMP_INIT (doallocate, INTUSE(_IO_wdefault_doallocate)), - JUMP_INIT (read, _IO_default_read), - JUMP_INIT (write, _IO_default_write), - JUMP_INIT (seek, _IO_default_seek), - JUMP_INIT (close, _IO_default_close), - JUMP_INIT (stat, _IO_default_stat), - JUMP_INIT(showmanyc, _IO_default_showmanyc), - JUMP_INIT(imbue, _IO_default_imbue) -}; - /* Open a stream that writes into a malloc'd buffer that is expanded as necessary. *BUFLOC and *SIZELOC are updated with the buffer's location and the number of characters written on fflush or fclose. */ @@ -172,55 +146,3 @@ _IO_mem_finish (fp, dummy) INTUSE(_IO_default_finish) (fp, 0); } - - -static int -_IO_wmem_sync (fp) - _IO_FILE* fp; -{ - struct _IO_FILE_memstream *mp = (struct _IO_FILE_memstream *) fp; - int res; - - res = _IO_default_sync (fp); - if (res < 0) - return res; - - if (fp->_wide_data->_IO_write_ptr == fp->_wide_data->_IO_write_end) - { - _IO_wstr_overflow (fp, L'\0'); - --fp->_wide_data->_IO_write_ptr; - } - else - *fp->_wide_data->_IO_write_ptr = '\0'; - - *mp->bufloc = (char *) fp->_wide_data->_IO_write_base; - *mp->sizeloc = (fp->_wide_data->_IO_write_ptr - - fp->_wide_data->_IO_write_base); - - return 0; -} - - -static void -_IO_wmem_finish (fp, dummy) - _IO_FILE* fp; - int dummy; -{ - struct _IO_FILE_memstream *mp = (struct _IO_FILE_memstream *) fp; - - *mp->bufloc = (char *) realloc (fp->_wide_data->_IO_write_base, - (fp->_wide_data->_IO_write_ptr - - fp->_wide_data->_IO_write_base + 1) - * sizeof (wchar_t)); - if (*mp->bufloc != NULL) - { - ((wchar_t *) (*mp->bufloc))[fp->_wide_data->_IO_write_ptr - - fp->_wide_data->_IO_write_base] = '\0'; - *mp->sizeloc = (fp->_wide_data->_IO_write_ptr - - fp->_wide_data->_IO_write_base); - } - - fp->_wide_data->_IO_buf_base = NULL; - - INTUSE(_IO_default_finish) (fp, 0); -} diff --git a/linuxthreads/ChangeLog b/linuxthreads/ChangeLog index cd5eb8e61f..5a86b94232 100644 --- a/linuxthreads/ChangeLog +++ b/linuxthreads/ChangeLog @@ -1,3 +1,9 @@ +2003-09-17 Philip Blundell <philb@gnu.org> + + * sysdeps/unix/sysv/linux/arm/vfork.S: Branch to fork if + libpthread is loaded. Elide backwards compatibility code when not + required. + 2003-09-17 Jakub Jelinek <jakub@redhat.com> * descr.h (manager_thread): Rename to... diff --git a/linuxthreads/attr.c b/linuxthreads/attr.c index a66eb72c27..687334ffdb 100644 --- a/linuxthreads/attr.c +++ b/linuxthreads/attr.c @@ -404,7 +404,11 @@ int pthread_getattr_np (pthread_t thread, pthread_attr_t *attr) # endif #endif +#ifdef USE_TLS if (attr->__stackaddr == NULL) +#else + if (descr == &__pthread_initial_thread) +#endif { /* Defined in ld.so. */ extern void *__libc_stack_end; @@ -448,6 +452,11 @@ int pthread_getattr_np (pthread_t thread, pthread_attr_t *attr) attr->__stacksize = rl.rlim_cur; attr->__stackaddr = (void *) to; + /* The limit might be too high. This is a bogus + situation but try to avoid making it worse. */ + if ((size_t) attr->__stacksize > (size_t) attr->__stackaddr) + attr->__stacksize = (size_t) attr->__stackaddr; + /* We succeed and no need to look further. */ ret = 0; break; diff --git a/linuxthreads/sysdeps/unix/sysv/linux/arm/vfork.S b/linuxthreads/sysdeps/unix/sysv/linux/arm/vfork.S index 8d3338afd0..23687342d1 100644 --- a/linuxthreads/sysdeps/unix/sysv/linux/arm/vfork.S +++ b/linuxthreads/sysdeps/unix/sysv/linux/arm/vfork.S @@ -20,37 +20,60 @@ #include <sysdep-cancel.h> #define _ERRNO_H 1 #include <bits/errno.h> +#include <kernel-features.h> -/* Clone the calling process, but without copying the whole address -pace. +/* Clone the calling process, but without copying the whole address space. The calling process is suspended until the new process exits or is - replaced by a call to `execve'. Return -1 for errors, 0 to the new -rocess, + replaced by a call to `execve'. Return -1 for errors, 0 to the new process, and the process ID of the new process to the old process. */ PSEUDO_PROLOGUE ENTRY (__vfork) - SINGLE_THREAD_P - bne HIDDEN_JUMPTARGET (__fork) #ifdef __NR_vfork + +#ifdef SHARED + ldr ip, 1f + ldr r0, 2f +3: add ip, pc, ip + ldr r0, [ip, r0] +#else + ldr r0, 1f +#endif + movs r0, r0 + bne HIDDEN_JUMPTARGET (__fork) + swi __NR_vfork cmn a1, #4096 RETINSTR(movcc, pc, lr) +#ifndef __ASSUME_VFORK_SYSCALL /* Check if vfork syscall is known at all. */ - ldr a2, =-ENOSYS - teq a1, a2 + cmn a1, #ENOSYS bne PLTJMP(C_SYMBOL_NAME(__syscall_error)) #endif +#endif + +#ifndef __ASSUME_VFORK_SYSCALL /* If we don't have vfork, fork is close enough. */ swi __NR_fork cmn a1, #4096 RETINSTR(movcc, pc, lr) +#elif !defined __NR_vfork +# error "__NR_vfork not available and __ASSUME_VFORK_SYSCALL defined" +#endif b PLTJMP(C_SYMBOL_NAME(__syscall_error)) +#ifdef SHARED +1: .word _GLOBAL_OFFSET_TABLE_ - 3b - 8 +2: .word __libc_pthread_functions(GOTOFF) +#else + .weak pthread_create +1: .word pthread_create +#endif + PSEUDO_END (__vfork) libc_hidden_def (__vfork) diff --git a/misc/Makefile b/misc/Makefile index e74070113d..ad57434f26 100644 --- a/misc/Makefile +++ b/misc/Makefile @@ -89,6 +89,7 @@ CFLAGS-mkstemp64.c = -fexceptions CFLAGS-getsysstats.c = -fexceptions CFLAGS-getusershell.c = -fexceptions CFLAGS-err.c = -fexceptions +CFLAGS-tst-tsearch.c = $(stack-align-test-flags) include ../Rules diff --git a/misc/tst-tsearch.c b/misc/tst-tsearch.c index 722b6d7907..66f76ac884 100644 --- a/misc/tst-tsearch.c +++ b/misc/tst-tsearch.c @@ -1,5 +1,5 @@ /* Test program for tsearch et al. - Copyright (C) 1997, 2000, 2001 Free Software Foundation, Inc. + Copyright (C) 1997, 2000, 2001, 2003 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -25,6 +25,7 @@ #include <stdlib.h> #include <string.h> #include <search.h> +#include <tst-stack-align.h> #define SEED 0 #define BALANCED 1 @@ -72,10 +73,14 @@ static int depths[SIZE]; /* Maximum depth during a tree walk. */ static int max_depth; +static int stack_align_check[2]; + /* Compare two keys. */ static int cmp_fn (const void *a, const void *b) { + if (!stack_align_check[0]) + stack_align_check[0] = TEST_STACK_ALIGN () ? -1 : 1; return *(const int *) a - *(const int *) b; } @@ -103,6 +108,9 @@ walk_action (const void *nodep, const VISIT which, const int depth) { int key = **(int **) nodep; + if (!stack_align_check[1]) + stack_align_check[1] = TEST_STACK_ALIGN () ? -1 : 1; + if (depth > max_depth) max_depth = depth; if (which == leaf || which == preorder) @@ -329,5 +337,17 @@ main (int argc, char **argv) total_error |= error; } + for (i = 0; i < 2; ++i) + if (stack_align_check[i] == 0) + { + printf ("stack alignment check %d not run\n", i); + total_error |= 1; + } + else if (stack_align_check[i] != 1) + { + printf ("stack insufficiently aligned in check %d\n", i); + total_error |= 1; + } + return total_error; } diff --git a/nptl/Banner b/nptl/Banner index cc4ac696ef..5d6a6d0445 100644 --- a/nptl/Banner +++ b/nptl/Banner @@ -1 +1 @@ -NPTL 0.58 by Ulrich Drepper +NPTL 0.59 by Ulrich Drepper diff --git a/nptl/ChangeLog b/nptl/ChangeLog index 1edbb9842b..e7341f1394 100644 --- a/nptl/ChangeLog +++ b/nptl/ChangeLog @@ -1,5 +1,16 @@ 2003-09-17 Jakub Jelinek <jakub@redhat.com> + * sysdeps/unix/sysv/linux/pthread_attr_getaffinity.c + (pthread_attr_getaffinity_np): Don't segfault if iattr->cpuset is + NULL. + * pthread_getattr_np.c: Set cpuset using pthread_getaffinity_np. + * pthreadP.h (pthread_getaffinity_np): Add hidden_proto. + * sysdeps/unix/sysv/linux/pthread_getaffinity.c + (pthread_getaffinity_np): Add hidden_def. + + * Makefile (tests): Add tst-attr3. + * tst-attr3.c: New test. + * sysdeps/i386/Makefile (CFLAGS-tst-align.c): Remove. 2003-09-15 Jakub Jelinek <jakub@redhat.com> diff --git a/nptl/Makefile b/nptl/Makefile index 7876331e52..ba568dffba 100644 --- a/nptl/Makefile +++ b/nptl/Makefile @@ -189,7 +189,7 @@ CFLAGS-pt-system.c = -fexceptions omit-deps = $(unix-syscalls:%=ptw-%) -tests = tst-attr1 tst-attr2 \ +tests = tst-attr1 tst-attr2 tst-attr3 \ tst-mutex1 tst-mutex2 tst-mutex3 tst-mutex4 tst-mutex5 tst-mutex6 \ tst-mutex7 tst-mutex8 tst-mutex9 \ tst-spin1 tst-spin2 tst-spin3 \ diff --git a/nptl/pthreadP.h b/nptl/pthreadP.h index 99b344489a..1981fc4aeb 100644 --- a/nptl/pthreadP.h +++ b/nptl/pthreadP.h @@ -424,4 +424,8 @@ extern void _pthread_cleanup_push_defer (struct _pthread_cleanup_buffer *buffer, extern void _pthread_cleanup_pop_restore (struct _pthread_cleanup_buffer *buffer, int execute); +#if defined NOT_IN_libc && defined IS_IN_libpthread +hidden_proto (pthread_getaffinity_np) +#endif + #endif /* pthreadP.h */ diff --git a/nptl/pthread_getattr_np.c b/nptl/pthread_getattr_np.c index dfacd887c9..9cc948f4c6 100644 --- a/nptl/pthread_getattr_np.c +++ b/nptl/pthread_getattr_np.c @@ -114,6 +114,11 @@ pthread_getattr_np (thread_id, attr) iattr->stacksize = rl.rlim_cur; iattr->stackaddr = (void *) to; + /* The limit might be too high. This is a bogus + situation but try to avoid making it worse. */ + if ((size_t) iattr->stacksize > (size_t) iattr->stackaddr) + iattr->stacksize = (size_t) iattr->stackaddr; + /* We succeed and no need to look further. */ ret = 0; break; @@ -127,6 +132,23 @@ pthread_getattr_np (thread_id, attr) iattr->flags |= ATTR_FLAG_STACKADDR; + if (ret == 0) + { + iattr->cpuset = (cpu_set_t *) malloc (sizeof (cpu_set_t)); + if (iattr->cpuset == NULL) + ret |
