[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[commits] r9667 - in /fsf/trunk/libc: ./ elf/ include/ manual/ nptl/ nptl/sysdeps/unix/sysv/linux/i386/i486/ posix/ sysdeps/generic/ s...



Author: eglibc
Date: Sat Jan 16 00:03:28 2010
New Revision: 9667

Log:
Import glibc-mainline for 2010-01-16

Modified:
    fsf/trunk/libc/ChangeLog
    fsf/trunk/libc/elf/dl-open.c
    fsf/trunk/libc/elf/dl-sysdep.c
    fsf/trunk/libc/elf/elf.h
    fsf/trunk/libc/elf/rtld.c
    fsf/trunk/libc/include/features.h
    fsf/trunk/libc/manual/install.texi
    fsf/trunk/libc/nptl/ChangeLog
    fsf/trunk/libc/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_cond_timedwait.S
    fsf/trunk/libc/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_cond_wait.S
    fsf/trunk/libc/posix/regcomp.c
    fsf/trunk/libc/posix/regex_internal.c
    fsf/trunk/libc/posix/regexec.c
    fsf/trunk/libc/sysdeps/generic/ldsodefs.h
    fsf/trunk/libc/sysdeps/s390/s390-32/dl-machine.h
    fsf/trunk/libc/sysdeps/s390/s390-32/elf/start.S

Modified: fsf/trunk/libc/ChangeLog
==============================================================================
--- fsf/trunk/libc/ChangeLog (original)
+++ fsf/trunk/libc/ChangeLog Sat Jan 16 00:03:28 2010
@@ -1,3 +1,32 @@
+2010-01-15  Ulrich Drepper  <drepper@xxxxxxxxxx>
+
+	* posix/regcomp.c: Fix a few more cases of ignored return values.
+	* posix/regex_internal.c: Likewise.
+	* posix/regexec.c: Likewise.
+
+	* include/features.h: _XOPEN_SOURCE_EXTENDED is not defined to be
+	used without _XOPEN_SOURCE.  Don't base any decisions on this macro
+	if _XOPEN_SOURCE is not defined as well.
+
+2010-01-15  Andreas Krebbel  <Andreas.Krebbel@xxxxxxxxxx>
+
+	* sysdeps/s390/s390-32/elf/start.S (_start): Added check for the
+	high gprs kernel facility.
+	* sysdeps/s390/s390-32/dl-machine.h (elf_machine_matches_host):
+	Added high gprs check for DSOs.
+	* elf/elf.h (EF_S390_HIGH_GPRS): Added macro definition for the
+	new elf header flag.
+
+2010-01-13  Andreas Krebbel  <Andreas.Krebbel@xxxxxxxxxx>
+
+	* elf/dl-sysdep.c (_dl_sysdep_start): Added the auxv parameter to
+	dl_main.
+	* elf/dl-open.c (_dl_sysdep_start): Likewise..
+	* sysdeps/generic/ldsodefs.h (_dl_sysdep_start): Likewise.
+	* elf/rtld.c (dl_main): Added new parameter auxv.  Adjust the
+	AT_PHDR, AT_PHNUM and AT_ENTRY fields if the ld.so is directly
+	started.
+
 2010-01-14  Ulrich Drepper  <drepper@xxxxxxxxxx>
 
 	[BZ #11027]

Modified: fsf/trunk/libc/elf/dl-open.c
==============================================================================
--- fsf/trunk/libc/elf/dl-open.c (original)
+++ fsf/trunk/libc/elf/dl-open.c Sat Jan 16 00:03:28 2010
@@ -1,5 +1,5 @@
 /* Load a shared object at runtime, relocate it, and run its initializer.
-   Copyright (C) 1996-2007, 2009 Free Software Foundation, Inc.
+   Copyright (C) 1996-2007, 2009, 2010 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
@@ -40,7 +40,8 @@
 extern ElfW(Addr) _dl_sysdep_start (void **start_argptr,
 				    void (*dl_main) (const ElfW(Phdr) *phdr,
 						     ElfW(Word) phnum,
-						     ElfW(Addr) *user_entry));
+						     ElfW(Addr) *user_entry,
+						     ElfW(auxv_t) *auxv));
 weak_extern (BP_SYM (_dl_sysdep_start))
 
 extern int __libc_multiple_libcs;	/* Defined in init-first.c.  */
@@ -346,8 +347,8 @@
 	    {
 	      /* If this here is the shared object which we want to profile
 		 make sure the profile is started.  We can find out whether
-	         this is necessary or not by observing the `_dl_profile_map'
-	         variable.  If was NULL but is not NULL afterwars we must
+		 this is necessary or not by observing the `_dl_profile_map'
+		 variable.  If was NULL but is not NULL afterwars we must
 		 start the profiling.  */
 	      struct link_map *old_profile_map = GL(dl_profile_map);
 

Modified: fsf/trunk/libc/elf/dl-sysdep.c
==============================================================================
--- fsf/trunk/libc/elf/dl-sysdep.c (original)
+++ fsf/trunk/libc/elf/dl-sysdep.c Sat Jan 16 00:03:28 2010
@@ -85,7 +85,7 @@
 ElfW(Addr)
 _dl_sysdep_start (void **start_argptr,
 		  void (*dl_main) (const ElfW(Phdr) *phdr, ElfW(Word) phnum,
-				   ElfW(Addr) *user_entry))
+				   ElfW(Addr) *user_entry, ElfW(auxv_t) *auxv))
 {
   const ElfW(Phdr) *phdr = NULL;
   ElfW(Word) phnum = 0;
@@ -241,7 +241,7 @@
   if (__builtin_expect (INTUSE(__libc_enable_secure), 0))
     __libc_check_standard_fds ();
 
-  (*dl_main) (phdr, phnum, &user_entry);
+  (*dl_main) (phdr, phnum, &user_entry, _dl_auxv);
   return user_entry;
 }
 
@@ -511,9 +511,9 @@
   /* Fill in the information.  This follows the following scheme
      (indeces from TEMP for four strings):
 	entry #0: 0, 1, 2, 3	binary: 1111
-	      #1: 0, 1, 3	        1101
-	      #2: 0, 2, 3	        1011
-	      #3: 0, 3		        1001
+	      #1: 0, 1, 3		1101
+	      #2: 0, 2, 3		1011
+	      #3: 0, 3			1001
      This allows the representation of all possible combinations of
      capability names in the string.  First generate the strings.  */
   result[1].str = result[0].str = cp = (char *) (result + *sz);

Modified: fsf/trunk/libc/elf/elf.h
==============================================================================
--- fsf/trunk/libc/elf/elf.h (original)
+++ fsf/trunk/libc/elf/elf.h Sat Jan 16 00:03:28 2010
@@ -2493,6 +2493,12 @@
 /* Keep this the last entry.  */
 #define	R_SH_NUM		256
 
+/* S/390 specific definitions.  */
+
+/* Valid values for the e_flags field.  */
+
+#define EF_S390_HIGH_GPRS    0x00000001  /* High GPRs kernel facility needed.  */
+
 /* Additional s390 relocs */
 
 #define R_390_NONE		0	/* No reloc.  */

Modified: fsf/trunk/libc/elf/rtld.c
==============================================================================
--- fsf/trunk/libc/elf/rtld.c (original)
+++ fsf/trunk/libc/elf/rtld.c Sat Jan 16 00:03:28 2010
@@ -1,5 +1,5 @@
 /* Run time dynamic linker.
-   Copyright (C) 1995-2006, 2007, 2008, 2009 Free Software Foundation, Inc.
+   Copyright (C) 1995-2006, 2007, 2008, 2009, 2010 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
@@ -182,7 +182,7 @@
 
 
 static void dl_main (const ElfW(Phdr) *phdr, ElfW(Word) phnum,
-		     ElfW(Addr) *user_entry);
+		     ElfW(Addr) *user_entry, ElfW(auxv_t) *auxv);
 
 /* These two variables cannot be moved into .data.rel.ro.  */
 static struct libname_list _dl_rtld_libname;
@@ -882,7 +882,8 @@
 static void
 dl_main (const ElfW(Phdr) *phdr,
 	 ElfW(Word) phnum,
-	 ElfW(Addr) *user_entry)
+	 ElfW(Addr) *user_entry,
+	 ElfW(auxv_t) *auxv)
 {
   const ElfW(Phdr) *ph;
   enum mode mode;
@@ -927,6 +928,8 @@
 
   if (*user_entry == (ElfW(Addr)) ENTRY_POINT)
     {
+      ElfW(auxv_t) *av;
+
       /* Ho ho.  We are not the program interpreter!  We are the program
 	 itself!  This means someone ran ld.so as a command.  Well, that
 	 might be convenient to do sometimes.  We support it by
@@ -1013,11 +1016,11 @@
 \n\
   --list                list all dependencies and how they are resolved\n\
   --verify              verify that given object really is a dynamically linked\n\
-                        object we can handle\n\
+			object we can handle\n\
   --library-path PATH   use given PATH instead of content of the environment\n\
-                        variable LD_LIBRARY_PATH\n\
+			variable LD_LIBRARY_PATH\n\
   --inhibit-rpath LIST  ignore RUNPATH and RPATH information in object names\n\
-                        in LIST\n\
+			in LIST\n\
   --audit LIST          use objects named in LIST as auditors\n");
 
       ++_dl_skip_args;
@@ -1082,6 +1085,22 @@
 	 makes sense to free the old string first.  */
       main_map->l_name = (char *) "";
       *user_entry = main_map->l_entry;
+
+      /* Adjust the on-stack auxiliary vector so that it looks like the
+	 binary was executed directly.  */
+      for (av = auxv; av->a_type != AT_NULL; av++)
+	switch (av->a_type)
+	  {
+	  case AT_PHDR:
+	    av->a_un.a_val = phdr;
+	    break;
+	  case AT_PHNUM:
+	    av->a_un.a_val = phnum;
+	    break;
+	  case AT_ENTRY:
+	    av->a_un.a_val = *user_entry;
+	    break;
+	  }
     }
   else
     {
@@ -2013,7 +2032,7 @@
 		  _dl_relocate_object (&GL(dl_rtld_map),
 				       main_map->l_scope, 0, 0);
 		}
-            }
+	    }
 #define VERNEEDTAG (DT_NUM + DT_THISPROCNUM + DT_VERSIONTAGIDX (DT_VERNEED))
 	  if (version_info)
 	    {
@@ -2682,10 +2701,10 @@
       while (*nextp != '\0');
 
       if (__access ("/etc/suid-debug", F_OK) != 0)
-        {
+	{
 	  unsetenv ("MALLOC_CHECK_");
 	  GLRO(dl_debug_mask) = 0;
-        }
+	}
 
       if (mode != normal)
 	_exit (5);
@@ -2752,7 +2771,7 @@
 	}
       *wp = '\0';
       _dl_debug_printf ("\
-            time needed for relocation: %s (%s%%)\n", buf, pbuf);
+	    time needed for relocation: %s (%s%%)\n", buf, pbuf);
     }
 #endif
 
