Merge "Ensure <fcntl.h> defines the S_* constants from <sys/stat.h>."
authorElliott Hughes <enh@google.com>
Mon, 29 Dec 2014 19:40:44 +0000 (19:40 +0000)
committerGerrit Code Review <noreply-gerritcodereview@google.com>
Mon, 29 Dec 2014 19:40:45 +0000 (19:40 +0000)
28 files changed:
benchmarks/pthread_benchmark.cpp
libc/NOTICE
libc/arch-mips/include/machine/elf_machdep.h
libc/bionic/libc_init_common.cpp
libc/bionic/pthread_create.cpp
libc/bionic/pthread_detach.cpp
libc/bionic/pthread_exit.cpp
libc/bionic/pthread_internal.h
libc/bionic/pthread_internals.cpp
libc/bionic/pthread_join.cpp
libc/bionic/pthread_key.cpp
libc/bionic/stubs.cpp
libc/dns/net/gethnamaddr.c [moved from libc/dns/gethnamaddr.c with 99% similarity]
libc/dns/net/nsdispatch.c
libc/dns/net/sethostent.c
libc/include/sys/cdefs.h
libc/include/sys/cdefs_elf.h [deleted file]
libc/include/sys/stat.h
libc/private/bionic_tls.h
libc/tools/generate-NOTICE.py
libc/upstream-openbsd/android/include/openbsd-compat.h
libc/upstream-openbsd/lib/libc/stdio/vfprintf.c
libc/upstream-openbsd/lib/libc/stdio/vfwprintf.c
libm/NOTICE
libm/freebsd-compat.h
linker/Android.mk
linker/linker.cpp
tests/stdio_test.cpp

index 92e59982f7c9013d3c32af279d6ced0b6f0c6795..42023e04ae84662b623dcf485c883e0bf095d894 100644 (file)
@@ -47,6 +47,21 @@ static void BM_pthread_getspecific(int iters) {
 }
 BENCHMARK(BM_pthread_getspecific);
 
+static void BM_pthread_setspecific(int iters) {
+  StopBenchmarkTiming();
+  pthread_key_t key;
+  pthread_key_create(&key, NULL);
+  StartBenchmarkTiming();
+
+  for (int i = 0; i < iters; ++i) {
+    pthread_setspecific(key, NULL);
+  }
+
+  StopBenchmarkTiming();
+  pthread_key_delete(key);
+}
+BENCHMARK(BM_pthread_setspecific);
+
 static void DummyPthreadOnceInitFunction() {
 }
 
@@ -137,3 +152,80 @@ static void BM_pthread_rw_lock_write(int iters) {
   pthread_rwlock_destroy(&lock);
 }
 BENCHMARK(BM_pthread_rw_lock_write);
+
+static void* IdleThread(void*) {
+  return NULL;
+}
+
+static void BM_pthread_create(int iters) {
+  StopBenchmarkTiming();
+  pthread_t thread;
+
+  for (int i = 0; i < iters; ++i) {
+    StartBenchmarkTiming();
+    pthread_create(&thread, NULL, IdleThread, NULL);
+    StopBenchmarkTiming();
+    pthread_join(thread, NULL);
+  }
+}
+BENCHMARK(BM_pthread_create);
+
+static void* RunThread(void*) {
+  StopBenchmarkTiming();
+  return NULL;
+}
+
+static void BM_pthread_create_and_run(int iters) {
+  StopBenchmarkTiming();
+  pthread_t thread;
+
+  for (int i = 0; i < iters; ++i) {
+    StartBenchmarkTiming();
+    pthread_create(&thread, NULL, RunThread, NULL);
+    pthread_join(thread, NULL);
+  }
+}
+BENCHMARK(BM_pthread_create_and_run);
+
+static void* ExitThread(void*) {
+  StartBenchmarkTiming();
+  pthread_exit(NULL);
+}
+
+static void BM_pthread_exit_and_join(int iters) {
+  StopBenchmarkTiming();
+  pthread_t thread;
+
+  for (int i = 0; i < iters; ++i) {
+    pthread_create(&thread, NULL, ExitThread, NULL);
+    pthread_join(thread, NULL);
+    StopBenchmarkTiming();
+  }
+}
+BENCHMARK(BM_pthread_exit_and_join);
+
+static void BM_pthread_key_create(int iters) {
+  StopBenchmarkTiming();
+  pthread_key_t key;
+
+  for (int i = 0; i < iters; ++i) {
+    StartBenchmarkTiming();
+    pthread_key_create(&key, NULL);
+    StopBenchmarkTiming();
+    pthread_key_delete(key);
+  }
+}
+BENCHMARK(BM_pthread_key_create);
+
+static void BM_pthread_key_delete(int iters) {
+  StopBenchmarkTiming();
+  pthread_key_t key;
+
+  for (int i = 0; i < iters; ++i) {
+    pthread_key_create(&key, NULL);
+    StartBenchmarkTiming();
+    pthread_key_delete(key);
+    StopBenchmarkTiming();
+  }
+}
+BENCHMARK(BM_pthread_key_delete);
index 697b8fc5a69f3a708e83b8bcef566d94a2664ff7..1fa31c2250640d616ee9374ef89285dc1295d316 100644 (file)
@@ -1679,35 +1679,6 @@ SUCH DAMAGE.
 
 -------------------------------------------------------------------
 
-Copyright (c) 1990 Regents of the University of California.
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions
-are met:
-1. Redistributions of source code must retain the above copyright
-   notice, this list of conditions and the following disclaimer.
-2. Redistributions in binary form must reproduce the above copyright
-   notice, this list of conditions and the following disclaimer in the
-   documentation and/or other materials provided with the distribution.
-3. Neither the name of the University nor the names of its contributors
-   may be used to endorse or promote products derived from this software
-   without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
-ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
-FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-SUCH DAMAGE.
-
--------------------------------------------------------------------
-
 Copyright (c) 1990 The Regents of the University of California.
 All rights reserved.
 
@@ -2539,33 +2510,6 @@ SUCH DAMAGE.
 
 -------------------------------------------------------------------
 
-Copyright (c) 1993 Christopher G. Demetriou
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions
-are met:
-1. Redistributions of source code must retain the above copyright
-   notice, this list of conditions and the following disclaimer.
-2. Redistributions in binary form must reproduce the above copyright
-   notice, this list of conditions and the following disclaimer in the
-   documentation and/or other materials provided with the distribution.
-3. The name of the author may not be used to endorse or promote products
-   derived from this software without specific prior written permission
-
-THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
-IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
-OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
-IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
-INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
-NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
-THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
--------------------------------------------------------------------
-
 Copyright (c) 1993 Martin Birgmeier
 All rights reserved.
 
@@ -2685,63 +2629,6 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 
 -------------------------------------------------------------------
 
-Copyright (c) 1996-2004 Per Fogelstrom, Opsycon AB
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions
-are met:
-1. Redistributions of source code must retain the above copyright
-   notice, this list of conditions and the following disclaimer.
-2. Redistributions in binary form must reproduce the above copyright
-   notice, this list of conditions and the following disclaimer in the
-   documentation and/or other materials provided with the distribution.
-
-THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
-OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
-DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-SUCH DAMAGE.
-
--------------------------------------------------------------------
-
-Copyright (c) 1997 Mark Brinicombe
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions
-are met:
-1. Redistributions of source code must retain the above copyright
-   notice, this list of conditions and the following disclaimer.
-2. Redistributions in binary form must reproduce the above copyright
-   notice, this list of conditions and the following disclaimer in the
-   documentation and/or other materials provided with the distribution.
-3. All advertising materials mentioning features or use of this software
-   must display the following acknowledgement:
-   This product includes software developed by Mark Brinicombe
-4. Neither the name of the University nor the names of its contributors
-   may be used to endorse or promote products derived from this software
-   without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
-ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
-FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-SUCH DAMAGE.
-
--------------------------------------------------------------------
-
 Copyright (c) 1997 Mark Brinicombe
 Copyright (c) 2010 Android Open Source Project.
 All rights reserved.
