about summary refs log tree commit diff
diff options
context:
space:
mode:
authorTulio Magno Quites Machado Filho <tuliom@linux.vnet.ibm.com>2015-12-17 17:31:21 -0200
committerTulio Magno Quites Machado Filho <tuliom@linux.vnet.ibm.com>2015-12-17 17:31:21 -0200
commitec54e4f7c24bfd5f3c9ecb6140e28fa67ae25801 (patch)
treefc54e2063f06b1925487810ef3da909bda99d44f
parent7d605623b146c6ca33a8fe08ff4638cd439da45e (diff)
parentcd51b1424477652cccdb83e7a95644d198fd4513 (diff)
downloadglibc-ec54e4f7c24bfd5f3c9ecb6140e28fa67ae25801.tar.gz
glibc-ec54e4f7c24bfd5f3c9ecb6140e28fa67ae25801.tar.xz
glibc-ec54e4f7c24bfd5f3c9ecb6140e28fa67ae25801.zip
Merge branch 'release/2.22/master' into ibm/2.22/master
-rw-r--r--ChangeLog90
-rw-r--r--NEWS2
-rw-r--r--config.make.in1
-rwxr-xr-xconfigure34
-rw-r--r--configure.ac23
-rw-r--r--elf/Makefile17
-rw-r--r--elf/dl-load.c44
-rw-r--r--elf/dl-lookup.c21
-rw-r--r--elf/dl-sysdep-open.h45
-rw-r--r--elf/tst-prelink.c30
-rw-r--r--elf/tst-prelink.exp1
-rw-r--r--math/Makefile2
-rw-r--r--sysdeps/nacl/dl-map-segments.h28
-rw-r--r--sysdeps/nacl/dl-sysdep-open.h40
-rw-r--r--sysdeps/nacl/dl-sysdep.c23
-rw-r--r--sysdeps/nacl/nacl-interface-list.h2
-rw-r--r--sysdeps/powerpc/nptl/elide.h6
-rw-r--r--sysdeps/unix/sysv/linux/powerpc/elision-lock.c15
-rw-r--r--sysdeps/x86/fpu/bits/math-vector.h29
-rw-r--r--sysdeps/x86_64/fpu/Makefile5
-rw-r--r--sysdeps/x86_64/fpu/svml_finite_alias.S59
21 files changed, 462 insertions, 55 deletions
diff --git a/ChangeLog b/ChangeLog
index 532811b565..580700b7f9 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,93 @@
+2015-12-17  Paul E. Murphy  <murphyp@linux.vnet.ibm.com>
+
+	[BZ #19174]
+	* sysdeps/powerpc/nptl/elide.h (__elide_lock): Fix usage of
+	.skip_lock_out_of_tbegin_retries.
+	* sysdeps/unix/sysv/linux/powerpc/elision-lock.c
+	(__lll_lock_elision): Likewise, and respect a value of
+	try_tbegin <= 0.
+
+2015-12-03  Andrew Senkevich  <andrew.senkevich@intel.com>
+
+	* math/Makefile ($(inst_libdir)/libm.so): Corrected path to
+	libmvec_nonshared.a
+
+2015-11-27  Andrew Senkevich  <andrew.senkevich@intel.com>
+
+	[BZ #19058]
+	* math/Makefile ($(inst_libdir)/libm.so): Added libmvec_nonshared.a to
+	AS_NEEDED.
+	* sysdeps/x86/fpu/bits/math-vector.h: Removed code with asm aliases
+	workaround.
+	* sysdeps/x86_64/fpu/Makefile (libmvec-support,
+	libmvec-static-only-routines): Added new file.
+	* sysdeps/x86_64/fpu/svml_finite_alias.S: New file.
+	* NEWS: Mention this fix.
+
+2015-11-20  Roland McGrath  <roland@hack.frob.com>
+
+	* sysdeps/nacl/dl-map-segments.h (_dl_map_segments): Use
+	__glibc_likely instead of __builtin_expect.  After falling back to
+	dyncode_create in a non-ET_DYN case, use the allocate_code_data
+	system interface to register the code pages as occupied.
+
+2015-11-14  H.J. Lu  <hongjiu.lu@intel.com>
+
+	* config.make.in (have-glob-dat-reloc): New.
+	* configure.ac (libc_cv_has_glob_dat): New.  Set to yes if
+	target supports GLOB_DAT relocaton. AC_SUBST.
+	* configure: Regenerated.
+	* elf/Makefile (tests): Add tst-prelink.
+	(tests-special): Add $(objpfx)tst-prelink-cmp.out.
+	(tst-prelink-ENV): New.
+	($(objpfx)tst-prelink-conflict.out): Likewise.
+	($(objpfx)tst-prelink-cmp.out): Likewise.
+	* sysdeps/x86/tst-prelink.c: Moved to ...
+	* elf/tst-prelink.c: Here.
+	* sysdeps/x86/tst-prelink.exp: Moved to ...
+	* elf/tst-prelink.exp: Here.
+	* sysdeps/x86/Makefile (tests): Don't add tst-prelink.
+	(tst-prelink-ENV): Removed.
+	($(objpfx)tst-prelink-conflict.out): Likewise.
+	($(objpfx)tst-prelink-cmp.out): Likewise.
+	(tests-special): Don't add $(objpfx)tst-prelink-cmp.out.
+
+2015-11-10  Roland McGrath  <roland@hack.frob.com>
+
+	* elf/dl-load.c (open_verify): Take new argument FD.
+	Skip __open call if passed FD is not -1.
+	(_dl_map_object, open_path): Update callers.
+	* elf/dl-sysdep-open.h: New file.
+	* elf/dl-load.c: Include it.
+	(_dl_map_object): Try _dl_sysdep_open_object before ldconfig cache.
+	* sysdeps/nacl/dl-sysdep.c (_dl_sysdep_open_object): New function.
+	* sysdeps/nacl/dl-sysdep-open.h: New file.
+	* sysdeps/nacl/nacl-interface-list.h: Move nacl_irt_resource_open
+	from libc to rtld.
+
+2015-11-10  H.J. Lu  <hongjiu.lu@intel.com>
+
+	[BZ #19178]
+	* sysdeps/x86/Makefile (tests): Add tst-prelink.
+	(tst-prelink-ENV): New.
+	($(objpfx)tst-prelink-conflict.out): Likewise.
+	($(objpfx)tst-prelink-cmp.out): Likewise.
+	(tests-special): Add $(objpfx)tst-prelink-cmp.out.
+	* sysdeps/x86/tst-prelink.c: New file.
+	* sysdeps/x86/tst-prelink.exp: Likewise.
+
+2015-11-07  H.J. Lu  <hongjiu.lu@intel.com>
+
+	[BZ #19178]
+	* elf/dl-lookup.c (RTYPE_CLASS_VALID): New.
+	(RTYPE_CLASS_PLT): Likewise.
+	(RTYPE_CLASS_COPY): Likewise.
+	(RTYPE_CLASS_TLS): Likewise.
+	(_dl_debug_bindings): Use RTYPE_CLASS_TLS and RTYPE_CLASS_VALID
+	to set relocation type class for DL_DEBUG_PRELINK.  Keep only
+	ELF_RTYPE_CLASS_PLT and ELF_RTYPE_CLASS_COPY bits for
+	DL_DEBUG_PRELINK.
+
 2015-10-20  Tulio Magno Quites Machado Filho  <tuliom@linux.vnet.ibm.com>
 
 	[BZ #18743]
diff --git a/NEWS b/NEWS
index 92037cee08..e1c1e58271 100644
--- a/NEWS
+++ b/NEWS
@@ -10,7 +10,7 @@ Version 2.22.1
 * The following bugs are resolved with this release:
 
   18589, 18743, 18778, 18781, 18787, 18796, 18870, 18887, 18921, 18928,
-  18969, 19018.
+  18969, 19018, 19058, 19174, 19178.
 
 * The LD_POINTER_GUARD environment variable can no longer be used to
   disable the pointer guard feature.  It is always enabled.
diff --git a/config.make.in b/config.make.in
index a9f5696077..46cd9bbb87 100644
--- a/config.make.in
+++ b/config.make.in
@@ -51,6 +51,7 @@ have-z-combreloc = @libc_cv_z_combreloc@
 have-z-execstack = @libc_cv_z_execstack@
 have-Bgroup = @libc_cv_Bgroup@
 have-protected-data = @libc_cv_protected_data@
+have-glob-dat-reloc = @libc_cv_has_glob_dat@
 with-fp = @with_fp@
 old-glibc-headers = @old_glibc_headers@
 unwind-find-fde = @libc_cv_gcc_unwind_find_fde@
diff --git a/configure b/configure
index 45cc7cba2b..4f87b31a73 100755
--- a/configure
+++ b/configure
@@ -628,6 +628,7 @@ gnu89_inline
 libc_cv_ssp
 fno_unit_at_a_time
 libc_cv_output_format
+libc_cv_has_glob_dat
 libc_cv_hashstyle
 libc_cv_fpie
 libc_cv_z_execstack
@@ -6335,6 +6336,39 @@ $as_echo "$libc_cv_use_default_link" >&6; }
   use_default_link=$libc_cv_use_default_link
 fi
 
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for GLOB_DAT reloc" >&5
+$as_echo_n "checking for GLOB_DAT reloc... " >&6; }
+if ${libc_cv_has_glob_dat+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat > conftest.c <<EOF
+extern int mumble;
+int foo (void) { return mumble; }
+EOF
+if { ac_try='${CC-cc} $CFLAGS $CPPFLAGS $LDFLAGS
+			-fPIC -shared -o conftest.so conftest.c
+			-nostdlib -nostartfiles
+			1>&5'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }
+then
+  if $READELF -rW conftest.so | grep '_GLOB_DAT' > /dev/null; then
+    libc_cv_has_glob_dat=yes
+  else
+    libc_cv_has_glob_dat=no
+  fi
+else
+  libc_cv_has_glob_dat=no
+fi
+rm -f conftest*
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $libc_cv_has_glob_dat" >&5
+$as_echo "$libc_cv_has_glob_dat" >&6; }
+
+
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking linker output format" >&5
 $as_echo_n "checking linker output format... " >&6; }
 if ${libc_cv_output_format+:} false; then :
diff --git a/configure.ac b/configure.ac
index 7e9383a7f0..8be612d744 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1535,6 +1535,29 @@ $ac_try"
   use_default_link=$libc_cv_use_default_link
 fi
 
+AC_CACHE_CHECK(for GLOB_DAT reloc,
+	       libc_cv_has_glob_dat, [dnl
+cat > conftest.c <<EOF
+extern int mumble;
+int foo (void) { return mumble; }
+EOF
+if AC_TRY_COMMAND([${CC-cc} $CFLAGS $CPPFLAGS $LDFLAGS
+			-fPIC -shared -o conftest.so conftest.c
+			-nostdlib -nostartfiles
+			1>&AS_MESSAGE_LOG_FD])
+then
+dnl look for GLOB_DAT relocation.
+  if $READELF -rW conftest.so | grep '_GLOB_DAT' > /dev/null; then
+    libc_cv_has_glob_dat=yes
+  else
+    libc_cv_has_glob_dat=no
+  fi
+else
+  libc_cv_has_glob_dat=no
+fi
+rm -f conftest*])
+AC_SUBST(libc_cv_has_glob_dat)
+
 AC_CACHE_CHECK(linker output format, libc_cv_output_format, [dnl
 if libc_cv_output_format=`
 ${CC-cc} -nostartfiles -nostdlib -Wl,--print-output-format 2>&AS_MESSAGE_LOG_FD`
diff --git a/elf/Makefile b/elf/Makefile
index 71a18a1ec4..a2c43bcdc3 100644
--- a/elf/Makefile
+++ b/elf/Makefile
@@ -293,6 +293,13 @@ check-abi: $(objpfx)check-abi-ld.out
 tests-special += $(objpfx)check-abi-ld.out
 update-abi: update-abi-ld
 
+ifeq ($(have-glob-dat-reloc),yes)
+tests += tst-prelink
+ifeq ($(run-built-tests),yes)
+tests-special += $(objpfx)tst-prelink-cmp.out
+endif
+endif
+
 include ../Rules
 
 ifeq (yes,$(build-shared))
@@ -1212,3 +1219,13 @@ $(objpfx)tst-unused-dep.out: $(objpfx)testobj1.so
 $(objpfx)tst-unused-dep-cmp.out: $(objpfx)tst-unused-dep.out
 	cmp $< /dev/null > $@; \
 	$(evaluate-test)
+
+tst-prelink-ENV = LD_TRACE_PRELINKING=1
+
+$(objpfx)tst-prelink-conflict.out: $(objpfx)tst-prelink.out
+	grep stdout $< | grep conflict | $(AWK) '{ print $$10, $$11 }' > $@
+
+$(objpfx)tst-prelink-cmp.out: tst-prelink.exp \
+			      $(objpfx)tst-prelink-conflict.out
+	cmp $^ > $@; \
+	$(evaluate-test)
diff --git a/elf/dl-load.c b/elf/dl-load.c
index 0c052e449a..7e6f4c52d1 100644
--- a/elf/dl-load.c
+++ b/elf/dl-load.c
@@ -42,6 +42,7 @@
 #include <dl-map-segments.h>
 #include <dl-unmap-segments.h>
 #include <dl-machine-reject-phdr.h>
+#include <dl-sysdep-open.h>
 
 
 #include <endian.h>
@@ -1471,9 +1472,13 @@ print_search_path (struct r_search_path_elem **list,
    ignore only ELF files for other architectures.  Non-ELF files and
    ELF files with different header information cause fatal errors since
    this could mean there is something wrong in the installation and the
-   user might want to know about this.  */
+   user might want to know about this.
+
+   If FD is not -1, then the file is already open and FD refers to it.
+   In that case, FD is consumed for both successful and error returns.  */
 static int
-open_verify (const char *name, struct filebuf *fbp, struct link_map *loader,
+open_verify (const char *name, int fd,
+             struct filebuf *fbp, struct link_map *loader,
 	     int whatcode, int mode, bool *found_other_class, bool free_name)
 {
   /* This is the expected ELF header.  */
@@ -1514,6 +1519,7 @@ open_verify (const char *name, struct filebuf *fbp, struct link_map *loader,
   if (__glibc_unlikely (GLRO(dl_naudit) > 0) && whatcode != 0
       && loader->l_auditing == 0)
     {
+      const char *original_name = name;
       struct audit_ifaces *afct = GLRO(dl_audit);
       for (unsigned int cnt = 0; cnt < GLRO(dl_naudit); ++cnt)
 	{
@@ -1528,11 +1534,21 @@ open_verify (const char *name, struct filebuf *fbp, struct link_map *loader,
 
 	  afct = afct->next;
 	}
+
+      if (fd != -1 && name != original_name && strcmp (name, original_name))
+        {
+          /* An audit library changed what we're supposed to open,
+             so FD no longer matches it.  */
+          __close (fd);
+          fd = -1;
+        }
     }
 #endif
 
-  /* Open the file.  We always open files read-only.  */
-  int fd = __open (name, O_RDONLY | O_CLOEXEC);
+  if (fd == -1)
+    /* Open the file.  We always open files read-only.  */
+    fd = __open (name, O_RDONLY | O_CLOEXEC);
+
   if (fd != -1)
     {
       ElfW(Ehdr) *ehdr;
@@ -1801,7 +1817,7 @@ open_path (const char *name, size_t namelen, int mode,
 	  if (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_LIBS))
 	    _dl_debug_printf ("  trying file=%s\n", buf);
 
-	  fd = open_verify (buf, fbp, loader, whatcode, mode,
+	  fd = open_verify (buf, -1, fbp, loader, whatcode, mode,
 			    found_other_class, false);
 	  if (this_dir->status[cnt] == unknown)
 	    {
@@ -2041,6 +2057,20 @@ _dl_map_object (struct link_map *loader, const char *name,
 			&loader->l_runpath_dirs, &realname, &fb, loader,
 			LA_SER_RUNPATH, &found_other_class);
 
+      if (fd == -1)
+        {
+          realname = _dl_sysdep_open_object (name, namelen, &fd);
+          if (realname != NULL)
+            {
+              fd = open_verify (realname, fd,
+                                &fb, loader ?: GL(dl_ns)[nsid]._ns_loaded,
+                                LA_SER_CONFIG, mode, &found_other_class,
+                                false);
+              if (fd == -1)
+                free (realname);
+            }
+        }
+
 #ifdef USE_LDCONFIG
       if (fd == -1
 	  && (__glibc_likely ((mode & __RTLD_SECURE) == 0)
@@ -2086,7 +2116,7 @@ _dl_map_object (struct link_map *loader, const char *name,
 
 	      if (cached != NULL)
 		{
-		  fd = open_verify (cached,
+		  fd = open_verify (cached, -1,
 				    &fb, loader ?: GL(dl_ns)[nsid]._ns_loaded,
 				    LA_SER_CONFIG, mode, &found_other_class,
 				    false);
@@ -2121,7 +2151,7 @@ _dl_map_object (struct link_map *loader, const char *name,
 	fd = -1;
       else
 	{
-	  fd = open_verify (realname, &fb,
+	  fd = open_verify (realname, -1, &fb,
 			    loader ?: GL(dl_ns)[nsid]._ns_loaded, 0, mode,
 			    &found_other_class, true);
 	  if (__glibc_unlikely (fd == -1))
diff --git a/elf/dl-lookup.c b/elf/dl-lookup.c
index 11cb44b451..acf52807df 100644
--- a/elf/dl-lookup.c
+++ b/elf/dl-lookup.c
@@ -1016,6 +1016,18 @@ _dl_debug_bindings (const char *undef_name, struct link_map *undef_map,
 #ifdef SHARED
   if (GLRO(dl_debug_mask) & DL_DEBUG_PRELINK)
     {
+/* ELF_RTYPE_CLASS_XXX must match RTYPE_CLASS_XXX used by prelink with
+   LD_TRACE_PRELINKING.  */
+#define RTYPE_CLASS_VALID	8
+#define RTYPE_CLASS_PLT		(8|1)
+#define RTYPE_CLASS_COPY	(8|2)
+#define RTYPE_CLASS_TLS		(8|4)
+#if ELF_RTYPE_CLASS_PLT != 0 && ELF_RTYPE_CLASS_PLT != 1
+# error ELF_RTYPE_CLASS_PLT must be 0 or 1!
+#endif
+#if ELF_RTYPE_CLASS_COPY != 0 && ELF_RTYPE_CLASS_COPY != 2
+# error ELF_RTYPE_CLASS_COPY must be 0 or 2!
+#endif
       int conflict = 0;
       struct sym_val val = { NULL, NULL };
 
@@ -1071,12 +1083,17 @@ _dl_debug_bindings (const char *undef_name, struct link_map *undef_map,
 
       if (value->s)
 	{
+	  /* Keep only ELF_RTYPE_CLASS_PLT and ELF_RTYPE_CLASS_COPY
+	     bits since since prelink only uses them.  */
+	  type_class &= ELF_RTYPE_CLASS_PLT | ELF_RTYPE_CLASS_COPY;
 	  if (__glibc_unlikely (ELFW(ST_TYPE) (value->s->st_info)
 				== STT_TLS))
-	    type_class = 4;
+	    /* Clear the RTYPE_CLASS_VALID bit in RTYPE_CLASS_TLS.  */
+	    type_class = RTYPE_CLASS_TLS & ~RTYPE_CLASS_VALID;
 	  else if (__glibc_unlikely (ELFW(ST_TYPE) (value->s->st_info)
 				     == STT_GNU_IFUNC))
-	    type_class |= 8;
+	    /* Set the RTYPE_CLASS_VALID bit.  */
+	    type_class |= RTYPE_CLASS_VALID;
 	}
 
       if (conflict
diff --git a/elf/dl-sysdep-open.h b/elf/dl-sysdep-open.h
new file mode 100644
index 0000000000..a63d9f5f78
--- /dev/null
+++ b/elf/dl-sysdep-open.h
@@ -0,0 +1,45 @@
+/* System-specific call to open a shared object by name.  Stub version.
+   Copyright (C) 2015 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, see
+   <http://www.gnu.org/licenses/>.  */
+
+#ifndef _DL_SYSDEP_OPEN_H
+#define _DL_SYSDEP_OPEN_H	1
+
+#include <assert.h>
+#include <stddef.h>
+
+/* NAME is a name without slashes, as it appears in a DT_NEEDED entry
+   or a dlopen call's argument or suchlike.  NAMELEN is (strlen (NAME) + 1).
+
+   Find NAME in an OS-dependent fashion, and return its "real" name.
+   Optionally fill in *FD with a file descriptor open on that file (or
+   else leave its initial value of -1).  The return value is a new
+   malloc'd string, which will be free'd by the caller.  If NAME is
+   resolved to an actual file that can be opened, then the return
+   value should name that file (and if *FD was not set, then a normal
+   __open call on that string will be made).  If *FD was set by some
+   other means than a normal open and there is no "real" name to use,
+   then __strdup (NAME) is fine (modulo error checking).  */
+
+static inline char *
+_dl_sysdep_open_object (const char *name, size_t namelen, int *fd)
+{
+  assert (*fd == -1);
+  return NULL;
+}
+
+#endif  /* dl-sysdep-open.h */
diff --git a/elf/tst-prelink.c b/elf/tst-prelink.c
new file mode 100644
index 0000000000..ab61c4ef31
--- /dev/null
+++ b/elf/tst-prelink.c
@@ -0,0 +1,30 @@
+/* Test the output from the environment variable, LD_TRACE_PRELINKING,
+   for prelink.
+   Copyright (C) 2015 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, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <stdio.h>
+
+static int
+do_test (void)
+{
+  fprintf (stdout, "hello\n");
+  return 0;
+}
+
+#define TEST_FUNCTION do_test ()
+#include "../test-skeleton.c"
diff --git a/elf/tst-prelink.exp b/elf/tst-prelink.exp
new file mode 100644
index 0000000000..b35b4c9705
--- /dev/null
+++ b/elf/tst-prelink.exp
@@ -0,0 +1 @@
+/0 stdout
diff --git a/math/Makefile b/math/Makefile
index 6388baec89..2c9d72da0b 100644
--- a/math/Makefile
+++ b/math/Makefile
@@ -98,7 +98,7 @@ $(inst_libdir)/libm.so: $(common-objpfx)format.lds \
 	(echo '/* GNU ld script'; echo '*/';\
 	 cat $<; \
 	 echo 'GROUP ( $(slibdir)/libm.so$(libm.so-version) ' \
-	      'AS_NEEDED ( $(slibdir)/libmvec.so$(libmvec.so-version) ) )' \
+	      'AS_NEEDED ( $(libdir)/libmvec_nonshared.a $(slibdir)/libmvec.so$(libmvec.so-version) ) )' \
 	) > $@
 endif
 
diff --git a/sysdeps/nacl/dl-map-segments.h b/sysdeps/nacl/dl-map-segments.h
index f305da304a..f2d5d84dcd 100644
--- a/sysdeps/nacl/dl-map-segments.h
+++ b/sysdeps/nacl/dl-map-segments.h
@@ -53,7 +53,7 @@ _dl_map_segments (struct link_map *l, int fd,
 		  const size_t maplength, bool has_holes,
 		  struct link_map *loader)
 {
-  if (__builtin_expect (type, ET_DYN) == ET_DYN)
+  if (__glibc_likely (type == ET_DYN))
     {
       /* This is a position-independent shared object.  Let the system
 	 choose where to place it.
@@ -165,6 +165,32 @@ _dl_map_segments (struct link_map *l, int fd,
 		    errno = error;
 		    return DL_MAP_SEGMENTS_ERROR_MAP_SEGMENT;
 		  }
+                if (__glibc_unlikely (type != ET_DYN))
+                  {
+                    /* A successful PROT_EXEC mmap would have implicitly
+                       updated the bookkeeping so that a future
+                       allocate_code_data call would know that this range
+                       of the address space is already occupied.  That
+                       doesn't happen implicitly with dyncode_create, so
+                       it's necessary to do an explicit call to update the
+                       bookkeeping.  */
+                    uintptr_t allocated_address;
+                    error = __nacl_irt_code_data_alloc.allocate_code_data
+                      (l->l_addr + c->mapstart, len, 0, 0, &allocated_address);
+                    if (__glibc_unlikely (error))
+                      {
+                        errno = error;
+                        return DL_MAP_SEGMENTS_ERROR_MAP_SEGMENT;
+                      }
+                    if (__glibc_unlikely
+                        (allocated_address != l->l_addr + c->mapstart))
+                      {
+                        /* This is not a very helpful error for this case,
+                           but there isn't really anything better to use.  */
+                        errno = ENOMEM;
+                        return DL_MAP_SEGMENTS_ERROR_MAP_SEGMENT;
+                      }
+                  }
 	      }
 	    else
 	      {
diff --git a/sysdeps/nacl/dl-sysdep-open.h b/sysdeps/nacl/dl-sysdep-open.h
new file mode 100644
index 0000000000..38b0f9e86d
--- /dev/null
+++ b/sysdeps/nacl/dl-sysdep-open.h
@@ -0,0 +1,40 @@
+/* System-specific call to open a shared object by name.  NaCl version.
+   Copyright (C) 2015 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, see
+   <http://www.gnu.org/licenses/>.  */
+
+#ifndef _DL_SYSDEP_OPEN_H
+#define _DL_SYSDEP_OPEN_H	1
+
+#include <stddef.h>
+
+/* NAME is a name without slashes, as it appears in a DT_NEEDED entry
+   or a dlopen call's argument or suchlike.  NAMELEN is (strlen (NAME) + 1).
+
+   Find NAME in an OS-dependent fashion, and return its "real" name.
+   Optionally fill in *FD with a file descriptor open on that file (or
+   else leave its initial value of -1).  The return value is a new
+   malloc'd string, which will be free'd by the caller.  If NAME is
+   resolved to an actual file that can be opened, then the return
+   value should name that file (and if *FD was not set, then a normal
+   __open call on that string will be made).  If *FD was set by some
+   other means than a normal open and there is no "real" name to use,
+   then __strdup (NAME) is fine (modulo error checking).  */
+
+extern char *_dl_sysdep_open_object (const char *name, size_t namelen, int *fd)
+  internal_function attribute_hidden;
+
+#endif  /* dl-sysdep-open.h */
diff --git a/sysdeps/nacl/dl-sysdep.c b/sysdeps/nacl/dl-sysdep.c
index 3e902c2cae..3a04aa1176 100644
--- a/sysdeps/nacl/dl-sysdep.c
+++ b/sysdeps/nacl/dl-sysdep.c
@@ -87,3 +87,26 @@ _dl_start_user (void (*user_entry) (uint32_t info[]), uint32_t info[])
 #endif  /* SHARED */
 
 #include <elf/dl-sysdep.c>
+
+#include <dl-sysdep-open.h>
+#include <nacl-interfaces.h>
+#include <assert.h>
+#include <string.h>
+#include <unistd.h>
+
+char *
+internal_function
+_dl_sysdep_open_object (const char *name, size_t namelen, int *fd)
+{
+  int error = __nacl_irt_resource_open.open_resource (name, fd);
+  if (error)
+    return NULL;
+  assert (*fd != -1);
+  char *realname = __strdup (name);
+  if (__glibc_unlikely (realname == NULL))
+    {
+      __close (*fd);
+      *fd = -1;
+    }
+  return realname;
+}
diff --git a/sysdeps/nacl/nacl-interface-list.h b/sysdeps/nacl/nacl-interface-list.h
index cb337510fc..c68faedc54 100644
--- a/sysdeps/nacl/nacl-interface-list.h
+++ b/sysdeps/nacl/nacl-interface-list.h
@@ -28,7 +28,7 @@ NACL_MANDATORY_INTERFACE (rtld,
 			  NACL_IRT_FUTEX_v0_1, nacl_irt_futex)
 NACL_MANDATORY_INTERFACE (rtld,
 			  NACL_IRT_TLS_v0_1, nacl_irt_tls)
-NACL_MANDATORY_INTERFACE (libc,
+NACL_MANDATORY_INTERFACE (rtld,
 			  NACL_IRT_RESOURCE_OPEN_v0_1, nacl_irt_resource_open)
 NACL_MANDATORY_INTERFACE (rtld,
 			  NACL_IRT_CODE_DATA_ALLOC_v0_1,
diff --git a/sysdeps/powerpc/nptl/elide.h b/sysdeps/powerpc/nptl/elide.h
index 12171f45dc..2e1e443278 100644
--- a/sysdeps/powerpc/nptl/elide.h
+++ b/sysdeps/powerpc/nptl/elide.h
@@ -27,7 +27,7 @@
    configurations.  Returns true if the system should retry again or false
    otherwise.  */
 static inline bool
-__get_new_count (uint8_t *adapt_count)
+__get_new_count (uint8_t *adapt_count, int attempt)
 {
   /* A persistent failure indicates that a retry will probably
      result in another failure.  Use normal locking now and
@@ -40,7 +40,7 @@ __get_new_count (uint8_t *adapt_count)
     }
   /* Same logic as above, but for a number of temporary failures in a
      a row.  */
-  else if (__elision_aconf.skip_lock_out_of_tbegin_retries > 0
+  else if (attempt <= 1 && __elision_aconf.skip_lock_out_of_tbegin_retries > 0
 	   && __elision_aconf.try_tbegin > 0)
     *adapt_count = __elision_aconf.skip_lock_out_of_tbegin_retries;
   return true;
@@ -78,7 +78,7 @@ __get_new_count (uint8_t *adapt_count)
 	      __builtin_tabort (_ABORT_LOCK_BUSY);			\
 	    }								\
 	  else								\
-	    if (!__get_new_count(&adapt_count))				\
+	    if (!__get_new_count (&adapt_count,i))			\
 	      break;							\
 	}								\
     ret;								\
diff --git a/sysdeps/unix/sysv/linux/powerpc/elision-lock.c b/sysdeps/unix/sysv/linux/powerpc/elision-lock.c
index 26d272e619..7b6c806ab5 100644
--- a/sysdeps/unix/sysv/linux/powerpc/elision-lock.c
+++ b/sysdeps/unix/sysv/linux/powerpc/elision-lock.c
@@ -51,8 +51,7 @@ __lll_lock_elision (int *lock, short *adapt_count, EXTRAARG int pshared)
       goto use_lock;
     }
 
-  int try_begin = aconf.try_tbegin;
-  while (1)
+  for (int i = aconf.try_tbegin; i > 0; i--)
     {
       if (__builtin_tbegin (0))
 	{
@@ -66,21 +65,19 @@ __lll_lock_elision (int *lock, short *adapt_count, EXTRAARG int pshared)
 	  /* A persistent failure indicates that a retry will probably
 	     result in another failure.  Use normal locking now and
 	     for the next couple of calls.  */
-	  if (try_begin-- <= 0
-	      || _TEXASRU_FAILURE_PERSISTENT (__builtin_get_texasru ()))
+	  if (_TEXASRU_FAILURE_PERSISTENT (__builtin_get_texasru ()))
 	    {
 	      if (aconf.skip_lock_internal_abort > 0)
 		*adapt_count = aconf.skip_lock_internal_abort;
 	      goto use_lock;
 	    }
-	  /* Same logic as above, but for for a number of temporary failures
-	     in a row.  */
-	  else if (aconf.skip_lock_out_of_tbegin_retries > 0
-                   && aconf.try_tbegin > 0)
-	    *adapt_count = aconf.skip_lock_out_of_tbegin_retries;
 	}
      }
 
+  /* Fall back to locks for a bit if retries have been exhausted */
+  if (aconf.try_tbegin > 0 && aconf.skip_lock_out_of_tbegin_retries > 0)
+    *adapt_count = aconf.skip_lock_out_of_tbegin_retries;
+
 use_lock:
   return LLL_LOCK ((*lock), pshared);
 }
diff --git a/sysdeps/x86/fpu/bits/math-vector.h b/sysdeps/x86/fpu/bits/math-vector.h
index f9e798b556..f3bfb869d4 100644
--- a/sysdeps/x86/fpu/bits/math-vector.h
+++ b/sysdeps/x86/fpu/bits/math-vector.h
@@ -53,34 +53,5 @@
 #  undef __DECL_SIMD_powf
 #  define __DECL_SIMD_powf __DECL_SIMD_x86_64
 
-/* Workaround to exclude unnecessary symbol aliases in libmvec
-   while GCC creates the vector names based on scalar asm name.
-   Corresponding discussion started at
-   <https://gcc.gnu.org/ml/gcc/2015-06/msg00173.html>.  */
-__asm__ ("_ZGVbN2v___log_finite = _ZGVbN2v_log");
-__asm__ ("_ZGVcN4v___log_finite = _ZGVcN4v_log");
-__asm__ ("_ZGVdN4v___log_finite = _ZGVdN4v_log");
-__asm__ ("_ZGVeN8v___log_finite = _ZGVeN8v_log");
-__asm__ ("_ZGVbN4v___logf_finite = _ZGVbN4v_logf");
-__asm__ ("_ZGVcN8v___logf_finite = _ZGVcN8v_logf");
-__asm__ ("_ZGVdN8v___logf_finite = _ZGVdN8v_logf");
-__asm__ ("_ZGVeN16v___logf_finite = _ZGVeN16v_logf");
-__asm__ ("_ZGVbN2v___exp_finite = _ZGVbN2v_exp");
-__asm__ ("_ZGVcN4v___exp_finite = _ZGVcN4v_exp");
-__asm__ ("_ZGVdN4v___exp_finite = _ZGVdN4v_exp");
-__asm__ ("_ZGVeN8v___exp_finite = _ZGVeN8v_exp");
-__asm__ ("_ZGVbN4v___expf_finite = _ZGVbN4v_expf");
-__asm__ ("_ZGVcN8v___expf_finite = _ZGVcN8v_expf");
-__asm__ ("_ZGVdN8v___expf_finite = _ZGVdN8v_expf");
-__asm__ ("_ZGVeN16v___expf_finite = _ZGVeN16v_expf");
-__asm__ ("_ZGVbN2vv___pow_finite = _ZGVbN2vv_pow");
-__asm__ ("_ZGVcN4vv___pow_finite = _ZGVcN4vv_pow");
-__asm__ ("_ZGVdN4vv___pow_finite = _ZGVdN4vv_pow");
-__asm__ ("_ZGVeN8vv___pow_finite = _ZGVeN8vv_pow");
-__asm__ ("_ZGVbN4vv___powf_finite = _ZGVbN4vv_powf");
-__asm__ ("_ZGVcN8vv___powf_finite = _ZGVcN8vv_powf");
-__asm__ ("_ZGVdN8vv___powf_finite = _ZGVdN8vv_powf");
-__asm__ ("_ZGVeN16vv___powf_finite = _ZGVeN16vv_powf");
-
 # endif
 #endif
diff --git a/sysdeps/x86_64/fpu/Makefile b/sysdeps/x86_64/fpu/Makefile
index 1ebe5118bf..b32b85274a 100644
--- a/sysdeps/x86_64/fpu/Makefile
+++ b/sysdeps/x86_64/fpu/Makefile
@@ -20,7 +20,10 @@ libmvec-support += svml_d_cos2_core svml_d_cos4_core_avx \
 		   svml_d_pow_data svml_s_powf4_core svml_s_powf8_core_avx \
 		   svml_s_powf8_core svml_s_powf16_core svml_s_powf_data \
 		   svml_s_sincosf4_core svml_s_sincosf8_core_avx \
-		   svml_s_sincosf8_core svml_s_sincosf16_core init-arch
+		   svml_s_sincosf8_core svml_s_sincosf16_core init-arch \
+		   svml_finite_alias
+
+libmvec-static-only-routines = svml_finite_alias
 endif
 
 # Variables for libmvec tests.
diff --git a/sysdeps/x86_64/fpu/svml_finite_alias.S b/sysdeps/x86_64/fpu/svml_finite_alias.S
new file mode 100644
index 0000000000..f8bcfeb550
--- /dev/null
+++ b/sysdeps/x86_64/fpu/svml_finite_alias.S
@@ -0,0 +1,59 @@
+/* These aliases added as workaround to exclude unnecessary symbol
+   aliases in libmvec.so while compiler creates the vector names
+   based on scalar asm name.  Corresponding discussion is at
+   <https://gcc.gnu.org/ml/gcc/2015-06/msg00173.html>.
+   Copyright (C) 2015 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, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <sysdep.h>
+
+#define ALIAS_IMPL(alias, target) \
+ENTRY (alias); \
+	call target; \
+	ret; \
+END (alias)
+
+	.text
+ALIAS_IMPL (_ZGVbN2v___log_finite, _ZGVbN2v_log)
+ALIAS_IMPL (_ZGVcN4v___log_finite, _ZGVcN4v_log)
+ALIAS_IMPL (_ZGVdN4v___log_finite, _ZGVdN4v_log)
+ALIAS_IMPL (_ZGVeN8v___log_finite, _ZGVeN8v_log)
+
+ALIAS_IMPL (_ZGVbN4v___logf_finite, _ZGVbN4v_logf)
+ALIAS_IMPL (_ZGVcN8v___logf_finite, _ZGVcN8v_logf)
+ALIAS_IMPL (_ZGVdN8v___logf_finite, _ZGVdN8v_logf)
+ALIAS_IMPL (_ZGVeN16v___logf_finite, _ZGVeN16v_logf)
+
+ALIAS_IMPL (_ZGVbN2v___exp_finite, _ZGVbN2v_exp)
+ALIAS_IMPL (_ZGVcN4v___exp_finite, _ZGVcN4v_exp)
+ALIAS_IMPL (_ZGVdN4v___exp_finite, _ZGVdN4v_exp)
+ALIAS_IMPL (_ZGVeN8v___exp_finite, _ZGVeN8v_exp)
+
+ALIAS_IMPL (_ZGVbN4v___expf_finite, _ZGVbN4v_expf)
+ALIAS_IMPL (_ZGVcN8v___expf_finite, _ZGVcN8v_expf)
+ALIAS_IMPL (_ZGVdN8v___expf_finite, _ZGVdN8v_expf)
+ALIAS_IMPL (_ZGVeN16v___expf_finite, _ZGVeN16v_expf)
+
+ALIAS_IMPL (_ZGVbN2vv___pow_finite, _ZGVbN2vv_pow)
+ALIAS_IMPL (_ZGVcN4vv___pow_finite, _ZGVcN4vv_pow)
+ALIAS_IMPL (_ZGVdN4vv___pow_finite, _ZGVdN4vv_pow)
+ALIAS_IMPL (_ZGVeN8vv___pow_finite, _ZGVeN8vv_pow)
+
+ALIAS_IMPL (_ZGVbN4vv___powf_finite, _ZGVbN4vv_powf)
+ALIAS_IMPL (_ZGVcN8vv___powf_finite, _ZGVcN8vv_powf)
+ALIAS_IMPL (_ZGVdN8vv___powf_finite, _ZGVdN8vv_powf)
+ALIAS_IMPL (_ZGVeN16vv___powf_finite, _ZGVeN16vv_powf)