@@ -2815,7 +2834,7 @@
 	}
       *wp = '\0';
       _dl_debug_printf ("\
-           time needed to load objects: %s (%s%%)\n",
+	   time needed to load objects: %s (%s%%)\n",
 				buf, pbuf);
     }
 #endif

Modified: fsf/trunk/libc/include/features.h
==============================================================================
--- fsf/trunk/libc/include/features.h (original)
+++ fsf/trunk/libc/include/features.h Sat Jan 16 00:03:28 2010
@@ -146,8 +146,7 @@
 /* If _BSD_SOURCE was defined by the user, favor BSD over POSIX.  */
 #if defined _BSD_SOURCE && \
     !(defined _POSIX_SOURCE || defined _POSIX_C_SOURCE || \
-      defined _XOPEN_SOURCE || defined _XOPEN_SOURCE_EXTENDED || \
-      defined _GNU_SOURCE || defined _SVID_SOURCE)
+      defined _XOPEN_SOURCE || defined _GNU_SOURCE || defined _SVID_SOURCE)
 # define __FAVOR_BSD	1
 #endif
 
@@ -179,8 +178,7 @@
    define _BSD_SOURCE and _SVID_SOURCE.  */
 #if (!defined __STRICT_ANSI__ && !defined _ISOC99_SOURCE && \
      !defined _POSIX_SOURCE && !defined _POSIX_C_SOURCE && \
-     !defined _XOPEN_SOURCE && !defined _XOPEN_SOURCE_EXTENDED && \
-     !defined _BSD_SOURCE && !defined _SVID_SOURCE)
+     !defined _XOPEN_SOURCE && !defined _BSD_SOURCE && !defined _SVID_SOURCE)
 # define _BSD_SOURCE	1
 # define _SVID_SOURCE	1
 #endif

Modified: fsf/trunk/libc/manual/install.texi
==============================================================================
--- fsf/trunk/libc/manual/install.texi (original)
+++ fsf/trunk/libc/manual/install.texi Sat Jan 16 00:03:28 2010
@@ -330,16 +330,15 @@
 @item
 GCC 3.4 or newer, GCC 4.1 recommended
 
-The GNU C library can only be compiled with the GNU C compiler family.
-For the 2.3 releases, GCC 3.2 or higher is required; GCC 3.4 is the
-compiler we advise to use for 2.3 versions.
-For the 2.4 release, GCC 3.4 or higher is required; as of this
-writing, GCC 4.1 is the compiler we advise to use for current versions.
+For the 2.4 release or later, GCC 3.4 or higher is required; as of this
+writing, GCC 4.4 is the compiler we advise to use for current versions.
 On certain machines including @code{powerpc64}, compilers prior to GCC
 4.0 have bugs that prevent them compiling the C library code in the
 2.4 release.  On other machines, GCC 4.1 is required to build the C
 library with support for the correct @code{long double} type format;
