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

[commits] r8714 - in /fsf/trunk/libc: ./ elf/ nptl/ resolv/ sysdeps/x86_64/ sysdeps/x86_64/multiarch/



Author: eglibc
Date: Tue Jul 28 00:10:55 2009
New Revision: 8714

Log:
Import glibc-mainline for 2009-07-28

Added:
    fsf/trunk/libc/elf/dl-scope.c
Removed:
    fsf/trunk/libc/sysdeps/x86_64/multiarch/rtld-rawmemchr.c
    fsf/trunk/libc/sysdeps/x86_64/rtld-memchr.c
    fsf/trunk/libc/sysdeps/x86_64/rtld-rawmemchr.c
    fsf/trunk/libc/sysdeps/x86_64/rtld-strcmp.S
Modified:
    fsf/trunk/libc/ChangeLog
    fsf/trunk/libc/elf/Makefile
    fsf/trunk/libc/elf/dl-lookup.c
    fsf/trunk/libc/elf/dl-open.c
    fsf/trunk/libc/nptl/ChangeLog
    fsf/trunk/libc/nptl/pthread_mutex_lock.c
    fsf/trunk/libc/nptl/pthread_mutex_timedlock.c
    fsf/trunk/libc/nptl/pthread_mutex_unlock.c
    fsf/trunk/libc/resolv/res_debug.c
    fsf/trunk/libc/resolv/res_mkquery.c
    fsf/trunk/libc/resolv/res_query.c
    fsf/trunk/libc/resolv/resolv.h
    fsf/trunk/libc/sysdeps/x86_64/Makefile
    fsf/trunk/libc/sysdeps/x86_64/tst-xmmymm.sh

Modified: fsf/trunk/libc/ChangeLog
==============================================================================
--- fsf/trunk/libc/ChangeLog (original)
+++ fsf/trunk/libc/ChangeLog Tue Jul 28 00:10:55 2009
@@ -1,3 +1,33 @@
+2009-07-27  Ulrich Drepper  <drepper@xxxxxxxxxx>
+
+	* sysdeps/x86_64/tst-xmmymm.sh: Refine testing.  The script now
+	determines which files are used in runtime lookups and only checks
+	those for SSE use.
+	* sysdeps/x86_64/rtld-memchr.c: Removed.  Not needed with refined
+	testing.
+	* sysdeps/x86_64/rtld-rawmemchr.c: Removed.
+	* sysdeps/x86_64/multiarch/rtld-rawmemchr.c: Removed
+	* sysdeps/x86_64/Makefile: Emit warning that tst-xmmymm.sh might
+	take a while.
+
+	* elf/dl-open.c: Move _dl_scope_free to...
+	* elf/dl-scope.c: ...here.  New file.
+	* elf/Makefile (dl-routines): Add scope.
+
+	* resolv/resolv.h (RES_USE_DNSSEC): Define.
+	* resolv/res_debug.c (p_option): Handle RES_USE_EDNS0 and
+	RES_USE_DNSSEC.
+	* resolv/res_mkquery.c (__res_nopt): Set flags for RES_USE_DNSSEC.
+	* resolv/res_query.c (__libc_res_nquery): Handle RES_USE_DNSSEC in
+	all the places we handled RES_USE_EDNS0 only before.
+	Patch by Adam Tkac <atkac@xxxxxxxxxx>.
+
+2009-07-27  Jakub Jelinek  <jakub@xxxxxxxxxx>
+
+	* elf/dl-lookup.c (do_lookup_x): Fix check for table more than
+	3/4 full.  Pass size + 1 rather than size to _dl_higher_prime_number.
+	Update size when reallocating.
+
 2009-07-26  Ulrich Drepper  <drepper@xxxxxxxxxx>
 
 	* sysdeps/x86_64/tst-xmmymm.sh: New file.  Check whether any of the
@@ -7,7 +37,6 @@
 	* sysdeps/x86_64/rtld-memcmp.c: New file.
 	* sysdeps/x86_64/rtld-rawmemchr.c: New file.
 	* sysdeps/x86_64/rtld-strchr.S: New file.
-	* sysdeps/x86_64/rtld-strcmp.S: New file.
 	* sysdeps/x86_64/rtld-strlen.S: New file.
 	* sysdeps/x86_64/multiarch/rtld-rawmemchr.c: New file.
 	* sysdeps/x86_64/multiarch/rtld-strlen.S: New file.

