Merge "Fix strlen function type for mips."
diff --git a/libc/Android.mk b/libc/Android.mk
index 6beb7b3..31807dd 100644
--- a/libc/Android.mk
+++ b/libc/Android.mk
@@ -38,8 +38,6 @@
 # =========================================================
 libc_common_src_files := \
     bionic/bindresvport.c \
-    bionic/daemon.c \
-    bionic/err.c \
     bionic/ether_aton.c \
     bionic/ether_ntoa.c \
     bionic/fts.c \
@@ -338,6 +336,9 @@
     upstream-openbsd/lib/libc/crypt/arc4random_uniform.c \
     upstream-openbsd/lib/libc/gen/alarm.c \
     upstream-openbsd/lib/libc/gen/ctype_.c \
+    upstream-openbsd/lib/libc/gen/daemon.c \
+    upstream-openbsd/lib/libc/gen/err.c \
+    upstream-openbsd/lib/libc/gen/errx.c \
     upstream-openbsd/lib/libc/gen/exec.c \
     upstream-openbsd/lib/libc/gen/fnmatch.c \
     upstream-openbsd/lib/libc/gen/ftok.c \
@@ -347,6 +348,12 @@
     upstream-openbsd/lib/libc/gen/time.c \
     upstream-openbsd/lib/libc/gen/tolower_.c \
     upstream-openbsd/lib/libc/gen/toupper_.c \
+    upstream-openbsd/lib/libc/gen/verr.c \
+    upstream-openbsd/lib/libc/gen/verrx.c \
+    upstream-openbsd/lib/libc/gen/vwarn.c \
+    upstream-openbsd/lib/libc/gen/vwarnx.c \
+    upstream-openbsd/lib/libc/gen/warn.c \
+    upstream-openbsd/lib/libc/gen/warnx.c \
     upstream-openbsd/lib/libc/locale/btowc.c \
     upstream-openbsd/lib/libc/locale/mbrlen.c \
     upstream-openbsd/lib/libc/locale/mbstowcs.c \
@@ -644,7 +651,13 @@
     upstream-netbsd/lib/libc/isc/ev_timers.c \
     upstream-netbsd/lib/libc/resolv/mtctxres.c \
 
-LOCAL_CFLAGS := \
+# We use the OpenBSD res_random.
+LOCAL_CFLAGS += \
+    -Dres_randomid=__res_randomid
+LOCAL_SRC_FILES += \
+    upstream-openbsd/lib/libc/net/res_random.c \
+
+LOCAL_CFLAGS += \
     $(libc_common_cflags) \
     -DANDROID_CHANGES \
     -DINET6 \
@@ -1076,7 +1089,6 @@
 
 # Make sure that unwind.h comes from libunwind.
 LOCAL_C_INCLUDES := \
-    external/libunwind/include \
     $(libc_common_c_includes) \
 
 LOCAL_SRC_FILES := \
@@ -1092,7 +1104,9 @@
 
 LOCAL_SHARED_LIBRARIES := libc libdl
 LOCAL_SYSTEM_SHARED_LIBRARIES :=
-LOCAL_WHOLE_STATIC_LIBRARIES := libunwindbacktrace
+# Only need this for arm since libc++ uses its own unwind code that
+# doesn't mix with the other default unwind code.
+LOCAL_STATIC_LIBRARIES_arm := libc++
 LOCAL_ALLOW_UNDEFINED_SYMBOLS := true
 
 # Don't install on release build
diff --git a/libc/arch-arm/arm.mk b/libc/arch-arm/arm.mk
index 00be4ae..70cc8eb 100644
--- a/libc/arch-arm/arm.mk
+++ b/libc/arch-arm/arm.mk
@@ -53,7 +53,6 @@
     arch-arm/bionic/atomics_arm.c \
     arch-arm/bionic/__bionic_clone.S \
     arch-arm/bionic/_exit_with_stack_teardown.S \
-    arch-arm/bionic/__get_sp.S \
     arch-arm/bionic/libgcc_compat.c \
     arch-arm/bionic/memcmp.S \
     arch-arm/bionic/_setjmp.S \
diff --git a/libc/arch-arm/bionic/__get_sp.S b/libc/arch-arm/bionic/__get_sp.S
deleted file mode 100644
index 9ae6f24..0000000
--- a/libc/arch-arm/bionic/__get_sp.S
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- * 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.
- *  * 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 OWNER 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.
- */
-
-#include <private/bionic_asm.h>
-
-ENTRY_PRIVATE(__get_sp)
-  mov r0, sp
-  bx lr
-END(__get_sp)
diff --git a/libc/arch-arm64/arm64.mk b/libc/arch-arm64/arm64.mk
index ed991ce..6c4f6a6 100644
--- a/libc/arch-arm64/arm64.mk
+++ b/libc/arch-arm64/arm64.mk
@@ -29,7 +29,6 @@
 libc_bionic_src_files_arm64 := \
     arch-arm64/bionic/__bionic_clone.S \
     arch-arm64/bionic/_exit_with_stack_teardown.S \
-    arch-arm64/bionic/__get_sp.S \
     arch-arm64/bionic/__rt_sigreturn.S \
     arch-arm64/bionic/_setjmp.S \
     arch-arm64/bionic/setjmp.S \
diff --git a/libc/arch-arm64/bionic/__get_sp.S b/libc/arch-arm64/bionic/__get_sp.S
deleted file mode 100644
index d5e88e9..0000000
--- a/libc/arch-arm64/bionic/__get_sp.S
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * Copyright (C) 2013 The Android Open Source Project
- * 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.
- *  * 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 OWNER 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.
- */
-
-#include <private/bionic_asm.h>
-
-ENTRY_PRIVATE(__get_sp)
-    mov x0, sp
-    ret
-END(__get_sp)
diff --git a/libc/arch-mips/bionic/__get_sp.S b/libc/arch-mips/bionic/__get_sp.S
deleted file mode 100644
index 5f5d32e..0000000
--- a/libc/arch-mips/bionic/__get_sp.S
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- * 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.
- *  * 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 OWNER 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.
- */
-
-#include <private/bionic_asm.h>
-
-ENTRY_PRIVATE(__get_sp)
-  move v0, sp
-  j ra
-END(__get_sp)
diff --git a/libc/arch-mips/mips.mk b/libc/arch-mips/mips.mk
index 8e415f9..31a1f32 100644
--- a/libc/arch-mips/mips.mk
+++ b/libc/arch-mips/mips.mk
@@ -54,7 +54,6 @@
     arch-mips/bionic/bzero.S \
     arch-mips/bionic/cacheflush.cpp \
     arch-mips/bionic/_exit_with_stack_teardown.S \
-    arch-mips/bionic/__get_sp.S \
     arch-mips/bionic/_setjmp.S \
     arch-mips/bionic/setjmp.S \
     arch-mips/bionic/sigsetjmp.S \
diff --git a/libc/arch-mips64/bionic/__get_sp.S b/libc/arch-mips64/bionic/__get_sp.S
deleted file mode 100644
index 5f5d32e..0000000
--- a/libc/arch-mips64/bionic/__get_sp.S
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- * 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.
- *  * 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 OWNER 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.
- */
-
-#include <private/bionic_asm.h>
-
-ENTRY_PRIVATE(__get_sp)
-  move v0, sp
-  j ra
-END(__get_sp)
diff --git a/libc/arch-x86/atom/string/sse2-wcslen-atom.S b/libc/arch-x86/atom/string/sse2-wcslen-atom.S
index 6a6ad51..2f10db4 100644
--- a/libc/arch-x86/atom/string/sse2-wcslen-atom.S
+++ b/libc/arch-x86/atom/string/sse2-wcslen-atom.S
@@ -65,21 +65,21 @@
 ENTRY (wcslen)
 	mov	STR(%esp), %edx
 #endif
-	cmp	$0, (%edx)
+	cmpl	$0, (%edx)
 	jz	L(exit_tail0)
-	cmp	$0, 4(%edx)
+	cmpl	$0, 4(%edx)
 	jz	L(exit_tail1)
-	cmp	$0, 8(%edx)
+	cmpl	$0, 8(%edx)
 	jz	L(exit_tail2)
-	cmp	$0, 12(%edx)
+	cmpl	$0, 12(%edx)
 	jz	L(exit_tail3)
