Merge "Fix bionic-unit-tests-glibc-run target"
diff --git a/libc/Android.mk b/libc/Android.mk
index 8c2ebd6..2ec1281 100644
--- a/libc/Android.mk
+++ b/libc/Android.mk
@@ -223,11 +223,9 @@
     upstream-freebsd/lib/libc/stdio/fclose.c \
     upstream-freebsd/lib/libc/stdio/flags.c \
     upstream-freebsd/lib/libc/stdio/fopen.c \
-    upstream-freebsd/lib/libc/stdio/fwrite.c \
     upstream-freebsd/lib/libc/stdio/makebuf.c \
     upstream-freebsd/lib/libc/stdio/mktemp.c \
     upstream-freebsd/lib/libc/stdio/setvbuf.c \
-    upstream-freebsd/lib/libc/stdio/wsetup.c \
     upstream-freebsd/lib/libc/stdlib/abs.c \
     upstream-freebsd/lib/libc/stdlib/getopt_long.c \
     upstream-freebsd/lib/libc/stdlib/imaxabs.c \
@@ -388,6 +386,7 @@
     upstream-openbsd/lib/libc/stdio/fwalk.c \
     upstream-openbsd/lib/libc/stdio/fwide.c \
     upstream-openbsd/lib/libc/stdio/fwprintf.c \
+    upstream-openbsd/lib/libc/stdio/fwrite.c \
     upstream-openbsd/lib/libc/stdio/fwscanf.c \
     upstream-openbsd/lib/libc/stdio/getc.c \
     upstream-openbsd/lib/libc/stdio/getchar.c \
@@ -436,6 +435,7 @@
     upstream-openbsd/lib/libc/stdio/wbuf.c \
     upstream-openbsd/lib/libc/stdio/wprintf.c \
     upstream-openbsd/lib/libc/stdio/wscanf.c \
+    upstream-openbsd/lib/libc/stdio/wsetup.c \
     upstream-openbsd/lib/libc/stdlib/atoi.c \
     upstream-openbsd/lib/libc/stdlib/atol.c \
     upstream-openbsd/lib/libc/stdlib/atoll.c \
@@ -554,6 +554,8 @@
 include $(CLEAR_VARS)
 
 LOCAL_SRC_FILES := $(call all-c-files-under,tzcode)
+# tzcode doesn't include wcsftime, so we use the OpenBSD one.
+LOCAL_SRC_FILES += upstream-openbsd/lib/libc/time/wcsftime.c
 
 LOCAL_CFLAGS := $(libc_common_cflags)
 # Don't use ridiculous amounts of stack.
@@ -566,10 +568,11 @@
 LOCAL_CFLAGS += -DTZDIR=\"/system/usr/share/zoneinfo\"
 # Include timezone and daylight globals.
 LOCAL_CFLAGS += -DUSG_COMPAT=1
+LOCAL_CFLAGS += -DNO_RUN_TIME_WARNINGS_ABOUT_YEAR_2000_PROBLEMS_THANK_YOU
 
 LOCAL_CONLYFLAGS := $(libc_common_conlyflags)
 LOCAL_CPPFLAGS := $(libc_common_cppflags)
-LOCAL_C_INCLUDES := $(libc_common_c_includes)
+LOCAL_C_INCLUDES := $(libc_common_c_includes) $(LOCAL_PATH)/tzcode/
 LOCAL_MODULE := libc_tzcode
 LOCAL_ADDITIONAL_DEPENDENCIES := $(libc_common_additional_dependencies)
 LOCAL_SYSTEM_SHARED_LIBRARIES :=
@@ -616,6 +619,7 @@
 LOCAL_SRC_FILES := $(libc_upstream_freebsd_src_files)
 LOCAL_CFLAGS := \
     $(libc_common_cflags) \
+    -Wno-sign-compare -Wno-uninitialized \
     -I$(LOCAL_PATH)/upstream-freebsd/android/include \
     -I$(LOCAL_PATH)/upstream-freebsd/lib/libc/include \
     -include freebsd-compat.h
@@ -642,6 +646,7 @@
 LOCAL_SRC_FILES := $(libc_upstream_netbsd_src_files)
 LOCAL_CFLAGS := \
     $(libc_common_cflags) \
+    -Wno-sign-compare -Wno-uninitialized \
     -DPOSIX_MISTAKE \
     -I$(LOCAL_PATH)/upstream-netbsd/android/include \
     -I$(LOCAL_PATH)/upstream-netbsd/lib/libc/include \
@@ -669,8 +674,10 @@
 LOCAL_SRC_FILES := $(libc_upstream_openbsd_src_files)
 LOCAL_CFLAGS := \
     $(libc_common_cflags) \
+    -Wno-sign-compare -Wno-uninitialized \
     -I$(LOCAL_PATH)/upstream-openbsd/android/include \
     -I$(LOCAL_PATH)/upstream-openbsd/lib/libc/include \
+    -I$(LOCAL_PATH)/upstream-openbsd/lib/libc/gdtoa/ \
     -include openbsd-compat.h
 LOCAL_CONLYFLAGS := $(libc_common_conlyflags)
 LOCAL_CPPFLAGS := $(libc_common_cppflags)
@@ -696,6 +703,7 @@
 LOCAL_SRC_FILES_64 := $(libc_upstream_openbsd_gdtoa_src_files_64)
 LOCAL_CFLAGS := \
     $(libc_common_cflags) \
+    -Wno-sign-compare -Wno-uninitialized \
     -fvisibility=hidden \
     -I$(LOCAL_PATH)/upstream-openbsd/android/include \
     -I$(LOCAL_PATH)/upstream-openbsd/lib/libc/include \
diff --git a/libc/NOTICE b/libc/NOTICE
index 82733a2..4334275 100644
--- a/libc/NOTICE
+++ b/libc/NOTICE
@@ -8,6 +8,38 @@
 
 -------------------------------------------------------------------
 
+Based on the UCB version with the ID appearing below.
+This is ANSIish only when "multibyte character == plain character".
+
+Copyright (c) 1989, 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.
+
+-------------------------------------------------------------------
+
 Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
 All rights reserved.
 
@@ -1201,35 +1233,6 @@
 -------------------------------------------------------------------
 
 Copyright (c) 1988, 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.
-
--------------------------------------------------------------------
-
-Copyright (c) 1988, 1993
    The Regents of the University of California.  All rights reserved.
 
 Redistribution and use in source and binary forms, with or without
@@ -1804,6 +1807,38 @@
 
 Copyright (c) 1990, 1993
    The Regents of the University of California.  All rights reserved.
+
+This code is derived from software contributed to Berkeley by
+Donn Seeley at UUNET Technologies, Inc.
+
+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.
+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 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, 1993
+   The Regents of the University of California.  All rights reserved.
 (c) UNIX System Laboratories, Inc.
 All or some portions of this file are derived from material licensed
 to the University of California by American Telephone and Telegraph
@@ -2704,6 +2739,33 @@
 
 -------------------------------------------------------------------
 
+Copyright (c) 1997 Todd C. Miller <Todd.Miller@courtesan.com>
+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 ``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, 1998 The NetBSD Foundation, Inc.
 All rights reserved.
 
@@ -3378,6 +3440,32 @@
 
 -------------------------------------------------------------------
 
+Copyright (c) 2002 Tim J. Robbins.
+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) 2002 Todd C. Miller <Todd.Miller@courtesan.com>
 
 Permission to use, copy, modify, and distribute this software for any
@@ -3398,6 +3486,84 @@
 
 -------------------------------------------------------------------
 
+Copyright (c) 2002, 2003 Tim J. Robbins.
+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) 2002-2004 Tim J. Robbins
+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) 2002-2004 Tim J. Robbins.
+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) 2003 Constantin S. Svintsoff <kostik@iclub.nsu.ru>
 
 Redistribution and use in source and binary forms, with or without
@@ -4057,6 +4223,32 @@
 
 -------------------------------------------------------------------
 
+Copyright (c) 2011 David Chisnall
+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) 2011 Intel Corporation
 All rights reserved.
 
@@ -4421,6 +4613,32 @@
 
 -------------------------------------------------------------------
 
+Copyright (c)1999, 2000, 2001 Citrus 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:
+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)2001 Citrus Project,
 All rights reserved.
 
diff --git a/libc/arch-common/bionic/atexit.h b/libc/arch-common/bionic/atexit.h
index 16ae7aa..90aa030 100644
--- a/libc/arch-common/bionic/atexit.h
+++ b/libc/arch-common/bionic/atexit.h
@@ -26,11 +26,20 @@
  * SUCH DAMAGE.
  */
 
+#include <stddef.h>
+
 extern void* __dso_handle;
 
 extern int __cxa_atexit(void (*)(void*), void*, void*);
 
 __attribute__ ((visibility ("hidden")))
+void __atexit_handler_wrapper(void* func) {
+  if (func != NULL) {
+    (*(void (*)(void))func)();
+  }
+}
+
+__attribute__ ((visibility ("hidden")))
 int atexit(void (*func)(void)) {
-  return (__cxa_atexit((void (*)(void*)) func, (void*) 0, &__dso_handle));
+  return (__cxa_atexit(&__atexit_handler_wrapper, func, &__dso_handle));
 }
diff --git a/libc/bionic/libc_logging.cpp b/libc/bionic/libc_logging.cpp
index c9c5d28..f15abbe 100644
--- a/libc/bionic/libc_logging.cpp
+++ b/libc/bionic/libc_logging.cpp
@@ -614,7 +614,7 @@
   __libc_fatal("FORTIFY_SOURCE: %s. Calling abort().", msg);
 }
 
