From 2af6396817fb9df98e63de75dd59fd999ee9f1d0 Mon Sep 17 00:00:00 2001 From: Ulrich Drepper Date: Tue, 15 Dec 2009 12:32:27 -0800 Subject: [PATCH 01/14] Avoid ELF lookup race. On some architectures the update of the l_used field in the lookup functions races with setting the other bits in the bitfield. Simply avoid this and optimize use of l_used in general. --- ChangeLog | 8 ++++++++ elf/dl-lookup.c | 7 ++++--- elf/dl-object.c | 8 ++++++-- include/link.h | 8 +++++--- 4 files changed, 23 insertions(+), 8 deletions(-) diff --git a/ChangeLog b/ChangeLog index ce4d4e8e3b..b1e14b664e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +2009-12-15 Ulrich Drepper + + * include/link.h (struct link_map): Move l_used into its own word. + * elf/dl-lookup.c (_dl_lookup_symbol_x): Only update l_used when it is + still zero. + * elf/dl-object.c (_dl_new_object): Set dl_used if we know it is + never really used. + 2009-12-13 H.J. Lu * sysdeps/i386/i686/multiarch/strcspn.S Include diff --git a/elf/dl-lookup.c b/elf/dl-lookup.c index c1a1366d6f..763ec16fa4 100644 --- a/elf/dl-lookup.c +++ b/elf/dl-lookup.c @@ -777,7 +777,7 @@ _dl_lookup_symbol_x (const char *undef_name, struct link_map *undef_map, if (__builtin_expect (protected != 0, 0)) { /* It is very tricky. We need to figure out what value to - return for the protected symbol. */ + return for the protected symbol. */ if (type_class == ELF_RTYPE_CLASS_PLT) { if (current_value.s != NULL && current_value.m != undef_map) @@ -822,7 +822,8 @@ _dl_lookup_symbol_x (const char *undef_name, struct link_map *undef_map, version, type_class, flags, skip_map); /* The object is used. */ - current_value.m->l_used = 1; + if (__builtin_expect (current_value.m->l_used == 0, 0)) + current_value.m->l_used = 1; if (__builtin_expect (GLRO(dl_debug_mask) & (DL_DEBUG_BINDINGS|DL_DEBUG_PRELINK), 0)) @@ -844,7 +845,7 @@ _dl_setup_hash (struct link_map *map) Elf_Symndx nchain; if (__builtin_expect (map->l_info[DT_ADDRTAGIDX (DT_GNU_HASH) + DT_NUM - + DT_THISPROCNUM + DT_VERSIONTAGNUM + + DT_THISPROCNUM + DT_VERSIONTAGNUM + DT_EXTRANUM + DT_VALNUM] != NULL, 1)) { Elf32_Word *hash32 diff --git a/elf/dl-object.c b/elf/dl-object.c index be4ea38f9f..788e2c07b9 100644 --- a/elf/dl-object.c +++ b/elf/dl-object.c @@ -1,5 +1,5 @@ /* Storage management for the chain of loaded shared objects. - Copyright (C) 1995-2002,2004,2006,2007,2008 Free Software Foundation, Inc. + Copyright (C) 1995-2002,2004,2006-2008,2009 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 @@ -67,6 +67,10 @@ _dl_new_object (char *realname, const char *libname, int type, new->l_name = realname; new->l_type = type; + /* If we set the bit now since we know it is never used we avoid + dirtying the cache line later. */ + if ((GLRO(dl_debug_mask) & DL_DEBUG_UNUSED) == 0) + new->l_used = 1; new->l_loader = loader; #if NO_TLS_OFFSET != 0 new->l_tls_offset = NO_TLS_OFFSET; @@ -174,7 +178,7 @@ _dl_new_object (char *realname, const char *libname, int type, if (result == NULL) { /* We were not able to determine the current directory. - Note that free(origin) is OK if origin == NULL. */ + Note that free(origin) is OK if origin == NULL. */ free (origin); origin = (char *) -1; goto out; diff --git a/include/link.h b/include/link.h index 4b9978ad61..26c67438f0 100644 --- a/include/link.h +++ b/include/link.h @@ -1,6 +1,6 @@ /* Data structure for communication from the run-time dynamic linker for loaded ELF shared objects. - Copyright (C) 1995-2006, 2007 Free Software Foundation, Inc. + Copyright (C) 1995-2006, 2007, 2009 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 @@ -180,7 +180,6 @@ struct link_map unsigned int l_need_tls_init:1; /* Nonzero if GL(dl_init_static_tls) should be called on this link map when relocation finishes. */ - unsigned int l_used:1; /* Nonzero if the DSO is used. */ unsigned int l_auditing:1; /* Nonzero if the DSO is used in auditing. */ unsigned int l_audit_any_plt:1; /* Nonzero if at least one audit module is interested in the PLT interception.*/ @@ -239,12 +238,15 @@ struct link_map struct link_map **l_initfini; /* List of the dependencies introduced through symbol binding. */ - unsigned int l_reldepsmax; struct link_map_reldeps { unsigned int act; struct link_map *list[]; } *l_reldeps; + unsigned int l_reldepsmax; + + /* Nonzero if the DSO is used. */ + unsigned int l_used; /* Various flag words. */ ElfW(Word) l_feature_1; From f282f6b90a52d95370392bd7a4e6ec1bbd90afe5 Mon Sep 17 00:00:00 2001 From: Ulrich Drepper Date: Tue, 15 Dec 2009 13:05:14 -0800 Subject: [PATCH 02/14] Update poll.h header for POSIX 2008. --- ChangeLog | 6 ++++++ bits/poll.h | 6 +++--- sysdeps/unix/sysv/linux/bits/poll.h | 4 ++-- sysdeps/unix/sysv/linux/sparc/bits/poll.h | 4 ++-- 4 files changed, 13 insertions(+), 7 deletions(-) diff --git a/ChangeLog b/ChangeLog index b1e14b664e..35d0a57f4f 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,11 @@ 2009-12-15 Ulrich Drepper + [BZ #11093] + * bits/poll.h: Define POLLRDNORM, POLLRDBAND, POLLWRNORM, and + POLLWRBAND also for POSIX 2008. + * sysdeps/unix/sysv/linux/bits/poll.h: Likewise. + * sysdeps/unix/sysv/linux/sparc/bits/poll.h: Likewise. + * include/link.h (struct link_map): Move l_used into its own word. * elf/dl-lookup.c (_dl_lookup_symbol_x): Only update l_used when it is still zero. diff --git a/bits/poll.h b/bits/poll.h index 022a06cc1b..0ee9b00583 100644 --- a/bits/poll.h +++ b/bits/poll.h @@ -1,4 +1,4 @@ -/* Copyright (C) 1997, 2000, 2001 Free Software Foundation, Inc. +/* Copyright (C) 1997, 2000, 2001, 2009 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 @@ -27,8 +27,8 @@ #define POLLPRI 02 /* There is urgent data to read. */ #define POLLOUT 04 /* Writing now will not block. */ -#ifdef __USE_XOPEN -/* These values are defined in XPG4.2. */ +#if defined __USE_XOPEN || defined __USE_XOPEN2K8 +/* These values are defined in XPG4.2 and later. */ # define POLLRDNORM POLLIN /* Normal data may be read. */ # define POLLRDBAND POLLPRI /* Priority data may be read. */ # define POLLWRNORM POLLOUT /* Writing now will not block. */ diff --git a/sysdeps/unix/sysv/linux/bits/poll.h b/sysdeps/unix/sysv/linux/bits/poll.h index d7996b46c5..9dd75cb3af 100644 --- a/sysdeps/unix/sysv/linux/bits/poll.h +++ b/sysdeps/unix/sysv/linux/bits/poll.h @@ -1,4 +1,4 @@ -/* Copyright (C) 1997, 2001, 2006 Free Software Foundation, Inc. +/* Copyright (C) 1997, 2001, 2006, 2009 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 @@ -27,7 +27,7 @@ #define POLLPRI 0x002 /* There is urgent data to read. */ #define POLLOUT 0x004 /* Writing now will not block. */ -#ifdef __USE_XOPEN +#if defined __USE_XOPEN || defined __USE_XOPEN2K8 /* These values are defined in XPG4.2. */ # define POLLRDNORM 0x040 /* Normal data may be read. */ # define POLLRDBAND 0x080 /* Priority data may be read. */ diff --git a/sysdeps/unix/sysv/linux/sparc/bits/poll.h b/sysdeps/unix/sysv/linux/sparc/bits/poll.h index 53b94bc50e..0a984ad765 100644 --- a/sysdeps/unix/sysv/linux/sparc/bits/poll.h +++ b/sysdeps/unix/sysv/linux/sparc/bits/poll.h @@ -1,4 +1,4 @@ -/* Copyright (C) 1997, 2001, 2006 Free Software Foundation, Inc. +/* Copyright (C) 1997, 2001, 2006, 2009 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 @@ -27,7 +27,7 @@ #define POLLPRI 0x002 /* There is urgent data to read. */ #define POLLOUT 0x004 /* Writing now will not block. */ -#ifdef __USE_XOPEN +#if defined __USE_XOPEN || defined __USE_XOPEN2K8 /* These values are defined in XPG4.2. */ # define POLLRDNORM 0x040 /* Normal data may be read. */ # define POLLRDBAND 0x080 /* Priority data may be read. */ From f01c2359ebd4ed130ea0bfa67b59db896cb55cd5 Mon Sep 17 00:00:00 2001 From: Ulrich Drepper Date: Thu, 17 Dec 2009 13:49:36 -0800 Subject: [PATCH 03/14] Small optimization of pthread_rwlock_init. --- nptl/ChangeLog | 5 +++++ nptl/pthread_rwlock_init.c | 17 ++++------------- 2 files changed, 9 insertions(+), 13 deletions(-) diff --git a/nptl/ChangeLog b/nptl/ChangeLog index b05f6e4a03..8cea2f648f 100644 --- a/nptl/ChangeLog +++ b/nptl/ChangeLog @@ -1,3 +1,8 @@ +2009-12-17 Ulrich Drepper + + * pthread_rwlock_init.c (__pthread_rwlock_init): Simplify code by + using memset. + 2009-12-01 Dinakar Guniguntala * sysdeps/unix/sysv/linux/i386/i486/lowlevellock.h: Define diff --git a/nptl/pthread_rwlock_init.c b/nptl/pthread_rwlock_init.c index 27f25ac2ab..c0aa194107 100644 --- a/nptl/pthread_rwlock_init.c +++ b/nptl/pthread_rwlock_init.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2002, 2007 Free Software Foundation, Inc. +/* Copyright (C) 2002, 2007, 2009 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Ulrich Drepper , 2002. @@ -37,13 +37,7 @@ __pthread_rwlock_init (rwlock, attr) iattr = ((const struct pthread_rwlockattr *) attr) ?: &default_attr; - rwlock->__data.__lock = 0; - rwlock->__data.__nr_readers = 0; - rwlock->__data.__readers_wakeup = 0; - rwlock->__data.__writer_wakeup = 0; - rwlock->__data.__nr_readers_queued = 0; - rwlock->__data.__nr_writers_queued = 0; - rwlock->__data.__writer = 0; + memset (rwlock, '\0', sizeof (*rwlock)); rwlock->__data.__flags = iattr->lockkind == PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP; @@ -56,8 +50,8 @@ __pthread_rwlock_init (rwlock, attr) 0x80 in case private futexes are available and zero otherwise. This leads to the following table: - | pshared | result - | shared private | shared private | + | pshared | result + | shared private | shared private | ------------+-----------------+-----------------+ !avail 0 | 0 0 | 0 0 | avail 0x80 | 0x80 0 | 0 0x80 | @@ -74,9 +68,6 @@ __pthread_rwlock_init (rwlock, attr) header.private_futex)); #endif - rwlock->__data.__pad1 = 0; - rwlock->__data.__pad2 = 0; - return 0; } strong_alias (__pthread_rwlock_init, pthread_rwlock_init) From 4286fa41edc33da4cfbc56c2c5902920a52e3184 Mon Sep 17 00:00:00 2001 From: Ulrich Drepper Date: Mon, 21 Dec 2009 14:08:05 -0800 Subject: [PATCH 04/14] Handle AT_FDCWD in futimens. --- ChangeLog | 4 ++++ sysdeps/unix/sysv/linux/futimens.c | 5 +++++ 2 files changed, 9 insertions(+) diff --git a/ChangeLog b/ChangeLog index 35d0a57f4f..02cae689d5 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2009-12-21 Ulrich Drepper + + * sysdeps/unix/sysv/linux/futimens.c: Handle AT_FDCWD. + 2009-12-15 Ulrich Drepper [BZ #11093] diff --git a/sysdeps/unix/sysv/linux/futimens.c b/sysdeps/unix/sysv/linux/futimens.c index 67f2588f86..fe8e92070d 100644 --- a/sysdeps/unix/sysv/linux/futimens.c +++ b/sysdeps/unix/sysv/linux/futimens.c @@ -33,6 +33,11 @@ int futimens (int fd, const struct timespec tsp[2]) { #ifdef __NR_utimensat + if (fd < 0) + { + __set_errno (EBADF); + return -1; + } return INLINE_SYSCALL (utimensat, 4, fd, NULL, tsp, 0); #else __set_errno (ENOSYS); From caf512dec254923b5eded0b3f36f5db66756066d Mon Sep 17 00:00:00 2001 From: Martin Schwidefsky Date: Tue, 22 Dec 2009 08:34:07 -0800 Subject: [PATCH 05/14] Implement handling of the needed S390 relocations. --- ChangeLog | 7 +++++++ sysdeps/s390/s390-32/dl-machine.h | 5 ++++- sysdeps/s390/s390-64/dl-machine.h | 2 -- 3 files changed, 11 insertions(+), 3 deletions(-) diff --git a/ChangeLog b/ChangeLog index 02cae689d5..07a707b051 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2009-12-17 Martin Schwidefsky + + * sysdeps/s390/s390-32/dl-machine.h (elf_machine_rela): Handle + R_390_PC32DBL. Remove unneeded R_390_PLT16DBL. + * sysdeps/s390/s390-32/dl-machine.h (elf_machine_rela): Remove + unneeded R_390_PLT16DBL and R_390_PLT32DBL. + 2009-12-21 Ulrich Drepper * sysdeps/unix/sysv/linux/futimens.c: Handle AT_FDCWD. diff --git a/sysdeps/s390/s390-32/dl-machine.h b/sysdeps/s390/s390-32/dl-machine.h index 64bf3423b6..251a5f6922 100644 --- a/sysdeps/s390/s390-32/dl-machine.h +++ b/sysdeps/s390/s390-32/dl-machine.h @@ -389,10 +389,13 @@ elf_machine_rela (struct link_map *map, const Elf32_Rela *reloc, *reloc_addr = value + reloc->r_addend - (Elf32_Addr) reloc_addr; break; case R_390_PC16DBL: - case R_390_PLT16DBL: *(unsigned short *) reloc_addr = (unsigned short) ((short) (value + reloc->r_addend - (Elf32_Addr) reloc_addr) >> 1); break; + case R_390_PC32DBL: + *(unsigned int *) reloc_addr = (unsigned int) + ((int) (value + reloc->r_addend - (Elf32_Addr) reloc_addr) >> 1); + break; case R_390_PC16: *(unsigned short *) reloc_addr = value + reloc->r_addend - (Elf32_Addr) reloc_addr; diff --git a/sysdeps/s390/s390-64/dl-machine.h b/sysdeps/s390/s390-64/dl-machine.h index fa893befdf..c4df274cdb 100644 --- a/sysdeps/s390/s390-64/dl-machine.h +++ b/sysdeps/s390/s390-64/dl-machine.h @@ -371,7 +371,6 @@ elf_machine_rela (struct link_map *map, const Elf64_Rela *reloc, *reloc_addr = value +reloc->r_addend - (Elf64_Addr) reloc_addr; break; case R_390_PC32DBL: - case R_390_PLT32DBL: *(unsigned int *) reloc_addr = (unsigned int) ((int) (value + reloc->r_addend - (Elf64_Addr) reloc_addr) >> 1); break; @@ -380,7 +379,6 @@ elf_machine_rela (struct link_map *map, const Elf64_Rela *reloc, value + reloc->r_addend - (Elf64_Addr) reloc_addr; break; case R_390_PC16DBL: - case R_390_PLT16DBL: *(unsigned short *) reloc_addr = (unsigned short) ((short) (value + reloc->r_addend - (Elf64_Addr) reloc_addr) >> 1); break; From d34bd80fceb76fa66308bd8005ad28be96a01e36 Mon Sep 17 00:00:00 2001 From: Thomas Schwinge Date: Tue, 22 Dec 2009 08:37:33 -0800 Subject: [PATCH 06/14] Fix s390 startup code in libpthread. --- nptl/ChangeLog | 6 ++++++ .../sysdeps/unix/sysv/linux/s390/s390-32/pt-initfini.c | 10 +--------- .../sysdeps/unix/sysv/linux/s390/s390-64/pt-initfini.c | 8 +------- 3 files changed, 8 insertions(+), 16 deletions(-) diff --git a/nptl/ChangeLog b/nptl/ChangeLog index 8cea2f648f..389bed4a68 100644 --- a/nptl/ChangeLog +++ b/nptl/ChangeLog @@ -1,3 +1,9 @@ +2009-12-18 Thomas Schwinge + + * sysdeps/unix/sysv/linux/s390/s390-32/pt-initfini.c (_init): Don't + call __gmon_start__. + * sysdeps/unix/sysv/linux/s390/s390-64/pt-initfini.c (_init): Likewise. + 2009-12-17 Ulrich Drepper * pthread_rwlock_init.c (__pthread_rwlock_init): Simplify code by diff --git a/nptl/sysdeps/unix/sysv/linux/s390/s390-32/pt-initfini.c b/nptl/sysdeps/unix/sysv/linux/s390/s390-32/pt-initfini.c index 40d4d50c32..eb09b4aaa9 100644 --- a/nptl/sysdeps/unix/sysv/linux/s390/s390-32/pt-initfini.c +++ b/nptl/sysdeps/unix/sysv/linux/s390/s390-32/pt-initfini.c @@ -1,5 +1,5 @@ /* Special .init and .fini section support for S/390. - Copyright (C) 2003 Free Software Foundation, Inc. + Copyright (C) 2003, 2009 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it @@ -67,8 +67,6 @@ _init:\n\ .LT1_0:\n\ .LC13:\n\ .long __pthread_initialize_minimal_internal-.LT1_0\n\ -.LC14:\n\ - .long __gmon_start__@GOT\n\ .LC15:\n\ .long _GLOBAL_OFFSET_TABLE_-.LT1_0\n\ .LTN1_0:\n\ @@ -80,12 +78,6 @@ _init:\n\ L 1,.LC13-.LT1_0(13)\n\ LA 1,0(1,13)\n\ BASR 14,1\n\ - L 1,.LC14-.LT1_0(13)\n\ - L 1,0(1,12)\n\ - LTR 1,1\n\ - JE .L22\n\ - BASR 14,1\n\ -.L22:\n\ #APP\n\ .align 4,0x07\n\ END_INIT\n\ diff --git a/nptl/sysdeps/unix/sysv/linux/s390/s390-64/pt-initfini.c b/nptl/sysdeps/unix/sysv/linux/s390/s390-64/pt-initfini.c index a102d07d6c..34951f6fbb 100644 --- a/nptl/sysdeps/unix/sysv/linux/s390/s390-64/pt-initfini.c +++ b/nptl/sysdeps/unix/sysv/linux/s390/s390-64/pt-initfini.c @@ -1,5 +1,5 @@ /* Special .init and .fini section support for 64 bit S/390. - Copyright (C) 2003 Free Software Foundation, Inc. + Copyright (C) 2003, 2009 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it @@ -68,12 +68,6 @@ _init:\n\ STG 1,0(15)\n\ LARL 12,_GLOBAL_OFFSET_TABLE_\n\ BRASL 14,__pthread_initialize_minimal_internal\n\ - LARL 1,__gmon_start__@GOTENT\n\ - LG 1,0(1)\n\ - LTGR 1,1\n\ - JE .L22\n\ - BASR 14,1\n\ -.L22:\n\ #APP\n\ .align 4,0x07\n\ END_INIT\n\ From e70ffcb0fa9a63e7befc3e513944aeb19d2e4748 Mon Sep 17 00:00:00 2001 From: Samuel Thibault Date: Tue, 22 Dec 2009 11:47:13 -0800 Subject: [PATCH 07/14] Hurd: Fix spurious mach_port_deallocate in getcwd. --- ChangeLog | 5 +++++ sysdeps/mach/hurd/getcwd.c | 4 ++-- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 07a707b051..3ff2684f56 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2009-12-20 Samuel Thibault + + * sysdeps/mach/hurd/getcwd.c (cleanup): Do not call + __mach_port_deallocate on rootdevid. + 2009-12-17 Martin Schwidefsky * sysdeps/s390/s390-32/dl-machine.h (elf_machine_rela): Handle diff --git a/sysdeps/mach/hurd/getcwd.c b/sysdeps/mach/hurd/getcwd.c index 7e07e6b404..7da677eec9 100644 --- a/sysdeps/mach/hurd/getcwd.c +++ b/sysdeps/mach/hurd/getcwd.c @@ -1,4 +1,5 @@ -/* Copyright (C) 1991,92,93,94,95,96,97,98,2002,04 Free Software Foundation, Inc. +/* Copyright (C) 1991,92,93,94,95,96,97,98,2002,2004,2009 + 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 @@ -60,7 +61,6 @@ _hurd_canonicalize_directory_name_internal (file_t thisdir, __mach_port_deallocate (__mach_task_self (), thisid); __mach_port_deallocate (__mach_task_self (), thisdevid); __mach_port_deallocate (__mach_task_self (), rootid); - __mach_port_deallocate (__mach_task_self (), rootdevid); if (dirbuf != NULL) __vm_deallocate (__mach_task_self (), From e87e2f48effefe5e70a9a21bc13d7187608d0365 Mon Sep 17 00:00:00 2001 From: Samuel Thibault Date: Tue, 22 Dec 2009 11:51:44 -0800 Subject: [PATCH 08/14] Hurd: Fix possibly uninitialized variable in _hurd_locked_install_cttyid. --- ChangeLog | 5 +++++ hurd/hurdioctl.c | 24 ++++++++++-------------- 2 files changed, 15 insertions(+), 14 deletions(-) diff --git a/ChangeLog b/ChangeLog index 3ff2684f56..aba0d71b28 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2009-12-22 Samuel Thibault + + * hurd/hurdioctl.c (_hurd_locked_install_cttyid): Set newctty to + MACH_PORT_NULL when id != cttyid. + 2009-12-20 Samuel Thibault * sysdeps/mach/hurd/getcwd.c (cleanup): Do not call diff --git a/hurd/hurdioctl.c b/hurd/hurdioctl.c index 96d910ba1a..7c689841ca 100644 --- a/hurd/hurdioctl.c +++ b/hurd/hurdioctl.c @@ -1,5 +1,6 @@ /* ioctl commands which must be done in the C library. - Copyright (C) 1994,95,96,97,99,2001,02 Free Software Foundation, Inc. + Copyright (C) 1994,95,96,97,99,2001,2002,2009 + 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 @@ -169,33 +170,28 @@ _hurd_locked_install_cttyid (mach_port_t cttyid) for (i = 0; i < _hurd_dtablesize; ++i) { struct hurd_fd *const d = _hurd_dtable[i]; - mach_port_t newctty; + mach_port_t newctty = MACH_PORT_NULL; if (d == NULL) /* Nothing to do for an unused descriptor cell. */ continue; - if (cttyid == MACH_PORT_NULL) - /* We now have no controlling tty at all. */ - newctty = MACH_PORT_NULL; - else + if (cttyid != MACH_PORT_NULL) + /* We do have some controlling tty. */ HURD_PORT_USE (&d->port, ({ mach_port_t id; /* Get the io object's cttyid port. */ if (! __term_getctty (port, &id)) { - if (id == cttyid && /* Is it ours? */ + if (id == cttyid /* Is it ours? */ /* Get the ctty io port. */ - __term_open_ctty (port, - _hurd_pid, _hurd_pgrp, - &newctty)) + && __term_open_ctty (port, + _hurd_pid, _hurd_pgrp, + &newctty)) /* XXX it is our ctty but the call failed? */ newctty = MACH_PORT_NULL; - __mach_port_deallocate - (__mach_task_self (), (mach_port_t) id); + __mach_port_deallocate (__mach_task_self (), id); } - else - newctty = MACH_PORT_NULL; 0; })); From 538fa939e746975bc556d630c2b5105933be14bb Mon Sep 17 00:00:00 2001 From: Ulrich Drepper Date: Wed, 23 Dec 2009 18:46:03 -0800 Subject: [PATCH 09/14] Fix up ChangeLog. --- ChangeLog | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ChangeLog b/ChangeLog index 07a707b051..0fe85205ee 100644 --- a/ChangeLog +++ b/ChangeLog @@ -7,7 +7,9 @@ 2009-12-21 Ulrich Drepper + [BZ #10992] * sysdeps/unix/sysv/linux/futimens.c: Handle AT_FDCWD. + Patch by Eric Blake . 2009-12-15 Ulrich Drepper From 63de5ef70af0eef3bc6af21463eac8e8efa74afb Mon Sep 17 00:00:00 2001 From: Ulrich Drepper Date: Wed, 23 Dec 2009 19:31:50 -0800 Subject: [PATCH 10/14] Fix isomac test after recent header change. --- ChangeLog | 5 +++++ include/stdlib.h | 6 +++++- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 18a6c16589..4be0d03940 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2009-12-23 Ulrich Drepper + + * include/stdlib.h: Exclude some includes and prototypes if _ISOMAC + is defined. + 2009-12-22 Samuel Thibault * hurd/hurdioctl.c (_hurd_locked_install_cttyid): Set newctty to diff --git a/include/stdlib.h b/include/stdlib.h index f540bece9c..b4799d7d04 100644 --- a/include/stdlib.h +++ b/include/stdlib.h @@ -9,7 +9,9 @@ /* Now define the internal interfaces. */ #ifndef __Need_M_And_C -# include +# ifndef _ISOMAC +# include +# endif __BEGIN_DECLS @@ -78,8 +80,10 @@ extern int __clearenv (void); extern char *__canonicalize_file_name (__const char *__name); extern char *__realpath (__const char *__name, char *__resolved); extern int __ptsname_r (int __fd, char *__buf, size_t __buflen); +# ifndef _ISOMAC extern int __ptsname_internal (int fd, char *buf, size_t buflen, struct stat64 *stp); +# endif extern int __getpt (void); extern int __posix_openpt (int __oflag); From 6f89d2f30f97211431d965993f570ed680747584 Mon Sep 17 00:00:00 2001 From: "H.J. Lu" Date: Wed, 23 Dec 2009 20:22:46 -0800 Subject: [PATCH 11/14] Enable multiarch whenever possible. --- ChangeLog | 6 ++++++ configure | 49 +++++++++++++++++++++++++++++++++++++++++-------- configure.in | 35 +++++++++++++++++++++++++++++++---- 3 files changed, 78 insertions(+), 12 deletions(-) diff --git a/ChangeLog b/ChangeLog index 4be0d03940..17dca3262f 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2009-12-17 H.J. Lu + + * configure.in: Enable multi-arch by default if the assembler + supports gnu_indirect_function symbol type and the architecture + supports it. + 2009-12-23 Ulrich Drepper * include/stdlib.h: Exclude some includes and prototypes if _ISOMAC diff --git a/configure b/configure index ce76653821..49ac30db46 100755 --- a/configure +++ b/configure @@ -724,12 +724,12 @@ INSTALL_PROGRAM sysdeps_add_ons sysnames submachine +multi_arch base_machine add_on_subdirs add_ons libc_cv_nss_crypt experimental_malloc -multi_arch all_warnings force_install bindnow @@ -3801,18 +3801,13 @@ fi if test "${enable_multi_arch+set}" = set; then enableval=$enable_multi_arch; multi_arch=$enableval else - multi_arch=no + multi_arch=default fi -if test x"$multi_arch" = xyes; then - cat >>confdefs.h <<\_ACEOF -#define USE_MULTIARCH 1 -_ACEOF - +if test x"$multi_arch" != xno; then multi_arch_d=/multiarch fi - # Check whether --enable-experimental-malloc was given. if test "${enable_experimental_malloc+set}" = set; then enableval=$enable_experimental_malloc; experimental_malloc=$enableval @@ -4359,6 +4354,44 @@ for b in $base ''; do done done +# If the assembler supports gnu_indirect_function symbol type and the +# architecture supports multi-arch, we enable multi-arch by default. +if test "$multi_arch" = default; then +{ $as_echo "$as_me:$LINENO: checking for assembler gnu_indirect_function symbol type support" >&5 +$as_echo_n "checking for assembler gnu_indirect_function symbol type support... " >&6; } +if test "${libc_cv_asm_gnu_indirect_function+set}" = set; then + $as_echo_n "(cached) " >&6 +else + cat > conftest.s <&5 2>&5; +then + libc_cv_asm_gnu_indirect_function=yes +else + libc_cv_asm_gnu_indirect_function=no +fi +rm -f conftest* +fi +{ $as_echo "$as_me:$LINENO: result: $libc_cv_asm_gnu_indirect_function" >&5 +$as_echo "$libc_cv_asm_gnu_indirect_function" >&6; } + multi_arch=no + if test "$libc_cv_asm_gnu_indirect_function" = yes; then + case $sysnames_add_ons$sysnames in + *"$multi_arch_d"*) + multi_arch=yes + ;; + esac + fi +fi +if test x"$multi_arch" = xyes; then + cat >>confdefs.h <<\_ACEOF +#define USE_MULTIARCH 1 +_ACEOF + +fi + + if test -z "$os_used" && test "$os" != none; then { { $as_echo "$as_me:$LINENO: error: Operating system $os is not supported." >&5 $as_echo "$as_me: error: Operating system $os is not supported." >&2;} diff --git a/configure.in b/configure.in index 182c683e50..8e506026b8 100644 --- a/configure.in +++ b/configure.in @@ -272,12 +272,10 @@ AC_ARG_ENABLE([multi-arch], AC_HELP_STRING([--enable-multi-arch], [enable single DSO with optimizations for multiple architectures]), [multi_arch=$enableval], - [multi_arch=no]) -if test x"$multi_arch" = xyes; then - AC_DEFINE(USE_MULTIARCH) + [multi_arch=default]) +if test x"$multi_arch" != xno; then multi_arch_d=/multiarch fi -AC_SUBST(multi_arch) AC_ARG_ENABLE([experimental-malloc], AC_HELP_STRING([--enable-experimental-malloc], @@ -722,6 +720,35 @@ for b in $base ''; do done done +# If the assembler supports gnu_indirect_function symbol type and the +# architecture supports multi-arch, we enable multi-arch by default. +if test "$multi_arch" = default; then +AC_CACHE_CHECK([for assembler gnu_indirect_function symbol type support], + libc_cv_asm_gnu_indirect_function, [dnl +cat > conftest.s <&AS_MESSAGE_LOG_FD 2>&AS_MESSAGE_LOG_FD; +then + libc_cv_asm_gnu_indirect_function=yes +else + libc_cv_asm_gnu_indirect_function=no +fi +rm -f conftest*]) + multi_arch=no + if test "$libc_cv_asm_gnu_indirect_function" = yes; then + case $sysnames_add_ons$sysnames in + *"$multi_arch_d"*) + multi_arch=yes + ;; + esac + fi +fi +if test x"$multi_arch" = xyes; then + AC_DEFINE(USE_MULTIARCH) +fi +AC_SUBST(multi_arch) + if test -z "$os_used" && test "$os" != none; then AC_MSG_ERROR(Operating system $os is not supported.) fi From 92505456637430272dc01f082b6f9dbb7f7cb60e Mon Sep 17 00:00:00 2001 From: "Maciej W. Rozycki" Date: Thu, 24 Dec 2009 13:22:33 -0800 Subject: [PATCH 12/14] Additional setcontext(), etc. conformance tests. --- ChangeLog | 8 + stdlib/Makefile | 3 +- stdlib/tst-makecontext3.c | 217 ++++++++++++++++++++++++++ stdlib/tst-setcontext.c | 2 +- stdlib/tst-sigcontext.c | 312 ++++++++++++++++++++++++++++++++++++++ 5 files changed, 540 insertions(+), 2 deletions(-) create mode 100644 stdlib/tst-makecontext3.c create mode 100644 stdlib/tst-sigcontext.c diff --git a/ChangeLog b/ChangeLog index 17dca3262f..0c1d2dbd36 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +2009-12-15 Maciej W. Rozycki + + * stdlib/tst-makecontext3.c: New file. + * stdlib/tst-sigcontext.c: file. + * stdlib/Makefile (tests): Add new tests. + + * stdlib/tst-setcontext.c (check_called): Fix a typo. + 2009-12-17 H.J. Lu * configure.in: Enable multi-arch by default if the assembler diff --git a/stdlib/Makefile b/stdlib/Makefile index d361dd8ffa..882302f25c 100644 --- a/stdlib/Makefile +++ b/stdlib/Makefile @@ -70,7 +70,8 @@ tests := tst-strtol tst-strtod testmb testrand testsort testdiv \ test-a64l tst-qsort tst-system testmb2 bug-strtod2 \ tst-atof1 tst-atof2 tst-strtod2 tst-strtod3 tst-rand48-2 \ tst-makecontext tst-strtod4 tst-strtod5 tst-qsort2 \ - tst-makecontext2 tst-strtod6 tst-unsetenv1 + tst-makecontext2 tst-strtod6 tst-unsetenv1 \ + tst-makecontext3 tst-sigcontext include ../Makeconfig diff --git a/stdlib/tst-makecontext3.c b/stdlib/tst-makecontext3.c new file mode 100644 index 0000000000..f127c6a579 --- /dev/null +++ b/stdlib/tst-makecontext3.c @@ -0,0 +1,217 @@ +/* Copyright (C) 2001,2002,2004,2006,2009 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 + 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, 51 Franklin Street - Fifth Floor, Boston, MA + 02110-1301, USA. */ + +#include +#include +#include +#include +#include +#include + +static ucontext_t ctx[3]; + +static int was_in_f1; +static int was_in_f2; + +static char st2[32768]; + +static volatile int flag; + +static void +f1 (int a00, int a01, int a02, int a03, int a04, int a05, int a06, int a07, + int a08, int a09, int a10, int a11, int a12, int a13, int a14, int a15, + int a16, int a17, int a18, int a19, int a20, int a21, int a22, int a23, + int a24, int a25, int a26, int a27, int a28, int a29, int a30, int a31, + int a32) +{ + printf ("start f1(a00=%08x,a01=%08x,a02=%08x,a03=%08x,\n" + " a04=%08x,a05=%08x,a06=%08x,a07=%08x,\n" + " a08=%08x,a09=%08x,a10=%08x,a11=%08x,\n" + " a12=%08x,a13=%08x,a14=%08x,a15=%08x,\n" + " a16=%08x,a17=%08x,a18=%08x,a19=%08x,\n" + " a20=%08x,a21=%08x,a22=%08x,a23=%08x,\n" + " a24=%08x,a25=%08x,a26=%08x,a27=%08x,\n" + " a28=%08x,a29=%08x,a30=%08x,a31=%08x,\n" + " a32=%08x) [%d]\n", + a00, a01, a02, a03, a04, a05, a06, a07, + a08, a09, a10, a11, a12, a13, a14, a15, + a16, a17, a18, a19, a20, a21, a22, a23, + a24, a25, a26, a27, a28, a29, a30, a31, + a32, flag); + + if (a00 != (0x00000001 << flag) || a01 != (0x00000004 << flag) + || a02 != (0x00000012 << flag) || a03 != (0x00000048 << flag) + || a04 != (0x00000123 << flag) || a05 != (0x0000048d << flag) + || a06 != (0x00001234 << flag) || a07 != (0x000048d1 << flag) + || a08 != (0x00012345 << flag) || a09 != (0x00048d15 << flag) + || a10 != (0x00123456 << flag) || a11 != (0x0048d159 << flag) + || a12 != (0x01234567 << flag) || a13 != (0x048d159e << flag) + || a14 != (0x12345678 << flag) || a15 != (0x48d159e2 << flag) + || a16 != (0x23456789 << flag) || a17 != (0x8d159e26 << flag) + || a18 != (0x3456789a << flag) || a19 != (0xd159e26a << flag) + || a20 != (0x456789ab << flag) || a21 != (0x159e26af << flag) + || a22 != (0x56789abc << flag) || a23 != (0x59e26af3 << flag) + || a24 != (0x6789abcd << flag) || a25 != (0x9e26af37 << flag) + || a26 != (0x789abcde << flag) || a27 != (0xe26af37b << flag) + || a28 != (0x89abcdef << flag) || a29 != (0x26af37bc << flag) + || a30 != (0x9abcdef0 << flag) || a31 != (0x6af37bc3 << flag) + || a32 != (0xabcdef0f << flag)) + { + puts ("arg mismatch"); + exit (-1); + } + + if (flag && swapcontext (&ctx[1], &ctx[2]) != 0) + { + printf ("%s: swapcontext: %m\n", __FUNCTION__); + exit (1); + } + printf ("finish f1 [%d]\n", flag); + flag++; + was_in_f1++; +} + +static void +f2 (void) +{ + puts ("start f2"); + if (swapcontext (&ctx[2], &ctx[1]) != 0) + { + printf ("%s: swapcontext: %m\n", __FUNCTION__); + exit (1); + } + puts ("finish f2"); + was_in_f2 = 1; +} + +volatile int global; + + +static int back_in_main; + + +static void +check_called (void) +{ + if (back_in_main == 0) + { + puts ("program did not reach main again"); + _exit (1); + } +} + + +int +main (void) +{ + atexit (check_called); + + char st1[32768]; + + puts ("making contexts"); + if (getcontext (&ctx[0]) != 0) + { + if (errno == ENOSYS) + { + back_in_main = 1; + exit (0); + } + + printf ("%s: getcontext: %m\n", __FUNCTION__); + exit (1); + } + + ctx[1] = ctx[0]; + ctx[1].uc_stack.ss_sp = st1; + ctx[1].uc_stack.ss_size = sizeof st1; + ctx[1].uc_link = &ctx[0]; + { + ucontext_t tempctx = ctx[1]; + makecontext (&ctx[1], (void (*) (void)) f1, 33, + 0x00000001 << flag, 0x00000004 << flag, + 0x00000012 << flag, 0x00000048 << flag, + 0x00000123 << flag, 0x0000048d << flag, + 0x00001234 << flag, 0x000048d1 << flag, + 0x00012345 << flag, 0x00048d15 << flag, + 0x00123456 << flag, 0x0048d159 << flag, + 0x01234567 << flag, 0x048d159e << flag, + 0x12345678 << flag, 0x48d159e2 << flag, + 0x23456789 << flag, 0x8d159e26 << flag, + 0x3456789a << flag, 0xd159e26a << flag, + 0x456789ab << flag, 0x159e26af << flag, + 0x56789abc << flag, 0x59e26af3 << flag, + 0x6789abcd << flag, 0x9e26af37 << flag, + 0x789abcde << flag, 0xe26af37b << flag, + 0x89abcdef << flag, 0x26af37bc << flag, + 0x9abcdef0 << flag, 0x6af37bc3 << flag, + 0xabcdef0f << flag); + + /* Without this check, a stub makecontext can make us spin forever. */ + if (memcmp (&tempctx, &ctx[1], sizeof ctx[1]) == 0) + { + puts ("makecontext was a no-op, presuming not implemented"); + return 0; + } + } + + /* Play some tricks with this context. */ + if (++global == 1) + if (setcontext (&ctx[1]) != 0) + { + printf ("%s: setcontext: %m\n", __FUNCTION__); + exit (1); + } + if (global != 2) + { + printf ("%s: 'global' not incremented twice\n", __FUNCTION__); + exit (1); + } + + if (getcontext (&ctx[2]) != 0) + { + printf ("%s: second getcontext: %m\n", __FUNCTION__); + exit (1); + } + ctx[2].uc_stack.ss_sp = st2; + ctx[2].uc_stack.ss_size = sizeof st2; + ctx[2].uc_link = &ctx[1]; + makecontext (&ctx[2], f2, 0); + + puts ("swapping contexts"); + if (swapcontext (&ctx[0], &ctx[2]) != 0) + { + printf ("%s: swapcontext: %m\n", __FUNCTION__); + exit (1); + } + puts ("back at main program"); + back_in_main = 1; + + if (was_in_f1 < 2) + { + puts ("didn't reach f1 twice"); + exit (1); + } + if (was_in_f2 == 0) + { + puts ("didn't reach f2"); + exit (1); + } + + puts ("test succeeded"); + return 0; +} diff --git a/stdlib/tst-setcontext.c b/stdlib/tst-setcontext.c index 51296f74ab..9a6d79ba9d 100644 --- a/stdlib/tst-setcontext.c +++ b/stdlib/tst-setcontext.c @@ -133,7 +133,7 @@ check_called (void) { if (back_in_main == 0) { - puts ("program did no reach main again"); + puts ("program did not reach main again"); _exit (1); } } diff --git a/stdlib/tst-sigcontext.c b/stdlib/tst-sigcontext.c new file mode 100644 index 0000000000..45b1a06a28 --- /dev/null +++ b/stdlib/tst-sigcontext.c @@ -0,0 +1,312 @@ +/* Copyright (C) 2009 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Maciej W. Rozycki . + + 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, 51 Franklin Street - Fifth Floor, Boston, MA + 02110-1301, USA. */ + +#include +#include +#include +#include +#include +#include +#include +#include + +static volatile ucontext_t ctx[3]; +static volatile int flags[3]; +static volatile int oflag; +static volatile int flag; + +static volatile int sig_errno_set; +static volatile int sig_errno; +static volatile int sig_ready; + +static int was_in_f1; +static int was_in_f2; + +static char st2[32768]; + +static long long int max; +static volatile long long int count; + +/* These have to be run with the caller's frame. */ +static inline int sig_getcontext (int) __attribute__ ((always_inline)); +static inline int sig_swapcontext (int, int) __attribute__ ((always_inline)); + +static void +sig_gethandler (int signo, siginfo_t *info, void *context) +{ + ucontext_t *ucp = context; + + if (! sig_ready) + { + alarm (1); + return; + } + + ctx[flag] = *ucp; + flags[flag] = 1; + + sig_errno_set = 1; + sig_errno = 0; +} + +static void +sig_swaphandler (int signo, siginfo_t *info, void *context) +{ + ucontext_t *oucp = context; + ucontext_t *ucp = (ucontext_t *) (ctx + flag); + + if (! sig_ready) + { + alarm (1); + return; + } + + ctx[oflag] = *oucp; + flags[oflag] = 1; + + sig_errno_set = 1; + sig_errno = setcontext (ucp); +} + +static int +sig_getcontext (int uci) +{ + struct sigaction sa; + + sigemptyset (&sa.sa_mask); + sa.sa_flags = SA_SIGINFO; + sa.sa_sigaction = sig_gethandler; + if (sigaction (SIGALRM, &sa, NULL) < 0) + { + printf ("%s: sigaction ALRM failed: %m\n", __FUNCTION__); + exit (1); + } + + flag = uci; + sig_errno_set = 0; + sig_ready = 0; + alarm (1); + + /* Need to get the signal in this frame. */ + sig_ready = 1; + for (count = max; count > 0; count--) + if (sig_errno_set) + break; + + if (! sig_errno_set) + { + printf ("%s: ALRM signal not received\n", __FUNCTION__); + exit (1); + } + + return 0; +} + +static int +sig_swapcontext (int ouci, int uci) +{ + struct sigaction sa; + + sigemptyset (&sa.sa_mask); + sa.sa_flags = SA_SIGINFO; + sa.sa_sigaction = sig_swaphandler; + if (sigaction (SIGALRM, &sa, NULL) < 0) + { + printf ("%s: sigaction ALRM failed: %m\n", __FUNCTION__); + exit (1); + } + + flag = uci; + oflag = ouci; + sig_errno_set = 0; + sig_ready = 0; + alarm (1); + + /* Need to get the signal in this frame. */ + sig_ready = 1; + for (count = max; count > 0; count--) + if (sig_errno_set) + break; + + if (! sig_errno_set) + { + printf ("%s: ALRM signal not received\n", __FUNCTION__); + exit (1); + } + + return sig_errno; +} + + +static void +f1 (int a0, int a1, int a2, int a3) +{ + int status; + + printf ("start f1(a0=%x,a1=%x,a2=%x,a3=%x)\n", a0, a1, a2, a3); + + if (a0 != 1 || a1 != 2 || a2 != 3 || a3 != -4) + { + puts ("arg mismatch"); + exit (-1); + } + + status = sig_swapcontext (1, 2); + if (status != 0) + { + printf ("%s: swapping contexts failed: %s\n", + __FUNCTION__, strerror (status)); + exit (1); + } + puts ("finish f1"); + was_in_f1 = 1; +} + +static void +f2 (void) +{ + int status; + + puts ("start f2"); + + status = sig_swapcontext (2, 1); + if (status != 0) + { + printf ("%s: swapping contexts failed: %s\n", + __FUNCTION__, strerror (status)); + exit (1); + } + puts ("finish f2"); + was_in_f2 = 1; +} + + +static int back_in_main; + +static void +check_called (void) +{ + if (back_in_main == 0) + { + printf ("%s: program did not reach main again", __FUNCTION__); + _exit (1); + } +} + + +volatile int global; + +int +main (void) +{ + char st1[32768]; + time_t t0, t1; + int status; + + atexit (check_called); + + puts ("calibrating delay loop"); + for (max = 0x10000; max < LLONG_MAX / 2; max *= 2) + { + t0 = time (NULL); + for (count = max; count > 0; count--); + t1 = time (NULL); + if (difftime (t1, t0) > 10.0) + break; + } + + puts ("making contexts"); + + sig_getcontext (1); + if (! flags[1]) + { + printf ("%s: context not retrieved\n", __FUNCTION__); + exit (1); + } + + /* Play some tricks with this context. */ + if (++global == 1) + if (setcontext ((ucontext_t *) &ctx[1]) != 0) + { + if (errno == ENOSYS) + { + back_in_main = 1; + exit (0); + } + printf ("%s: setcontext: %m\n", __FUNCTION__); + exit (1); + } + if (global != 2) + { + printf ("%s: 'global' not incremented twice\n", __FUNCTION__); + exit (1); + } + + ctx[1].uc_stack.ss_sp = st1; + ctx[1].uc_stack.ss_size = sizeof st1; + ctx[1].uc_link = (ucontext_t *) &ctx[0]; + { + ucontext_t tempctx = ctx[1]; + makecontext ((ucontext_t *) &ctx[1], (void (*) (void)) f1, 4, 1, 2, 3, -4); + + /* Without this check, a stub makecontext can make us spin forever. */ + if (memcmp (&tempctx, (void *) &ctx[1], sizeof ctx[1]) == 0) + { + puts ("makecontext was a no-op, presuming not implemented"); + return 0; + } + } + + sig_getcontext (2); + if (! flags[2]) + { + printf ("%s: second context not retrieved\n", __FUNCTION__); + exit (1); + } + + ctx[2].uc_stack.ss_sp = st2; + ctx[2].uc_stack.ss_size = sizeof st2; + ctx[2].uc_link = (ucontext_t *) &ctx[1]; + makecontext ((ucontext_t *) &ctx[2], f2, 0); + + puts ("swapping contexts"); + status = sig_swapcontext (0, 2); + if (status != 0) + { + printf ("%s: swapping contexts failed: %s\n", + __FUNCTION__, strerror (status)); + exit (1); + } + puts ("back at main program"); + back_in_main = 1; + + if (was_in_f1 == 0) + { + puts ("didn't reach f1"); + exit (1); + } + if (was_in_f2 == 0) + { + puts ("didn't reach f2"); + exit (1); + } + + puts ("test succeeded"); + return 0; +} From a87cd2894cbd79b05972e168d0bdb51967dd9574 Mon Sep 17 00:00:00 2001 From: Ulrich Drepper Date: Thu, 24 Dec 2009 13:34:05 -0800 Subject: [PATCH 13/14] Remove tst-sigcontext test. It's bogus in many places. --- ChangeLog | 1 + stdlib/Makefile | 2 +- stdlib/tst-sigcontext.c | 312 ---------------------------------------- 3 files changed, 2 insertions(+), 313 deletions(-) delete mode 100644 stdlib/tst-sigcontext.c diff --git a/ChangeLog b/ChangeLog index 0c1d2dbd36..bdd41da14a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,6 @@ 2009-12-15 Maciej W. Rozycki + [BZ #11115] * stdlib/tst-makecontext3.c: New file. * stdlib/tst-sigcontext.c: file. * stdlib/Makefile (tests): Add new tests. diff --git a/stdlib/Makefile b/stdlib/Makefile index 882302f25c..bb0661af3b 100644 --- a/stdlib/Makefile +++ b/stdlib/Makefile @@ -71,7 +71,7 @@ tests := tst-strtol tst-strtod testmb testrand testsort testdiv \ tst-atof1 tst-atof2 tst-strtod2 tst-strtod3 tst-rand48-2 \ tst-makecontext tst-strtod4 tst-strtod5 tst-qsort2 \ tst-makecontext2 tst-strtod6 tst-unsetenv1 \ - tst-makecontext3 tst-sigcontext + tst-makecontext3 include ../Makeconfig diff --git a/stdlib/tst-sigcontext.c b/stdlib/tst-sigcontext.c deleted file mode 100644 index 45b1a06a28..0000000000 --- a/stdlib/tst-sigcontext.c +++ /dev/null @@ -1,312 +0,0 @@ -/* Copyright (C) 2009 Free Software Foundation, Inc. - This file is part of the GNU C Library. - Contributed by Maciej W. Rozycki . - - 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, 51 Franklin Street - Fifth Floor, Boston, MA - 02110-1301, USA. */ - -#include -#include -#include -#include -#include -#include -#include -#include - -static volatile ucontext_t ctx[3]; -static volatile int flags[3]; -static volatile int oflag; -static volatile int flag; - -static volatile int sig_errno_set; -static volatile int sig_errno; -static volatile int sig_ready; - -static int was_in_f1; -static int was_in_f2; - -static char st2[32768]; - -static long long int max; -static volatile long long int count; - -/* These have to be run with the caller's frame. */ -static inline int sig_getcontext (int) __attribute__ ((always_inline)); -static inline int sig_swapcontext (int, int) __attribute__ ((always_inline)); - -static void -sig_gethandler (int signo, siginfo_t *info, void *context) -{ - ucontext_t *ucp = context; - - if (! sig_ready) - { - alarm (1); - return; - } - - ctx[flag] = *ucp; - flags[flag] = 1; - - sig_errno_set = 1; - sig_errno = 0; -} - -static void -sig_swaphandler (int signo, siginfo_t *info, void *context) -{ - ucontext_t *oucp = context; - ucontext_t *ucp = (ucontext_t *) (ctx + flag); - - if (! sig_ready) - { - alarm (1); - return; - } - - ctx[oflag] = *oucp; - flags[oflag] = 1; - - sig_errno_set = 1; - sig_errno = setcontext (ucp); -} - -static int -sig_getcontext (int uci) -{ - struct sigaction sa; - - sigemptyset (&sa.sa_mask); - sa.sa_flags = SA_SIGINFO; - sa.sa_sigaction = sig_gethandler; - if (sigaction (SIGALRM, &sa, NULL) < 0) - { - printf ("%s: sigaction ALRM failed: %m\n", __FUNCTION__); - exit (1); - } - - flag = uci; - sig_errno_set = 0; - sig_ready = 0; - alarm (1); - - /* Need to get the signal in this frame. */ - sig_ready = 1; - for (count = max; count > 0; count--) - if (sig_errno_set) - break; - - if (! sig_errno_set) - { - printf ("%s: ALRM signal not received\n", __FUNCTION__); - exit (1); - } - - return 0; -} - -static int -sig_swapcontext (int ouci, int uci) -{ - struct sigaction sa; - - sigemptyset (&sa.sa_mask); - sa.sa_flags = SA_SIGINFO; - sa.sa_sigaction = sig_swaphandler; - if (sigaction (SIGALRM, &sa, NULL) < 0) - { - printf ("%s: sigaction ALRM failed: %m\n", __FUNCTION__); - exit (1); - } - - flag = uci; - oflag = ouci; - sig_errno_set = 0; - sig_ready = 0; - alarm (1); - - /* Need to get the signal in this frame. */ - sig_ready = 1; - for (count = max; count > 0; count--) - if (sig_errno_set) - break; - - if (! sig_errno_set) - { - printf ("%s: ALRM signal not received\n", __FUNCTION__); - exit (1); - } - - return sig_errno; -} - - -static void -f1 (int a0, int a1, int a2, int a3) -{ - int status; - - printf ("start f1(a0=%x,a1=%x,a2=%x,a3=%x)\n", a0, a1, a2, a3); - - if (a0 != 1 || a1 != 2 || a2 != 3 || a3 != -4) - { - puts ("arg mismatch"); - exit (-1); - } - - status = sig_swapcontext (1, 2); - if (status != 0) - { - printf ("%s: swapping contexts failed: %s\n", - __FUNCTION__, strerror (status)); - exit (1); - } - puts ("finish f1"); - was_in_f1 = 1; -} - -static void -f2 (void) -{ - int status; - - puts ("start f2"); - - status = sig_swapcontext (2, 1); - if (status != 0) - { - printf ("%s: swapping contexts failed: %s\n", - __FUNCTION__, strerror (status)); - exit (1); - } - puts ("finish f2"); - was_in_f2 = 1; -} - - -static int back_in_main; - -static void -check_called (void) -{ - if (back_in_main == 0) - { - printf ("%s: program did not reach main again", __FUNCTION__); - _exit (1); - } -} - - -volatile int global; - -int -main (void) -{ - char st1[32768]; - time_t t0, t1; - int status; - - atexit (check_called); - - puts ("calibrating delay loop"); - for (max = 0x10000; max < LLONG_MAX / 2; max *= 2) - { - t0 = time (NULL); - for (count = max; count > 0; count--); - t1 = time (NULL); - if (difftime (t1, t0) > 10.0) - break; - } - - puts ("making contexts"); - - sig_getcontext (1); - if (! flags[1]) - { - printf ("%s: context not retrieved\n", __FUNCTION__); - exit (1); - } - - /* Play some tricks with this context. */ - if (++global == 1) - if (setcontext ((ucontext_t *) &ctx[1]) != 0) - { - if (errno == ENOSYS) - { - back_in_main = 1; - exit (0); - } - printf ("%s: setcontext: %m\n", __FUNCTION__); - exit (1); - } - if (global != 2) - { - printf ("%s: 'global' not incremented twice\n", __FUNCTION__); - exit (1); - } - - ctx[1].uc_stack.ss_sp = st1; - ctx[1].uc_stack.ss_size = sizeof st1; - ctx[1].uc_link = (ucontext_t *) &ctx[0]; - { - ucontext_t tempctx = ctx[1]; - makecontext ((ucontext_t *) &ctx[1], (void (*) (void)) f1, 4, 1, 2, 3, -4); - - /* Without this check, a stub makecontext can make us spin forever. */ - if (memcmp (&tempctx, (void *) &ctx[1], sizeof ctx[1]) == 0) - { - puts ("makecontext was a no-op, presuming not implemented"); - return 0; - } - } - - sig_getcontext (2); - if (! flags[2]) - { - printf ("%s: second context not retrieved\n", __FUNCTION__); - exit (1); - } - - ctx[2].uc_stack.ss_sp = st2; - ctx[2].uc_stack.ss_size = sizeof st2; - ctx[2].uc_link = (ucontext_t *) &ctx[1]; - makecontext ((ucontext_t *) &ctx[2], f2, 0); - - puts ("swapping contexts"); - status = sig_swapcontext (0, 2); - if (status != 0) - { - printf ("%s: swapping contexts failed: %s\n", - __FUNCTION__, strerror (status)); - exit (1); - } - puts ("back at main program"); - back_in_main = 1; - - if (was_in_f1 == 0) - { - puts ("didn't reach f1"); - exit (1); - } - if (was_in_f2 == 0) - { - puts ("didn't reach f2"); - exit (1); - } - - puts ("test succeeded"); - return 0; -} From c10f8866e5b673b6f41dcb14c8ea319f5e545b1a Mon Sep 17 00:00:00 2001 From: Ulrich Drepper Date: Fri, 25 Dec 2009 09:49:07 -0800 Subject: [PATCH 14/14] Fix up ChangeLog. --- ChangeLog | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index bdd41da14a..9b1d78bca1 100644 --- a/ChangeLog +++ b/ChangeLog @@ -2,8 +2,7 @@ [BZ #11115] * stdlib/tst-makecontext3.c: New file. - * stdlib/tst-sigcontext.c: file. - * stdlib/Makefile (tests): Add new tests. + * stdlib/Makefile (tests): Add new test. * stdlib/tst-setcontext.c (check_called): Fix a typo.