Modified: fsf/trunk/libc/elf/Makefile
==============================================================================
--- fsf/trunk/libc/elf/Makefile (original)
+++ fsf/trunk/libc/elf/Makefile Tue Jul 28 00:10:55 2009
@@ -29,7 +29,7 @@
 # profiled libraries.
 dl-routines	= $(addprefix dl-,load cache lookup object reloc deps \
 			          runtime error init fini debug misc \
-				  version profile conflict tls origin \
+				  version profile conflict tls origin scope \
 				  execstack caller open close trampoline)
 all-dl-routines = $(dl-routines) $(sysdep-dl-routines)
 # But they are absent from the shared libc, because that code is in ld.so.

Modified: fsf/trunk/libc/elf/dl-lookup.c
==============================================================================
--- fsf/trunk/libc/elf/dl-lookup.c (original)
+++ fsf/trunk/libc/elf/dl-lookup.c Tue Jul 28 00:10:55 2009
@@ -377,10 +377,10 @@
 			idx -= size;
 		    }
 
-		  if (size * 3 <= tab->n_elements)
+		  if (size * 3 <= tab->n_elements * 4)
 		    {
 		      /* Expand the table.  */
-		      size_t newsize = _dl_higher_prime_number (size);
+		      size_t newsize = _dl_higher_prime_number (size + 1);
 		      struct unique_sym *newentries
 			= calloc (sizeof (struct unique_sym), newsize);
 		      if (newentries == NULL)
@@ -398,6 +398,7 @@
 
 		      tab->free (entries);
 		      tab->size = newsize;
+		      size = newsize;
 		      entries = tab->entries = newentries;
 		      tab->free = free;
 		    }

Modified: fsf/trunk/libc/elf/dl-open.c
==============================================================================
--- fsf/trunk/libc/elf/dl-open.c (original)
+++ fsf/trunk/libc/elf/dl-open.c Tue Jul 28 00:10:55 2009
@@ -165,41 +165,6 @@
   return 0;
 }
 