-	cmp	$0, 16(%edx)
+	cmpl	$0, 16(%edx)
 	jz	L(exit_tail4)
-	cmp	$0, 20(%edx)
+	cmpl	$0, 20(%edx)
 	jz	L(exit_tail5)
-	cmp	$0, 24(%edx)
+	cmpl	$0, 24(%edx)
 	jz	L(exit_tail6)
-	cmp	$0, 28(%edx)
+	cmpl	$0, 28(%edx)
 	jz	L(exit_tail7)
 
 	pxor	%xmm0, %xmm0
diff --git a/libc/arch-x86/bionic/__get_sp.S b/libc/arch-x86/bionic/__get_sp.S
deleted file mode 100644
index aea6ac6..0000000
--- a/libc/arch-x86/bionic/__get_sp.S
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- * 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.
- *  * 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 OWNER 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.
- */
-
-#include <private/bionic_asm.h>
-
-ENTRY_PRIVATE(__get_sp)
-  mov  %esp, %eax
-  ret
-END(__get_sp)
diff --git a/libc/arch-x86/x86.mk b/libc/arch-x86/x86.mk
index 019dc8e..a141548 100644
--- a/libc/arch-x86/x86.mk
+++ b/libc/arch-x86/x86.mk
@@ -25,7 +25,6 @@
 libc_bionic_src_files_x86 += \
     arch-x86/bionic/__bionic_clone.S \
     arch-x86/bionic/_exit_with_stack_teardown.S \
-    arch-x86/bionic/__get_sp.S \
     arch-x86/bionic/_setjmp.S \
     arch-x86/bionic/setjmp.S \
     arch-x86/bionic/__set_tls.c \
diff --git a/libc/arch-x86_64/bionic/__get_sp.S b/libc/arch-x86_64/bionic/__get_sp.S
deleted file mode 100644
index 49a2406..0000000
--- a/libc/arch-x86_64/bionic/__get_sp.S
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * Copyright (C) 2013 The Android Open Source Project
- * 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.
- *  * 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 OWNER 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.
- */
-
-#include <private/bionic_asm.h>
-
-ENTRY_PRIVATE(__get_sp)
-  mov  %rsp, %rax
-  ret
-END(__get_sp)
diff --git a/libc/arch-x86_64/x86_64.mk b/libc/arch-x86_64/x86_64.mk
index 7887c51..b001b5e 100644
--- a/libc/arch-x86_64/x86_64.mk
+++ b/libc/arch-x86_64/x86_64.mk
@@ -30,7 +30,6 @@
 libc_bionic_src_files_x86_64 := \
     arch-x86_64/bionic/__bionic_clone.S \
     arch-x86_64/bionic/_exit_with_stack_teardown.S \
-    arch-x86_64/bionic/__get_sp.S \
     arch-x86_64/bionic/__rt_sigreturn.S \
     arch-x86_64/bionic/_setjmp.S \
     arch-x86_64/bionic/setjmp.S \
