[Feature][ZXW-33]merge ZXW 0428 version

Change-Id: I11f167edfea428d9fab198ff00ff1364932d1b0b
diff --git a/ap/libc/glibc/glibc-2.23/nptl/tst-pthread-getattr.c b/ap/libc/glibc/glibc-2.23/nptl/tst-pthread-getattr.c
new file mode 100644
index 0000000..59a3ceb
--- /dev/null
+++ b/ap/libc/glibc/glibc-2.23/nptl/tst-pthread-getattr.c
@@ -0,0 +1,161 @@
+/* Make sure that the stackaddr returned by pthread_getattr_np is
+   reachable.
+
+   Copyright (C) 2012-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/>.  */
+
+#include <stdio.h>
+#include <string.h>
+#include <sys/resource.h>
+#include <sys/param.h>
+#include <pthread.h>
+#include <alloca.h>
+#include <assert.h>
+#include <unistd.h>
+#include <inttypes.h>
+
+/* There is an obscure bug in the kernel due to which RLIMIT_STACK is sometimes
+   returned as unlimited when it is not, which may cause this test to fail.
+   There is also the other case where RLIMIT_STACK is intentionally set as
+   unlimited or very high, which may result in a vma that is too large and again
+   results in a test case failure.  To avoid these problems, we cap the stack
+   size to one less than 8M.  See the following mailing list threads for more
+   information about this problem:
+   <http://sourceware.org/ml/libc-alpha/2012-06/msg00599.html>
+   <http://sourceware.org/ml/libc-alpha/2012-06/msg00713.html>.  */
+#define MAX_STACK_SIZE (8192 * 1024 - 1)
+
+static size_t pagesize;
+
+/* Check if the page in which TARGET lies is accessible.  This will segfault
+   if it fails.  */
+static volatile char *
+allocate_and_test (char *target)
+{
+  volatile char *mem = (char *) &mem;
+  /* FIXME:  mem >= target for _STACK_GROWSUP.  */
+  mem = alloca ((size_t) (mem - target));
+
+  *mem = 42;
+  return mem;
+}
+
+static int
+get_self_pthread_attr (const char *id, void **stackaddr, size_t *stacksize)
+{
+  pthread_attr_t attr;
+  int ret;
+  pthread_t me = pthread_self ();
+
+  if ((ret = pthread_getattr_np (me, &attr)) < 0)
+    {
+      printf ("%s: pthread_getattr_np failed: %s\n", id, strerror (ret));
+      return 1;
+    }
+
+  if ((ret = pthread_attr_getstack (&attr, stackaddr, stacksize)) < 0)
+    {
+      printf ("%s: pthread_attr_getstack returned error: %s\n", id,
+	      strerror (ret));
+      return 1;
+    }
+
+  return 0;
+}
+
+/* Verify that the stack size returned by pthread_getattr_np is usable when
+   the returned value is subject to rlimit.  */
+static int
+check_stack_top (void)
+{
+  struct rlimit stack_limit;
+  void *stackaddr;
+  volatile void *mem;
+  size_t stacksize = 0;
+  int ret;
+  uintptr_t pagemask = ~(pagesize - 1);
+
+  puts ("Verifying that stack top is accessible");
+
+  ret = getrlimit (RLIMIT_STACK, &stack_limit);
+  if (ret)
+    {
+      perror ("getrlimit failed");
+      return 1;
+    }
+
+  printf ("current rlimit_stack is %zu\n", (size_t) stack_limit.rlim_cur);
+
+  if (get_self_pthread_attr ("check_stack_top", &stackaddr, &stacksize))
+    return 1;
+
+  /* Reduce the rlimit to a page less that what is currently being returned
+     (subject to a maximum of MAX_STACK_SIZE) so that we ensure that
+     pthread_getattr_np uses rlimit.  The figure is intentionally unaligned so
+     to verify that pthread_getattr_np returns an aligned stacksize that
+     correctly fits into the rlimit.  We don't bother about the case where the
+     stack is limited by the vma below it and not by the rlimit because the
+     stacksize returned in that case is computed from the end of that vma and is
+     hence safe.  */
+  stack_limit.rlim_cur = MIN (stacksize - pagesize + 1, MAX_STACK_SIZE);
+  printf ("Adjusting RLIMIT_STACK to %zu\n", (size_t) stack_limit.rlim_cur);
+  if ((ret = setrlimit (RLIMIT_STACK, &stack_limit)) < 0)
+    {
+      perror ("setrlimit failed");
+      return 1;
+    }
+
+  if (get_self_pthread_attr ("check_stack_top2", &stackaddr, &stacksize))
+    return 1;
+
+  printf ("Adjusted rlimit: stacksize=%zu, stackaddr=%p\n", stacksize,
+          stackaddr);
+
+  /* A lot of targets tend to write stuff on top of the user stack during
+     context switches, so we cannot possibly safely go up to the very top of
+     stack and test access there.  It is however sufficient to simply check if
+     the top page is accessible, so we target our access halfway up the top
+     page.  Thanks Chris Metcalf for this idea.  */
+  mem = allocate_and_test (stackaddr + pagesize / 2);
+
+  /* Before we celebrate, make sure we actually did test the same page.  */
+  if (((uintptr_t) stackaddr & pagemask) != ((uintptr_t) mem & pagemask))
+    {
+      printf ("We successfully wrote into the wrong page.\n"
+	      "Expected %#" PRIxPTR ", but got %#" PRIxPTR "\n",
+	      (uintptr_t) stackaddr & pagemask, (uintptr_t) mem & pagemask);
+
+      return 1;
+    }
+
+  puts ("Stack top tests done");
+
+  return 0;
+}
+
+/* TODO: Similar check for thread stacks once the thread stack sizes are
+   fixed.  */
+static int
+do_test (void)
+{
+  pagesize = sysconf (_SC_PAGESIZE);
+  return check_stack_top ();
+}
+
+
+#define TEST_FUNCTION do_test ()
+#include "../test-skeleton.c"