-int
-_dl_scope_free (void *old)
-{
-  struct dl_scope_free_list *fsl;
-#define DL_SCOPE_FREE_LIST_SIZE (sizeof (fsl->list) / sizeof (fsl->list[0]))
-
-  if (RTLD_SINGLE_THREAD_P)
-    free (old);
-  else if ((fsl = GL(dl_scope_free_list)) == NULL)
-    {
-      GL(dl_scope_free_list) = fsl = malloc (sizeof (*fsl));
-      if (fsl == NULL)
-	{
-	  THREAD_GSCOPE_WAIT ();
-	  free (old);
-	  return 1;
-	}
-      else
-	{
-	  fsl->list[0] = old;
-	  fsl->count = 1;
-	}
-    }
-  else if (fsl->count < DL_SCOPE_FREE_LIST_SIZE)
-    fsl->list[fsl->count++] = old;
-  else
-    {
-      THREAD_GSCOPE_WAIT ();
-      while (fsl->count > 0)
-	free (fsl->list[--fsl->count]);
-      return 1;
-    }
-  return 0;
-}
-
 static void
 dl_open_worker (void *a)
 {

Added: fsf/trunk/libc/elf/dl-scope.c
==============================================================================
--- fsf/trunk/libc/elf/dl-scope.c (added)
+++ fsf/trunk/libc/elf/dl-scope.c Tue Jul 28 00:10:55 2009
@@ -1,0 +1,58 @@
+/* Memory handling for the scope data structures.
+   Copyright (C) 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, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#include <stdlib.h>
+#include <ldsodefs.h>
+#include <sysdep-cancel.h>
+
+
+int
+_dl_scope_free (void *old)
+{
+  struct dl_scope_free_list *fsl;
+#define DL_SCOPE_FREE_LIST_SIZE (sizeof (fsl->list) / sizeof (fsl->list[0]))
+
+  if (RTLD_SINGLE_THREAD_P)
+    free (old);
+  else if ((fsl = GL(dl_scope_free_list)) == NULL)
+    {
+      GL(dl_scope_free_list) = fsl = malloc (sizeof (*fsl));
+      if (fsl == NULL)
+	{
+	  THREAD_GSCOPE_WAIT ();
+	  free (old);
+	  return 1;
+	}
+      else
+	{
+	  fsl->list[0] = old;
+	  fsl->count = 1;
+	}
+    }
+  else if (fsl->count < DL_SCOPE_FREE_LIST_SIZE)
+    fsl->list[fsl->count++] = old;
+  else
+    {
+      THREAD_GSCOPE_WAIT ();
+      while (fsl->count > 0)
+	free (fsl->list[--fsl->count]);
+      return 1;
+    }
+  return 0;
+}

Modified: fsf/trunk/libc/nptl/ChangeLog
==============================================================================
--- fsf/trunk/libc/nptl/ChangeLog (original)
+++ fsf/trunk/libc/nptl/ChangeLog Tue Jul 28 00:10:55 2009
@@ -1,9 +1,8 @@
-2009-07-26  Ulrich Drepper  <drepper@xxxxxxxxxx>
+2009-07-27  Ulrich Drepper  <drepper@xxxxxxxxxx>
 
 	[BZ #10418]
-	* pthread_mutex_lock.c (pthread_mutex_lock): Use _rel instead of of
-	_acq variants of cmpxchg.
-	* pthread_mutex_timedlock.c (pthread_mutex_timedlock): Likewise.
+	* pthread_mutex_unlock.c (__pthread_mutex_unlock_full): Use _rel
+	instead of of _acq variants of cmpxchg.
 
 2009-07-23  Ulrich Drepper  <drepper@xxxxxxxxxx>
 

Modified: fsf/trunk/libc/nptl/pthread_mutex_lock.c
==============================================================================
--- fsf/trunk/libc/nptl/pthread_mutex_lock.c (original)
+++ fsf/trunk/libc/nptl/pthread_mutex_lock.c Tue Jul 28 00:10:55 2009
@@ -1,4 +1,4 @@
-/* Copyright (C) 2002-2007, 2008, 2009 Free Software Foundation, Inc.
+/* Copyright (C) 2002-2007, 2008 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@xxxxxxxxxx>, 2002.
 
@@ -160,7 +160,7 @@
 #endif
 
 	      newval
-		= atomic_compare_and_exchange_val_rel (&mutex->__data.__lock,
+		= atomic_compare_and_exchange_val_acq (&mutex->__data.__lock,
 						       newval, oldval);
 
 	      if (newval != oldval)
@@ -285,7 +285,7 @@
 #ifdef NO_INCR
 	newval |= FUTEX_WAITERS;
 #endif
-	oldval = atomic_compare_and_exchange_val_rel (&mutex->__data.__lock,
+	oldval = atomic_compare_and_exchange_val_acq (&mutex->__data.__lock,
 						      newval, 0);
 
 	if (oldval != 0)
@@ -420,7 +420,7 @@
 	    oldprio = ceiling;
 
 	    oldval
-	      = atomic_compare_and_exchange_val_rel (&mutex->__data.__lock,
+	      = atomic_compare_and_exchange_val_acq (&mutex->__data.__lock,
 #ifdef NO_INCR
 						     ceilval | 2,
 #else
@@ -434,7 +434,7 @@
 	    do
 	      {
 		oldval
-		  = atomic_compare_and_exchange_val_rel (&mutex->__data.__lock,
+		  = atomic_compare_and_exchange_val_acq (&mutex->__data.__lock,
 							 ceilval | 2,
 							 ceilval | 1);
 
@@ -445,7 +445,7 @@
 		  lll_futex_wait (&mutex->__data.__lock, ceilval | 2,
 				  PTHREAD_MUTEX_PSHARED (mutex));
 	      }
-	    while (atomic_compare_and_exchange_val_rel (&mutex->__data.__lock,
+	    while (atomic_compare_and_exchange_val_acq (&mutex->__data.__lock,
 							ceilval | 2, ceilval)
 		   != ceilval);
 	  }

Modified: fsf/trunk/libc/nptl/pthread_mutex_timedlock.c
==============================================================================
--- fsf/trunk/libc/nptl/pthread_mutex_timedlock.c (original)
+++ fsf/trunk/libc/nptl/pthread_mutex_timedlock.c Tue Jul 28 00:10:55 2009
@@ -1,4 +1,4 @@
-/* Copyright (C) 2002-2007, 2008, 2009 Free Software Foundation, Inc.
+/* Copyright (C) 2002-2007, 2008 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@xxxxxxxxxx>, 2002.
 
@@ -126,7 +126,7 @@
 	      int newval = id | (oldval & FUTEX_WAITERS);
 
 	      newval
-		= atomic_compare_and_exchange_val_rel (&mutex->__data.__lock,
+		= atomic_compare_and_exchange_val_acq (&mutex->__data.__lock,
 						       newval, oldval);
 	      if (newval != oldval)
 		{
@@ -246,7 +246,7 @@
 	      }
 	  }
 
-	oldval = atomic_compare_and_exchange_val_rel (&mutex->__data.__lock,
+	oldval = atomic_compare_and_exchange_val_acq (&mutex->__data.__lock,
 						      id, 0);
 
 	if (oldval != 0)
@@ -404,7 +404,7 @@
 	    oldprio = ceiling;
 
 	    oldval
-	      = atomic_compare_and_exchange_val_rel (&mutex->__data.__lock,
+	      = atomic_compare_and_exchange_val_acq (&mutex->__data.__lock,
 						     ceilval | 1, ceilval);
 
 	    if (oldval == ceilval)
@@ -413,7 +413,7 @@
 	    do
 	      {
 		oldval
-		  = atomic_compare_and_exchange_val_rel (&mutex->__data.__lock,
+		  = atomic_compare_and_exchange_val_acq (&mutex->__data.__lock,
 							 ceilval | 2,
 							 ceilval | 1);
 
@@ -456,7 +456,7 @@
 					  PTHREAD_MUTEX_PSHARED (mutex));
 		  }
 	      }
-	    while (atomic_compare_and_exchange_val_rel (&mutex->__data.__lock,
+	    while (atomic_compare_and_exchange_val_acq (&mutex->__data.__lock,
 							ceilval | 2, ceilval)
 		   != ceilval);
 	  }

Modified: fsf/trunk/libc/nptl/pthread_mutex_unlock.c
==============================================================================
--- fsf/trunk/libc/nptl/pthread_mutex_unlock.c (original)
+++ fsf/trunk/libc/nptl/pthread_mutex_unlock.c Tue Jul 28 00:10:55 2009
@@ -1,4 +1,4 @@
-/* Copyright (C) 2002, 2003, 2005-2007, 2008 Free Software Foundation, Inc.
+/* Copyright (C) 2002, 2003, 2005-2008, 2009 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@xxxxxxxxxx>, 2002.
 
@@ -213,7 +213,7 @@
 
       /* Unlock.  */
       if ((mutex->__data.__lock & FUTEX_WAITERS) != 0
-	  || atomic_compare_and_exchange_bool_acq (&mutex->__data.__lock, 0,
+	  || atomic_compare_and_exchange_bool_rel (&mutex->__data.__lock, 0,
 						   THREAD_GETMEM (THREAD_SELF,
 								  tid)))
 	{
@@ -263,7 +263,7 @@
 	  oldval = mutex->__data.__lock;
 	  newval = oldval & PTHREAD_MUTEX_PRIO_CEILING_MASK;
 	}
-      while (atomic_compare_and_exchange_bool_acq (&mutex->__data.__lock,
+      while (atomic_compare_and_exchange_bool_rel (&mutex->__data.__lock,
 						   newval, oldval));
 
       if ((oldval & ~PTHREAD_MUTEX_PRIO_CEILING_MASK) > 1)

Modified: fsf/trunk/libc/resolv/res_debug.c
==============================================================================
--- fsf/trunk/libc/resolv/res_debug.c (original)
+++ fsf/trunk/libc/resolv/res_debug.c Tue Jul 28 00:10:55 2009
@@ -586,6 +586,8 @@
 	case RES_ROTATE:	return "rotate";
 	case RES_NOCHECKNAME:	return "no-check-names";
 	case RES_USEBSTRING:	return "ip6-bytstring";
+	case RES_USE_EDNS0:	return "edns0";
+	case RES_USE_DNSSEC:	return "dnssec";
 				/* XXX nonreentrant */
 	default:		sprintf(nbuf, "?0x%lx?", (u_long)option);
 				return (nbuf);

Modified: fsf/trunk/libc/resolv/res_mkquery.c
==============================================================================
--- fsf/trunk/libc/resolv/res_mkquery.c (original)
+++ fsf/trunk/libc/resolv/res_mkquery.c Tue Jul 28 00:10:55 2009
@@ -247,7 +247,15 @@
 	NS_PUT16(MIN(anslen, 0xffff), cp);	/* CLASS = UDP payload size */
 	*cp++ = NOERROR;	/* extended RCODE */
 	*cp++ = 0;		/* EDNS version */
-	/* XXX Once we support DNSSEC we change the flag value here.  */
+
+	if (statp->options & RES_USE_DNSSEC) {
+#ifdef DEBUG
+		if (statp->options & RES_DEBUG)
+			printf(";; res_opt()... ENDS0 DNSSEC\n");
+#endif
+		flags |= NS_OPT_DNSSEC_OK;
+	}
+
 	NS_PUT16(flags, cp);
 	NS_PUT16(0, cp);	/* RDLEN */
 	hp->arcount = htons(ntohs(hp->arcount) + 1);

Modified: fsf/trunk/libc/resolv/res_query.c
==============================================================================
--- fsf/trunk/libc/resolv/res_query.c (original)
+++ fsf/trunk/libc/resolv/res_query.c Tue Jul 28 00:10:55 2009
@@ -147,7 +147,7 @@
 	    if (n > 0)
 	      {
 		if ((oflags & RES_F_EDNS0ERR) == 0
-		    && (statp->options & RES_USE_EDNS0) != 0)
+		    && (statp->options & (RES_USE_EDNS0|RES_USE_DNSSEC)) != 0)
 		  {
 		    n = __res_nopt(statp, n, query1, bufsize, anslen / 2);
 		    if (n < 0)
@@ -169,7 +169,7 @@
 				 NULL, query2, bufsize - nused);
 		if (n > 0
 		    && (oflags & RES_F_EDNS0ERR) == 0
-		    && (statp->options & RES_USE_EDNS0) != 0)
+		    && (statp->options & (RES_USE_EDNS0|RES_USE_DNSSEC)) != 0)
 		  n = __res_nopt(statp, n, query2, bufsize - nused - n,
 				 anslen / 2);
 		nquery2 = n;
@@ -184,7 +184,7 @@
 
 	    if (n > 0
 		&& (oflags & RES_F_EDNS0ERR) == 0
-		&& (statp->options & RES_USE_EDNS0) != 0)
+		&& (statp->options & (RES_USE_EDNS0|RES_USE_DNSSEC)) != 0)
 	      n = __res_nopt(statp, n, query1, bufsize, anslen);
 
 	    nquery1 = n;
@@ -203,7 +203,7 @@
 	}
 	if (__builtin_expect (n <= 0, 0)) {
 		/* If the query choked with EDNS0, retry without EDNS0.  */
-		if ((statp->options & RES_USE_EDNS0) != 0
+		if ((statp->options & (RES_USE_EDNS0|RES_USE_DNSSEC)) != 0
 		    && ((oflags ^ statp->_flags) & RES_F_EDNS0ERR) != 0) {
 			statp->_flags |= RES_F_EDNS0ERR;
 #ifdef DEBUG

Modified: fsf/trunk/libc/resolv/resolv.h
==============================================================================
--- fsf/trunk/libc/resolv/resolv.h (original)
+++ fsf/trunk/libc/resolv/resolv.h Tue Jul 28 00:10:55 2009
@@ -218,6 +218,7 @@
 #define RES_SNGLKUP	0x00200000	/* one outstanding request at a time */
 #define RES_SNGLKUPREOP	0x00400000	/* -"-, but open new socket for each
 					   request */
+#define RES_USE_DNSSEC	0x00800000	/* use DNSSEC using OK bit in OPT */
 
 #define RES_DEFAULT	(RES_RECURSE|RES_DEFNAMES|RES_DNSRCH|RES_NOIP6DOTINT)
 

Modified: fsf/trunk/libc/sysdeps/x86_64/Makefile
==============================================================================
--- fsf/trunk/libc/sysdeps/x86_64/Makefile (original)
+++ fsf/trunk/libc/sysdeps/x86_64/Makefile Tue Jul 28 00:10:55 2009
@@ -22,6 +22,7 @@
 
 tests: $(objpfx)tst-xmmymm.out
 $(objpfx)tst-xmmymm.out: ../sysdeps/x86_64/tst-xmmymm.sh $(objpfx)ld.so
+	@echo "Checking ld.so for SSE register use.  This will take a few seconds..."
 	$(SHELL) -e $< $(objpfx) > $@
 endif
 

Modified: fsf/trunk/libc/sysdeps/x86_64/tst-xmmymm.sh
==============================================================================
--- fsf/trunk/libc/sysdeps/x86_64/tst-xmmymm.sh (original)
+++ fsf/trunk/libc/sysdeps/x86_64/tst-xmmymm.sh Tue Jul 28 00:10:55 2009
@@ -1,17 +1,79 @@
-#! /bin/sh
+#! /bin/bash
 objpfx="$1"
 
 tmp=$(mktemp ${objpfx}tst-xmmymm.XXXXXX)
 trap 'rm -f "$tmp"' 1 2 3 15
 
-objdump -d "${objpfx}ld.so" |
-awk 'BEGIN { last="" } /^[[:xdigit:]]* <[_[:alnum:]]*>:$/ { fct=substr($2, 2, length($2)-3) } /,%[xy]mm[[:digit:]]*$/ { if (last != fct) { print fct; last=fct} }' |
-tee "$tmp"
+# List of object files we have to test
+rtldobjs=$(readelf -W -wi ${objpfx}dl-allobjs.os |
+    awk '/^ </ { if ($5 == "(DW_TAG_compile_unit)") c=1; else c=0 } $2 == "DW_AT_name" { if (c == 1) print $NF }' |
+    sed 's,\(.*/\|\)\([_[:alnum:]-]*[.]\).$,\2os,')
+rtldobjs="$rtldobjs $(ar t ${objpfx}rtld-libc.a)"
 
-echo "Functions which incorrectly modify xmm/ymm registers:"
-err=1
-egrep -vs '^_dl_runtime_profile$' "$tmp" || err=0
-if test $err -eq 0; then echo "None"; fi
+# OBJECT symbols can be ignored.
+readelf -sW ${objpfx}dl-allobjs.os ${objpfx}rtld-libc.a |
+egrep " OBJECT  *GLOBAL " |
+awk '{if ($7 != "ABS") print $8 }' |
+sort -u > "$tmp"
+declare -a objects
+objects=($(cat "$tmp"))
+
+objs="dl-runtime.os"
+tocheck="dl-runtime.os"
+
+while test -n "$objs"; do
+  this="$objs"
+  objs=""
+
+  for f in $this; do
+    undef=$(nm -u "$objpfx"../*/"$f" | awk '{print $2}')
+    if test -n "$undef"; then
+      for s in $undef; do
+	for obj in ${objects[*]} "_GLOBAL_OFFSET_TABLE_"; do
+	  if test "$obj" = "$s"; then
+	    continue 2
+	  fi
+	done
+        for o in $rtldobjs; do
+	  ro=$(echo "$objpfx"../*/"$o")
+	  if nm -g --defined-only "$ro" | egrep -qs " $s\$"; then
+	    if ! (echo "$tocheck $objs" | fgrep -qs "$o"); then
+	      echo "$o needed for $s"
+	      objs="$objs $o"
+	    fi
+	    break;
+	  fi
+	done
+      done
+    fi
+  done
+  tocheck="$tocheck$objs"
+done
+
+echo
+echo
+echo "object files needed: $tocheck"
+
+cp /dev/null "$tmp"
+for f in $tocheck; do
+  objdump -d "$objpfx"../*/"$f" |
+  awk 'BEGIN { last="" } /^[[:xdigit:]]* <[_[:alnum:]]*>:$/ { fct=substr($2, 2, length($2)-3) } /,%[xy]mm[[:digit:]]*$/ { if (last != fct) { print fct; last=fct} }' |
+  while read fct; do
+    if test "$fct" != "_dl_runtime_profile"; then
+      echo "function $fct in $f modifies xmm/ymm" >> "$tmp"
+      result=1
+    fi
+  done
+done
+
+if test -s "$tmp"; then
+  echo
+  echo
+  cat "$tmp"
+  result=1
+else
+  result=0
+fi
 
 rm "$tmp"
-exit $err
+exit $result