diff --git a/libc/bionic/bionic_systrace.cpp b/libc/bionic/bionic_systrace.cpp
index b8e892e..f5be415 100644
--- a/libc/bionic/bionic_systrace.cpp
+++ b/libc/bionic/bionic_systrace.cpp
@@ -74,7 +74,7 @@
   }
 
   if (g_trace_marker_fd == -1) {
-    g_trace_marker_fd = open("/sys/kernel/debug/tracing/trace_marker", O_WRONLY | O_CLOEXEC);
+    g_trace_marker_fd = open("/sys/kernel/debug/tracing/trace_marker", O_CLOEXEC | O_WRONLY);
     if (g_trace_marker_fd == -1) {
       __libc_fatal("Could not open kernel trace file: %s\n", strerror(errno));
     }
diff --git a/libc/bionic/daemon.c b/libc/bionic/daemon.c
deleted file mode 100644
index 8181d16..0000000
--- a/libc/bionic/daemon.c
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- * 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.
- *  * 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 OWNER 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.
- */
-#include <stdlib.h>
-#include <unistd.h>
-#include <fcntl.h>
-
-int  daemon( int  nochdir, int  noclose )
-{
-   pid_t  pid;
-
-   if ( !nochdir && chdir("/") != 0 )
-       return -1;
-   
-   if ( !noclose )
-   {
-     int  fd = open("/dev/null", O_RDWR);
-
-     if ( fd < 0 )
-      return -1;
-
-     if ( dup2( fd, 0 ) < 0 ||
-	  dup2( fd, 1 ) < 0 ||
-          dup2( fd, 2 ) < 0 ) 
-     {
-       close(fd);
-      return -1;
-     }
-     close(fd);
-  }
-  
-   pid = fork();
-   if (pid < 0)
-    return -1;
-
-   if (pid > 0)
-    _exit(0);
-
-   if ( setsid() < 0 )
-     return -1;
-
-   return 0;
-}
-
diff --git a/libc/bionic/debug_mapinfo.cpp b/libc/bionic/debug_mapinfo.cpp
index d83799a..698ab6b 100644
--- a/libc/bionic/debug_mapinfo.cpp
+++ b/libc/bionic/debug_mapinfo.cpp
@@ -71,7 +71,7 @@
   struct mapinfo_t* milist = NULL;
   char data[1024]; // Used to read lines as well as to construct the filename.
   snprintf(data, sizeof(data), "/proc/%d/maps", pid);
-  FILE* fp = fopen(data, "r");
+  FILE* fp = fopen(data, "re");
   if (fp != NULL) {
     while (fgets(data, sizeof(data), fp) != NULL) {
       mapinfo_t* mi = parse_maps_line(data);
diff --git a/libc/bionic/dirent.cpp b/libc/bionic/dirent.cpp
index 7abc7f3..5e1c7a5 100644
--- a/libc/bionic/dirent.cpp
+++ b/libc/bionic/dirent.cpp
@@ -78,7 +78,7 @@
 }
 
 DIR* opendir(const char* path) {
-  int fd = open(path, O_RDONLY | O_DIRECTORY);
+  int fd = open(path, O_CLOEXEC | O_DIRECTORY | O_RDONLY);
   return (fd != -1) ? __allocate_DIR(fd) : NULL;
 }
 
diff --git a/libc/bionic/err.c b/libc/bionic/err.c
deleted file mode 100644
index 84a3d85..0000000
--- a/libc/bionic/err.c
+++ /dev/null
@@ -1,126 +0,0 @@
-/*-
- * Copyright (c) 1993
- *      The 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.
- */
-
-#include <sys/cdefs.h>
-#include <err.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <stdarg.h>
-#include <errno.h>
-
-extern const char* __progname;
-
-__noreturn void
-err(int eval, const char *fmt, ...)
-{
-        va_list ap;
-
-        va_start(ap, fmt);
-        verr(eval, fmt, ap);
-        va_end(ap);
-}
-
-__noreturn void
-errx(int eval, const char *fmt, ...)
-{
-        va_list ap;
-
-        va_start(ap, fmt);
-        verrx(eval, fmt, ap);
-        va_end(ap);
-}
-
-__noreturn void
-verr(int eval, const char *fmt, va_list ap)
-{
-        int sverrno;
-
-        sverrno = errno;
-        (void)fprintf(stderr, "%s: ", __progname);
-        if (fmt != NULL) {
-                (void)vfprintf(stderr, fmt, ap);
-                (void)fprintf(stderr, ": ");
-        }
-        (void)fprintf(stderr, "%s\n", strerror(sverrno));
-        exit(eval);
-}
-
-
-__noreturn void
-verrx(int eval, const char *fmt, va_list ap)
-{
-        (void)fprintf(stderr, "%s: ", __progname);
-        if (fmt != NULL)
-                (void)vfprintf(stderr, fmt, ap);
-        (void)fprintf(stderr, "\n");
-        exit(eval);
-}
-
-void
-warn(const char *fmt, ...)
-{
-	va_list ap;
-
-	va_start(ap, fmt);
-	vwarn(fmt, ap);
-	va_end(ap);
-}
-
-void
-warnx(const char *fmt, ...)
-{
-	va_list ap;
-
-	va_start(ap, fmt);
-	vwarnx(fmt, ap);
-	va_end(ap);
-}
-
-void
-vwarn(const char *fmt, va_list ap)
-{
-	int sverrno;
-
-	sverrno = errno;
-	(void)fprintf(stderr, "%s: ", __progname);
-	if (fmt != NULL) {
-		(void)vfprintf(stderr, fmt, ap);
-		(void)fprintf(stderr, ": ");
-	}
-	(void)fprintf(stderr, "%s\n", strerror(sverrno));
-}
-
-void
-vwarnx(const char *fmt, va_list ap)
-{
-	(void)fprintf(stderr, "%s: ", __progname);
-	if (fmt != NULL)
-		(void)vfprintf(stderr, fmt, ap);
-	(void)fprintf(stderr, "\n");
-}
diff --git a/libc/bionic/libc_init_common.cpp b/libc/bionic/libc_init_common.cpp
index ff9940e..2a6a03b 100644
--- a/libc/bionic/libc_init_common.cpp
+++ b/libc/bionic/libc_init_common.cpp
@@ -36,7 +36,6 @@
 #include <stdlib.h>
 #include <sys/auxv.h>
 #include <sys/time.h>
-#include <sys/resource.h>
 #include <unistd.h>
 
 #include "private/bionic_auxv.h"
@@ -46,7 +45,6 @@
 #include "pthread_internal.h"
 
 extern "C" abort_msg_t** __abort_message_ptr;
-extern "C" uintptr_t __get_sp(void);
 extern "C" int __system_properties_init(void);
 extern "C" int __set_tls(void* ptr);
 extern "C" int __set_tid_address(int* tid_address);
@@ -62,17 +60,6 @@
 // Declared in "private/bionic_ssp.h".
 uintptr_t __stack_chk_guard = 0;
 
-static size_t get_main_thread_stack_size() {
-  rlimit stack_limit;
-  int rlimit_result = getrlimit(RLIMIT_STACK, &stack_limit);
-  if ((rlimit_result == 0) &&
-      (stack_limit.rlim_cur != RLIM_INFINITY) &&
-      (stack_limit.rlim_cur > PTHREAD_STACK_MIN)) {
-    return (stack_limit.rlim_cur & ~(PAGE_SIZE - 1));
-  }
-  return PTHREAD_STACK_SIZE_DEFAULT;
-}
-
 /* Init TLS for the initial thread. Called by the linker _before_ libc is mapped
  * in memory. Beware: all writes to libc globals from this function will
  * apply to linker-private copies and will not be visible from libc later on.
@@ -96,16 +83,15 @@
   main_thread.tid = __set_tid_address(&main_thread.tid);
   main_thread.set_cached_pid(main_thread.tid);
 
-  // Work out the extent of the main thread's stack.
-  uintptr_t stack_top = (__get_sp() & ~(PAGE_SIZE - 1)) + PAGE_SIZE;
-  size_t stack_size = get_main_thread_stack_size();
-  void* stack_bottom = reinterpret_cast<void*>(stack_top - stack_size);
-
   // We don't want to free the main thread's stack even when the main thread exits
   // because things like environment variables with global scope live on it.
+  // We also can't free the pthread_internal_t itself, since that lives on the main
+  // thread's stack rather than on the heap.
   pthread_attr_init(&main_thread.attr);
-  pthread_attr_setstack(&main_thread.attr, stack_bottom, stack_size);
   main_thread.attr.flags = PTHREAD_ATTR_FLAG_USER_ALLOCATED_STACK | PTHREAD_ATTR_FLAG_MAIN_THREAD;
+  main_thread.attr.guard_size = 0; // The main thread has no guard page.
+  main_thread.attr.stack_size = 0; // User code should never see this; we'll compute it when asked.
+  // TODO: the main thread's sched_policy and sched_priority need to be queried.
 
   __init_thread(&main_thread, false);
   __init_tls(&main_thread);
diff --git a/libc/bionic/malloc_debug_qemu.cpp b/libc/bionic/malloc_debug_qemu.cpp
index b3b604d..2f4949b 100644
--- a/libc/bionic/malloc_debug_qemu.cpp
+++ b/libc/bionic/malloc_debug_qemu.cpp
@@ -606,7 +606,7 @@
      * the memory mapped spaces into writes to an I/O port that emulator
      * "listens to" on the other end. Note that until we open and map that
      * device, logging to emulator's stdout will not be available. */
-    int fd = open("/dev/qemu_trace", O_RDWR);
+    int fd = open("/dev/qemu_trace", O_CLOEXEC | O_RDWR);
     if (fd < 0) {
         error_log("Unable to open /dev/qemu_trace");
         return false;
diff --git a/libc/bionic/pthread_attr.cpp b/libc/bionic/pthread_attr.cpp
index e1cd853..8df3bff 100644
--- a/libc/bionic/pthread_attr.cpp
+++ b/libc/bionic/pthread_attr.cpp
@@ -28,6 +28,13 @@
 
 #include <pthread.h>
 
+#include <inttypes.h>
+#include <stdio.h>
+#include <sys/resource.h>
+
+#include "private/bionic_string_utils.h"
+#include "private/ErrnoRestorer.h"
+#include "private/libc_logging.h"
 #include "pthread_internal.h"
 
 int pthread_attr_init(pthread_attr_t* attr) {
@@ -90,8 +97,8 @@
 }
 
 int pthread_attr_getstacksize(const pthread_attr_t* attr, size_t* stack_size) {
-  *stack_size = attr->stack_size;
-  return 0;
+  void* unused;
+  return pthread_attr_getstack(attr, &unused, stack_size);
 }
 
 int pthread_attr_setstack(pthread_attr_t* attr, void* stack_base, size_t stack_size) {
@@ -106,7 +113,42 @@
   return 0;
 }
 
+static int __pthread_attr_getstack_main_thread(void** stack_base, size_t* stack_size) {
+  ErrnoRestorer errno_restorer;
+
+  // It doesn't matter which thread we are; we're just looking for "[stack]".
+  FILE* fp = fopen("/proc/self/maps", "re");
+  if (fp == NULL) {
+    return errno;
+  }
+  char line[BUFSIZ];
+  while (fgets(line, sizeof(line), fp) != NULL) {
+    if (ends_with(line, " [stack]\n")) {
+      uintptr_t lo, hi;
+      if (sscanf(line, "%" SCNxPTR "-%" SCNxPTR, &lo, &hi) == 2) {
+        *stack_base = reinterpret_cast<void*>(lo);
+        *stack_size = hi - lo;
+
+        // Does our current RLIMIT_STACK mean we won't actually get everything /proc/maps promises?
+        rlimit stack_limit;
+        if (getrlimit(RLIMIT_STACK, &stack_limit) != -1) {
+          if (*stack_size > stack_limit.rlim_cur) {
+            *stack_size = stack_limit.rlim_cur;
+          }
+        }
+
+        fclose(fp);
+        return 0;
+      }
+    }
+  }
+  __libc_fatal("No [stack] line found in /proc/self/maps!");
+}
+
 int pthread_attr_getstack(const pthread_attr_t* attr, void** stack_base, size_t* stack_size) {
+  if ((attr->flags & PTHREAD_ATTR_FLAG_MAIN_THREAD) != 0) {
+    return __pthread_attr_getstack_main_thread(stack_base, stack_size);
+  }
   *stack_base = attr->stack_base;
   *stack_size = attr->stack_size;
   return 0;
@@ -122,9 +164,8 @@
   return 0;
 }
 
-int pthread_getattr_np(pthread_t thid, pthread_attr_t* attr) {
-  pthread_internal_t* thread = (pthread_internal_t*) thid;
-  *attr = thread->attr;
+int pthread_getattr_np(pthread_t t, pthread_attr_t* attr) {
+  *attr = reinterpret_cast<pthread_internal_t*>(t)->attr;
   return 0;
 }
 
diff --git a/libc/bionic/pthread_setname_np.cpp b/libc/bionic/pthread_setname_np.cpp
index 1ddf810..7b2fa6b 100644
--- a/libc/bionic/pthread_setname_np.cpp
+++ b/libc/bionic/pthread_setname_np.cpp
@@ -67,7 +67,7 @@
   }
   char comm_name[sizeof(TASK_COMM_FMT) + 8];
   snprintf(comm_name, sizeof(comm_name), TASK_COMM_FMT, tid);
-  int fd = open(comm_name, O_WRONLY);
+  int fd = open(comm_name, O_CLOEXEC | O_WRONLY);
   if (fd == -1) {
     return errno;
   }
diff --git a/libc/bionic/pututline.c b/libc/bionic/pututline.c
index c8427f7..8cbf470 100644
--- a/libc/bionic/pututline.c
+++ b/libc/bionic/pututline.c
@@ -36,7 +36,7 @@
     struct utmp u;
     long i;
 
-    if (!(f = fopen(_PATH_UTMP, "w+")))
+    if (!(f = fopen(_PATH_UTMP, "w+e")))
         return;
 
     while (fread(&u, sizeof(struct utmp), 1, f) == 1)
@@ -55,7 +55,7 @@
 
     fclose(f);
 
-    if (!(f = fopen(_PATH_UTMP, "w+")))
+    if (!(f = fopen(_PATH_UTMP, "w+e")))
         return;
     fwrite(utmp, sizeof(struct utmp), 1, f);
 
diff --git a/libc/bionic/sysconf.cpp b/libc/bionic/sysconf.cpp
index 8309f08..d8aac4f 100644
--- a/libc/bionic/sysconf.cpp
+++ b/libc/bionic/sysconf.cpp
@@ -95,7 +95,7 @@
 }
 
 static int __sysconf_nprocessors_onln() {
-  FILE* fp = fopen("/proc/stat", "r");
+  FILE* fp = fopen("/proc/stat", "re");
   if (fp == NULL) {
     return 1;
   }
@@ -118,7 +118,7 @@
 }
 
 static int __get_meminfo(const char* pattern) {
-  FILE* fp = fopen("/proc/meminfo", "r");
+  FILE* fp = fopen("/proc/meminfo", "re");
   if (fp == NULL) {
     return -1;
   }
diff --git a/libc/bionic/system_properties.cpp b/libc/bionic/system_properties.cpp
index ad69cf5..411d6bf 100644
--- a/libc/bionic/system_properties.cpp
+++ b/libc/bionic/system_properties.cpp
@@ -201,14 +201,6 @@
         return -1;
     }
 
-    // TODO: Is this really required ? Does android run on any kernels that
-    // don't support O_CLOEXEC ?
-    const int ret = fcntl(fd, F_SETFD, FD_CLOEXEC);
-    if (ret < 0) {
-        close(fd);
-        return -1;
-    }
-
     if (ftruncate(fd, PA_SIZE) < 0) {
         close(fd);
         return -1;
@@ -271,18 +263,9 @@
 
 static int map_prop_area()
 {
-    int fd(open(property_filename, O_RDONLY | O_NOFOLLOW | O_CLOEXEC));
-    if (fd >= 0) {
-        /* For old kernels that don't support O_CLOEXEC */
-        const int ret = fcntl(fd, F_SETFD, FD_CLOEXEC);
-        if (ret < 0) {
-            close(fd);
-            return -1;
-        }
-    }
-
+    int fd = open(property_filename, O_CLOEXEC | O_NOFOLLOW | O_RDONLY);
     bool close_fd = true;
-    if ((fd < 0) && (errno == ENOENT)) {
+    if (fd == -1 && errno == ENOENT) {
         /*
          * For backwards compatibility, if the file doesn't
          * exist, we use the environment to get the file descriptor.
diff --git a/libc/dns/gethnamaddr.c b/libc/dns/gethnamaddr.c
index 80fdcbe..cc33c61 100644
--- a/libc/dns/gethnamaddr.c
+++ b/libc/dns/gethnamaddr.c
@@ -899,7 +899,7 @@
     res_static  rs = __res_get_static();
     if (rs == NULL) return;
 	if (!rs->hostf)
-		rs->hostf = fopen(_PATH_HOSTS, "r" );
+		rs->hostf = fopen(_PATH_HOSTS, "re" );
 	else
 		rewind(rs->hostf);
 	rs->stayopen = f;
@@ -925,7 +925,7 @@
 	int af, len;
 	res_static  rs = __res_get_static();
 
-	if (!rs->hostf && !(rs->hostf = fopen(_PATH_HOSTS, "r" ))) {
+	if (!rs->hostf && !(rs->hostf = fopen(_PATH_HOSTS, "re" ))) {
 		h_errno = NETDB_INTERNAL;
 		return NULL;
 	}
diff --git a/libc/dns/net/getaddrinfo.c b/libc/dns/net/getaddrinfo.c
index 65fd1c1..a492318 100644
--- a/libc/dns/net/getaddrinfo.c
+++ b/libc/dns/net/getaddrinfo.c
@@ -2017,7 +2017,7 @@
 {
 
 	if (!*hostf)
-		*hostf = fopen(_PATH_HOSTS, "r" );
+		*hostf = fopen(_PATH_HOSTS, "re");
 	else
 		rewind(*hostf);
 }
@@ -2046,7 +2046,7 @@
 	assert(name != NULL);
 	assert(pai != NULL);
 
-	if (!*hostf && !(*hostf = fopen(_PATH_HOSTS, "r" )))
+	if (!*hostf && !(*hostf = fopen(_PATH_HOSTS, "re")))
 		return (NULL);
  again:
 	if (!(p = fgets(hostbuf, sizeof hostbuf, *hostf)))
diff --git a/libc/dns/resolv/res_cache.c b/libc/dns/resolv/res_cache.c
index 77a1b4d..0201aa8 100644
--- a/libc/dns/resolv/res_cache.c
+++ b/libc/dns/resolv/res_cache.c
@@ -1436,7 +1436,7 @@
     char* buf;
     int fileLen;
 
-    fp = fopen("/data/reslog.txt", "w+");
+    fp = fopen("/data/reslog.txt", "w+e");
     if (fp != NULL) {
         statep = __res_get_state();
 
diff --git a/libc/dns/resolv/res_init.c b/libc/dns/resolv/res_init.c
index f1cbed8..713b6e0 100644
--- a/libc/dns/resolv/res_init.c
+++ b/libc/dns/resolv/res_init.c
@@ -289,7 +289,7 @@
 	 line[sizeof(name) - 1] == '\t'))
 
 	nserv = 0;
-	if ((fp = fopen(_PATH_RESCONF, "r")) != NULL) {
+	if ((fp = fopen(_PATH_RESCONF, "re")) != NULL) {
 	    /* read the config file */
 	    while (fgets(buf, sizeof(buf), fp) != NULL) {
 		/* skip comments */
@@ -616,47 +616,6 @@
 }
 #endif
 
-#ifdef ANDROID_CHANGES
-static int
-real_randomid(u_int *random_value) {
-	/* open the nonblocking random device, returning -1 on failure */
-	int random_device = open("/dev/urandom", O_RDONLY | O_CLOEXEC);
-	if (random_device < 0) {
-		return -1;
-	}
-
-	/* read from the random device, returning -1 on failure (or too many retries)*/
-	for (u_int retry = 5; retry > 0; retry--) {
-		int retval = read(random_device, random_value, sizeof(u_int));
-		if (retval == sizeof(u_int)) {
-			*random_value &= 0xffff;
-			close(random_device);
-			return 0;
-		} else if ((retval < 0) && (errno != EINTR)) {
-			break;
-		}
-	}
-
-	close(random_device);
-	return -1;
-}
-#endif /* ANDROID_CHANGES */
-
-u_int
-res_randomid(void) {
-#ifdef ANDROID_CHANGES
-	int status = 0;
-	u_int output = 0;
-	status = real_randomid(&output);
-	if (status != -1) {
-		return output;
-	}
-#endif /* ANDROID_CHANGES */
-	struct timeval now;
-	gettimeofday(&now, NULL);
-	return (0xffff & (now.tv_sec ^ now.tv_usec ^ getpid()));
-}
-
 /*%
  * This routine is for closing the socket if a virtual circuit is used and
  * the program wants to close it.  This provides support for endhostent()
diff --git a/libc/include/stdatomic.h b/libc/include/stdatomic.h
index adf60bb..99ab536 100644
--- a/libc/include/stdatomic.h
+++ b/libc/include/stdatomic.h
@@ -39,6 +39,13 @@
 
 #include <atomic>
 
+#undef _Atomic
+        /* Also defined by <atomic> for gcc.  But not used in macros. */
+        /* Also a clang intrinsic.                                    */
+        /* Should not be used by client code before this file is      */
+        /* included.  The definitions in <atomic> themselves see      */
+        /* the old definition, as they should.                        */
+        /* Client code sees the following definition.                 */
 #define _Atomic(t) std::atomic<t>
 
 using std::atomic_is_lock_free;
diff --git a/libc/private/bionic_string_utils.h b/libc/private/bionic_string_utils.h
new file mode 100644
index 0000000..ab0eccf
--- /dev/null
+++ b/libc/private/bionic_string_utils.h
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef _BIONIC_STRING_UTILS_H_
+#define _BIONIC_STRING_UTILS_H_
+
+#include <string.h>
+
+static inline bool ends_with(const char* s1, const char* s2) {
+  size_t s1_length = strlen(s1);
+  size_t s2_length = strlen(s2);
+  if (s2_length > s1_length) {
+    return false;
+  }
+  return memcmp(s1 + (s1_length - s2_length), s2, s2_length) == 0;
+}
+
+#endif // _BIONIC_STRING_UTILS_H_
diff --git a/libc/upstream-openbsd/android/include/openbsd-compat.h b/libc/upstream-openbsd/android/include/openbsd-compat.h
index 488b5f9..b9768e1 100644
--- a/libc/upstream-openbsd/android/include/openbsd-compat.h
+++ b/libc/upstream-openbsd/android/include/openbsd-compat.h
@@ -22,6 +22,16 @@
 #include <sys/cdefs.h>
 #include <stddef.h> // For size_t.
 
+/* Redirect internal C library calls to the public function. */
+#define _err err
+#define _errx errx
+#define _verr verr
+#define _verrx verrx
+#define _vwarn vwarn
+#define _vwarnx vwarnx
+#define _warn warn
+#define _warnx warnx
+
 /* OpenBSD's <ctype.h> uses these names, which conflicted with stlport.
  * Additionally, we changed the numeric/digit type from N to D for libcxx.
  */
diff --git a/libc/upstream-openbsd/lib/libc/gen/daemon.c b/libc/upstream-openbsd/lib/libc/gen/daemon.c
new file mode 100644
index 0000000..79f4264
--- /dev/null
+++ b/libc/upstream-openbsd/lib/libc/gen/daemon.c
@@ -0,0 +1,64 @@
+/*	$OpenBSD: daemon.c,v 1.7 2010/07/27 22:29:09 marco Exp $ */
+/*-
+ * Copyright (c) 1990, 1993
+ *	The 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.
+ */
+
+#include <fcntl.h>
+#include <paths.h>
+#include <unistd.h>
+#include <stdlib.h>
+
+int
+daemon(int nochdir, int noclose)
+{
+	int fd;
+
+	switch (fork()) {
+	case -1:
+		return (-1);
+	case 0:
+		break;
+	default:
+		_exit(0);
+	}
+
+	if (setsid() == -1)
+		return (-1);
+
+	if (!nochdir)
+		(void)chdir("/");
+
+	if (!noclose && (fd = open(_PATH_DEVNULL, O_RDWR, 0)) != -1) {
+		(void)dup2(fd, STDIN_FILENO);
+		(void)dup2(fd, STDOUT_FILENO);
+		(void)dup2(fd, STDERR_FILENO);
+		if (fd > 2)
+			(void)close(fd);
+	}
+	return (0);
+}
diff --git a/libc/upstream-openbsd/lib/libc/gen/err.c b/libc/upstream-openbsd/lib/libc/gen/err.c
new file mode 100644
index 0000000..e7ec29d
--- /dev/null
+++ b/libc/upstream-openbsd/lib/libc/gen/err.c
@@ -0,0 +1,47 @@
+/*	$OpenBSD: err.c,v 1.11 2012/12/05 23:19:59 deraadt Exp $ */
+/*-
+ * Copyright (c) 1993
+ *	The 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.
+ */
+
+#include <err.h>
+#include <stdarg.h>
+
+/* PRINTFLIKE2 */
+__dead void
+_err(int eval, const char *fmt, ...)
+{
+	va_list ap;
+
+	va_start(ap, fmt);
+	_verr(eval, fmt, ap);
+	va_end(ap);
+}
+
+/* PRINTFLIKE2 */
+__weak_alias(err, _err);
+
diff --git a/libc/upstream-openbsd/lib/libc/gen/errx.c b/libc/upstream-openbsd/lib/libc/gen/errx.c
new file mode 100644
index 0000000..d213435
--- /dev/null
+++ b/libc/upstream-openbsd/lib/libc/gen/errx.c
@@ -0,0 +1,47 @@
+/*	$OpenBSD: errx.c,v 1.10 2012/12/05 23:19:59 deraadt Exp $ */
+/*-
+ * Copyright (c) 1993
+ *	The 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.
+ */
+
+#include <err.h>
+#include <stdarg.h>
+
+/* PRINTFLIKE2 */
+__dead void
+_errx(int eval, const char *fmt, ...)
+{
+	va_list ap;
+
+	va_start(ap, fmt);
+	_verrx(eval, fmt, ap);
+	va_end(ap);
+}
+
+/* PRINTFLIKE2 */
+__weak_alias(errx, _errx);
+
diff --git a/libc/upstream-openbsd/lib/libc/gen/verr.c b/libc/upstream-openbsd/lib/libc/gen/verr.c
new file mode 100644
index 0000000..dcd8edc
--- /dev/null
+++ b/libc/upstream-openbsd/lib/libc/gen/verr.c
@@ -0,0 +1,56 @@
+/*	$OpenBSD: verr.c,v 1.9 2012/12/05 23:20:00 deraadt Exp $ */
+/*-
+ * Copyright (c) 1993
+ *	The 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.
+ */
+
+#include <err.h>
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdarg.h>
+
+extern char *__progname;		/* Program name, from crt0. */
+
+__dead void
+_verr(int eval, const char *fmt, va_list ap)
+{
+	int sverrno;
+
+	sverrno = errno;
+	(void)fprintf(stderr, "%s: ", __progname);
+	if (fmt != NULL) {
+		(void)vfprintf(stderr, fmt, ap);
+		(void)fprintf(stderr, ": ");
+	}
+	(void)fprintf(stderr, "%s\n", strerror(sverrno));
+	exit(eval);
+}
+
+__weak_alias(verr, _verr);
+
diff --git a/libc/upstream-openbsd/lib/libc/gen/verrx.c b/libc/upstream-openbsd/lib/libc/gen/verrx.c
new file mode 100644
index 0000000..60da062
--- /dev/null
+++ b/libc/upstream-openbsd/lib/libc/gen/verrx.c
@@ -0,0 +1,49 @@
+/*	$OpenBSD: verrx.c,v 1.9 2012/12/05 23:20:00 deraadt Exp $ */
+/*-
+ * Copyright (c) 1993
+ *	The 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.
+ */
+
+#include <err.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdarg.h>
+
+extern char *__progname;		/* Program name, from crt0. */
+
+__dead void
+_verrx(int eval, const char *fmt, va_list ap)
+{
+	(void)fprintf(stderr, "%s: ", __progname);
+	if (fmt != NULL)
+		(void)vfprintf(stderr, fmt, ap);
+	(void)fprintf(stderr, "\n");
+	exit(eval);
+}
+
+__weak_alias(verrx, _verrx);
+
diff --git a/libc/upstream-openbsd/lib/libc/gen/vwarn.c b/libc/upstream-openbsd/lib/libc/gen/vwarn.c
new file mode 100644
index 0000000..26b60f3
--- /dev/null
+++ b/libc/upstream-openbsd/lib/libc/gen/vwarn.c
@@ -0,0 +1,54 @@
+/*	$OpenBSD: vwarn.c,v 1.9 2012/12/05 23:20:00 deraadt Exp $ */
+/*-
+ * Copyright (c) 1993
+ *	The 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.
+ */
+
+#include <err.h>
+#include <errno.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdarg.h>
+
+extern char *__progname;		/* Program name, from crt0. */
+
+void
+_vwarn(const char *fmt, va_list ap)
+{
+	int sverrno;
+
+	sverrno = errno;
+	(void)fprintf(stderr, "%s: ", __progname);
+	if (fmt != NULL) {
+		(void)vfprintf(stderr, fmt, ap);
+		(void)fprintf(stderr, ": ");
+	}
+	(void)fprintf(stderr, "%s\n", strerror(sverrno));
+}
+
+__weak_alias(vwarn, _vwarn);
+
diff --git a/libc/upstream-openbsd/lib/libc/gen/vwarnx.c b/libc/upstream-openbsd/lib/libc/gen/vwarnx.c
new file mode 100644
index 0000000..e6b1957
--- /dev/null
+++ b/libc/upstream-openbsd/lib/libc/gen/vwarnx.c
@@ -0,0 +1,47 @@
+/*	$OpenBSD: vwarnx.c,v 1.9 2012/12/05 23:20:00 deraadt Exp $ */
+/*-
+ * Copyright (c) 1993
+ *	The 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.
+ */
+
+#include <err.h>
+#include <stdio.h>
+#include <stdarg.h>
+
+extern char *__progname;		/* Program name, from crt0. */
+
+void
+_vwarnx(const char *fmt, va_list ap)
+{
+	(void)fprintf(stderr, "%s: ", __progname);
+	if (fmt != NULL)
+		(void)vfprintf(stderr, fmt, ap);
+	(void)fprintf(stderr, "\n");
+}
+
+__weak_alias(vwarnx, _vwarnx);
+
diff --git a/libc/upstream-openbsd/lib/libc/gen/warn.c b/libc/upstream-openbsd/lib/libc/gen/warn.c
new file mode 100644
index 0000000..c1b47a6
--- /dev/null
+++ b/libc/upstream-openbsd/lib/libc/gen/warn.c
@@ -0,0 +1,47 @@
+/*	$OpenBSD: warn.c,v 1.10 2012/12/05 23:20:00 deraadt Exp $ */
+/*-
+ * Copyright (c) 1993
+ *	The 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.
+ */
+
+#include <err.h>
+#include <stdarg.h>
+
+/* PRINTFLIKE1 */
+void
+_warn(const char *fmt, ...)
+{
+	va_list ap;
+
+	va_start(ap, fmt);
+	_vwarn(fmt, ap);
+	va_end(ap);
+}
+
+/* PRINTFLIKE1 */
+__weak_alias(warn, _warn);
+
diff --git a/libc/upstream-openbsd/lib/libc/gen/warnx.c b/libc/upstream-openbsd/lib/libc/gen/warnx.c
new file mode 100644
index 0000000..af2ab66
--- /dev/null
+++ b/libc/upstream-openbsd/lib/libc/gen/warnx.c
@@ -0,0 +1,47 @@
+/*	$OpenBSD: warnx.c,v 1.9 2012/12/05 23:20:00 deraadt Exp $ */
+/*-
+ * Copyright (c) 1993
+ *	The 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.
+ */
+
+#include <err.h>
+#include <stdarg.h>
+
+/* PRINTFLIKE1 */
+void
+_warnx(const char *fmt, ...)
+{
+	va_list ap;
+
+	va_start(ap, fmt);
+	_vwarnx(fmt, ap);
+	va_end(ap);
+}
+
+/* PRINTFLIKE1 */
+__weak_alias(warnx, _warnx);
+
diff --git a/libc/upstream-openbsd/lib/libc/net/res_random.c b/libc/upstream-openbsd/lib/libc/net/res_random.c
new file mode 100644
index 0000000..f28692f
--- /dev/null
+++ b/libc/upstream-openbsd/lib/libc/net/res_random.c
@@ -0,0 +1,275 @@
+/* $OpenBSD: res_random.c,v 1.21 2014/07/20 04:22:34 guenther Exp $ */
+
+/*
+ * Copyright 1997 Niels Provos <provos@physnet.uni-hamburg.de>
+ * Copyright 2008 Damien Miller <djm@openbsd.org>
+ * All rights reserved.
+ *
+ * Theo de Raadt <deraadt@openbsd.org> came up with the idea of using
+ * such a mathematical system to generate more random (yet non-repeating)
+ * ids to solve the resolver/named problem.  But Niels designed the
+ * actual system based on the constraints.
+ *
+ * Later modified by Damien Miller to wrap the LCG output in a 15-bit
+ * permutation generator based on a Luby-Rackoff block cipher. This
+ * ensures the output is non-repeating and preserves the MSB twiddle
+ * trick, but makes it more resistant to LCG prediction.
+ *
+ * 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.
+ */
+
+/* 
+ * seed = random 15bit
+ * n = prime, g0 = generator to n,
+ * j = random so that gcd(j,n-1) == 1
+ * g = g0^j mod n will be a generator again.
+ *
+ * X[0] = random seed.
+ * X[n] = a*X[n-1]+b mod m is a Linear Congruential Generator
+ * with a = 7^(even random) mod m, 
+ *      b = random with gcd(b,m) == 1
+ *      m = 31104 and a maximal period of m-1.
+ *
+ * The transaction id is determined by:
+ * id[n] = seed xor (g^X[n] mod n)
+ *
+ * Effectivly the id is restricted to the lower 15 bits, thus
+ * yielding two different cycles by toggling the msb on and off.
+ * This avoids reuse issues caused by reseeding.
+ *
+ * The output of this generator is then randomly permuted though a
+ * custom 15 bit Luby-Rackoff block cipher.
+ */
+
+#include <sys/types.h>
+#include <netinet/in.h>
+#include <sys/time.h>
+#include <resolv.h>
+
+#include <unistd.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "thread_private.h"
+
+#define RU_OUT  	180	/* Time after wich will be reseeded */
+#define RU_MAX		30000	/* Uniq cycle, avoid blackjack prediction */
+#define RU_GEN		2	/* Starting generator */
+#define RU_N		32749	/* RU_N-1 = 2*2*3*2729 */
+#define RU_AGEN		7	/* determine ru_a as RU_AGEN^(2*rand) */
+#define RU_M		31104	/* RU_M = 2^7*3^5 - don't change */
+#define RU_ROUNDS	11	/* Number of rounds for permute (odd) */
+
+struct prf_ctx {
+	/* PRF lookup table for odd rounds (7 bits input to 8 bits output) */
+	u_char prf7[(RU_ROUNDS / 2) * (1 << 7)];
+
+	/* PRF lookup table for even rounds (8 bits input to 7 bits output) */
+	u_char prf8[((RU_ROUNDS + 1) / 2) * (1 << 8)];
+};
+
+#define PFAC_N 3
+static const u_int16_t pfacts[PFAC_N] = {
+	2, 
+	3,
+	2729
+};
+
+static u_int16_t ru_x;
+static u_int16_t ru_seed, ru_seed2;
+static u_int16_t ru_a, ru_b;
+static u_int16_t ru_g;
+static u_int16_t ru_counter = 0;
+static u_int16_t ru_msb = 0;
+static struct prf_ctx *ru_prf = NULL;
+static time_t ru_reseed;
+
+static u_int16_t pmod(u_int16_t, u_int16_t, u_int16_t);
+static void res_initid(void);
+
+/*
+ * Do a fast modular exponation, returned value will be in the range
+ * of 0 - (mod-1)
+ */
+static u_int16_t
+pmod(u_int16_t gen, u_int16_t exp, u_int16_t mod)
+{
+	u_int16_t s, t, u;
+
+	s = 1;
+	t = gen;
+	u = exp;
+
+	while (u) {
+		if (u & 1)
+			s = (s * t) % mod;
+		u >>= 1;
+		t = (t * t) % mod;
+	}
+	return (s);
+}
+
+/*
+ * 15-bit permutation based on Luby-Rackoff block cipher
+ */
+static u_int
+permute15(u_int in)
+{
+	int i;
+	u_int left, right, tmp;
+
+	if (ru_prf == NULL)
+		return in;
+
+	left = (in >> 8) & 0x7f;
+	right = in & 0xff;
+
+	/*
+	 * Each round swaps the width of left and right. Even rounds have
+	 * a 7-bit left, odd rounds have an 8-bit left.	Since this uses an
+	 * odd number of rounds, left is always 8 bits wide at the end.
+	 */
+	for (i = 0; i < RU_ROUNDS; i++) {
+		if ((i & 1) == 0)
+			tmp = ru_prf->prf8[(i << (8 - 1)) | right] & 0x7f;
+		else
+			tmp = ru_prf->prf7[((i - 1) << (7 - 1)) | right];
+		tmp ^= left;
+		left = right;
+		right = tmp;
+	}
+
+	return (right << 8) | left;
+}
+
+/* 
+ * Initializes the seed and chooses a suitable generator. Also toggles 
+ * the msb flag. The msb flag is used to generate two distinct
+ * cycles of random numbers and thus avoiding reuse of ids.
+ *
+ * This function is called from res_randomid() when needed, an 
+ * application does not have to worry about it.
+ */
+static void 
+res_initid(void)
+{
+	u_int16_t j, i;
+	u_int32_t tmp;
+	int noprime = 1;
+	struct timespec ts;
+
+	ru_x = arc4random_uniform(RU_M);
+
+	/* 15 bits of random seed */
+	tmp = arc4random();
+	ru_seed = (tmp >> 16) & 0x7FFF;
+	ru_seed2 = tmp & 0x7FFF;
+
+	/* Determine the LCG we use */
+	tmp = arc4random();
+	ru_b = (tmp & 0xfffe) | 1;
+	ru_a = pmod(RU_AGEN, (tmp >> 16) & 0xfffe, RU_M);
+	while (ru_b % 3 == 0)
+		ru_b += 2;
+	
+	j = arc4random_uniform(RU_N);
+
+	/* 
+	 * Do a fast gcd(j,RU_N-1), so we can find a j with
+	 * gcd(j, RU_N-1) == 1, giving a new generator for
+	 * RU_GEN^j mod RU_N
+	 */
+
+	while (noprime) {
+		for (i = 0; i < PFAC_N; i++)
+			if (j % pfacts[i] == 0)
+				break;
+
+		if (i >= PFAC_N)
+			noprime = 0;
+		else 
+			j = (j + 1) % RU_N;
+	}
+
+	ru_g = pmod(RU_GEN, j, RU_N);
+	ru_counter = 0;
+
+	/* Initialise PRF for Luby-Rackoff permutation */
+	if (ru_prf == NULL)
+		ru_prf = malloc(sizeof(*ru_prf));
+	if (ru_prf != NULL)
+		arc4random_buf(ru_prf, sizeof(*ru_prf));
+
+	clock_gettime(CLOCK_MONOTONIC, &ts);
+	ru_reseed = ts.tv_sec + RU_OUT;
+	ru_msb = ru_msb == 0x8000 ? 0 : 0x8000; 
+}
+
+u_int
+res_randomid(void)
+{
+	struct timespec ts;
+	u_int r;
+	_THREAD_PRIVATE_MUTEX(random);
+
+	clock_gettime(CLOCK_MONOTONIC, &ts);
+
+	_THREAD_PRIVATE_MUTEX_LOCK(random);
+
+	if (ru_counter >= RU_MAX || ts.tv_sec > ru_reseed)
+		res_initid();
+
+	/* Linear Congruential Generator */
+	ru_x = (ru_a * ru_x + ru_b) % RU_M;
+	ru_counter++;
+
+	r = permute15(ru_seed ^ pmod(ru_g, ru_seed2 + ru_x, RU_N)) | ru_msb;
+
+	_THREAD_PRIVATE_MUTEX_UNLOCK(random);
+
+	return (r);
+}
+
+#if 0
+int
+main(int argc, char **argv)
+{
+	int i, n;
+	u_int16_t wert;
+
+	res_initid();
+
+	printf("Generator: %u\n", ru_g);
+	printf("Seed: %u\n", ru_seed);
+	printf("Reseed at %ld\n", ru_reseed);
+	printf("Ru_X: %u\n", ru_x);
+	printf("Ru_A: %u\n", ru_a);
+	printf("Ru_B: %u\n", ru_b);
+
+	n = argc > 1 ? atoi(argv[1]) : 60001;
+	for (i=0;i<n;i++) {
+		wert = res_randomid();
+		printf("%u\n", wert);
+	}
+	return 0;
+}
+#endif
+
diff --git a/linker/Android.mk b/linker/Android.mk
index 5853c90..4298032 100644
--- a/linker/Android.mk
+++ b/linker/Android.mk
@@ -8,6 +8,7 @@
     linker.cpp \
     linker_allocator.cpp \
     linker_environ.cpp \
+    linker_libc_support.c \
     linker_phdr.cpp \
     rt.cpp \
 
diff --git a/linker/linked_list.h b/linker/linked_list.h
index 8096e62..e51eb9c 100644
--- a/linker/linked_list.h
+++ b/linker/linked_list.h
@@ -32,6 +32,9 @@
 class LinkedList {
  public:
   LinkedList() : head_(nullptr), tail_(nullptr) {}
+  ~LinkedList() {
+    clear();
+  }
 
   void push_front(T* const element) {
     LinkedListEntry<T>* new_entry = Allocator::alloc();
diff --git a/linker/linker.cpp b/linker/linker.cpp
index 6a55571..5f5823b 100644
--- a/linker/linker.cpp
+++ b/linker/linker.cpp
@@ -639,8 +639,6 @@
 
     if (result != nullptr) {
       *found = current_soinfo;
-      visit_list.clear();
-      visited.clear();
       return result;
     }
     visited.push_back(current_soinfo);
@@ -650,8 +648,6 @@
     });
   }
 
-  visit_list.clear();
-  visited.clear();
   return nullptr;
 }
 
@@ -2167,16 +2163,6 @@
  * and other non-local data at this point.
  */
 static ElfW(Addr) __linker_init_post_relocation(KernelArgumentBlock& args, ElfW(Addr) linker_base) {
-    /* NOTE: we store the args pointer on a special location
-     *       of the temporary TLS area in order to pass it to
-     *       the C Library's runtime initializer.
-     *
-     *       The initializer must clear the slot and reset the TLS
-     *       to point to a different location to ensure that no other
-     *       shared library constructor can access it.
-     */
-  __libc_init_tls(args);
-
 #if TIMING
     struct timeval t0, t1;
     gettimeofday(&t0, 0);
@@ -2403,6 +2389,8 @@
     _exit(EXIT_FAILURE);
   }
 
+  __libc_init_tls(args);
+
   // Initialize the linker's own global variables
   linker_so.CallConstructors();
 
@@ -2412,7 +2400,6 @@
   solist = get_libdl_info();
   sonext = get_libdl_info();
 
-
   // We have successfully fixed our own relocations. It's safe to run
   // the main part of the linker now.
   args.abort_message_ptr = &g_abort_message;
diff --git a/linker/linker_libc_support.c b/linker/linker_libc_support.c
new file mode 100644
index 0000000..17db6d4
--- /dev/null
+++ b/linker/linker_libc_support.c
@@ -0,0 +1,17 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "../libc/arch-common/bionic/__dso_handle.h"
diff --git a/tests/Android.mk b/tests/Android.mk
index 13d7cbe..5179bfa 100644
--- a/tests/Android.mk
+++ b/tests/Android.mk
@@ -366,7 +366,7 @@
 
 ifeq ($(TARGET_ARCH),$(filter $(TARGET_ARCH),x86_64))
 # add target to run lp32 tests
-bionic-unit-tests-run-on-host32: bionic-unit-tests $(TARGET_OUT_EXECUTABLES)/$(LINKER) $(TARGET_OUT_EXECUTABLES)/sh
+bionic-unit-tests-run-on-host32: bionic-unit-tests_32 $(TARGET_OUT_EXECUTABLES)/$(LINKER) $(TARGET_OUT_EXECUTABLES)/sh
 	if [ ! -d /system -o ! -d /system/bin ]; then \
 	  echo "Attempting to create /system/bin"; \
 	  sudo mkdir -p -m 0777 /system/bin; \
diff --git a/tests/dlext_test.cpp b/tests/dlext_test.cpp
index da63046..9a96b67 100644
--- a/tests/dlext_test.cpp
+++ b/tests/dlext_test.cpp
@@ -117,7 +117,7 @@
   ASSERT_DL_NOTNULL(handle_);
   fn f = reinterpret_cast<fn>(dlsym(handle_, "getRandomNumber"));
   ASSERT_DL_NOTNULL(f);
-  EXPECT_GE(f, start);
+  EXPECT_GE(reinterpret_cast<void*>(f), start);
   EXPECT_LT(reinterpret_cast<void*>(f),
             reinterpret_cast<char*>(start) + LIBSIZE);
   EXPECT_EQ(4, f());
@@ -147,7 +147,7 @@
   ASSERT_DL_NOTNULL(handle_);
   fn f = reinterpret_cast<fn>(dlsym(handle_, "getRandomNumber"));
   ASSERT_DL_NOTNULL(f);
-  EXPECT_GE(f, start);
+  EXPECT_GE(reinterpret_cast<void*>(f), start);
   EXPECT_LT(reinterpret_cast<void*>(f),
             reinterpret_cast<char*>(start) + LIBSIZE);
   EXPECT_EQ(4, f());
@@ -165,8 +165,9 @@
   ASSERT_DL_NOTNULL(handle_);
   fn f = reinterpret_cast<fn>(dlsym(handle_, "getRandomNumber"));
   ASSERT_DL_NOTNULL(f);
-  EXPECT_TRUE(f < start || (reinterpret_cast<void*>(f) >=
-                            reinterpret_cast<char*>(start) + PAGE_SIZE));
+  EXPECT_TRUE(reinterpret_cast<void*>(f) < start ||
+              (reinterpret_cast<void*>(f) >=
+               reinterpret_cast<char*>(start) + PAGE_SIZE));
   EXPECT_EQ(4, f());
 }
 
diff --git a/tests/dlfcn_test.cpp b/tests/dlfcn_test.cpp
index a731748..6de38c8 100644
--- a/tests/dlfcn_test.cpp
+++ b/tests/dlfcn_test.cpp
@@ -231,10 +231,8 @@
   // Look in /proc/pid/maps to find out what address we were loaded at.
   // TODO: factor /proc/pid/maps parsing out into a class and reuse all over bionic.
   void* base_address = NULL;
-  char path[PATH_MAX];
-  snprintf(path, sizeof(path), "/proc/%d/maps", getpid());
   char line[BUFSIZ];
-  FILE* fp = fopen(path, "r");
+  FILE* fp = fopen("/proc/self/maps", "r");
   ASSERT_TRUE(fp != NULL);
   while (fgets(line, sizeof(line), fp) != NULL) {
     uintptr_t start = strtoul(line, 0, 16);
diff --git a/tests/locale_test.cpp b/tests/locale_test.cpp
index 325f6ce..7ec607a 100644
--- a/tests/locale_test.cpp
+++ b/tests/locale_test.cpp
@@ -114,11 +114,12 @@
   locale_t cloc = newlocale(LC_ALL, "C", 0);
   locale_t cloc_utf8 = newlocale(LC_ALL, "C.UTF-8", 0);
 
-  uselocale(cloc);
+  locale_t old_locale = uselocale(cloc);
   ASSERT_EQ(1U, MB_CUR_MAX);
   uselocale(cloc_utf8);
   ASSERT_EQ(4U, MB_CUR_MAX);
 
+  uselocale(old_locale);
   freelocale(cloc);
   freelocale(cloc_utf8);
 }
diff --git a/tests/pthread_test.cpp b/tests/pthread_test.cpp
index 5328e48..5f74e38 100644
--- a/tests/pthread_test.cpp
+++ b/tests/pthread_test.cpp
@@ -23,6 +23,7 @@
 #include <pthread.h>
 #include <signal.h>
 #include <sys/mman.h>
+#include <sys/syscall.h>
 #include <time.h>
 #include <unistd.h>
 
@@ -816,3 +817,88 @@
   ASSERT_EQ(0, pthread_mutex_unlock(&m));
   ASSERT_EQ(0, pthread_mutex_destroy(&m));
 }
+
+TEST(pthread, pthread_attr_getstack__main_thread) {
+  // This test is only meaningful for the main thread, so make sure we're running on it!
+  ASSERT_EQ(getpid(), syscall(__NR_gettid));
+
+  // Get the main thread's attributes.
+  pthread_attr_t attributes;
+  ASSERT_EQ(0, pthread_getattr_np(pthread_self(), &attributes));
+
+  // Check that we correctly report that the main thread has no guard page.
+  size_t guard_size;
+  ASSERT_EQ(0, pthread_attr_getguardsize(&attributes, &guard_size));
+  ASSERT_EQ(0U, guard_size); // The main thread has no guard page.
+
+  // Get the stack base and the stack size (both ways).
+  void* stack_base;
+  size_t stack_size;
+  ASSERT_EQ(0, pthread_attr_getstack(&attributes, &stack_base, &stack_size));
+  size_t stack_size2;
+  ASSERT_EQ(0, pthread_attr_getstacksize(&attributes, &stack_size2));
+
+  // The two methods of asking for the stack size should agree.
+  EXPECT_EQ(stack_size, stack_size2);
+
+  // What does /proc/self/maps' [stack] line say?
+  void* maps_stack_base = NULL;
+  size_t maps_stack_size = 0;
+  FILE* fp = fopen("/proc/self/maps", "r");
+  ASSERT_TRUE(fp != NULL);
+  char line[BUFSIZ];
+  while (fgets(line, sizeof(line), fp) != NULL) {
+    uintptr_t lo, hi;
+    char name[10];
+    sscanf(line, "%" PRIxPTR "-%" PRIxPTR " %*4s %*x %*x:%*x %*d %10s", &lo, &hi, name);
+    if (strcmp(name, "[stack]") == 0) {
+      maps_stack_base = reinterpret_cast<void*>(lo);
+      maps_stack_size = hi - lo;
+      break;
+    }
+  }
+  fclose(fp);
+
+#if defined(__BIONIC__)
+  // bionic thinks that the stack base and size should correspond to the mapped region.
+  EXPECT_EQ(maps_stack_base, stack_base);
+  EXPECT_EQ(maps_stack_size, stack_size);
+#else
+  // glibc doesn't give the true extent for some reason.
+#endif
+
+  // Both bionic and glibc agree that the high address you can compute from the returned
+  // values should match what /proc/self/maps says.
+  void* stack_end = reinterpret_cast<uint8_t*>(stack_base) + stack_size;
+  void* maps_stack_end = reinterpret_cast<uint8_t*>(maps_stack_base) + maps_stack_size;
+  EXPECT_EQ(maps_stack_end, stack_end);
+
+  //
+  // What if the rlimit is smaller than the stack's current extent?
+  //
+  rlimit rl;
+  rl.rlim_cur = rl.rlim_max = 1024; // 1KiB. We know the stack must be at least a page already.
+  rl.rlim_max = RLIM_INFINITY;
+  ASSERT_EQ(0, setrlimit(RLIMIT_STACK, &rl));
+
+  ASSERT_EQ(0, pthread_getattr_np(pthread_self(), &attributes));
+  ASSERT_EQ(0, pthread_attr_getstack(&attributes, &stack_base, &stack_size));
+  ASSERT_EQ(0, pthread_attr_getstacksize(&attributes, &stack_size2));
+
+  EXPECT_EQ(stack_size, stack_size2);
+  ASSERT_EQ(1024U, stack_size);
+
+  //
+  // What if the rlimit isn't a whole number of pages?
+  //
+  rl.rlim_cur = rl.rlim_max = 6666; // Not a whole number of pages.
+  rl.rlim_max = RLIM_INFINITY;
+  ASSERT_EQ(0, setrlimit(RLIMIT_STACK, &rl));
+
+  ASSERT_EQ(0, pthread_getattr_np(pthread_self(), &attributes));
+  ASSERT_EQ(0, pthread_attr_getstack(&attributes, &stack_base, &stack_size));
+  ASSERT_EQ(0, pthread_attr_getstacksize(&attributes, &stack_size2));
+
+  EXPECT_EQ(stack_size, stack_size2);
+  ASSERT_EQ(6666U, stack_size);
+}
diff --git a/tests/stdio_test.cpp b/tests/stdio_test.cpp
index 2cd0df2..c01ab68 100644
--- a/tests/stdio_test.cpp
+++ b/tests/stdio_test.cpp
@@ -428,7 +428,7 @@
 
 TEST(stdio, snprintf_utf8_15439554) {
   locale_t cloc = newlocale(LC_ALL, "C.UTF-8", 0);
-  uselocale(cloc);
+  locale_t old_locale = uselocale(cloc);
 
   // http://b/15439554
   char buf[BUFSIZ];
@@ -446,6 +446,7 @@
   snprintf(buf, sizeof(buf), "%d\xf0\xa4\xad\xa2%d", 1, 2);
   EXPECT_STREQ("1𤭢2", buf);
 
+  uselocale(old_locale);
   freelocale(cloc);
 }