@@ -3365,34 +3252,6 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
 -------------------------------------------------------------------
 
-Copyright (c) 2002 Opsycon AB  (www.opsycon.se / www.opsycon.com)
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions
-are met:
-1. Redistributions of source code must retain the above copyright
-   notice, this list of conditions and the following disclaimer.
-2. Redistributions in binary form must reproduce the above copyright
-   notice, this list of conditions and the following disclaimer in the
-   documentation and/or other materials provided with the distribution.
-3. Neither the name of Opsycon AB nor the names of its contributors
-   may be used to endorse or promote products derived from this software
-   without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
-OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
-DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-SUCH DAMAGE.
-
--------------------------------------------------------------------
-
 Copyright (c) 2002 The NetBSD Foundation, Inc.
 All rights reserved.
 
@@ -4025,6 +3884,22 @@ SUCH DAMAGE.
 
 -------------------------------------------------------------------
 
+Copyright (c) 2008 Otto Moerbeek <otto@drijf.net>
+
+Permission to use, copy, modify, and distribute this software for any
+purpose with or without fee is hereby granted, provided that the above
+copyright notice and this permission notice appear in all copies.
+
+THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+-------------------------------------------------------------------
+
 Copyright (c) 2008 Todd C. Miller <millert@openbsd.org>
 
 Permission to use, copy, modify, and distribute this software for any
@@ -4611,35 +4486,32 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 
 -------------------------------------------------------------------
 
-Copyright (c) 2013, Linaro Limited
-   All rights reserved.
-
-   Redistribution and use in source and binary forms, with or without
-   modification, are permitted provided that the following conditions
-   are met:
-
-      * Redistributions of source code must retain the above copyright
-      notice, this list of conditions and the following disclaimer.
+Copyright (c) 2013 The NetBSD Foundation, Inc.
+All rights reserved.
 
-      * Redistributions in binary form must reproduce the above copyright
-      notice, this list of conditions and the following disclaimer in the
-      documentation and/or other materials provided with the distribution.
+This code is derived from software contributed to The NetBSD Foundation
+by Christos Zoulas.
 
-      * Neither the name of Linaro Limited nor the names of its
-      contributors may be used to endorse or promote products derived
-      from this software without specific prior written permission.
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+1. Redistributions of source code must retain the above copyright
+   notice, this list of conditions and the following disclaimer.
+2. Redistributions in binary form must reproduce the above copyright
+   notice, this list of conditions and the following disclaimer in the
+   documentation and/or other materials provided with the distribution.
 
-   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-   HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
 
 -------------------------------------------------------------------
 
index d27d43183560587f8bf1637e91310ee54bafd0ae..0aacedfe8c52901784ee5ebb274662251e7dcfcf 100644 (file)
 #define        DT_MIPS_GOTSYM          0x70000013      /* first dynamic sym in got */
 #define DT_MIPS_HIPAGENO       0x70000014
 #define        DT_MIPS_RLD_MAP         0x70000016      /* address of loader map */