-static void __libc_fatal(const char* tag, const char* format, va_list args) {
+static void __libc_fatal(const char* format, va_list args) {
   char msg[1024];
   BufferOutputStream os(msg, sizeof(msg));
   out_vformat(os, format, args);
@@ -622,50 +622,53 @@
   // TODO: log to stderr for the benefit of "adb shell" users.
 
   // Log to the log for the benefit of regular app developers (whose stdout and stderr are closed).
-  __libc_write_log(ANDROID_LOG_FATAL, tag, msg);
+  __libc_write_log(ANDROID_LOG_FATAL, "libc", msg);
 
-  __libc_set_abort_message(msg);
+  __android_set_abort_message(msg);
 }
 
 void __libc_fatal_no_abort(const char* format, ...) {
   va_list args;
   va_start(args, format);
-  __libc_fatal("libc", format, args);
+  __libc_fatal(format, args);
   va_end(args);
 }
 
 void __libc_fatal(const char* format, ...) {
   va_list args;
   va_start(args, format);
-  __libc_fatal("libc", format, args);
+  __libc_fatal(format, args);
   va_end(args);
   abort();
 }
 
-// This is used by liblog to implement LOG_ALWAYS_FATAL and LOG_ALWAYS_FATAL_IF.
-void __android_fatal(const char* tag, const char* format, ...) {
-  va_list args;
-  va_start(args, format);
-  __libc_fatal(tag, format, args);
-  va_end(args);
-  abort();
-}
+void __android_set_abort_message(const char* msg) {
+  ScopedPthreadMutexLocker locker(&gAbortMsgLock);
 
-void __libc_set_abort_message(const char* msg) {
+  if (__abort_message_ptr == NULL) {
+    // We must have crashed _very_ early.
+    return;
+  }
+
+  if (*__abort_message_ptr != NULL) {
+    // We already have an abort message.
+    // Assume that the first crash is the one most worth reporting.
+    return;
+  }
+
   size_t size = sizeof(abort_msg_t) + strlen(msg) + 1;
   void* map = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE, -1, 0);
   if (map == MAP_FAILED) {
     return;
   }
 
-  if (__abort_message_ptr != NULL) {
-    ScopedPthreadMutexLocker locker(&gAbortMsgLock);
-    if (*__abort_message_ptr != NULL) {
-      munmap(*__abort_message_ptr, (*__abort_message_ptr)->size);
-    }
-    abort_msg_t* new_abort_message = reinterpret_cast<abort_msg_t*>(map);
-    new_abort_message->size = size;
-    strcpy(new_abort_message->msg, msg);
-    *__abort_message_ptr = new_abort_message;
+  // TODO: if we stick to the current "one-shot" scheme, we can remove this code and
+  // stop storing the size.
+  if (*__abort_message_ptr != NULL) {
+    munmap(*__abort_message_ptr, (*__abort_message_ptr)->size);
   }
+  abort_msg_t* new_abort_message = reinterpret_cast<abort_msg_t*>(map);
+  new_abort_message->size = size;
+  strcpy(new_abort_message->msg, msg);
+  *__abort_message_ptr = new_abort_message;
 }
diff --git a/libc/bionic/wctype.cpp b/libc/bionic/wctype.cpp
index 4fd590a..673402d 100644
--- a/libc/bionic/wctype.cpp
+++ b/libc/bionic/wctype.cpp
@@ -31,7 +31,7 @@
 #include <string.h>
 #include <wchar.h>
 
-// TODO: these only work for the ASCII range; rewrite to dlsym icu4c?
+// TODO: these only work for the ASCII range; rewrite to dlsym icu4c? http://b/14499654
 
 int iswalnum(wint_t wc) { return isalnum(wc); }
 int iswalpha(wint_t wc) { return isalpha(wc); }
@@ -48,18 +48,18 @@
 
 int iswctype(wint_t wc, wctype_t char_class) {
   switch (char_class) {
-    case WC_TYPE_ALNUM: return isalnum(wc);
-    case WC_TYPE_ALPHA: return isalpha(wc);
-    case WC_TYPE_BLANK: return isblank(wc);
-    case WC_TYPE_CNTRL: return iscntrl(wc);
-    case WC_TYPE_DIGIT: return isdigit(wc);
-    case WC_TYPE_GRAPH: return isgraph(wc);
-    case WC_TYPE_LOWER: return islower(wc);
-    case WC_TYPE_PRINT: return isprint(wc);
-    case WC_TYPE_PUNCT: return ispunct(wc);
-    case WC_TYPE_SPACE: return isspace(wc);
-    case WC_TYPE_UPPER: return isupper(wc);
-    case WC_TYPE_XDIGIT: return isxdigit(wc);
+    case WC_TYPE_ALNUM: return iswalnum(wc);
+    case WC_TYPE_ALPHA: return iswalpha(wc);
+    case WC_TYPE_BLANK: return iswblank(wc);
+    case WC_TYPE_CNTRL: return iswcntrl(wc);
+    case WC_TYPE_DIGIT: return iswdigit(wc);
+    case WC_TYPE_GRAPH: return iswgraph(wc);
+    case WC_TYPE_LOWER: return iswlower(wc);
+    case WC_TYPE_PRINT: return iswprint(wc);
+    case WC_TYPE_PUNCT: return iswpunct(wc);
+    case WC_TYPE_SPACE: return iswspace(wc);
+    case WC_TYPE_UPPER: return iswupper(wc);
+    case WC_TYPE_XDIGIT: return iswxdigit(wc);
     default: return 0;
   }
 }
@@ -84,8 +84,3 @@
 int wcwidth(wchar_t wc) {
   return (wc > 0);
 }
-
-// TODO: implement wcsftime.
-size_t wcsftime(wchar_t* wcs, size_t maxsize, const wchar_t* format,  const struct tm* timptr) {
-  abort();
-}
diff --git a/libc/dns/gethnamaddr.c b/libc/dns/gethnamaddr.c
index dbcadee..4da99b2 100644
--- a/libc/dns/gethnamaddr.c
+++ b/libc/dns/gethnamaddr.c
@@ -828,27 +828,27 @@
 
 	assert(addr != NULL);
 
-	if (af == AF_INET6 && len == IN6ADDRSZ &&
-	    (IN6_IS_ADDR_LINKLOCAL((const struct in6_addr *)(const void *)uaddr) ||
-	     IN6_IS_ADDR_SITELOCAL((const struct in6_addr *)(const void *)uaddr))) {
+	if (af == AF_INET6 && len == NS_IN6ADDRSZ &&
+	    (IN6_IS_ADDR_LINKLOCAL((const struct in6_addr *)addr) ||
+	     IN6_IS_ADDR_SITELOCAL((const struct in6_addr *)addr))) {
 		h_errno = HOST_NOT_FOUND;
 		return NULL;
 	}
-	if (af == AF_INET6 && len == IN6ADDRSZ &&
-	    (IN6_IS_ADDR_V4MAPPED((const struct in6_addr *)(const void *)uaddr) ||
-	     IN6_IS_ADDR_V4COMPAT((const struct in6_addr *)(const void *)uaddr))) {
+	if (af == AF_INET6 && len == NS_IN6ADDRSZ &&
+	    (IN6_IS_ADDR_V4MAPPED((const struct in6_addr *)addr) ||
+	     IN6_IS_ADDR_V4COMPAT((const struct in6_addr *)addr))) {
 		/* Unmap. */
-		addr += IN6ADDRSZ - INADDRSZ;
-		uaddr += IN6ADDRSZ - INADDRSZ;
+		uaddr += NS_IN6ADDRSZ - NS_INADDRSZ;
+		addr = uaddr;
 		af = AF_INET;
-		len = INADDRSZ;
+		len = NS_INADDRSZ;
 	}
 	switch (af) {
 	case AF_INET:
-		size = INADDRSZ;
+		size = NS_INADDRSZ;
 		break;
 	case AF_INET6:
-		size = IN6ADDRSZ;
+		size = NS_IN6ADDRSZ;
 		break;
 	default:
 		errno = EAFNOSUPPORT;
diff --git a/libc/include/pthread.h b/libc/include/pthread.h
index 3f59b91..7b8de81 100644
--- a/libc/include/pthread.h
+++ b/libc/include/pthread.h
@@ -91,7 +91,7 @@
 typedef long pthread_mutexattr_t;
 typedef long pthread_condattr_t;
 
-typedef int pthread_rwlockattr_t;
+typedef long pthread_rwlockattr_t;
 
 typedef struct {
   pthread_mutex_t lock;
diff --git a/libc/include/semaphore.h b/libc/include/semaphore.h
index 30e3123..7ae3c3a 100644
--- a/libc/include/semaphore.h
+++ b/libc/include/semaphore.h
@@ -33,10 +33,13 @@
 __BEGIN_DECLS
 
 typedef struct {
-    volatile unsigned int  count;
+  volatile unsigned int count;
+#ifdef __LP64__
+  int __reserved[3];
+#endif
 } sem_t;
 
-#define  SEM_FAILED  NULL
+#define SEM_FAILED NULL
 
 extern int sem_init(sem_t *sem, int pshared, unsigned int value);
 
diff --git a/libc/include/sys/epoll.h b/libc/include/sys/epoll.h
index c06a081..4a5a37c 100644
--- a/libc/include/sys/epoll.h
+++ b/libc/include/sys/epoll.h
@@ -67,7 +67,11 @@
 struct epoll_event {
   uint32_t events;
   epoll_data_t data;
-};
+}
+#ifdef __x86_64__
+__packed
+#endif
+;
 
 int epoll_create(int);
 int epoll_create1(int);
diff --git a/libc/include/sys/types.h b/libc/include/sys/types.h
index dc847d2..9a76ad2 100644
--- a/libc/include/sys/types.h
+++ b/libc/include/sys/types.h
@@ -63,7 +63,7 @@
 typedef __kernel_key_t __key_t;
 typedef __key_t key_t;
 
-typedef uint32_t __ino_t;
+typedef __kernel_ino_t __ino_t;
 typedef __ino_t ino_t;
 
 typedef uint32_t __nlink_t;
@@ -72,9 +72,10 @@
 typedef void* __timer_t;
 typedef __timer_t timer_t;
 
-typedef int32_t __suseconds_t;
+typedef __kernel_suseconds_t __suseconds_t;
 typedef __suseconds_t suseconds_t;
 
+/* useconds_t is 32-bit on both LP32 and LP64. */
 typedef uint32_t __useconds_t;
 typedef __useconds_t useconds_t;
 
diff --git a/libc/include/time64.h b/libc/include/time64.h
index b4f1280..905669d 100644
--- a/libc/include/time64.h
+++ b/libc/include/time64.h
@@ -33,12 +33,7 @@
 
 #if defined(__LP64__)
 
-/* TODO: remove this when external/chromium_org is fixed. */
-#define time64_t time_t
-#define gmtime64_r gmtime_r
-#define localtime64_r localtime_r
-#define mktime64 mktime
-#define timegm64 timegm
+#error Your time_t is already 64-bit.
 
 #else
 
diff --git a/libc/include/utmp.h b/libc/include/utmp.h
index ffd3c92..d764227 100644
--- a/libc/include/utmp.h
+++ b/libc/include/utmp.h
@@ -36,9 +36,15 @@
 #define _PATH_WTMP      "/var/log/wtmp"
 #define _PATH_LASTLOG   "/var/log/lastlog"
 
-#define	UT_NAMESIZE	8
-#define	UT_LINESIZE	8
-#define	UT_HOSTSIZE	16
+#ifdef __LP64__
+#define UT_NAMESIZE 32
+#define UT_LINESIZE 32
+#define UT_HOSTSIZE 256
+#else
+#define UT_NAMESIZE 8
+#define UT_LINESIZE 8
+#define UT_HOSTSIZE 16
+#endif
 
 #define USER_PROCESS 7
 
diff --git a/libc/private/libc_logging.h b/libc/private/libc_logging.h
index 54e050a..822f232 100644
--- a/libc/private/libc_logging.h
+++ b/libc/private/libc_logging.h
@@ -68,14 +68,13 @@
   char msg[0];
 };
 
-__LIBC_HIDDEN__ void __libc_set_abort_message(const char* msg);
+void __android_set_abort_message(const char* msg);
 
 //
 // Formats a message to the log (priority 'fatal'), then aborts.
 //
 
 __LIBC_HIDDEN__ __noreturn void __libc_fatal(const char* format, ...) __printflike(1, 2);
-__noreturn void __android_fatal(const char* tag, const char* format, ...) __printflike(2, 3);
 
 //
 // Formats a message to the log (priority 'fatal'), but doesn't abort.
diff --git a/libc/stdio/fileext.h b/libc/stdio/fileext.h
index fa6fed6..1f2a3a3 100644
--- a/libc/stdio/fileext.h
+++ b/libc/stdio/fileext.h
@@ -29,6 +29,9 @@
  * $Citrus$
  */
 
+#ifndef _FILEEXT_H_
+#define _FILEEXT_H_
+
 #include <pthread.h>
 
 /*
@@ -59,3 +62,5 @@
 	(f)->_ext._base = (unsigned char *)(fext); \
 	_FILEEXT_INIT(f); \
 } while (0)
+
+#endif /* _FILEEXT_H_ */
diff --git a/libc/stdio/local.h b/libc/stdio/local.h
index 5fb2292..907fd21 100644
--- a/libc/stdio/local.h
+++ b/libc/stdio/local.h
@@ -102,6 +102,7 @@
 #define FLOATING_POINT
 #define PRINTF_WIDE_CHAR
 #define SCANF_WIDE_CHAR
+#define NO_PRINTF_PERCENT_N
 
 /* OpenBSD exposes these in <stdio.h>, but we only want them exposed to the implementation. */
 __BEGIN_DECLS
diff --git a/libc/stdlib/atexit.c b/libc/stdlib/atexit.c
index 4e14434..b051e22 100644
--- a/libc/stdlib/atexit.c
+++ b/libc/stdlib/atexit.c
@@ -41,11 +41,52 @@
 struct atexit *__atexit;
 
 /*
+ * TODO: Read this before upstreaming:
+ *
+ * As of Apr 2014 there is a bug regaring function type detection logic in
+ * Free/Open/NetBSD implementations of __cxa_finalize().
+ *
+ * What it is about:
+ * First of all there are two kind of atexit handlers:
+ *  1) void handler(void) - this is the regular type
+ *     available for to user via atexit(.) function call.
+ *
+ *  2) void internal_handler(void*) - this is the type
+ *     __cxa_atexit() function expects. This handler is used
+ *     by C++ compiler to register static destructor calls.
+ *     Note that calling this function as the handler of type (1)
+ *     results in incorrect this pointer in static d-tors.
+ *
+ * What is wrong with BSD implementations:
+ *
+ *  They use dso argument to identify the handler type. The problem
+ *  with it is dso is also used to identify the handlers associated
+ *  with particular dynamic library and allow __cxa_finalize to call correct
+ *  set of functions on dlclose(). And it cannot identify both.
+ *
+ * What is correct way to identify function type?
+ *
+ *  Consider this:
+ *  1. __cxa_finalize and __cxa_atexit are part of libc and do not have access to hidden
+ *     &__dso_handle.
+ *  2. __cxa_atexit has only 3 arguments: function pointer, function argument, dso.
+ *     none of them can be reliably used to pass information about handler type.
+ *  3. following http://www.codesourcery.com/cxx-abi/abi.html#dso-dtor (3.3.5.3 - B)
+ *     translation of user atexit -> __cxa_atexit(f, NULL, NULL) results in crashes
+ *     on exit() after dlclose() of a library with an atexit() call.
+ *
+ *  One way to resolve this is to always call second form of handler, which will
+ *  result in storing unused argument in register/stack depending on architecture
+ *  and should not present any problems.
+ *
+ *  Another way is to make them dso-local in one way or the other.
+ */
+
+/*
  * Function pointers are stored in a linked list of pages. The list
  * is initially empty, and pages are allocated on demand. The first
  * function pointer in the first allocated page (the last one in
  * the linked list) was reserved for the cleanup function.
- * TODO: switch to the regular FreeBSD/NetBSD atexit implementation.
  *
  * Outside the following functions, all pages are mprotect()'ed
  * to prevent unintentional/malicious corruption.
@@ -94,7 +135,7 @@
 			__atexit_invalid = 0;
 	}
 	fnp = &p->fns[p->ind++];
-	fnp->fn_ptr.cxa_func = func;
+	fnp->cxa_func = func;
 	fnp->fn_arg = arg;
 	fnp->fn_dso = dso;
 	if (mprotect(p, pgsize, PROT_READ))
@@ -113,57 +154,59 @@
 void
 __cxa_finalize(void *dso)
 {
-	struct atexit *p, *q;
+	struct atexit *p, *q, *original_atexit;
 	struct atexit_fn fn;
-	int n, pgsize = getpagesize();
+	int n, pgsize = getpagesize(), original_ind;
 	static int call_depth;
 
 	if (__atexit_invalid)
 		return;
-
 	_ATEXIT_LOCK();
 	call_depth++;
 
-	for (p = __atexit; p != NULL; p = p->next) {
-		for (n = p->ind; --n >= 0;) {
-			if (p->fns[n].fn_ptr.cxa_func == NULL)
-				continue;	/* already called */
-			if (dso != NULL && dso != p->fns[n].fn_dso)
-				continue;	/* wrong DSO */
-
+	p = original_atexit = __atexit;
+	n = original_ind = p != NULL ? p->ind : 0;
+	while (p != NULL) {
+		if (p->fns[n].cxa_func != NULL /* not called */
+				&& (dso == NULL || dso == p->fns[n].fn_dso)) { /* correct DSO */
 			/*
 			 * Mark handler as having been already called to avoid
 			 * dupes and loops, then call the appropriate function.
 			 */
 			fn = p->fns[n];
 			if (mprotect(p, pgsize, PROT_READ | PROT_WRITE) == 0) {
-				p->fns[n].fn_ptr.cxa_func = NULL;
+				p->fns[n].cxa_func = NULL;
 				mprotect(p, pgsize, PROT_READ);
 			}
+
 			_ATEXIT_UNLOCK();
-#if ANDROID
-                        /* it looks like we should always call the function
-                         * with an argument, even if dso is not NULL. Otherwise
-                         * static destructors will not be called properly on
-                         * the ARM.
-                         */
-                        (*fn.fn_ptr.cxa_func)(fn.fn_arg);
-#else /* !ANDROID */
-			if (dso != NULL)
-				(*fn.fn_ptr.cxa_func)(fn.fn_arg);
-			else
-				(*fn.fn_ptr.std_func)();
-#endif /* !ANDROID */
+			(*fn.cxa_func)(fn.fn_arg);
 			_ATEXIT_LOCK();
+			// check for new atexit handlers
+			if ((__atexit->ind != original_ind) || (__atexit != original_atexit)) {
+				// need to restart now to preserve correct
+				// call order - LIFO
+				p = original_atexit = __atexit;
+				n = original_ind = p->ind;
+				continue;
+			}
+		}
+		if (n == 0) {
+			p = p->next;
+			n = p != NULL ? p->ind : 0;
+		} else {
+			--n;
 		}
 	}
 
+	--call_depth;
+
 	/*
 	 * If called via exit(), unmap the pages since we have now run
 	 * all the handlers.  We defer this until calldepth == 0 so that
 	 * we don't unmap things prematurely if called recursively.
 	 */
-	if (dso == NULL && --call_depth == 0) {
+	if (dso == NULL && call_depth == 0) {
 		for (p = __atexit; p != NULL; ) {
 			q = p;
 			p = p->next;
diff --git a/libc/stdlib/atexit.h b/libc/stdlib/atexit.h
index 4b3e5ab..2e88ad6 100644
--- a/libc/stdlib/atexit.h
+++ b/libc/stdlib/atexit.h
@@ -37,10 +37,7 @@
 	int ind;			/* next index in this table */
 	int max;			/* max entries >= ATEXIT_SIZE */
 	struct atexit_fn {
-		union {
-			void (*std_func)(void);
-			void (*cxa_func)(void *);
-		} fn_ptr;
+		void (*cxa_func)(void *);
 		void *fn_arg;		/* argument for CXA callback */
 		void *fn_dso;		/* shared module handle */
 	} fns[1];			/* the table itself */
diff --git a/libc/tools/generate-NOTICE.py b/libc/tools/generate-NOTICE.py
index 3fad656..6d4c761 100755
--- a/libc/tools/generate-NOTICE.py
+++ b/libc/tools/generate-NOTICE.py
@@ -55,10 +55,13 @@
             break
         if "\tcitrus Id: " in lines[i]:
             break
-        if "\t$OpenBSD: " in lines[i] or " $FreeBSD: " in lines[i] or "\t$NetBSD: " in lines[i]:
+        if "\t$Citrus: " in lines[i] or "\t$OpenBSD: " in lines[i] or " $FreeBSD: " in lines[i] or "\t$NetBSD: " in lines[i]:
             break
         if "$FreeBSD$" in lines[i] or "$Citrus$" in lines[i]:
             break
+        # OpenBSD likes to say where stuff originally came from:
+        if "Original version ID:" in lines[i]:
+            break
         i += 1
 
     end = i
diff --git a/libc/tzcode/strftime.c b/libc/tzcode/strftime.c
index 1164a13..967629d 100644
--- a/libc/tzcode/strftime.c
+++ b/libc/tzcode/strftime.c
@@ -37,7 +37,12 @@
 #include "fcntl.h"
 #include "locale.h"
 #include <ctype.h>
+#if defined(__LP64__)
+#define time64_t time_t
+#define mktime64 mktime
+#else
 #include <time64.h>
+#endif
 #include "private/bionic_time.h"  /* for strftime_tz */
 
 /* struct lc_time_T is now defined as strftime_locale
@@ -155,7 +160,7 @@
     tzset();
     warn = IN_NONE;
     p = _fmt(((format == NULL) ? "%c" : format), t, s, s + maxsize, &warn, locale);
-#if 0  /* ifndef NO_RUN_TIME_WARNINGS_ABOUT_YEAR_2000_PROBLEMS_THANK_YOU */
+#ifndef NO_RUN_TIME_WARNINGS_ABOUT_YEAR_2000_PROBLEMS_THANK_YOU
     if (warn != IN_NONE && getenv(YEAR_2000_NAME) != NULL) {
         (void) fprintf(stderr, "\n");
         if (format == NULL)
diff --git a/libc/upstream-openbsd/android/include/openbsd-compat.h b/libc/upstream-openbsd/android/include/openbsd-compat.h
index b55f390..bacd1d7 100644
--- a/libc/upstream-openbsd/android/include/openbsd-compat.h
+++ b/libc/upstream-openbsd/android/include/openbsd-compat.h
@@ -17,7 +17,6 @@
 #ifndef _BIONIC_OPENBSD_COMPAT_H_included
 #define _BIONIC_OPENBSD_COMPAT_H_included
 
-#define _GNU_SOURCE
 #define __USE_BSD
 
 /* OpenBSD's <ctype.h> uses these names, which conflicted with stlport.
diff --git a/libc/upstream-openbsd/lib/libc/gen/fnmatch.c b/libc/upstream-openbsd/lib/libc/gen/fnmatch.c
index c3d1a3c..2c860f7 100644
--- a/libc/upstream-openbsd/lib/libc/gen/fnmatch.c
+++ b/libc/upstream-openbsd/lib/libc/gen/fnmatch.c
@@ -1,4 +1,4 @@
-/*	$OpenBSD: fnmatch.c,v 1.16 2011/12/06 11:47:46 stsp Exp $	*/
+/*	$OpenBSD: fnmatch.c,v 1.17 2013/11/24 23:51:29 deraadt Exp $	*/
 
 /* Copyright (c) 2011, VMware, Inc.
  * All rights reserved.
@@ -214,10 +214,13 @@
                 /* XXX: handle locale/MBCS comparison, advance by MBCS char width */
                 if ((**string >= *startch) && (**string <= **pattern))
                     result = 0;
-                else if (nocase && (isupper(**string) || isupper(*startch)
-                                                      || isupper(**pattern))
-                            && (tolower(**string) >= tolower(*startch)) 
-                            && (tolower(**string) <= tolower(**pattern)))
+                else if (nocase && (isupper((unsigned char)**string) ||
+			    isupper((unsigned char)*startch) ||
+                            isupper((unsigned char)**pattern))
+                            && (tolower((unsigned char)**string) >=
+			        tolower((unsigned char)*startch)) 
+                            && (tolower((unsigned char)**string) <=
+				tolower((unsigned char)**pattern)))
                     result = 0;
 
                 ++*pattern;
@@ -227,8 +230,10 @@
             /* XXX: handle locale/MBCS comparison, advance by MBCS char width */
             if ((**string == **pattern))
                 result = 0;
-            else if (nocase && (isupper(**string) || isupper(**pattern))
-                            && (tolower(**string) == tolower(**pattern)))
+            else if (nocase && (isupper((unsigned char)**string) ||
+			    isupper((unsigned char)**pattern))
+                            && (tolower((unsigned char)**string) ==
+				tolower((unsigned char)**pattern)))
                 result = 0;
 
             ++*pattern;
@@ -254,8 +259,10 @@
     /* XXX: handle locale/MBCS comparison, advance by the MBCS char width */
     if (**string == **pattern)
         result = 0;
-    else if (nocase && (isupper(**string) || isupper(**pattern))
-                    && (tolower(**string) == tolower(**pattern)))
+    else if (nocase && (isupper((unsigned char)**string) ||
+		    isupper((unsigned char)**pattern))
+                    && (tolower((unsigned char)**string) ==
+			tolower((unsigned char)**pattern)))
         result = 0;
 
     /* Refuse to advance over trailing slash or nulls
diff --git a/libc/upstream-openbsd/lib/libc/gen/getprogname.c b/libc/upstream-openbsd/lib/libc/gen/getprogname.c
index 1cf498c88..17046ab 100644
--- a/libc/upstream-openbsd/lib/libc/gen/getprogname.c
+++ b/libc/upstream-openbsd/lib/libc/gen/getprogname.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: getprogname.c,v 1.2 2013/05/31 21:19:01 tedu Exp $ */
+/* $OpenBSD: getprogname.c,v 1.3 2013/11/12 06:09:48 deraadt Exp $ */
 /*
  * Copyright (c) 2013 Antoine Jacoutot <ajacoutot@openbsd.org>
  *
@@ -15,6 +15,8 @@
  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  */
 
+#include <stdlib.h>
+
 extern const char *__progname;
 
 const char *
diff --git a/libc/upstream-openbsd/lib/libc/gen/setprogname.c b/libc/upstream-openbsd/lib/libc/gen/setprogname.c
index 18b2ce0..089a15a 100644
--- a/libc/upstream-openbsd/lib/libc/gen/setprogname.c
+++ b/libc/upstream-openbsd/lib/libc/gen/setprogname.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: setprogname.c,v 1.3 2013/06/01 01:43:43 tedu Exp $ */
+/* $OpenBSD: setprogname.c,v 1.4 2013/11/12 06:09:48 deraadt Exp $ */
 /*
  * Copyright (c) 2013 Antoine Jacoutot <ajacoutot@openbsd.org>
  *
@@ -16,6 +16,7 @@
  */
 
 #include <string.h>
+#include <stdlib.h>
 
 extern const char *__progname;
 
diff --git a/libc/upstream-openbsd/lib/libc/stdio/fgetln.c b/libc/upstream-openbsd/lib/libc/stdio/fgetln.c
index 539b3c0..d0c0809 100644
--- a/libc/upstream-openbsd/lib/libc/stdio/fgetln.c
+++ b/libc/upstream-openbsd/lib/libc/stdio/fgetln.c
@@ -1,4 +1,4 @@
-/*	$OpenBSD: fgetln.c,v 1.11 2009/11/21 09:53:44 guenther Exp $ */
+/*	$OpenBSD: fgetln.c,v 1.12 2013/11/12 07:04:06 deraadt Exp $ */
 /*-
  * Copyright (c) 1990, 1993
  *	The Regents of the University of California.  All rights reserved.
@@ -43,7 +43,7 @@
  * so we add 1 here.
 #endif
  */
-int
+static int
 __slbexpand(FILE *fp, size_t newsize)
 {
 	void *p;
diff --git a/libc/upstream-openbsd/lib/libc/stdio/fputws.c b/libc/upstream-openbsd/lib/libc/stdio/fputws.c
index c4c2d8e..108846e 100644
--- a/libc/upstream-openbsd/lib/libc/stdio/fputws.c
+++ b/libc/upstream-openbsd/lib/libc/stdio/fputws.c
@@ -1,4 +1,4 @@
-/*	$OpenBSD: fputws.c,v 1.6 2013/04/17 17:40:35 tedu Exp $	*/
+/*	$OpenBSD: fputws.c,v 1.7 2013/11/12 07:04:35 deraadt Exp $	*/
 /* $NetBSD: fputws.c,v 1.1 2003/03/07 07:11:37 tshiozak Exp $ */
 
 /*-
@@ -34,8 +34,7 @@
 #include <stdio.h>
 #include <wchar.h>
 #include "local.h"
-
-wint_t __fputwc_unlock(wchar_t wc, FILE *fp);
+#include "fvwrite.h"
 
 int
 fputws(ws, fp)
diff --git a/libc/upstream-openbsd/lib/libc/stdio/fread.c b/libc/upstream-openbsd/lib/libc/stdio/fread.c
index 430865d..8a592f6 100644
--- a/libc/upstream-openbsd/lib/libc/stdio/fread.c
+++ b/libc/upstream-openbsd/lib/libc/stdio/fread.c
@@ -1,4 +1,4 @@
-/*	$OpenBSD: fread.c,v 1.11 2009/11/21 09:53:44 guenther Exp $ */
+/*	$OpenBSD: fread.c,v 1.12 2014/05/01 16:40:36 deraadt Exp $ */
 /*-
  * Copyright (c) 1990, 1993
  *	The Regents of the University of California.  All rights reserved.
@@ -33,8 +33,12 @@
 
 #include <stdio.h>
 #include <string.h>
+#include <stdint.h>
+#include <errno.h>
 #include "local.h"
 
+#define MUL_NO_OVERFLOW	(1UL << (sizeof(size_t) * 4))
+
 size_t
 fread(void *buf, size_t size, size_t count, FILE *fp)
 {
@@ -44,6 +48,16 @@
 	size_t total;
 
 	/*
+	 * Extension:  Catch integer overflow
+	 */
+	if ((size >= MUL_NO_OVERFLOW || count >= MUL_NO_OVERFLOW) &&
+	    size > 0 && SIZE_MAX / size < count) {
+		errno = EOVERFLOW;
+		fp->_flags |= __SERR;
+		return (0);
+	}
+
+	/*
 	 * ANSI and SUSv2 require a return value of 0 if size or count are 0.
 	 */
 	if ((resid = count * size) == 0)
diff --git a/libc/stdio/fvwrite.h b/libc/upstream-openbsd/lib/libc/stdio/fvwrite.h
similarity index 93%
rename from libc/stdio/fvwrite.h
rename to libc/upstream-openbsd/lib/libc/stdio/fvwrite.h
index 96f65de..d3a309b 100644
--- a/libc/stdio/fvwrite.h
+++ b/libc/upstream-openbsd/lib/libc/stdio/fvwrite.h
@@ -1,4 +1,4 @@
-/*	$OpenBSD: fvwrite.h,v 1.5 2003/06/02 20:18:37 millert Exp $	*/
+/*	$OpenBSD: fvwrite.h,v 1.6 2013/11/12 07:04:35 deraadt Exp $	*/
 
 /*-
  * Copyright (c) 1990, 1993
@@ -36,7 +36,7 @@
  * I/O descriptors for __sfvwrite().
  */
 struct __siov {
-	const void	*iov_base;
+	void	*iov_base;
 	size_t	iov_len;
 };
 struct __suio {
@@ -46,3 +46,4 @@
 };
 
 extern int __sfvwrite(FILE *, struct __suio *);
+wint_t __fputwc_unlock(wchar_t wc, FILE *fp);
diff --git a/libc/upstream-freebsd/lib/libc/stdio/fwrite.c b/libc/upstream-openbsd/lib/libc/stdio/fwrite.c
similarity index 74%
rename from libc/upstream-freebsd/lib/libc/stdio/fwrite.c
rename to libc/upstream-openbsd/lib/libc/stdio/fwrite.c
index 707d362..f0a17bf 100644
--- a/libc/upstream-freebsd/lib/libc/stdio/fwrite.c
+++ b/libc/upstream-openbsd/lib/libc/stdio/fwrite.c
@@ -1,3 +1,4 @@
+/*	$OpenBSD: fwrite.c,v 1.11 2014/05/01 16:40:36 deraadt Exp $ */
 /*-
  * Copyright (c) 1990, 1993
  *	The Regents of the University of California.  All rights reserved.
@@ -30,67 +31,58 @@
  * SUCH DAMAGE.
  */
 
-#if defined(LIBC_SCCS) && !defined(lint)
-static char sccsid[] = "@(#)fwrite.c	8.1 (Berkeley) 6/4/93";
-#endif /* LIBC_SCCS and not lint */
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-#include "namespace.h"
-#include <errno.h>
-#include <stdint.h>
 #include <stdio.h>
-#include "un-namespace.h"
+#include <stdlib.h>
+#include <stdint.h>
+#include <errno.h>
 #include "local.h"
 #include "fvwrite.h"
-#include "libc_private.h"
+
+#define MUL_NO_OVERFLOW	(1UL << (sizeof(size_t) * 4))
 
 /*
  * Write `count' objects (each size `size') from memory to the given file.
  * Return the number of whole objects written.
  */
 size_t
-fwrite(const void * __restrict buf, size_t size, size_t count, FILE * __restrict fp)
+fwrite(const void *buf, size_t size, size_t count, FILE *fp)
 {
 	size_t n;
 	struct __suio uio;
 	struct __siov iov;
+	int ret;
 
 	/*
-	 * ANSI and SUSv2 require a return value of 0 if size or count are 0.
+	 * Extension:  Catch integer overflow
 	 */
-	if ((count == 0) || (size == 0))
-		return (0);
-
-	/*
-	 * Check for integer overflow.  As an optimization, first check that
-	 * at least one of {count, size} is at least 2^16, since if both
-	 * values are less than that, their product can't possible overflow
-	 * (size_t is always at least 32 bits on FreeBSD).
-	 */
-	if (((count | size) > 0xFFFF) &&
-	    (count > SIZE_MAX / size)) {
-		errno = EINVAL;
+	if ((size >= MUL_NO_OVERFLOW || count >= MUL_NO_OVERFLOW) &&
+	    size > 0 && SIZE_MAX / size < count) {
+		errno = EOVERFLOW;
 		fp->_flags |= __SERR;
 		return (0);
 	}
 
-	n = count * size;
+	/*
+	 * ANSI and SUSv2 require a return value of 0 if size or count are 0.
+	 */
+	if ((n = count * size) == 0)
+		return (0);
 
 	iov.iov_base = (void *)buf;
 	uio.uio_resid = iov.iov_len = n;
 	uio.uio_iov = &iov;
 	uio.uio_iovcnt = 1;
 
-	FLOCKFILE(fp);
-	ORIENT(fp, -1);
 	/*
 	 * The usual case is success (__sfvwrite returns 0);
 	 * skip the divide if this happens, since divides are
 	 * generally slow and since this occurs whenever size==0.
 	 */
-	if (__sfvwrite(fp, &uio) != 0)
-	    count = (n - uio.uio_resid) / size;
+	FLOCKFILE(fp);
+	_SET_ORIENTATION(fp, -1);
+	ret = __sfvwrite(fp, &uio);
 	FUNLOCKFILE(fp);
-	return (count);
+	if (ret == 0)
+		return (count);
+	return ((n - uio.uio_resid) / size);
 }
diff --git a/libc/upstream-openbsd/lib/libc/stdio/vfprintf.c b/libc/upstream-openbsd/lib/libc/stdio/vfprintf.c
index b4f8f29..7f8ff31 100644
--- a/libc/upstream-openbsd/lib/libc/stdio/vfprintf.c
+++ b/libc/upstream-openbsd/lib/libc/stdio/vfprintf.c
@@ -1,4 +1,4 @@
-/*	$OpenBSD: vfprintf.c,v 1.63 2013/03/02 19:40:08 guenther Exp $	*/
+/*	$OpenBSD: vfprintf.c,v 1.66 2014/05/03 12:36:45 deraadt Exp $	*/
 /*-
  * Copyright (c) 1990 The Regents of the University of California.
  * All rights reserved.
@@ -216,11 +216,10 @@
 #include <locale.h>
 #include <math.h>
 #include "floatio.h"
+#include "gdtoa.h"
 
 #define	DEFPREC		6
 
-extern char *__dtoa(double, int, int, int *, int *, char **);
-extern void  __freedtoa(char *);
 static int exponent(char *, int, int);
 #endif /* FLOATING_POINT */
 
@@ -399,7 +398,7 @@
 	    flags&PTRINT ? GETARG(ptrdiff_t) : \
 	    flags&SIZEINT ? GETARG(ssize_t) : \
 	    flags&SHORTINT ? (short)GETARG(int) : \
-	    flags&CHARINT ? (__signed char)GETARG(int) : \
+	    flags&CHARINT ? (signed char)GETARG(int) : \
 	    GETARG(int)))
 #define	UARG() \
 	((uintmax_t)(flags&MAXINT ? GETARG(uintmax_t) : \
@@ -802,6 +801,7 @@
 			}
 			break;
 #endif /* FLOATING_POINT */
+#ifndef NO_PRINTF_PERCENT_N
 		case 'n':
 			if (flags & LLONGINT)
 				*GETARG(long long *) = ret;
@@ -810,7 +810,7 @@
 			else if (flags & SHORTINT)
 				*GETARG(short *) = ret;
 			else if (flags & CHARINT)
-				*GETARG(__signed char *) = ret;
+				*GETARG(signed char *) = ret;
 			else if (flags & PTRINT)
 				*GETARG(ptrdiff_t *) = ret;
 			else if (flags & SIZEINT)
@@ -820,6 +820,7 @@
 			else
 				*GETARG(int *) = ret;
 			continue;	/* no output */
+#endif /* NO_PRINTF_PERCENT_N */
 		case 'O':
 			flags |= LONGINT;
 			/*FALLTHROUGH*/
@@ -1318,6 +1319,7 @@
 				ADDTYPE(T_DOUBLE);
 			break;
 #endif /* FLOATING_POINT */
+#ifndef NO_PRINTF_PERCENT_N
 		case 'n':
 			if (flags & LLONGINT)
 				ADDTYPE(TP_LLONG);
@@ -1334,6 +1336,7 @@
 			else
 				ADDTYPE(TP_INT);
 			continue;	/* no output */
+#endif /* NO_PRINTF_PERCENT_N */
 		case 'O':
 			flags |= LONGINT;
 			/*FALLTHROUGH*/
diff --git a/libc/upstream-openbsd/lib/libc/stdio/vfscanf.c b/libc/upstream-openbsd/lib/libc/stdio/vfscanf.c
index c2996a9..abefe32 100644
--- a/libc/upstream-openbsd/lib/libc/stdio/vfscanf.c
+++ b/libc/upstream-openbsd/lib/libc/stdio/vfscanf.c
@@ -1,4 +1,4 @@
-/*	$OpenBSD: vfscanf.c,v 1.30 2013/04/17 17:40:35 tedu Exp $ */
+/*	$OpenBSD: vfscanf.c,v 1.31 2014/03/19 05:17:01 guenther Exp $ */
 /*-
  * Copyright (c) 1990, 1993
  *	The Regents of the University of California.  All rights reserved.
@@ -273,7 +273,7 @@
 			if (flags & SUPPRESS)
 				continue;
 			if (flags & SHORTSHORT)
-				*va_arg(ap, __signed char *) = nread;
+				*va_arg(ap, signed char *) = nread;
 			else if (flags & SHORT)
 				*va_arg(ap, short *) = nread;
 			else if (flags & LONG)
@@ -749,7 +749,7 @@
 				else if (flags & SHORT)
 					*va_arg(ap, short *) = res;
 				else if (flags & SHORTSHORT)
-					*va_arg(ap, __signed char *) = res;
+					*va_arg(ap, signed char *) = res;
 				else
 					*va_arg(ap, int *) = res;
 				nassigned++;
diff --git a/libc/upstream-openbsd/lib/libc/stdio/vfwprintf.c b/libc/upstream-openbsd/lib/libc/stdio/vfwprintf.c
index f76eed3..745b4d9 100644
--- a/libc/upstream-openbsd/lib/libc/stdio/vfwprintf.c
+++ b/libc/upstream-openbsd/lib/libc/stdio/vfwprintf.c
@@ -1,4 +1,4 @@
-/*	$OpenBSD: vfwprintf.c,v 1.6 2013/04/17 17:40:35 tedu Exp $ */
+/*	$OpenBSD: vfwprintf.c,v 1.10 2014/05/03 12:36:45 deraadt Exp $ */
 /*-
  * Copyright (c) 1990 The Regents of the University of California.
  * All rights reserved.
@@ -54,8 +54,6 @@
 #include "local.h"
 #include "fvwrite.h"
 
-wint_t __fputwc_unlock(wchar_t wc, FILE *fp);
-
 union arg {
 	int			intarg;
 	unsigned int		uintarg;
@@ -235,11 +233,10 @@
 #include <locale.h>
 #include <math.h>
 #include "floatio.h"
+#include "gdtoa.h"
 
 #define	DEFPREC		6
 
-extern char *__dtoa(double, int, int, int *, int *, char **);
-extern void  __freedtoa(char *);
 static int exponent(wchar_t *, int, int);
 #endif /* FLOATING_POINT */
 
@@ -392,7 +389,7 @@
 	    flags&PTRINT ? GETARG(ptrdiff_t) : \
 	    flags&SIZEINT ? GETARG(ssize_t) : \
 	    flags&SHORTINT ? (short)GETARG(int) : \
-	    flags&CHARINT ? (__signed char)GETARG(int) : \
+	    flags&CHARINT ? (signed char)GETARG(int) : \
 	    GETARG(int)))
 #define	UARG() \
 	((uintmax_t)(flags&MAXINT ? GETARG(uintmax_t) : \
@@ -787,6 +784,7 @@
 			}
 			break;
 #endif /* FLOATING_POINT */
+#ifndef NO_PRINTF_PERCENT_N
 		case 'n':
 			if (flags & LLONGINT)
 				*GETARG(long long *) = ret;
@@ -795,7 +793,7 @@
 			else if (flags & SHORTINT)
 				*GETARG(short *) = ret;
 			else if (flags & CHARINT)
-				*GETARG(__signed char *) = ret;
+				*GETARG(signed char *) = ret;
 			else if (flags & PTRINT)
 				*GETARG(ptrdiff_t *) = ret;
 			else if (flags & SIZEINT)
@@ -805,6 +803,7 @@
 			else
 				*GETARG(int *) = ret;
 			continue;	/* no output */
+#endif /* NO_PRINTF_PERCENT_N */
 		case 'O':
 			flags |= LONGINT;
 			/*FALLTHROUGH*/
@@ -1299,6 +1298,7 @@
 				ADDTYPE(T_DOUBLE);
 			break;
 #endif /* FLOATING_POINT */
+#ifndef NO_PRINTF_PERCENT_N
 		case 'n':
 			if (flags & LLONGINT)
 				ADDTYPE(TP_LLONG);
@@ -1315,6 +1315,7 @@
 			else
 				ADDTYPE(TP_INT);
 			continue;	/* no output */
+#endif /* NO_PRINTF_PERCENT_N */
 		case 'O':
 			flags |= LONGINT;
 			/*FALLTHROUGH*/
diff --git a/libc/upstream-openbsd/lib/libc/stdio/vfwscanf.c b/libc/upstream-openbsd/lib/libc/stdio/vfwscanf.c
index e5cf5e1..cbb36be 100644
--- a/libc/upstream-openbsd/lib/libc/stdio/vfwscanf.c
+++ b/libc/upstream-openbsd/lib/libc/stdio/vfwscanf.c
@@ -1,4 +1,4 @@
-/*	$OpenBSD: vfwscanf.c,v 1.2 2012/01/18 17:23:11 chl Exp $ */
+/*	$OpenBSD: vfwscanf.c,v 1.4 2014/03/19 05:17:01 guenther Exp $ */
 /*-
  * Copyright (c) 1990, 1993
  *	The Regents of the University of California.  All rights reserved.
@@ -31,7 +31,6 @@
  * SUCH DAMAGE.
  */
 
-#include <ctype.h>
 #include <inttypes.h>
 #include <limits.h>
 #include <locale.h>
@@ -300,7 +299,7 @@
 			if (flags & SUPPRESS)
 				continue;
 			if (flags & SHORTSHORT)
-				*va_arg(ap, __signed char *) = nread;
+				*va_arg(ap, signed char *) = nread;
 			else if (flags & SHORT)
 				*va_arg(ap, short *) = nread;
 			else if (flags & LONG)
@@ -324,7 +323,7 @@
 			return (EOF);
 
 		default:	/* compat */
-			if (isupper(c))
+			if (iswupper(c))
 				flags |= LONG;
 			c = CT_INT;
 			base = 10;
@@ -672,7 +671,7 @@
 				else if (flags & SHORT)
 					*va_arg(ap, short *) = res;
 				else if (flags & SHORTSHORT)
-					*va_arg(ap, __signed char *) = res;
+					*va_arg(ap, signed char *) = res;
 				else
 					*va_arg(ap, int *) = res;
 				nassigned++;
diff --git a/libc/upstream-freebsd/lib/libc/stdio/wsetup.c b/libc/upstream-openbsd/lib/libc/stdio/wsetup.c
similarity index 87%
rename from libc/upstream-freebsd/lib/libc/stdio/wsetup.c
rename to libc/upstream-openbsd/lib/libc/stdio/wsetup.c
index 70f8247..0834223 100644
--- a/libc/upstream-freebsd/lib/libc/stdio/wsetup.c
+++ b/libc/upstream-openbsd/lib/libc/stdio/wsetup.c
@@ -1,3 +1,4 @@
+/*	$OpenBSD: wsetup.c,v 1.7 2005/08/08 08:05:36 espie Exp $ */
 /*-
  * Copyright (c) 1990, 1993
  *	The Regents of the University of California.  All rights reserved.
@@ -30,13 +31,6 @@
  * SUCH DAMAGE.
  */
 
-#if defined(LIBC_SCCS) && !defined(lint)
-static char sccsid[] = "@(#)wsetup.c	8.1 (Berkeley) 6/4/93";
-#endif /* LIBC_SCCS and not lint */
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-#include <errno.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include "local.h"
@@ -44,7 +38,7 @@
 /*
  * Various output routines call wsetup to be sure it is safe to write,
  * because either _flags does not include __SWR, or _buf is NULL.
- * _wsetup returns 0 if OK to write; otherwise, it returns EOF and sets errno.
+ * _wsetup returns 0 if OK to write, nonzero otherwise.
  */
 int
 __swsetup(FILE *fp)
@@ -57,11 +51,8 @@
 	 * If we are not writing, we had better be reading and writing.
 	 */
 	if ((fp->_flags & __SWR) == 0) {
-		if ((fp->_flags & __SRW) == 0) {
-			errno = EBADF;
-			fp->_flags |= __SERR;
+		if ((fp->_flags & __SRW) == 0)
 			return (EOF);
-		}
 		if (fp->_flags & __SRD) {
 			/* clobber any ungetc data */
 			if (HASUB(fp))
@@ -76,8 +67,11 @@
 	/*
 	 * Make a buffer if necessary, then set _w.
 	 */
-	if (fp->_bf._base == NULL)
+	if (fp->_bf._base == NULL) {
+		if ((fp->_flags & (__SSTR | __SALC)) == __SSTR)
+			return (EOF);
 		__smakebuf(fp);
+	}
 	if (fp->_flags & __SLBF) {
 		/*
 		 * It is line buffered, so make _lbfsize be -_bufsize
diff --git a/libc/upstream-openbsd/lib/libc/string/strsep.c b/libc/upstream-openbsd/lib/libc/string/strsep.c
index bcca681..2ffc4b4 100644
--- a/libc/upstream-openbsd/lib/libc/string/strsep.c
+++ b/libc/upstream-openbsd/lib/libc/string/strsep.c
@@ -1,4 +1,4 @@
-/*	$OpenBSD: strsep.c,v 1.6 2005/08/08 08:05:37 espie Exp $	*/
+/*	$OpenBSD: strsep.c,v 1.7 2014/02/05 20:42:32 stsp Exp $	*/
 
 /*-
  * Copyright (c) 1990, 1993
@@ -30,7 +30,6 @@
  */
 
 #include <string.h>
-#include <stdio.h>
 
 /*
  * Get next token from string *stringp, where tokens are possibly-empty
diff --git a/libc/upstream-openbsd/lib/libc/time/wcsftime.c b/libc/upstream-openbsd/lib/libc/time/wcsftime.c
new file mode 100644
index 0000000..21ccac7
--- /dev/null
+++ b/libc/upstream-openbsd/lib/libc/time/wcsftime.c
@@ -0,0 +1,555 @@
+/*	$OpenBSD: wcsftime.c,v 1.3 2014/05/06 15:49:45 tedu Exp $ */
+#include "private.h"
+
+/*
+** Based on the UCB version with the ID appearing below.
+** This is ANSIish only when "multibyte character == plain character".
+**
+** Copyright (c) 1989, 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 "tzfile.h"
+#include "fcntl.h"
+#include <locale.h>
+#include <wchar.h>
+
+struct lc_time_T {
+	const wchar_t *	mon[MONSPERYEAR];
+	const wchar_t *	month[MONSPERYEAR];
+	const wchar_t *	wday[DAYSPERWEEK];
+	const wchar_t *	weekday[DAYSPERWEEK];
+	const wchar_t *	X_fmt;
+	const wchar_t *	x_fmt;
+	const wchar_t *	c_fmt;
+	const wchar_t *	am;
+	const wchar_t *	pm;
+	const wchar_t *	date_fmt;
+};
+
+#define Locale	(&C_time_locale)
+
+static const struct lc_time_T	C_time_locale = {
+	{
+		L"Jan", L"Feb", L"Mar", L"Apr", L"May", L"Jun",
+		L"Jul", L"Aug", L"Sep", L"Oct", L"Nov", L"Dec"
+	}, {
+		L"January", L"February", L"March", L"April", L"May", L"June",
+		L"July", L"August", L"September", L"October", L"November", 
+		L"December"
+	}, {
+		L"Sun", L"Mon", L"Tue", L"Wed",
+		L"Thu", L"Fri", L"Sat"
+	}, {
+		L"Sunday", L"Monday", L"Tuesday", L"Wednesday",
+		L"Thursday", L"Friday", L"Saturday"
+	},
+
+	/* X_fmt */
+	L"%H:%M:%S",
+
+	/*
+	** x_fmt
+	** C99 requires this format.
+	** Using just numbers (as here) makes Quakers happier;
+	** it's also compatible with SVR4.
+	*/
+	L"%m/%d/%y",
+
+	/*
+	** c_fmt
+	** C99 requires this format.
+	** Previously this code used "%D %X", but we now conform to C99.
+	** Note that
+	**	"%a %b %d %H:%M:%S %Y"
+	** is used by Solaris 2.3.
+	*/
+	L"%a %b %e %T %Y",
+
+	/* am */
+	L"AM",
+
+	/* pm */
+	L"PM",
+
+	/* date_fmt */
+	L"%a %b %e %H:%M:%S %Z %Y"
+};
+
+#define UNKNOWN L"?"
+static wchar_t *	_add(const wchar_t *, wchar_t *, const wchar_t *);
+static wchar_t *	_sadd(const char *, wchar_t *, const wchar_t *);
+static wchar_t *	_conv(int, const wchar_t *, wchar_t *, const wchar_t *);
+static wchar_t *	_fmt(const wchar_t *, const struct tm *, wchar_t *, const wchar_t *,
+			int *);
+static wchar_t *	_yconv(int, int, int, int, wchar_t *, const wchar_t *);
+
+extern char *	tzname[];
+
+#define IN_NONE	0
+#define IN_SOME	1
+#define IN_THIS	2
+#define IN_ALL	3
+
+size_t
+wcsftime(wchar_t *__restrict s, size_t maxsize, 
+    const wchar_t *__restrict format, const struct tm *__restrict t)
+{
+	wchar_t *p;
+	int	warn;
+
+	tzset();
+	warn = IN_NONE;
+	p = _fmt(((format == NULL) ? L"%c" : format), t, s, s + maxsize, &warn);
+	if (p == s + maxsize) {
+		if (maxsize > 0)
+			s[maxsize - 1] = '\0';
+		return 0;
+	}
+	*p = L'\0';
+	return p - s;
+}
+
+static wchar_t *
+_fmt(const wchar_t *format, const struct tm *t, wchar_t *pt, 
+    const wchar_t *ptlim, int *warnp)
+{
+	for ( ; *format; ++format) {
+		if (*format != L'%') {
+			if (pt == ptlim)
+				break;
+			*pt++ = *format;
+			continue;
+		}
+label:
+		switch (*++format) {
+		case '\0':
+			--format;
+			break;
+		case 'A':
+			pt = _add((t->tm_wday < 0 ||
+				t->tm_wday >= DAYSPERWEEK) ?
+				UNKNOWN : Locale->weekday[t->tm_wday],
+				pt, ptlim);
+			continue;
+		case 'a':
+			pt = _add((t->tm_wday < 0 ||
+				t->tm_wday >= DAYSPERWEEK) ?
+				UNKNOWN : Locale->wday[t->tm_wday],
+				pt, ptlim);
+			continue;
+		case 'B':
+			pt = _add((t->tm_mon < 0 ||
+				t->tm_mon >= MONSPERYEAR) ?
+				UNKNOWN : Locale->month[t->tm_mon],
+				pt, ptlim);
+			continue;
+		case 'b':
+		case 'h':
+			pt = _add((t->tm_mon < 0 ||
+				t->tm_mon >= MONSPERYEAR) ?
+				UNKNOWN : Locale->mon[t->tm_mon],
+				pt, ptlim);
+			continue;
+		case 'C':
+			/*
+			** %C used to do a...
+			**	_fmt("%a %b %e %X %Y", t);
+			** ...whereas now POSIX 1003.2 calls for
+			** something completely different.
+			** (ado, 1993-05-24)
+			*/
+			pt = _yconv(t->tm_year, TM_YEAR_BASE, 1, 0,
+				pt, ptlim);
+			continue;
+		case 'c':
+			{
+			int warn2 = IN_SOME;
+
+			pt = _fmt(Locale->c_fmt, t, pt, ptlim, &warn2);
+			if (warn2 == IN_ALL)
+				warn2 = IN_THIS;
+			if (warn2 > *warnp)
+				*warnp = warn2;
+			}
+			continue;
+		case 'D':
+			pt = _fmt(L"%m/%d/%y", t, pt, ptlim, warnp);
+			continue;
+		case 'd':
+			pt = _conv(t->tm_mday, L"%02d", pt, ptlim);
+			continue;
+		case 'E':
+		case 'O':
+			/*
+			** C99 locale modifiers.
+			** The sequences
+			**	%Ec %EC %Ex %EX %Ey %EY
+			**	%Od %oe %OH %OI %Om %OM
+			**	%OS %Ou %OU %OV %Ow %OW %Oy
+			** are supposed to provide alternate
+			** representations.
+			*/
+			goto label;
+		case 'e':
+			pt = _conv(t->tm_mday, L"%2d", pt, ptlim);
+			continue;
+		case 'F':
+			pt = _fmt(L"%Y-%m-%d", t, pt, ptlim, warnp);
+			continue;
+		case 'H':
+			pt = _conv(t->tm_hour, L"%02d", pt, ptlim);
+			continue;
+		case 'I':
+			pt = _conv((t->tm_hour % 12) ?
+				(t->tm_hour % 12) : 12,
+				L"%02d", pt, ptlim);
+			continue;
+		case 'j':
+			pt = _conv(t->tm_yday + 1, L"%03d", pt, ptlim);
+			continue;
+		case 'k':
+			/*
+			** This used to be...
+			**	_conv(t->tm_hour % 12 ?
+			**		t->tm_hour % 12 : 12, 2, ' ');
+			** ...and has been changed to the below to
+			** match SunOS 4.1.1 and Arnold Robbins'
+			** strftime version 3.0. That is, "%k" and
+			** "%l" have been swapped.
+			** (ado, 1993-05-24)
+			*/
+			pt = _conv(t->tm_hour, L"%2d", pt, ptlim);
+			continue;
+		case 'l':
+			/*
+			** This used to be...
+			**	_conv(t->tm_hour, 2, ' ');
+			** ...and has been changed to the below to
+			** match SunOS 4.1.1 and Arnold Robbin's
+			** strftime version 3.0. That is, "%k" and
+			** "%l" have been swapped.
+			** (ado, 1993-05-24)
+			*/
+			pt = _conv((t->tm_hour % 12) ?
+				(t->tm_hour % 12) : 12,
+				L"%2d", pt, ptlim);
+			continue;
+		case 'M':
+			pt = _conv(t->tm_min, L"%02d", pt, ptlim);
+			continue;
+		case 'm':
+			pt = _conv(t->tm_mon + 1, L"%02d", pt, ptlim);
+			continue;
+		case 'n':
+			pt = _add(L"\n", pt, ptlim);
+			continue;
+		case 'p':
+			pt = _add((t->tm_hour >= (HOURSPERDAY / 2)) ?
+				Locale->pm :
+				Locale->am,
+				pt, ptlim);
+			continue;
+		case 'R':
+			pt = _fmt(L"%H:%M", t, pt, ptlim, warnp);
+			continue;
+		case 'r':
+			pt = _fmt(L"%I:%M:%S %p", t, pt, ptlim, warnp);
+			continue;
+		case 'S':
+			pt = _conv(t->tm_sec, L"%02d", pt, ptlim);
+			continue;
+		case 's':
+			{
+				struct tm	tm;
+				wchar_t		buf[INT_STRLEN_MAXIMUM(
+							time_t) + 1];
+				time_t		mkt;
+
+				tm = *t;
+				mkt = mktime(&tm);
+				if (TYPE_SIGNED(time_t))
+					(void) swprintf(buf, 
+					    sizeof buf/sizeof buf[0],
+					    L"%ld", (long) mkt);
+				else	
+					(void) swprintf(buf, 
+					    sizeof buf/sizeof buf[0],
+					    L"%lu", (unsigned long) mkt);
+				pt = _add(buf, pt, ptlim);
+			}
+			continue;
+		case 'T':
+			pt = _fmt(L"%H:%M:%S", t, pt, ptlim, warnp);
+			continue;
+		case 't':
+			pt = _add(L"\t", pt, ptlim);
+			continue;
+		case 'U':
+			pt = _conv((t->tm_yday + DAYSPERWEEK -
+				t->tm_wday) / DAYSPERWEEK,
+				L"%02d", pt, ptlim);
+			continue;
+		case 'u':
+			/*
+			** From Arnold Robbins' strftime version 3.0:
+			** "ISO 8601: Weekday as a decimal number
+			** [1 (Monday) - 7]"
+			** (ado, 1993-05-24)
+			*/
+			pt = _conv((t->tm_wday == 0) ?
+				DAYSPERWEEK : t->tm_wday,
+				L"%d", pt, ptlim);
+			continue;
+		case 'V':	/* ISO 8601 week number */
+		case 'G':	/* ISO 8601 year (four digits) */
+		case 'g':	/* ISO 8601 year (two digits) */
+/*
+** From Arnold Robbins' strftime version 3.0: "the week number of the
+** year (the first Monday as the first day of week 1) as a decimal number
+** (01-53)."
+** (ado, 1993-05-24)
+**
+** From "http://www.ft.uni-erlangen.de/~mskuhn/iso-time.html" by Markus Kuhn:
+** "Week 01 of a year is per definition the first week which has the
+** Thursday in this year, which is equivalent to the week which contains
+** the fourth day of January. In other words, the first week of a new year
+** is the week which has the majority of its days in the new year. Week 01
+** might also contain days from the previous year and the week before week
+** 01 of a year is the last week (52 or 53) of the previous year even if
+** it contains days from the new year. A week starts with Monday (day 1)
+** and ends with Sunday (day 7). For example, the first week of the year
+** 1997 lasts from 1996-12-30 to 1997-01-05..."
+** (ado, 1996-01-02)
+*/
+			{
+			int	year;
+			int	base;
+			int	yday;
+			int	wday;
+			int	w;
+
+			year = t->tm_year;
+			base = TM_YEAR_BASE;
+			yday = t->tm_yday;
+			wday = t->tm_wday;
+			for ( ; ; ) {
+				int	len;
+				int	bot;
+				int	top;
+
+				len = isleap_sum(year, base) ?
+					DAYSPERLYEAR :
+					DAYSPERNYEAR;
+				/*
+				** What yday (-3 ... 3) does the ISO year 
+				** begin on?
+				*/
+				bot = ((yday + 11 - wday) % DAYSPERWEEK) - 3;
+				/*
+				** What yday does the NEXT ISO year begin on?
+				*/
+				top = bot - (len % DAYSPERWEEK);
+				if (top < -3)
+					top += DAYSPERWEEK;
+				top += len;
+				if (yday >= top) {
+					++base;
+					w = 1;
+					break;
+				}
+				if (yday >= bot) {
+					w = 1 + ((yday - bot) / DAYSPERWEEK);
+					break;
+				}
+				--base;
+				yday += isleap_sum(year, base) ?
+					DAYSPERLYEAR :
+					DAYSPERNYEAR;
+			}
+			if ((w == 52 && t->tm_mon == TM_JANUARY) ||
+				(w == 1 && t->tm_mon == TM_DECEMBER))
+					w = 53;
+			if (*format == 'V')
+				pt = _conv(w, L"%02d", pt, ptlim);
+			else if (*format == 'g') {
+				*warnp = IN_ALL;
+				pt = _yconv(year, base, 0, 1, pt, ptlim);
+			} else	
+				pt = _yconv(year, base, 1, 1, pt, ptlim);
+			}
+			continue;
+		case 'v':
+			/*
+			** From Arnold Robbins' strftime version 3.0:
+			** "date as dd-bbb-YYYY"
+			** (ado, 1993-05-24)
+			*/
+			pt = _fmt(L"%e-%b-%Y", t, pt, ptlim, warnp);
+			continue;
+		case 'W':
+			pt = _conv((t->tm_yday + DAYSPERWEEK -
+				(t->tm_wday ?
+				(t->tm_wday - 1) :
+				(DAYSPERWEEK - 1))) / DAYSPERWEEK,
+				L"%02d", pt, ptlim);
+			continue;
+		case 'w':
+			pt = _conv(t->tm_wday, L"%d", pt, ptlim);
+			continue;
+		case 'X':
+			pt = _fmt(Locale->X_fmt, t, pt, ptlim, warnp);
+			continue;
+		case 'x':
+			{
+			int	warn2 = IN_SOME;
+
+			pt = _fmt(Locale->x_fmt, t, pt, ptlim, &warn2);
+			if (warn2 == IN_ALL)
+				warn2 = IN_THIS;
+			if (warn2 > *warnp)
+				*warnp = warn2;
+			}
+			continue;
+		case 'y':
+			*warnp = IN_ALL;
+			pt = _yconv(t->tm_year, TM_YEAR_BASE, 0, 1, pt, ptlim);
+			continue;
+		case 'Y':
+			pt = _yconv(t->tm_year, TM_YEAR_BASE, 1, 1, pt, ptlim);
+			continue;
+		case 'Z':
+			if (t->tm_zone != NULL)
+				pt = _sadd(t->TM_ZONE, pt, ptlim);
+			else
+				if (t->tm_isdst >= 0)
+					pt = _sadd(tzname[t->tm_isdst != 0], 
+					    pt, ptlim);
+			/*
+			** C99 says that %Z must be replaced by the
+			** empty string if the time zone is not
+			** determinable.
+			*/
+			continue;
+		case 'z':
+			{
+			int		diff;
+			wchar_t const *	sign;
+
+			if (t->tm_isdst < 0)
+				continue;
+			diff = t->tm_gmtoff;
+			if (diff < 0) {
+				sign = L"-";
+				diff = -diff;
+			} else	
+				sign = L"+";
+			pt = _add(sign, pt, ptlim);
+			diff /= SECSPERMIN;
+			diff = (diff / MINSPERHOUR) * 100 +
+				(diff % MINSPERHOUR);
+			pt = _conv(diff, L"%04d", pt, ptlim);
+			}
+			continue;
+		case '+':
+			pt = _fmt(Locale->date_fmt, t, pt, ptlim, warnp);
+			continue;
+		case '%':
+		/*
+		** X311J/88-090 (4.12.3.5): if conversion wchar_t is
+		** undefined, behavior is undefined. Print out the
+		** character itself as printf(3) also does.
+		*/
+		default:
+			if (pt != ptlim)
+				*pt++ = *format;
+			break;
+		}
+	}
+	return pt;
+}
+
+static wchar_t *
+_conv(int n, const wchar_t *format, wchar_t *pt, const wchar_t *ptlim)
+{
+	wchar_t	buf[INT_STRLEN_MAXIMUM(int) + 1];
+
+	(void) swprintf(buf, sizeof buf/sizeof buf[0], format, n);
+	return _add(buf, pt, ptlim);
+}
+
+static wchar_t *
+_add(const wchar_t *str, wchar_t *pt, const wchar_t *ptlim)
+{
+	while (pt < ptlim && (*pt = *str++) != L'\0')
+		++pt;
+	return pt;
+}
+
+static wchar_t *
+_sadd(const char *str, wchar_t *pt, const wchar_t *ptlim)
+{
+	while (pt < ptlim && (*pt = btowc(*str++)) != L'\0')
+		++pt;
+	return pt;
+}
+/*
+** POSIX and the C Standard are unclear or inconsistent about
+** what %C and %y do if the year is negative or exceeds 9999.
+** Use the convention that %C concatenated with %y yields the
+** same output as %Y, and that %Y contains at least 4 bytes,
+** with more only if necessary.
+*/
+
+static wchar_t *
+_yconv(int a, int b, int convert_top, int convert_yy, wchar_t *pt, 
+    const wchar_t *ptlim)
+{
+	register int	lead;
+	register int	trail;
+
+#define DIVISOR	100
+	trail = a % DIVISOR + b % DIVISOR;
+	lead = a / DIVISOR + b / DIVISOR + trail / DIVISOR;
+	trail %= DIVISOR;
+	if (trail < 0 && lead > 0) {
+		trail += DIVISOR;
+		--lead;
+	} else if (lead < 0 && trail > 0) {
+		trail -= DIVISOR;
+		++lead;
+	}
+	if (convert_top) {
+		if (lead == 0 && trail < 0)
+			pt = _add(L"-0", pt, ptlim);
+		else	pt = _conv(lead, L"%02d", pt, ptlim);
+	}
+	if (convert_yy)
+		pt = _conv(((trail < 0) ? -trail : trail), L"%02d", pt, ptlim);
+	return pt;
+}
+
diff --git a/libm/Android.mk b/libm/Android.mk
index 5f69d1e..d7d8bc1 100644
--- a/libm/Android.mk
+++ b/libm/Android.mk
@@ -234,6 +234,11 @@
     -DFLT_EVAL_METHOD=0 \
     -std=c99 \
     -include $(LOCAL_PATH)/freebsd-compat.h \
+    -Wno-missing-braces \
+    -Wno-parentheses \
+    -Wno-sign-compare \
+    -Wno-uninitialized \
+    -Wno-unknown-pragmas \
 
 libm_common_includes := $(LOCAL_PATH)/upstream-freebsd/lib/msun/src/
 
diff --git a/libm/NOTICE b/libm/NOTICE
index 5a8e139..5be60db 100644
--- a/libm/NOTICE
+++ b/libm/NOTICE
@@ -155,6 +155,32 @@
 
 -------------------------------------------------------------------
 
+Copyright (C) 2014 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:
+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) 1985, 1993
    The Regents of the University of California.  All rights reserved.
 
@@ -312,32 +338,6 @@
 
 -------------------------------------------------------------------
 
-Copyright (c) 2002, 2003 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) 2003 Dag-Erling Smørgrav
 All rights reserved.
 
@@ -976,6 +976,32 @@
 
 -------------------------------------------------------------------
 
+Copyright (c) 2013 David Chisnall
+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.
+
+-------------------------------------------------------------------
+
 From: @(#)s_ilogb.c 5.1 93/09/24
 ====================================================
 Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
diff --git a/libm/include/math.h b/libm/include/math.h
index bd0241b..4d174f9 100644
--- a/libm/include/math.h
+++ b/libm/include/math.h
@@ -396,16 +396,23 @@
  * long double versions of ISO/POSIX math functions
  */
 #if __ISO_C_VISIBLE >= 1999
+long double	acoshl(long double);
 long double	acosl(long double);
+long double	asinhl(long double);
 long double	asinl(long double);
 long double	atan2l(long double, long double);
+long double	atanhl(long double);
 long double	atanl(long double);
 long double	cbrtl(long double);
 long double	ceill(long double);
 long double	copysignl(long double, long double) __pure2;
+long double	coshl(long double);
 long double	cosl(long double);
+long double	erfcl(long double);
+long double	erfl(long double);
 long double	exp2l(long double);
 long double	expl(long double);
+long double	expm1l(long double);
 long double	fabsl(long double) __pure2;
 long double	fdiml(long double, long double);
 long double	floorl(long double);
@@ -417,9 +424,14 @@
 long double	hypotl(long double, long double);
 int		ilogbl(long double) __pure2;
 long double	ldexpl(long double, int);
+long double	lgammal(long double);
 long long	llrintl(long double);
 long long	llroundl(long double);
+long double	log10l(long double);
+long double	log1pl(long double);
+long double	log2l(long double);
 long double	logbl(long double);
+long double	logl(long double);
 long		lrintl(long double);
 long		lroundl(long double);
 long double	modfl(long double, long double *); /* fundamentally !__pure2 */
@@ -429,53 +441,22 @@
 double		nexttoward(double, long double);
 float		nexttowardf(float, long double);
 long double	nexttowardl(long double, long double);
+long double	powl(long double, long double);
 long double	remainderl(long double, long double);
 long double	remquol(long double, long double, int *);
 long double	rintl(long double);
 long double	roundl(long double);
 long double	scalblnl(long double, long);
 long double	scalbnl(long double, int);
+long double	sinhl(long double);
 long double	sinl(long double);
 long double	sqrtl(long double);
+long double	tanhl(long double);
 long double	tanl(long double);
+long double	tgammal(long double);
 long double	truncl(long double);
 
 #endif /* __ISO_C_VISIBLE >= 1999 */
 __END_DECLS
 
 #endif /* !_MATH_H_ */
-
-/* separate header for cmath */
-#ifndef _MATH_EXTRA_H_
-#if __ISO_C_VISIBLE >= 1999
-#if _DECLARE_C99_LDBL_MATH
-
-#define _MATH_EXTRA_H_
-
-/*
- * extra long double versions of math functions for C99 and cmath
- */
-__BEGIN_DECLS
-
-long double	acoshl(long double);
-long double	asinhl(long double);
-long double	atanhl(long double);
-long double	coshl(long double);
-long double	erfcl(long double);
-long double	erfl(long double);
-long double	expm1l(long double);
-long double	lgammal(long double);
-long double	log10l(long double);
-long double	log1pl(long double);
-long double	log2l(long double);
-long double	logl(long double);
-long double	powl(long double, long double);
-long double	sinhl(long double);
-long double	tanhl(long double);
-long double	tgammal(long double);
-
-__END_DECLS
-
-#endif /* !_DECLARE_C99_LDBL_MATH */
-#endif /* __ISO_C_VISIBLE >= 1999 */
-#endif /* !_MATH_EXTRA_H_ */
diff --git a/linker/linker.cpp b/linker/linker.cpp
index 4d8563e..08231ea 100755
--- a/linker/linker.cpp
+++ b/linker/linker.cpp
@@ -680,6 +680,9 @@
       return fd;
     }
     // ...but nvidia binary blobs (at least) rely on this behavior, so fall through for now.
+#if defined(__LP64__)
+    return -1;
+#endif
   }
 
   // Otherwise we try LD_LIBRARY_PATH first, and fall back to the built-in well known paths.
diff --git a/linker/linker_phdr.cpp b/linker/linker_phdr.cpp
index cfeab96..12e9779 100644
--- a/linker/linker_phdr.cpp
+++ b/linker/linker_phdr.cpp
@@ -591,9 +591,12 @@
     return -1;
   }
   off_t file_size = file_stat.st_size;
-  void* temp_mapping = mmap(NULL, file_size, PROT_READ, MAP_PRIVATE, fd, 0);
-  if (temp_mapping == MAP_FAILED) {
-    return -1;
+  void* temp_mapping = NULL;
+  if (file_size > 0) {
+    temp_mapping = mmap(NULL, file_size, PROT_READ, MAP_PRIVATE, fd, 0);
+    if (temp_mapping == MAP_FAILED) {
+      return -1;
+    }
   }
   size_t file_offset = 0;
 
@@ -614,6 +617,13 @@
     size_t match_offset = 0;
     size_t size = seg_page_end - seg_page_start;
 
+    if (file_size - file_offset < size) {
+      // File is too short to compare to this segment. The contents are likely
+      // different as well (it's probably for a different library version) so
+      // just don't bother checking.
+      break;
+    }
+
     while (match_offset < size) {
       // Skip over dissimilar pages.
       while (match_offset < size &&
diff --git a/tests/Android.mk b/tests/Android.mk
index bd77c9e..c379c04 100644
--- a/tests/Android.mk
+++ b/tests/Android.mk
@@ -198,17 +198,44 @@
 endif
 
 # -----------------------------------------------------------------------------
-# Library used by dlext tests.
+# Library used by dlext tests - with/without GNU RELRO program header
 # -----------------------------------------------------------------------------
 libdlext_test_src_files := \
     dlext_test_library.cpp \
 
+libdlext_test_ldflags := \
+    -Wl,-z,relro \
+
 module := libdlext_test
 module_tag := optional
 build_type := target
 build_target := SHARED_LIBRARY
 include $(LOCAL_PATH)/Android.build.mk
 
+libdlext_test_norelro_src_files := \
+    dlext_test_library.cpp \
+
+libdlext_test_norelro_ldflags := \
+    -Wl,-z,norelro \
+
+module := libdlext_test_norelro
+module_tag := optional
+build_type := target
+build_target := SHARED_LIBRARY
+include $(LOCAL_PATH)/Android.build.mk
+
+# -----------------------------------------------------------------------------
+# This library used by atexit tests
+# -----------------------------------------------------------------------------
+
+libtest_atexit_src_files := \
+    atexit_testlib.cpp
+
+module := libtest_atexit
+build_type := target
+build_target := SHARED_LIBRARY
+include $(LOCAL_PATH)/Android.build.mk
+
 # -----------------------------------------------------------------------------
 # Tests for the device using bionic's .so. Run with:
 #   adb shell /data/nativetest/bionic-unit-tests/bionic-unit-tests
@@ -217,6 +244,7 @@
     libBionicTests \
 
 bionic-unit-tests_src_files := \
+    atexit_test.cpp \
     dlext_test.cpp \
     dlfcn_test.cpp \
 
@@ -224,8 +252,12 @@
     -Wl,--export-dynamic \
     -Wl,-u,DlSymTestFunction \
 
+bionic-unit-tests_c_includes := \
+    $(call include-path-for, libpagemap) \
+
 bionic-unit-tests_shared_libraries_target := \
     libdl \
+    libpagemap \
 
 module := bionic-unit-tests
 module_tag := optional
@@ -263,11 +295,14 @@
 
 ifeq ($(HOST_OS)-$(HOST_ARCH),linux-x86)
 
+bionic-unit-tests-glibc_src_files := \
+    atexit_test.cpp \
+
 bionic-unit-tests-glibc_whole_static_libraries := \
     libBionicStandardTests \
 
 bionic-unit-tests-glibc_ldlibs := \
-    -lrt \
+    -lrt -ldl \
 
 module := bionic-unit-tests-glibc
 module_tag := optional
diff --git a/tests/atexit_test.cpp b/tests/atexit_test.cpp
new file mode 100644
index 0000000..e52235d
--- /dev/null
+++ b/tests/atexit_test.cpp
@@ -0,0 +1,44 @@
+/*
+ * 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 <gtest/gtest.h>
+
+#include <dlfcn.h>
+#include <libgen.h>
+#include <limits.h>
+#include <stdio.h>
+#include <stdint.h>
+
+#include <string>
+
+TEST(atexit, combined_test) {
+  std::string atexit_call_sequence;
+  bool valid_this_in_static_dtor = false;
+  void* handle = dlopen("libtest_atexit.so", RTLD_NOW);
+  ASSERT_TRUE(handle != NULL);
+
+  void* sym = dlsym(handle, "register_atexit");
+  ASSERT_TRUE(sym != NULL);
+  reinterpret_cast<void (*)(std::string*, bool*)>(sym)(&atexit_call_sequence, &valid_this_in_static_dtor);
+
+  ASSERT_EQ(0, dlclose(handle));
+  // this test verifies atexit call from atexit handler. as well as the order of calls
+  ASSERT_EQ("Humpty Dumpty sat on a wall", atexit_call_sequence);
+  ASSERT_TRUE(valid_this_in_static_dtor);
+}
+
+// TODO: test for static dtor calls from from exit(.) -> __cxa_finalize(NULL)
+
diff --git a/tests/atexit_testlib.cpp b/tests/atexit_testlib.cpp
new file mode 100644
index 0000000..36393e7
--- /dev/null
+++ b/tests/atexit_testlib.cpp
@@ -0,0 +1,75 @@
+/*
+ * 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 <stdio.h>
+#include <stdlib.h>
+
+#include <string>
+
+// use external control number from main test
+static std::string* atexit_sequence = NULL;
+static bool* atexit_valid_this_in_static_dtor = NULL;
+
+class AtExitStaticClass;
+
+static const AtExitStaticClass* valid_this = NULL;
+
+static class AtExitStaticClass {
+public:
+  AtExitStaticClass() { valid_this = this; }
+  ~AtExitStaticClass() {
+    if (atexit_valid_this_in_static_dtor) {
+      *atexit_valid_this_in_static_dtor = (valid_this == this);
+    }
+  }
+} staticObj;
+
+// 4
+static void atexit_handler_from_atexit_from_atexit2() {
+  *atexit_sequence += " on";
+}
+
+// 3
+static void atexit_handler_from_atexit_from_atexit1() {
+  *atexit_sequence += " sat";
+}
+
+// 2
+static void atexit_handler_from_atexit() {
+  *atexit_sequence += " Dumpty";
+  // register 2 others
+  atexit(atexit_handler_from_atexit_from_atexit2);
+  atexit(atexit_handler_from_atexit_from_atexit1);
+}
+
+// 1
+static void atexit_handler_with_atexit() {
+  *atexit_sequence += "Humpty";
+  atexit(atexit_handler_from_atexit);
+}
+
+// last
+static void atexit_handler_regular() {
+  *atexit_sequence += " a wall";
+}
+
+extern "C" void register_atexit(std::string* sequence, bool* valid_this_in_static_dtor) {
+  atexit_sequence = sequence;
+  atexit_valid_this_in_static_dtor = valid_this_in_static_dtor;
+  atexit(atexit_handler_regular);
+  atexit(atexit_handler_with_atexit);
+  atexit(NULL);
+}
+
diff --git a/tests/dlext_test.cpp b/tests/dlext_test.cpp
index 872cc5b..b56fc41 100644
--- a/tests/dlext_test.cpp
+++ b/tests/dlext_test.cpp
@@ -24,8 +24,11 @@
 #include <unistd.h>
 #include <android/dlext.h>
 #include <sys/mman.h>
+#include <sys/types.h>
 #include <sys/wait.h>
 
+#include <pagemap/pagemap.h>
+
 
 #define ASSERT_DL_NOTNULL(ptr) \
     ASSERT_TRUE(ptr != NULL) << "dlerror: " << dlerror()
@@ -39,6 +42,7 @@
 
 typedef int (*fn)(void);
 #define LIBNAME "libdlext_test.so"
+#define LIBNAME_NORELRO "libdlext_test_norelro.so"
 #define LIBSIZE 1024*1024 // how much address space to reserve for it
 
 
@@ -144,52 +148,208 @@
   EXPECT_EQ(4, f());
 }
 
-TEST_F(DlExtTest, RelroShareChildWrites) {
-  void* start = mmap(NULL, LIBSIZE, PROT_NONE, MAP_PRIVATE | MAP_ANONYMOUS,
-                     -1, 0);
-  ASSERT_TRUE(start != MAP_FAILED);
-  android_dlextinfo extinfo;
-  extinfo.reserved_addr = start;
-  extinfo.reserved_size = LIBSIZE;
+class DlExtRelroSharingTest : public DlExtTest {
+protected:
+  virtual void SetUp() {
+    DlExtTest::SetUp();
+    void* start = mmap(NULL, LIBSIZE, PROT_NONE, MAP_PRIVATE | MAP_ANONYMOUS,
+                       -1, 0);
+    ASSERT_TRUE(start != MAP_FAILED);
+    extinfo_.flags = ANDROID_DLEXT_RESERVED_ADDRESS;
+    extinfo_.reserved_addr = start;
+    extinfo_.reserved_size = LIBSIZE;
+    extinfo_.relro_fd = -1;
 
-  int relro_fd;
-  char relro_file[PATH_MAX];
-  const char* android_data = getenv("ANDROID_DATA");
-  ASSERT_TRUE(android_data != NULL);
-  snprintf(relro_file, sizeof(relro_file), "%s/local/tmp/libdlext_test.relro", android_data);
-  relro_fd = open(relro_file, O_CREAT | O_RDWR | O_TRUNC, 0644);
-  extinfo.flags = ANDROID_DLEXT_RESERVED_ADDRESS | ANDROID_DLEXT_WRITE_RELRO;
-  ASSERT_NOERROR(relro_fd);
-  extinfo.relro_fd = relro_fd;
-
-  pid_t pid = fork();
-  if (pid == 0) {
-    // child process
-    void* handle = android_dlopen_ext(LIBNAME, RTLD_NOW, &extinfo);
-    if (handle == NULL) {
-      fprintf(stderr, "in child: %s\n", dlerror());
-      exit(1);
-    }
-    exit(0);
+    const char* android_data = getenv("ANDROID_DATA");
+    ASSERT_TRUE(android_data != NULL);
+    snprintf(relro_file_, sizeof(relro_file_), "%s/local/tmp/libdlext_test.relro", android_data);
   }
 
-  // continuing in parent
-  ASSERT_NOERROR(close(relro_fd));
-  ASSERT_NOERROR(pid);
-  int status;
-  ASSERT_EQ(pid, waitpid(pid, &status, 0));
-  ASSERT_TRUE(WIFEXITED(status));
-  ASSERT_EQ(0, WEXITSTATUS(status));
+  virtual void TearDown() {
+    DlExtTest::TearDown();
+    if (extinfo_.relro_fd != -1) {
+      ASSERT_NOERROR(close(extinfo_.relro_fd));
+    }
+  }
 
-  relro_fd = open(relro_file, O_RDONLY);
+  void CreateRelroFile(const char* lib) {
+    int relro_fd = open(relro_file_, O_CREAT | O_RDWR | O_TRUNC, 0644);
+    ASSERT_NOERROR(relro_fd);
+
+    pid_t pid = fork();
+    if (pid == 0) {
+      // child process
+      extinfo_.flags |= ANDROID_DLEXT_WRITE_RELRO;
+      extinfo_.relro_fd = relro_fd;
+      void* handle = android_dlopen_ext(lib, RTLD_NOW, &extinfo_);
+      if (handle == NULL) {
+        fprintf(stderr, "in child: %s\n", dlerror());
+        exit(1);
+      }
+      exit(0);
+    }
+
+    // continuing in parent
+    ASSERT_NOERROR(close(relro_fd));
+    ASSERT_NOERROR(pid);
+    int status;
+    ASSERT_EQ(pid, waitpid(pid, &status, 0));
+    ASSERT_TRUE(WIFEXITED(status));
+    ASSERT_EQ(0, WEXITSTATUS(status));
+
+    // reopen file for reading so it can be used
+    relro_fd = open(relro_file_, O_RDONLY);
+    ASSERT_NOERROR(relro_fd);
+    extinfo_.flags |= ANDROID_DLEXT_USE_RELRO;
+    extinfo_.relro_fd = relro_fd;
+  }
+
+  void TryUsingRelro(const char* lib) {
+    handle_ = android_dlopen_ext(lib, RTLD_NOW, &extinfo_);
+    ASSERT_DL_NOTNULL(handle_);
+    fn f = reinterpret_cast<fn>(dlsym(handle_, "getRandomNumber"));
+    ASSERT_DL_NOTNULL(f);
+    EXPECT_EQ(4, f());
+  }
+
+  void SpawnChildrenAndMeasurePss(const char* lib, bool share_relro, size_t* pss_out);
+
+  android_dlextinfo extinfo_;
+  char relro_file_[PATH_MAX];
+};
+
+TEST_F(DlExtRelroSharingTest, ChildWritesGoodData) {
+  ASSERT_NO_FATAL_FAILURE(CreateRelroFile(LIBNAME));
+  ASSERT_NO_FATAL_FAILURE(TryUsingRelro(LIBNAME));
+}
+
+TEST_F(DlExtRelroSharingTest, ChildWritesNoRelro) {
+  ASSERT_NO_FATAL_FAILURE(CreateRelroFile(LIBNAME_NORELRO));
+  ASSERT_NO_FATAL_FAILURE(TryUsingRelro(LIBNAME_NORELRO));
+}
+
+TEST_F(DlExtRelroSharingTest, RelroFileEmpty) {
+  int relro_fd = open(relro_file_, O_CREAT | O_RDWR | O_TRUNC, 0644);
   ASSERT_NOERROR(relro_fd);
-  extinfo.flags = ANDROID_DLEXT_RESERVED_ADDRESS | ANDROID_DLEXT_USE_RELRO;
-  extinfo.relro_fd = relro_fd;
-  handle_ = android_dlopen_ext(LIBNAME, RTLD_NOW, &extinfo);
   ASSERT_NOERROR(close(relro_fd));
 
-  ASSERT_DL_NOTNULL(handle_);
-  fn f = reinterpret_cast<fn>(dlsym(handle_, "getRandomNumber"));
-  ASSERT_DL_NOTNULL(f);
-  EXPECT_EQ(4, f());
+  ASSERT_NO_FATAL_FAILURE(TryUsingRelro(LIBNAME));
+}
+
+TEST_F(DlExtRelroSharingTest, VerifyMemorySaving) {
+  ASSERT_NO_FATAL_FAILURE(CreateRelroFile(LIBNAME));
+  int relro_fd = open(relro_file_, O_RDONLY);
+  ASSERT_NOERROR(relro_fd);
+  extinfo_.flags |= ANDROID_DLEXT_USE_RELRO;
+  extinfo_.relro_fd = relro_fd;
+  int pipefd[2];
+  ASSERT_NOERROR(pipe(pipefd));
+
+  size_t without_sharing, with_sharing;
+  ASSERT_NO_FATAL_FAILURE(SpawnChildrenAndMeasurePss(LIBNAME, false, &without_sharing));
+  ASSERT_NO_FATAL_FAILURE(SpawnChildrenAndMeasurePss(LIBNAME, true, &with_sharing));
+
+  // We expect the sharing to save at least 10% of the total PSS. In practice
+  // it saves 40%+ for this test.
+  size_t expected_size = without_sharing - (without_sharing/10);
+  EXPECT_LT(with_sharing, expected_size);
+}
+
+void getPss(pid_t pid, size_t* pss_out) {
+  pm_kernel_t* kernel;
+  ASSERT_EQ(0, pm_kernel_create(&kernel));
+
+  pm_process_t* process;
+  ASSERT_EQ(0, pm_process_create(kernel, pid, &process));
+
+  pm_map_t** maps;
+  size_t num_maps;
+  ASSERT_EQ(0, pm_process_maps(process, &maps, &num_maps));
+
+  size_t total_pss = 0;
+  for (size_t i = 0; i < num_maps; i++) {
+    pm_memusage_t usage;
+    ASSERT_EQ(0, pm_map_usage(maps[i], &usage));
+    total_pss += usage.pss;
+  }
+  *pss_out = total_pss;
+
+  free(maps);
+  pm_process_destroy(process);
+  pm_kernel_destroy(kernel);
+}
+
+void DlExtRelroSharingTest::SpawnChildrenAndMeasurePss(const char* lib, bool share_relro,
+                                                       size_t* pss_out) {
+  const int CHILDREN = 20;
+
+  // Create children
+  pid_t childpid[CHILDREN];
+  int childpipe[CHILDREN];
+  for (int i=0; i<CHILDREN; ++i) {
+    char read_buf;
+    int child_done_pipe[2], parent_done_pipe[2];
+    ASSERT_NOERROR(pipe(child_done_pipe));
+    ASSERT_NOERROR(pipe(parent_done_pipe));
+
+    pid_t child = fork();
+    if (child == 0) {
+      // close the 'wrong' ends of the pipes in the child
+      close(child_done_pipe[0]);
+      close(parent_done_pipe[1]);
+
+      // open the library
+      void* handle;
+      if (share_relro) {
+        handle = android_dlopen_ext(lib, RTLD_NOW, &extinfo_);
+      } else {
+        handle = dlopen(lib, RTLD_NOW);
+      }
+      if (handle == NULL) {
+        fprintf(stderr, "in child: %s\n", dlerror());
+        exit(1);
+      }
+
+      // close write end of child_done_pipe to signal the parent that we're done.
+      close(child_done_pipe[1]);
+
+      // wait for the parent to close parent_done_pipe, then exit
+      read(parent_done_pipe[0], &read_buf, 1);
+      exit(0);
+    }
+
+    ASSERT_NOERROR(child);
+
+    // close the 'wrong' ends of the pipes in the parent
+    close(child_done_pipe[1]);
+    close(parent_done_pipe[0]);
+
+    // wait for the child to be done
+    read(child_done_pipe[0], &read_buf, 1);
+    close(child_done_pipe[0]);
+
+    // save the child's pid and the parent_done_pipe
+    childpid[i] = child;
+    childpipe[i] = parent_done_pipe[1];
+  }
+
+  // Sum the PSS of all the children
+  size_t total_pss = 0;
+  for (int i=0; i<CHILDREN; ++i) {
+    size_t child_pss;
+    ASSERT_NO_FATAL_FAILURE(getPss(childpid[i], &child_pss));
+    total_pss += child_pss;
+  }
+  *pss_out = total_pss;
+
+  // Close pipes and wait for children to exit
+  for (int i=0; i<CHILDREN; ++i) {
+    ASSERT_NOERROR(close(childpipe[i]));
+  }
+  for (int i=0; i<CHILDREN; ++i) {
+    int status;
+    ASSERT_EQ(childpid[i], waitpid(childpid[i], &status, 0));
+    ASSERT_TRUE(WIFEXITED(status));
+    ASSERT_EQ(0, WEXITSTATUS(status));
+  }
 }
diff --git a/tests/math_test.cpp b/tests/math_test.cpp
index 0b98e40..63ac719 100644
--- a/tests/math_test.cpp
+++ b/tests/math_test.cpp
@@ -14,8 +14,6 @@
  * limitations under the License.
  */
 
-#define _DECLARE_C99_LDBL_MATH 1
-
 // This include (and the associated definition of __test_capture_signbit)
 // must be placed before any files that include <cmath> (gtest.h in this case).
 //
diff --git a/tests/stdio_test.cpp b/tests/stdio_test.cpp
index d825c14..73e9dcd 100644
--- a/tests/stdio_test.cpp
+++ b/tests/stdio_test.cpp
@@ -220,11 +220,16 @@
 }
 
 TEST(stdio, snprintf_n) {
+#if !defined(__GLIBC__)
+  // http://b/14492135
   char buf[32];
-  int i = 0;
-  EXPECT_EQ(4, snprintf(buf, sizeof(buf), "a %n b", &i));
-  EXPECT_EQ(2, i);
-  EXPECT_STREQ("a  b", buf);
+  int i = 1234;
+  EXPECT_EQ(5, snprintf(buf, sizeof(buf), "a %n b", &i));
+  EXPECT_EQ(1234, i);
+  EXPECT_STREQ("a n b", buf);
+#else
+  GTEST_LOG_(INFO) << "This test does nothing.\n";
+#endif
 }
 
 TEST(stdio, snprintf_smoke) {
@@ -436,3 +441,45 @@
   ASSERT_EQ(123, i1);
   ASSERT_DOUBLE_EQ(1.23, d1);
 }
+
+TEST(stdio, cantwrite_EBADF) {
+  // If we open a file read-only...
+  FILE* fp = fopen("/proc/version", "r");
+
+  // ...all attempts to write to that file should return failure.
+
+  // They should also set errno to EBADF. This isn't POSIX, but it's traditional.
+  // glibc gets the wide-character functions wrong.
+
+  errno = 0;
+  EXPECT_EQ(EOF, putc('x', fp));
+  EXPECT_EQ(EBADF, errno);
+
+  errno = 0;
+  EXPECT_EQ(EOF, fprintf(fp, "hello"));
+  EXPECT_EQ(EBADF, errno);
+
+  errno = 0;
+  EXPECT_EQ(EOF, fwprintf(fp, L"hello"));
+#if !defined(__GLIBC__)
+  EXPECT_EQ(EBADF, errno);
+#endif
+
+  errno = 0;
+  EXPECT_EQ(EOF, putw(1234, fp));
+  EXPECT_EQ(EBADF, errno);
+
+  errno = 0;
+  EXPECT_EQ(0U, fwrite("hello", 1, 2, fp));
+  EXPECT_EQ(EBADF, errno);
+
+  errno = 0;
+  EXPECT_EQ(EOF, fputs("hello", fp));
+  EXPECT_EQ(EBADF, errno);
+
+  errno = 0;
+  EXPECT_EQ(WEOF, fputwc(L'x', fp));
+#if !defined(__GLIBC__)
+  EXPECT_EQ(EBADF, errno);
+#endif
+}
diff --git a/tests/sys_epoll_test.cpp b/tests/sys_epoll_test.cpp
index daa064a..6e7a807 100644
--- a/tests/sys_epoll_test.cpp
+++ b/tests/sys_epoll_test.cpp
@@ -17,8 +17,10 @@
 #include <gtest/gtest.h>
 
 #include <errno.h>
+#include <fcntl.h>
 #include <signal.h>
 #include <sys/epoll.h>
+#include <unistd.h>
 
 TEST(sys_epoll, smoke) {
   int epoll_fd = epoll_create(1);
@@ -37,3 +39,30 @@
   sigaddset(&ss, SIGPIPE);
   ASSERT_EQ(0, epoll_pwait(epoll_fd, events, 1, 1, &ss));
 }
+
+TEST(sys_epoll, epoll_event_data) {
+  int epoll_fd = epoll_create(1);
+  ASSERT_NE(-1, epoll_fd) << strerror(errno);
+
+  int fds[2];
+  ASSERT_NE(-1, pipe(fds));
+
+  const uint64_t expected = 0x123456789abcdef0;
+
+  // Get ready to poll on read end of pipe.
+  epoll_event ev;
+  ev.events = EPOLLIN;
+  ev.data.u64 = expected;
+  ASSERT_NE(-1, epoll_ctl(epoll_fd, EPOLL_CTL_ADD, fds[0], &ev));
+
+  // Ensure there's something in the pipe.
+  ASSERT_EQ(1, write(fds[1], "\n", 1));
+
+  // Poll.
+  epoll_event events[1];
+  ASSERT_EQ(1, epoll_wait(epoll_fd, events, 1, 1));
+  ASSERT_EQ(expected, events[0].data.u64);
+
+  close(fds[0]);
+  close(fds[1]);
+}
diff --git a/tests/wchar_test.cpp b/tests/wchar_test.cpp
index 468f09f..a92ac9d 100644
--- a/tests/wchar_test.cpp
+++ b/tests/wchar_test.cpp
@@ -319,3 +319,18 @@
   ASSERT_EQ(L'l', dst[2]);
   ASSERT_EQ(&s[3], src);
 }
+
+TEST(wchar, wcsftime) {
+  setenv("TZ", "UTC", 1);
+
+  struct tm t;
+  memset(&t, 0, sizeof(tm));
+  t.tm_year = 200;
+  t.tm_mon = 2;
+  t.tm_mday = 10;
+
+  wchar_t buf[64];
+
+  EXPECT_EQ(24U, wcsftime(buf, sizeof(buf), L"%c", &t));
+  EXPECT_STREQ(L"Sun Mar 10 00:00:00 2100", buf);
+}