This is the mail archive of the glibc-cvs@sourceware.org mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

GNU C Library master sources branch linaro/2.23/master updated. glibc-2.23-95-g058b5a4


This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "GNU C Library master sources".

The branch, linaro/2.23/master has been updated
       via  058b5a41d56b9a8860dede14d97dd443792d064b (commit)
       via  afb035f50b140f808f52d11e3155ed555fb37e8c (commit)
       via  254269d6a9d5c025b5e1df31f4019daadf6a35bb (commit)
       via  d7d49b08413124b03f227f5fe06aa811a52c2b23 (commit)
       via  fa9a646079950ea326e1f2feee7093580dc1ecd3 (commit)
       via  d848d802563193cbc9a8113577eab582a958d994 (commit)
       via  1ec838a143b35f65169acc455308eb20198a4853 (commit)
       via  2eb71adc3fc023c026b88bdfce69561f1f91ee4a (commit)
      from  e124685d6140c870fd2de18545a58bd0b8d91177 (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=058b5a41d56b9a8860dede14d97dd443792d064b

commit 058b5a41d56b9a8860dede14d97dd443792d064b
Author: Florian Weimer <fweimer@redhat.com>
Date:   Fri Aug 26 22:40:27 2016 +0200

    malloc: Simplify static malloc interposition [BZ #20432]
    
    Existing interposed mallocs do not define the glibc-internal
    fork callbacks (and they should not), so statically interposed
    mallocs lead to link failures because the strong reference from
    fork pulls in glibc's malloc, resulting in multiple definitions
    of malloc-related symbols.

diff --git a/ChangeLog b/ChangeLog
index ea446d3..66bbb17 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,37 @@
+2016-08-26  Florian Weimer  <fweimer@redhat.com>
+
+	[BZ #20432]
+	Avoid strong references to malloc-internal symbols when linking
+	statically, to support statically interposed mallocs.
+	* include/libc-symbols.h (call_function_static_weak): New macro.
+	* malloc/Makefile (tests): Add tst-interpose-nothread,
+	tst-interpose-thread, tst-interpose-static-nothread,
+	tst-interpose-static-thread.
+	(tests-static): Add tst-interpose-static-nothread,
+	tst-interpose-static-thread.
+	(extra-tests-objs): Add tst-interpose-aux-nothread.o,
+	tst-interpose-aux-thread.o.
+	(test-extras): Add tst-interpose-aux-nothread,
+	tst-interpose-aux-thread.
+	(tst-interpose-nothread, tst-interpose-static-nothread): Link with
+	tst-interpose-aux-nothread.o.
+	(tst-interpose-thread, tst-interpose-static-thread): Link with
+	tst-interpose-aux-thread.o and libthread.
+	* malloc/tst-interpose-aux-nothread.c: New file.
+	* malloc/tst-interpose-aux-thread.c: Likewise.
+	* malloc/tst-interpose-aux.c: Likewise.
+	* malloc/tst-interpose-aux.h: Likewise.
+	* malloc/tst-interpose-nothread.c: Likewise.
+	* malloc/tst-interpose-skeleton.c: Likewise.
+	* malloc/tst-interpose-static-nothread.c: Likewise.
+	* malloc/tst-interpose-static-thread.c: Likewise.
+	* malloc/tst-interpose-thread.c: Likewise.
+	* nptl/tst-tls3-malloc.c: Use new interposed malloc.
+	* sysdeps/mach/hurd/fork.c (__fork): Only call
+	__malloc_fork_lock_parent, __malloc_fork_unlock_parent,
+	__malloc_fork_unlock_child if defined.
+	* sysdeps/nptl/fork.c (__libc_fork): Likewise.
+
 2016-08-16  Florian Weimer  <fweimer@redhat.com>
 
 	* nptl/tst-tls3.c (default_stack_size_in_mb, stack_size_in_mb):
diff --git a/include/libc-symbols.h b/include/libc-symbols.h
index 4548e09..8245885 100644
--- a/include/libc-symbols.h
+++ b/include/libc-symbols.h
@@ -121,6 +121,21 @@
 # define weak_extern(symbol) _weak_extern (weak symbol)
 # define _weak_extern(expr) _Pragma (#expr)
 
+/* In shared builds, the expression call_function_static_weak
+   (FUNCTION-SYMBOL, ARGUMENTS) invokes FUNCTION-SYMBOL (an
+   identifier) unconditionally, with the (potentially empty) argument
+   list ARGUMENTS.  In static builds, if FUNCTION-SYMBOL has a
+   definition, the function is invoked as before; if FUNCTION-SYMBOL
+   is NULL, no call is performed.  */
+# ifdef SHARED
+#  define call_function_static_weak(func, ...) func (__VA_ARGS__)
+# else	/* !SHARED */
+#  define call_function_static_weak(func, ...)		\
+  ({							\
+    extern __typeof__ (func) func weak_function;	\
+    (func != NULL ? func (__VA_ARGS__) : (void)0);	\
+  })
+# endif
 
 #else /* __ASSEMBLER__ */
 
diff --git a/malloc/Makefile b/malloc/Makefile
index 4d5c81d..037e830 100644
--- a/malloc/Makefile
+++ b/malloc/Makefile
@@ -30,7 +30,16 @@ tests := mallocbug tst-malloc tst-valloc tst-calloc tst-obstack \
 	 tst-pvalloc tst-memalign tst-mallopt tst-scratch_buffer \
 	 tst-malloc-backtrace tst-malloc-thread-exit \
 	 tst-malloc-thread-fail tst-malloc-fork-deadlock \
-	 tst-mallocfork2
+	 tst-mallocfork2 \
+	 tst-interpose-nothread \
+	 tst-interpose-thread \
+	 tst-interpose-static-nothread \
+	 tst-interpose-static-thread \
+
+tests-static := \
+	 tst-interpose-static-nothread \
+	 tst-interpose-static-thread \
+
 test-srcs = tst-mtrace
 
 routines = malloc morecore mcheck mtrace obstack \
@@ -44,6 +53,15 @@ non-lib.a := libmcheck.a
 extra-libs = libmemusage
 extra-libs-others = $(extra-libs)
 
+# Helper objects for some tests.
+extra-tests-objs += \
+  tst-interpose-aux-nothread.o \
+  tst-interpose-aux-thread.o \
+
+test-extras = \
+  tst-interpose-aux-nothread \
+  tst-interpose-aux-thread \
+
 libmemusage-routines = memusage
 libmemusage-inhibit-o = $(filter-out .os,$(object-suffixes))
 
@@ -170,3 +188,10 @@ $(foreach o,$(all-object-suffixes),$(objpfx)malloc$(o)): arena.c hooks.c
 # Compile the tests with a flag which suppresses the mallopt call in
 # the test skeleton.
 $(tests:%=$(objpfx)%.o): CPPFLAGS += -DTEST_NO_MALLOPT
+
+$(objpfx)tst-interpose-nothread: $(objpfx)tst-interpose-aux-nothread.o
+$(objpfx)tst-interpose-thread: \
+  $(objpfx)tst-interpose-aux-thread.o $(shared-thread-library)
+$(objpfx)tst-interpose-static-nothread: $(objpfx)tst-interpose-aux-nothread.o
+$(objpfx)tst-interpose-static-thread: \
+  $(objpfx)tst-interpose-aux-thread.o $(static-thread-library)
diff --git a/malloc/tst-interpose-aux-nothread.c b/malloc/tst-interpose-aux-nothread.c
new file mode 100644
index 0000000..0eae66f
--- /dev/null
+++ b/malloc/tst-interpose-aux-nothread.c
@@ -0,0 +1,20 @@
+/* Interposed malloc, version without threading support.
+   Copyright (C) 2016 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; see the file COPYING.LIB.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#define INTERPOSE_THREADS 0
+#include "tst-interpose-aux.c"
diff --git a/malloc/tst-interpose-aux-thread.c b/malloc/tst-interpose-aux-thread.c
new file mode 100644
index 0000000..354e4d8
--- /dev/null
+++ b/malloc/tst-interpose-aux-thread.c
@@ -0,0 +1,20 @@
+/* Interposed malloc, version with threading support.
+   Copyright (C) 2016 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; see the file COPYING.LIB.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#define INTERPOSE_THREADS 1
+#include "tst-interpose-aux.c"
diff --git a/malloc/tst-interpose-aux.c b/malloc/tst-interpose-aux.c
new file mode 100644
index 0000000..77866b2
--- /dev/null
+++ b/malloc/tst-interpose-aux.c
@@ -0,0 +1,270 @@
+/* Minimal malloc implementation for interposition tests.
+   Copyright (C) 2016 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; see the file COPYING.LIB.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#include "tst-interpose-aux.h"
+
+#include <errno.h>
+#include <stdarg.h>
+#include <stddef.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/mman.h>
+#include <sys/uio.h>
+#include <unistd.h>
+
+#if INTERPOSE_THREADS
+#include <pthread.h>
+#endif
+
+/* Print the error message and terminate the process with status 1.  */
+__attribute__ ((noreturn))
+__attribute__ ((format (printf, 1, 2)))
+static void *
+fail (const char *format, ...)
+{
+  /* This assumes that vsnprintf will not call malloc.  It does not do
+     so for the format strings we use.  */
+  char message[4096];
+  va_list ap;
+  va_start (ap, format);
+  vsnprintf (message, sizeof (message), format, ap);
+  va_end (ap);
+
+  enum { count = 3 };
+  struct iovec iov[count];
+
+  iov[0].iov_base = (char *) "error: ";
+  iov[1].iov_base = (char *) message;
+  iov[2].iov_base = (char *) "\n";
+
+  for (int i = 0; i < count; ++i)
+    iov[i].iov_len = strlen (iov[i].iov_base);
+
+  int unused __attribute__ ((unused));
+  unused = writev (STDOUT_FILENO, iov, count);
+  _exit (1);
+}
+
+#if INTERPOSE_THREADS
+static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
+#endif
+
+static void
+lock (void)
+{
+#if INTERPOSE_THREADS
+  int ret = pthread_mutex_lock (&mutex);
+  if (ret != 0)
+    {
+      errno = ret;
+      fail ("pthread_mutex_lock: %m");
+    }
+#endif
+}
+
+static void
+unlock (void)
+{
+#if INTERPOSE_THREADS
+  int ret = pthread_mutex_unlock (&mutex);
+  if (ret != 0)
+    {
+      errno = ret;
+      fail ("pthread_mutex_unlock: %m");
+    }
+#endif
+}
+
+struct __attribute__ ((aligned (__alignof__ (max_align_t)))) allocation_header
+{
+  size_t allocation_index;
+  size_t allocation_size;
+};
+
+/* Array of known allocations, to track invalid frees.  */
+enum { max_allocations = 65536 };
+static struct allocation_header *allocations[max_allocations];
+static size_t allocation_index;
+static size_t deallocation_count;
+
+/* Sanity check for successful malloc interposition.  */
+__attribute__ ((destructor))
+static void
+check_for_allocations (void)
+{
+  if (allocation_index == 0)
+    {
+      /* Make sure that malloc is called at least once from libc.  */
+      void *volatile ptr = strdup ("ptr");
+      free (ptr);
+      /* Compiler barrier.  The strdup function calls malloc, which
+         updates allocation_index, but strdup is marked __THROW, so
+         the compiler could optimize away the reload.  */
+      __asm__ volatile ("" ::: "memory");
+      /* If the allocation count is still zero, it means we did not
+         interpose malloc successfully.  */
+      if (allocation_index == 0)
+        fail ("malloc does not seem to have been interposed");
+    }
+}
+
+static struct allocation_header *get_header (const char *op, void *ptr)
+{
+  struct allocation_header *header = ((struct allocation_header *) ptr) - 1;
+  if (header->allocation_index >= allocation_index)
+    fail ("%s: %p: invalid allocation index: %zu (not less than %zu)",
+          op, ptr, header->allocation_index, allocation_index);
+  if (allocations[header->allocation_index] != header)
+    fail ("%s: %p: allocation pointer does not point to header, but %p",
+          op, ptr, allocations[header->allocation_index]);
+  return header;
+}
+
+/* Internal helper functions.  Those must be called while the lock is
+   acquired.  */
+
+static void *
+malloc_internal (size_t size)
+{
+  if (allocation_index == max_allocations)
+    {
+      errno = ENOMEM;
+      return NULL;
+    }
+  size_t allocation_size = size + sizeof (struct allocation_header);
+  if (allocation_size < size)
+    {
+      errno = ENOMEM;
+      return NULL;
+    }
+
+  size_t index = allocation_index++;
+  void *result = mmap (NULL, allocation_size, PROT_READ | PROT_WRITE,
+                       MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
+  if (result == MAP_FAILED)
+    return NULL;
+  allocations[index] = result;
+  *allocations[index] = (struct allocation_header)
+    {
+      .allocation_index = index,
+      .allocation_size = allocation_size
+    };
+  return allocations[index] + 1;
+}
+
+static void
+free_internal (const char *op, struct allocation_header *header)
+{
+  size_t index = header->allocation_index;
+  int result = mprotect (header, header->allocation_size, PROT_NONE);
+  if (result != 0)
+    fail ("%s: mprotect (%p, %zu): %m", op, header, header->allocation_size);
+  /* Catch double-free issues.  */
+  allocations[index] = NULL;
+  ++deallocation_count;
+}
+
+static void *
+realloc_internal (void *ptr, size_t new_size)
+{
+  struct allocation_header *header = get_header ("realloc", ptr);
+  size_t old_size = header->allocation_size - sizeof (struct allocation_header);
+  if (old_size >= new_size)
+    return ptr;
+
+  void *newptr = malloc_internal (new_size);
+  if (newptr == NULL)
+    return NULL;
+  memcpy (newptr, ptr, old_size);
+  free_internal ("realloc", header);
+  return newptr;
+}
+
+/* Public interfaces.  These functions must perform locking.  */
+
+size_t
+malloc_allocation_count (void)
+{
+  lock ();
+  size_t count = allocation_index;
+  unlock ();
+  return count;
+}
+
+size_t
+malloc_deallocation_count (void)
+{
+  lock ();
+  size_t count = deallocation_count;
+  unlock ();
+  return count;
+}
+void *
+malloc (size_t size)
+{
+  lock ();
+  void *result = malloc_internal (size);
+  unlock ();
+  return result;
+}
+
+void
+free (void *ptr)
+{
+  if (ptr == NULL)
+    return;
+  lock ();
+  struct allocation_header *header = get_header ("free", ptr);
+  free_internal ("free", header);
+  unlock ();
+}
+
+void *
+calloc (size_t a, size_t b)
+{
+  if (b > 0 && a > SIZE_MAX / b)
+    {
+      errno = ENOMEM;
+      return NULL;
+    }
+  lock ();
+  /* malloc_internal uses mmap, so the memory is zeroed.  */
+  void *result = malloc_internal (a * b);
+  unlock ();
+  return result;
+}
+
+void *
+realloc (void *ptr, size_t n)
+{
+  if (n ==0)
+    {
+      free (ptr);
+      return NULL;
+    }
+  else if (ptr == NULL)
+    return malloc (n);
+  else
+    {
+      lock ();
+      void *result = realloc_internal (ptr, n);
+      unlock ();
+      return result;
+    }
+}
diff --git a/malloc/tst-interpose-aux.h b/malloc/tst-interpose-aux.h
new file mode 100644
index 0000000..2fb22d3
--- /dev/null
+++ b/malloc/tst-interpose-aux.h
@@ -0,0 +1,30 @@
+/* Statistics interface for the minimal malloc implementation.
+   Copyright (C) 2016 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; see the file COPYING.LIB.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifndef TST_INTERPOSE_AUX_H
+#define TST_INTERPOSE_AUX_H
+
+#include <stddef.h>
+
+/* Return the number of allocations performed.  */
+size_t malloc_allocation_count (void);
+
+/* Return the number of deallocations performed.  */
+size_t malloc_deallocation_count (void);
+
+#endif /* TST_INTERPOSE_AUX_H */
diff --git a/malloc/tst-interpose-nothread.c b/malloc/tst-interpose-nothread.c
new file mode 100644
index 0000000..9acb572
--- /dev/null
+++ b/malloc/tst-interpose-nothread.c
@@ -0,0 +1,20 @@
+/* Malloc interposition test, dynamically-linked version without threads.
+   Copyright (C) 2016 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; see the file COPYING.LIB.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#define INTERPOSE_THREADS 0
+#include "tst-interpose-skeleton.c"
diff --git a/malloc/tst-interpose-skeleton.c b/malloc/tst-interpose-skeleton.c
new file mode 100644
index 0000000..fa39e8b
--- /dev/null
+++ b/malloc/tst-interpose-skeleton.c
@@ -0,0 +1,210 @@
+/* Test driver for malloc interposition tests.
+   Copyright (C) 2016 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; see the file COPYING.LIB.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#if INTERPOSE_THREADS
+#include <pthread.h>
+#endif
+
+static int do_test (void);
+#define TEST_FUNCTION do_test ()
+#include "../test-skeleton.c"
+
+/* Fills BUFFER with a test string.  */
+static void
+line_string (int number, char *buffer, size_t length)
+{
+  for (size_t i = 0; i < length - 2; ++i)
+    buffer[i] = 'A' + ((number + i) % 26);
+  buffer[length - 2] = '\n';
+  buffer[length - 1] = '\0';
+}
+
+/* Perform the tests.  */
+static void *
+run_tests (void *closure)
+{
+  char *temp_file_path;
+  int fd = create_temp_file ("tst-malloc-interpose", &temp_file_path);
+  if (fd < 0)
+    _exit (1);
+
+  /* Line lengths excluding the line terminator.  */
+  static const int line_lengths[] = { 0, 45, 80, 2, 8201, 0, 17, -1 };
+
+  /* Fill the test file with data.  */
+  {
+    FILE *fp = fdopen (fd, "w");
+    for (int lineno = 0; line_lengths[lineno] >= 0; ++lineno)
+      {
+        char buffer[line_lengths[lineno] + 2];
+        line_string (lineno, buffer, sizeof (buffer));
+        fprintf (fp, "%s", buffer);
+      }
+
+    if (ferror (fp))
+      {
+        printf ("error: fprintf: %m\n");
+        _exit (1);
+      }
+    if (fclose (fp) != 0)
+      {
+        printf ("error: fclose: %m\n");
+        _exit (1);
+      }
+  }
+
+  /* Read the test file.  This tests libc-internal allocation with
+     realloc.  */
+  {
+    FILE *fp = fopen (temp_file_path, "r");
+
+    char *actual = NULL;
+    size_t actual_size = 0;
+    for (int lineno = 0; ; ++lineno)
+      {
+        errno = 0;
+        ssize_t result = getline (&actual, &actual_size, fp);
+        if (result == 0)
+          {
+            printf ("error: invalid return value 0 from getline\n");
+            _exit (1);
+          }
+        if (result < 0 && errno != 0)
+          {
+            printf ("error: getline: %m\n");
+            _exit (1);
+          }
+        if (result < 0 && line_lengths[lineno] >= 0)
+          {
+            printf ("error: unexpected end of file after line %d\n", lineno);
+            _exit (1);
+          }
+        if (result > 0 && line_lengths[lineno] < 0)
+          {
+            printf ("error: no end of file after line %d\n", lineno);
+            _exit (1);
+          }
+        if (result == -1 && line_lengths[lineno] == -1)
+          /* End of file reached as expected.  */
+          break;
+
+        if (result != line_lengths[lineno] + 1)
+          {
+            printf ("error: line length mismatch: expected %d, got %zd\n",
+                    line_lengths[lineno], result);
+            _exit (1);
+          }
+
+        char expected[line_lengths[lineno] + 2];
+        line_string (lineno, expected, sizeof (expected));
+        if (strcmp (actual, expected) != 0)
+          {
+            printf ("error: line mismatch\n");
+            printf ("error:   expected: [[%s]]\n", expected);
+            printf ("error:   actual:   [[%s]]\n", actual);
+            _exit (1);
+          }
+      }
+
+    if (fclose (fp) != 0)
+      {
+        printf ("error: fclose (after reading): %m\n");
+        _exit (1);
+      }
+  }
+
+  free (temp_file_path);
+
+  /* Make sure that fork is working.  */
+  pid_t pid = fork ();
+  if (pid == -1)
+    {
+      printf ("error: fork: %m\n");
+      _exit (1);
+    }
+  enum { exit_code = 55 };
+  if (pid == 0)
+    _exit (exit_code);
+  int status;
+  int ret = waitpid (pid, &status, 0);
+  if (ret < 0)
+    {
+      printf ("error: waitpid: %m\n");
+      _exit (1);
+    }
+  if (!WIFEXITED (status) || WEXITSTATUS (status) != exit_code)
+    {
+      printf ("error: unexpected exit status from child process: %d\n",
+              status);
+      _exit (1);
+    }
+
+  return NULL;
+}
+
+/* This is used to detect if malloc has not been successfully
+   interposed.  The interposed malloc does not use brk/sbrk.  */
+static void *initial_brk;
+__attribute__ ((constructor))
+static void
+set_initial_brk (void)
+{
+  initial_brk = sbrk (0);
+}
+
+/* Terminate the process if the break value has been changed.  */
+__attribute__ ((destructor))
+static void
+check_brk (void)
+{
+  void *current = sbrk (0);
+  if (current != initial_brk)
+    {
+      printf ("error: brk changed from %p to %p; no interposition?\n",
+              initial_brk, current);
+      _exit (1);
+    }
+}
+
+static int
+do_test (void)
+{
+  check_brk ();
+
+#if INTERPOSE_THREADS
+  pthread_t thr;
+  int ret;
+  if ((ret = pthread_create (&thr, NULL, run_tests, NULL)) != 0)
+    {
+      errno = ret;
+      printf ("error: %s failed: %m\n", __func__);
+      exit (EXIT_FAILURE);
+    }
+#else
+  run_tests (NULL);
+#endif
+
+  check_brk ();
+
+  return 0;
+}
diff --git a/malloc/tst-interpose-static-nothread.c b/malloc/tst-interpose-static-nothread.c
new file mode 100644
index 0000000..3fb2dd8
--- /dev/null
+++ b/malloc/tst-interpose-static-nothread.c
@@ -0,0 +1,19 @@
+/* Malloc interposition test, static version without threads.
+   Copyright (C) 2016 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; see the file COPYING.LIB.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#include "tst-interpose-nothread.c"
diff --git a/malloc/tst-interpose-static-thread.c b/malloc/tst-interpose-static-thread.c
new file mode 100644
index 0000000..c78ebc7
--- /dev/null
+++ b/malloc/tst-interpose-static-thread.c
@@ -0,0 +1,19 @@
+/* Malloc interposition test, static version with threads.
+   Copyright (C) 2016 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; see the file COPYING.LIB.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#include "tst-interpose-nothread.c"
diff --git a/malloc/tst-interpose-thread.c b/malloc/tst-interpose-thread.c
new file mode 100644
index 0000000..d3e20c7
--- /dev/null
+++ b/malloc/tst-interpose-thread.c
@@ -0,0 +1,20 @@
+/* Malloc interposition test, dynamically-linked version with threads.
+   Copyright (C) 2016 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; see the file COPYING.LIB.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#define INTERPOSE_THREADS 1
+#include "tst-interpose-skeleton.c"
diff --git a/nptl/tst-tls3-malloc.c b/nptl/tst-tls3-malloc.c
index 8a580fa..719ab28 100644
--- a/nptl/tst-tls3-malloc.c
+++ b/nptl/tst-tls3-malloc.c
@@ -17,6 +17,7 @@
    <http://www.gnu.org/licenses/>.  */
 
 /* Reuse the test.  */
+#define STACK_SIZE_MB 5
 #include "tst-tls3.c"
 
 /* Increase the thread stack size to 10 MiB, so that some thread
@@ -26,156 +27,5 @@ static long stack_size_in_mb = 10;
 
 #include <sys/mman.h>
 
-/* Interpose a minimal malloc implementation.  This implementation
-   deliberately interposes just a restricted set of symbols, to detect
-   if the TLS code bypasses the interposed malloc.  */
-
-/* Lock to guard malloc internals.  */
-static pthread_mutex_t malloc_lock = PTHREAD_MUTEX_INITIALIZER;
-
-/* Information about an allocation chunk.  */
-struct malloc_chunk
-{
-  /* Start of the allocation.  */
-  void *start;
-  /* Size of the allocation.  */
-  size_t size;
-};
-
-enum { malloc_chunk_count = 1000 };
-static struct malloc_chunk chunks[malloc_chunk_count];
-
-/* Lock the malloc lock.  */
-static void
-xlock (void)
-{
-  int ret = pthread_mutex_lock (&malloc_lock);
-  if (ret != 0)
-    {
-      errno = ret;
-      printf ("error: pthread_mutex_lock: %m\n");
-      _exit (1);
-    }
-}
-
-/* Unlock the malloc lock.  */
-static void
-xunlock (void)
-{
-  int ret = pthread_mutex_unlock (&malloc_lock);
-  if (ret != 0)
-    {
-      errno = ret;
-      printf ("error: pthread_mutex_unlock: %m\n");
-      _exit (1);
-    }
-}
-
-/* Internal malloc without locking and registration.  */
-static void *
-malloc_internal (size_t size)
-{
-  void *result = mmap (NULL, size, PROT_READ | PROT_WRITE,
-                       MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
-  if (result == MAP_FAILED)
-    {
-      printf ("error: mmap: %m\n");
-      _exit (1);
-    }
-  return result;
-}
-
-void *
-malloc (size_t size)
-{
-  if (size == 0)
-    size = 1;
-  xlock ();
-  void *result = malloc_internal (size);
-  for (int i = 0; i < malloc_chunk_count; ++i)
-    if (chunks[i].start == NULL)
-      {
-        chunks[i].start = result;
-        chunks[i].size = size;
-        xunlock ();
-        return result;
-      }
-  xunlock ();
-  printf ("error: no place to store chunk pointer\n");
-  _exit (1);
-}
-
-void *
-calloc (size_t a, size_t b)
-{
-  if (b != 0 && a > SIZE_MAX / b)
-    return NULL;
-  /* malloc uses mmap, which provides zeroed memory.  */
-  return malloc (a * b);
-}
-
-static void
-xunmap (void *ptr, size_t size)
-{
-  int ret = munmap (ptr, size);
-  if (ret < 0)
-    {
-      printf ("error: munmap (%p, %zu) failed: %m\n", ptr, size);
-      _exit (1);
-    }
-}
-
-void
-free (void *ptr)
-{
-  if (ptr == NULL)
-    return;
-
-  xlock ();
-  for (int i = 0; i < malloc_chunk_count; ++i)
-    if (chunks[i].start == ptr)
-      {
-        xunmap (ptr, chunks[i].size);
-        chunks[i] = (struct malloc_chunk) {};
-        xunlock ();
-        return;
-      }
-  xunlock ();
-  printf ("error: tried to free non-allocated pointer %p\n", ptr);
-  _exit (1);
-}
-
-void *
-realloc (void *old, size_t size)
-{
-  if (old != NULL)
-    {
-      xlock ();
-      for (int i = 0; i < malloc_chunk_count; ++i)
-        if (chunks[i].start == old)
-          {
-            size_t old_size = chunks[i].size;
-            void *result;
-            if (old_size < size)
-              {
-                result = malloc_internal (size);
-                /* Reuse the slot for the new allocation.  */
-                memcpy (result, old, old_size);
-                xunmap (old, old_size);
-                chunks[i].start = result;
-                chunks[i].size = size;
-              }
-            else
-              /* Old size is not smaller, so reuse the old
-                 allocation.  */
-              result = old;
-            xunlock ();
-            return result;
-          }
-      xunlock ();
-      printf ("error: tried to realloc non-allocated pointer %p\n", old);
-      _exit (1);
-    }
-  else
-    return malloc (size);
-}
+#define INTERPOSE_THREADS 1
+#include "../malloc/tst-interpose-aux.c"
diff --git a/sysdeps/mach/hurd/fork.c b/sysdeps/mach/hurd/fork.c
index 2e8b59e..9973b1b 100644
--- a/sysdeps/mach/hurd/fork.c
+++ b/sysdeps/mach/hurd/fork.c
@@ -112,7 +112,7 @@ __fork (void)
 	 handlers may use malloc, and the libio list lock has an
 	 indirect malloc dependency as well (via the getdelim
 	 function).  */
-      __malloc_fork_lock_parent ();
+      call_function_static_weak (__malloc_fork_lock_parent);
 
       /* Lock things that want to be locked before we fork.  */
       {
@@ -612,7 +612,7 @@ __fork (void)
 	}
 
       /* Release malloc locks.  */
-      __malloc_fork_unlock_parent ();
+      call_function_static_weak (__malloc_fork_unlock_parent);
 
       /* Run things that want to run in the parent to restore it to
 	 normality.  Usually prepare hooks and parent hooks are
@@ -666,7 +666,7 @@ __fork (void)
       __sigemptyset (&_hurdsig_traced);
 
       /* Release malloc locks.  */
-      __malloc_fork_unlock_child ();
+      call_function_static_weak (__malloc_fork_unlock_child);
 
       /* Run things that want to run in the child task to set up.  */
       RUN_HOOK (_hurd_fork_child_hook, ());
diff --git a/sysdeps/nptl/fork.c b/sysdeps/nptl/fork.c
index 616d897..ea135f8 100644
--- a/sysdeps/nptl/fork.c
+++ b/sysdeps/nptl/fork.c
@@ -128,7 +128,7 @@ __libc_fork (void)
 	 handlers may use malloc, and the libio list lock has an
 	 indirect malloc dependency as well (via the getdelim
 	 function).  */
-      __malloc_fork_lock_parent ();
+      call_function_static_weak (__malloc_fork_lock_parent);
     }
 
 #ifndef NDEBUG
@@ -192,7 +192,7 @@ __libc_fork (void)
       if (multiple_threads)
 	{
 	  /* Release malloc locks.  */
-	  __malloc_fork_unlock_child ();
+	  call_function_static_weak (__malloc_fork_unlock_child);
 
 	  /* Reset the file list.  These are recursive mutexes.  */
 	  fresetlockfiles ();
@@ -240,7 +240,7 @@ __libc_fork (void)
       if (multiple_threads)
 	{
 	  /* Release malloc locks, parent process variant.  */
-	  __malloc_fork_unlock_parent ();
+	  call_function_static_weak (__malloc_fork_unlock_parent);
 
 	  /* We execute this even if the 'fork' call failed.  */
 	  _IO_list_unlock ();

http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=afb035f50b140f808f52d11e3155ed555fb37e8c

commit afb035f50b140f808f52d11e3155ed555fb37e8c
Author: Florian Weimer <fweimer@redhat.com>
Date:   Tue Aug 16 11:06:13 2016 +0200

    nptl/tst-tls3-malloc: Force freeing of thread stacks
    
    It turns out that due to the reduced stack size in tst-tls3 and the
    (fixed) default stack cache size, allocated TLS variables are never
    freed, so the test coverage for tst-tls3-malloc is less than complete.
    This change increases the thread stack size for tst-tls3-malloc only,
    to make sure thread stacks and TLS variables are freed.

diff --git a/ChangeLog b/ChangeLog
index 95ed4a6..ea446d3 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+2016-08-16  Florian Weimer  <fweimer@redhat.com>
+
+	* nptl/tst-tls3.c (default_stack_size_in_mb, stack_size_in_mb):
+	New.
+	(do_test): Apply default_stack_size_in_mb if not set.
+	* nptl/tst-tls3-malloc.c (stack_size_in_mb): Override default.
+
 2016-08-02  Florian Weimer  <fweimer@redhat.com>
 
 	[BZ #19469]
diff --git a/nptl/tst-tls3-malloc.c b/nptl/tst-tls3-malloc.c
index 5eab3cd..8a580fa 100644
--- a/nptl/tst-tls3-malloc.c
+++ b/nptl/tst-tls3-malloc.c
@@ -19,6 +19,11 @@
 /* Reuse the test.  */
 #include "tst-tls3.c"
 
+/* Increase the thread stack size to 10 MiB, so that some thread
+   stacks are actually freed.  (The stack cache size is currently
+   hard-wired to 40 MiB in allocatestack.c.)  */
+static long stack_size_in_mb = 10;
+
 #include <sys/mman.h>
 
 /* Interpose a minimal malloc implementation.  This implementation
diff --git a/nptl/tst-tls3.c b/nptl/tst-tls3.c
index 982c1fd..649cb8f 100644
--- a/nptl/tst-tls3.c
+++ b/nptl/tst-tls3.c
@@ -29,6 +29,11 @@
 
 #define THE_SIG SIGUSR1
 
+/* The stack size can be overriden.  With a sufficiently large stack
+   size, thread stacks for terminated threads are freed, but this does
+   not happen with the default size of 1 MiB.  */
+enum { default_stack_size_in_mb = 1 };
+static long stack_size_in_mb;
 
 #define N 10
 static pthread_t th[N];
@@ -72,6 +77,9 @@ int nsigs;
 int
 do_test (void)
 {
+  if (stack_size_in_mb == 0)
+    stack_size_in_mb = default_stack_size_in_mb;
+
   if ((uintptr_t) pthread_self () & (TCB_ALIGNMENT - 1))
     {
       puts ("initial thread's struct pthread not aligned enough");
@@ -127,7 +135,7 @@ do_test (void)
       exit (1);
     }
 
-  if (pthread_attr_setstacksize (&a, 1 * 1024 * 1024) != 0)
+  if (pthread_attr_setstacksize (&a, stack_size_in_mb * 1024 * 1024) != 0)
     {
       puts ("attr_setstacksize failed");
       return 1;

http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=254269d6a9d5c025b5e1df31f4019daadf6a35bb

commit 254269d6a9d5c025b5e1df31f4019daadf6a35bb
Author: Florian Weimer <fweimer@redhat.com>
Date:   Tue Aug 2 17:01:02 2016 +0200

    malloc: Run tests without calling mallopt [BZ #19469]
    
    The compiled tests no longer refer to the mallopt symbol
    from their main functions.  (Some tests still call mallopt
    explicitly, which is fine.)

diff --git a/ChangeLog b/ChangeLog
index a7f14b7..95ed4a6 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+2016-08-02  Florian Weimer  <fweimer@redhat.com>
+
+	[BZ #19469]
+	* malloc/Makefile (CPPFLAGS): Compile tests with
+	-DTEST_NO_MALLOPT.
+	* test-skeleton.c (main): Only call mallopt if !TEST_NO_MALLOPT.
+
 2016-08-03  Florian Weimer  <fweimer@redhat.com>
 
 	[BZ #17730]
diff --git a/malloc/Makefile b/malloc/Makefile
index fa1730e..4d5c81d 100644
--- a/malloc/Makefile
+++ b/malloc/Makefile
@@ -166,3 +166,7 @@ $(objpfx)libmemusage.so: $(libdl)
 
 # Extra dependencies
 $(foreach o,$(all-object-suffixes),$(objpfx)malloc$(o)): arena.c hooks.c
+
+# Compile the tests with a flag which suppresses the mallopt call in
+# the test skeleton.
+$(tests:%=$(objpfx)%.o): CPPFLAGS += -DTEST_NO_MALLOPT
diff --git a/test-skeleton.c b/test-skeleton.c
index 7ab3529..7ded816 100644
--- a/test-skeleton.c
+++ b/test-skeleton.c
@@ -295,8 +295,10 @@ main (int argc, char *argv[])
   unsigned int timeoutfactor = 1;
   pid_t termpid;
 
+#ifndef TEST_NO_MALLOPT
   /* Make uses of freed and uninitialized memory known.  */
   mallopt (M_PERTURB, 42);
+#endif
 
 #ifdef STDOUT_UNBUFFERED
   setbuf (stdout, NULL);

http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=d7d49b08413124b03f227f5fe06aa811a52c2b23

commit d7d49b08413124b03f227f5fe06aa811a52c2b23
Author: Florian Weimer <fweimer@redhat.com>
Date:   Wed Aug 3 16:16:57 2016 +0200

    elf: Do not use memalign for TCB/TLS blocks allocation [BZ #17730]
    
    Instead, call malloc and explicitly align the pointer.
    
    There is no external location to store the original (unaligned)
    pointer, and this commit increases the allocation size to store
    the pointer at a fixed location relative to the TCB pointer.
    
    The manual alignment means that some space goes unused which
    was previously made available for subsequent allocations.
    However, in the TLS_DTV_AT_TP case, the manual alignment code
    avoids aligning the pre-TCB to the TLS block alignment.  (Even
    while using memalign, the allocation had some unused padding
    in front.)
    
    This concludes the removal of memalign calls from the TLS code,
    and the new tst-tls3-malloc test verifies that only core malloc
    routines are used.

diff --git a/ChangeLog b/ChangeLog
index 0124474..a7f14b7 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,6 +1,21 @@
 2016-08-03  Florian Weimer  <fweimer@redhat.com>
 
 	[BZ #17730]
+	Avoid using memalign for TCB allocations.
+	* elf/dl-tls.c (tcb_to_pointer_to_free_location): New.
+	(_dl_allocate_tls_storage): Use malloc and manual alignment.
+	Avoid alignment gap in the TLS_DTV_AT_TP case.
+	(_dl_deallocate_tls): Use tcb_to_pointer_to_free_location to
+	determine the pointer to free.
+	* nptl/tst-tls3-malloc.c: New test.
+	* nptl/Makefile (tests): Add it.
+	(tst-tls3-malloc): Link with libdl, libpthread.
+	(LDFLAGS-tst-tls3-malloc): Set.
+	(tst-tls3-malloc.out): Depend on DSO used in test.
+
+2016-08-03  Florian Weimer  <fweimer@redhat.com>
+
+	[BZ #17730]
 	Avoid using memalign for TLS allocations.
 	* sysdeps/generic/dl-dtv.h (struct dtv_pointer): New.  Replaces
 	is_static member with to_free member.
diff --git a/elf/dl-tls.c b/elf/dl-tls.c
index be6a3c7..17567ad 100644
--- a/elf/dl-tls.c
+++ b/elf/dl-tls.c
@@ -347,6 +347,22 @@ _dl_get_tls_static_info (size_t *sizep, size_t *alignp)
   *alignp = GL(dl_tls_static_align);
 }
 
+/* Derive the location of the pointer to the start of the original
+   allocation (before alignment) from the pointer to the TCB.  */
+static inline void **
+tcb_to_pointer_to_free_location (void *tcb)
+{
+#if TLS_TCB_AT_TP
+  /* The TCB follows the TLS blocks, and the pointer to the front
+     follows the TCB.  */
+  void **original_pointer_location = tcb + TLS_TCB_SIZE;
+#elif TLS_DTV_AT_TP
+  /* The TCB comes first, preceded by the pre-TCB, and the pointer is
+     before that.  */
+  void **original_pointer_location = tcb - TLS_PRE_TCB_SIZE - sizeof (void *);
+#endif
+  return original_pointer_location;
+}
 
 void *
 internal_function
@@ -359,39 +375,50 @@ _dl_allocate_tls_storage (void)
   /* Memory layout is:
      [ TLS_PRE_TCB_SIZE ] [ TLS_TCB_SIZE ] [ TLS blocks ]
 			  ^ This should be returned.  */
-  size += (TLS_PRE_TCB_SIZE + GL(dl_tls_static_align) - 1)
-	  & ~(GL(dl_tls_static_align) - 1);
+  size += TLS_PRE_TCB_SIZE;
 #endif
 
-  /* Allocate a correctly aligned chunk of memory.  */
-  result = __libc_memalign (GL(dl_tls_static_align), size);
-  if (__builtin_expect (result != NULL, 1))
-    {
-      /* Allocate the DTV.  */
-      void *allocated = result;
+  /* Perform the allocation.  Reserve space for the required alignment
+     and the pointer to the original allocation.  */
+  size_t alignment = GL(dl_tls_static_align);
+  void *allocated = malloc (size + alignment + sizeof (void *));
+  if (__glibc_unlikely (allocated == NULL))
+    return NULL;
 
+  /* Perform alignment and allocate the DTV.  */
 #if TLS_TCB_AT_TP
-      /* The TCB follows the TLS blocks.  */
-      result = (char *) result + size - TLS_TCB_SIZE;
-
-      /* Clear the TCB data structure.  We can't ask the caller (i.e.
-	 libpthread) to do it, because we will initialize the DTV et al.  */
-      memset (result, '\0', TLS_TCB_SIZE);
+  /* The TCB follows the TLS blocks, which determine the alignment.
+     (TCB alignment requirements have been taken into account when
+     calculating GL(dl_tls_static_align).)  */
+  void *aligned = (void *) roundup ((uintptr_t) allocated, alignment);
+  result = aligned + size - TLS_TCB_SIZE;
+
+  /* Clear the TCB data structure.  We can't ask the caller (i.e.
+     libpthread) to do it, because we will initialize the DTV et al.  */
+  memset (result, '\0', TLS_TCB_SIZE);
 #elif TLS_DTV_AT_TP
-      result = (char *) result + size - GL(dl_tls_static_size);
-
-      /* Clear the TCB data structure and TLS_PRE_TCB_SIZE bytes before it.
-	 We can't ask the caller (i.e. libpthread) to do it, because we will
-	 initialize the DTV et al.  */
-      memset ((char *) result - TLS_PRE_TCB_SIZE, '\0',
-	      TLS_PRE_TCB_SIZE + TLS_TCB_SIZE);
+  /* Pre-TCB and TCB come before the TLS blocks.  The layout computed
+     in _dl_determine_tlsoffset assumes that the TCB is aligned to the
+     TLS block alignment, and not just the TLS blocks after it.  This
+     can leave an unused alignment gap between the TCB and the TLS
+     blocks.  */
+  result = (void *) roundup
+    (sizeof (void *) + TLS_PRE_TCB_SIZE + (uintptr_t) allocated,
+     alignment);
+
+  /* Clear the TCB data structure and TLS_PRE_TCB_SIZE bytes before
+     it.  We can't ask the caller (i.e. libpthread) to do it, because
+     we will initialize the DTV et al.  */
+  memset (result - TLS_PRE_TCB_SIZE, '\0', TLS_PRE_TCB_SIZE + TLS_TCB_SIZE);
 #endif
 
-      result = allocate_dtv (result);
-      if (result == NULL)
-	free (allocated);
-    }
+  /* Record the value of the original pointer for later
+     deallocation.  */
+  *tcb_to_pointer_to_free_location (result) = allocated;
 
+  result = allocate_dtv (result);
+  if (result == NULL)
+    free (allocated);
   return result;
 }
 
@@ -558,17 +585,7 @@ _dl_deallocate_tls (void *tcb, bool dealloc_tcb)
     free (dtv - 1);
 
   if (dealloc_tcb)
-    {
-#if TLS_TCB_AT_TP
-      /* The TCB follows the TLS blocks.  Back up to free the whole block.  */
-      tcb -= GL(dl_tls_static_size) - TLS_TCB_SIZE;
-#elif TLS_DTV_AT_TP
-      /* Back up the TLS_PRE_TCB_SIZE bytes.  */
-      tcb -= (TLS_PRE_TCB_SIZE + GL(dl_tls_static_align) - 1)
-	     & ~(GL(dl_tls_static_align) - 1);
-#endif
-      free (tcb);
-    }
+    free (*tcb_to_pointer_to_free_location (tcb));
 }
 rtld_hidden_def (_dl_deallocate_tls)
 
diff --git a/nptl/Makefile b/nptl/Makefile
index dc3ccab..e0db52d 100644
--- a/nptl/Makefile
+++ b/nptl/Makefile
@@ -319,8 +319,8 @@ tests += tst-cancelx2 tst-cancelx3 tst-cancelx4 tst-cancelx5 \
 	 tst-cleanupx0 tst-cleanupx1 tst-cleanupx2 tst-cleanupx3 tst-cleanupx4 \
 	 tst-oncex3 tst-oncex4
 ifeq ($(build-shared),yes)
-tests += tst-atfork2 tst-tls3 tst-tls4 tst-tls5 tst-_res1 tst-fini1 \
-	 tst-stackguard1
+tests += tst-atfork2 tst-tls3 tst-tls3-malloc tst-tls4 tst-tls5 tst-_res1 \
+	 tst-fini1 tst-stackguard1
 tests-nolibpthread += tst-fini1
 ifeq ($(have-z-execstack),yes)
 tests += tst-execstack
@@ -525,6 +525,10 @@ LDFLAGS-tst-tls3 = -rdynamic
 $(objpfx)tst-tls3.out: $(objpfx)tst-tls3mod.so
 $(objpfx)tst-tls3mod.so: $(shared-thread-library)
 
+$(objpfx)tst-tls3-malloc: $(libdl) $(shared-thread-library)
+LDFLAGS-tst-tls3-malloc = -rdynamic
+$(objpfx)tst-tls3-malloc.out: $(objpfx)tst-tls3mod.so
+
 $(objpfx)tst-tls4: $(libdl) $(shared-thread-library)
 $(objpfx)tst-tls4.out: $(objpfx)tst-tls4moda.so $(objpfx)tst-tls4modb.so
 
diff --git a/nptl/tst-tls3-malloc.c b/nptl/tst-tls3-malloc.c
new file mode 100644
index 0000000..5eab3cd
--- /dev/null
+++ b/nptl/tst-tls3-malloc.c
@@ -0,0 +1,176 @@
+/* Test TLS allocation with an interposed malloc.
+   Copyright (C) 2016 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/>.  */
+
+/* Reuse the test.  */
+#include "tst-tls3.c"
+
+#include <sys/mman.h>
+
+/* Interpose a minimal malloc implementation.  This implementation
+   deliberately interposes just a restricted set of symbols, to detect
+   if the TLS code bypasses the interposed malloc.  */
+
+/* Lock to guard malloc internals.  */
+static pthread_mutex_t malloc_lock = PTHREAD_MUTEX_INITIALIZER;
+
+/* Information about an allocation chunk.  */
+struct malloc_chunk
+{
+  /* Start of the allocation.  */
+  void *start;
+  /* Size of the allocation.  */
+  size_t size;
+};
+
+enum { malloc_chunk_count = 1000 };
+static struct malloc_chunk chunks[malloc_chunk_count];
+
+/* Lock the malloc lock.  */
+static void
+xlock (void)
+{
+  int ret = pthread_mutex_lock (&malloc_lock);
+  if (ret != 0)
+    {
+      errno = ret;
+      printf ("error: pthread_mutex_lock: %m\n");
+      _exit (1);
+    }
+}
+
+/* Unlock the malloc lock.  */
+static void
+xunlock (void)
+{
+  int ret = pthread_mutex_unlock (&malloc_lock);
+  if (ret != 0)
+    {
+      errno = ret;
+      printf ("error: pthread_mutex_unlock: %m\n");
+      _exit (1);
+    }
+}
+
+/* Internal malloc without locking and registration.  */
+static void *
+malloc_internal (size_t size)
+{
+  void *result = mmap (NULL, size, PROT_READ | PROT_WRITE,
+                       MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
+  if (result == MAP_FAILED)
+    {
+      printf ("error: mmap: %m\n");
+      _exit (1);
+    }
+  return result;
+}
+
+void *
+malloc (size_t size)
+{
+  if (size == 0)
+    size = 1;
+  xlock ();
+  void *result = malloc_internal (size);
+  for (int i = 0; i < malloc_chunk_count; ++i)
+    if (chunks[i].start == NULL)
+      {
+        chunks[i].start = result;
+        chunks[i].size = size;
+        xunlock ();
+        return result;
+      }
+  xunlock ();
+  printf ("error: no place to store chunk pointer\n");
+  _exit (1);
+}
+
+void *
+calloc (size_t a, size_t b)
+{
+  if (b != 0 && a > SIZE_MAX / b)
+    return NULL;
+  /* malloc uses mmap, which provides zeroed memory.  */
+  return malloc (a * b);
+}
+
+static void
+xunmap (void *ptr, size_t size)
+{
+  int ret = munmap (ptr, size);
+  if (ret < 0)
+    {
+      printf ("error: munmap (%p, %zu) failed: %m\n", ptr, size);
+      _exit (1);
+    }
+}
+
+void
+free (void *ptr)
+{
+  if (ptr == NULL)
+    return;
+
+  xlock ();
+  for (int i = 0; i < malloc_chunk_count; ++i)
+    if (chunks[i].start == ptr)
+      {
+        xunmap (ptr, chunks[i].size);
+        chunks[i] = (struct malloc_chunk) {};
+        xunlock ();
+        return;
+      }
+  xunlock ();
+  printf ("error: tried to free non-allocated pointer %p\n", ptr);
+  _exit (1);
+}
+
+void *
+realloc (void *old, size_t size)
+{
+  if (old != NULL)
+    {
+      xlock ();
+      for (int i = 0; i < malloc_chunk_count; ++i)
+        if (chunks[i].start == old)
+          {
+            size_t old_size = chunks[i].size;
+            void *result;
+            if (old_size < size)
+              {
+                result = malloc_internal (size);
+                /* Reuse the slot for the new allocation.  */
+                memcpy (result, old, old_size);
+                xunmap (old, old_size);
+                chunks[i].start = result;
+                chunks[i].size = size;
+              }
+            else
+              /* Old size is not smaller, so reuse the old
+                 allocation.  */
+              result = old;
+            xunlock ();
+            return result;
+          }
+      xunlock ();
+      printf ("error: tried to realloc non-allocated pointer %p\n", old);
+      _exit (1);
+    }
+  else
+    return malloc (size);
+}

http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=fa9a646079950ea326e1f2feee7093580dc1ecd3

commit fa9a646079950ea326e1f2feee7093580dc1ecd3
Author: Florian Weimer <fweimer@redhat.com>
Date:   Wed Aug 3 16:15:38 2016 +0200

    elf: Avoid using memalign for TLS allocations [BZ #17730]
    
    Instead of a flag which indicates the pointer can be freed, dtv_t
    now includes the pointer which should be freed.  Due to padding,
    the size of dtv_t does not increase.
    
    To avoid using memalign, the new allocate_dtv_entry function
    allocates a sufficiently large buffer so that a sub-buffer
    can be found in it which starts with an aligned pointer.  Both
    the aligned and original pointers are kept, the latter for calling
    free later.

diff --git a/ChangeLog b/ChangeLog
index e5e06a2..0124474 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,25 @@
+2016-08-03  Florian Weimer  <fweimer@redhat.com>
+
+	[BZ #17730]
+	Avoid using memalign for TLS allocations.
+	* sysdeps/generic/dl-dtv.h (struct dtv_pointer): New.  Replaces
+	is_static member with to_free member.
+	(union dtv): Use struct dtv_pointer.
+	* csu/libc-tls.c (__libc_setup_tls): Set to_free member of struct
+	dtv_pointer instead of is_static.
+	* elf/dl-tls.c (_dl_allocate_tls_init): Likewise.
+	(_dl_deallocate_tls): Free to_free member of struct dtv_pointer
+	instead of val.
+	(allocate_dtv_entry): New function.
+	(allocate_and_init): Return struct dtv_pointer.  Call
+	allocate_dtv_entry instead of __libc_memalign.
+	(_dl_update_slotinfo): Free to_free member of struct dtv_pointer
+	instead of val.
+	(tls_get_addr_tail): Set to_free member of struct dtv_pointer
+	instead of is_static.  Adjust call to allocate_and_init.
+	* nptl/allocatestack.c (get_cached_stack): Free to_free member of
+	struct dtv_pointer instead of val.
+
 2016-06-20  Florian Weimer  <fweimer@redhat.com>
 
 	Consolidate machine-agnostic DTV definitions in <dl-dtv.h>.
diff --git a/csu/libc-tls.c b/csu/libc-tls.c
index d6425e0..235ac79 100644
--- a/csu/libc-tls.c
+++ b/csu/libc-tls.c
@@ -175,7 +175,7 @@ __libc_setup_tls (size_t tcbsize, size_t tcbalign)
 #else
 # error "Either TLS_TCB_AT_TP or TLS_DTV_AT_TP must be defined"
 #endif
-  _dl_static_dtv[2].pointer.is_static = true;
+  _dl_static_dtv[2].pointer.to_free = NULL;
   /* sbrk gives us zero'd memory, so we don't need to clear the remainder.  */
   memcpy (_dl_static_dtv[2].pointer.val, initimage, filesz);
 
diff --git a/elf/dl-tls.c b/elf/dl-tls.c
index ed13fd9..be6a3c7 100644
--- a/elf/dl-tls.c
+++ b/elf/dl-tls.c
@@ -494,7 +494,7 @@ _dl_allocate_tls_init (void *result)
 	  maxgen = MAX (maxgen, listp->slotinfo[cnt].gen);
 
 	  dtv[map->l_tls_modid].pointer.val = TLS_DTV_UNALLOCATED;
-	  dtv[map->l_tls_modid].pointer.is_static = false;
+	  dtv[map->l_tls_modid].pointer.to_free = NULL;
 
 	  if (map->l_tls_offset == NO_TLS_OFFSET
 	      || map->l_tls_offset == FORCED_DYNAMIC_TLS_OFFSET)
@@ -551,9 +551,7 @@ _dl_deallocate_tls (void *tcb, bool dealloc_tcb)
 
   /* We need to free the memory allocated for non-static TLS.  */
   for (size_t cnt = 0; cnt < dtv[-1].counter; ++cnt)
-    if (! dtv[1 + cnt].pointer.is_static
-	&& dtv[1 + cnt].pointer.val != TLS_DTV_UNALLOCATED)
-      free (dtv[1 + cnt].pointer.val);
+    free (dtv[1 + cnt].pointer.to_free);
 
   /* The array starts with dtv[-1].  */
   if (dtv != GL(dl_initial_dtv))
@@ -594,21 +592,49 @@ rtld_hidden_def (_dl_deallocate_tls)
 #  define GET_ADDR_OFFSET ti->ti_offset
 # endif
 
+/* Allocate one DTV entry.  */
+static struct dtv_pointer
+allocate_dtv_entry (size_t alignment, size_t size)
+{
+  if (powerof2 (alignment) && alignment <= _Alignof (max_align_t))
+    {
+      /* The alignment is supported by malloc.  */
+      void *ptr = malloc (size);
+      return (struct dtv_pointer) { ptr, ptr };
+    }
 
-static void *
+  /* Emulate memalign to by manually aligning a pointer returned by
+     malloc.  First compute the size with an overflow check.  */
+  size_t alloc_size = size + alignment;
+  if (alloc_size < size)
+    return (struct dtv_pointer) {};
+
+  /* Perform the allocation.  This is the pointer we need to free
+     later.  */
+  void *start = malloc (alloc_size);
+  if (start == NULL)
+    return (struct dtv_pointer) {};
+
+  /* Find the aligned position within the larger allocation.  */
+  void *aligned = (void *) roundup ((uintptr_t) start, alignment);
+
+  return (struct dtv_pointer) { .val = aligned, .to_free = start };
+}
+
+static struct dtv_pointer
 allocate_and_init (struct link_map *map)
 {
-  void *newp;
-
-  newp = __libc_memalign (map->l_tls_align, map->l_tls_blocksize);
-  if (newp == NULL)
+  struct dtv_pointer result = allocate_dtv_entry
+    (map->l_tls_align, map->l_tls_blocksize);
+  if (result.val == NULL)
     oom ();
 
   /* Initialize the memory.  */
-  memset (__mempcpy (newp, map->l_tls_initimage, map->l_tls_initimage_size),
+  memset (__mempcpy (result.val, map->l_tls_initimage,
+		     map->l_tls_initimage_size),
 	  '\0', map->l_tls_blocksize - map->l_tls_initimage_size);
 
-  return newp;
+  return result;
 }
 
 
@@ -678,12 +704,9 @@ _dl_update_slotinfo (unsigned long int req_modid)
 		    {
 		      /* If this modid was used at some point the memory
 			 might still be allocated.  */
-		      if (! dtv[total + cnt].pointer.is_static
-			  && (dtv[total + cnt].pointer.val
-			      != TLS_DTV_UNALLOCATED))
-			free (dtv[total + cnt].pointer.val);
+		      free (dtv[total + cnt].pointer.to_free);
 		      dtv[total + cnt].pointer.val = TLS_DTV_UNALLOCATED;
-		      dtv[total + cnt].pointer.is_static = false;
+		      dtv[total + cnt].pointer.to_free = NULL;
 		    }
 
 		  continue;
@@ -708,16 +731,9 @@ _dl_update_slotinfo (unsigned long int req_modid)
 		 dtv entry free it.  */
 	      /* XXX Ideally we will at some point create a memory
 		 pool.  */
-	      if (! dtv[modid].pointer.is_static
-		  && dtv[modid].pointer.val != TLS_DTV_UNALLOCATED)
-		/* Note that free is called for NULL is well.  We
-		   deallocate even if it is this dtv entry we are
-		   supposed to load.  The reason is that we call
-		   memalign and not malloc.  */
-		free (dtv[modid].pointer.val);
-
+	      free (dtv[modid].pointer.to_free);
 	      dtv[modid].pointer.val = TLS_DTV_UNALLOCATED;
-	      dtv[modid].pointer.is_static = false;
+	      dtv[modid].pointer.to_free = NULL;
 
 	      if (modid == req_modid)
 		the_map = map;
@@ -780,7 +796,7 @@ tls_get_addr_tail (GET_ADDR_ARGS, dtv_t *dtv, struct link_map *the_map)
 #endif
 	  __rtld_lock_unlock_recursive (GL(dl_load_lock));
 
-	  dtv[GET_ADDR_MODULE].pointer.is_static = true;
+	  dtv[GET_ADDR_MODULE].pointer.to_free = NULL;
 	  dtv[GET_ADDR_MODULE].pointer.val = p;
 
 	  return (char *) p + GET_ADDR_OFFSET;
@@ -788,10 +804,11 @@ tls_get_addr_tail (GET_ADDR_ARGS, dtv_t *dtv, struct link_map *the_map)
       else
 	__rtld_lock_unlock_recursive (GL(dl_load_lock));
     }
-  void *p = dtv[GET_ADDR_MODULE].pointer.val = allocate_and_init (the_map);
-  assert (!dtv[GET_ADDR_MODULE].pointer.is_static);
+  struct dtv_pointer result = allocate_and_init (the_map);
+  dtv[GET_ADDR_MODULE].pointer = result;
+  assert (result.to_free != NULL);
 
-  return (char *) p + GET_ADDR_OFFSET;
+  return (char *) result.val + GET_ADDR_OFFSET;
 }
 
 
diff --git a/nptl/allocatestack.c b/nptl/allocatestack.c
index c044b20..424a590 100644
--- a/nptl/allocatestack.c
+++ b/nptl/allocatestack.c
@@ -245,9 +245,7 @@ get_cached_stack (size_t *sizep, void **memp)
   /* Clear the DTV.  */
   dtv_t *dtv = GET_DTV (TLS_TPADJ (result));
   for (size_t cnt = 0; cnt < dtv[-1].counter; ++cnt)
-    if (! dtv[1 + cnt].pointer.is_static
-	&& dtv[1 + cnt].pointer.val != TLS_DTV_UNALLOCATED)
-      free (dtv[1 + cnt].pointer.val);
+    free (dtv[1 + cnt].pointer.to_free);
   memset (dtv, '\0', (dtv[-1].counter + 1) * sizeof (dtv_t));
 
   /* Re-initialize the TLS.  */
diff --git a/sysdeps/generic/dl-dtv.h b/sysdeps/generic/dl-dtv.h
index 36c5c58..39d8fe2 100644
--- a/sysdeps/generic/dl-dtv.h
+++ b/sysdeps/generic/dl-dtv.h
@@ -19,15 +19,17 @@
 #ifndef _DL_DTV_H
 #define _DL_DTV_H
 
+struct dtv_pointer
+{
+  void *val;                    /* Pointer to data, or TLS_DTV_UNALLOCATED.  */
+  void *to_free;                /* Unaligned pointer, for deallocation.  */
+};
+
 /* Type for the dtv.  */
 typedef union dtv
 {
   size_t counter;
-  struct
-  {
-    void *val;
-    bool is_static;
-  } pointer;
+  struct dtv_pointer pointer;
 } dtv_t;
 
 /* Value used for dtv entries for which the allocation is delayed.  */

http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=d848d802563193cbc9a8113577eab582a958d994

commit d848d802563193cbc9a8113577eab582a958d994
Author: Florian Weimer <fweimer@redhat.com>
Date:   Mon Jun 20 14:31:40 2016 +0200

    elf: Consolidate machine-agnostic DTV definitions in <dl-dtv.h>
    
    Identical definitions of dtv_t and TLS_DTV_UNALLOCATED were
    repeated for all architectures using DTVs.

diff --git a/ChangeLog b/ChangeLog
index 411ba2e..e5e06a2 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,55 @@
+2016-06-20  Florian Weimer  <fweimer@redhat.com>
+
+	Consolidate machine-agnostic DTV definitions in <dl-dtv.h>.
+	* sysdeps/generic/dl-dtv.h: New file.
+	* sysdeps/aarch64/dl-tls.h (TLS_DTV_UNALLOCATED): Remove.
+	* sysdeps/aarch64/nptl/tls.h: Include <dl-dtv.h>.
+	(dtv_t): Remove.
+	* sysdeps/alpha/dl-tls.h (TLS_DTV_UNALLOCATED): Remove.
+	* sysdeps/alpha/nptl/tls.h: Include <dl-dtv.h>.
+	(dtv_t): Remove.
+	* sysdeps/arm/dl-tls.h (TLS_DTV_UNALLOCATED): Remove.
+	* sysdeps/arm/nptl/tls.h: Include <dl-dtv.h>.
+	(dtv_t): Remove.
+	* sysdeps/hppa/dl-tls.h (TLS_DTV_UNALLOCATED): Remove.
+	* sysdeps/hppa/nptl/tls.h: Include <dl-dtv.h>.
+	(dtv_t): Remove.
+	* sysdeps/i386/dl-tls.h (TLS_DTV_UNALLOCATED): Remove.
+	* sysdeps/i386/nptl/tls.h: Include <dl-dtv.h>.
+	(dtv_t): Remove.
+	* sysdeps/ia64/dl-tls.h (TLS_DTV_UNALLOCATED): Remove.
+	* sysdeps/ia64/nptl/tls.h: Include <dl-dtv.h>.
+	(dtv_t): Remove.
+	* sysdeps/m68k/dl-tls.h (TLS_DTV_UNALLOCATED): Remove.
+	* sysdeps/m68k/nptl/tls.h: Include <dl-dtv.h>.
+	(dtv_t): Remove.
+	* sysdeps/mach/hurd/i386/tls.h: Include <dl-dtv.h>.
+	(dtv_t): Remove.
+	* sysdeps/microblaze/dl-tls.h (TLS_DTV_UNALLOCATED): Remove.
+	* sysdeps/microblaze/nptl/tls.h: Include <dl-dtv.h>.
+	(dtv_t): Remove.
+	* sysdeps/mips/dl-tls.h (TLS_DTV_UNALLOCATED): Remove.
+	* sysdeps/mips/nptl/tls.h: Include <dl-dtv.h>.
+	(dtv_t): Remove.
+	* sysdeps/nios2/dl-tls.h (TLS_DTV_UNALLOCATED): Remove.
+	* sysdeps/nios2/nptl/tls.h: Include <dl-dtv.h>.
+	(dtv_t): Remove.
+	* sysdeps/powerpc/dl-tls.h (TLS_DTV_UNALLOCATED): Remove.
+	* sysdeps/powerpc/nptl/tls.h: Include <dl-dtv.h>.
+	(dtv_t): Remove.
+	* sysdeps/s390/dl-tls.h (TLS_DTV_UNALLOCATED): Remove.
+	* sysdeps/s390/nptl/tls.h: Include <dl-dtv.h>.
+	(dtv_t): Remove.
+	* sysdeps/sh/dl-tls.h (TLS_DTV_UNALLOCATED): Remove.
+	* sysdeps/sh/nptl/tls.h: Include <dl-dtv.h>.
+	(dtv_t): Remove.
+	* sysdeps/sparc/dl-tls.h (TLS_DTV_UNALLOCATED): Remove.
+	* sysdeps/sparc/nptl/tls.h: Include <dl-dtv.h>.
+	(dtv_t): Remove.
+	* sysdeps/x86_64/dl-tls.h (TLS_DTV_UNALLOCATED): Remove.
+	* sysdeps/x86_64/nptl/tls.h: Include <dl-dtv.h>.
+	(dtv_t): Remove.
+
 2016-07-18  Siddhesh Poyarekar  <siddhesh@sourceware.org>
 	    Matt Clay  <mclay@lycos.com>
 
diff --git a/sysdeps/aarch64/dl-tls.h b/sysdeps/aarch64/dl-tls.h
index 71265c5..7eff427 100644
--- a/sysdeps/aarch64/dl-tls.h
+++ b/sysdeps/aarch64/dl-tls.h
@@ -25,6 +25,3 @@ typedef struct
 
 
 extern void *__tls_get_addr (tls_index *ti);
-
-/* Value used for dtv entries for which the allocation is delayed.  */
-#define TLS_DTV_UNALLOCATED ((void *) -1l)
diff --git a/sysdeps/aarch64/nptl/tls.h b/sysdeps/aarch64/nptl/tls.h
index 95ea3f9..c5f20ef 100644
--- a/sysdeps/aarch64/nptl/tls.h
+++ b/sysdeps/aarch64/nptl/tls.h
@@ -25,17 +25,7 @@
 # include <stdbool.h>
 # include <stddef.h>
 # include <stdint.h>
-
-/* Type for the dtv.  */
-typedef union dtv
-{
-  size_t counter;
-  struct
-  {
-    void *val;
-    bool is_static;
-  } pointer;
-} dtv_t;
+# include <dl-dtv.h>
 
 #else /* __ASSEMBLER__ */
 # include <tcb-offsets.h>
diff --git a/sysdeps/alpha/dl-tls.h b/sysdeps/alpha/dl-tls.h
index 5f4e4cf..b723a6e 100644
--- a/sysdeps/alpha/dl-tls.h
+++ b/sysdeps/alpha/dl-tls.h
@@ -25,6 +25,3 @@ typedef struct
 } tls_index;
 
 extern void *__tls_get_addr (tls_index *ti);
-
-/* Value used for dtv entries for which the allocation is delayed.  */
-#define TLS_DTV_UNALLOCATED	((void *) -1l)
diff --git a/sysdeps/alpha/nptl/tls.h b/sysdeps/alpha/nptl/tls.h
index 90d98e1..0d63770 100644
--- a/sysdeps/alpha/nptl/tls.h
+++ b/sysdeps/alpha/nptl/tls.h
@@ -25,17 +25,7 @@
 # include <stdbool.h>
 # include <stddef.h>
 # include <stdint.h>
-
-/* Type for the dtv.  */
-typedef union dtv
-{
-  size_t counter;
-  struct
-  {
-    void *val;
-    bool is_static;
-  } pointer;
-} dtv_t;
+# include <dl-dtv.h>
 
 /* Get system call information.  */
 # include <sysdep.h>
diff --git a/sysdeps/arm/dl-tls.h b/sysdeps/arm/dl-tls.h
index ed2efe8..be2fe62 100644
--- a/sysdeps/arm/dl-tls.h
+++ b/sysdeps/arm/dl-tls.h
@@ -26,6 +26,3 @@ typedef struct dl_tls_index
 
 
 extern void *__tls_get_addr (tls_index *ti);
-
-/* Value used for dtv entries for which the allocation is delayed.  */
-#define TLS_DTV_UNALLOCATED	((void *) -1l)
diff --git a/sysdeps/arm/nptl/tls.h b/sysdeps/arm/nptl/tls.h
index 1ef57d2..9b9a521 100644
--- a/sysdeps/arm/nptl/tls.h
+++ b/sysdeps/arm/nptl/tls.h
@@ -25,17 +25,7 @@
 # include <stdbool.h>
 # include <stddef.h>
 # include <stdint.h>
-
-/* Type for the dtv.  */
-typedef union dtv
-{
-  size_t counter;
-  struct
-  {
-    void *val;
-    bool is_static;
-  } pointer;
-} dtv_t;
+# include <dl-dtv.h>
 
 #else /* __ASSEMBLER__ */
 # include <tcb-offsets.h>
diff --git a/sysdeps/sh/dl-tls.h b/sysdeps/generic/dl-dtv.h
similarity index 72%
copy from sysdeps/sh/dl-tls.h
copy to sysdeps/generic/dl-dtv.h
index 276ec54..36c5c58 100644
--- a/sysdeps/sh/dl-tls.h
+++ b/sysdeps/generic/dl-dtv.h
@@ -1,4 +1,4 @@
-/* Thread-local storage handling in the ELF dynamic linker.  SH version.
+/* Generic declarations for DTV-based TLS handling in the dynamic linker.
    Copyright (C) 2002-2016 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
@@ -16,16 +16,21 @@
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
+#ifndef _DL_DTV_H
+#define _DL_DTV_H
 
-/* Type used for the representation of TLS information in the GOT.  */
-typedef struct
+/* Type for the dtv.  */
+typedef union dtv
 {
-  unsigned long int ti_module;
-  unsigned long int ti_offset;
-} tls_index;
-
-
-extern void *__tls_get_addr (tls_index *ti);
+  size_t counter;
+  struct
+  {
+    void *val;
+    bool is_static;
+  } pointer;
+} dtv_t;
 
 /* Value used for dtv entries for which the allocation is delayed.  */
-#define TLS_DTV_UNALLOCATED	((void *) -1l)
+#define TLS_DTV_UNALLOCATED ((void *) -1l)
+
+#endif /* _DLT_DTV_H */
diff --git a/sysdeps/hppa/dl-tls.h b/sysdeps/hppa/dl-tls.h
index 58b9280..2cae6e4 100644
--- a/sysdeps/hppa/dl-tls.h
+++ b/sysdeps/hppa/dl-tls.h
@@ -26,6 +26,3 @@ typedef struct
 
 
 extern void *__tls_get_addr (tls_index *ti);
-
-/* Value used for dtv entries for which the allocation is delayed.  */
-#define TLS_DTV_UNALLOCATED	((void *) -1l)
diff --git a/sysdeps/hppa/nptl/tls.h b/sysdeps/hppa/nptl/tls.h
index 2e0c861..14a0083 100644
--- a/sysdeps/hppa/nptl/tls.h
+++ b/sysdeps/hppa/nptl/tls.h
@@ -25,17 +25,7 @@
 # include <stdbool.h>
 # include <stddef.h>
 # include <stdint.h>
-
-/* Type for the dtv.  */
-typedef union dtv
-{
-  size_t counter;
-  struct
-  {
-    void *val;
-    bool is_static;
-  } pointer;
-} dtv_t;
+# include <dl-dtv.h>
 
 #else /* __ASSEMBLER__ */
 # include <tcb-offsets.h>
diff --git a/sysdeps/i386/dl-tls.h b/sysdeps/i386/dl-tls.h
index 1a8c358..d798b9a 100644
--- a/sysdeps/i386/dl-tls.h
+++ b/sysdeps/i386/dl-tls.h
@@ -59,6 +59,3 @@ rtld_hidden_def (___tls_get_addr)
 
 # endif
 #endif
-
-/* Value used for dtv entries for which the allocation is delayed.  */
-#define TLS_DTV_UNALLOCATED	((void *) -1l)
diff --git a/sysdeps/i386/nptl/tls.h b/sysdeps/i386/nptl/tls.h
index a6dfa9b..74a11dd 100644
--- a/sysdeps/i386/nptl/tls.h
+++ b/sysdeps/i386/nptl/tls.h
@@ -28,19 +28,7 @@
 # include <sysdep.h>
 # include <libc-internal.h>
 # include <kernel-features.h>
-
-
-/* Type for the dtv.  */
-typedef union dtv
-{
-  size_t counter;
-  struct
-  {
-    void *val;
-    bool is_static;
-  } pointer;
-} dtv_t;
-
+# include <dl-dtv.h>
 
 typedef struct
 {
diff --git a/sysdeps/ia64/dl-tls.h b/sysdeps/ia64/dl-tls.h
index bc00888..756b84d 100644
--- a/sysdeps/ia64/dl-tls.h
+++ b/sysdeps/ia64/dl-tls.h
@@ -28,6 +28,3 @@
 #define DONT_USE_TLS_INDEX	1
 
 extern void *__tls_get_addr (size_t m, size_t offset);
-
-/* Value used for dtv entries for which the allocation is delayed.  */
-#define TLS_DTV_UNALLOCATED	((void *) -1l)
diff --git a/sysdeps/ia64/nptl/tls.h b/sysdeps/ia64/nptl/tls.h
index 54fddf5..1e03e2c 100644
--- a/sysdeps/ia64/nptl/tls.h
+++ b/sysdeps/ia64/nptl/tls.h
@@ -26,19 +26,7 @@
 # include <stdint.h>
 # include <stdlib.h>
 # include <list.h>
-
-
-/* Type for the dtv.  */
-typedef union dtv
-{
-  size_t counter;
-  struct
-  {
-    void *val;
-    bool is_static;
-  } pointer;
-} dtv_t;
-
+# include <dl-dtv.h>
 
 typedef struct
 {
diff --git a/sysdeps/m68k/dl-tls.h b/sysdeps/m68k/dl-tls.h
index f853b99..d24ad90 100644
--- a/sysdeps/m68k/dl-tls.h
+++ b/sysdeps/m68k/dl-tls.h
@@ -45,6 +45,3 @@ extern void *__tls_get_addr (tls_index *ti);
 
 #define GET_ADDR_OFFSET		(ti->ti_offset + TLS_DTV_OFFSET)
 #define __TLS_GET_ADDR(__ti)	(__tls_get_addr (__ti) - TLS_DTV_OFFSET)
-
-/* Value used for dtv entries for which the allocation is delayed.  */
-#define TLS_DTV_UNALLOCATED	((void *) -1l)
diff --git a/sysdeps/m68k/nptl/tls.h b/sysdeps/m68k/nptl/tls.h
index f932282..4825c4c 100644
--- a/sysdeps/m68k/nptl/tls.h
+++ b/sysdeps/m68k/nptl/tls.h
@@ -26,17 +26,7 @@
 # include <stdbool.h>
 # include <stddef.h>
 # include <stdint.h>
-
-/* Type for the dtv.  */
-typedef union dtv
-{
-  size_t counter;
-  struct
-  {
-    void *val;
-    bool is_static;
-  } pointer;
-} dtv_t;
+# include <dl-dtv.h>
 
 #else /* __ASSEMBLER__ */
 # include <tcb-offsets.h>
diff --git a/sysdeps/mach/hurd/i386/tls.h b/sysdeps/mach/hurd/i386/tls.h
index 3ec5bb0..81e6926 100644
--- a/sysdeps/mach/hurd/i386/tls.h
+++ b/sysdeps/mach/hurd/i386/tls.h
@@ -25,17 +25,7 @@
 
 
 #ifndef __ASSEMBLER__
-/* Type for the dtv.  */
-typedef union dtv
-{
-  size_t counter;
-  struct
-  {
-    void *val;
-    bool is_static;
-  } pointer;
-} dtv_t;
-
+# include <dl-dtv.h>
 
 /* Type of the TCB.  */
 typedef struct
diff --git a/sysdeps/microblaze/dl-tls.h b/sysdeps/microblaze/dl-tls.h
index f0f8205..5613e21 100644
--- a/sysdeps/microblaze/dl-tls.h
+++ b/sysdeps/microblaze/dl-tls.h
@@ -24,6 +24,3 @@ typedef struct
 } tls_index;
 
 extern void *__tls_get_addr (tls_index *ti);
-
-/* Value used for dtv entries for which the allocation is delayed.  */
-#define TLS_DTV_UNALLOCATED	((void *) -1l)
diff --git a/sysdeps/microblaze/nptl/tls.h b/sysdeps/microblaze/nptl/tls.h
index 8376f50..5e9560a 100644
--- a/sysdeps/microblaze/nptl/tls.h
+++ b/sysdeps/microblaze/nptl/tls.h
@@ -25,17 +25,7 @@
 # include <stdbool.h>
 # include <stddef.h>
 # include <stdint.h>
-
-/* Type for the dtv.  */
-typedef union dtv
-{
-  size_t counter;
-  struct
-  {
-    void *val;
-    bool is_static;
-  } pointer;
-} dtv_t;
+# include <dl-dtv.h>
 
 #else /* __ASSEMBLER__ */
 # include <tcb-offsets.h>
diff --git a/sysdeps/mips/dl-tls.h b/sysdeps/mips/dl-tls.h
index 4d084d6..1c5a83f 100644
--- a/sysdeps/mips/dl-tls.h
+++ b/sysdeps/mips/dl-tls.h
@@ -43,6 +43,3 @@ extern void *__tls_get_addr (tls_index *ti);
 
 # define GET_ADDR_OFFSET	(ti->ti_offset + TLS_DTV_OFFSET)
 # define __TLS_GET_ADDR(__ti)	(__tls_get_addr (__ti) - TLS_DTV_OFFSET)
-
-/* Value used for dtv entries for which the allocation is delayed.  */
-#define TLS_DTV_UNALLOCATED	((void *) -1l)
diff --git a/sysdeps/mips/nptl/tls.h b/sysdeps/mips/nptl/tls.h
index 10ca878..f5f4891 100644
--- a/sysdeps/mips/nptl/tls.h
+++ b/sysdeps/mips/nptl/tls.h
@@ -25,20 +25,11 @@
 # include <stdbool.h>
 # include <stddef.h>
 # include <stdint.h>
+# include <dl-dtv.h>
+
 /* Get system call information.  */
 # include <sysdep.h>
 
-/* Type for the dtv.  */
-typedef union dtv
-{
-  size_t counter;
-  struct
-  {
-    void *val;
-    bool is_static;
-  } pointer;
-} dtv_t;
-
 #ifdef __mips16
 /* MIPS16 uses GCC builtin to access the TP.  */
 # define READ_THREAD_POINTER() (__builtin_thread_pointer ())
diff --git a/sysdeps/nios2/dl-tls.h b/sysdeps/nios2/dl-tls.h
index cd79461..45c0db2 100644
--- a/sysdeps/nios2/dl-tls.h
+++ b/sysdeps/nios2/dl-tls.h
@@ -43,6 +43,3 @@ extern void *__tls_get_addr (tls_index *ti);
 
 # define GET_ADDR_OFFSET	(ti->ti_offset + TLS_DTV_OFFSET)
 # define __TLS_GET_ADDR(__ti)	(__tls_get_addr (__ti) - TLS_DTV_OFFSET)
-
-/* Value used for dtv entries for which the allocation is delayed.  */
-#define TLS_DTV_UNALLOCATED	((void *) -1l)
diff --git a/sysdeps/nios2/nptl/tls.h b/sysdeps/nios2/nptl/tls.h
index ad29ac5..55e1154 100644
--- a/sysdeps/nios2/nptl/tls.h
+++ b/sysdeps/nios2/nptl/tls.h
@@ -25,17 +25,7 @@
 # include <stdbool.h>
 # include <stddef.h>
 # include <stdint.h>
-
-/* Type for the dtv.  */
-typedef union dtv
-{
-  size_t counter;
-  struct
-  {
-    void *val;
-    bool is_static;
-  } pointer;
-} dtv_t;
+# include <dl-dtv.h>
 
 #else /* __ASSEMBLER__ */
 # include <tcb-offsets.h>
diff --git a/sysdeps/powerpc/dl-tls.h b/sysdeps/powerpc/dl-tls.h
index eced36b..f8b6fcf 100644
--- a/sysdeps/powerpc/dl-tls.h
+++ b/sysdeps/powerpc/dl-tls.h
@@ -49,7 +49,4 @@ extern void *__tls_get_addr (tls_index *ti);
 # define __TLS_GET_ADDR(__ti)	(__tls_get_addr (__ti) - TLS_DTV_OFFSET)
 #endif
 
-/* Value used for dtv entries for which the allocation is delayed.  */
-#define TLS_DTV_UNALLOCATED	((void *) -1l)
-
 #endif /* dl-tls.h */
diff --git a/sysdeps/powerpc/nptl/tls.h b/sysdeps/powerpc/nptl/tls.h
index 0e889bc..fa476a5 100644
--- a/sysdeps/powerpc/nptl/tls.h
+++ b/sysdeps/powerpc/nptl/tls.h
@@ -25,17 +25,7 @@
 # include <stdbool.h>
 # include <stddef.h>
 # include <stdint.h>
-
-/* Type for the dtv.  */
-typedef union dtv
-{
-  size_t counter;
-  struct
-  {
-    void *val;
-    bool is_static;
-  } pointer;
-} dtv_t;
+# include <dl-dtv.h>
 
 #else /* __ASSEMBLER__ */
 # include <tcb-offsets.h>
diff --git a/sysdeps/s390/dl-tls.h b/sysdeps/s390/dl-tls.h
index 503048a..ce2d020 100644
--- a/sysdeps/s390/dl-tls.h
+++ b/sysdeps/s390/dl-tls.h
@@ -102,6 +102,3 @@ extern void *__tls_get_addr_internal (tls_index *ti);
       + (unsigned long) __builtin_thread_pointer (); })
 
 #endif
-
-/* Value used for dtv entries for which the allocation is delayed.  */
-#define TLS_DTV_UNALLOCATED	((void *) -1l)
diff --git a/sysdeps/s390/nptl/tls.h b/sysdeps/s390/nptl/tls.h
index e4c3ec7..0fec586 100644
--- a/sysdeps/s390/nptl/tls.h
+++ b/sysdeps/s390/nptl/tls.h
@@ -27,19 +27,7 @@
 # include <stdlib.h>
 # include <list.h>
 # include <kernel-features.h>
-
-
-/* Type for the dtv.  */
-typedef union dtv
-{
-  size_t counter;
-  struct
-  {
-    void *val;
-    bool is_static;
-  } pointer;
-} dtv_t;
-
+# include <dl-dtv.h>
 
 typedef struct
 {
diff --git a/sysdeps/sh/dl-tls.h b/sysdeps/sh/dl-tls.h
index 276ec54..52e2a10 100644
--- a/sysdeps/sh/dl-tls.h
+++ b/sysdeps/sh/dl-tls.h
@@ -26,6 +26,3 @@ typedef struct
 
 
 extern void *__tls_get_addr (tls_index *ti);
-
-/* Value used for dtv entries for which the allocation is delayed.  */
-#define TLS_DTV_UNALLOCATED	((void *) -1l)
diff --git a/sysdeps/sh/nptl/tls.h b/sysdeps/sh/nptl/tls.h
index 6f128c9..a81e805 100644
--- a/sysdeps/sh/nptl/tls.h
+++ b/sysdeps/sh/nptl/tls.h
@@ -28,17 +28,7 @@
 # include <stdlib.h>
 # include <list.h>
 # include <sysdep.h>
-
-/* Type for the dtv.  */
-typedef union dtv
-{
-  size_t counter;
-  struct
-  {
-    void *val;
-    bool is_static;
-  } pointer;
-} dtv_t;
+# include <dl-dtv.h>
 
 typedef struct
 {
diff --git a/sysdeps/sparc/dl-tls.h b/sysdeps/sparc/dl-tls.h
index 2bfd366..b74861a 100644
--- a/sysdeps/sparc/dl-tls.h
+++ b/sysdeps/sparc/dl-tls.h
@@ -26,6 +26,3 @@ typedef struct
 
 
 extern void *__tls_get_addr (tls_index *ti);
-
-/* Value used for dtv entries for which the allocation is delayed.  */
-#define TLS_DTV_UNALLOCATED	((void *) -1l)
diff --git a/sysdeps/sparc/nptl/tls.h b/sysdeps/sparc/nptl/tls.h
index 08c0552..85f2a2c 100644
--- a/sysdeps/sparc/nptl/tls.h
+++ b/sysdeps/sparc/nptl/tls.h
@@ -27,17 +27,7 @@
 # include <stdlib.h>
 # include <list.h>
 # include <kernel-features.h>
-
-/* Type for the dtv.  */
-typedef union dtv
-{
-  size_t counter;
-  struct
-  {
-    void *val;
-    bool is_static;
-  } pointer;
-} dtv_t;
+# include <dl-dtv.h>
 
 typedef struct
 {
diff --git a/sysdeps/tile/dl-tls.h b/sysdeps/tile/dl-tls.h
index d26c6be..20096f4 100644
--- a/sysdeps/tile/dl-tls.h
+++ b/sysdeps/tile/dl-tls.h
@@ -40,6 +40,3 @@ extern void *__tls_get_addr (tls_index *ti);
 /* Compute the value for a DTPREL reloc.  */
 #define TLS_DTPREL_VALUE(sym) \
   ((sym)->st_value - TLS_DTV_OFFSET)
-
-/* Value used for dtv entries for which the allocation is delayed.  */
-#define TLS_DTV_UNALLOCATED    ((void *) -1l)
diff --git a/sysdeps/tile/nptl/tls.h b/sysdeps/tile/nptl/tls.h
index c908fb8..16e8faf 100644
--- a/sysdeps/tile/nptl/tls.h
+++ b/sysdeps/tile/nptl/tls.h
@@ -25,17 +25,7 @@
 # include <stdbool.h>
 # include <stddef.h>
 # include <stdint.h>
-
-/* Type for the dtv.  */
-typedef union dtv
-{
-  size_t counter;
-  struct
-  {
-    void *val;
-    bool is_static;
-  } pointer;
-} dtv_t;
+# include <dl-dtv.h>
 
 #else /* __ASSEMBLER__ */
 # include <tcb-offsets.h>
diff --git a/sysdeps/x86_64/dl-tls.h b/sysdeps/x86_64/dl-tls.h
index 0f101e6..cf6c107 100644
--- a/sysdeps/x86_64/dl-tls.h
+++ b/sysdeps/x86_64/dl-tls.h
@@ -27,6 +27,3 @@ typedef struct dl_tls_index
 
 
 extern void *__tls_get_addr (tls_index *ti);
-
-/* Value used for dtv entries for which the allocation is delayed.  */
-#define TLS_DTV_UNALLOCATED	((void *) -1l)
diff --git a/sysdeps/x86_64/nptl/tls.h b/sysdeps/x86_64/nptl/tls.h
index 2b061a0..1bf9586 100644
--- a/sysdeps/x86_64/nptl/tls.h
+++ b/sysdeps/x86_64/nptl/tls.h
@@ -28,6 +28,7 @@
 # include <sysdep.h>
 # include <libc-internal.h>
 # include <kernel-features.h>
+# include <dl-dtv.h>
 
 /* Replacement type for __m128 since this file is included by ld.so,
    which is compiled with -mno-sse.  It must not change the alignment
@@ -38,18 +39,6 @@ typedef struct
 } __128bits;
 
 
-/* Type for the dtv.  */
-typedef union dtv
-{
-  size_t counter;
-  struct
-  {
-    void *val;
-    bool is_static;
-  } pointer;
-} dtv_t;
-
-
 typedef struct
 {
   void *tcb;		/* Pointer to the TCB.  Not necessarily the

http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=1ec838a143b35f65169acc455308eb20198a4853

commit 1ec838a143b35f65169acc455308eb20198a4853
Author: Mike Frysinger <vapier@gentoo.org>
Date:   Thu Dec 15 18:34:05 2016 -0500

    localedata: bs_BA: fix yesexpr/noexpr [BZ #20974]
    
    Both regexes end with a "*." which means the previous match can be
    omitted, and then the . allows them to match any input at all.
    
    This means tools like coreutils' `rm -i` will always delete things
    when prompted because the yesexpr regex matches all inputs (even
    the negative ones).
    
    (cherry picked from commit a035eb6928bc63fb798dcc1421529f933122d74f)

diff --git a/localedata/ChangeLog b/localedata/ChangeLog
index dd1c2b1..02c0219 100644
--- a/localedata/ChangeLog
+++ b/localedata/ChangeLog
@@ -1,3 +1,9 @@
+2016-12-30  Mike Frysinger  <vapier@gentoo.org>
+
+	[BZ #20974]
+	* localedata/bs_BA (LC_MESSAGES): Delete "*." from the end of
+	yesexpr and noexpr.
+
 2016-02-19  Florian Weimer  <fweimer@redhat.com>
 
 	[BZ #19581]
diff --git a/localedata/locales/bs_BA b/localedata/locales/bs_BA
index fa574a1..9201862 100644
--- a/localedata/locales/bs_BA
+++ b/localedata/locales/bs_BA
@@ -144,8 +144,8 @@ copy "en_DK"
 END LC_CTYPE
 
 LC_MESSAGES
-yesexpr "<U005E><U005B><U0064><U0044><U0079><U0059><U005D><U002A><U002E>"
-noexpr  "<U005E><U005B><U006E><U004E><U005D><U002A><U002E>"
+yesexpr "<U005E><U005B><U0064><U0044><U0079><U0059><U005D>"
+noexpr  "<U005E><U005B><U006E><U004E><U005D>"
 END LC_MESSAGES
 
 LC_MONETARY

http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=2eb71adc3fc023c026b88bdfce69561f1f91ee4a

commit 2eb71adc3fc023c026b88bdfce69561f1f91ee4a
Author: Siddhesh Poyarekar <siddhesh@sourceware.org>
Date:   Mon Jul 18 22:33:09 2016 +0530

    Fix cos computation for multiple precision fallback (bz #20357)
    
    During the sincos consolidation I made two mistakes, one was a logical
    error due to which cos(0x1.8475e5afd4481p+0) returned
    sin(0x1.8475e5afd4481p+0) instead.
    
    The second issue was an error in negating inputs for the correct
    quadrants for sine.  I could not find a suitable test case for this
    despite running a program to search for such an input for a couple of
    hours.
    
    Following patch fixes both issues.  Tested on x86_64.  Thanks to Matt
    Clay for identifying the issue.
    
    	[BZ #20357]
    	* sysdeps/ieee754/dbl-64/s_sin.c (sloww): Fix up condition
    	to call __mpsin/__mpcos and to negate values.
    	* math/auto-libm-test-in: Add test.
    	* math/auto-libm-test-out: Regenerate.
    
    (cherry picked from commit cbf88869edced4b23d792d95a8626e35b831df35)

diff --git a/ChangeLog b/ChangeLog
index dfd5040..411ba2e 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,12 @@
+2016-07-18  Siddhesh Poyarekar  <siddhesh@sourceware.org>
+	    Matt Clay  <mclay@lycos.com>
+
+	[BZ #20357]
+	* sysdeps/ieee754/dbl-64/s_sin.c (sloww): Fix up condition
+	to call __mpsin/__mpcos and to negate values.
+	* math/auto-libm-test-in: Add test.
+	* math/auto-libm-test-out: Regenerate.
+
 2016-10-17  H.J. Lu <hjl.tools@gmail.com>
 
 	[BZ #20384]
diff --git a/NEWS b/NEWS
index e03e9f1..b3beeaf 100644
--- a/NEWS
+++ b/NEWS
@@ -41,6 +41,7 @@ The following bugs are resolved with this release:
   [19879] network: nss_dns: Stack overflow in getnetbyname implementation
     (CVE-2016-3075)
   [20177] $dp is not initialized correctly in sysdeps/hppa/start.S
+  [20357] Incorrect cos result for 1.5174239687223976
 
 
 Version 2.23
diff --git a/math/auto-libm-test-in b/math/auto-libm-test-in
index 4b753de..1b25997 100644
--- a/math/auto-libm-test-in
+++ b/math/auto-libm-test-in
@@ -1144,6 +1144,7 @@ cos 0x4.7857dp+68
 cos -0x1.02e34cp+0
 cos 0xf.f0274p+4
 cos 0x3.042d88p+0
+cos 0x1.8475e5afd4481p+0
 
 cosh 0
 cosh -0
@@ -3780,6 +3781,7 @@ sin min
 sin -min
 sin min_subnorm
 sin -min_subnorm
+sin 0x1.8475e5afd4481p+0
 
 sincos 0
 sincos -0
@@ -3814,6 +3816,7 @@ sincos min
 sincos -min
 sincos min_subnorm
 sincos -min_subnorm
+sincos 0x1.8475e5afd4481p+0
 
 sinh 0
 sinh -0
diff --git a/math/auto-libm-test-out b/math/auto-libm-test-out
index 9d3819c..b751fa7 100644
--- a/math/auto-libm-test-out
+++ b/math/auto-libm-test-out
@@ -103416,6 +103416,75 @@ cos 0x3.042d88p+0
 = cos tonearest ldbl-128ibm 0x3.042d88p+0L : -0xf.dfe6f2169e24f276e8027d91bcp-4L : inexact-ok
 = cos towardzero ldbl-128ibm 0x3.042d88p+0L : -0xf.dfe6f2169e24f276e8027d91b8p-4L : inexact-ok
 = cos upward ldbl-128ibm 0x3.042d88p+0L : -0xf.dfe6f2169e24f276e8027d91b8p-4L : inexact-ok
+cos 0x1.8475e5afd4481p+0
+= cos downward flt-32 0x1.8475e6p+0f : 0xd.a8263p-8f : inexact-ok
+= cos tonearest flt-32 0x1.8475e6p+0f : 0xd.a8263p-8f : inexact-ok
+= cos towardzero flt-32 0x1.8475e6p+0f : 0xd.a8263p-8f : inexact-ok
+= cos upward flt-32 0x1.8475e6p+0f : 0xd.a8264p-8f : inexact-ok
+= cos downward dbl-64 0x1.8475e6p+0 : 0xd.a8263394be6dp-8 : inexact-ok
+= cos tonearest dbl-64 0x1.8475e6p+0 : 0xd.a8263394be6dp-8 : inexact-ok
+= cos towardzero dbl-64 0x1.8475e6p+0 : 0xd.a8263394be6dp-8 : inexact-ok
+= cos upward dbl-64 0x1.8475e6p+0 : 0xd.a8263394be6d8p-8 : inexact-ok
+= cos downward ldbl-96-intel 0x1.8475e6p+0L : 0xd.a8263394be6d0e5p-8L : inexact-ok
+= cos tonearest ldbl-96-intel 0x1.8475e6p+0L : 0xd.a8263394be6d0e6p-8L : inexact-ok
+= cos towardzero ldbl-96-intel 0x1.8475e6p+0L : 0xd.a8263394be6d0e5p-8L : inexact-ok
+= cos upward ldbl-96-intel 0x1.8475e6p+0L : 0xd.a8263394be6d0e6p-8L : inexact-ok
+= cos downward ldbl-96-m68k 0x1.8475e6p+0L : 0xd.a8263394be6d0e5p-8L : inexact-ok
+= cos tonearest ldbl-96-m68k 0x1.8475e6p+0L : 0xd.a8263394be6d0e6p-8L : inexact-ok
+= cos towardzero ldbl-96-m68k 0x1.8475e6p+0L : 0xd.a8263394be6d0e5p-8L : inexact-ok
+= cos upward ldbl-96-m68k 0x1.8475e6p+0L : 0xd.a8263394be6d0e6p-8L : inexact-ok
+= cos downward ldbl-128 0x1.8475e6p+0L : 0xd.a8263394be6d0e58c1c35a8a3bap-8L : inexact-ok
+= cos tonearest ldbl-128 0x1.8475e6p+0L : 0xd.a8263394be6d0e58c1c35a8a3bap-8L : inexact-ok
+= cos towardzero ldbl-128 0x1.8475e6p+0L : 0xd.a8263394be6d0e58c1c35a8a3bap-8L : inexact-ok
+= cos upward ldbl-128 0x1.8475e6p+0L : 0xd.a8263394be6d0e58c1c35a8a3ba8p-8L : inexact-ok
+= cos downward ldbl-128ibm 0x1.8475e6p+0L : 0xd.a8263394be6d0e58c1c35a8a38p-8L : inexact-ok
+= cos tonearest ldbl-128ibm 0x1.8475e6p+0L : 0xd.a8263394be6d0e58c1c35a8a3cp-8L : inexact-ok
+= cos towardzero ldbl-128ibm 0x1.8475e6p+0L : 0xd.a8263394be6d0e58c1c35a8a38p-8L : inexact-ok
+= cos upward ldbl-128ibm 0x1.8475e6p+0L : 0xd.a8263394be6d0e58c1c35a8a3cp-8L : inexact-ok
+= cos downward flt-32 0x1.8475e4p+0f : 0xd.a8283p-8f : inexact-ok
+= cos tonearest flt-32 0x1.8475e4p+0f : 0xd.a8283p-8f : inexact-ok
+= cos towardzero flt-32 0x1.8475e4p+0f : 0xd.a8283p-8f : inexact-ok
+= cos upward flt-32 0x1.8475e4p+0f : 0xd.a8284p-8f : inexact-ok
+= cos downward dbl-64 0x1.8475e4p+0 : 0xd.a82832da19f98p-8 : inexact-ok
+= cos tonearest dbl-64 0x1.8475e4p+0 : 0xd.a82832da19f98p-8 : inexact-ok
+= cos towardzero dbl-64 0x1.8475e4p+0 : 0xd.a82832da19f98p-8 : inexact-ok
+= cos upward dbl-64 0x1.8475e4p+0 : 0xd.a82832da19fap-8 : inexact-ok
+= cos downward ldbl-96-intel 0x1.8475e4p+0L : 0xd.a82832da19f9891p-8L : inexact-ok
+= cos tonearest ldbl-96-intel 0x1.8475e4p+0L : 0xd.a82832da19f9892p-8L : inexact-ok
+= cos towardzero ldbl-96-intel 0x1.8475e4p+0L : 0xd.a82832da19f9891p-8L : inexact-ok
+= cos upward ldbl-96-intel 0x1.8475e4p+0L : 0xd.a82832da19f9892p-8L : inexact-ok
+= cos downward ldbl-96-m68k 0x1.8475e4p+0L : 0xd.a82832da19f9891p-8L : inexact-ok
+= cos tonearest ldbl-96-m68k 0x1.8475e4p+0L : 0xd.a82832da19f9892p-8L : inexact-ok
+= cos towardzero ldbl-96-m68k 0x1.8475e4p+0L : 0xd.a82832da19f9891p-8L : inexact-ok
+= cos upward ldbl-96-m68k 0x1.8475e4p+0L : 0xd.a82832da19f9892p-8L : inexact-ok
+= cos downward ldbl-128 0x1.8475e4p+0L : 0xd.a82832da19f9891d9762fa659ff8p-8L : inexact-ok
+= cos tonearest ldbl-128 0x1.8475e4p+0L : 0xd.a82832da19f9891d9762fa659ff8p-8L : inexact-ok
+= cos towardzero ldbl-128 0x1.8475e4p+0L : 0xd.a82832da19f9891d9762fa659ff8p-8L : inexact-ok
+= cos upward ldbl-128 0x1.8475e4p+0L : 0xd.a82832da19f9891d9762fa65ap-8L : inexact-ok
+= cos downward ldbl-128ibm 0x1.8475e4p+0L : 0xd.a82832da19f9891d9762fa659cp-8L : inexact-ok
+= cos tonearest ldbl-128ibm 0x1.8475e4p+0L : 0xd.a82832da19f9891d9762fa65ap-8L : inexact-ok
+= cos towardzero ldbl-128ibm 0x1.8475e4p+0L : 0xd.a82832da19f9891d9762fa659cp-8L : inexact-ok
+= cos upward ldbl-128ibm 0x1.8475e4p+0L : 0xd.a82832da19f9891d9762fa65ap-8L : inexact-ok
+= cos downward dbl-64 0x1.8475e5afd4481p+0 : 0xd.a82683a33cbe8p-8 : inexact-ok
+= cos tonearest dbl-64 0x1.8475e5afd4481p+0 : 0xd.a82683a33cbe8p-8 : inexact-ok
+= cos towardzero dbl-64 0x1.8475e5afd4481p+0 : 0xd.a82683a33cbe8p-8 : inexact-ok
+= cos upward dbl-64 0x1.8475e5afd4481p+0 : 0xd.a82683a33cbfp-8 : inexact-ok
+= cos downward ldbl-96-intel 0x1.8475e5afd4481p+0L : 0xd.a82683a33cbebffp-8L : inexact-ok
+= cos tonearest ldbl-96-intel 0x1.8475e5afd4481p+0L : 0xd.a82683a33cbecp-8L : inexact-ok
+= cos towardzero ldbl-96-intel 0x1.8475e5afd4481p+0L : 0xd.a82683a33cbebffp-8L : inexact-ok
+= cos upward ldbl-96-intel 0x1.8475e5afd4481p+0L : 0xd.a82683a33cbecp-8L : inexact-ok
+= cos downward ldbl-96-m68k 0x1.8475e5afd4481p+0L : 0xd.a82683a33cbebffp-8L : inexact-ok
+= cos tonearest ldbl-96-m68k 0x1.8475e5afd4481p+0L : 0xd.a82683a33cbecp-8L : inexact-ok
+= cos towardzero ldbl-96-m68k 0x1.8475e5afd4481p+0L : 0xd.a82683a33cbebffp-8L : inexact-ok
+= cos upward ldbl-96-m68k 0x1.8475e5afd4481p+0L : 0xd.a82683a33cbecp-8L : inexact-ok
+= cos downward ldbl-128 0x1.8475e5afd4481p+0L : 0xd.a82683a33cbebfffffffa2966878p-8L : inexact-ok
+= cos tonearest ldbl-128 0x1.8475e5afd4481p+0L : 0xd.a82683a33cbebfffffffa2966878p-8L : inexact-ok
+= cos towardzero ldbl-128 0x1.8475e5afd4481p+0L : 0xd.a82683a33cbebfffffffa2966878p-8L : inexact-ok
+= cos upward ldbl-128 0x1.8475e5afd4481p+0L : 0xd.a82683a33cbebfffffffa296688p-8L : inexact-ok
+= cos downward ldbl-128ibm 0x1.8475e5afd4481p+0L : 0xd.a82683a33cbebfffffffa29668p-8L : inexact-ok
+= cos tonearest ldbl-128ibm 0x1.8475e5afd4481p+0L : 0xd.a82683a33cbebfffffffa29668p-8L : inexact-ok
+= cos towardzero ldbl-128ibm 0x1.8475e5afd4481p+0L : 0xd.a82683a33cbebfffffffa29668p-8L : inexact-ok
+= cos upward ldbl-128ibm 0x1.8475e5afd4481p+0L : 0xd.a82683a33cbebfffffffa2966cp-8L : inexact-ok
 cosh 0
 = cosh downward flt-32 0x0p+0f : 0x1p+0f : inexact-ok
 = cosh tonearest flt-32 0x0p+0f : 0x1p+0f : inexact-ok
@@ -262073,6 +262142,75 @@ sin -min_subnorm
 = sin tonearest ldbl-128 -0x4p-16496L : -0x4p-16496L : inexact-ok underflow errno-erange-ok
 = sin towardzero ldbl-128 -0x4p-16496L : -0x0p+0L : inexact-ok underflow errno-erange-ok
 = sin upward ldbl-128 -0x4p-16496L : -0x0p+0L : inexact-ok underflow errno-erange-ok
+sin 0x1.8475e5afd4481p+0
+= sin downward flt-32 0x1.8475e6p+0f : 0xf.fa2adp-4f : inexact-ok
+= sin tonearest flt-32 0x1.8475e6p+0f : 0xf.fa2aep-4f : inexact-ok
+= sin towardzero flt-32 0x1.8475e6p+0f : 0xf.fa2adp-4f : inexact-ok
+= sin upward flt-32 0x1.8475e6p+0f : 0xf.fa2aep-4f : inexact-ok
+= sin downward dbl-64 0x1.8475e6p+0 : 0xf.fa2add3e58948p-4 : inexact-ok
+= sin tonearest dbl-64 0x1.8475e6p+0 : 0xf.fa2add3e58948p-4 : inexact-ok
+= sin towardzero dbl-64 0x1.8475e6p+0 : 0xf.fa2add3e58948p-4 : inexact-ok
+= sin upward dbl-64 0x1.8475e6p+0 : 0xf.fa2add3e5895p-4 : inexact-ok
+= sin downward ldbl-96-intel 0x1.8475e6p+0L : 0xf.fa2add3e58948d1p-4L : inexact-ok
+= sin tonearest ldbl-96-intel 0x1.8475e6p+0L : 0xf.fa2add3e58948d1p-4L : inexact-ok
+= sin towardzero ldbl-96-intel 0x1.8475e6p+0L : 0xf.fa2add3e58948d1p-4L : inexact-ok
+= sin upward ldbl-96-intel 0x1.8475e6p+0L : 0xf.fa2add3e58948d2p-4L : inexact-ok
+= sin downward ldbl-96-m68k 0x1.8475e6p+0L : 0xf.fa2add3e58948d1p-4L : inexact-ok
+= sin tonearest ldbl-96-m68k 0x1.8475e6p+0L : 0xf.fa2add3e58948d1p-4L : inexact-ok
+= sin towardzero ldbl-96-m68k 0x1.8475e6p+0L : 0xf.fa2add3e58948d1p-4L : inexact-ok
+= sin upward ldbl-96-m68k 0x1.8475e6p+0L : 0xf.fa2add3e58948d2p-4L : inexact-ok
+= sin downward ldbl-128 0x1.8475e6p+0L : 0xf.fa2add3e58948d10238cc27b5618p-4L : inexact-ok
+= sin tonearest ldbl-128 0x1.8475e6p+0L : 0xf.fa2add3e58948d10238cc27b562p-4L : inexact-ok
+= sin towardzero ldbl-128 0x1.8475e6p+0L : 0xf.fa2add3e58948d10238cc27b5618p-4L : inexact-ok
+= sin upward ldbl-128 0x1.8475e6p+0L : 0xf.fa2add3e58948d10238cc27b562p-4L : inexact-ok
+= sin downward ldbl-128ibm 0x1.8475e6p+0L : 0xf.fa2add3e58948d10238cc27b54p-4L : inexact-ok
+= sin tonearest ldbl-128ibm 0x1.8475e6p+0L : 0xf.fa2add3e58948d10238cc27b58p-4L : inexact-ok
+= sin towardzero ldbl-128ibm 0x1.8475e6p+0L : 0xf.fa2add3e58948d10238cc27b54p-4L : inexact-ok
+= sin upward ldbl-128ibm 0x1.8475e6p+0L : 0xf.fa2add3e58948d10238cc27b58p-4L : inexact-ok
+= sin downward flt-32 0x1.8475e4p+0f : 0xf.fa2adp-4f : inexact-ok
+= sin tonearest flt-32 0x1.8475e4p+0f : 0xf.fa2aep-4f : inexact-ok
+= sin towardzero flt-32 0x1.8475e4p+0f : 0xf.fa2adp-4f : inexact-ok
+= sin upward flt-32 0x1.8475e4p+0f : 0xf.fa2aep-4f : inexact-ok
+= sin downward dbl-64 0x1.8475e4p+0 : 0xf.fa2adb8953aep-4 : inexact-ok
+= sin tonearest dbl-64 0x1.8475e4p+0 : 0xf.fa2adb8953aep-4 : inexact-ok
+= sin towardzero dbl-64 0x1.8475e4p+0 : 0xf.fa2adb8953aep-4 : inexact-ok
+= sin upward dbl-64 0x1.8475e4p+0 : 0xf.fa2adb8953ae8p-4 : inexact-ok
+= sin downward ldbl-96-intel 0x1.8475e4p+0L : 0xf.fa2adb8953ae262p-4L : inexact-ok
+= sin tonearest ldbl-96-intel 0x1.8475e4p+0L : 0xf.fa2adb8953ae262p-4L : inexact-ok
+= sin towardzero ldbl-96-intel 0x1.8475e4p+0L : 0xf.fa2adb8953ae262p-4L : inexact-ok
+= sin upward ldbl-96-intel 0x1.8475e4p+0L : 0xf.fa2adb8953ae263p-4L : inexact-ok
+= sin downward ldbl-96-m68k 0x1.8475e4p+0L : 0xf.fa2adb8953ae262p-4L : inexact-ok
+= sin tonearest ldbl-96-m68k 0x1.8475e4p+0L : 0xf.fa2adb8953ae262p-4L : inexact-ok
+= sin towardzero ldbl-96-m68k 0x1.8475e4p+0L : 0xf.fa2adb8953ae262p-4L : inexact-ok
+= sin upward ldbl-96-m68k 0x1.8475e4p+0L : 0xf.fa2adb8953ae263p-4L : inexact-ok
+= sin downward ldbl-128 0x1.8475e4p+0L : 0xf.fa2adb8953ae26229c919ec8f6b8p-4L : inexact-ok
+= sin tonearest ldbl-128 0x1.8475e4p+0L : 0xf.fa2adb8953ae26229c919ec8f6cp-4L : inexact-ok
+= sin towardzero ldbl-128 0x1.8475e4p+0L : 0xf.fa2adb8953ae26229c919ec8f6b8p-4L : inexact-ok
+= sin upward ldbl-128 0x1.8475e4p+0L : 0xf.fa2adb8953ae26229c919ec8f6cp-4L : inexact-ok
+= sin downward ldbl-128ibm 0x1.8475e4p+0L : 0xf.fa2adb8953ae26229c919ec8f4p-4L : inexact-ok
+= sin tonearest ldbl-128ibm 0x1.8475e4p+0L : 0xf.fa2adb8953ae26229c919ec8f8p-4L : inexact-ok
+= sin towardzero ldbl-128ibm 0x1.8475e4p+0L : 0xf.fa2adb8953ae26229c919ec8f4p-4L : inexact-ok
+= sin upward ldbl-128ibm 0x1.8475e4p+0L : 0xf.fa2adb8953ae26229c919ec8f8p-4L : inexact-ok
+= sin downward dbl-64 0x1.8475e5afd4481p+0 : 0xf.fa2adcf9ea838p-4 : inexact-ok
+= sin tonearest dbl-64 0x1.8475e5afd4481p+0 : 0xf.fa2adcf9ea84p-4 : inexact-ok
+= sin towardzero dbl-64 0x1.8475e5afd4481p+0 : 0xf.fa2adcf9ea838p-4 : inexact-ok
+= sin upward dbl-64 0x1.8475e5afd4481p+0 : 0xf.fa2adcf9ea84p-4 : inexact-ok
+= sin downward ldbl-96-intel 0x1.8475e5afd4481p+0L : 0xf.fa2adcf9ea83dbdp-4L : inexact-ok
+= sin tonearest ldbl-96-intel 0x1.8475e5afd4481p+0L : 0xf.fa2adcf9ea83dbep-4L : inexact-ok
+= sin towardzero ldbl-96-intel 0x1.8475e5afd4481p+0L : 0xf.fa2adcf9ea83dbdp-4L : inexact-ok
+= sin upward ldbl-96-intel 0x1.8475e5afd4481p+0L : 0xf.fa2adcf9ea83dbep-4L : inexact-ok
+= sin downward ldbl-96-m68k 0x1.8475e5afd4481p+0L : 0xf.fa2adcf9ea83dbdp-4L : inexact-ok
+= sin tonearest ldbl-96-m68k 0x1.8475e5afd4481p+0L : 0xf.fa2adcf9ea83dbep-4L : inexact-ok
+= sin towardzero ldbl-96-m68k 0x1.8475e5afd4481p+0L : 0xf.fa2adcf9ea83dbdp-4L : inexact-ok
+= sin upward ldbl-96-m68k 0x1.8475e5afd4481p+0L : 0xf.fa2adcf9ea83dbep-4L : inexact-ok
+= sin downward ldbl-128 0x1.8475e5afd4481p+0L : 0xf.fa2adcf9ea83dbdd053ee455ea68p-4L : inexact-ok
+= sin tonearest ldbl-128 0x1.8475e5afd4481p+0L : 0xf.fa2adcf9ea83dbdd053ee455ea7p-4L : inexact-ok
+= sin towardzero ldbl-128 0x1.8475e5afd4481p+0L : 0xf.fa2adcf9ea83dbdd053ee455ea68p-4L : inexact-ok
+= sin upward ldbl-128 0x1.8475e5afd4481p+0L : 0xf.fa2adcf9ea83dbdd053ee455ea7p-4L : inexact-ok
+= sin downward ldbl-128ibm 0x1.8475e5afd4481p+0L : 0xf.fa2adcf9ea83dbdd053ee455e8p-4L : inexact-ok
+= sin tonearest ldbl-128ibm 0x1.8475e5afd4481p+0L : 0xf.fa2adcf9ea83dbdd053ee455ecp-4L : inexact-ok
+= sin towardzero ldbl-128ibm 0x1.8475e5afd4481p+0L : 0xf.fa2adcf9ea83dbdd053ee455e8p-4L : inexact-ok
+= sin upward ldbl-128ibm 0x1.8475e5afd4481p+0L : 0xf.fa2adcf9ea83dbdd053ee455ecp-4L : inexact-ok
 sincos 0
 = sincos downward flt-32 0x0p+0f : 0x0p+0f 0x1p+0f : inexact-ok
 = sincos tonearest flt-32 0x0p+0f : 0x0p+0f 0x1p+0f : inexact-ok
@@ -264170,6 +264308,75 @@ sincos -min_subnorm
 = sincos tonearest ldbl-128 -0x4p-16496L : -0x4p-16496L 0x1p+0L : inexact-ok underflow errno-erange-ok
 = sincos towardzero ldbl-128 -0x4p-16496L : -0x0p+0L 0xf.fffffffffffffffffffffffffff8p-4L : inexact-ok underflow errno-erange-ok
 = sincos upward ldbl-128 -0x4p-16496L : -0x0p+0L 0x1p+0L : inexact-ok underflow errno-erange-ok
+sincos 0x1.8475e5afd4481p+0
+= sincos downward flt-32 0x1.8475e6p+0f : 0xf.fa2adp-4f 0xd.a8263p-8f : inexact-ok
+= sincos tonearest flt-32 0x1.8475e6p+0f : 0xf.fa2aep-4f 0xd.a8263p-8f : inexact-ok
+= sincos towardzero flt-32 0x1.8475e6p+0f : 0xf.fa2adp-4f 0xd.a8263p-8f : inexact-ok
+= sincos upward flt-32 0x1.8475e6p+0f : 0xf.fa2aep-4f 0xd.a8264p-8f : inexact-ok
+= sincos downward dbl-64 0x1.8475e6p+0 : 0xf.fa2add3e58948p-4 0xd.a8263394be6dp-8 : inexact-ok
+= sincos tonearest dbl-64 0x1.8475e6p+0 : 0xf.fa2add3e58948p-4 0xd.a8263394be6dp-8 : inexact-ok
+= sincos towardzero dbl-64 0x1.8475e6p+0 : 0xf.fa2add3e58948p-4 0xd.a8263394be6dp-8 : inexact-ok
+= sincos upward dbl-64 0x1.8475e6p+0 : 0xf.fa2add3e5895p-4 0xd.a8263394be6d8p-8 : inexact-ok
+= sincos downward ldbl-96-intel 0x1.8475e6p+0L : 0xf.fa2add3e58948d1p-4L 0xd.a8263394be6d0e5p-8L : inexact-ok
+= sincos tonearest ldbl-96-intel 0x1.8475e6p+0L : 0xf.fa2add3e58948d1p-4L 0xd.a8263394be6d0e6p-8L : inexact-ok
+= sincos towardzero ldbl-96-intel 0x1.8475e6p+0L : 0xf.fa2add3e58948d1p-4L 0xd.a8263394be6d0e5p-8L : inexact-ok
+= sincos upward ldbl-96-intel 0x1.8475e6p+0L : 0xf.fa2add3e58948d2p-4L 0xd.a8263394be6d0e6p-8L : inexact-ok
+= sincos downward ldbl-96-m68k 0x1.8475e6p+0L : 0xf.fa2add3e58948d1p-4L 0xd.a8263394be6d0e5p-8L : inexact-ok
+= sincos tonearest ldbl-96-m68k 0x1.8475e6p+0L : 0xf.fa2add3e58948d1p-4L 0xd.a8263394be6d0e6p-8L : inexact-ok
+= sincos towardzero ldbl-96-m68k 0x1.8475e6p+0L : 0xf.fa2add3e58948d1p-4L 0xd.a8263394be6d0e5p-8L : inexact-ok
+= sincos upward ldbl-96-m68k 0x1.8475e6p+0L : 0xf.fa2add3e58948d2p-4L 0xd.a8263394be6d0e6p-8L : inexact-ok
+= sincos downward ldbl-128 0x1.8475e6p+0L : 0xf.fa2add3e58948d10238cc27b5618p-4L 0xd.a8263394be6d0e58c1c35a8a3bap-8L : inexact-ok
+= sincos tonearest ldbl-128 0x1.8475e6p+0L : 0xf.fa2add3e58948d10238cc27b562p-4L 0xd.a8263394be6d0e58c1c35a8a3bap-8L : inexact-ok
+= sincos towardzero ldbl-128 0x1.8475e6p+0L : 0xf.fa2add3e58948d10238cc27b5618p-4L 0xd.a8263394be6d0e58c1c35a8a3bap-8L : inexact-ok
+= sincos upward ldbl-128 0x1.8475e6p+0L : 0xf.fa2add3e58948d10238cc27b562p-4L 0xd.a8263394be6d0e58c1c35a8a3ba8p-8L : inexact-ok
+= sincos downward ldbl-128ibm 0x1.8475e6p+0L : 0xf.fa2add3e58948d10238cc27b54p-4L 0xd.a8263394be6d0e58c1c35a8a38p-8L : inexact-ok
+= sincos tonearest ldbl-128ibm 0x1.8475e6p+0L : 0xf.fa2add3e58948d10238cc27b58p-4L 0xd.a8263394be6d0e58c1c35a8a3cp-8L : inexact-ok
+= sincos towardzero ldbl-128ibm 0x1.8475e6p+0L : 0xf.fa2add3e58948d10238cc27b54p-4L 0xd.a8263394be6d0e58c1c35a8a38p-8L : inexact-ok
+= sincos upward ldbl-128ibm 0x1.8475e6p+0L : 0xf.fa2add3e58948d10238cc27b58p-4L 0xd.a8263394be6d0e58c1c35a8a3cp-8L : inexact-ok
+= sincos downward flt-32 0x1.8475e4p+0f : 0xf.fa2adp-4f 0xd.a8283p-8f : inexact-ok
+= sincos tonearest flt-32 0x1.8475e4p+0f : 0xf.fa2aep-4f 0xd.a8283p-8f : inexact-ok
+= sincos towardzero flt-32 0x1.8475e4p+0f : 0xf.fa2adp-4f 0xd.a8283p-8f : inexact-ok
+= sincos upward flt-32 0x1.8475e4p+0f : 0xf.fa2aep-4f 0xd.a8284p-8f : inexact-ok
+= sincos downward dbl-64 0x1.8475e4p+0 : 0xf.fa2adb8953aep-4 0xd.a82832da19f98p-8 : inexact-ok
+= sincos tonearest dbl-64 0x1.8475e4p+0 : 0xf.fa2adb8953aep-4 0xd.a82832da19f98p-8 : inexact-ok
+= sincos towardzero dbl-64 0x1.8475e4p+0 : 0xf.fa2adb8953aep-4 0xd.a82832da19f98p-8 : inexact-ok
+= sincos upward dbl-64 0x1.8475e4p+0 : 0xf.fa2adb8953ae8p-4 0xd.a82832da19fap-8 : inexact-ok
+= sincos downward ldbl-96-intel 0x1.8475e4p+0L : 0xf.fa2adb8953ae262p-4L 0xd.a82832da19f9891p-8L : inexact-ok
+= sincos tonearest ldbl-96-intel 0x1.8475e4p+0L : 0xf.fa2adb8953ae262p-4L 0xd.a82832da19f9892p-8L : inexact-ok
+= sincos towardzero ldbl-96-intel 0x1.8475e4p+0L : 0xf.fa2adb8953ae262p-4L 0xd.a82832da19f9891p-8L : inexact-ok
+= sincos upward ldbl-96-intel 0x1.8475e4p+0L : 0xf.fa2adb8953ae263p-4L 0xd.a82832da19f9892p-8L : inexact-ok
+= sincos downward ldbl-96-m68k 0x1.8475e4p+0L : 0xf.fa2adb8953ae262p-4L 0xd.a82832da19f9891p-8L : inexact-ok
+= sincos tonearest ldbl-96-m68k 0x1.8475e4p+0L : 0xf.fa2adb8953ae262p-4L 0xd.a82832da19f9892p-8L : inexact-ok
+= sincos towardzero ldbl-96-m68k 0x1.8475e4p+0L : 0xf.fa2adb8953ae262p-4L 0xd.a82832da19f9891p-8L : inexact-ok
+= sincos upward ldbl-96-m68k 0x1.8475e4p+0L : 0xf.fa2adb8953ae263p-4L 0xd.a82832da19f9892p-8L : inexact-ok
+= sincos downward ldbl-128 0x1.8475e4p+0L : 0xf.fa2adb8953ae26229c919ec8f6b8p-4L 0xd.a82832da19f9891d9762fa659ff8p-8L : inexact-ok
+= sincos tonearest ldbl-128 0x1.8475e4p+0L : 0xf.fa2adb8953ae26229c919ec8f6cp-4L 0xd.a82832da19f9891d9762fa659ff8p-8L : inexact-ok
+= sincos towardzero ldbl-128 0x1.8475e4p+0L : 0xf.fa2adb8953ae26229c919ec8f6b8p-4L 0xd.a82832da19f9891d9762fa659ff8p-8L : inexact-ok
+= sincos upward ldbl-128 0x1.8475e4p+0L : 0xf.fa2adb8953ae26229c919ec8f6cp-4L 0xd.a82832da19f9891d9762fa65ap-8L : inexact-ok
+= sincos downward ldbl-128ibm 0x1.8475e4p+0L : 0xf.fa2adb8953ae26229c919ec8f4p-4L 0xd.a82832da19f9891d9762fa659cp-8L : inexact-ok
+= sincos tonearest ldbl-128ibm 0x1.8475e4p+0L : 0xf.fa2adb8953ae26229c919ec8f8p-4L 0xd.a82832da19f9891d9762fa65ap-8L : inexact-ok
+= sincos towardzero ldbl-128ibm 0x1.8475e4p+0L : 0xf.fa2adb8953ae26229c919ec8f4p-4L 0xd.a82832da19f9891d9762fa659cp-8L : inexact-ok
+= sincos upward ldbl-128ibm 0x1.8475e4p+0L : 0xf.fa2adb8953ae26229c919ec8f8p-4L 0xd.a82832da19f9891d9762fa65ap-8L : inexact-ok
+= sincos downward dbl-64 0x1.8475e5afd4481p+0 : 0xf.fa2adcf9ea838p-4 0xd.a82683a33cbe8p-8 : inexact-ok
+= sincos tonearest dbl-64 0x1.8475e5afd4481p+0 : 0xf.fa2adcf9ea84p-4 0xd.a82683a33cbe8p-8 : inexact-ok
+= sincos towardzero dbl-64 0x1.8475e5afd4481p+0 : 0xf.fa2adcf9ea838p-4 0xd.a82683a33cbe8p-8 : inexact-ok
+= sincos upward dbl-64 0x1.8475e5afd4481p+0 : 0xf.fa2adcf9ea84p-4 0xd.a82683a33cbfp-8 : inexact-ok
+= sincos downward ldbl-96-intel 0x1.8475e5afd4481p+0L : 0xf.fa2adcf9ea83dbdp-4L 0xd.a82683a33cbebffp-8L : inexact-ok
+= sincos tonearest ldbl-96-intel 0x1.8475e5afd4481p+0L : 0xf.fa2adcf9ea83dbep-4L 0xd.a82683a33cbecp-8L : inexact-ok
+= sincos towardzero ldbl-96-intel 0x1.8475e5afd4481p+0L : 0xf.fa2adcf9ea83dbdp-4L 0xd.a82683a33cbebffp-8L : inexact-ok
+= sincos upward ldbl-96-intel 0x1.8475e5afd4481p+0L : 0xf.fa2adcf9ea83dbep-4L 0xd.a82683a33cbecp-8L : inexact-ok
+= sincos downward ldbl-96-m68k 0x1.8475e5afd4481p+0L : 0xf.fa2adcf9ea83dbdp-4L 0xd.a82683a33cbebffp-8L : inexact-ok
+= sincos tonearest ldbl-96-m68k 0x1.8475e5afd4481p+0L : 0xf.fa2adcf9ea83dbep-4L 0xd.a82683a33cbecp-8L : inexact-ok
+= sincos towardzero ldbl-96-m68k 0x1.8475e5afd4481p+0L : 0xf.fa2adcf9ea83dbdp-4L 0xd.a82683a33cbebffp-8L : inexact-ok
+= sincos upward ldbl-96-m68k 0x1.8475e5afd4481p+0L : 0xf.fa2adcf9ea83dbep-4L 0xd.a82683a33cbecp-8L : inexact-ok
+= sincos downward ldbl-128 0x1.8475e5afd4481p+0L : 0xf.fa2adcf9ea83dbdd053ee455ea68p-4L 0xd.a82683a33cbebfffffffa2966878p-8L : inexact-ok
+= sincos tonearest ldbl-128 0x1.8475e5afd4481p+0L : 0xf.fa2adcf9ea83dbdd053ee455ea7p-4L 0xd.a82683a33cbebfffffffa2966878p-8L : inexact-ok
+= sincos towardzero ldbl-128 0x1.8475e5afd4481p+0L : 0xf.fa2adcf9ea83dbdd053ee455ea68p-4L 0xd.a82683a33cbebfffffffa2966878p-8L : inexact-ok
+= sincos upward ldbl-128 0x1.8475e5afd4481p+0L : 0xf.fa2adcf9ea83dbdd053ee455ea7p-4L 0xd.a82683a33cbebfffffffa296688p-8L : inexact-ok
+= sincos downward ldbl-128ibm 0x1.8475e5afd4481p+0L : 0xf.fa2adcf9ea83dbdd053ee455e8p-4L 0xd.a82683a33cbebfffffffa29668p-8L : inexact-ok
+= sincos tonearest ldbl-128ibm 0x1.8475e5afd4481p+0L : 0xf.fa2adcf9ea83dbdd053ee455ecp-4L 0xd.a82683a33cbebfffffffa29668p-8L : inexact-ok
+= sincos towardzero ldbl-128ibm 0x1.8475e5afd4481p+0L : 0xf.fa2adcf9ea83dbdd053ee455e8p-4L 0xd.a82683a33cbebfffffffa29668p-8L : inexact-ok
+= sincos upward ldbl-128ibm 0x1.8475e5afd4481p+0L : 0xf.fa2adcf9ea83dbdd053ee455ecp-4L 0xd.a82683a33cbebfffffffa2966cp-8L : inexact-ok
 sinh 0
 = sinh downward flt-32 0x0p+0f : 0x0p+0f : inexact-ok
 = sinh tonearest flt-32 0x0p+0f : 0x0p+0f : inexact-ok
diff --git a/sysdeps/ieee754/dbl-64/s_sin.c b/sysdeps/ieee754/dbl-64/s_sin.c
index ca2532f..7c9a079 100644
--- a/sysdeps/ieee754/dbl-64/s_sin.c
+++ b/sysdeps/ieee754/dbl-64/s_sin.c
@@ -803,7 +803,7 @@ sloww (double x, double dx, double orig, int k)
   a = t - y;
   da = ((t - a) - y) + da;
 
-  if (n == 2 || n == 1)
+  if (n & 2)
     {
       a = -a;
       da = -da;
@@ -817,7 +817,7 @@ sloww (double x, double dx, double orig, int k)
   if (w[0] == w[0] + cor)
     return (a > 0) ? w[0] : -w[0];
 
-  return (n & 1) ? __mpcos (orig, 0, true) : __mpsin (orig, 0, true);
+  return k ? __mpcos (orig, 0, true) : __mpsin (orig, 0, true);
 }
 
 /***************************************************************************/

-----------------------------------------------------------------------

Summary of changes:
 ChangeLog                              |  146 +++++++++++++++++
 NEWS                                   |    1 +
 csu/libc-tls.c                         |    2 +-
 elf/dl-tls.c                           |  164 ++++++++++++--------
 include/libc-symbols.h                 |   15 ++
 localedata/ChangeLog                   |    6 +
 localedata/locales/bs_BA               |    4 +-
 malloc/Makefile                        |   31 ++++-
 malloc/tst-interpose-aux-nothread.c    |   20 +++
 malloc/tst-interpose-aux-thread.c      |   20 +++
 malloc/tst-interpose-aux.c             |  270 ++++++++++++++++++++++++++++++++
 malloc/tst-interpose-aux.h             |   30 ++++
 malloc/tst-interpose-nothread.c        |   20 +++
 malloc/tst-interpose-skeleton.c        |  210 +++++++++++++++++++++++++
 malloc/tst-interpose-static-nothread.c |   19 +++
 malloc/tst-interpose-static-thread.c   |   19 +++
 malloc/tst-interpose-thread.c          |   20 +++
 math/auto-libm-test-in                 |    3 +
 math/auto-libm-test-out                |  207 ++++++++++++++++++++++++
 nptl/Makefile                          |    8 +-
 nptl/allocatestack.c                   |    4 +-
 nptl/tst-tls3-malloc.c                 |   31 ++++
 nptl/tst-tls3.c                        |   10 +-
 sysdeps/aarch64/dl-tls.h               |    3 -
 sysdeps/aarch64/nptl/tls.h             |   12 +--
 sysdeps/alpha/dl-tls.h                 |    3 -
 sysdeps/alpha/nptl/tls.h               |   12 +--
 sysdeps/arm/dl-tls.h                   |    3 -
 sysdeps/arm/nptl/tls.h                 |   12 +--
 sysdeps/generic/dl-dtv.h               |   38 +++++
 sysdeps/hppa/dl-tls.h                  |    3 -
 sysdeps/hppa/nptl/tls.h                |   12 +--
 sysdeps/i386/dl-tls.h                  |    3 -
 sysdeps/i386/nptl/tls.h                |   14 +--
 sysdeps/ia64/dl-tls.h                  |    3 -
 sysdeps/ia64/nptl/tls.h                |   14 +--
 sysdeps/ieee754/dbl-64/s_sin.c         |    4 +-
 sysdeps/m68k/dl-tls.h                  |    3 -
 sysdeps/m68k/nptl/tls.h                |   12 +--
 sysdeps/mach/hurd/fork.c               |    6 +-
 sysdeps/mach/hurd/i386/tls.h           |   12 +--
 sysdeps/microblaze/dl-tls.h            |    3 -
 sysdeps/microblaze/nptl/tls.h          |   12 +--
 sysdeps/mips/dl-tls.h                  |    3 -
 sysdeps/mips/nptl/tls.h                |   13 +--
 sysdeps/nios2/dl-tls.h                 |    3 -
 sysdeps/nios2/nptl/tls.h               |   12 +--
 sysdeps/nptl/fork.c                    |    6 +-
 sysdeps/powerpc/dl-tls.h               |    3 -
 sysdeps/powerpc/nptl/tls.h             |   12 +--
 sysdeps/s390/dl-tls.h                  |    3 -
 sysdeps/s390/nptl/tls.h                |   14 +--
 sysdeps/sh/dl-tls.h                    |    3 -
 sysdeps/sh/nptl/tls.h                  |   12 +--
 sysdeps/sparc/dl-tls.h                 |    3 -
 sysdeps/sparc/nptl/tls.h               |   12 +--
 sysdeps/tile/dl-tls.h                  |    3 -
 sysdeps/tile/nptl/tls.h                |   12 +--
 sysdeps/x86_64/dl-tls.h                |    3 -
 sysdeps/x86_64/nptl/tls.h              |   13 +--
 test-skeleton.c                        |    2 +
 61 files changed, 1251 insertions(+), 325 deletions(-)
 create mode 100644 malloc/tst-interpose-aux-nothread.c
 create mode 100644 malloc/tst-interpose-aux-thread.c
 create mode 100644 malloc/tst-interpose-aux.c
 create mode 100644 malloc/tst-interpose-aux.h
 create mode 100644 malloc/tst-interpose-nothread.c
 create mode 100644 malloc/tst-interpose-skeleton.c
 create mode 100644 malloc/tst-interpose-static-nothread.c
 create mode 100644 malloc/tst-interpose-static-thread.c
 create mode 100644 malloc/tst-interpose-thread.c
 create mode 100644 nptl/tst-tls3-malloc.c
 create mode 100644 sysdeps/generic/dl-dtv.h


hooks/post-receive
-- 
GNU C Library master sources


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]