+#define DT_MIPS_RLD_MAP2       0x70000035      /* offset of loader map, used for PIE */
 
 /*
  * ELF Flags
index 2a6a03b5d688462c520c2adbff3a49d064c2c6dc..15b3fd5e1177e144989cb99ba536451239096bdc 100644 (file)
@@ -74,9 +74,7 @@ uintptr_t __stack_chk_guard = 0;
 void __libc_init_tls(KernelArgumentBlock& args) {
   __libc_auxv = args.auxv;
 
-  static void* tls[BIONIC_TLS_SLOTS];
   static pthread_internal_t main_thread;
-  main_thread.tls = tls;
 
   // Tell the kernel to clear our tid field when we exit, so we're like any other pthread.
   // As a side-effect, this tells us our pid (which is the same as the main thread's tid).
@@ -96,7 +94,7 @@ void __libc_init_tls(KernelArgumentBlock& args) {
   __init_thread(&main_thread, false);
   __init_tls(&main_thread);
   __set_tls(main_thread.tls);
-  tls[TLS_SLOT_BIONIC_PREINIT] = &args;
+  main_thread.tls[TLS_SLOT_BIONIC_PREINIT] = &args;
 
   __init_alternate_signal_stack(&main_thread);
 }
index c99e69c90fcc42ead98099c11542daf190040370..c47b750484537b6a45c370747aa705ff2567e158 100644 (file)
@@ -35,6 +35,7 @@
 #include "pthread_internal.h"
 
 #include "private/bionic_macros.h"
+#include "private/bionic_prctl.h"
 #include "private/bionic_ssp.h"
 #include "private/bionic_tls.h"
 #include "private/libc_logging.h"
@@ -72,6 +73,10 @@ void __init_alternate_signal_stack(pthread_internal_t* thread) {
     ss.ss_flags = 0;
     sigaltstack(&ss, NULL);
     thread->alternate_signal_stack = ss.ss_sp;
+
+    // We can only use const static allocated string for mapped region name, as Android kernel
+    // uses the string pointer directly when dumping /proc/pid/maps.
+    prctl(PR_SET_VMA, PR_SET_VMA_ANON_NAME, ss.ss_sp, ss.ss_size, "thread signal stack");
   }
 }
 
@@ -101,31 +106,64 @@ int __init_thread(pthread_internal_t* thread, bool add_to_thread_list) {
   return error;
 }
 
-static void* __create_thread_stack(pthread_internal_t* thread) {
+static void* __create_thread_stack(const pthread_attr_t& attr) {
   // Create a new private anonymous map.
   int prot = PROT_READ | PROT_WRITE;
   int flags = MAP_PRIVATE | MAP_ANONYMOUS | MAP_NORESERVE;
-  void* stack = mmap(NULL, thread->attr.stack_size, prot, flags, -1, 0);
+  void* stack = mmap(NULL, attr.stack_size, prot, flags, -1, 0);
   if (stack == MAP_FAILED) {
     __libc_format_log(ANDROID_LOG_WARN,
                       "libc",
                       "pthread_create failed: couldn't allocate %zd-byte stack: %s",
-                      thread->attr.stack_size, strerror(errno));
+                      attr.stack_size, strerror(errno));
     return NULL;
   }
 
   // Set the guard region at the end of the stack to PROT_NONE.
-  if (mprotect(stack, thread->attr.guard_size, PROT_NONE) == -1) {
+  if (mprotect(stack, attr.guard_size, PROT_NONE) == -1) {
     __libc_format_log(ANDROID_LOG_WARN, "libc",
                       "pthread_create failed: couldn't mprotect PROT_NONE %zd-byte stack guard region: %s",
-                      thread->attr.guard_size, strerror(errno));
-    munmap(stack, thread->attr.stack_size);
+                      attr.guard_size, strerror(errno));
+    munmap(stack, attr.stack_size);
     return NULL;
   }
 
   return stack;
 }
 
+static int __allocate_thread(pthread_attr_t* attr, pthread_internal_t** threadp, void** child_stack) {
+  if (attr->stack_base == NULL) {
+    // The caller didn't provide a stack, so allocate one.
+    // Make sure the stack size and guard size are multiples of PAGE_SIZE.
+    attr->stack_size = BIONIC_ALIGN(attr->stack_size, PAGE_SIZE);
+    attr->guard_size = BIONIC_ALIGN(attr->guard_size, PAGE_SIZE);
+    attr->stack_base = __create_thread_stack(*attr);
+    if (attr->stack_base == NULL) {
+      return EAGAIN;
+    }
+  } else {
+    // The caller did provide a stack, so remember we're not supposed to free it.
+    attr->flags |= PTHREAD_ATTR_FLAG_USER_ALLOCATED_STACK;
+  }
+
+  // Thread stack is used for two sections:
+  //   pthread_internal_t.
+  //   regular stack, from top to down.
+  uint8_t* stack_top = reinterpret_cast<uint8_t*>(attr->stack_base) + attr->stack_size;
+  stack_top -= sizeof(pthread_internal_t);
+  pthread_internal_t* thread = reinterpret_cast<pthread_internal_t*>(stack_top);
+
+  // No need to check stack_top alignment. The size of pthread_internal_t is 16-bytes aligned,
+  // and user allocated stack is guaranteed by pthread_attr_setstack.
+
+  thread->attr = *attr;
+  __init_tls(thread);
+
+  *threadp = thread;
+  *child_stack = stack_top;
+  return 0;
+}
+
 static int __pthread_start(void* arg) {
   pthread_internal_t* thread = reinterpret_cast<pthread_internal_t*>(arg);
 
@@ -158,43 +196,21 @@ int pthread_create(pthread_t* thread_out, pthread_attr_t const* attr,
   // Inform the rest of the C library that at least one thread was created.
   __isthreaded = 1;
 
-  pthread_internal_t* thread = __create_thread_struct();
-  if (thread == NULL) {
-    return EAGAIN;
-  }
-
+  pthread_attr_t thread_attr;
   if (attr == NULL) {
-    pthread_attr_init(&thread->attr);
+    pthread_attr_init(&thread_attr);
   } else {
-    thread->attr = *attr;
+    thread_attr = *attr;
     attr = NULL; // Prevent misuse below.
   }
 
-  // Make sure the stack size and guard size are multiples of PAGE_SIZE.
-  thread->attr.stack_size = BIONIC_ALIGN(thread->attr.stack_size, PAGE_SIZE);
-  thread->attr.guard_size = BIONIC_ALIGN(thread->attr.guard_size, PAGE_SIZE);
-
-  if (thread->attr.stack_base == NULL) {
-    // The caller didn't provide a stack, so allocate one.
-    thread->attr.stack_base = __create_thread_stack(thread);
-    if (thread->attr.stack_base == NULL) {
-      __free_thread_struct(thread);
-      return EAGAIN;
-    }
-  } else {
-    // The caller did provide a stack, so remember we're not supposed to free it.
-    thread->attr.flags |= PTHREAD_ATTR_FLAG_USER_ALLOCATED_STACK;
+  pthread_internal_t* thread = NULL;
+  void* child_stack = NULL;
+  int result = __allocate_thread(&thread_attr, &thread, &child_stack);
+  if (result != 0) {
+    return result;
   }
 
-  // Make room for the TLS area.
-  // The child stack is the same address, just growing in the opposite direction.
-  // At offsets >= 0, we have the TLS slots.
-  // At offsets < 0, we have the child stack.
-  thread->tls = reinterpret_cast<void**>(reinterpret_cast<uint8_t*>(thread->attr.stack_base) +
-                  thread->attr.stack_size - BIONIC_ALIGN(BIONIC_TLS_SLOTS * sizeof(void*), 16));
-  void* child_stack = thread->tls;
-  __init_tls(thread);
-
   // Create a mutex for the thread in TLS to wait on once it starts so we can keep
   // it from doing anything until after we notify the debugger about it
   //
@@ -211,7 +227,7 @@ int pthread_create(pthread_t* thread_out, pthread_attr_t const* attr,
 
   int flags = CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND | CLONE_THREAD | CLONE_SYSVSEM |
       CLONE_SETTLS | CLONE_PARENT_SETTID | CLONE_CHILD_CLEARTID;
-  void* tls = thread->tls;
+  void* tls = reinterpret_cast<void*>(thread->tls);
 #if defined(__i386__)
   // On x86 (but not x86-64), CLONE_SETTLS takes a pointer to a struct user_desc rather than
   // a pointer to the TLS itself.
@@ -229,7 +245,6 @@ int pthread_create(pthread_t* thread_out, pthread_attr_t const* attr,
     if (!thread->user_allocated_stack()) {
       munmap(thread->attr.stack_base, thread->attr.stack_size);
     }
-    __free_thread_struct(thread);
     __libc_format_log(ANDROID_LOG_WARN, "libc", "pthread_create failed: clone failed: %s", strerror(errno));
     return clone_errno;
   }
index a8608e3a7ad099f36704b25d2f712f6231baf566..715acf13a8b047b9bdc5567fa41a730413dbf4a4 100644 (file)
@@ -46,7 +46,7 @@ int pthread_detach(pthread_t t) {
 
   if (thread->tid == 0) {
     // Already exited; clean up.
-    _pthread_internal_remove_locked(thread.get());
+    _pthread_internal_remove_locked(thread.get(), true);
     return 0;
   }
 
index a6bb36312c075c39959d0284617d247dfe25d542..e04cf8e7f8246682ee406e61117a77a1447d1998 100644 (file)
@@ -90,7 +90,7 @@ void pthread_exit(void* return_value) {
   // Keep track of what we need to know about the stack before we lose the pthread_internal_t.
   void* stack_base = thread->attr.stack_base;
   size_t stack_size = thread->attr.stack_size;
-  bool user_allocated_stack = thread->user_allocated_stack();
+  bool free_stack = false;
 
   pthread_mutex_lock(&g_thread_list_lock);
   if ((thread->attr.flags & PTHREAD_ATTR_FLAG_DETACHED) != 0) {
@@ -98,24 +98,18 @@ void pthread_exit(void* return_value) {
     // First make sure that the kernel does not try to clear the tid field
     // because we'll have freed the memory before the thread actually exits.
     __set_tid_address(NULL);
-    _pthread_internal_remove_locked(thread);
-  } else {
-    // Make sure that the pthread_internal_t doesn't have stale pointers to a stack that
-    // will be unmapped after the exit call below.
-    if (!user_allocated_stack) {
-      thread->attr.stack_base = NULL;
-      thread->attr.stack_size = 0;
-      thread->tls = NULL;
+
+    // pthread_internal_t is freed below with stack, not here.
+    _pthread_internal_remove_locked(thread, false);
+    if (!thread->user_allocated_stack()) {
+      free_stack = true;
     }
-    // pthread_join is responsible for destroying the pthread_internal_t for non-detached threads.
-    // The kernel will futex_wake on the pthread_internal_t::tid field to wake pthread_join.
   }
   pthread_mutex_unlock(&g_thread_list_lock);
 
-  if (user_allocated_stack) {
-    // Cleaning up this thread's stack is the creator's responsibility, not ours.
-    __exit(0);
-  } else {
+  // Detached threads exit with stack teardown, and everything deallocated here.
+  // Threads that can be joined exit but leave their stacks for the pthread_join caller to clean up.
+  if (free_stack) {
     // We need to munmap the stack we're running on before calling exit.
     // That's not something we can do in C.
 
@@ -126,5 +120,7 @@ void pthread_exit(void* return_value) {
     sigprocmask(SIG_SETMASK, &mask, NULL);
 
     _exit_with_stack_teardown(stack_base, stack_size);
+  } else {
+    __exit(0);
   }
 }
index c5136c93cbfff8fb58f2e773c9d10d7ac8a4e510..95097b7ea0b54f7ef89bdd3b697513fec9615bdf 100644 (file)
@@ -30,6 +30,8 @@
 
 #include <pthread.h>
 
+#include "private/bionic_tls.h"
+
 /* Has the thread been detached by a pthread_join or pthread_detach call? */
 #define PTHREAD_ATTR_FLAG_DETACHED 0x00000001
 