-these include @code{powerpc} (32 bit), @code{s390} and @code{s390x}.
+these include @code{powerpc} (32 bit), @code{s390} and @code{s390x}.  For
+other architectures special compiler-provided headers are needed
+(like @file{cpuid.h} on x86) which only come with later compiler versions.
 
 You can use whatever compiler you like to compile programs that use GNU
 libc, but be aware that both GCC 2.7 and 2.8 have bugs in their

Modified: fsf/trunk/libc/nptl/ChangeLog
==============================================================================
--- fsf/trunk/libc/nptl/ChangeLog (original)
+++ fsf/trunk/libc/nptl/ChangeLog Sat Jan 16 00:03:28 2010
@@ -1,3 +1,16 @@
+2010-01-15  Ulrich Drepper  <drepper@xxxxxxxxxx>
+
+	* sysdeps/unix/sysv/linux/i386/i486/pthread_cond_timedwait.S:
+	Fix unwind info.
+	* sysdeps/unix/sysv/linux/i386/i486/pthread_cond_wait.S: Likewise.
+
+2010-01-15  Michal Schmidt  <mschmidt@xxxxxxxxxx>
+
+	* sysdeps/unix/sysv/linux/i386/i486/pthread_cond_timedwait.S:
+	Fix pthread_cond_timedwait with requeue-PI.
+	* sysdeps/unix/sysv/linux/i386/i486/pthread_cond_wait.S:
+	Fix pthread_cond_wait with requeue-PI.
+
 2010-01-14  Ulrich Drepper  <drepper@xxxxxxxxxx>
 
 	* Versions: Add pthread_mutex_consistent, pthread_mutexattr_getrobust,

Modified: fsf/trunk/libc/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_cond_timedwait.S
==============================================================================
--- fsf/trunk/libc/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_cond_timedwait.S (original)
+++ fsf/trunk/libc/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_cond_timedwait.S Sat Jan 16 00:03:28 2010
@@ -1,4 +1,4 @@
-/* Copyright (C) 2002-2004, 2006-2007, 2009 Free Software Foundation, Inc.
+/* Copyright (C) 2002-2004,2006-2007,2009,2010 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@xxxxxxxxxx>, 2002.
 
@@ -57,7 +57,6 @@
 	pushl	%ebx
 	cfi_adjust_cfa_offset(4)
 	cfi_rel_offset(%ebx, 0)
-	cfi_remember_state
 
 	movl	20(%esp), %ebx
 	movl	28(%esp), %ebp
@@ -99,6 +98,7 @@
 #define FRAME_SIZE 32
 	subl	$FRAME_SIZE, %esp
 	cfi_adjust_cfa_offset(FRAME_SIZE)
+	cfi_remember_state
 
 	/* Get and store current wakeup_seq value.  */
 	movl	wakeup_seq(%ebx), %edi
@@ -326,14 +326,12 @@
 #endif
 	jne	10f
 
-11:	xorl	%eax, %eax
+11:	movl	24+FRAME_SIZE(%esp), %eax
 	/* With requeue_pi, the mutex lock is held in the kernel.  */
 	movl	24(%esp), %ecx
 	testl	%ecx, %ecx
-	jnz	26f
-
-	/* Remove cancellation handler.  */
-	movl	24+FRAME_SIZE(%esp), %eax
+	jnz	27f
+
 	call	__pthread_mutex_cond_lock
 26:	addl	$FRAME_SIZE, %esp
 	cfi_adjust_cfa_offset(-FRAME_SIZE);
@@ -366,8 +364,10 @@
 	cfi_restore_state
 
 27:	call	__pthread_mutex_cond_lock_adjust
+	xorl	%eax, %eax
 	jmp	26b
 
+	cfi_adjust_cfa_offset(-FRAME_SIZE);
 	/* Initial locking failed.  */
 1:
 #if cond_lock == 0

Modified: fsf/trunk/libc/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_cond_wait.S
==============================================================================
--- fsf/trunk/libc/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_cond_wait.S (original)
+++ fsf/trunk/libc/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_cond_wait.S Sat Jan 16 00:03:28 2010
@@ -1,4 +1,4 @@
-/* Copyright (C) 2002-2004, 2006-2007, 2009 Free Software Foundation, Inc.
+/* Copyright (C) 2002-2004,2006-2007,2009,2010 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@xxxxxxxxxx>, 2002.
 
@@ -57,7 +57,6 @@
 	pushl	%ebx
 	cfi_adjust_cfa_offset(4)
 	cfi_rel_offset(%ebx, 0)
-	cfi_remember_state
 
 	xorl	%esi, %esi
 	movl	20(%esp), %ebx
@@ -95,6 +94,7 @@
 #define FRAME_SIZE 20
 	subl	$FRAME_SIZE, %esp
 	cfi_adjust_cfa_offset(FRAME_SIZE)
+	cfi_remember_state
 
 	/* Get and store current wakeup_seq value.  */
 	movl	wakeup_seq(%ebx), %edi
@@ -247,12 +247,11 @@
 	jne	10f
 
 	/* With requeue_pi, the mutex lock is held in the kernel.  */
-11:	xorl	%eax, %eax
+11:	movl	24+FRAME_SIZE(%esp), %eax
 	movl	16(%esp), %ecx
 	testl	%ecx, %ecx
-	jnz	20f
-
-	movl	24+FRAME_SIZE(%esp), %eax
+	jnz	21f
+
 	call	__pthread_mutex_cond_lock
 20:	addl	$FRAME_SIZE, %esp
 	cfi_adjust_cfa_offset(-FRAME_SIZE);
@@ -279,6 +278,7 @@
 	xorl	%eax, %eax
 	jmp	20b
 
+	cfi_adjust_cfa_offset(-FRAME_SIZE);
 	/* Initial locking failed.  */
 1:
 #if cond_lock == 0

Modified: fsf/trunk/libc/posix/regcomp.c
==============================================================================
--- fsf/trunk/libc/posix/regcomp.c (original)
+++ fsf/trunk/libc/posix/regcomp.c Sat Jan 16 00:03:28 2010
@@ -409,8 +409,8 @@
 			  != (size_t) -1)
 			re_set_fastmap (fastmap, false, *(unsigned char *) buf);
 		    }
- 		}
- 	    }
+		}
+	    }
 	}
 #endif /* RE_ENABLE_I18N */
       else if (type == OP_PERIOD
@@ -999,7 +999,11 @@
 	    int dest_idx = dfa->edests[node_idx].elems[0];
 	    if (!re_node_set_contains (&init_nodes, dest_idx))
 	      {
-		re_node_set_merge (&init_nodes, dfa->eclosures + dest_idx);
+		reg_errcode_t err = re_node_set_merge (&init_nodes,
+						       dfa->eclosures
+						       + dest_idx);
+		if (err != REG_NOERROR)
+		  return err;
 		i = 0;
 	      }
 	  }
@@ -1414,7 +1418,7 @@
     case OP_BACK_REF:
       dfa->nexts[idx] = node->next->node_idx;
       if (node->token.type == OP_BACK_REF)
-	re_node_set_init_1 (dfa->edests + idx, dfa->nexts[idx]);
+	err = re_node_set_init_1 (dfa->edests + idx, dfa->nexts[idx]);
       break;
 
     default:
@@ -1690,7 +1694,9 @@
 	else
 	  eclosure_elem = dfa->eclosures[edest];
 	/* Merge the epsilon closure of `edest'.  */
-	re_node_set_merge (&eclosure, &eclosure_elem);
+	err = re_node_set_merge (&eclosure, &eclosure_elem);
+	if (BE (err != REG_NOERROR, 0))
+	  return err;
 	/* If the epsilon closure of `edest' is incomplete,
 	   the epsilon closure of this node is also incomplete.  */
 	if (dfa->eclosures[edest].nelem == 0)

Modified: fsf/trunk/libc/posix/regex_internal.c
==============================================================================
--- fsf/trunk/libc/posix/regex_internal.c (original)
+++ fsf/trunk/libc/posix/regex_internal.c Sat Jan 16 00:03:28 2010
@@ -1,5 +1,5 @@
 /* Extended regular expression matching and search library.
-   Copyright (C) 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
+   Copyright (C) 2002-2006, 2010 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Isamu Hasegawa <isamu@xxxxxxxxxxxxxx>.
 
@@ -36,7 +36,7 @@
    re_string_reconstruct before using the object.  */
 
 static reg_errcode_t
-internal_function
+internal_function __attribute_warn_unused_result__
 re_string_allocate (re_string_t *pstr, const char *str, int len, int init_len,
 		    RE_TRANSLATE_TYPE trans, int icase, const re_dfa_t *dfa)
 {
@@ -64,7 +64,7 @@
 /* This function allocate the buffers, and initialize them.  */
 
 static reg_errcode_t
-internal_function
+internal_function __attribute_warn_unused_result__
 re_string_construct (re_string_t *pstr, const char *str, int len,
 		     RE_TRANSLATE_TYPE trans, int icase, const re_dfa_t *dfa)
 {
@@ -127,7 +127,7 @@
 /* Helper functions for re_string_allocate, and re_string_construct.  */
 
 static reg_errcode_t
-internal_function
+internal_function __attribute_warn_unused_result__
 re_string_realloc_buffers (re_string_t *pstr, int new_buf_len)
 {
 #ifdef RE_ENABLE_I18N
@@ -260,7 +260,7 @@
    but for REG_ICASE.  */
 
 static reg_errcode_t
-internal_function
+internal_function __attribute_warn_unused_result__
 build_wcs_upper_buffer (re_string_t *pstr)
 {
   mbstate_t prev_st;
@@ -423,8 +423,8 @@
 		    src_idx += mbclen;
 		    continue;
 		  }
-                else
-                  memcpy (pstr->mbs + byte_idx, p, mbclen);
+		else
+		  memcpy (pstr->mbs + byte_idx, p, mbclen);
 	      }
 	    else
 	      memcpy (pstr->mbs + byte_idx, p, mbclen);
@@ -559,7 +559,7 @@
    convert to upper case in case of REG_ICASE, apply translation.  */
 
 static reg_errcode_t
-internal_function
+internal_function __attribute_warn_unused_result__
 re_string_reconstruct (re_string_t *pstr, int idx, int eflags)
 {
   int offset = idx - pstr->raw_mbs_idx;
@@ -951,7 +951,7 @@
 /* Functions for set operation.  */
 
 static reg_errcode_t
-internal_function
+internal_function __attribute_warn_unused_result__
 re_node_set_alloc (re_node_set *set, int size)
 {
   set->alloc = size;
@@ -963,7 +963,7 @@
 }
 
 static reg_errcode_t
-internal_function
+internal_function __attribute_warn_unused_result__
 re_node_set_init_1 (re_node_set *set, int elem)
 {
   set->alloc = 1;
@@ -979,7 +979,7 @@
 }
 
 static reg_errcode_t
-internal_function
+internal_function __attribute_warn_unused_result__
 re_node_set_init_2 (re_node_set *set, int elem1, int elem2)
 {
   set->alloc = 2;
@@ -1009,7 +1009,7 @@
 }
 
 static reg_errcode_t
-internal_function
+internal_function __attribute_warn_unused_result__
 re_node_set_init_copy (re_node_set *dest, const re_node_set *src)
 {
   dest->nelem = src->nelem;
@@ -1034,7 +1034,7 @@
    Note: We assume dest->elems is NULL, when dest->alloc is 0.  */
 
 static reg_errcode_t
-internal_function
+internal_function __attribute_warn_unused_result__
 re_node_set_add_intersect (re_node_set *dest, const re_node_set *src1,
 			   const re_node_set *src2)
 {
@@ -1049,7 +1049,7 @@
       int new_alloc = src1->nelem + src2->nelem + dest->alloc;
       int *new_elems = re_realloc (dest->elems, int, new_alloc);
       if (BE (new_elems == NULL, 0))
-        return REG_ESPACE;
+	return REG_ESPACE;
       dest->elems = new_elems;
       dest->alloc = new_alloc;
     }
@@ -1068,8 +1068,8 @@
 	  while (id >= 0 && dest->elems[id] > src1->elems[i1])
 	    --id;
 
-          if (id < 0 || dest->elems[id] != src1->elems[i1])
-            dest->elems[--sbase] = src1->elems[i1];
+	  if (id < 0 || dest->elems[id] != src1->elems[i1])
+	    dest->elems[--sbase] = src1->elems[i1];
 
 	  if (--i1 < 0 || --i2 < 0)
 	    break;
@@ -1099,20 +1099,20 @@
   if (delta > 0 && id >= 0)
     for (;;)
       {
-        if (dest->elems[is] > dest->elems[id])
-          {
-            /* Copy from the top.  */
-            dest->elems[id + delta--] = dest->elems[is--];
-            if (delta == 0)
-              break;
-          }
-        else
-          {
-            /* Slide from the bottom.  */
-            dest->elems[id + delta] = dest->elems[id];
-            if (--id < 0)
-              break;
-          }
+	if (dest->elems[is] > dest->elems[id])
+	  {
+	    /* Copy from the top.  */
+	    dest->elems[id + delta--] = dest->elems[is--];
+	    if (delta == 0)
+	      break;
+	  }
+	else
+	  {
+	    /* Slide from the bottom.  */
+	    dest->elems[id + delta] = dest->elems[id];
+	    if (--id < 0)
+	      break;
+	  }
       }
 
   /* Copy remaining SRC elements.  */
@@ -1125,7 +1125,7 @@
    DEST. Return value indicate the error code or REG_NOERROR if succeeded.  */
 
 static reg_errcode_t
-internal_function
+internal_function __attribute_warn_unused_result__
 re_node_set_init_union (re_node_set *dest, const re_node_set *src1,
 			const re_node_set *src2)
 {
@@ -1178,7 +1178,7 @@
    DEST. Return value indicate the error code or REG_NOERROR if succeeded.  */
 
 static reg_errcode_t
-internal_function
+internal_function __attribute_warn_unused_result__
 re_node_set_merge (re_node_set *dest, const re_node_set *src)
 {
   int is, id, sbase, delta;
@@ -1207,11 +1207,11 @@
        is = src->nelem - 1, id = dest->nelem - 1; is >= 0 && id >= 0; )
     {
       if (dest->elems[id] == src->elems[is])
-        is--, id--;
+	is--, id--;
       else if (dest->elems[id] < src->elems[is])
-        dest->elems[--sbase] = src->elems[is--];
+	dest->elems[--sbase] = src->elems[is--];
       else /* if (dest->elems[id] > src->elems[is]) */
-        --id;
+	--id;
     }
 
   if (is >= 0)
@@ -1233,21 +1233,21 @@
   for (;;)
     {
       if (dest->elems[is] > dest->elems[id])
-        {
+	{
 	  /* Copy from the top.  */
-          dest->elems[id + delta--] = dest->elems[is--];
+	  dest->elems[id + delta--] = dest->elems[is--];
 	  if (delta == 0)
 	    break;
 	}
       else
-        {
-          /* Slide from the bottom.  */
-          dest->elems[id + delta] = dest->elems[id];
+	{
+	  /* Slide from the bottom.  */
+	  dest->elems[id + delta] = dest->elems[id];
 	  if (--id < 0)
 	    {
 	      /* Copy remaining SRC elements.  */
 	      memcpy (dest->elems, dest->elems + sbase,
-	              delta * sizeof (int));
+		      delta * sizeof (int));
 	      break;
 	    }
 	}
@@ -1261,7 +1261,7 @@
    return -1 if an error is occured, return 1 otherwise.  */
 
 static int
-internal_function
+internal_function __attribute_warn_unused_result__
 re_node_set_insert (re_node_set *set, int elem)
 {
   int idx;
@@ -1299,12 +1299,12 @@
     {
       idx = 0;
       for (idx = set->nelem; idx > 0; idx--)
-        set->elems[idx] = set->elems[idx - 1];
+	set->elems[idx] = set->elems[idx - 1];
     }
   else
     {
       for (idx = set->nelem; set->elems[idx - 1] > elem; idx--)
-        set->elems[idx] = set->elems[idx - 1];
+	set->elems[idx] = set->elems[idx - 1];
     }
 
   /* Insert the new element.  */
@@ -1318,7 +1318,7 @@
    Return -1 if an error is occured, return 1 otherwise.  */
 
 static int
-internal_function
+internal_function __attribute_warn_unused_result__
 re_node_set_insert_last (re_node_set *set, int elem)
 {
   /* Realloc if we need.  */
@@ -1458,7 +1458,7 @@
 	   optimization.  */
 
 static re_dfastate_t *
-internal_function
+internal_function __attribute_warn_unused_result__
 re_acquire_state (reg_errcode_t *err, const re_dfa_t *dfa,
 		  const re_node_set *nodes)
 {
@@ -1502,7 +1502,7 @@
 	   optimization.  */
 
 static re_dfastate_t *
-internal_function
+internal_function __attribute_warn_unused_result__
 re_acquire_state_context (reg_errcode_t *err, const re_dfa_t *dfa,
 			  const re_node_set *nodes, unsigned int context)
 {
@@ -1539,6 +1539,7 @@
    indicates the error code if failed.  */
 
 static reg_errcode_t
+__attribute_warn_unused_result__
 register_state (const re_dfa_t *dfa, re_dfastate_t *newstate,
 		unsigned int hash)
 {
@@ -1554,7 +1555,8 @@
     {
       int elem = newstate->nodes.elems[i];
       if (!IS_EPSILON_NODE (dfa->nodes[elem].type))
-        re_node_set_insert_last (&newstate->non_eps_nodes, elem);
+	if (re_node_set_insert_last (&newstate->non_eps_nodes, elem) < 0)
+	  return REG_ESPACE;
     }
 
   spot = dfa->state_table + (hash & dfa->state_hash_mask);
@@ -1592,7 +1594,7 @@
    Return the new state if succeeded, otherwise return NULL.  */
 
 static re_dfastate_t *
-internal_function
+internal_function __attribute_warn_unused_result__
 create_ci_newstate (const re_dfa_t *dfa, const re_node_set *nodes,
 		    unsigned int hash)
 {
@@ -1642,7 +1644,7 @@
    Return the new state if succeeded, otherwise return NULL.  */
 
 static re_dfastate_t *
-internal_function
+internal_function __attribute_warn_unused_result__
 create_cd_newstate (const re_dfa_t *dfa, const re_node_set *nodes,
 		    unsigned int context, unsigned int hash)
 {
@@ -1691,7 +1693,9 @@
 		  free_state (newstate);
 		  return NULL;
 		}
-	      re_node_set_init_copy (newstate->entrance_nodes, nodes);
+	      if (re_node_set_init_copy (newstate->entrance_nodes, nodes)
+		  != REG_NOERROR)
+		return NULL;
 	      nctx_nodes = 0;
 	      newstate->has_constraint = 1;
 	    }

Modified: fsf/trunk/libc/posix/regexec.c
==============================================================================
--- fsf/trunk/libc/posix/regexec.c (original)
+++ fsf/trunk/libc/posix/regexec.c Sat Jan 16 00:03:28 2010
@@ -1,5 +1,5 @@
 /* Extended regular expression matching and search library.
-   Copyright (C) 2002, 2003, 2004, 2005, 2007, 2009 Free Software Foundation, Inc.
+   Copyright (C) 2002-2005, 2007, 2009, 2010 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Isamu Hasegawa <isamu@xxxxxxxxxxxxxx>.
 
@@ -617,6 +617,7 @@
    (START + RANGE >= 0 && START + RANGE <= LENGTH)  */
 
 static reg_errcode_t
+__attribute_warn_unused_result__
 re_search_internal (preg, string, length, start, range, stop, nmatch, pmatch,
 		    eflags)
     const regex_t *preg;
@@ -668,7 +669,7 @@
 	  || !preg->newline_anchor))
     {
       if (start != 0 && start + range != 0)
-        return REG_NOMATCH;
+	return REG_NOMATCH;
       start = range = 0;
     }
 
@@ -800,10 +801,10 @@
 		break;
 	      match_first += incr;
 	      if (match_first < left_lim || match_first > right_lim)
-	        {
-	          err = REG_NOMATCH;
-	          goto free_return;
-	        }
+		{
+		  err = REG_NOMATCH;
+		  goto free_return;
+		}
 	    }
 	  break;
 	}
@@ -917,14 +918,14 @@
 	}
 
       if (dfa->subexp_map)
-        for (reg_idx = 0; reg_idx + 1 < nmatch; reg_idx++)
-          if (dfa->subexp_map[reg_idx] != reg_idx)
-            {
-              pmatch[reg_idx + 1].rm_so
-                = pmatch[dfa->subexp_map[reg_idx] + 1].rm_so;
-              pmatch[reg_idx + 1].rm_eo
-                = pmatch[dfa->subexp_map[reg_idx] + 1].rm_eo;
-            }
+	for (reg_idx = 0; reg_idx + 1 < nmatch; reg_idx++)
+	  if (dfa->subexp_map[reg_idx] != reg_idx)
+	    {
+	      pmatch[reg_idx + 1].rm_so
+		= pmatch[dfa->subexp_map[reg_idx] + 1].rm_so;
+	      pmatch[reg_idx + 1].rm_eo
+		= pmatch[dfa->subexp_map[reg_idx] + 1].rm_eo;
+	    }
     }
 
  free_return:
@@ -936,6 +937,7 @@
 }
 
 static reg_errcode_t
+__attribute_warn_unused_result__
 prune_impossible_nodes (mctx)
      re_match_context_t *mctx;
 {
@@ -1069,7 +1071,7 @@
    index of the buffer.  */
 
 static int
-internal_function
+internal_function __attribute_warn_unused_result__
 check_matching (re_match_context_t *mctx, int fl_longest_match,
 		int *p_match_first)
 {
@@ -1108,7 +1110,7 @@
 	    {
 	      err = transit_state_bkref (mctx, &cur_state->nodes);
 	      if (BE (err != REG_NOERROR, 0))
-	        return err;
+		return err;
 	    }
 	}
     }
@@ -1135,16 +1137,16 @@
       int next_char_idx = re_string_cur_idx (&mctx->input) + 1;
 
       if (BE (next_char_idx >= mctx->input.bufs_len, 0)
-          || (BE (next_char_idx >= mctx->input.valid_len, 0)
-              && mctx->input.valid_len < mctx->input.len))
-        {
-          err = extend_buffers (mctx);
-          if (BE (err != REG_NOERROR, 0))
+	  || (BE (next_char_idx >= mctx->input.valid_len, 0)
+	      && mctx->input.valid_len < mctx->input.len))
+	{
+	  err = extend_buffers (mctx);
+	  if (BE (err != REG_NOERROR, 0))
 	    {
 	      assert (err == REG_ESPACE);
 	      return -2;
 	    }
-        }
+	}
 
       cur_state = transit_state (&err, mctx, cur_state);
       if (mctx->state_log != NULL)
@@ -1263,20 +1265,20 @@
 	  int candidate = edests->elems[i];
 	  if (!re_node_set_contains (cur_nodes, candidate))
 	    continue;
-          if (dest_node == -1)
+	  if (dest_node == -1)
 	    dest_node = candidate;
 
-          else
+	  else
 	    {
 	      /* In order to avoid infinite loop like "(a*)*", return the second
-	         epsilon-transition if the first was already considered.  */
+		 epsilon-transition if the first was already considered.  */
 	      if (re_node_set_contains (eps_via_nodes, dest_node))
-	        return candidate;
+		return candidate;
 
 	      /* Otherwise, push the second epsilon-transition on the fail stack.  */
 	      else if (fs != NULL
 		       && push_fail_stack (fs, *pidx, candidate, nregs, regs,
-				           eps_via_nodes))
+					   eps_via_nodes))
 		return -2;
 
 	      /* We know we are going to exit.  */
@@ -1342,7 +1344,7 @@
 }
 
 static reg_errcode_t
-internal_function
+internal_function __attribute_warn_unused_result__
 push_fail_stack (struct re_fail_stack_t *fs, int str_idx, int dest_node,
 		 int nregs, regmatch_t *regs, re_node_set *eps_via_nodes)
 {
@@ -1389,7 +1391,7 @@
    pmatch[i].rm_so == pmatch[i].rm_eo == -1 for 0 < i < nmatch.  */
 
 static reg_errcode_t
-internal_function
+internal_function __attribute_warn_unused_result__
 set_regs (const regex_t *preg, const re_match_context_t *mctx, size_t nmatch,
 	  regmatch_t *pmatch, int fl_backtrack)
 {
@@ -1624,7 +1626,7 @@
       if (mctx->state_log[str_idx])
 	{
 	  err = build_sifted_states (mctx, sctx, str_idx, &cur_dest);
-          if (BE (err != REG_NOERROR, 0))
+	  if (BE (err != REG_NOERROR, 0))
 	    goto free_return;
 	}
 
@@ -1643,7 +1645,7 @@
 }
 
 static reg_errcode_t
-internal_function
+internal_function __attribute_warn_unused_result__
 build_sifted_states (const re_match_context_t *mctx, re_sift_context_t *sctx,
 		     int str_idx, re_node_set *cur_dest)
 {
@@ -1805,7 +1807,7 @@
 }
 
 static reg_errcode_t
-internal_function
+internal_function __attribute_warn_unused_result__
 add_epsilon_src_nodes (const re_dfa_t *dfa, re_node_set *dest_nodes,
 		       const re_node_set *candidates)
 {
@@ -1820,10 +1822,14 @@
     {
       err = re_node_set_alloc (&state->inveclosure, dest_nodes->nelem);
       if (BE (err != REG_NOERROR, 0))
-        return REG_ESPACE;
+	return REG_ESPACE;
       for (i = 0; i < dest_nodes->nelem; i++)
-        re_node_set_merge (&state->inveclosure,
-			   dfa->inveclosures + dest_nodes->elems[i]);
+	{
+	  err = re_node_set_merge (&state->inveclosure,
+				   dfa->inveclosures + dest_nodes->elems[i]);
+	  if (BE (err != REG_NOERROR, 0))
+	    return REG_ESPACE;
+	}
     }
   return re_node_set_add_intersect (dest_nodes, candidates,
 				    &state->inveclosure);
@@ -1935,7 +1941,7 @@
 	    {
 	      struct re_backref_cache_entry *ent = mctx->bkref_ents + bkref_idx;
 	      do
-	        {
+		{
 		  int dst, cpos;
 
 		  if (ent->node != node)
@@ -1956,9 +1962,9 @@
 		  if (dst == from_node)
 		    {
 		      if (boundaries & 1)
-		        return -1;
+			return -1;
 		      else /* if (boundaries & 2) */
-		        return 0;
+			return 0;
 		    }
 
 		  cpos =
@@ -1972,7 +1978,7 @@
 		  if (subexp_idx < BITSET_WORD_BITS)
 		    ent->eps_reachable_subexps_map
 		      &= ~((bitset_word_t) 1 << subexp_idx);
-	        }
+		}
 	      while (ent++->more);
 	    }
 	  break;
@@ -2114,7 +2120,7 @@
 }
 
 static reg_errcode_t
-internal_function
+internal_function __attribute_warn_unused_result__
 sift_states_bkref (const re_match_context_t *mctx, re_sift_context_t *sctx,
 		   int str_idx, const re_node_set *candidates)
 {
@@ -2197,7 +2203,7 @@
 	  re_node_set_remove (&local_sctx.limits, enabled_idx);
 
 	  /* mctx->bkref_ents may have changed, reload the pointer.  */
-          entry = mctx->bkref_ents + enabled_idx;
+	  entry = mctx->bkref_ents + enabled_idx;
 	}
       while (enabled_idx++, entry++->more);
     }
@@ -2244,7 +2250,7 @@
    update the destination of STATE_LOG.  */
 
 static re_dfastate_t *
-internal_function
+internal_function __attribute_warn_unused_result__
 transit_state (reg_errcode_t *err, re_match_context_t *mctx,
 	       re_dfastate_t *state)
 {
@@ -2278,7 +2284,7 @@
 
       trtable = state->word_trtable;
       if (BE (trtable != NULL, 1))
-        {
+	{
 	  unsigned int context;
 	  context
 	    = re_string_context_at (&mctx->input,
@@ -2324,21 +2330,21 @@
       unsigned int context;
       re_node_set next_nodes, *log_nodes, *table_nodes = NULL;
       /* If (state_log[cur_idx] != 0), it implies that cur_idx is
-         the destination of a multibyte char/collating element/
-         back reference.  Then the next state is the union set of
-         these destinations and the results of the transition table.  */
+	 the destination of a multibyte char/collating element/
+	 back reference.  Then the next state is the union set of
+	 these destinations and the results of the transition table.  */
       pstate = mctx->state_log[cur_idx];
       log_nodes = pstate->entrance_nodes;
       if (next_state != NULL)
-        {
-          table_nodes = next_state->entrance_nodes;
-          *err = re_node_set_init_union (&next_nodes, table_nodes,
+	{
+	  table_nodes = next_state->entrance_nodes;
+	  *err = re_node_set_init_union (&next_nodes, table_nodes,
 					     log_nodes);
-          if (BE (*err != REG_NOERROR, 0))
+	  if (BE (*err != REG_NOERROR, 0))
 	    return NULL;
-        }
+	}
       else
-        next_nodes = *log_nodes;
+	next_nodes = *log_nodes;
       /* Note: We already add the nodes of the initial state,
 	 then we don't need to add them here.  */
 
@@ -2346,12 +2352,12 @@
 				      re_string_cur_idx (&mctx->input) - 1,
 				      mctx->eflags);
       next_state = mctx->state_log[cur_idx]
-        = re_acquire_state_context (err, dfa, &next_nodes, context);
+	= re_acquire_state_context (err, dfa, &next_nodes, context);
       /* We don't need to check errors here, since the return value of
-         this function is next_state and ERR is already set.  */
+	 this function is next_state and ERR is already set.  */
 
       if (table_nodes != NULL)
-        re_node_set_free (&next_nodes);
+	re_node_set_free (&next_nodes);
     }
 
   if (BE (dfa->nbackref, 0) && next_state != NULL)
@@ -2392,9 +2398,9 @@
 
       do
 	{
-          if (++cur_str_idx > max)
-            return NULL;
-          re_string_skip_bytes (&mctx->input, 1);
+	  if (++cur_str_idx > max)
+	    return NULL;
+	  re_string_skip_bytes (&mctx->input, 1);
 	}
       while (mctx->state_log[cur_str_idx] == NULL);
 
@@ -2501,7 +2507,7 @@
       re_dfastate_t *dest_state;
 
       if (!dfa->nodes[cur_node_idx].accept_mb)
-        continue;
+	continue;
 
       if (dfa->nodes[cur_node_idx].constraint)
 	{
@@ -2669,7 +2675,7 @@
    delay these checking for prune_impossible_nodes().  */
 
 static reg_errcode_t
-internal_function
+internal_function __attribute_warn_unused_result__
 get_subexp (re_match_context_t *mctx, int bkref_node, int bkref_str_idx)
 {
   const re_dfa_t *const dfa = mctx->dfa;
@@ -2682,7 +2688,7 @@
       const struct re_backref_cache_entry *entry
 	= mctx->bkref_ents + cache_idx;
       do
-        if (entry->node == bkref_node)
+	if (entry->node == bkref_node)
 	  return REG_NOERROR; /* We already checked it.  */
       while (entry++->more);
     }
@@ -2869,7 +2875,7 @@
    Return REG_NOERROR if it can arrive, or REG_NOMATCH otherwise.  */
 
 static reg_errcode_t
-internal_function
+internal_function __attribute_warn_unused_result__
 check_arrival (re_match_context_t *mctx, state_array_t *path, int top_node,
 	       int top_str, int last_node, int last_str, int type)
 {
@@ -3030,7 +3036,7 @@
 	 Can't we unify them?  */
 
 static reg_errcode_t
-internal_function
+internal_function __attribute_warn_unused_result__
 check_arrival_add_next_nodes (re_match_context_t *mctx, int str_idx,
 			      re_node_set *cur_nodes, re_node_set *next_nodes)
 {
@@ -3162,7 +3168,7 @@
    problematic append it to DST_NODES.  */
 
 static reg_errcode_t
-internal_function
+internal_function __attribute_warn_unused_result__
 check_arrival_expand_ecl_sub (const re_dfa_t *dfa, re_node_set *dst_nodes,
 			      int target, int ex_subexp, int type)
 {
@@ -3206,7 +3212,7 @@
    in MCTX->BKREF_ENTS.  */
 
 static reg_errcode_t
-internal_function
+internal_function __attribute_warn_unused_result__
 expand_bkref_cache (re_match_context_t *mctx, re_node_set *cur_nodes,
 		    int cur_str, int subexp_num, int type)
 {
@@ -3564,13 +3570,13 @@
 	}
 #ifdef RE_ENABLE_I18N
       else if (type == OP_UTF8_PERIOD)
-        {
+	{
 	  memset (accepts, '\xff', sizeof (bitset_t) / 2);
 	  if (!(dfa->syntax & RE_DOT_NEWLINE))
 	    bitset_clear (accepts, '\n');
 	  if (dfa->syntax & RE_DOT_NOT_NULL)
 	    bitset_clear (accepts, '\0');
-        }
+	}
 #endif
       else
 	continue;
@@ -3775,7 +3781,7 @@
   if (node->type == OP_PERIOD)
     {
       if (char_len <= 1)
-        return 0;
+	return 0;
       /* FIXME: I don't think this if is needed, as both '\n'
 	 and '\0' are char_len == 1.  */
       /* '.' accepts any one character except the following two cases.  */
@@ -4025,18 +4031,18 @@
     {
     case CHARACTER:
       if (node->opr.c != ch)
-        return 0;
+	return 0;
       break;
 
     case SIMPLE_BRACKET:
       if (!bitset_contain (node->opr.sbcset, ch))
-        return 0;
+	return 0;
       break;
 
 #ifdef RE_ENABLE_I18N
     case OP_UTF8_PERIOD:
       if (ch >= 0x80)
-        return 0;
+	return 0;
       /* FALLTHROUGH */
 #endif
     case OP_PERIOD:
@@ -4065,7 +4071,7 @@
 /* Extend the buffers, if the buffers have run out.  */
 
 static reg_errcode_t
-internal_function
+internal_function __attribute_warn_unused_result__
 extend_buffers (re_match_context_t *mctx)
 {
   reg_errcode_t ret;
@@ -4124,7 +4130,7 @@
 /* Initialize MCTX.  */
 
 static reg_errcode_t
-internal_function
+internal_function __attribute_warn_unused_result__
 match_ctx_init (re_match_context_t *mctx, int eflags, int n)
 {
   mctx->eflags = eflags;
@@ -4197,7 +4203,7 @@
 */
 
 static reg_errcode_t
-internal_function
+internal_function __attribute_warn_unused_result__
 match_ctx_add_entry (re_match_context_t *mctx, int node, int str_idx, int from,
 		     int to)
 {
@@ -4269,7 +4275,7 @@
    at STR_IDX.  */
 
 static reg_errcode_t
-internal_function
+internal_function __attribute_warn_unused_result__
 match_ctx_add_subtop (re_match_context_t *mctx, int node, int str_idx)
 {
 #ifdef DEBUG

Modified: fsf/trunk/libc/sysdeps/generic/ldsodefs.h
==============================================================================
--- fsf/trunk/libc/sysdeps/generic/ldsodefs.h (original)
+++ fsf/trunk/libc/sysdeps/generic/ldsodefs.h Sat Jan 16 00:03:28 2010
@@ -1,5 +1,5 @@
 /* Run-time dynamic linker data structures for loaded ELF shared objects.
-   Copyright (C) 1995-2006, 2007, 2008, 2009 Free Software Foundation, Inc.
+   Copyright (C) 1995-2009, 2010 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
@@ -1015,7 +1015,8 @@
 extern ElfW(Addr) _dl_sysdep_start (void **start_argptr,
 				    void (*dl_main) (const ElfW(Phdr) *phdr,
 						     ElfW(Word) phnum,
-						     ElfW(Addr) *user_entry))
+						     ElfW(Addr) *user_entry,
+						     ElfW(auxv_t) *auxv))
      attribute_hidden;
 
 extern void _dl_sysdep_start_cleanup (void)

Modified: fsf/trunk/libc/sysdeps/s390/s390-32/dl-machine.h
==============================================================================
--- fsf/trunk/libc/sysdeps/s390/s390-32/dl-machine.h (original)
+++ fsf/trunk/libc/sysdeps/s390/s390-32/dl-machine.h Sat Jan 16 00:03:28 2010
@@ -27,6 +27,7 @@
 #include <sys/param.h>
 #include <string.h>
 #include <link.h>
+#include <sysdeps/s390/dl-procinfo.h>
 
 /* This is an older, now obsolete value.  */
 #define EM_S390_OLD	0xA390
@@ -35,6 +36,12 @@
 static inline int
 elf_machine_matches_host (const Elf32_Ehdr *ehdr)
 {
+  /* Check if the kernel provides the high gpr facility if needed by
+     the binary.  */
+  if ((ehdr->e_flags & EF_S390_HIGH_GPRS)
+      && !(GLRO (dl_hwcap) & HWCAP_S390_HIGH_GPRS))
+    return 0;
+
   return (ehdr->e_machine == EM_S390 || ehdr->e_machine == EM_S390_OLD)
          && ehdr->e_ident[EI_CLASS] == ELFCLASS32;
 }

Modified: fsf/trunk/libc/sysdeps/s390/s390-32/elf/start.S
==============================================================================
--- fsf/trunk/libc/sysdeps/s390/s390-32/elf/start.S (original)
+++ fsf/trunk/libc/sysdeps/s390/s390-32/elf/start.S Sat Jan 16 00:03:28 2010
@@ -59,6 +59,88 @@
 	.globl _start
 	.type _start,@function
 _start:
+	/* Check if the kernel provides highgprs facility if needed by
+	   the binary.  */
+
+	lr	%r6,%r15
+	la	%r6,4(%r6)     /* Skip the argument counter.  */
+
+.L11:	l	%r5,0(%r6)     /* Skip the argument vector.  */
+	la	%r6,4(%r6)
+	ltr	%r5,%r5
+	jne	.L11
+
+.L12:	l	%r5,0(%r6)     /* Skip the environment vector.  */
+	la	%r6,4(%r6)
+	ltr	%r5,%r5
+	jne	.L12
+
+	/* Obtain the needed values from the auxiliary vector.  */
+
+	lhi	%r7,16	       /* AT_HWCAP */
+	lhi	%r8,3	       /* AT_PHDR */
+	lhi	%r9,5          /* AT_PHNUM */
+	lhi	%r2,4          /* AT_PHENT */
+.L13:	l	%r5,0(%r6)
+	clr	%r5,%r7
+	jne	.L15
+	l	%r10,4(%r6)    /* r10 = AT_HWCAP value.  */
+.L15:	clr	%r5,%r8
+	jne	.L16
+	l	%r11,4(%r6)    /* r11 = AT_PHDR value.  */
+.L16:	clr	%r5,%r9
+	jne	.L17
+	l	%r12,4(%r6)    /* r12 = AT_PHNUM value.  */
+.L17:	clr	%r5,%r2
+	jne	.L18
+	l	%r0,4(%r6)     /* r0 = AT_PHENT value.  */
+.L18:	ltr	%r5,%r5
+	la	%r6,8(%r6)
+	jnz	.L13
+
+	/* Locate the ELF header by looking for the first PT_LOAD
+	   segment with a p_offset of zero.  */
+
+	lr	%r4,%r11       /* Backup AT_PHDR.  */
+	lhi	%r7,1          /* PT_LOAD id */
+	lhi	%r8,0
+.L19:	cl	%r7,0(%r4)     /* p_type == PT_LOAD? */
+	jne	.L20
+	cl	%r8,4(%r4)     /* p_offset == 0? */
+	jne	.L20
+	l	%r9,8(%r4)     /* r9 = p_vaddr <- ELF header address  */
+	j	.L24
+.L20:	alr	%r4,%r0        /* r4 += AT_PHENT value */
+	brct	%r12,.L19
+
+	j	.+2            /* Trap, there must be such a phdr.  */
+
+.L24:	lr	%r4,%r11       /* Backup AT_PHDR.  */
+	lhi	%r2,6          /* PT_PHDR id */
+.L23:	cl	%r2,0(%r4)
+	jne	.L22
+	l	%r3,8(%r4)     /* r3 = PT_PHDR p_vaddr */
+	j	.L25
+.L22:	alr	%r4,%r0        /* r4 += AT_PHENT value */
+	brct	%r12,.L23
+
+	ltr	%r9,%r9        /* Load address == 0? */
+	jz	.L14           /* No checking for PIE without PT_PHDR.  */
+	j	.L21
+
+.L25:	clr	%r3,%r11       /* PT_PHDR p_vaddr == AT_PHDR? */
+	je	.L21
+	lr	%r9,%r11
+	slr	%r9,%r3        /* elf_header_addr = AT_PHDR - PT_PHDR.p_vaddr */
+
+.L21:	l	%r5,36(%r9)    /* Load the e_flags field.  */
+	tml	%r5,1
+	jz	.L14	       /* Binary does not require highgprs facility.  */
+
+	tml	%r10,512       /* Check the AT_HWCAP value.  */
+	jz	2              /* Trap if no highgprs facility available.  */
+.L14:
+
 	/* Setup pointer to literal pool of _start */
 	basr    %r13,0
 .L0:    ahi     %r13,.Llit-.L0