@@ -72,8 +74,6 @@ struct pthread_internal_t {
     return (attr.flags & PTHREAD_ATTR_FLAG_USER_ALLOCATED_STACK) != 0;
   }
 
-  void** tls;
-
   pthread_attr_t attr;
 
   __pthread_cleanup_t* cleanup_stack;
@@ -86,16 +86,16 @@ struct pthread_internal_t {
 
   pthread_mutex_t startup_handshake_mutex;
 
+  void* tls[BIONIC_TLS_SLOTS];
+
   /*
    * The dynamic linker implements dlerror(3), which makes it hard for us to implement this
    * per-thread buffer by simply using malloc(3) and free(3).
    */
 #define __BIONIC_DLERROR_BUFFER_SIZE 512
   char dlerror_buffer[__BIONIC_DLERROR_BUFFER_SIZE];
-};
+} __attribute__((aligned(16))); // Align it as thread stack top below it should be aligned.
 
-__LIBC_HIDDEN__ pthread_internal_t* __create_thread_struct();
-__LIBC_HIDDEN__ void __free_thread_struct(pthread_internal_t*);
 __LIBC_HIDDEN__ int __init_thread(pthread_internal_t* thread, bool add_to_thread_list);
 __LIBC_HIDDEN__ void __init_tls(pthread_internal_t* thread);
 __LIBC_HIDDEN__ void __init_alternate_signal_stack(pthread_internal_t*);
@@ -105,7 +105,7 @@ __LIBC_HIDDEN__ void _pthread_internal_add(pthread_internal_t* thread);
 extern "C" __LIBC64_HIDDEN__ pthread_internal_t* __get_thread(void);
 
 __LIBC_HIDDEN__ void pthread_key_clean_all(void);
-__LIBC_HIDDEN__ void _pthread_internal_remove_locked(pthread_internal_t* thread);
+__LIBC_HIDDEN__ void _pthread_internal_remove_locked(pthread_internal_t* thread, bool free_thread);
 
 /*
  * Traditionally we gave threads a 1MiB stack. When we started
index 33cddd74e771683f587a9398275b234e60ee0449..7c30e6e4ad413e667bf7382e66823d4f9f33d850 100644 (file)
 pthread_internal_t* g_thread_list = NULL;
 pthread_mutex_t g_thread_list_lock = PTHREAD_MUTEX_INITIALIZER;
 
-pthread_internal_t* __create_thread_struct() {
-  void* result = mmap(NULL, sizeof(pthread_internal_t), PROT_READ | PROT_WRITE,
-                      MAP_PRIVATE | MAP_ANONYMOUS | MAP_NORESERVE, -1, 0);
-  if (result == MAP_FAILED) {
-    __libc_format_log(ANDROID_LOG_WARN, "libc",
-                      "__create_thread_struct() failed: %s", strerror(errno));
-    return NULL;
-  }
-  return reinterpret_cast<pthread_internal_t*>(result);
-}
-
-void __free_thread_struct(pthread_internal_t* thread) {
-  int result = munmap(thread, sizeof(pthread_internal_t));
-  if (result != 0) {
-    __libc_format_log(ANDROID_LOG_WARN, "libc",
-                      "__free_thread_struct() failed: %s", strerror(errno));
-  }
-}
-
-void _pthread_internal_remove_locked(pthread_internal_t* thread) {
+void _pthread_internal_remove_locked(pthread_internal_t* thread, bool free_thread) {
   if (thread->next != NULL) {
     thread->next->prev = thread->prev;
   }
@@ -70,10 +51,11 @@ void _pthread_internal_remove_locked(pthread_internal_t* thread) {
     g_thread_list = thread->next;
   }
 
-  // The main thread is not heap-allocated. See __libc_init_tls for the declaration,
-  // and __libc_init_common for the point where it's added to the thread list.
-  if ((thread->attr.flags & PTHREAD_ATTR_FLAG_MAIN_THREAD) == 0) {
-    __free_thread_struct(thread);
+  // For threads using user allocated stack (including the main thread), the pthread_internal_t
+  // can't be freed since it is on the stack.
+  if (free_thread && !(thread->attr.flags & PTHREAD_ATTR_FLAG_USER_ALLOCATED_STACK)) {
+    // Use one munmap to free the whole thread stack, including pthread_internal_t.
+    munmap(thread->attr.stack_base, thread->attr.stack_size);
   }
 }
 
index 0cbed62bad51f3ada3f6bb5e047ad929c1e8f6db..e3350efd35169b8efbd3523bf72323d0a41c0928 100644 (file)
@@ -74,6 +74,6 @@ int pthread_join(pthread_t t, void** return_value) {
     *return_value = thread->return_value;
   }
 
-  _pthread_internal_remove_locked(thread.get());
+  _pthread_internal_remove_locked(thread.get(), true);
   return 0;
 }
index b47ef229d8c009d6fcec466894109d807d8379dd..49b72e9deaec6fb268a9e13f62e8ea92cc3824e7 100644 (file)
@@ -213,16 +213,6 @@ int pthread_key_delete(pthread_key_t key) {
   // Clear value in all threads.
   pthread_mutex_lock(&g_thread_list_lock);
   for (pthread_internal_t*  t = g_thread_list; t != NULL; t = t->next) {
-    // Skip zombie threads. They don't have a valid TLS area any more.
-    // Similarly, it is possible to have t->tls == NULL for threads that
-    // were just recently created through pthread_create() but whose
-    // startup trampoline (__pthread_start) hasn't been run yet by the
-    // scheduler. t->tls will also be NULL after a thread's stack has been
-    // unmapped but before the ongoing pthread_join() is finished.
-    if (t->tid == 0 || t->tls == NULL) {
-      continue;
-    }
-
     t->tls[key] = NULL;
   }
   tls_map.DeleteKey(key);
index 88e5ac5ed50e6b1113755cb20a97d3fea3fb7c50..ab6793556189b75f6b1ac6dada0ff4795536c8fc 100644 (file)
 #include "private/libc_logging.h"
 #include "private/ThreadLocalBuffer.h"
 
-GLOBAL_INIT_THREAD_LOCAL_BUFFER(stubs);
+// POSIX seems to envisage an implementation where the <pwd.h> functions are
+// implemented by brute-force searching with getpwent(3), and the <grp.h>
+// functions are implemented similarly with getgrent(3). This means that it's
+// okay for all the <grp.h> functions to share state, and all the <passwd.h>
+// functions to share state, but <grp.h> functions can't clobber <passwd.h>
+// functions' state and vice versa.
 
-struct stubs_state_t {
-  passwd passwd_;
+GLOBAL_INIT_THREAD_LOCAL_BUFFER(group);
+
+struct group_state_t {
   group group_;
   char* group_members_[2];
-  char app_name_buffer_[32];
   char group_name_buffer_[32];
+};
+
+static group_state_t* __group_state() {
+  LOCAL_INIT_THREAD_LOCAL_BUFFER(group_state_t*, group, sizeof(group_state_t));
+  if (group_tls_buffer != NULL) {
+    memset(group_tls_buffer, 0, sizeof(group_state_t));
+    group_tls_buffer->group_.gr_mem = group_tls_buffer->group_members_;
+  }
+  return group_tls_buffer;
+}
+
+GLOBAL_INIT_THREAD_LOCAL_BUFFER(passwd);
+
+struct passwd_state_t {
+  passwd passwd_;
+  char app_name_buffer_[32];
   char dir_buffer_[32];
   char sh_buffer_[32];
 };
 
+static passwd_state_t* __passwd_state() {
+  LOCAL_INIT_THREAD_LOCAL_BUFFER(passwd_state_t*, passwd, sizeof(passwd_state_t));
+  return passwd_tls_buffer;
+}
+
 static int do_getpw_r(int by_name, const char* name, uid_t uid,
                       passwd* dst, char* buf, size_t byte_count,
                       passwd** result) {
@@ -91,7 +117,7 @@ static int do_getpw_r(int by_name, const char* name, uid_t uid,
 
   // pw_passwd and pw_gecos are non-POSIX and unused (always NULL) in bionic.
   dst->pw_passwd = NULL;
-#ifdef __LP64__
+#if defined(__LP64__)
   dst->pw_gecos = NULL;
 #endif
 
@@ -113,17 +139,7 @@ int getpwuid_r(uid_t uid, passwd* pwd,
   return do_getpw_r(0, NULL, uid, pwd, buf, byte_count, result);
 }
 
-static stubs_state_t* __stubs_state() {
-  LOCAL_INIT_THREAD_LOCAL_BUFFER(stubs_state_t*, stubs, sizeof(stubs_state_t));
-
-  if (stubs_tls_buffer != NULL) {
-    memset(stubs_tls_buffer, 0, sizeof(stubs_state_t));
-    stubs_tls_buffer->group_.gr_mem = stubs_tls_buffer->group_members_;
-  }
-  return stubs_tls_buffer;
-}
-
-static passwd* android_iinfo_to_passwd(stubs_state_t* state,
+static passwd* android_iinfo_to_passwd(passwd_state_t* state,
                                        const android_id_info* iinfo) {
   snprintf(state->dir_buffer_, sizeof(state->dir_buffer_), "/");
   snprintf(state->sh_buffer_, sizeof(state->sh_buffer_), "/system/bin/sh");
@@ -145,7 +161,7 @@ static group* android_iinfo_to_group(group* gr,
   return gr;
 }
 
-static passwd* android_id_to_passwd(stubs_state_t* state, unsigned id) {
+static passwd* android_id_to_passwd(passwd_state_t* state, unsigned id) {
   for (size_t n = 0; n < android_id_count; ++n) {
     if (android_ids[n].aid == id) {
       return android_iinfo_to_passwd(state, android_ids + n);
@@ -154,7 +170,7 @@ static passwd* android_id_to_passwd(stubs_state_t* state, unsigned id) {
   return NULL;
 }
 
-static passwd* android_name_to_passwd(stubs_state_t* state, const char* name) {
+static passwd* android_name_to_passwd(passwd_state_t* state, const char* name) {
   for (size_t n = 0; n < android_id_count; ++n) {
     if (!strcmp(android_ids[n].name, name)) {
       return android_iinfo_to_passwd(state, android_ids + n);
@@ -297,9 +313,7 @@ static void print_app_name_from_gid(const gid_t gid, char* buffer, const int buf
 // AID_ISOLATED_START to AID_USER-1 -> u0_i1234
 // AID_USER+                        -> u1_radio, u1_a1234, u2_i1234, etc.
 // returns a passwd structure (sets errno to ENOENT on failure).
-static passwd* app_id_to_passwd(uid_t uid, stubs_state_t* state) {
-  passwd* pw = &state->passwd_;
-
+static passwd* app_id_to_passwd(uid_t uid, passwd_state_t* state) {
   if (uid < AID_APP) {
     errno = ENOENT;
     return NULL;
@@ -316,18 +330,18 @@ static passwd* app_id_to_passwd(uid_t uid, stubs_state_t* state) {
 
   snprintf(state->sh_buffer_, sizeof(state->sh_buffer_), "/system/bin/sh");
 
+  passwd* pw = &state->passwd_;
   pw->pw_name  = state->app_name_buffer_;
   pw->pw_dir   = state->dir_buffer_;
   pw->pw_shell = state->sh_buffer_;
   pw->pw_uid   = uid;
   pw->pw_gid   = uid;
-
   return pw;
 }
 
 // Translate a gid into the corresponding app_<gid>
 // group structure (sets errno to ENOENT on failure).
-static group* app_id_to_group(gid_t gid, stubs_state_t* state) {
+static group* app_id_to_group(gid_t gid, group_state_t* state) {
   if (gid < AID_APP) {
     errno = ENOENT;
     return NULL;
@@ -339,13 +353,11 @@ static group* app_id_to_group(gid_t gid, stubs_state_t* state) {
   gr->gr_name   = state->group_name_buffer_;
   gr->gr_gid    = gid;
   gr->gr_mem[0] = gr->gr_name;
-
   return gr;
 }
 
-
 passwd* getpwuid(uid_t uid) { // NOLINT: implementing bad function.
-  stubs_state_t* state = __stubs_state();
+  passwd_state_t* state = __passwd_state();
   if (state == NULL) {
     return NULL;
   }
@@ -358,7 +370,7 @@ passwd* getpwuid(uid_t uid) { // NOLINT: implementing bad function.
 }
 
 passwd* getpwnam(const char* login) { // NOLINT: implementing bad function.
-  stubs_state_t* state = __stubs_state();
+  passwd_state_t* state = __passwd_state();
   if (state == NULL) {
     return NULL;
   }
@@ -372,12 +384,12 @@ passwd* getpwnam(const char* login) { // NOLINT: implementing bad function.
 
 // All users are in just one group, the one passed in.
 int getgrouplist(const char* /*user*/, gid_t group, gid_t* groups, int* ngroups) {
-    if (*ngroups < 1) {
-        *ngroups = 1;
-        return -1;
-    }
-    groups[0] = group;
-    return (*ngroups = 1);
+  if (*ngroups < 1) {
+    *ngroups = 1;
+    return -1;
+  }
+  groups[0] = group;
+  return (*ngroups = 1);
 }
 
 char* getlogin() { // NOLINT: implementing bad function.
@@ -386,7 +398,7 @@ char* getlogin() { // NOLINT: implementing bad function.
 }
 
 group* getgrgid(gid_t gid) { // NOLINT: implementing bad function.
-  stubs_state_t* state = __stubs_state();
+  group_state_t* state = __group_state();
   if (state == NULL) {
     return NULL;
   }
@@ -399,7 +411,7 @@ group* getgrgid(gid_t gid) { // NOLINT: implementing bad function.
 }
 
 group* getgrnam(const char* name) { // NOLINT: implementing bad function.
-  stubs_state_t* state = __stubs_state();
+  group_state_t* state = __group_state();
   if (state == NULL) {
     return NULL;
   }
similarity index 99%
rename from libc/dns/gethnamaddr.c
rename to libc/dns/net/gethnamaddr.c
index 63a6a60d3e218f4f7d6bbe1ba5cac7cd6844a302..8f5800a434460f70a0d14965eb6b371c16613eb9 100644 (file)
@@ -1208,7 +1208,7 @@ _dns_gethtbyname(void *rv, void *cb_data, va_list ap)
        free(buf);
        __res_put_state(res);
        if (hp == NULL)
-               switch (h_errno) {
+               switch (*info->he) {
                case HOST_NOT_FOUND:
                        return NS_NOTFOUND;
                case TRY_AGAIN:
@@ -1326,6 +1326,7 @@ _dns_gethtbyaddr(void *rv, void   *cb_data, va_list ap)
        *info->he = NETDB_SUCCESS;
        return NS_SUCCESS;
 nospc:
+       errno = ENOSPC;
        *info->he = NETDB_INTERNAL;
        return NS_UNAVAIL;
 }
index fb6d8f6ab0ee4949d405e7dd87e90b5f09c360cd..d025592a0473a101d9b05e929d91f64dba83e497 100644 (file)
@@ -71,6 +71,7 @@
 #include <sys/cdefs.h>
 
 #include <assert.h>
+#include <errno.h>
 #include <nsswitch.h>
 #include <stdarg.h>
 #include <strings.h>
@@ -133,6 +134,10 @@ nsdispatch(void *retval, const ns_dtab disp_tab[], const char *database,
                                continue;
                        if (result & srclist[i].flags)
                                break;
+                       /* Stop trying next resolver when there is a memory space fatal error. */
+                       if ((result & NS_UNAVAIL) != 0 && errno == ENOSPC) {
+                         break;
+                       }
                }
        }
        result &= NS_STATUSMASK;        /* clear private flags in result */
index f501c8b5abc1f6e77f12f079df10bf1722bcf66a..916421e3329e2220ff86436e2e4de30043d0ad5a 100644 (file)
@@ -116,7 +116,9 @@ _hf_gethtbyname(void *rv, void *cb_data, va_list ap)
        hp = _hf_gethtbyname2(name, af, info);
 #endif
        if (hp == NULL) {
-               *info->he = HOST_NOT_FOUND;
+               if (*info->he == NETDB_INTERNAL && errno == ENOSPC) {
+                       return NS_UNAVAIL;
+               }
                return NS_NOTFOUND;
        }
        return NS_SUCCESS;
@@ -159,8 +161,12 @@ _hf_gethtbyname2(const char *name, int af, struct getnamaddr *info)
 
                hp = netbsd_gethostent_r(hf, info->hp, info->buf, info->buflen,
                    info->he);
-               if (hp == NULL)
+               if (hp == NULL) {
+                       if (*info->he == NETDB_INTERNAL && errno == ENOSPC) {
+                               goto nospc;
+                       }
                        break;
+               }
 
                if (strcasecmp(hp->h_name, name) != 0) {
                        char **cp;
@@ -259,6 +265,9 @@ _hf_gethtbyaddr(void *rv, void *cb_data, va_list ap)
        endhostent_r(&hf);
 
        if (hp == NULL) {
+               if (errno == ENOSPC) {
+                       return NS_UNAVAIL;
+               }
                *info->he = HOST_NOT_FOUND;
                return NS_NOTFOUND;
        }
index 6f238a93d728d313eb1a632925f1a1e10a0b40c7..21d59fa57a87789eab19625a28eac5ab90390b8c 100644 (file)
@@ -77,7 +77,9 @@
 #define        __GNUC_PREREQ(x, y)     0
 #endif
 
-#include <sys/cdefs_elf.h>
+#define __strong_alias(alias, sym) \
+    __asm__(".global " #alias "\n" \
+            #alias " = " #sym);
 
 #if defined(__cplusplus)
 #define        __BEGIN_DECLS           extern "C" {
 #endif
 #endif /* !(__STDC_VERSION__ >= 199901L) */
 
-#if defined(_KERNEL)
-#if defined(NO_KERNEL_RCSIDS)
-#undef __KERNEL_RCSID
-#define        __KERNEL_RCSID(_n, _s)          /* nothing */
-#endif /* NO_KERNEL_RCSIDS */
-#endif /* _KERNEL */
-
 /*
  * A barrier to stop the optimizer from moving code or assume live
  * register values. This is gcc specific, the version is more or less
diff --git a/libc/include/sys/cdefs_elf.h b/libc/include/sys/cdefs_elf.h
deleted file mode 100644 (file)
index a40a867..0000000
+++ /dev/null
@@ -1,43 +0,0 @@
-/*     $NetBSD: cdefs_elf.h,v 1.22 2005/02/26 22:25:34 perry Exp $     */
-
-/*
- * Copyright (c) 1995, 1996 Carnegie-Mellon University.
- * All rights reserved.
- *
- * Author: Chris G. Demetriou
- *
- * Permission to use, copy, modify and distribute this software and
- * its documentation is hereby granted, provided that both the copyright
- * notice and this permission notice appear in all copies of the
- * software, derivative works or modified versions, and any portions
- * thereof, and that both notices appear in supporting documentation.
- *
- * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
- * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND
- * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
- *
- * Carnegie Mellon requests users of this software to return to
- *
- *  Software Distribution Coordinator  or  Software.Distribution@CS.CMU.EDU
- *  School of Computer Science
- *  Carnegie Mellon University
- *  Pittsburgh PA 15213-3890
- *
- * any improvements or extensions that they make and grant Carnegie the
- * rights to redistribute these changes.
- */
-
-#ifndef _SYS_CDEFS_ELF_H_
-#define        _SYS_CDEFS_ELF_H_
-
-#define __strong_alias(alias, sym) \
-    __asm__(".global " #alias "\n" \
-            #alias " = " #sym);
-
-/* We use __warnattr instead of __warn_references.
- * TODO: remove this and put an empty definition in one of the upstream-* compatibility headers.
- */
-#define        __warn_references(sym,msg)                                      \
-    /*__asm__(".section .gnu.warning." #sym "\n\t.ascii \"" msg "\"\n\t.text");*/
-
-#endif /* !_SYS_CDEFS_ELF_H_ */
index 5c82a5b24885d2a5539003db04f9c17c3a9e69f4..7017865bd477b17ec8971d7373c6faa10e7ab7ca 100644 (file)
@@ -29,7 +29,6 @@
 #ifndef _SYS_STAT_H_
 #define _SYS_STAT_H_
 
-#include <endian.h>
 #include <linux/stat.h>
 #include <machine/timespec.h>
 #include <sys/cdefs.h>
@@ -39,15 +38,15 @@ __BEGIN_DECLS
 
 #if defined(__aarch64__)
 #define __STAT64_BODY \
-  unsigned long st_dev; \
-  unsigned long st_ino; \
-  unsigned int st_mode; \
-  unsigned int st_nlink; \
+  dev_t st_dev; \
+  ino_t st_ino; \
+  mode_t st_mode; \
+  nlink_t st_nlink; \
   uid_t st_uid; \
   gid_t st_gid; \
-  unsigned long st_rdev; \
+  dev_t st_rdev; \
   unsigned long __pad1; \
-  long st_size; \
+  off_t st_size; \
   int st_blksize; \
   int __pad2; \
   long st_blocks; \
@@ -57,13 +56,13 @@ __BEGIN_DECLS
   unsigned int __unused4; \
   unsigned int __unused5; \
 
-#elif defined(__mips__)
+#elif defined(__mips__) /* and mips64 */
 #define __STAT64_BODY \
   unsigned int st_dev; \
   unsigned int __pad0[3]; \
   unsigned long long st_ino; \
-  unsigned int st_mode; \
-  unsigned int st_nlink; \
+  mode_t st_mode; \
+  nlink_t st_nlink; \
   uid_t st_uid; \
   gid_t st_gid; \
   unsigned int st_rdev; \
@@ -94,13 +93,13 @@ __BEGIN_DECLS
   struct timespec st_ctim; \
   long __pad3[3]; \
 
-#else
+#else /* __arm__ || __i386__ */
 #define __STAT64_BODY \
   unsigned long long st_dev; \
   unsigned char __pad0[4]; \
   unsigned long __st_ino; \
   unsigned int st_mode; \
-  unsigned int st_nlink; \
+  nlink_t st_nlink; \
   uid_t st_uid; \
   gid_t st_gid; \
   unsigned long long st_rdev; \
index 4a3516683f116f91d439d57518d73481145e8bfe..944f957900920f8e9c0d8167429c50816dff344d 100644 (file)
@@ -85,7 +85,8 @@ enum {
  *  ttyname                libc (GLOBAL_INIT_THREAD_LOCAL_BUFFER)
  *  strerror               libc (GLOBAL_INIT_THREAD_LOCAL_BUFFER)
  *  strsignal              libc (GLOBAL_INIT_THREAD_LOCAL_BUFFER)
- *  stubs                  libc (GLOBAL_INIT_THREAD_LOCAL_BUFFER)
+ *  passwd                 libc (GLOBAL_INIT_THREAD_LOCAL_BUFFER)
+ *  group                  libc (GLOBAL_INIT_THREAD_LOCAL_BUFFER)
  *  _res_key               libc
  * je_thread_allocated_tsd jemalloc
  * je_arenas_tsd           jemalloc
@@ -95,7 +96,7 @@ enum {
  *
  */
 
-#define LIBC_TLS_RESERVED_SLOTS 11
+#define LIBC_TLS_RESERVED_SLOTS 12
 
 #if defined(USE_JEMALLOC)
 /* jemalloc uses 5 keys for itself. */
index 3edc29963f8ec95f2f8d870b3da7ca25a5021ddc..79b4ea97e97b76202583e57f571e84c4bf825170 100755 (executable)
@@ -1,7 +1,7 @@
 #!/usr/bin/python
 # Run with directory arguments from any directory, with no special setup required.
 # Or:
-# for i in libc libdl libm linker libstdc++ libthread_db ; do ./libc/tools/generate-NOTICE.py $i > $i/NOTICE ; done
+# for i in libc libdl libm linker libstdc++ ; do ./libc/tools/generate-NOTICE.py $i > $i/NOTICE ; done
 
 import ftplib
 import hashlib
index 8386ba5fcb8401f162991fee669e9cab7e179f72..8783467c11ea68466507ed3a4aa8f3375ec823b3 100644 (file)
@@ -35,6 +35,9 @@
 /* Ignore all __weak_alias in OpenBSD. */
 #define __weak_alias(alias,sym)
 
+/* Ignore all __warn_references in OpenBSD. */
+#define __warn_references(sym,msg)
+
 /* OpenBSD's <ctype.h> uses these names, which conflicted with stlport.
  * Additionally, we changed the numeric/digit type from N to D for libcxx.
  */
index 7f8ff31779477f1df85395262bc0c19b2d9e8423..5f4fb7fa9bb561d578a0618cbd526ba407b0a93f 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: vfprintf.c,v 1.66 2014/05/03 12:36:45 deraadt Exp $   */
+/*     $OpenBSD: vfprintf.c,v 1.67 2014/12/21 00:23:30 daniel Exp $    */
 /*-
  * Copyright (c) 1990 The Regents of the University of California.
  * All rights reserved.
@@ -753,10 +753,9 @@ fp_common:
                        if (signflag)
                                sign = '-';
                        if (expt == INT_MAX) {  /* inf or nan */
-                               if (*cp == 'N') {
+                               if (*cp == 'N')
                                        cp = (ch >= 'a') ? "nan" : "NAN";
-                                       sign = '\0';
-                               } else
+                               else
                                        cp = (ch >= 'a') ? "inf" : "INF";
                                size = 3;
                                flags &= ~ZEROPAD;
index ef0ca43b91ff7389a76596830ce0abed897aee88..a6f41232c53bbc9059ef1df1c409d60d18d44122 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: vfwprintf.c,v 1.11 2014/06/04 07:45:25 stsp Exp $ */
+/*     $OpenBSD: vfwprintf.c,v 1.12 2014/12/21 00:23:30 daniel Exp $ */
 /*-
  * Copyright (c) 1990 The Regents of the University of California.
  * All rights reserved.
@@ -731,10 +731,9 @@ fp_common:
                        if (signflag)
                                sign = '-';
                        if (expt == INT_MAX) {  /* inf or nan */
-                               if (*cp == 'N') {
+                               if (*cp == 'N')
                                        cp = (ch >= 'a') ? L"nan" : L"NAN";
-                                       sign = '\0';
-                               } else
+                               else
                                        cp = (ch >= 'a') ? L"inf" : L"INF";
                                size = 3;
                                flags &= ~ZEROPAD;
index 5be60dbf4b0ef439d91811446360960815cc0845..70f2f460152c4efd7112ce052cc0edb28d866471 100644 (file)
@@ -549,32 +549,6 @@ SUCH DAMAGE.
 
 -------------------------------------------------------------------
 
-Copyright (c) 2004-2011 David Schultz <das@FreeBSD.ORG>
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions
-are met:
-1. Redistributions of source code must retain the above copyright
-   notice, this list of conditions and the following disclaimer.
-2. Redistributions in binary form must reproduce the above copyright
-   notice, this list of conditions and the following disclaimer in the
-   documentation and/or other materials provided with the distribution.
-
-THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
-ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
-FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-SUCH DAMAGE.
-
--------------------------------------------------------------------
-
 Copyright (c) 2005 Bruce D. Evans and Steven G. Kargl
 All rights reserved.
 
@@ -976,6 +950,32 @@ SUCH DAMAGE.
 
 -------------------------------------------------------------------
 
+Copyright (c) 2012 Stephen Montgomery-Smith <stephen@FreeBSD.ORG>
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+1. Redistributions of source code must retain the above copyright
+   notice, this list of conditions and the following disclaimer.
+2. Redistributions in binary form must reproduce the above copyright
+   notice, this list of conditions and the following disclaimer in the
+   documentation and/or other materials provided with the distribution.
+
+THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGE.
+
+-------------------------------------------------------------------
+
 Copyright (c) 2013 David Chisnall
 All rights reserved.
 
index 1481cc224ef67175d310884d9b1c6251b5c0916f..a4dd6c2c771f06e6b09847d39b6dbf416eea7e85 100644 (file)
@@ -26,6 +26,8 @@
 #define __strong_reference(sym,aliassym) \
     extern __typeof (sym) aliassym __attribute__ ((__alias__ (#sym)))
 
+#define __warn_references(sym,msg) /* ignored */
+
 /* digittoint is in BSD's <ctype.h>. */
 int digittoint(char ch);
 
index d6e0095757d0df30255b8f9f86d9984e0d3d261f..0383e7b7e395213e311109a107d4abeee0761d81 100644 (file)
@@ -19,6 +19,13 @@ LOCAL_SRC_FILES_x86_64  := arch/x86_64/begin.S
 LOCAL_SRC_FILES_mips    := arch/mips/begin.S
 LOCAL_SRC_FILES_mips64  := arch/mips64/begin.S
 
+# GNU assembler aborted with clang's output for linker.cpp:
+# Assertion failure in get_line_subseg at
+#   /s/ndk-toolchain/src/build/../binutils/binutils-2.24/gas/dwarf2dbg.c line 271.
+ifeq ($(TARGET_ARCH),mips)
+    LOCAL_CLANG_CFLAGS += -integrated-as
+endif
+
 LOCAL_LDFLAGS := \
     -shared \
     -Wl,-Bsymbolic \
index 34099316fe163eda504e9cd52cb7581012bcdb6c..babefeb3c1fb259fd27da4abec33f913e96b29ea 100644 (file)
@@ -2402,6 +2402,13 @@ bool soinfo::prelink_image() {
           *dp = &_r_debug;
         }
         break;
+      case DT_MIPS_RLD_MAP2:
+        // Set the DT_MIPS_RLD_MAP2 entry to the address of _r_debug for GDB.
+        {
+          r_debug** dp = reinterpret_cast<r_debug**>(reinterpret_cast<ElfW(Addr)>(d) + d->d_un.d_val);
+          *dp = &_r_debug;
+        }
+        break;
 
       case DT_MIPS_RLD_VERSION:
       case DT_MIPS_FLAGS:
index 854fc7b7b1703765de829c0449c2a1d848b21fb6..de5eea347f4251aae68044ef01307ea2782375ed 100644 (file)
@@ -364,22 +364,52 @@ TEST(stdio, snprintf_smoke) {
   EXPECT_STREQ("print_me_twice print_me_twice", buf);
 }
 
-TEST(stdio, snprintf_f_special) {
-  char buf[BUFSIZ];
-  snprintf(buf, sizeof(buf), "%f", nanf(""));
-  EXPECT_STRCASEEQ("NaN", buf);
-
-  snprintf(buf, sizeof(buf), "%f", HUGE_VALF);
-  EXPECT_STRCASEEQ("Inf", buf);
-}
-
-TEST(stdio, snprintf_g_special) {
-  char buf[BUFSIZ];
-  snprintf(buf, sizeof(buf), "%g", nan(""));
-  EXPECT_STRCASEEQ("NaN", buf);
-
-  snprintf(buf, sizeof(buf), "%g", HUGE_VAL);
-  EXPECT_STRCASEEQ("Inf", buf);
+template <typename T>
+void CheckInfNan(int snprintf_fn(T*, size_t, const T*, ...),
+                 const T* fmt, const T* fmt_plus,
+                 const T* minus_inf, const T* inf_, const T* plus_inf,
+                 const T* minus_nan, const T* nan_, const T* plus_nan) {
+  T buf[BUFSIZ];
+
+  snprintf_fn(buf, sizeof(buf), fmt, nan(""));
+  EXPECT_STREQ(nan_, buf) << fmt;
+  snprintf_fn(buf, sizeof(buf), fmt, -nan(""));
+  EXPECT_STREQ(minus_nan, buf) << fmt;
+  snprintf_fn(buf, sizeof(buf), fmt_plus, nan(""));
+  EXPECT_STREQ(plus_nan, buf) << fmt_plus;
+  snprintf_fn(buf, sizeof(buf), fmt_plus, -nan(""));
+  EXPECT_STREQ(minus_nan, buf) << fmt_plus;
+
+  snprintf_fn(buf, sizeof(buf), fmt, HUGE_VAL);
+  EXPECT_STREQ(inf_, buf) << fmt;
+  snprintf_fn(buf, sizeof(buf), fmt, -HUGE_VAL);
+  EXPECT_STREQ(minus_inf, buf) << fmt;
+  snprintf_fn(buf, sizeof(buf), fmt_plus, HUGE_VAL);
+  EXPECT_STREQ(plus_inf, buf) << fmt_plus;
+  snprintf_fn(buf, sizeof(buf), fmt_plus, -HUGE_VAL);
+  EXPECT_STREQ(minus_inf, buf) << fmt_plus;
+}
+
+TEST(stdio, snprintf_inf_nan) {
+  CheckInfNan(snprintf, "%a", "%+a", "-inf", "inf", "+inf", "-nan", "nan", "+nan");
+  CheckInfNan(snprintf, "%A", "%+A", "-INF", "INF", "+INF", "-NAN", "NAN", "+NAN");
+  CheckInfNan(snprintf, "%e", "%+e", "-inf", "inf", "+inf", "-nan", "nan", "+nan");
+  CheckInfNan(snprintf, "%E", "%+E", "-INF", "INF", "+INF", "-NAN", "NAN", "+NAN");
+  CheckInfNan(snprintf, "%f", "%+f", "-inf", "inf", "+inf", "-nan", "nan", "+nan");
+  CheckInfNan(snprintf, "%F", "%+F", "-INF", "INF", "+INF", "-NAN", "NAN", "+NAN");
+  CheckInfNan(snprintf, "%g", "%+g", "-inf", "inf", "+inf", "-nan", "nan", "+nan");
+  CheckInfNan(snprintf, "%G", "%+G", "-INF", "INF", "+INF", "-NAN", "NAN", "+NAN");
+}
+
+TEST(stdio, wsprintf_inf_nan) {
+  CheckInfNan(swprintf, L"%a", L"%+a", L"-inf", L"inf", L"+inf", L"-nan", L"nan", L"+nan");
+  CheckInfNan(swprintf, L"%A", L"%+A", L"-INF", L"INF", L"+INF", L"-NAN", L"NAN", L"+NAN");
+  CheckInfNan(swprintf, L"%e", L"%+e", L"-inf", L"inf", L"+inf", L"-nan", L"nan", L"+nan");
+  CheckInfNan(swprintf, L"%E", L"%+E", L"-INF", L"INF", L"+INF", L"-NAN", L"NAN", L"+NAN");
+  CheckInfNan(swprintf, L"%f", L"%+f", L"-inf", L"inf", L"+inf", L"-nan", L"nan", L"+nan");
+  CheckInfNan(swprintf, L"%F", L"%+F", L"-INF", L"INF", L"+INF", L"-NAN", L"NAN", L"+NAN");
+  CheckInfNan(swprintf, L"%g", L"%+g", L"-inf", L"inf", L"+inf", L"-nan", L"nan", L"+nan");
+  CheckInfNan(swprintf, L"%G", L"%+G", L"-INF", L"INF", L"+INF", L"-NAN", L"NAN", L"+NAN");
 }
 
 TEST(stdio, snprintf_d_INT_MAX) {
@@ -439,8 +469,22 @@ TEST(stdio, snprintf_e) {
 TEST(stdio, snprintf_negative_zero_5084292) {
   char buf[BUFSIZ];
 
+  snprintf(buf, sizeof(buf), "%e", -0.0);
+  EXPECT_STREQ("-0.000000e+00", buf);
+  snprintf(buf, sizeof(buf), "%E", -0.0);
+  EXPECT_STREQ("-0.000000E+00", buf);
   snprintf(buf, sizeof(buf), "%f", -0.0);
   EXPECT_STREQ("-0.000000", buf);
+  snprintf(buf, sizeof(buf), "%F", -0.0);
+  EXPECT_STREQ("-0.000000", buf);
+  snprintf(buf, sizeof(buf), "%g", -0.0);
+  EXPECT_STREQ("-0", buf);
+  snprintf(buf, sizeof(buf), "%G", -0.0);
+  EXPECT_STREQ("-0", buf);
+  snprintf(buf, sizeof(buf), "%a", -0.0);
+  EXPECT_STREQ("-0x0p+0", buf);
+  snprintf(buf, sizeof(buf), "%A", -0.0);
+  EXPECT_STREQ("-0X0P+0", buf);
 }
 
 TEST(stdio, snprintf_utf8_15439554) {