Reconcile with jb-mr2-release - do not merge

Change-Id: I0839dac295b83f3c5d53d0bb81925b44e3ec17cc
diff --git a/libc/Android.mk b/libc/Android.mk
index 22ed2d8..411d780 100644
--- a/libc/Android.mk
+++ b/libc/Android.mk
@@ -15,58 +15,29 @@
 	unistd/system.c \
 	unistd/time.c \
 	stdio/asprintf.c \
-	stdio/clrerr.c \
-	stdio/fclose.c \
-	stdio/fdopen.c \
-	stdio/feof.c \
-	stdio/ferror.c \
 	stdio/fflush.c \
 	stdio/fgetc.c \
-	stdio/fgetln.c \
-	stdio/fgetpos.c \
-	stdio/fgets.c \
-	stdio/fileno.c \
 	stdio/findfp.c \
-	stdio/flags.c \
-	stdio/fopen.c \
 	stdio/fprintf.c \
-	stdio/fpurge.c \
 	stdio/fputc.c \
-	stdio/fputs.c \
 	stdio/fread.c \
 	stdio/freopen.c \
 	stdio/fscanf.c \
 	stdio/fseek.c \
-	stdio/fsetpos.c \
 	stdio/ftell.c \
-	stdio/funopen.c \
 	stdio/fvwrite.c \
-	stdio/fwalk.c \
-	stdio/fwrite.c \
-	stdio/getc.c \
-	stdio/getchar.c \
 	stdio/gets.c \
 	stdio/makebuf.c \
 	stdio/mktemp.c \
 	stdio/printf.c \
-	stdio/putc.c \
-	stdio/putchar.c \
-	stdio/puts.c \
-	stdio/putw.c \
 	stdio/refill.c \
-	stdio/remove.c \
 	stdio/rewind.c \
-	stdio/rget.c \
 	stdio/scanf.c \
-	stdio/setbuf.c \
-	stdio/setbuffer.c \
 	stdio/setvbuf.c \
 	stdio/snprintf.c\
 	stdio/sprintf.c \
 	stdio/sscanf.c \
 	stdio/stdio.c \
-	stdio/tempnam.c \
-	stdio/tmpnam.c \
 	stdio/ungetc.c \
 	stdio/vasprintf.c \
 	stdio/vfprintf.c \
@@ -77,13 +48,11 @@
 	stdio/vscanf.c \
 	stdio/vsscanf.c \
 	stdio/wbuf.c \
-	stdio/wsetup.c \
 	stdlib/atexit.c \
 	stdlib/ctype_.c \
 	stdlib/exit.c \
 	stdlib/getenv.c \
 	stdlib/putenv.c \
-	stdlib/qsort.c \
 	stdlib/setenv.c \
 	stdlib/strtod.c \
 	stdlib/strtoimax.c \
@@ -97,7 +66,6 @@
 	string/index.c \
 	string/strcasecmp.c \
 	string/strcat.c \
-	string/strchr.c \
 	string/strcspn.c \
 	string/strdup.c \
 	string/strlcat.c \
@@ -170,7 +138,6 @@
 	bionic/recv.c \
 	bionic/sched_cpualloc.c \
 	bionic/sched_cpucount.c \
-	bionic/sched_getaffinity.c \
 	bionic/sched_getcpu.c \
 	bionic/semaphore.c \
 	bionic/send.c \
@@ -264,11 +231,13 @@
     bionic/raise.cpp \
     bionic/sbrk.cpp \
     bionic/scandir.cpp \
+    bionic/sched_getaffinity.cpp \
     bionic/__set_errno.cpp \
     bionic/setlocale.cpp \
     bionic/signalfd.cpp \
     bionic/sigwait.cpp \
     bionic/__strcat_chk.cpp \
+    bionic/strchr.cpp \
     bionic/__strcpy_chk.cpp \
     bionic/strerror.cpp \
     bionic/strerror_r.cpp \
@@ -289,6 +258,37 @@
     bionic/wchar.cpp \
 
 libc_upstream_freebsd_src_files := \
+    upstream-freebsd/lib/libc/stdio/clrerr.c \
+    upstream-freebsd/lib/libc/stdio/fclose.c \
+    upstream-freebsd/lib/libc/stdio/fdopen.c \
+    upstream-freebsd/lib/libc/stdio/feof.c \
+    upstream-freebsd/lib/libc/stdio/ferror.c \
+    upstream-freebsd/lib/libc/stdio/fgetln.c \
+    upstream-freebsd/lib/libc/stdio/fgetpos.c \
+    upstream-freebsd/lib/libc/stdio/fgets.c \
+    upstream-freebsd/lib/libc/stdio/fileno.c \
+    upstream-freebsd/lib/libc/stdio/flags.c \
+    upstream-freebsd/lib/libc/stdio/fopen.c \
+    upstream-freebsd/lib/libc/stdio/fpurge.c \
+    upstream-freebsd/lib/libc/stdio/fputs.c \
+    upstream-freebsd/lib/libc/stdio/fsetpos.c \
+    upstream-freebsd/lib/libc/stdio/funopen.c \
+    upstream-freebsd/lib/libc/stdio/fwalk.c \
+    upstream-freebsd/lib/libc/stdio/fwrite.c \
+    upstream-freebsd/lib/libc/stdio/getc.c \
+    upstream-freebsd/lib/libc/stdio/getchar.c \
+    upstream-freebsd/lib/libc/stdio/putc.c \
+    upstream-freebsd/lib/libc/stdio/putchar.c \
+    upstream-freebsd/lib/libc/stdio/puts.c \
+    upstream-freebsd/lib/libc/stdio/putw.c \
+    upstream-freebsd/lib/libc/stdio/remove.c \
+    upstream-freebsd/lib/libc/stdio/rget.c \
+    upstream-freebsd/lib/libc/stdio/setbuf.c \
+    upstream-freebsd/lib/libc/stdio/setbuffer.c \
+    upstream-freebsd/lib/libc/stdio/tempnam.c \
+    upstream-freebsd/lib/libc/stdio/tmpnam.c \
+    upstream-freebsd/lib/libc/stdio/wsetup.c \
+    upstream-freebsd/lib/libc/stdlib/qsort.c \
     upstream-freebsd/lib/libc/stdlib/realpath.c \
     upstream-freebsd/lib/libc/string/wcpcpy.c \
     upstream-freebsd/lib/libc/string/wcpncpy.c \
diff --git a/libc/NOTICE b/libc/NOTICE
index 730fa46..be59d38 100644
--- a/libc/NOTICE
+++ b/libc/NOTICE
@@ -2056,6 +2056,35 @@
 Copyright (c) 1992, 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.
+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) 1992, 1993
+   The Regents of the University of California.  All rights reserved.
+
 This code is derived from software contributed to Berkeley by
 Ralph Campbell.
 
diff --git a/libc/SYSCALLS.TXT b/libc/SYSCALLS.TXT
index 96cc9e6..ac04e51 100644
--- a/libc/SYSCALLS.TXT
+++ b/libc/SYSCALLS.TXT
@@ -221,6 +221,9 @@
 int           __timer_delete:timer_delete(timer_t)                                                      1
 int           utimes(const char*, const struct timeval tvp[2])                          1
 int           utimensat(int, const char *, const struct timespec times[2], int)         1
+int           timerfd_create(clockid_t, int)   1
+int           timerfd_settime(int, int, const struct itimerspec *, struct itimerspec *)   1
+int           timerfd_gettime(int, struct itimerspec *)   1
 
 # signals
 int     sigaction(int, const struct sigaction *, struct sigaction *)  1
diff --git a/libc/arch-arm/bionic/strlen.c b/libc/arch-arm/bionic/strlen.c
index 01632e3..ca0669d 100644
--- a/libc/arch-arm/bionic/strlen.c
+++ b/libc/arch-arm/bionic/strlen.c
@@ -60,52 +60,52 @@
     // We need to process 32 bytes per loop to schedule PLD properly
     // and achieve the maximum bus speed.
     asm(
-        "ldr     %[v], [ %[s] ], #4         \n"
+        "ldr     %[v], [%[s]], #4           \n"
         "sub     %[l], %[l], %[s]           \n"
         "0:                                 \n"
 #if __ARM_HAVE_PLD
-        "pld     [ %[s], #64 ]              \n"
+        "pld     [%[s], #64]                \n"
 #endif
         "sub     %[t], %[v], %[mask], lsr #7\n"
         "and     %[t], %[t], %[mask]        \n"
         "bics    %[t], %[t], %[v]           \n"
-        "ldreq   %[v], [ %[s] ], #4         \n"
+        "ldreq   %[v], [%[s]], #4           \n"
 #if !defined(__OPTIMIZE_SIZE__)
         "bne     1f                         \n"
         "sub     %[t], %[v], %[mask], lsr #7\n"
         "and     %[t], %[t], %[mask]        \n"
         "bics    %[t], %[t], %[v]           \n"
-        "ldreq   %[v], [ %[s] ], #4         \n"
+        "ldreq   %[v], [%[s]], #4           \n"
         "bne     1f                         \n"
         "sub     %[t], %[v], %[mask], lsr #7\n"
         "and     %[t], %[t], %[mask]        \n"
         "bics    %[t], %[t], %[v]           \n"
-        "ldreq   %[v], [ %[s] ], #4         \n"
+        "ldreq   %[v], [%[s]], #4           \n"
         "bne     1f                         \n"
         "sub     %[t], %[v], %[mask], lsr #7\n"
         "and     %[t], %[t], %[mask]        \n"
         "bics    %[t], %[t], %[v]           \n"
-        "ldreq   %[v], [ %[s] ], #4         \n"
+        "ldreq   %[v], [%[s]], #4           \n"
         "bne     1f                         \n"
         "sub     %[t], %[v], %[mask], lsr #7\n"
         "and     %[t], %[t], %[mask]        \n"
         "bics    %[t], %[t], %[v]           \n"
-        "ldreq   %[v], [ %[s] ], #4         \n"
+        "ldreq   %[v], [%[s]], #4           \n"
         "bne     1f                         \n"
         "sub     %[t], %[v], %[mask], lsr #7\n"
         "and     %[t], %[t], %[mask]        \n"
         "bics    %[t], %[t], %[v]           \n"
-        "ldreq   %[v], [ %[s] ], #4         \n"
+        "ldreq   %[v], [%[s]], #4           \n"
         "bne     1f                         \n"
         "sub     %[t], %[v], %[mask], lsr #7\n"
         "and     %[t], %[t], %[mask]        \n"
         "bics    %[t], %[t], %[v]           \n"
-        "ldreq   %[v], [ %[s] ], #4         \n"
+        "ldreq   %[v], [%[s]], #4           \n"
         "bne     1f                         \n"
         "sub     %[t], %[v], %[mask], lsr #7\n"
         "and     %[t], %[t], %[mask]        \n"
         "bics    %[t], %[t], %[v]           \n"
-        "ldreq   %[v], [ %[s] ], #4         \n"
+        "ldreq   %[v], [%[s]], #4           \n"
 #endif
         "beq     0b                         \n"
         "1:                                 \n"
diff --git a/libc/arch-arm/cortex-a15/bionic/memcpy.S b/libc/arch-arm/cortex-a15/bionic/memcpy.S
index 16187b5..d297064 100644
--- a/libc/arch-arm/cortex-a15/bionic/memcpy.S
+++ b/libc/arch-arm/cortex-a15/bionic/memcpy.S
@@ -25,80 +25,109 @@
  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  */
+/*
+ * Copyright (c) 2013 ARM Ltd
+ * 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 company may not be used to endorse or promote
+ *    products derived from this software without specific prior written
+ *    permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY ARM LTD ``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 ARM LTD 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.
+ */
 
-/* Assumes neon instructions and a cache line size of 64 bytes. */
+    /* Prototype: void *memcpy (void *dst, const void *src, size_t count).  */
+
+        // This version is tuned for the Cortex-A15 processor.
 
 #include <machine/cpu-features.h>
 #include <machine/asm.h>
 
-/*
- * This code assumes it is running on a processor that supports all arm v7
- * instructions, that supports neon instructions, and that has a 64 byte
- * cache line.
- */
-
         .text
+        .syntax unified
         .fpu    neon
 
-#define CACHE_LINE_SIZE     64
+#define CACHE_LINE_SIZE 64
 
 ENTRY(memcpy)
-        .save       {r0, lr}
-        /* start preloading as early as possible */
-        pld         [r1, #(CACHE_LINE_SIZE*0)]
-        stmfd       sp!, {r0, lr}
-        pld         [r1, #(CACHE_LINE_SIZE*1)]
+        // Assumes that n >= 0, and dst, src are valid pointers.
+        // For any sizes less than 832 use the neon code that doesn't
+        // care about the src alignment. This avoids any checks
+        // for src alignment, and offers the best improvement since
+        // smaller sized copies are dominated by the overhead of
+        // the pre and post main loop.
+        // For larger copies, if src and dst cannot both be aligned to
+        // word boundaries, use the neon code.
+        // For all other copies, align dst to a double word boundary
+        // and copy using LDRD/STRD instructions.
 
-        /* do we have at least 16-bytes to copy (needed for alignment below) */
-        cmp         r2, #16
-        blo         5f
+        // Save registers (r0 holds the return value):
+        // optimized push {r0, lr}.
+        .save   {r0, lr}
+        pld     [r1, #(CACHE_LINE_SIZE*16)]
+        push    {r0, lr}
 
-        /* align destination to cache-line for the write-buffer */
+        cmp     r2, #16
+        blo     copy_less_than_16_unknown_align
+
+        cmp     r2, #832
+        bge     check_alignment
+
+copy_unknown_alignment:
+        // Unknown alignment of src and dst.
+        // Assumes that the first few bytes have already been prefetched.
+
+        // Align destination to 128 bits. The mainloop store instructions
+        // require this alignment or they will throw an exception.
         rsb         r3, r0, #0
         ands        r3, r3, #0xF
-        beq         0f
+        beq         2f
 
-        /* copy up to 15-bytes (count in r3) */
+        // Copy up to 15 bytes (count in r3).
         sub         r2, r2, r3
         movs        ip, r3, lsl #31
-        ldrmib      lr, [r1], #1
-        strmib      lr, [r0], #1
-        ldrcsb      ip, [r1], #1
-        ldrcsb      lr, [r1], #1
-        strcsb      ip, [r0], #1
-        strcsb      lr, [r0], #1
+
+        itt         mi
+        ldrbmi      lr, [r1], #1
+        strbmi      lr, [r0], #1
+        itttt       cs
+        ldrbcs      ip, [r1], #1
+        ldrbcs      lr, [r1], #1
+        strbcs      ip, [r0], #1
+        strbcs      lr, [r0], #1
+
         movs        ip, r3, lsl #29
         bge         1f
-        // copies 4 bytes, destination 32-bits aligned
+        // Copies 4 bytes, dst 32 bits aligned before, at least 64 bits after.
         vld4.8      {d0[0], d1[0], d2[0], d3[0]}, [r1]!
         vst4.8      {d0[0], d1[0], d2[0], d3[0]}, [r0, :32]!
 1:      bcc         2f
-        // copies 8 bytes, destination 64-bits aligned
+        // Copies 8 bytes, dst 64 bits aligned before, at least 128 bits after.
         vld1.8      {d0}, [r1]!
         vst1.8      {d0}, [r0, :64]!
-2:
 
-0:      /* preload immediately the next cache line, which we may need */
-        pld         [r1, #(CACHE_LINE_SIZE*0)]
-        pld         [r1, #(CACHE_LINE_SIZE*1)]
-
-        /* make sure we have at least 64 bytes to copy */
+2:      // Make sure we have at least 64 bytes to copy.
         subs        r2, r2, #64
         blo         2f
 
-        /* Preload all the cache lines we need.
-         * NOTE: The number of pld below depends on CACHE_LINE_SIZE,
-         * ideally we would increase the distance in the main loop to
-         * avoid the goofy code below. In practice this doesn't seem to make
-         * a big difference.
-         * NOTE: The value CACHE_LINE_SIZE * 4 was chosen through
-         * experimentation.
-         */
-        pld         [r1, #(CACHE_LINE_SIZE*2)]
-        pld         [r1, #(CACHE_LINE_SIZE*3)]
-        pld         [r1, #(CACHE_LINE_SIZE*4)]
-
-1:      /* The main loop copies 64 bytes at a time */
+1:      // The main loop copies 64 bytes at a time.
         vld1.8      {d0  - d3},   [r1]!
         vld1.8      {d4  - d7},   [r1]!
         pld         [r1, #(CACHE_LINE_SIZE*4)]
@@ -107,25 +136,24 @@
         vst1.8      {d4  - d7},   [r0, :128]!
         bhs         1b
 
-2:      /* fix-up the remaining count and make sure we have >= 32 bytes left */
-        add         r2, r2, #64
-        subs        r2, r2, #32
-        blo         4f
+2:      // Fix-up the remaining count and make sure we have >= 32 bytes left.
+        adds        r2, r2, #32
+        blo         3f
 
-3:      /* 32 bytes at a time. These cache lines were already preloaded */
+        // 32 bytes. These cache lines were already preloaded.
         vld1.8      {d0 - d3},  [r1]!
-        subs        r2, r2, #32
+        sub         r2, r2, #32
         vst1.8      {d0 - d3},  [r0, :128]!
-        bhs         3b
-4:      /* less than 32 left */
+3:      // Less than 32 left.
         add         r2, r2, #32
         tst         r2, #0x10
-        beq         5f
-        // copies 16 bytes, 128-bits aligned
+        beq         copy_less_than_16_unknown_align
+        // Copies 16 bytes, destination 128 bits aligned.
         vld1.8      {d0, d1}, [r1]!
         vst1.8      {d0, d1}, [r0, :128]!
 
-5:      /* copy up to 15-bytes (count in r2) */
+copy_less_than_16_unknown_align:
+        // Copy up to 15 bytes (count in r2).
         movs        ip, r2, lsl #29
         bcc         1f
         vld1.8      {d0}, [r1]!
@@ -133,14 +161,164 @@
 1:      bge         2f
         vld4.8      {d0[0], d1[0], d2[0], d3[0]}, [r1]!
         vst4.8      {d0[0], d1[0], d2[0], d3[0]}, [r0]!
-2:      movs        ip, r2, lsl #31
-        ldrmib      r3, [r1], #1
-        ldrcsb      ip, [r1], #1
-        ldrcsb      lr, [r1], #1
-        strmib      r3, [r0], #1
-        strcsb      ip, [r0], #1
-        strcsb      lr, [r0], #1
 
-        ldmfd       sp!, {r0, lr}
-        bx          lr
+2:      // Copy 0 to 4 bytes.
+        lsls        r2, r2, #31
+        itt         ne
+        ldrbne      lr, [r1], #1
+        strbne      lr, [r0], #1
+        itttt       cs
+        ldrbcs      ip, [r1], #1
+        ldrbcs      lr, [r1]
+        strbcs      ip, [r0], #1
+        strbcs      lr, [r0]
+
+        pop         {r0, pc}
+
+check_alignment:
+        // If src and dst cannot both be aligned to a word boundary,
+        // use the unaligned copy version.
+        eor     r3, r0, r1
+        ands    r3, r3, #0x3
+        bne     copy_unknown_alignment
+
+        // To try and improve performance, stack layout changed,
+        // i.e., not keeping the stack looking like users expect
+        // (highest numbered register at highest address).
+        // TODO: Add debug frame directives.
+        // We don't need exception unwind directives, because the code below
+        // does not throw any exceptions and does not call any other functions.
+        // Generally, newlib functions like this lack debug information for
+        // assembler source.
+        .save   {r4, r5}
+        strd    r4, r5, [sp, #-8]!
+        .save   {r6, r7}
+        strd    r6, r7, [sp, #-8]!
+        .save   {r8, r9}
+        strd    r8, r9, [sp, #-8]!
+
+        // Optimized for already aligned dst code.
+        ands    ip, r0, #3
+        bne     dst_not_word_aligned
+
+word_aligned:
+        // Align the destination buffer to 8 bytes, to make sure double
+        // loads and stores don't cross a cache line boundary,
+        // as they are then more expensive even if the data is in the cache
+        // (require two load/store issue cycles instead of one).
+        // If only one of the buffers is not 8 bytes aligned,
+        // then it's more important to align dst than src,
+        // because there is more penalty for stores
+        // than loads that cross a cacheline boundary.
+        // This check and realignment are only done if there is >= 832
+        // bytes to copy.
+
+        // Dst is word aligned, but check if it is already double word aligned.
+        ands    r3, r0, #4
+        beq     1f
+        ldr     r3, [r1], #4
+        str     r3, [r0], #4
+        sub     r2, #4
+
+1:      // Can only get here if > 64 bytes to copy, so don't do check r2.
+        sub     r2, #64
+
+2:      // Every loop iteration copies 64 bytes.
+        .irp    offset, #0, #8, #16, #24, #32
+        ldrd    r4, r5, [r1, \offset]
+        strd    r4, r5, [r0, \offset]
+        .endr
+
+        ldrd    r4, r5, [r1, #40]
+        ldrd    r6, r7, [r1, #48]
+        ldrd    r8, r9, [r1, #56]
+
+        // Keep the pld as far from the next load as possible.
+        // The amount to prefetch was determined experimentally using
+        // large sizes, and verifying the prefetch size does not affect
+        // the smaller copies too much.
+        // WARNING: If the ldrd and strd instructions get too far away
+        //          from each other, performance suffers. Three loads
+        //          in a row is the best tradeoff.
+        pld     [r1, #(CACHE_LINE_SIZE*16)]
+        strd    r4, r5, [r0, #40]
+        strd    r6, r7, [r0, #48]
+        strd    r8, r9, [r0, #56]
+
+        add     r0, r0, #64
+        add     r1, r1, #64
+        subs    r2, r2, #64
+        bge     2b
+
+        // Fix-up the remaining count and make sure we have >= 32 bytes left.
+        adds    r2, r2, #32
+        blo     4f
+
+        // Copy 32 bytes. These cache lines were already preloaded.
+        .irp    offset, #0, #8, #16, #24
+        ldrd    r4, r5, [r1, \offset]
+        strd    r4, r5, [r0, \offset]
+        .endr
+        add     r1, r1, #32
+        add     r0, r0, #32
+        sub     r2, r2, #32
+4:      // Less than 32 left.
+        add     r2, r2, #32
+        tst     r2, #0x10
+        beq     5f
+        // Copy 16 bytes.
+        .irp    offset, #0, #8
+        ldrd    r4, r5, [r1, \offset]
+        strd    r4, r5, [r0, \offset]
+        .endr
+        add     r1, r1, #16
+        add     r0, r0, #16
+
+5:      // Copy up to 15 bytes (count in r2).
+        movs    ip, r2, lsl #29
+        bcc     1f
+        // Copy 8 bytes.
+        ldrd    r4, r5, [r1], #8
+        strd    r4, r5, [r0], #8
+1:      bge         2f
+        // Copy 4 bytes.
+        ldr     r4, [r1], #4
+        str     r4, [r0], #4
+2:      // Copy 0 to 4 bytes.
+        lsls    r2, r2, #31
+        itt     ne
+        ldrbne  lr, [r1], #1
+        strbne  lr, [r0], #1
+        itttt   cs
+        ldrbcs  ip, [r1], #1
+        ldrbcs  lr, [r1]
+        strbcs  ip, [r0], #1
+        strbcs  lr, [r0]
+
+        // Restore registers: optimized pop {r0, pc}
+        ldrd    r8, r9, [sp], #8
+        ldrd    r6, r7, [sp], #8
+        ldrd    r4, r5, [sp], #8
+        pop     {r0, pc}
+
+dst_not_word_aligned:
+        // Align dst to word.
+        rsb     ip, ip, #4
+        cmp     ip, #2
+
+        itt     gt
+        ldrbgt  lr, [r1], #1
+        strbgt  lr, [r0], #1
+
+        itt     ge
+        ldrbge  lr, [r1], #1
+        strbge  lr, [r0], #1
+
+        ldrb    lr, [r1], #1
+        strb    lr, [r0], #1
+
+        sub     r2, r2, ip
+
+        // Src is guaranteed to be at least word aligned by this point.
+        b       word_aligned
 END(memcpy)
diff --git a/libc/arch-arm/cortex-a15/bionic/memset.S b/libc/arch-arm/cortex-a15/bionic/memset.S
index 7bb3297..2e1ad54 100644
--- a/libc/arch-arm/cortex-a15/bionic/memset.S
+++ b/libc/arch-arm/cortex-a15/bionic/memset.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2008 The Android Open Source Project
+ * Copyright (C) 2013 The Android Open Source Project
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -35,11 +35,12 @@
          * memset() returns its first argument.
 		 */
 
-    .fpu    neon
+        .fpu        neon
+        .syntax     unified
 
 ENTRY(bzero)
-        mov     r2, r1
-        mov     r1, #0
+        mov         r2, r1
+        mov         r1, #0
         // Fall through to memset...
 END(bzero)
 
@@ -47,60 +48,117 @@
         .save       {r0}
         stmfd       sp!, {r0}
 
-        vdup.8      q0, r1
-
-        /* do we have at least 16-bytes to write (needed for alignment below) */
+        // The new algorithm is slower for copies < 16 so use the old
+        // neon code in that case.
         cmp         r2, #16
-        blo         3f
+        blo         set_less_than_16_unknown_align
 
-        /* align destination to 16 bytes for the write-buffer */
-        rsb         r3, r0, #0
-        ands        r3, r3, #0xF
-        beq         2f
+        // Use strd which requires an even and odd register so move the
+        // values so that:
+        //   r0 and r1 contain the memset value
+        //   r2 is the number of bytes to set
+        //   r3 is the destination pointer
+        mov         r3, r0
 
-        /* write up to 15-bytes (count in r3) */
-        sub         r2, r2, r3
-        movs        ip, r3, lsl #31
-        strmib      r1, [r0], #1
-        strcsb      r1, [r0], #1
-        strcsb      r1, [r0], #1
-        movs        ip, r3, lsl #29
-        bge         1f
+        // Copy the byte value in every byte of r1.
+        mov         r1, r1, lsl #24
+        orr         r1, r1, r1, lsr #8
+        orr         r1, r1, r1, lsr #16
 
-        // writes 4 bytes, 32-bits aligned
-        vst1.32     {d0[0]}, [r0, :32]!
-1:      bcc         2f
+check_alignment:
+        // Align destination to a double word to avoid the strd crossing
+        // a cache line boundary.
+        ands        ip, r3, #7
+        bne         do_double_word_align
 
-        // writes 8 bytes, 64-bits aligned
-        vst1.8      {d0}, [r0, :64]!
-2:
-        /* make sure we have at least 32 bytes to write */
-        subs        r2, r2, #32
-        blo         2f
-        vmov        q1, q0
+double_word_aligned:
+        mov         r0, r1
 
-1:      /* The main loop writes 32 bytes at a time */
-        subs        r2, r2, #32
-        vst1.8      {d0 - d3}, [r0, :128]!
-        bhs         1b
+        subs        r2, #64
+        blo         set_less_than_64
 
-2:      /* less than 32 left */
-        add         r2, r2, #32
-        tst         r2, #0x10
-        beq         3f
+1:      // Main loop sets 64 bytes at a time.
+        .irp        offset, #0, #8, #16, #24, #32, #40, #48, #56
+        strd        r0, r1, [r3, \offset]
+        .endr
 
-        // writes 16 bytes, 128-bits aligned
-        vst1.8      {d0, d1}, [r0, :128]!
-3:      /* write up to 15-bytes (count in r2) */
+        add         r3, #64
+        subs        r2, #64
+        bge         1b
+
+set_less_than_64:
+        // Restore r2 to the count of bytes left to set.
+        add         r2, #64
+        lsls        ip, r2, #27
+        bcc         set_less_than_32
+        // Set 32 bytes.
+        .irp        offset, #0, #8, #16, #24
+        strd        r0, r1, [r3, \offset]
+        .endr
+        add         r3, #32
+
+set_less_than_32:
+        bpl         set_less_than_16
+        // Set 16 bytes.
+        .irp        offset, #0, #8
+        strd        r0, r1, [r3, \offset]
+        .endr
+        add         r3, #16
+
+set_less_than_16:
+        // Less than 16 bytes to set.
+        lsls        ip, r2, #29
+        bcc         set_less_than_8
+
+        // Set 8 bytes.
+        strd        r0, r1, [r3], #8
+
+set_less_than_8:
+        bpl         set_less_than_4
+        // Set 4 bytes
+        str         r1, [r3], #4
+
+set_less_than_4:
+        lsls        ip, r2, #31
+        it          ne
+        strbne      r1, [r3], #1
+        itt         cs
+        strbcs      r1, [r3], #1
+        strbcs      r1, [r3]
+
+        ldmfd       sp!, {r0}
+        bx          lr
+
+do_double_word_align:
+        rsb         ip, ip, #8
+        sub         r2, r2, ip
+        movs        r0, ip, lsl #31
+        it          mi
+        strbmi      r1, [r3], #1
+        itt         cs
+        strbcs      r1, [r3], #1
+        strbcs      r1, [r3], #1
+
+        // Dst is at least word aligned by this point.
+        cmp         ip, #4
+        blo         double_word_aligned
+        str         r1, [r3], #4
+        b           double_word_aligned
+
+set_less_than_16_unknown_align:
+        // Set up to 15 bytes.
+        vdup.8      d0, r1
         movs        ip, r2, lsl #29
         bcc         1f
         vst1.8      {d0}, [r0]!
 1:      bge         2f
         vst1.32     {d0[0]}, [r0]!
 2:      movs        ip, r2, lsl #31
-        strmib      r1, [r0], #1
-        strcsb      r1, [r0], #1
-        strcsb      r1, [r0], #1
+        it          mi
+        strbmi      r1, [r0], #1
+        itt         cs
+        strbcs      r1, [r0], #1
+        strbcs      r1, [r0], #1
         ldmfd       sp!, {r0}
         bx          lr
 END(memset)
diff --git a/libc/arch-arm/syscalls.mk b/libc/arch-arm/syscalls.mk
index 9eb5136..3c8f204 100644
--- a/libc/arch-arm/syscalls.mk
+++ b/libc/arch-arm/syscalls.mk
@@ -144,6 +144,9 @@
 syscall_src += arch-arm/syscalls/__timer_delete.S
 syscall_src += arch-arm/syscalls/utimes.S
 syscall_src += arch-arm/syscalls/utimensat.S
+syscall_src += arch-arm/syscalls/timerfd_create.S
+syscall_src += arch-arm/syscalls/timerfd_settime.S
+syscall_src += arch-arm/syscalls/timerfd_gettime.S
 syscall_src += arch-arm/syscalls/sigaction.S
 syscall_src += arch-arm/syscalls/sigprocmask.S
 syscall_src += arch-arm/syscalls/__sigsuspend.S
diff --git a/libc/arch-arm/syscalls/timerfd_create.S b/libc/arch-arm/syscalls/timerfd_create.S
new file mode 100644
index 0000000..7e3f16f
--- /dev/null
+++ b/libc/arch-arm/syscalls/timerfd_create.S
@@ -0,0 +1,15 @@
+/* autogenerated by gensyscalls.py */
+#include <asm/unistd.h>
+#include <linux/err.h>
+#include <machine/asm.h>
+
+ENTRY(timerfd_create)
+    mov     ip, r7
+    ldr     r7, =__NR_timerfd_create
+    swi     #0
+    mov     r7, ip
+    cmn     r0, #(MAX_ERRNO + 1)
+    bxls    lr
+    neg     r0, r0
+    b       __set_errno
+END(timerfd_create)
diff --git a/libc/arch-arm/syscalls/timerfd_gettime.S b/libc/arch-arm/syscalls/timerfd_gettime.S
new file mode 100644
index 0000000..2c3e2cf
--- /dev/null
+++ b/libc/arch-arm/syscalls/timerfd_gettime.S
@@ -0,0 +1,15 @@
+/* autogenerated by gensyscalls.py */
+#include <asm/unistd.h>
+#include <linux/err.h>
+#include <machine/asm.h>
+
+ENTRY(timerfd_gettime)
+    mov     ip, r7
+    ldr     r7, =__NR_timerfd_gettime
+    swi     #0
+    mov     r7, ip
+    cmn     r0, #(MAX_ERRNO + 1)
+    bxls    lr
+    neg     r0, r0
+    b       __set_errno
+END(timerfd_gettime)
diff --git a/libc/arch-arm/syscalls/timerfd_settime.S b/libc/arch-arm/syscalls/timerfd_settime.S
new file mode 100644
index 0000000..f7f0cf0
--- /dev/null
+++ b/libc/arch-arm/syscalls/timerfd_settime.S
@@ -0,0 +1,15 @@
+/* autogenerated by gensyscalls.py */
+#include <asm/unistd.h>
+#include <linux/err.h>
+#include <machine/asm.h>
+
+ENTRY(timerfd_settime)
+    mov     ip, r7
+    ldr     r7, =__NR_timerfd_settime
+    swi     #0
+    mov     r7, ip
+    cmn     r0, #(MAX_ERRNO + 1)
+    bxls    lr
+    neg     r0, r0
+    b       __set_errno
+END(timerfd_settime)
diff --git a/libc/arch-mips/syscalls.mk b/libc/arch-mips/syscalls.mk
index 0b8eccd..d3096bc 100644
--- a/libc/arch-mips/syscalls.mk
+++ b/libc/arch-mips/syscalls.mk
@@ -147,6 +147,9 @@
 syscall_src += arch-mips/syscalls/__timer_delete.S
 syscall_src += arch-mips/syscalls/utimes.S
 syscall_src += arch-mips/syscalls/utimensat.S
+syscall_src += arch-mips/syscalls/timerfd_create.S
+syscall_src += arch-mips/syscalls/timerfd_settime.S
+syscall_src += arch-mips/syscalls/timerfd_gettime.S
 syscall_src += arch-mips/syscalls/sigaction.S
 syscall_src += arch-mips/syscalls/sigprocmask.S
 syscall_src += arch-mips/syscalls/__sigsuspend.S
diff --git a/libc/arch-mips/syscalls/timerfd_create.S b/libc/arch-mips/syscalls/timerfd_create.S
new file mode 100644
index 0000000..b5ac003
--- /dev/null
+++ b/libc/arch-mips/syscalls/timerfd_create.S
@@ -0,0 +1,22 @@
+/* autogenerated by gensyscalls.py */
+#include <asm/unistd.h>
+    .text
+    .globl timerfd_create
+    .align 4
+    .ent timerfd_create
+
+timerfd_create:
+    .set noreorder
+    .cpload $t9
+    li $v0, __NR_timerfd_create
+    syscall
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
+    nop
+1:
+    la $t9,__set_errno
+    j $t9
+    nop
+    .set reorder
+    .end timerfd_create
diff --git a/libc/arch-mips/syscalls/timerfd_gettime.S b/libc/arch-mips/syscalls/timerfd_gettime.S
new file mode 100644
index 0000000..b1c21ff
--- /dev/null
+++ b/libc/arch-mips/syscalls/timerfd_gettime.S
@@ -0,0 +1,22 @@
+/* autogenerated by gensyscalls.py */
+#include <asm/unistd.h>
+    .text
+    .globl timerfd_gettime
+    .align 4
+    .ent timerfd_gettime
+
+timerfd_gettime:
+    .set noreorder
+    .cpload $t9
+    li $v0, __NR_timerfd_gettime
+    syscall
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
+    nop
+1:
+    la $t9,__set_errno
+    j $t9
+    nop
+    .set reorder
+    .end timerfd_gettime
diff --git a/libc/arch-mips/syscalls/timerfd_settime.S b/libc/arch-mips/syscalls/timerfd_settime.S
new file mode 100644
index 0000000..f68819d
--- /dev/null
+++ b/libc/arch-mips/syscalls/timerfd_settime.S
@@ -0,0 +1,22 @@
+/* autogenerated by gensyscalls.py */
+#include <asm/unistd.h>
+    .text
+    .globl timerfd_settime
+    .align 4
+    .ent timerfd_settime
+
+timerfd_settime:
+    .set noreorder
+    .cpload $t9
+    li $v0, __NR_timerfd_settime
+    syscall
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
+    nop
+1:
+    la $t9,__set_errno
+    j $t9
+    nop
+    .set reorder
+    .end timerfd_settime
diff --git a/libc/arch-x86/syscalls.mk b/libc/arch-x86/syscalls.mk
index b4ad564..31eb930 100644
--- a/libc/arch-x86/syscalls.mk
+++ b/libc/arch-x86/syscalls.mk
@@ -148,6 +148,9 @@
 syscall_src += arch-x86/syscalls/__timer_delete.S
 syscall_src += arch-x86/syscalls/utimes.S
 syscall_src += arch-x86/syscalls/utimensat.S
+syscall_src += arch-x86/syscalls/timerfd_create.S
+syscall_src += arch-x86/syscalls/timerfd_settime.S
+syscall_src += arch-x86/syscalls/timerfd_gettime.S
 syscall_src += arch-x86/syscalls/sigaction.S
 syscall_src += arch-x86/syscalls/sigprocmask.S
 syscall_src += arch-x86/syscalls/__sigsuspend.S
diff --git a/libc/arch-x86/syscalls/timerfd_create.S b/libc/arch-x86/syscalls/timerfd_create.S
new file mode 100644
index 0000000..801f8a7
--- /dev/null
+++ b/libc/arch-x86/syscalls/timerfd_create.S
@@ -0,0 +1,24 @@
+/* autogenerated by gensyscalls.py */
+#include <linux/err.h>
+#include <machine/asm.h>
+#include <asm/unistd.h>
+
+ENTRY(timerfd_create)
+    pushl   %ebx
+    pushl   %ecx
+    mov     12(%esp), %ebx
+    mov     16(%esp), %ecx
+    movl    $__NR_timerfd_create, %eax
+    int     $0x80
+    cmpl    $-MAX_ERRNO, %eax
+    jb      1f
+    negl    %eax
+    pushl   %eax
+    call    __set_errno
+    addl    $4, %esp
+    orl     $-1, %eax
+1:
+    popl    %ecx
+    popl    %ebx
+    ret
+END(timerfd_create)
diff --git a/libc/arch-x86/syscalls/timerfd_gettime.S b/libc/arch-x86/syscalls/timerfd_gettime.S
new file mode 100644
index 0000000..fde17be
--- /dev/null
+++ b/libc/arch-x86/syscalls/timerfd_gettime.S
@@ -0,0 +1,24 @@
+/* autogenerated by gensyscalls.py */
+#include <linux/err.h>
+#include <machine/asm.h>
+#include <asm/unistd.h>
+
+ENTRY(timerfd_gettime)
+    pushl   %ebx
+    pushl   %ecx
+    mov     12(%esp), %ebx
+    mov     16(%esp), %ecx
+    movl    $__NR_timerfd_gettime, %eax
+    int     $0x80
+    cmpl    $-MAX_ERRNO, %eax
+    jb      1f
+    negl    %eax
+    pushl   %eax
+    call    __set_errno
+    addl    $4, %esp
+    orl     $-1, %eax
+1:
+    popl    %ecx
+    popl    %ebx
+    ret
+END(timerfd_gettime)
diff --git a/libc/arch-x86/syscalls/timerfd_settime.S b/libc/arch-x86/syscalls/timerfd_settime.S
new file mode 100644
index 0000000..5a5f3e4
--- /dev/null
+++ b/libc/arch-x86/syscalls/timerfd_settime.S
@@ -0,0 +1,30 @@
+/* autogenerated by gensyscalls.py */
+#include <linux/err.h>
+#include <machine/asm.h>
+#include <asm/unistd.h>
+
+ENTRY(timerfd_settime)
+    pushl   %ebx
+    pushl   %ecx
+    pushl   %edx
+    pushl   %esi
+    mov     20(%esp), %ebx
+    mov     24(%esp), %ecx
+    mov     28(%esp), %edx
+    mov     32(%esp), %esi
+    movl    $__NR_timerfd_settime, %eax
+    int     $0x80
+    cmpl    $-MAX_ERRNO, %eax
+    jb      1f
+    negl    %eax
+    pushl   %eax
+    call    __set_errno
+    addl    $4, %esp
+    orl     $-1, %eax
+1:
+    popl    %esi
+    popl    %edx
+    popl    %ecx
+    popl    %ebx
+    ret
+END(timerfd_settime)
diff --git a/libc/bionic/__memcpy_chk.cpp b/libc/bionic/__memcpy_chk.cpp
index b36cfdd..a3d744c 100644
--- a/libc/bionic/__memcpy_chk.cpp
+++ b/libc/bionic/__memcpy_chk.cpp
@@ -45,7 +45,7 @@
 extern "C" void *__memcpy_chk(void *dest, const void *src,
               size_t copy_amount, size_t dest_len)
 {
-    if (__builtin_expect(copy_amount > dest_len, 0)) {
+    if (__predict_false(copy_amount > dest_len)) {
         __fortify_chk_fail("memcpy buffer overflow",
                              BIONIC_EVENT_MEMCPY_BUFFER_OVERFLOW);
     }
diff --git a/libc/bionic/__memmove_chk.cpp b/libc/bionic/__memmove_chk.cpp
index ff770b5..49a0597 100644
--- a/libc/bionic/__memmove_chk.cpp
+++ b/libc/bionic/__memmove_chk.cpp
@@ -44,7 +44,7 @@
 extern "C" void *__memmove_chk (void *dest, const void *src,
               size_t len, size_t dest_len)
 {
-    if (len > dest_len) {
+    if (__predict_false(len > dest_len)) {
         __fortify_chk_fail("memmove buffer overflow",
                              BIONIC_EVENT_MEMMOVE_BUFFER_OVERFLOW);
     }
diff --git a/libc/bionic/__memset_chk.cpp b/libc/bionic/__memset_chk.cpp
index b201ed2..f7a5f24 100644
--- a/libc/bionic/__memset_chk.cpp
+++ b/libc/bionic/__memset_chk.cpp
@@ -42,7 +42,7 @@
  * greater than 0.
  */
 extern "C" void *__memset_chk (void *dest, int c, size_t n, size_t dest_len) {
-    if (n > dest_len) {
+    if (__predict_false(n > dest_len)) {
         __fortify_chk_fail("memset buffer overflow",
                              BIONIC_EVENT_MEMSET_BUFFER_OVERFLOW);
     }
diff --git a/libc/bionic/__strcpy_chk.cpp b/libc/bionic/__strcpy_chk.cpp
index bfb6642..5aa0e93 100644
--- a/libc/bionic/__strcpy_chk.cpp
+++ b/libc/bionic/__strcpy_chk.cpp
@@ -44,7 +44,7 @@
 extern "C" char *__strcpy_chk (char *dest, const char *src, size_t dest_len) {
     // TODO: optimize so we don't scan src twice.
     size_t src_len = strlen(src) + 1;
-    if (src_len > dest_len) {
+    if (__predict_false(src_len > dest_len)) {
         __fortify_chk_fail("strcpy buffer overflow",
                              BIONIC_EVENT_STRCPY_BUFFER_OVERFLOW);
     }
diff --git a/libc/bionic/__strlcat_chk.cpp b/libc/bionic/__strlcat_chk.cpp
index 96f62f9..25c67ad 100644
--- a/libc/bionic/__strlcat_chk.cpp
+++ b/libc/bionic/__strlcat_chk.cpp
@@ -45,7 +45,7 @@
 extern "C" size_t __strlcat_chk(char *dest, const char *src,
               size_t supplied_size, size_t dest_len_from_compiler)
 {
-    if (supplied_size > dest_len_from_compiler) {
+    if (__predict_false(supplied_size > dest_len_from_compiler)) {
         __fortify_chk_fail("strlcat buffer overflow", 0);
     }
 
diff --git a/libc/bionic/__strlcpy_chk.cpp b/libc/bionic/__strlcpy_chk.cpp
index 636966b..f6b11fc 100644
--- a/libc/bionic/__strlcpy_chk.cpp
+++ b/libc/bionic/__strlcpy_chk.cpp
@@ -45,7 +45,7 @@
 extern "C" size_t __strlcpy_chk(char *dest, const char *src,
               size_t supplied_size, size_t dest_len_from_compiler)
 {
-    if (supplied_size > dest_len_from_compiler) {
+    if (__predict_false(supplied_size > dest_len_from_compiler)) {
         __fortify_chk_fail("strlcpy buffer overflow", 0);
     }
 
diff --git a/libc/bionic/__strlen_chk.cpp b/libc/bionic/__strlen_chk.cpp
index 6ebf09c..151a497 100644
--- a/libc/bionic/__strlen_chk.cpp
+++ b/libc/bionic/__strlen_chk.cpp
@@ -56,7 +56,7 @@
 extern "C" size_t __strlen_chk(const char *s, size_t s_len) {
     size_t ret = strlen(s);
 
-    if (__builtin_expect(ret >= s_len, 0)) {
+    if (__predict_false(ret >= s_len)) {
         __fortify_chk_fail("strlen read overflow", 0);
     }
 
diff --git a/libc/bionic/__strncpy_chk.cpp b/libc/bionic/__strncpy_chk.cpp
index 0f1797e..b01879c 100644
--- a/libc/bionic/__strncpy_chk.cpp
+++ b/libc/bionic/__strncpy_chk.cpp
@@ -44,7 +44,7 @@
 extern "C" char *__strncpy_chk (char *dest, const char *src,
               size_t len, size_t dest_len)
 {
-    if (len > dest_len) {
+    if (__predict_false(len > dest_len)) {
         __fortify_chk_fail("strncpy buffer overflow",
                              BIONIC_EVENT_STRNCPY_BUFFER_OVERFLOW);
     }
diff --git a/libc/bionic/__umask_chk.cpp b/libc/bionic/__umask_chk.cpp
index ff67ed6..8fe95a2 100644
--- a/libc/bionic/__umask_chk.cpp
+++ b/libc/bionic/__umask_chk.cpp
@@ -42,7 +42,7 @@
  * greater than 0.
  */
 extern "C" mode_t __umask_chk(mode_t mode) {
-    if ((mode & 0777) != mode) {
+    if (__predict_false((mode & 0777) != mode)) {
         __fortify_chk_fail("umask called with invalid mask", 0);
     }
 
diff --git a/libc/bionic/__vsnprintf_chk.cpp b/libc/bionic/__vsnprintf_chk.cpp
index 0fdda3e..2d3a81e 100644
--- a/libc/bionic/__vsnprintf_chk.cpp
+++ b/libc/bionic/__vsnprintf_chk.cpp
@@ -50,7 +50,7 @@
         const char *format,
         va_list va)
 {
-    if (supplied_size > dest_len_from_compiler) {
+    if (__predict_false(supplied_size > dest_len_from_compiler)) {
         __fortify_chk_fail("vsnprintf buffer overflow", 0);
     }
 
diff --git a/libc/bionic/malloc_debug_common.cpp b/libc/bionic/malloc_debug_common.cpp
index 2148d20..f6fa83c 100644
--- a/libc/bionic/malloc_debug_common.cpp
+++ b/libc/bionic/malloc_debug_common.cpp
@@ -524,7 +524,7 @@
  * This routine is called from __libc_init routines implemented
  * in libc_init_static.c and libc_init_dynamic.c files.
  */
-extern "C" void malloc_debug_init() {
+extern "C" __LIBC_HIDDEN__ void malloc_debug_init() {
     /* We need to initialize malloc iff we implement here custom
      * malloc routines (i.e. USE_DL_PREFIX is defined) for libc.so */
 #if defined(USE_DL_PREFIX) && !defined(LIBC_STATIC)
@@ -534,7 +534,7 @@
 #endif  // USE_DL_PREFIX && !LIBC_STATIC
 }
 
-extern "C" void malloc_debug_fini() {
+extern "C" __LIBC_HIDDEN__ void malloc_debug_fini() {
     /* We need to finalize malloc iff we implement here custom
      * malloc routines (i.e. USE_DL_PREFIX is defined) for libc.so */
 #if defined(USE_DL_PREFIX) && !defined(LIBC_STATIC)
diff --git a/libc/bionic/open.c b/libc/bionic/open.c
index e3573a3..424573f 100644
--- a/libc/bionic/open.c
+++ b/libc/bionic/open.c
@@ -52,7 +52,7 @@
 }
 
 int __open_2(const char *pathname, int flags) {
-    if (flags & O_CREAT) {
+    if (__predict_false(flags & O_CREAT)) {
         __fortify_chk_fail("open(O_CREAT) called without specifying a mode", 0);
     }
 
diff --git a/libc/bionic/sched_getaffinity.c b/libc/bionic/sched_getaffinity.cpp
similarity index 76%
rename from libc/bionic/sched_getaffinity.c
rename to libc/bionic/sched_getaffinity.cpp
index 7313822..26f22b1 100644
--- a/libc/bionic/sched_getaffinity.c
+++ b/libc/bionic/sched_getaffinity.cpp
@@ -25,17 +25,21 @@
  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  */
+
 #define _GNU_SOURCE 1
 #include <sched.h>
+#include <string.h>
 
-int  sched_getaffinity(pid_t pid, size_t setsize, cpu_set_t* set)
-{
-    int ret = __sched_getaffinity(pid, setsize, set);
-    if (ret >= 0) {
-        if ((size_t)ret < setsize) {
-            memset((char*)set + ret, '\0', setsize - (size_t)ret);
-        }
-        ret = 0;
-    }
-    return ret;
+extern "C" int __sched_getaffinity(pid_t, size_t, cpu_set_t*);
+
+int sched_getaffinity(pid_t pid, size_t set_size, cpu_set_t* set) {
+  int rc = __sched_getaffinity(pid, set_size, set);
+  if (rc == -1) {
+      return -1;
+  }
+
+  // Clear any bytes the kernel didn't touch.
+  // (The kernel returns the number of bytes written on success.)
+  memset(reinterpret_cast<char*>(set) + rc, 0, set_size - rc);
+  return 0;
 }
diff --git a/libc/string/strchr.c b/libc/bionic/strchr.cpp
similarity index 77%
rename from libc/string/strchr.c
rename to libc/bionic/strchr.cpp
index 29acca5..972029e 100644
--- a/libc/string/strchr.c
+++ b/libc/bionic/strchr.cpp
@@ -1,4 +1,3 @@
-/*	$OpenBSD: index.c,v 1.5 2005/08/08 08:05:37 espie Exp $ */
 /*-
  * Copyright (c) 1990 The Regents of the University of California.
  * All rights reserved.
@@ -31,21 +30,21 @@
 #include <string.h>
 #include "libc_logging.h"
 
-char *
-__strchr_chk(const char *p, int ch, size_t s_len)
-{
-	for (;; ++p, s_len--) {
-		if (s_len == 0)
-			__fortify_chk_fail("strchr read beyond buffer", 0);
-		if (*p == (char) ch)
-			return((char *)p);
-		if (!*p)
-			return((char *)NULL);
-	}
-	/* NOTREACHED */
+extern "C" char* __strchr_chk(const char* p, int ch, size_t s_len) {
+  for (;; ++p, s_len--) {
+    if (__predict_false(s_len == 0)) {
+      __fortify_chk_fail("read beyond buffer", 0);
+    }
+    if (*p == static_cast<char>(ch)) {
+      return const_cast<char*>(p);
+    }
+    if (*p == '\0') {
+      return NULL;
+    }
+  }
+  /* NOTREACHED */
 }
 
-char *
-strchr(const char *p, int ch) {
-    return __strchr_chk(p, ch, __BIONIC_FORTIFY_UNKNOWN_SIZE);
+extern "C" char* strchr(const char* p, int ch) {
+  return __strchr_chk(p, ch, __BIONIC_FORTIFY_UNKNOWN_SIZE);
 }
diff --git a/libc/bionic/sysconf.cpp b/libc/bionic/sysconf.cpp
index 5e39e61..9ab2007 100644
--- a/libc/bionic/sysconf.cpp
+++ b/libc/bionic/sysconf.cpp
@@ -298,8 +298,8 @@
     case _SC_TIMERS:            return _POSIX_TIMERS;
 #endif
 
-    // GETGR_R_SIZE_MAX ?
-    // GETPW_R_SIZE_MAX ?
+    case _SC_GETGR_R_SIZE_MAX: return 1024;
+    case _SC_GETPW_R_SIZE_MAX: return 1024;
 
     case _SC_LOGIN_NAME_MAX:    return SYSTEM_LOGIN_NAME_MAX;
 
diff --git a/libc/include/err.h b/libc/include/err.h
index 1636efe..f24da61 100644
--- a/libc/include/err.h
+++ b/libc/include/err.h
@@ -48,42 +48,42 @@
 __BEGIN_DECLS
 
 __noreturn void	err(int, const char *, ...)
-			__attribute__((__format__ (printf, 2, 3)));
+			__printflike(2, 3);
 __noreturn void	verr(int, const char *, __va_list)
-			__attribute__((__format__ (printf, 2, 0)));
+			__printflike(2, 0);
 __noreturn void	errx(int, const char *, ...)
-			__attribute__((__format__ (printf, 2, 3)));
+			__printflike(2, 3);
 __noreturn void	verrx(int, const char *, __va_list)
-			__attribute__((__format__ (printf, 2, 0)));
+			__printflike(2, 0);
 void		warn(const char *, ...)
-			__attribute__((__format__ (printf, 1, 2)));
+			__printflike(1, 2);
 void		vwarn(const char *, __va_list)
-			__attribute__((__format__ (printf, 1, 0)));
+			__printflike(1, 0);
 void		warnx(const char *, ...)
-			__attribute__((__format__ (printf, 1, 2)));
+			__printflike(1, 2);
 void		vwarnx(const char *, __va_list)
-			__attribute__((__format__ (printf, 1, 0)));
+			__printflike(1, 0);
 
 /*
  * The _* versions are for use in library functions so user-defined
  * versions of err*,warn* do not get used.
  */
 __noreturn void	_err(int, const char *, ...)
-			__attribute__((__format__ (printf, 2, 3)));
+			__printflike(2, 3);
 __noreturn void	_verr(int, const char *, __va_list)
-			__attribute__((__format__ (printf, 2, 0)));
+			__printflike(2, 0);
 __noreturn void	_errx(int, const char *, ...)
-			__attribute__((__format__ (printf, 2, 3)));
+			__printflike(2, 3);
 __noreturn void	_verrx(int, const char *, __va_list)
-			__attribute__((__format__ (printf, 2, 0)));
+			__printflike(2, 0);
 void		_warn(const char *, ...)
-			__attribute__((__format__ (printf, 1, 2)));
+			__printflike(1, 2);
 void		_vwarn(const char *, __va_list)
-			__attribute__((__format__ (printf, 1, 0)));
+			__printflike(1, 0);
 void		_warnx(const char *, ...)
-			__attribute__((__format__ (printf, 1, 2)));
+			__printflike(1, 2);
 void		_vwarnx(const char *, __va_list)
-			__attribute__((__format__ (printf, 1, 0)));
+			__printflike(1, 0);
 
 __END_DECLS
 
diff --git a/libc/include/stdio.h b/libc/include/stdio.h
index fdf747d..aca6d9f 100644
--- a/libc/include/stdio.h
+++ b/libc/include/stdio.h
@@ -139,8 +139,8 @@
 #define	__SMBF	0x0080		/* _buf is from malloc */
 #define	__SAPP	0x0100		/* fdopen()ed in append mode */
 #define	__SSTR	0x0200		/* this is an sprintf/snprintf string */
-#define	__SOPT	0x0400		/* do fseek() optimisation */
-#define	__SNPT	0x0800		/* do not do fseek() optimisation */
+#define	__SOPT	0x0400		/* do fseek() optimization */
+#define	__SNPT	0x0800		/* do not do fseek() optimization */
 #define	__SOFF	0x1000		/* set iff _offset is in fact correct */
 #define	__SMOD	0x2000		/* true => fgetln modified _p text */
 #define	__SALC	0x4000		/* allocate string space dynamically */
@@ -160,14 +160,14 @@
 #define	_IONBF	2		/* setvbuf should set unbuffered */
 
 #define	BUFSIZ	1024		/* size of buffer used by setbuf */
-
 #define	EOF	(-1)
 
 /*
- * FOPEN_MAX is a minimum maximum, and should be the number of descriptors
- * that the kernel can provide without allocation of a resource that can
- * fail without the process sleeping.  Do not use this for anything.
+ * FOPEN_MAX is a minimum maximum, and is the number of streams that
+ * stdio can provide without attempting to allocate further resources
+ * (which could fail).  Do not use this for anything.
  */
+
 #define	FOPEN_MAX	20	/* must be <= OPEN_MAX <sys/syslimits.h> */
 #define	FILENAME_MAX	1024	/* must be <= PATH_MAX <sys/syslimits.h> */
 
@@ -178,6 +178,7 @@
 #define	L_tmpnam	1024	/* XXX must be == PATH_MAX */
 #define	TMP_MAX		308915776
 
+/* Always ensure that these are consistent with <fcntl.h> and <unistd.h>! */
 #ifndef SEEK_SET
 #define	SEEK_SET	0	/* set file offset to offset */
 #endif
@@ -202,25 +203,20 @@
 int	 ferror(FILE *);
 int	 fflush(FILE *);
 int	 fgetc(FILE *);
-int	 fgetpos(FILE *, fpos_t *);
-char	*fgets(char *, int, FILE *);
-FILE	*fopen(const char *, const char *);
-int	 fprintf(FILE *, const char *, ...)
-		__attribute__((__format__ (printf, 2, 3)))
-		__attribute__((__nonnull__ (2)));
+char	*fgets(char * __restrict, int, FILE * __restrict);
+FILE	*fopen(const char * __restrict , const char * __restrict);
+int	 fprintf(FILE * __restrict , const char * __restrict, ...)
+		__printflike(2, 3);
 int	 fputc(int, FILE *);
-int	 fputs(const char *, FILE *);
-size_t	 fread(void *, size_t, size_t, FILE *);
-FILE	*freopen(const char *, const char *, FILE *);
-int	 fscanf(FILE *, const char *, ...)
-		__attribute__ ((__format__ (scanf, 2, 3)))
-		__attribute__ ((__nonnull__ (2)));
+int	 fputs(const char * __restrict, FILE * __restrict);
+size_t	 fread(void * __restrict, size_t, size_t, FILE * __restrict);
+FILE	*freopen(const char * __restrict, const char * __restrict,
+	    FILE * __restrict);
+int	 fscanf(FILE * __restrict, const char * __restrict, ...)
+		__scanflike(2, 3);
 int	 fseek(FILE *, long, int);
-int	 fseeko(FILE *, off_t, int);
-int	 fsetpos(FILE *, const fpos_t *);
 long	 ftell(FILE *);
-off_t	 ftello(FILE *);
-size_t	 fwrite(const void *, size_t, size_t, FILE *);
+size_t	 fwrite(const void * __restrict, size_t, size_t, FILE * __restrict);
 int	 getc(FILE *);
 int	 getchar(void);
 ssize_t	 getdelim(char ** __restrict, size_t * __restrict, int,
@@ -234,55 +230,55 @@
 extern char *sys_errlist[];
 #endif
 void	 perror(const char *);
-int	 printf(const char *, ...)
-		__attribute__((__format__ (printf, 1, 2)))
-		__attribute__((__nonnull__ (1)));
+int	 printf(const char * __restrict, ...)
+		__printflike(1, 2);
 int	 putc(int, FILE *);
 int	 putchar(int);
 int	 puts(const char *);
 int	 remove(const char *);
-int	 rename(const char *, const char *);
 void	 rewind(FILE *);
-int	 scanf(const char *, ...)
-		__attribute__ ((__format__ (scanf, 1, 2)))
-		__attribute__ ((__nonnull__ (1)));
-void	 setbuf(FILE *, char *);
-int	 setvbuf(FILE *, char *, int, size_t);
-int	 sprintf(char *, const char *, ...)
-		__attribute__((__format__ (printf, 2, 3)))
-		__attribute__((__nonnull__ (2)));
-int	 sscanf(const char *, const char *, ...)
-		__attribute__ ((__format__ (scanf, 2, 3)))
-		__attribute__ ((__nonnull__ (2)));
+int	 scanf(const char * __restrict, ...)
+		__scanflike(1, 2);
+void	 setbuf(FILE * __restrict, char * __restrict);
+int	 setvbuf(FILE * __restrict, char * __restrict, int, size_t);
+int	 sscanf(const char * __restrict, const char * __restrict, ...)
+		__scanflike(2, 3);
 FILE	*tmpfile(void);
-char	*tmpnam(char *);
 int	 ungetc(int, FILE *);
-int	 vfprintf(FILE *, const char *, __va_list)
-		__attribute__((__format__ (printf, 2, 0)))
-		__attribute__((__nonnull__ (2)));
-int	 vprintf(const char *, __va_list)
-		__attribute__((__format__ (printf, 1, 0)))
-		__attribute__((__nonnull__ (1)));
-int	 vsprintf(char *, const char *, __va_list)
-		__attribute__((__format__ (printf, 2, 0)))
-		__attribute__((__nonnull__ (2)));
+int	 vfprintf(FILE * __restrict, const char * __restrict, __va_list)
+		__printflike(2, 0);
+int	 vprintf(const char * __restrict, __va_list)
+		__printflike(1, 0);
+
+#ifndef __AUDIT__
+char	*gets(char *);
+int	 sprintf(char * __restrict, const char * __restrict, ...)
+		__printflike(2, 3);
+char	*tmpnam(char *);
+int	 vsprintf(char * __restrict, const char * __restrict,
+    __va_list)
+		__printflike(2, 0);
+#endif
+
+int	 rename (const char *, const char *);
+
+int	 fgetpos(FILE * __restrict, fpos_t * __restrict);
+int	 fsetpos(FILE *, const fpos_t *);
+
+int	 fseeko(FILE *, off_t, int);
+off_t	 ftello(FILE *);
 
 #if __ISO_C_VISIBLE >= 1999 || __BSD_VISIBLE
-int	 snprintf(char *, size_t, const char *, ...)
-		__attribute__((__format__ (printf, 3, 4)))
-		__attribute__((__nonnull__ (3)));
-int	 vfscanf(FILE *, const char *, __va_list)
-		__attribute__((__format__ (scanf, 2, 0)))
-		__attribute__((__nonnull__ (2)));
+int	 snprintf(char * __restrict, size_t, const char * __restrict, ...)
+		__printflike(3, 4);
+int	 vfscanf(FILE * __restrict, const char * __restrict, __va_list)
+		__scanflike(2, 0);
 int	 vscanf(const char *, __va_list)
-		__attribute__((__format__ (scanf, 1, 0)))
-		__attribute__((__nonnull__ (1)));
-int	 vsnprintf(char *, size_t, const char *, __va_list)
-		__attribute__((__format__ (printf, 3, 0)))
-		__attribute__((__nonnull__ (3)));
-int	 vsscanf(const char *, const char *, __va_list)
-		__attribute__((__format__ (scanf, 2, 0)))
-		__attribute__((__nonnull__ (2)));
+		__scanflike(1, 0);
+int	 vsnprintf(char * __restrict, size_t, const char * __restrict, __va_list)
+		__printflike(3, 0);
+int	 vsscanf(const char * __restrict, const char * __restrict, __va_list)
+		__scanflike(2, 0);
 #endif /* __ISO_C_VISIBLE >= 1999 || __BSD_VISIBLE */
 
 __END_DECLS
@@ -335,18 +331,17 @@
  */
 #if __BSD_VISIBLE
 __BEGIN_DECLS
-int	 asprintf(char **, const char *, ...)
-		__attribute__((__format__ (printf, 2, 3)))
-		__attribute__((__nonnull__ (2)));
-char	*fgetln(FILE *, size_t *);
+int	 asprintf(char ** __restrict, const char * __restrict, ...)
+		__printflike(2, 3);
+char	*fgetln(FILE * __restrict, size_t * __restrict);
 int	 fpurge(FILE *);
 int	 getw(FILE *);
 int	 putw(int, FILE *);
 void	 setbuffer(FILE *, char *, int);
 int	 setlinebuf(FILE *);
-int	 vasprintf(char **, const char *, __va_list)
-		__attribute__((__format__ (printf, 2, 0)))
-		__attribute__((__nonnull__ (2)));
+int	 vasprintf(char ** __restrict, const char * __restrict,
+    __va_list)
+		__printflike(2, 0);
 __END_DECLS
 
 /*
@@ -449,11 +444,9 @@
  */
 __BEGIN_DECLS
 int fdprintf(int, const char*, ...)
-		__attribute__((__format__ (printf, 2, 3)))
-		__attribute__((__nonnull__ (2)));
+		__printflike(2, 3);
 int vfdprintf(int, const char*, __va_list)
-		__attribute__((__format__ (printf, 2, 0)))
-		__attribute__((__nonnull__ (2)));
+		__printflike(2, 0);
 __END_DECLS
 #endif /* _GNU_SOURCE */
 
@@ -462,39 +455,33 @@
 __BEGIN_DECLS
 
 __BIONIC_FORTIFY_INLINE
-__attribute__((__format__ (printf, 3, 0)))
-__attribute__((__nonnull__ (3)))
+__printflike(3, 0)
 int vsnprintf(char *dest, size_t size, const char *format, __va_list ap)
 {
-    return __builtin___vsnprintf_chk(dest, size, 0,
-        __builtin_object_size(dest, 0), format, ap);
+    return __builtin___vsnprintf_chk(dest, size, 0, __bos(dest), format, ap);
 }
 
 __BIONIC_FORTIFY_INLINE
-__attribute__((__format__ (printf, 2, 0)))
-__attribute__((__nonnull__ (2)))
+__printflike(2, 0)
 int vsprintf(char *dest, const char *format, __va_list ap)
 {
-    return __builtin___vsprintf_chk(dest, 0,
-        __builtin_object_size(dest, 0), format, ap);
+    return __builtin___vsprintf_chk(dest, 0, __bos(dest), format, ap);
 }
 
 __BIONIC_FORTIFY_INLINE
-__attribute__((__format__ (printf, 3, 4)))
-__attribute__((__nonnull__ (3)))
+__printflike(3, 4)
 int snprintf(char *str, size_t size, const char *format, ...)
 {
     return __builtin___snprintf_chk(str, size, 0,
-        __builtin_object_size(str, 0), format, __builtin_va_arg_pack());
+        __bos(str), format, __builtin_va_arg_pack());
 }
 
 __BIONIC_FORTIFY_INLINE
-__attribute__((__format__ (printf, 2, 3)))
-__attribute__((__nonnull__ (2)))
+__printflike(2, 3)
 int sprintf(char *dest, const char *format, ...)
 {
     return __builtin___sprintf_chk(dest, 0,
-        __builtin_object_size(dest, 0), format, __builtin_va_arg_pack());
+        __bos(dest), format, __builtin_va_arg_pack());
 }
 
 extern char *__fgets_real(char *, int, FILE *)
@@ -508,7 +495,7 @@
 __BIONIC_FORTIFY_INLINE
 char *fgets(char *dest, int size, FILE *stream)
 {
-    size_t bos = __builtin_object_size(dest, 0);
+    size_t bos = __bos(dest);
 
     // Compiler can prove, at compile time, that the passed in size
     // is always negative. Force a compiler error.
diff --git a/libc/include/string.h b/libc/include/string.h
index 56d89a4..f8c573c 100644
--- a/libc/include/string.h
+++ b/libc/include/string.h
@@ -34,11 +34,11 @@
 
 __BEGIN_DECLS
 
-extern void*  memccpy(void *, const void *, int, size_t);
+extern void*  memccpy(void* __restrict, const void* __restrict, int, size_t);
 extern void*  memchr(const void *, int, size_t) __purefunc;
 extern void*  memrchr(const void *, int, size_t) __purefunc;
 extern int    memcmp(const void *, const void *, size_t) __purefunc;
-extern void*  memcpy(void *, const void *, size_t);
+extern void*  memcpy(void* __restrict, const void* __restrict, size_t);
 extern void*  memmove(void *, const void *, size_t);
 extern void*  memset(void *, int, size_t);
 extern void*  memmem(const void *, size_t, const void *, size_t) __purefunc;
@@ -50,8 +50,8 @@
 
 extern size_t strlen(const char *) __purefunc;
 extern int    strcmp(const char *, const char *) __purefunc;
-extern char*  strcpy(char *, const char *);
-extern char*  strcat(char *, const char *);
+extern char*  strcpy(char* __restrict, const char* __restrict);
+extern char*  strcat(char* __restrict, const char* __restrict);
 
 extern int    strcasecmp(const char *, const char *) __purefunc;
 extern int    strncasecmp(const char *, const char *, size_t) __purefunc;
@@ -59,30 +59,30 @@
 
 extern char*  strstr(const char *, const char *) __purefunc;
 extern char*  strcasestr(const char *haystack, const char *needle) __purefunc;
-extern char*  strtok(char *, const char *);
-extern char*  strtok_r(char *, const char *, char**);
+extern char*  strtok(char* __restrict, const char* __restrict);
+extern char*  strtok_r(char* __restrict, const char* __restrict, char** __restrict);
 
 extern char*  strerror(int);
 extern int    strerror_r(int errnum, char *buf, size_t n);
 
 extern size_t strnlen(const char *, size_t) __purefunc;
-extern char*  strncat(char *, const char *, size_t);
+extern char*  strncat(char* __restrict, const char* __restrict, size_t);
 extern char*  strndup(const char *, size_t);
 extern int    strncmp(const char *, const char *, size_t) __purefunc;
-extern char*  strncpy(char *, const char *, size_t);
+extern char*  strncpy(char* __restrict, const char* __restrict, size_t);
 
-extern size_t strlcat(char *, const char *, size_t);
-extern size_t strlcpy(char *, const char *, size_t);
+extern size_t strlcat(char* __restrict, const char* __restrict, size_t);
+extern size_t strlcpy(char* __restrict, const char* __restrict, size_t);
 
 extern size_t strcspn(const char *, const char *) __purefunc;
 extern char*  strpbrk(const char *, const char *) __purefunc;
-extern char*  strsep(char **, const char *);
+extern char*  strsep(char** __restrict, const char* __restrict);
 extern size_t strspn(const char *, const char *);
 
 extern char*  strsignal(int  sig);
 
 extern int    strcoll(const char *, const char *) __purefunc;
-extern size_t strxfrm(char *, const char *, size_t);
+extern size_t strxfrm(char* __restrict, const char* __restrict, size_t);
 
 #if defined(__BIONIC_FORTIFY)
 
@@ -92,7 +92,7 @@
     __attribute__((__error__("memcpy called with size bigger than source")));
 
 __BIONIC_FORTIFY_INLINE
-void *memcpy (void *dest, const void *src, size_t copy_amount) {
+void *memcpy (void* __restrict dest, const void* __restrict src, size_t copy_amount) {
     char *d = (char *) dest;
     const char *s = (const char *) src;
     size_t s_len = __builtin_object_size(s, 0);
@@ -115,23 +115,30 @@
 }
 
 __BIONIC_FORTIFY_INLINE
-char *strcpy(char *dest, const char *src) {
-    return __builtin___strcpy_chk(dest, src, __builtin_object_size (dest, 0));
+char *strcpy(char* __restrict dest, const char* __restrict src) {
+    return __builtin___strcpy_chk(dest, src, __bos(dest));
+}
+
+extern void __strncpy_error()
+    __attribute__((__error__("strncpy called with size bigger than buffer")));
+
+__BIONIC_FORTIFY_INLINE
+char *strncpy(char* __restrict dest, const char* __restrict src, size_t n) {
+    size_t bos = __bos(dest);
+    if (__builtin_constant_p(n) && (n > bos)) {
+        __strncpy_error();
+    }
+    return __builtin___strncpy_chk(dest, src, n, bos);
 }
 
 __BIONIC_FORTIFY_INLINE
-char *strncpy(char *dest, const char *src, size_t n) {
-    return __builtin___strncpy_chk(dest, src, n, __builtin_object_size (dest, 0));
+char *strcat(char* __restrict dest, const char* __restrict src) {
+    return __builtin___strcat_chk(dest, src, __bos(dest));
 }
 
 __BIONIC_FORTIFY_INLINE
-char *strcat(char *dest, const char *src) {
-    return __builtin___strcat_chk(dest, src, __builtin_object_size (dest, 0));
-}
-
-__BIONIC_FORTIFY_INLINE
-char *strncat(char *dest, const char *src, size_t n) {
-    return __builtin___strncat_chk(dest, src, n, __builtin_object_size (dest, 0));
+char *strncat(char* __restrict dest, const char* __restrict src, size_t n) {
+    return __builtin___strncat_chk(dest, src, n, __bos(dest));
 }
 
 __BIONIC_FORTIFY_INLINE
@@ -139,15 +146,15 @@
     return __builtin___memset_chk(s, c, n, __builtin_object_size (s, 0));
 }
 
-extern size_t __strlcpy_real(char *, const char *, size_t)
+extern size_t __strlcpy_real(char* __restrict, const char* __restrict, size_t)
     __asm__(__USER_LABEL_PREFIX__ "strlcpy");
 extern void __strlcpy_error()
     __attribute__((__error__("strlcpy called with size bigger than buffer")));
 extern size_t __strlcpy_chk(char *, const char *, size_t, size_t);
 
 __BIONIC_FORTIFY_INLINE
-size_t strlcpy(char *dest, const char *src, size_t size) {
-    size_t bos = __builtin_object_size(dest, 0);
+size_t strlcpy(char* __restrict dest, const char* __restrict src, size_t size) {
+    size_t bos = __bos(dest);
 
     // Compiler doesn't know destination size. Don't call __strlcpy_chk
     if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
@@ -169,16 +176,16 @@
     return __strlcpy_chk(dest, src, size, bos);
 }
 
-extern size_t __strlcat_real(char *, const char *, size_t)
+extern size_t __strlcat_real(char* __restrict, const char* __restrict, size_t)
     __asm__(__USER_LABEL_PREFIX__ "strlcat");
 extern void __strlcat_error()
     __attribute__((__error__("strlcat called with size bigger than buffer")));
-extern size_t __strlcat_chk(char *, const char *, size_t, size_t);
+extern size_t __strlcat_chk(char* __restrict, const char* __restrict, size_t, size_t);
 
 
 __BIONIC_FORTIFY_INLINE
-size_t strlcat(char *dest, const char *src, size_t size) {
-    size_t bos = __builtin_object_size(dest, 0);
+size_t strlcat(char* __restrict dest, const char* __restrict src, size_t size) {
+    size_t bos = __bos(dest);
 
     // Compiler doesn't know destination size. Don't call __strlcat_chk
     if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
@@ -204,7 +211,7 @@
 
 __BIONIC_FORTIFY_INLINE
 size_t strlen(const char *s) {
-    size_t bos = __builtin_object_size(s, 0);
+    size_t bos = __bos(s);
 
     // Compiler doesn't know destination size. Don't call __strlen_chk
     if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
@@ -223,7 +230,7 @@
 
 __BIONIC_FORTIFY_INLINE
 char* strchr(const char *s, int c) {
-    size_t bos = __builtin_object_size(s, 0);
+    size_t bos = __bos(s);
 
     // Compiler doesn't know destination size. Don't call __strchr_chk
     if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
@@ -242,7 +249,7 @@
 
 __BIONIC_FORTIFY_INLINE
 char* strrchr(const char *s, int c) {
-    size_t bos = __builtin_object_size(s, 0);
+    size_t bos = __bos(s);
 
     // Compiler doesn't know destination size. Don't call __strrchr_chk
     if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
diff --git a/libc/include/sys/cdefs.h b/libc/include/sys/cdefs.h
index 1976d6a..c710356 100644
--- a/libc/include/sys/cdefs.h
+++ b/libc/include/sys/cdefs.h
@@ -211,6 +211,9 @@
 #define __statement(x)	(x)
 #endif
 
+#define __printflike(x, y) __attribute__((__format__(printf, x, y))) __attribute__((__nonnull__(x)))
+#define __scanflike(x, y) __attribute__((__format__(scanf, x, y))) __attribute__((__nonnull__(x)))
+
 /*
  * C99 defines the restrict type qualifier keyword, which was made available
  * in GCC 2.92.
@@ -517,6 +520,12 @@
 
 #if defined(_FORTIFY_SOURCE) && _FORTIFY_SOURCE > 0 && defined(__OPTIMIZE__) && __OPTIMIZE__ > 0 && !defined(__clang__)
 #define __BIONIC_FORTIFY 1
+#if _FORTIFY_SOURCE == 2
+#define __bos(s) __builtin_object_size((s), 1)
+#else
+#define __bos(s) __builtin_object_size((s), 0)
+#endif
+
 #define __BIONIC_FORTIFY_INLINE \
     extern inline \
     __attribute__ ((always_inline)) \
diff --git a/libc/include/sys/epoll.h b/libc/include/sys/epoll.h
index decdb46..38739aa 100644
--- a/libc/include/sys/epoll.h
+++ b/libc/include/sys/epoll.h
@@ -42,6 +42,9 @@
 #define EPOLLWRNORM      0x00000100
 #define EPOLLWRBAND      0x00000200
 #define EPOLLMSG         0x00000400
+#define EPOLLRDHUP       0x00002000
+#define EPOLLWAKEUP      0x20000000
+#define EPOLLONESHOT     0x40000000
 #define EPOLLET          0x80000000
 
 #define EPOLL_CTL_ADD    1
diff --git a/libc/bionic/sched_getaffinity.c b/libc/include/sys/timerfd.h
similarity index 74%
copy from libc/bionic/sched_getaffinity.c
copy to libc/include/sys/timerfd.h
index 7313822..0651f1c 100644
--- a/libc/bionic/sched_getaffinity.c
+++ b/libc/include/sys/timerfd.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2010 The Android Open Source Project
+ * Copyright (C) 2013 The Android Open Source Project
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -25,17 +25,21 @@
  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  */
-#define _GNU_SOURCE 1
-#include <sched.h>
 
-int  sched_getaffinity(pid_t pid, size_t setsize, cpu_set_t* set)
-{
-    int ret = __sched_getaffinity(pid, setsize, set);
-    if (ret >= 0) {
-        if ((size_t)ret < setsize) {
-            memset((char*)set + ret, '\0', setsize - (size_t)ret);
-        }
-        ret = 0;
-    }
-    return ret;
-}
+#ifndef _SYS_TIMERFD_H_
+#define _SYS_TIMERFD_H_
+
+#include <time.h>
+#include <sys/types.h>
+#include <linux/timerfd.h>
+
+__BEGIN_DECLS
+
+extern int timerfd_create(clockid_t, int);
+extern int timerfd_settime(int, int, const struct itimerspec*,
+                           struct itimerspec*);
+extern int timerfd_gettime(int, struct itimerspec*);
+
+__END_DECLS
+
+#endif /* _SYS_TIMERFD_H */
diff --git a/libc/include/time.h b/libc/include/time.h
index e280e0a..8995585 100644
--- a/libc/include/time.h
+++ b/libc/include/time.h
@@ -101,9 +101,12 @@
 #define CLOCK_MONOTONIC            1
 #define CLOCK_PROCESS_CPUTIME_ID   2
 #define CLOCK_THREAD_CPUTIME_ID    3
-#define CLOCK_REALTIME_HR          4
-#define CLOCK_MONOTONIC_HR         5
+#define CLOCK_MONOTONIC_RAW        4
+#define CLOCK_REALTIME_COARSE      5
+#define CLOCK_MONOTONIC_COARSE     6
 #define CLOCK_BOOTTIME             7
+#define CLOCK_REALTIME_ALARM       8
+#define CLOCK_BOOTTIME_ALARM       9
 
 extern int  timer_create(int, struct sigevent*, timer_t*);
 extern int  timer_delete(timer_t);
diff --git a/libc/kernel/common/linux/netfilter_ipv4/ip_tables.h b/libc/kernel/common/linux/netfilter_ipv4/ip_tables.h
index e5e9d66..6f75416 100644
--- a/libc/kernel/common/linux/netfilter_ipv4/ip_tables.h
+++ b/libc/kernel/common/linux/netfilter_ipv4/ip_tables.h
@@ -23,7 +23,7 @@
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #include <linux/netfilter/x_tables.h>
 #define IPT_FUNCTION_MAXNAMELEN XT_FUNCTION_MAXNAMELEN
-#define IPT_TABLE_MAXNAMELEN XT_FUNCTION_MAXNAMELEN
+#define IPT_TABLE_MAXNAMELEN XT_TABLE_MAXNAMELEN
 #define ipt_match xt_match
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define ipt_target xt_target
diff --git a/libc/kernel/common/linux/timerfd.h b/libc/kernel/common/linux/timerfd.h
new file mode 100644
index 0000000..0165ebb
--- /dev/null
+++ b/libc/kernel/common/linux/timerfd.h
@@ -0,0 +1,31 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ***   To edit the content of this header, modify the corresponding
+ ***   source file (e.g. under external/kernel-headers/original/) then
+ ***   run bionic/libc/kernel/tools/update_all.py
+ ***
+ ***   Any manual change here will be lost the next time this script will
+ ***   be run. You've been warned!
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _LINUX_TIMERFD_H
+#define _LINUX_TIMERFD_H
+#include <linux/fcntl.h>
+#define TFD_TIMER_ABSTIME (1 << 0)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define TFD_TIMER_CANCEL_ON_SET (1 << 1)
+#define TFD_CLOEXEC O_CLOEXEC
+#define TFD_NONBLOCK O_NONBLOCK
+#define TFD_SHARED_FCNTL_FLAGS (TFD_CLOEXEC | TFD_NONBLOCK)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define TFD_CREATE_FLAGS TFD_SHARED_FCNTL_FLAGS
+#define TFD_SETTIME_FLAGS (TFD_TIMER_ABSTIME | TFD_TIMER_CANCEL_ON_SET)
+#endif
diff --git a/libc/netbsd/resolv/res_send.c b/libc/netbsd/resolv/res_send.c
index d407ac8..0bb5b6b 100644
--- a/libc/netbsd/resolv/res_send.c
+++ b/libc/netbsd/resolv/res_send.c
@@ -581,8 +581,8 @@
 			if (n == 0)
 				goto next_ns;
 			if (DBG) {
-				__libc_format_log(ANDROID_LOG_DEBUG, "libc",
-					"time=%d, %d\n",time(NULL), time(NULL)%2);
+				__libc_format_log(ANDROID_LOG_DEBUG, "libc", "time=%ld\n",
+                                                  time(NULL));
 			}
 			if (v_circuit)
 				goto same_ns;
@@ -961,7 +961,7 @@
 	fcntl(sock, F_SETFL, origflags);
 	if (DBG) {
 		__libc_format_log(ANDROID_LOG_DEBUG, "libc",
-			"  %d connect_with_timeout returning %s\n", sock, res);
+			"  %d connect_with_timeout returning %d\n", sock, res);
 	}
 	return res;
 }
@@ -1025,7 +1025,7 @@
 	}
 	if (DBG) {
 		__libc_format_log(ANDROID_LOG_DEBUG, "libc",
-			"  %d retrying_select returning %d for %d\n",sock, n);
+			"  %d retrying_select returning %d\n",sock, n);
 	}
 
 	return n;
diff --git a/libc/private/libc_logging.h b/libc/private/libc_logging.h
index 281bad3..c6e1765 100644
--- a/libc/private/libc_logging.h
+++ b/libc/private/libc_logging.h
@@ -79,7 +79,7 @@
 //
 
 __LIBC_HIDDEN__ __noreturn void __libc_fatal(const char* format, ...)
-    __attribute__((__format__(printf, 1, 2)));
+    __printflike(1, 2);
 
 //
 // Formatting routines for the C library's internal debugging.
@@ -87,13 +87,13 @@
 //
 
 __LIBC_HIDDEN__ int __libc_format_buffer(char* buffer, size_t buffer_size, const char* format, ...)
-    __attribute__((__format__(printf, 3, 4)));
+    __printflike(3, 4);
 
 __LIBC_HIDDEN__ int __libc_format_fd(int fd, const char* format, ...)
-    __attribute__((__format__(printf, 2, 3)));
+    __printflike(2, 3);
 
 __LIBC_HIDDEN__ int __libc_format_log(int priority, const char* tag, const char* format, ...)
-    __attribute__((__format__(printf, 3, 4)));
+    __printflike(3, 4);
 
 __LIBC_HIDDEN__ int __libc_format_log_va_list(int priority, const char* tag, const char* format,
                                               va_list ap);
diff --git a/libc/stdio/fgetpos.c b/libc/stdio/fgetpos.c
deleted file mode 100644
index e6188e5..0000000
--- a/libc/stdio/fgetpos.c
+++ /dev/null
@@ -1,43 +0,0 @@
-/*	$OpenBSD: fgetpos.c,v 1.6 2005/08/08 08:05:36 espie Exp $ */
-/*-
- * Copyright (c) 1990, 1993
- *	The Regents of the University of California.  All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Chris Torek.
- *
- * 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 <stdio.h>
-
-/*
- * fgetpos: like ftello.
- */
-int
-fgetpos(FILE *fp, fpos_t *pos)
-{
-	return((*pos = ftello(fp)) == (fpos_t)-1);
-}
diff --git a/libc/stdlib/qsort.c b/libc/stdlib/qsort.c
deleted file mode 100644
index f6fc8e1..0000000
--- a/libc/stdlib/qsort.c
+++ /dev/null
@@ -1,161 +0,0 @@
-/*	$OpenBSD: qsort.c,v 1.10 2005/08/08 08:05:37 espie Exp $ */
-/*-
- * Copyright (c) 1992, 1993
- *	The Regents of the University of California.  All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the University nor the names of its contributors
- *    may be used to endorse or promote products derived from this software
- *    without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#include <sys/types.h>
-#include <stdlib.h>
-
-static __inline char	*med3(char *, char *, char *, int (*)(const void *, const void *));
-static __inline void	 swapfunc(char *, char *, int, int);
-
-#define min(a, b)	(a) < (b) ? a : b
-
-/*
- * Qsort routine from Bentley & McIlroy's "Engineering a Sort Function".
- */
-#define swapcode(TYPE, parmi, parmj, n) {		\
-	long i = (n) / sizeof (TYPE);			\
-	TYPE *pi = (TYPE *) (parmi);			\
-	TYPE *pj = (TYPE *) (parmj);			\
-	do {						\
-		TYPE	t = *pi;			\
-		*pi++ = *pj;				\
-		*pj++ = t;				\
-        } while (--i > 0);				\
-}
-
-#define SWAPINIT(a, es) swaptype = ((char *)a - (char *)0) % sizeof(long) || \
-	es % sizeof(long) ? 2 : es == sizeof(long)? 0 : 1;
-
-static __inline void
-swapfunc(char *a, char *b, int n, int swaptype)
-{
-	if (swaptype <= 1)
-		swapcode(long, a, b, n)
-	else
-		swapcode(char, a, b, n)
-}
-
-#define swap(a, b)					\
-	if (swaptype == 0) {				\
-		long t = *(long *)(a);			\
-		*(long *)(a) = *(long *)(b);		\
-		*(long *)(b) = t;			\
-	} else						\
-		swapfunc(a, b, es, swaptype)
-
-#define vecswap(a, b, n)	if ((n) > 0) swapfunc(a, b, n, swaptype)
-
-static __inline char *
-med3(char *a, char *b, char *c, int (*cmp)(const void *, const void *))
-{
-	return cmp(a, b) < 0 ?
-	       (cmp(b, c) < 0 ? b : (cmp(a, c) < 0 ? c : a ))
-              :(cmp(b, c) > 0 ? b : (cmp(a, c) < 0 ? a : c ));
-}
-
-void
-qsort(void *aa, size_t n, size_t es, int (*cmp)(const void *, const void *))
-{
-	char *pa, *pb, *pc, *pd, *pl, *pm, *pn;
-	int d, r, swaptype, swap_cnt;
-	char *a = aa;
-
-loop:	SWAPINIT(a, es);
-	swap_cnt = 0;
-	if (n < 7) {
-		for (pm = (char *)a + es; pm < (char *) a + n * es; pm += es)
-			for (pl = pm; pl > (char *) a && cmp(pl - es, pl) > 0;
-			     pl -= es)
-				swap(pl, pl - es);
-		return;
-	}
-	pm = (char *)a + (n / 2) * es;
-	if (n > 7) {
-		pl = (char *)a;
-		pn = (char *)a + (n - 1) * es;
-		if (n > 40) {
-			d = (n / 8) * es;
-			pl = med3(pl, pl + d, pl + 2 * d, cmp);
-			pm = med3(pm - d, pm, pm + d, cmp);
-			pn = med3(pn - 2 * d, pn - d, pn, cmp);
-		}
-		pm = med3(pl, pm, pn, cmp);
-	}
-	swap(a, pm);
-	pa = pb = (char *)a + es;
-
-	pc = pd = (char *)a + (n - 1) * es;
-	for (;;) {
-		while (pb <= pc && (r = cmp(pb, a)) <= 0) {
-			if (r == 0) {
-				swap_cnt = 1;
-				swap(pa, pb);
-				pa += es;
-			}
-			pb += es;
-		}
-		while (pb <= pc && (r = cmp(pc, a)) >= 0) {
-			if (r == 0) {
-				swap_cnt = 1;
-				swap(pc, pd);
-				pd -= es;
-			}
-			pc -= es;
-		}
-		if (pb > pc)
-			break;
-		swap(pb, pc);
-		swap_cnt = 1;
-		pb += es;
-		pc -= es;
-	}
-	if (swap_cnt == 0) {  /* Switch to insertion sort */
-		for (pm = (char *) a + es; pm < (char *) a + n * es; pm += es)
-			for (pl = pm; pl > (char *) a && cmp(pl - es, pl) > 0;
-			     pl -= es)
-				swap(pl, pl - es);
-		return;
-	}
-
-	pn = (char *)a + n * es;
-	r = min(pa - (char *)a, pb - pa);
-	vecswap(a, pb - r, r);
-	r = min(pd - pc, pn - pd - (int)es);
-	vecswap(pb, pn - r, r);
-	if ((r = pb - pa) > (int)es)
-		qsort(a, r / es, es, cmp);
-	if ((r = pd - pc) > (int)es) {
-		/* Iterate rather than recurse to save stack space */
-		a = pn - r;
-		n = r / es;
-		goto loop;
-	}
-	/* qsort(pn - r, r / es, es, cmp); */
-}
diff --git a/libc/tools/zoneinfo/generate b/libc/tools/zoneinfo/update-tzdata.py
similarity index 68%
rename from libc/tools/zoneinfo/generate
rename to libc/tools/zoneinfo/update-tzdata.py
index 334ba3c..8956136 100755
--- a/libc/tools/zoneinfo/generate
+++ b/libc/tools/zoneinfo/update-tzdata.py
@@ -3,6 +3,7 @@
 """Updates the tzdata file."""
 
 import ftplib
+import httplib
 import os
 import re
 import subprocess
@@ -58,27 +59,57 @@
   setup.close()
 
 
-def Retrieve(ftp, filename):
-  ftp.retrbinary('RETR %s' % filename, open(filename, 'wb').write)
-
-
-def UpgradeTo(ftp, data_filename):
-  """Downloads and repackages the given data from the given FTP server."""
-
-  new_version = re.search('(tzdata.+)\\.tar\\.gz', data_filename).group(1)
-
-  # Switch to a temporary directory.
+def SwitchToNewTemporaryDirectory():
   tmp_dir = tempfile.mkdtemp('-tzdata')
   os.chdir(tmp_dir)
   print 'Created temporary directory "%s"...' % tmp_dir
 
+
+def FtpRetrieve(ftp, filename):
+  ftp.retrbinary('RETR %s' % filename, open(filename, 'wb').write)
+
+
+def FtpUpgrade(ftp, data_filename):
+  """Downloads and repackages the given data from the given FTP server."""
+  SwitchToNewTemporaryDirectory()
+
   print 'Downloading data...'
-  Retrieve(ftp, data_filename)
+  FtpRetrieve(ftp, data_filename)
 
   print 'Downloading signature...'
   signature_filename = '%s.asc' % data_filename
-  Retrieve(ftp, signature_filename)
+  FtpRetrieve(ftp, signature_filename)
 
+  ExtractAndCompile(data_filename)
+
+
+def HttpRetrieve(http, path, output_filename):
+  http.request("GET", path)
+  f = open(output_filename, 'wb')
+  f.write(http.getresponse().read())
+  f.close()
+
+
+def HttpUpgrade(http, data_filename):
+  """Downloads and repackages the given data from the given HTTP server."""
+  SwitchToNewTemporaryDirectory()
+
+  path = "/time-zones/repository/releases/%s" % data_filename
+
+  print 'Downloading data...'
+  HttpRetrieve(http, path, data_filename)
+
+  print 'Downloading signature...'
+  signature_filename = '%s.asc' % data_filename
+  HttpRetrieve(http, "%s.asc" % path, signature_filename)
+
+  ExtractAndCompile(data_filename)
+
+
+def ExtractAndCompile(data_filename):
+  new_version = re.search('(tzdata.+)\\.tar\\.gz', data_filename).group(1)
+
+  signature_filename = '%s.asc' % data_filename
   print 'Verifying signature...'
   # If this fails for you, you probably need to import Paul Eggert's public key:
   # gpg --recv-keys ED97E90E62AA7E34
@@ -113,14 +144,29 @@
 # See http://www.iana.org/time-zones/ for more about the source of this data.
 def main():
   print 'Looking for new tzdata...'
-  ftp = ftplib.FTP('ftp.iana.org')
-  ftp.login()
-  ftp.cwd('tz/releases')
+
   tzdata_filenames = []
-  for filename in ftp.nlst():
-    if filename.startswith('tzdata20') and filename.endswith('.tar.gz'):
-      tzdata_filenames.append(filename)
-  tzdata_filenames.sort()
+
+  # The FTP server lets you download intermediate releases, and also lets you
+  # download the signatures for verification, so it's your best choice.
+  use_ftp = True
+
+  if use_ftp:
+    ftp = ftplib.FTP('ftp.iana.org')
+    ftp.login()
+    ftp.cwd('tz/releases')
+    for filename in ftp.nlst():
+      if filename.startswith('tzdata20') and filename.endswith('.tar.gz'):
+        tzdata_filenames.append(filename)
+    tzdata_filenames.sort()
+  else:
+    http = httplib.HTTPConnection('www.iana.org')
+    http.request("GET", "/time-zones")
+    index_lines = http.getresponse().read().split('\n')
+    for line in index_lines:
+      m = re.compile('.*href="/time-zones/repository/releases/(tzdata20\d\d\c\.tar\.gz)".*').match(line)
+      if m:
+        tzdata_filenames.append(m.group(1))
 
   # If you're several releases behind, we'll walk you through the upgrades
   # one by one.
@@ -129,7 +175,10 @@
   for filename in tzdata_filenames:
     if filename > current_filename:
       print 'Found new tzdata: %s' % filename
-      UpgradeTo(ftp, filename)
+      if use_ftp:
+        FtpUpgrade(ftp, filename)
+      else:
+        HttpUpgrade(http, filename)
       sys.exit(0)
 
   print 'You already have the latest tzdata (%s)!' % current_version
diff --git a/libc/tzcode/localtime.c b/libc/tzcode/localtime.c
index 8a54e81..0c4d268 100644
--- a/libc/tzcode/localtime.c
+++ b/libc/tzcode/localtime.c
@@ -2276,14 +2276,18 @@
     int32_t data_offset;
     int32_t zonetab_offset;
   } header;
-  if (TEMP_FAILURE_RETRY(read(fd, &header, sizeof(header))) != sizeof(header)) {
-    fprintf(stderr, "%s: could not read header: %s\n", __FUNCTION__, strerror(errno));
+  memset(&header, 0, sizeof(header));
+  ssize_t bytes_read = TEMP_FAILURE_RETRY(read(fd, &header, sizeof(header)));
+  if (bytes_read != sizeof(header)) {
+    fprintf(stderr, "%s: could not read header of \"%s\": %s\n",
+            __FUNCTION__, path, (bytes_read == -1) ? strerror(errno) : "short read");
     close(fd);
     return -1;
   }
 
   if (strncmp(header.tzdata_version, "tzdata", 6) != 0 || header.tzdata_version[11] != 0) {
-    fprintf(stderr, "%s: bad magic: %s\n", __FUNCTION__, header.tzdata_version);
+    fprintf(stderr, "%s: bad magic in \"%s\": \"%.6s\"\n",
+            __FUNCTION__, path, header.tzdata_version);
     close(fd);
     return -1;
   }
@@ -2296,7 +2300,8 @@
 #endif
 
   if (TEMP_FAILURE_RETRY(lseek(fd, ntohl(header.index_offset), SEEK_SET)) == -1) {
-    fprintf(stderr, "%s: couldn't seek to index: %s\n", __FUNCTION__, strerror(errno));
+    fprintf(stderr, "%s: couldn't seek to index in \"%s\": %s\n",
+            __FUNCTION__, path, strerror(errno));
     close(fd);
     return -1;
   }
@@ -2330,11 +2335,14 @@
   }
 
   if (TEMP_FAILURE_RETRY(lseek(fd, specific_zone_offset, SEEK_SET)) == -1) {
-    fprintf(stderr, "%s: could not seek to %ld: %s\n", __FUNCTION__, specific_zone_offset, strerror(errno));
+    fprintf(stderr, "%s: could not seek to %ld in \"%s\": %s\n",
+            __FUNCTION__, specific_zone_offset, path, strerror(errno));
     close(fd);
     return -1;
   }
 
+  // TODO: check that there's TZ_MAGIC at this offset, so we can fall back to the other file if not.
+
   return fd;
 }
 
diff --git a/libc/upstream-freebsd/freebsd-compat.h b/libc/upstream-freebsd/freebsd-compat.h
index 08dec15..697ddcb 100644
--- a/libc/upstream-freebsd/freebsd-compat.h
+++ b/libc/upstream-freebsd/freebsd-compat.h
@@ -17,4 +17,12 @@
 #ifndef _BIONIC_FREEBSD_COMPAT_H_included
 #define _BIONIC_FREEBSD_COMPAT_H_included
 
+#define __USE_BSD
+
+#define _close close
+#define _fcntl fcntl
+#define _open open
+
+#define _sseek __sseek /* Needed as long as we have a mix of OpenBSD and FreeBSD stdio. */
+
 #endif
diff --git a/libc/stdio/clrerr.c b/libc/upstream-freebsd/lib/libc/stdio/clrerr.c
similarity index 82%
rename from libc/stdio/clrerr.c
rename to libc/upstream-freebsd/lib/libc/stdio/clrerr.c
index cb6c4df..f161a6e 100644
--- a/libc/stdio/clrerr.c
+++ b/libc/upstream-freebsd/lib/libc/stdio/clrerr.c
@@ -1,4 +1,3 @@
-/*	$OpenBSD: clrerr.c,v 1.6 2005/08/08 08:05:36 espie Exp $ */
 /*-
  * Copyright (c) 1990, 1993
  *	The Regents of the University of California.  All rights reserved.
@@ -31,9 +30,19 @@
  * SUCH DAMAGE.
  */
 
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)clrerr.c	8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include "namespace.h"
 #include <stdio.h>
-#include "local.h"
-#undef	clearerr
+#include "un-namespace.h"
+#include "libc_private.h"
+
+#undef clearerr
+#undef clearerr_unlocked
 
 void
 clearerr(FILE *fp)
@@ -42,3 +51,10 @@
 	__sclearerr(fp);
 	FUNLOCKFILE(fp);
 }
+
+void
+clearerr_unlocked(FILE *fp)
+{
+
+	__sclearerr(fp);
+}
diff --git a/libc/stdio/fclose.c b/libc/upstream-freebsd/lib/libc/stdio/fclose.c
similarity index 75%
rename from libc/stdio/fclose.c
rename to libc/upstream-freebsd/lib/libc/stdio/fclose.c
index 8c3bac4..5ed8b2c 100644
--- a/libc/stdio/fclose.c
+++ b/libc/upstream-freebsd/lib/libc/stdio/fclose.c
@@ -1,4 +1,3 @@
-/*	$OpenBSD: fclose.c,v 1.6 2005/08/08 08:05:36 espie Exp $ */
 /*-
  * Copyright (c) 1990, 1993
  *	The Regents of the University of California.  All rights reserved.
@@ -31,9 +30,19 @@
  * SUCH DAMAGE.
  */
 
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)fclose.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 <stdio.h>
 #include <stdlib.h>
+#include "un-namespace.h"
+#include <spinlock.h>
+#include "libc_private.h"
 #include "local.h"
 
 int
@@ -46,7 +55,6 @@
 		return (EOF);
 	}
 	FLOCKFILE(fp);
-	WCIO_FREE(fp);
 	r = fp->_flags & __SWR ? __sflush(fp) : 0;
 	if (fp->_close != NULL && (*fp->_close)(fp->_cookie) < 0)
 		r = EOF;
@@ -56,8 +64,22 @@
 		FREEUB(fp);
 	if (HASLB(fp))
 		FREELB(fp);
+	fp->_file = -1;
 	fp->_r = fp->_w = 0;	/* Mess up if reaccessed. */
+
+	/*
+	 * Lock the spinlock used to protect __sglue list walk in
+	 * __sfp().  The __sfp() uses fp->_flags == 0 test as an
+	 * indication of the unused FILE.
+	 *
+	 * Taking the lock prevents possible compiler or processor
+	 * reordering of the writes performed before the final _flags
+	 * cleanup, making sure that we are done with the FILE before
+	 * it is considered available.
+	 */
+	STDIO_THREAD_LOCK();
 	fp->_flags = 0;		/* Release this FILE for reuse. */
+	STDIO_THREAD_UNLOCK();
 	FUNLOCKFILE(fp);
 	return (r);
 }
diff --git a/libc/stdio/fdopen.c b/libc/upstream-freebsd/lib/libc/stdio/fdopen.c
similarity index 74%
rename from libc/stdio/fdopen.c
rename to libc/upstream-freebsd/lib/libc/stdio/fdopen.c
index 1df609c..2e19b9f 100644
--- a/libc/stdio/fdopen.c
+++ b/libc/upstream-freebsd/lib/libc/stdio/fdopen.c
@@ -1,4 +1,3 @@
-/*	$OpenBSD: fdopen.c,v 1.5 2005/08/08 08:05:36 espie Exp $ */
 /*-
  * Copyright (c) 1990, 1993
  *	The Regents of the University of California.  All rights reserved.
@@ -31,11 +30,20 @@
  * SUCH DAMAGE.
  */
 
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)fdopen.c	8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include "namespace.h"
 #include <sys/types.h>
 #include <fcntl.h>
 #include <unistd.h>
 #include <stdio.h>
 #include <errno.h>
+#include <limits.h>
+#include "un-namespace.h"
 #include "local.h"
 
 FILE *
@@ -44,11 +52,23 @@
 	FILE *fp;
 	int flags, oflags, fdflags, tmp;
 
+	/*
+	 * File descriptors are a full int, but _file is only a short.
+	 * If we get a valid file descriptor that is greater than
+	 * SHRT_MAX, then the fd will get sign-extended into an
+	 * invalid file descriptor.  Handle this case by failing the
+	 * open.
+	 */
+	if (fd > SHRT_MAX) {
+		errno = EMFILE;
+		return (NULL);
+	}
+
 	if ((flags = __sflags(mode, &oflags)) == 0)
 		return (NULL);
 
 	/* Make sure the mode the user wants is a subset of the actual mode. */
-	if ((fdflags = fcntl(fd, F_GETFL, 0)) < 0)
+	if ((fdflags = _fcntl(fd, F_GETFL, 0)) < 0)
 		return (NULL);
 	tmp = fdflags & O_ACCMODE;
 	if (tmp != O_RDWR && (tmp != (oflags & O_ACCMODE))) {
@@ -58,11 +78,17 @@
 
 	if ((fp = __sfp()) == NULL)
 		return (NULL);
+
+	if ((oflags & O_CLOEXEC) && _fcntl(fd, F_SETFD, FD_CLOEXEC) == -1) {
+		fp->_flags = 0;
+		return (NULL);
+	}
+
 	fp->_flags = flags;
 	/*
 	 * If opened for appending, but underlying descriptor does not have
-	 * O_APPEND bit set, assert __SAPP so that __swrite() will lseek to
-	 * end before each write.
+	 * O_APPEND bit set, assert __SAPP so that __swrite() caller
+	 * will _sseek() to the end before write.
 	 */
 	if ((oflags & O_APPEND) && !(fdflags & O_APPEND))
 		fp->_flags |= __SAPP;
diff --git a/libc/stdio/feof.c b/libc/upstream-freebsd/lib/libc/stdio/feof.c
similarity index 82%
rename from libc/stdio/feof.c
rename to libc/upstream-freebsd/lib/libc/stdio/feof.c
index 0fa65b0..b970248 100644
--- a/libc/stdio/feof.c
+++ b/libc/upstream-freebsd/lib/libc/stdio/feof.c
@@ -1,4 +1,3 @@
-/*	$OpenBSD: feof.c,v 1.5 2005/08/08 08:05:36 espie Exp $ */
 /*-
  * Copyright (c) 1990, 1993
  *	The Regents of the University of California.  All rights reserved.
@@ -31,21 +30,34 @@
  * SUCH DAMAGE.
  */
 
-#include <stdio.h>
-#include "local.h"
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)feof.c	8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
 
-/*
- * A subroutine version of the macro feof.
- */
+#include "namespace.h"
+#include <stdio.h>
+#include "un-namespace.h"
+#include "libc_private.h"
+
 #undef feof
+#undef feof_unlocked
 
 int
 feof(FILE *fp)
 {
-	int ret;
+	int	ret;
 
 	FLOCKFILE(fp);
-	ret = __sfeof(fp);
+	ret= __sfeof(fp);
 	FUNLOCKFILE(fp);
 	return (ret);
 }
+
+int
+feof_unlocked(FILE *fp)
+{
+
+	return (__sfeof(fp));
+}
diff --git a/libc/stdio/ferror.c b/libc/upstream-freebsd/lib/libc/stdio/ferror.c
similarity index 81%
rename from libc/stdio/ferror.c
rename to libc/upstream-freebsd/lib/libc/stdio/ferror.c
index 0d2cf01..7e0f8f9 100644
--- a/libc/stdio/ferror.c
+++ b/libc/upstream-freebsd/lib/libc/stdio/ferror.c
@@ -1,4 +1,3 @@
-/*	$OpenBSD: ferror.c,v 1.5 2005/08/08 08:05:36 espie Exp $ */
 /*-
  * Copyright (c) 1990, 1993
  *	The Regents of the University of California.  All rights reserved.
@@ -31,15 +30,34 @@
  * SUCH DAMAGE.
  */
 
-#include <stdio.h>
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)ferror.c	8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
 
-/*
- * A subroutine version of the macro ferror.
- */
+#include "namespace.h"
+#include <stdio.h>
+#include "un-namespace.h"
+#include "libc_private.h"
+
 #undef ferror
+#undef ferror_unlocked
 
 int
 ferror(FILE *fp)
 {
+	int	ret;
+
+	FLOCKFILE(fp);
+	ret = __sferror(fp);
+	FUNLOCKFILE(fp);
+	return (ret);
+}
+
+int
+ferror_unlocked(FILE *fp)
+{
+
 	return (__sferror(fp));
 }
diff --git a/libc/stdio/fgetln.c b/libc/upstream-freebsd/lib/libc/stdio/fgetln.c
similarity index 85%
rename from libc/stdio/fgetln.c
rename to libc/upstream-freebsd/lib/libc/stdio/fgetln.c
index 0947dd8..1779de2 100644
--- a/libc/stdio/fgetln.c
+++ b/libc/upstream-freebsd/lib/libc/stdio/fgetln.c
@@ -1,4 +1,3 @@
-/*	$OpenBSD: fgetln.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.
@@ -31,9 +30,18 @@
  * SUCH DAMAGE.
  */
 
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)fgetln.c	8.2 (Berkeley) 1/2/94";
+#endif /* LIBC_SCCS and not lint */
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include "namespace.h"
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
+#include "un-namespace.h"
+#include "libc_private.h"
 #include "local.h"
 
 /*
@@ -43,7 +51,7 @@
  * so we add 1 here.
 #endif
  */
-static int
+int
 __slbexpand(FILE *fp, size_t newsize)
 {
 	void *p;
@@ -51,7 +59,7 @@
 #ifdef notdef
 	++newsize;
 #endif
-	if ((size_t)fp->_lb._size >= newsize)
+	if (fp->_lb._size >= newsize)
 		return (0);
 	if ((p = realloc(fp->_lb._base, newsize)) == NULL)
 		return (-1);
@@ -62,7 +70,7 @@
 
 /*
  * Get an input line.  The returned pointer often (but not always)
- * points into a stdio buffer.  Fgetline does not alter the text of
+ * points into a stdio buffer.  Fgetln does not alter the text of
  * the returned line (which is thus not a C string because it will
  * not necessarily end with '\0'), but does allow callers to modify
  * it if they wish.  Thus, we set __SMOD in case the caller does.
@@ -71,18 +79,22 @@
 fgetln(FILE *fp, size_t *lenp)
 {
 	unsigned char *p;
-	char *ret;
 	size_t len;
 	size_t off;
 
 	FLOCKFILE(fp);
-
+	ORIENT(fp, -1);
 	/* make sure there is input */
-	if (fp->_r <= 0 && __srefill(fp))
-		goto error;
+	if (fp->_r <= 0 && __srefill(fp)) {
+		*lenp = 0;
+		FUNLOCKFILE(fp);
+		return (NULL);
+	}
 
 	/* look for a newline in the input */
-	if ((p = memchr((void *)fp->_p, '\n', fp->_r)) != NULL) {
+	if ((p = memchr((void *)fp->_p, '\n', (size_t)fp->_r)) != NULL) {
+		char *ret;
+
 		/*
 		 * Found one.  Flag buffer as modified to keep fseek from
 		 * `optimising' a backward seek, in case the user stomps on
@@ -123,7 +135,7 @@
 		off = len;
 		if (__srefill(fp))
 			break;	/* EOF or error: return partial line */
-		if ((p = memchr((void *)fp->_p, '\n', fp->_r)) == NULL)
+		if ((p = memchr((void *)fp->_p, '\n', (size_t)fp->_r)) == NULL)
 			continue;
 
 		/* got it: finish up the line (like code above) */
@@ -139,12 +151,11 @@
 		break;
 	}
 	*lenp = len;
-	ret = (char *)fp->_lb._base;
 #ifdef notdef
-	ret[len] = '\0';
+	fp->_lb._base[len] = 0;
 #endif
 	FUNLOCKFILE(fp);
-	return (ret);
+	return ((char *)fp->_lb._base);
 
 error:
 	*lenp = 0;		/* ??? */
diff --git a/libc/stdio/remove.c b/libc/upstream-freebsd/lib/libc/stdio/fgetpos.c
similarity index 82%
copy from libc/stdio/remove.c
copy to libc/upstream-freebsd/lib/libc/stdio/fgetpos.c
index d09d76f..f161f43 100644
--- a/libc/stdio/remove.c
+++ b/libc/upstream-freebsd/lib/libc/stdio/fgetpos.c
@@ -1,5 +1,3 @@
-/*	$OpenBSD: remove.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.
@@ -32,18 +30,22 @@
  * SUCH DAMAGE.
  */
 
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)fgetpos.c	8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
 #include <stdio.h>
-#include <unistd.h>
-#include <sys/stat.h>
 
 int
-remove(const char *file)
+fgetpos(FILE * __restrict fp, fpos_t * __restrict pos)
 {
-	struct stat st;
-
-	if (lstat(file, &st) < 0)
+	/*
+	 * ftello is thread-safe; no need to lock fp.
+	 */
+	if ((*pos = ftello(fp)) == (fpos_t)-1)
 		return (-1);
-	if (S_ISDIR(st.st_mode))
-		return (rmdir(file));
-	return (unlink(file));
+	else
+		return (0);
 }
diff --git a/libc/stdio/fgets.c b/libc/upstream-freebsd/lib/libc/stdio/fgets.c
similarity index 86%
rename from libc/stdio/fgets.c
rename to libc/upstream-freebsd/lib/libc/stdio/fgets.c
index 311b7b2..9abf559 100644
--- a/libc/stdio/fgets.c
+++ b/libc/upstream-freebsd/lib/libc/stdio/fgets.c
@@ -1,4 +1,3 @@
-/*	$OpenBSD: fgets.c,v 1.10 2005/08/08 08:05:36 espie Exp $ */
 /*-
  * Copyright (c) 1990, 1993
  *	The Regents of the University of California.  All rights reserved.
@@ -31,18 +30,26 @@
  * SUCH DAMAGE.
  */
 
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)fgets.c	8.2 (Berkeley) 12/22/93";
+#endif /* LIBC_SCCS and not lint */
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include "namespace.h"
 #include <stdio.h>
 #include <string.h>
+#include "un-namespace.h"
 #include "local.h"
+#include "libc_private.h"
 
 /*
  * Read at most n-1 characters from the given file.
  * Stop when a newline has been read, or the count runs out.
  * Return first argument, or NULL if no characters were read.
- * Do not return NULL if n == 1.
  */
 char *
-fgets(char *buf, int n, FILE *fp)
+fgets(char * __restrict buf, int n, FILE * __restrict fp)
 {
 	size_t len;
 	char *s;
@@ -52,24 +59,24 @@
 		return (NULL);
 
 	FLOCKFILE(fp);
-	_SET_ORIENTATION(fp, -1);
+	ORIENT(fp, -1);
 	s = buf;
 	n--;			/* leave space for NUL */
 	while (n != 0) {
 		/*
 		 * If the buffer is empty, refill it.
 		 */
-		if (fp->_r <= 0) {
+		if ((len = fp->_r) <= 0) {
 			if (__srefill(fp)) {
 				/* EOF/error: stop with partial or no line */
 				if (s == buf) {
 					FUNLOCKFILE(fp);
 					return (NULL);
-                                }
+				}
 				break;
 			}
+			len = fp->_r;
 		}
-		len = fp->_r;
 		p = fp->_p;
 
 		/*
@@ -78,7 +85,7 @@
 		 * newline, and stop.  Otherwise, copy entire chunk
 		 * and loop.
 		 */
-		if ((int)len > n)
+		if (len > n)
 			len = n;
 		t = memchr((void *)p, '\n', len);
 		if (t != NULL) {
@@ -86,7 +93,7 @@
 			fp->_r -= len;
 			fp->_p = t;
 			(void)memcpy((void *)s, (void *)p, len);
-			s[len] = '\0';
+			s[len] = 0;
 			FUNLOCKFILE(fp);
 			return (buf);
 		}
@@ -96,7 +103,7 @@
 		s += len;
 		n -= len;
 	}
-	*s = '\0';
+	*s = 0;
 	FUNLOCKFILE(fp);
 	return (buf);
 }
diff --git a/libc/stdio/fileno.c b/libc/upstream-freebsd/lib/libc/stdio/fileno.c
similarity index 81%
rename from libc/stdio/fileno.c
rename to libc/upstream-freebsd/lib/libc/stdio/fileno.c
index cbefdeb..3ac1830 100644
--- a/libc/stdio/fileno.c
+++ b/libc/upstream-freebsd/lib/libc/stdio/fileno.c
@@ -1,4 +1,3 @@
-/*	$OpenBSD: fileno.c,v 1.5 2005/08/08 08:05:36 espie Exp $ */
 /*-
  * Copyright (c) 1990, 1993
  *	The Regents of the University of California.  All rights reserved.
@@ -31,21 +30,35 @@
  * SUCH DAMAGE.
  */
 
-#include <stdio.h>
-#include "local.h"
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)fileno.c	8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
 
-/*
- * A subroutine version of the macro fileno.
- */
+#include "namespace.h"
+#include <stdio.h>
+#include "un-namespace.h"
+#include "libc_private.h"
+
 #undef fileno
+#undef fileno_unlocked
 
 int
 fileno(FILE *fp)
 {
-	int ret;
+	int fd;
 
 	FLOCKFILE(fp);
-	ret = __sfileno(fp);
+	fd = __sfileno(fp);
 	FUNLOCKFILE(fp);
-	return (ret);
+
+	return (fd);
+}
+
+int
+fileno_unlocked(FILE *fp)
+{
+
+	return (__sfileno(fp));
 }
diff --git a/libc/stdio/flags.c b/libc/upstream-freebsd/lib/libc/stdio/flags.c
similarity index 76%
rename from libc/stdio/flags.c
rename to libc/upstream-freebsd/lib/libc/stdio/flags.c
index dde0447..1878c2f 100644
--- a/libc/stdio/flags.c
+++ b/libc/upstream-freebsd/lib/libc/stdio/flags.c
@@ -1,4 +1,3 @@
-/*	$OpenBSD: flags.c,v 1.6 2005/08/08 08:05:36 espie Exp $ */
 /*-
  * Copyright (c) 1990, 1993
  *	The Regents of the University of California.  All rights reserved.
@@ -31,15 +30,22 @@
  * SUCH DAMAGE.
  */
 
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)flags.c	8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
 #include <sys/types.h>
 #include <sys/file.h>
 #include <stdio.h>
 #include <errno.h>
-#include <fcntl.h>
+
+#include "local.h"
 
 /*
  * Return the (stdio) flags for a given mode.  Store the flags
- * to be passed to an open() syscall through *optr.
+ * to be passed to an _open() syscall through *optr.
  * Return 0 on error.
  */
 int
@@ -72,11 +78,35 @@
 		return (0);
 	}
 
-	/* [rwa]\+ or [rwa]b\+ means read and write */
-	if (*mode == '+' || (*mode == 'b' && mode[1] == '+')) {
+	/* 'b' (binary) is ignored */
+	if (*mode == 'b')
+		mode++;
+
+	/* [rwa][b]\+ means read and write */
+	if (*mode == '+') {
+		mode++;
 		ret = __SRW;
 		m = O_RDWR;
 	}
+
+	/* 'b' (binary) can appear here, too -- and is ignored again */
+	if (*mode == 'b')
+		mode++;
+
+	/* 'x' means exclusive (fail if the file exists) */
+	if (*mode == 'x') {
+		mode++;
+		if (m == O_RDONLY) {
+			errno = EINVAL;
+			return (0);
+		}
+		o |= O_EXCL;
+	}
+
+	/* set close-on-exec */
+	if (*mode == 'e')
+		o |= O_CLOEXEC;
+
 	*optr = m | o;
 	return (ret);
 }
diff --git a/libc/stdio/fopen.c b/libc/upstream-freebsd/lib/libc/stdio/fopen.c
similarity index 75%
rename from libc/stdio/fopen.c
rename to libc/upstream-freebsd/lib/libc/stdio/fopen.c
index 6d2d882..b08e336 100644
--- a/libc/stdio/fopen.c
+++ b/libc/upstream-freebsd/lib/libc/stdio/fopen.c
@@ -1,4 +1,3 @@
-/*	$OpenBSD: fopen.c,v 1.5 2005/08/08 08:05:36 espie Exp $ */
 /*-
  * Copyright (c) 1990, 1993
  *	The Regents of the University of California.  All rights reserved.
@@ -31,18 +30,26 @@
  * SUCH DAMAGE.
  */
 
-#define __USE_BSD
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)fopen.c	8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
 
+#include "namespace.h"
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <fcntl.h>
+#include <unistd.h>
 #include <stdio.h>
 #include <errno.h>
+#include <limits.h>
+#include "un-namespace.h"
+
 #include "local.h"
-#include <linux/stat.h>
 
 FILE *
-fopen(const char *file, const char *mode)
+fopen(const char * __restrict file, const char * __restrict mode)
 {
 	FILE *fp;
 	int f;
@@ -52,10 +59,23 @@
 		return (NULL);
 	if ((fp = __sfp()) == NULL)
 		return (NULL);
-	if ((f = open(file, oflags, DEFFILEMODE)) < 0) {
+	if ((f = _open(file, oflags, DEFFILEMODE)) < 0) {
 		fp->_flags = 0;			/* release */
 		return (NULL);
 	}
+	/*
+	 * File descriptors are a full int, but _file is only a short.
+	 * If we get a valid file descriptor that is greater than
+	 * SHRT_MAX, then the fd will get sign-extended into an
+	 * invalid file descriptor.  Handle this case by failing the
+	 * open.
+	 */
+	if (f > SHRT_MAX) {
+		fp->_flags = 0;			/* release */
+		_close(f);
+		errno = EMFILE;
+		return (NULL);
+	}
 	fp->_file = f;
 	fp->_flags = flags;
 	fp->_cookie = fp;
@@ -63,7 +83,6 @@
 	fp->_write = __swrite;
 	fp->_seek = __sseek;
 	fp->_close = __sclose;
-
 	/*
 	 * When opening in append mode, even though we use O_APPEND,
 	 * we need to seek to the end so that ftell() gets the right
@@ -73,6 +92,6 @@
 	 * fseek and ftell.)
 	 */
 	if (oflags & O_APPEND)
-		(void) __sseek((void *)fp, (fpos_t)0, SEEK_END);
+		(void)_sseek(fp, (fpos_t)0, SEEK_END);
 	return (fp);
 }
diff --git a/libc/stdio/fpurge.c b/libc/upstream-freebsd/lib/libc/stdio/fpurge.c
similarity index 80%
rename from libc/stdio/fpurge.c
rename to libc/upstream-freebsd/lib/libc/stdio/fpurge.c
index e04c4fe..f205bdf 100644
--- a/libc/stdio/fpurge.c
+++ b/libc/upstream-freebsd/lib/libc/stdio/fpurge.c
@@ -1,4 +1,3 @@
-/*	$OpenBSD: fpurge.c,v 1.6 2005/08/08 08:05:36 espie Exp $ */
 /*-
  * Copyright (c) 1990, 1993
  *	The Regents of the University of California.  All rights reserved.
@@ -31,10 +30,19 @@
  * SUCH DAMAGE.
  */
 
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)fpurge.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 <stdio.h>
 #include <stdlib.h>
+#include "un-namespace.h"
 #include "local.h"
+#include "libc_private.h"
 
 /*
  * fpurge: like fflush, but without writing anything: leave the
@@ -43,19 +51,19 @@
 int
 fpurge(FILE *fp)
 {
+	int retval;
 	FLOCKFILE(fp);
 	if (!fp->_flags) {
-		FUNLOCKFILE(fp);
 		errno = EBADF;
-		return(EOF);
+		retval = EOF;
+	} else {
+		if (HASUB(fp))
+			FREEUB(fp);
+		fp->_p = fp->_bf._base;
+		fp->_r = 0;
+		fp->_w = fp->_flags & (__SLBF|__SNBF|__SRD) ? 0 : fp->_bf._size;
+		retval = 0;
 	}
-
-	if (HASUB(fp))
-		FREEUB(fp);
-	WCIO_FREE(fp);
-	fp->_p = fp->_bf._base;
-	fp->_r = 0;
-	fp->_w = fp->_flags & (__SLBF|__SNBF) ? 0 : fp->_bf._size;
 	FUNLOCKFILE(fp);
-	return (0);
+	return (retval);
 }
diff --git a/libc/stdio/fputs.c b/libc/upstream-freebsd/lib/libc/stdio/fputs.c
similarity index 83%
rename from libc/stdio/fputs.c
rename to libc/upstream-freebsd/lib/libc/stdio/fputs.c
index c2462ba..3b8f2c9 100644
--- a/libc/stdio/fputs.c
+++ b/libc/upstream-freebsd/lib/libc/stdio/fputs.c
@@ -1,4 +1,3 @@
-/*	$OpenBSD: fputs.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.
@@ -31,28 +30,37 @@
  * SUCH DAMAGE.
  */
 
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)fputs.c	8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include "namespace.h"
 #include <stdio.h>
 #include <string.h>
-#include "local.h"
+#include "un-namespace.h"
 #include "fvwrite.h"
+#include "libc_private.h"
+#include "local.h"
 
 /*
  * Write the given string to the given file.
  */
 int
-fputs(const char *s, FILE *fp)
+fputs(const char * __restrict s, FILE * __restrict fp)
 {
+	int retval;
 	struct __suio uio;
 	struct __siov iov;
-	int ret;
 
 	iov.iov_base = (void *)s;
 	iov.iov_len = uio.uio_resid = strlen(s);
 	uio.uio_iov = &iov;
 	uio.uio_iovcnt = 1;
 	FLOCKFILE(fp);
-	_SET_ORIENTATION(fp, -1);
-	ret = __sfvwrite(fp, &uio);
+	ORIENT(fp, -1);
+	retval = __sfvwrite(fp, &uio);
 	FUNLOCKFILE(fp);
-	return (ret);
+	return (retval);
 }
diff --git a/libc/stdio/fsetpos.c b/libc/upstream-freebsd/lib/libc/stdio/fsetpos.c
similarity index 88%
rename from libc/stdio/fsetpos.c
rename to libc/upstream-freebsd/lib/libc/stdio/fsetpos.c
index 9624fe5..c6b8b78 100644
--- a/libc/stdio/fsetpos.c
+++ b/libc/upstream-freebsd/lib/libc/stdio/fsetpos.c
@@ -1,4 +1,3 @@
-/*	$OpenBSD: fsetpos.c,v 1.6 2005/08/08 08:05:36 espie Exp $ */
 /*-
  * Copyright (c) 1990, 1993
  *	The Regents of the University of California.  All rights reserved.
@@ -31,10 +30,17 @@
  * SUCH DAMAGE.
  */
 
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)fsetpos.c	8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/types.h>
 #include <stdio.h>
 
 /*
- * fsetpos: like fseeko.
+ * fsetpos: like fseek.
  */
 int
 fsetpos(FILE *iop, const fpos_t *pos)
diff --git a/libc/stdio/funopen.c b/libc/upstream-freebsd/lib/libc/stdio/funopen.c
similarity index 86%
rename from libc/stdio/funopen.c
rename to libc/upstream-freebsd/lib/libc/stdio/funopen.c
index b85ee96..983fe50 100644
--- a/libc/stdio/funopen.c
+++ b/libc/upstream-freebsd/lib/libc/stdio/funopen.c
@@ -1,4 +1,3 @@
-/*	$OpenBSD: funopen.c,v 1.8 2005/08/08 08:05:36 espie Exp $ */
 /*-
  * Copyright (c) 1990, 1993
  *	The Regents of the University of California.  All rights reserved.
@@ -31,14 +30,23 @@
  * SUCH DAMAGE.
  */
 
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)funopen.c	8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
 #include <stdio.h>
 #include <errno.h>
+
 #include "local.h"
 
 FILE *
-funopen(const void *cookie, int (*readfn)(void *, char *, int),
+funopen(const void *cookie,
+	int (*readfn)(void *, char *, int),
 	int (*writefn)(void *, const char *, int),
-	fpos_t (*seekfn)(void *, fpos_t, int), int (*closefn)(void *))
+	fpos_t (*seekfn)(void *, fpos_t, int),
+	int (*closefn)(void *))
 {
 	FILE *fp;
 	int flags;
@@ -59,7 +67,7 @@
 		return (NULL);
 	fp->_flags = flags;
 	fp->_file = -1;
-	fp->_cookie = (void *)cookie;		/* SAFE: cookie not modified */
+	fp->_cookie = (void *)cookie;
 	fp->_read = readfn;
 	fp->_write = writefn;
 	fp->_seek = seekfn;
diff --git a/libc/stdio/fwalk.c b/libc/upstream-freebsd/lib/libc/stdio/fwalk.c
similarity index 78%
rename from libc/stdio/fwalk.c
rename to libc/upstream-freebsd/lib/libc/stdio/fwalk.c
index b1df891..151837b 100644
--- a/libc/stdio/fwalk.c
+++ b/libc/upstream-freebsd/lib/libc/stdio/fwalk.c
@@ -1,4 +1,3 @@
-/*	$OpenBSD: fwalk.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.
@@ -31,7 +30,13 @@
  * SUCH DAMAGE.
  */
 
-#include <errno.h>
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)fwalk.c	8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/types.h>
 #include <stdio.h>
 #include "local.h"
 #include "glue.h"
@@ -44,10 +49,17 @@
 	struct glue *g;
 
 	ret = 0;
+	/*
+	 * It should be safe to walk the list without locking it;
+	 * new nodes are only added to the end and none are ever
+	 * removed.
+	 *
+	 * Avoid locking this list while walking it or else you will
+	 * introduce a potential deadlock in [at least] refill.c.
+	 */
 	for (g = &__sglue; g != NULL; g = g->next)
-		for (fp = g->iobs, n = g->niobs; --n >= 0; fp++) {
+		for (fp = g->iobs, n = g->niobs; --n >= 0; fp++)
 			if ((fp->_flags != 0) && ((fp->_flags & __SIGN) == 0))
 				ret |= (*function)(fp);
-		}
 	return (ret);
 }
diff --git a/libc/stdio/fwrite.c b/libc/upstream-freebsd/lib/libc/stdio/fwrite.c
similarity index 67%
rename from libc/stdio/fwrite.c
rename to libc/upstream-freebsd/lib/libc/stdio/fwrite.c
index a97313e..707d362 100644
--- a/libc/stdio/fwrite.c
+++ b/libc/upstream-freebsd/lib/libc/stdio/fwrite.c
@@ -1,4 +1,3 @@
-/*	$OpenBSD: fwrite.c,v 1.5 2005/08/08 08:05:36 espie Exp $ */
 /*-
  * Copyright (c) 1990, 1993
  *	The Regents of the University of California.  All rights reserved.
@@ -31,36 +30,67 @@
  * 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 "local.h"
 #include "fvwrite.h"
+#include "libc_private.h"
 
 /*
  * Write `count' objects (each size `size') from memory to the given file.
  * Return the number of whole objects written.
  */
 size_t
-fwrite(const void *buf, size_t size, size_t count, FILE *fp)
+fwrite(const void * __restrict buf, size_t size, size_t count, FILE * __restrict 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.
+	 */
+	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;
+		fp->_flags |= __SERR;
+		return (0);
+	}
+
+	n = count * size;
 
 	iov.iov_base = (void *)buf;
-	uio.uio_resid = iov.iov_len = n = count * size;
+	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.
 	 */
-	FLOCKFILE(fp);
-	ret = __sfvwrite(fp, &uio);
+	if (__sfvwrite(fp, &uio) != 0)
+	    count = (n - uio.uio_resid) / size;
 	FUNLOCKFILE(fp);
-	if (ret == 0)
-		return (count);
-	return ((n - uio.uio_resid) / size);
+	return (count);
 }
diff --git a/libc/stdio/getc.c b/libc/upstream-freebsd/lib/libc/stdio/getc.c
similarity index 82%
rename from libc/stdio/getc.c
rename to libc/upstream-freebsd/lib/libc/stdio/getc.c
index 16a5b1d..4963c8c 100644
--- a/libc/stdio/getc.c
+++ b/libc/upstream-freebsd/lib/libc/stdio/getc.c
@@ -1,4 +1,3 @@
-/*	$OpenBSD: getc.c,v 1.6 2005/08/08 08:05:36 espie Exp $ */
 /*-
  * Copyright (c) 1990, 1993
  *	The Regents of the University of California.  All rights reserved.
@@ -31,32 +30,36 @@
  * SUCH DAMAGE.
  */
 
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)getc.c	8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include "namespace.h"
 #include <stdio.h>
+#include "un-namespace.h"
+#include "libc_private.h"
 #include "local.h"
 
-/*
- * A subroutine version of the macro getc_unlocked.
- */
-#undef getc_unlocked
-
-int
-getc_unlocked(FILE *fp)
-{
-	return (__sgetc(fp));
-}
-
-/*
- * A subroutine version of the macro getc.
- */
 #undef getc
+#undef getc_unlocked
 
 int
 getc(FILE *fp)
 {
-	int c;
-
+	int retval;
 	FLOCKFILE(fp);
-	c = __sgetc(fp);
+	/* Orientation set by __sgetc() when buffer is empty. */
+	/* ORIENT(fp, -1); */
+	retval = __sgetc(fp);
 	FUNLOCKFILE(fp);
-	return (c);
+	return (retval);
+}
+
+int
+getc_unlocked(FILE *fp)
+{
+
+	return (__sgetc(fp));
 }
diff --git a/libc/stdio/getchar.c b/libc/upstream-freebsd/lib/libc/stdio/getchar.c
similarity index 78%
rename from libc/stdio/getchar.c
rename to libc/upstream-freebsd/lib/libc/stdio/getchar.c
index 550817d..21040bc 100644
--- a/libc/stdio/getchar.c
+++ b/libc/upstream-freebsd/lib/libc/stdio/getchar.c
@@ -1,4 +1,3 @@
-/*	$OpenBSD: getchar.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.
@@ -31,28 +30,39 @@
  * SUCH DAMAGE.
  */
 
-#include <stdio.h>
-
-/*
- * A subroutine version of the macro getchar_unlocked.
- */
-#undef getchar_unlocked
-
-int
-getchar_unlocked(void)
-{
-	return (getc_unlocked(stdin));
-}
-
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)getchar.c	8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
 
 /*
  * A subroutine version of the macro getchar.
  */
+#include "namespace.h"
+#include <stdio.h>
+#include "un-namespace.h"
+#include "local.h"
+#include "libc_private.h"
 
 #undef getchar
+#undef getchar_unlocked
 
 int
-getchar(void)
+getchar()
 {
-	return (getc(stdin));
+	int retval;
+	FLOCKFILE(stdin);
+	/* Orientation set by __sgetc() when buffer is empty. */
+	/* ORIENT(stdin, -1); */
+	retval = __sgetc(stdin);
+	FUNLOCKFILE(stdin);
+	return (retval);
+}
+
+int
+getchar_unlocked(void)
+{
+
+	return (__sgetc(stdin));
 }
diff --git a/libc/stdio/putc.c b/libc/upstream-freebsd/lib/libc/stdio/putc.c
similarity index 79%
rename from libc/stdio/putc.c
rename to libc/upstream-freebsd/lib/libc/stdio/putc.c
index 2b05504..aaffece 100644
--- a/libc/stdio/putc.c
+++ b/libc/upstream-freebsd/lib/libc/stdio/putc.c
@@ -1,4 +1,3 @@
-/*	$OpenBSD: putc.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.
@@ -31,37 +30,36 @@
  * SUCH DAMAGE.
  */
 
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)putc.c	8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include "namespace.h"
 #include <stdio.h>
-#include <errno.h>
+#include "un-namespace.h"
 #include "local.h"
+#include "libc_private.h"
 
-/*
- * A subroutine version of the macro putc_unlocked.
- */
-#undef putc_unlocked
-
-int
-putc_unlocked(int c, FILE *fp)
-{
-	if (cantwrite(fp)) {
-		errno = EBADF;
-		return (EOF);
-	}
-	return (__sputc(c, fp));
-}
-
-/*
- * A subroutine version of the macro putc.
- */
 #undef putc
+#undef putc_unlocked
 
 int
 putc(int c, FILE *fp)
 {
-	int ret;
-
+	int retval;
 	FLOCKFILE(fp);
-	ret = putc_unlocked(c, fp);
+	/* Orientation set by __sputc() when buffer is full. */
+	/* ORIENT(fp, -1); */
+	retval = __sputc(c, fp);
 	FUNLOCKFILE(fp);
-	return (ret);
+	return (retval);
+}
+
+int
+putc_unlocked(int ch, FILE *fp)
+{
+
+	return (__sputc(ch, fp));
 }
diff --git a/libc/stdio/putchar.c b/libc/upstream-freebsd/lib/libc/stdio/putchar.c
similarity index 78%
rename from libc/stdio/putchar.c
rename to libc/upstream-freebsd/lib/libc/stdio/putchar.c
index eeed0a2..7561559 100644
--- a/libc/stdio/putchar.c
+++ b/libc/upstream-freebsd/lib/libc/stdio/putchar.c
@@ -1,4 +1,3 @@
-/*	$OpenBSD: putchar.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.
@@ -31,21 +30,20 @@
  * SUCH DAMAGE.
  */
 
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)putchar.c	8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include "namespace.h"
 #include <stdio.h>
-
-#undef putchar_unlocked
-/*
- * A subrouting version of the macro putchar_unlocked
- */
-int
-putchar_unlocked(int c)
-{
-	FILE *so = stdout;
-
-	return (putc_unlocked(c, so));
-}
+#include "un-namespace.h"
+#include "local.h"
+#include "libc_private.h"
 
 #undef putchar
+#undef putchar_unlocked
 
 /*
  * A subroutine version of the macro putchar
@@ -53,7 +51,20 @@
 int
 putchar(int c)
 {
+	int retval;
 	FILE *so = stdout;
 
-	return (putc(c, so));
+	FLOCKFILE(so);
+	/* Orientation set by __sputc() when buffer is full. */
+	/* ORIENT(so, -1); */
+	retval = __sputc(c, so);
+	FUNLOCKFILE(so);
+	return (retval);
+}
+
+int
+putchar_unlocked(int ch)
+{
+
+	return (__sputc(ch, stdout));
 }
diff --git a/libc/stdio/puts.c b/libc/upstream-freebsd/lib/libc/stdio/puts.c
similarity index 84%
rename from libc/stdio/puts.c
rename to libc/upstream-freebsd/lib/libc/stdio/puts.c
index 4603a3d..5ee7fc1 100644
--- a/libc/stdio/puts.c
+++ b/libc/upstream-freebsd/lib/libc/stdio/puts.c
@@ -1,4 +1,3 @@
-/*	$OpenBSD: puts.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.
@@ -31,21 +30,30 @@
  * SUCH DAMAGE.
  */
 
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)puts.c	8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include "namespace.h"
 #include <stdio.h>
 #include <string.h>
-#include "local.h"
+#include "un-namespace.h"
 #include "fvwrite.h"
+#include "libc_private.h"
+#include "local.h"
 
 /*
  * Write the given string to stdout, appending a newline.
  */
 int
-puts(const char *s)
+puts(char const *s)
 {
+	int retval;
 	size_t c = strlen(s);
 	struct __suio uio;
 	struct __siov iov[2];
-	int ret;
 
 	iov[0].iov_base = (void *)s;
 	iov[0].iov_len = c;
@@ -55,7 +63,8 @@
 	uio.uio_iov = &iov[0];
 	uio.uio_iovcnt = 2;
 	FLOCKFILE(stdout);
-	ret = __sfvwrite(stdout, &uio);
+	ORIENT(stdout, -1);
+	retval = __sfvwrite(stdout, &uio) ? EOF : '\n';
 	FUNLOCKFILE(stdout);
-	return (ret ? EOF : '\n');
+	return (retval);
 }
diff --git a/libc/stdio/putw.c b/libc/upstream-freebsd/lib/libc/stdio/putw.c
similarity index 83%
rename from libc/stdio/putw.c
rename to libc/upstream-freebsd/lib/libc/stdio/putw.c
index 12955fe..0360caf 100644
--- a/libc/stdio/putw.c
+++ b/libc/upstream-freebsd/lib/libc/stdio/putw.c
@@ -1,4 +1,3 @@
-/*	$OpenBSD: putw.c,v 1.6 2005/08/08 08:05:36 espie Exp $ */
 /*-
  * Copyright (c) 1990, 1993
  *	The Regents of the University of California.  All rights reserved.
@@ -31,12 +30,22 @@
  * SUCH DAMAGE.
  */
 
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)putw.c	8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include "namespace.h"
 #include <stdio.h>
+#include "un-namespace.h"
 #include "fvwrite.h"
+#include "libc_private.h"
 
 int
 putw(int w, FILE *fp)
 {
+	int retval;
 	struct __suio uio;
 	struct __siov iov;
 
@@ -44,5 +53,8 @@
 	iov.iov_len = uio.uio_resid = sizeof(w);
 	uio.uio_iov = &iov;
 	uio.uio_iovcnt = 1;
-	return (__sfvwrite(fp, &uio));
+	FLOCKFILE(fp);
+	retval = __sfvwrite(fp, &uio);
+	FUNLOCKFILE(fp);
+	return (retval);
 }
diff --git a/libc/stdio/remove.c b/libc/upstream-freebsd/lib/libc/stdio/remove.c
similarity index 86%
rename from libc/stdio/remove.c
rename to libc/upstream-freebsd/lib/libc/stdio/remove.c
index d09d76f..2e984ba 100644
--- a/libc/stdio/remove.c
+++ b/libc/upstream-freebsd/lib/libc/stdio/remove.c
@@ -1,5 +1,3 @@
-/*	$OpenBSD: remove.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.
@@ -32,18 +30,25 @@
  * SUCH DAMAGE.
  */
 
-#include <stdio.h>
-#include <unistd.h>
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)remove.c	8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/types.h>
 #include <sys/stat.h>
+#include <unistd.h>
+#include <stdio.h>
 
 int
 remove(const char *file)
 {
-	struct stat st;
+	struct stat sb;
 
-	if (lstat(file, &st) < 0)
+	if (lstat(file, &sb) < 0)
 		return (-1);
-	if (S_ISDIR(st.st_mode))
+	if (S_ISDIR(sb.st_mode))
 		return (rmdir(file));
 	return (unlink(file));
 }
diff --git a/libc/stdio/rget.c b/libc/upstream-freebsd/lib/libc/stdio/rget.c
similarity index 91%
rename from libc/stdio/rget.c
rename to libc/upstream-freebsd/lib/libc/stdio/rget.c
index 4cd97cb..bdc0311 100644
--- a/libc/stdio/rget.c
+++ b/libc/upstream-freebsd/lib/libc/stdio/rget.c
@@ -1,4 +1,3 @@
-/*	$OpenBSD: rget.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.
@@ -31,6 +30,12 @@
  * SUCH DAMAGE.
  */
 
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)rget.c	8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
 #include <stdio.h>
 #include "local.h"
 
@@ -42,7 +47,6 @@
 int
 __srget(FILE *fp)
 {
-	_SET_ORIENTATION(fp, -1);
 	if (__srefill(fp) == 0) {
 		fp->_r--;
 		return (*fp->_p++);
diff --git a/libc/stdio/setbuf.c b/libc/upstream-freebsd/lib/libc/stdio/setbuf.c
similarity index 87%
rename from libc/stdio/setbuf.c
rename to libc/upstream-freebsd/lib/libc/stdio/setbuf.c
index 883b895..5c65f97 100644
--- a/libc/stdio/setbuf.c
+++ b/libc/upstream-freebsd/lib/libc/stdio/setbuf.c
@@ -1,4 +1,3 @@
-/*	$OpenBSD: setbuf.c,v 1.5 2005/08/08 08:05:36 espie Exp $ */
 /*-
  * Copyright (c) 1990, 1993
  *	The Regents of the University of California.  All rights reserved.
@@ -31,11 +30,17 @@
  * SUCH DAMAGE.
  */
 
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)setbuf.c	8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
 #include <stdio.h>
 #include "local.h"
 
 void
-setbuf(FILE *fp, char *buf)
+setbuf(FILE * __restrict fp, char * __restrict buf)
 {
 	(void) setvbuf(fp, buf, buf ? _IOFBF : _IONBF, BUFSIZ);
 }
diff --git a/libc/stdio/setbuffer.c b/libc/upstream-freebsd/lib/libc/stdio/setbuffer.c
similarity index 87%
rename from libc/stdio/setbuffer.c
rename to libc/upstream-freebsd/lib/libc/stdio/setbuffer.c
index 8725ff7..af5eb3c 100644
--- a/libc/stdio/setbuffer.c
+++ b/libc/upstream-freebsd/lib/libc/stdio/setbuffer.c
@@ -1,4 +1,3 @@
-/*	$OpenBSD: setbuffer.c,v 1.5 2005/08/08 08:05:36 espie Exp $ */
 /*-
  * Copyright (c) 1990, 1993
  *	The Regents of the University of California.  All rights reserved.
@@ -31,13 +30,19 @@
  * SUCH DAMAGE.
  */
 
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)setbuffer.c	8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
 #include <stdio.h>
 
 void
 setbuffer(FILE *fp, char *buf, int size)
 {
 
-	(void)setvbuf(fp, buf, buf ? _IOFBF : _IONBF, size);
+	(void)setvbuf(fp, buf, buf ? _IOFBF : _IONBF, (size_t)size);
 }
 
 /*
diff --git a/libc/stdio/tempnam.c b/libc/upstream-freebsd/lib/libc/stdio/tempnam.c
similarity index 85%
rename from libc/stdio/tempnam.c
rename to libc/upstream-freebsd/lib/libc/stdio/tempnam.c
index 3b7ec75..e15746f 100644
--- a/libc/stdio/tempnam.c
+++ b/libc/upstream-freebsd/lib/libc/stdio/tempnam.c
@@ -1,4 +1,3 @@
-/*	$OpenBSD: tempnam.c,v 1.14 2005/08/08 08:05:36 espie Exp $ */
 /*
  * Copyright (c) 1988, 1993
  *	The Regents of the University of California.  All rights reserved.
@@ -28,6 +27,12 @@
  * SUCH DAMAGE.
  */
 
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)tempnam.c	8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
 #include <sys/param.h>
 #include <errno.h>
 #include <stdio.h>
@@ -54,26 +59,26 @@
 		pfx = "tmp.";
 
 	if (issetugid() == 0 && (f = getenv("TMPDIR"))) {
-		(void)snprintf(name, MAXPATHLEN, "%s%s%sXXXXXXXXXX", f,
+		(void)snprintf(name, MAXPATHLEN, "%s%s%sXXXXXX", f,
 		    *(f + strlen(f) - 1) == '/'? "": "/", pfx);
 		if ((f = _mktemp(name)))
 			return(f);
 	}
 
 	if ((f = (char *)dir)) {
-		(void)snprintf(name, MAXPATHLEN, "%s%s%sXXXXXXXXXX", f,
+		(void)snprintf(name, MAXPATHLEN, "%s%s%sXXXXXX", f,
 		    *(f + strlen(f) - 1) == '/'? "": "/", pfx);
 		if ((f = _mktemp(name)))
 			return(f);
 	}
 
 	f = P_tmpdir;
-	(void)snprintf(name, MAXPATHLEN, "%s%sXXXXXXXXX", f, pfx);
+	(void)snprintf(name, MAXPATHLEN, "%s%sXXXXXX", f, pfx);
 	if ((f = _mktemp(name)))
 		return(f);
 
 	f = _PATH_TMP;
-	(void)snprintf(name, MAXPATHLEN, "%s%sXXXXXXXXX", f, pfx);
+	(void)snprintf(name, MAXPATHLEN, "%s%sXXXXXX", f, pfx);
 	if ((f = _mktemp(name)))
 		return(f);
 
diff --git a/libc/stdio/tmpnam.c b/libc/upstream-freebsd/lib/libc/stdio/tmpnam.c
similarity index 88%
rename from libc/stdio/tmpnam.c
rename to libc/upstream-freebsd/lib/libc/stdio/tmpnam.c
index 32e0a22..ce32dcc 100644
--- a/libc/stdio/tmpnam.c
+++ b/libc/upstream-freebsd/lib/libc/stdio/tmpnam.c
@@ -1,4 +1,3 @@
-/*	$OpenBSD: tmpnam.c,v 1.10 2005/08/08 08:05:36 espie Exp $ */
 /*-
  * Copyright (c) 1990, 1993, 1994
  *	The Regents of the University of California.  All rights reserved.
@@ -31,6 +30,12 @@
  * SUCH DAMAGE.
  */
 
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)tmpnam.c	8.3 (Berkeley) 3/28/94";
+#endif /* LIBC_SCCS and not lint */
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
 #include <sys/types.h>
 
 #include <stdio.h>
@@ -49,7 +54,7 @@
 
 	if (s == NULL)
 		s = buf;
-	(void)snprintf(s, L_tmpnam, "%stmp.%lu.XXXXXXXXX", P_tmpdir, tmpcount);
+	(void)snprintf(s, L_tmpnam, "%stmp.%lu.XXXXXX", P_tmpdir, tmpcount);
 	++tmpcount;
 	return (_mktemp(s));
 }
diff --git a/libc/stdio/wsetup.c b/libc/upstream-freebsd/lib/libc/stdio/wsetup.c
similarity index 86%
rename from libc/stdio/wsetup.c
rename to libc/upstream-freebsd/lib/libc/stdio/wsetup.c
index 0834223..70f8247 100644
--- a/libc/stdio/wsetup.c
+++ b/libc/upstream-freebsd/lib/libc/stdio/wsetup.c
@@ -1,4 +1,3 @@
-/*	$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.
@@ -31,6 +30,13 @@
  * 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"
@@ -38,7 +44,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, nonzero otherwise.
+ * _wsetup returns 0 if OK to write; otherwise, it returns EOF and sets errno.
  */
 int
 __swsetup(FILE *fp)
@@ -51,8 +57,11 @@
 	 * If we are not writing, we had better be reading and writing.
 	 */
 	if ((fp->_flags & __SWR) == 0) {
-		if ((fp->_flags & __SRW) == 0)
+		if ((fp->_flags & __SRW) == 0) {
+			errno = EBADF;
+			fp->_flags |= __SERR;
 			return (EOF);
+		}
 		if (fp->_flags & __SRD) {
 			/* clobber any ungetc data */
 			if (HASUB(fp))
@@ -67,11 +76,8 @@
 	/*
 	 * Make a buffer if necessary, then set _w.
 	 */
-	if (fp->_bf._base == NULL) {
-		if ((fp->_flags & (__SSTR | __SALC)) == __SSTR)
-			return (EOF);
+	if (fp->_bf._base == NULL)
 		__smakebuf(fp);
-	}
 	if (fp->_flags & __SLBF) {
 		/*
 		 * It is line buffered, so make _lbfsize be -_bufsize
diff --git a/libc/upstream-freebsd/lib/libc/stdlib/qsort.c b/libc/upstream-freebsd/lib/libc/stdlib/qsort.c
new file mode 100644
index 0000000..3687b05
--- /dev/null
+++ b/libc/upstream-freebsd/lib/libc/stdlib/qsort.c
@@ -0,0 +1,195 @@
+/*-
+ * Copyright (c) 1992, 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.
+ * 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.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)qsort.c	8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <stdlib.h>
+
+#ifdef I_AM_QSORT_R
+typedef int		 cmp_t(void *, const void *, const void *);
+#else
+typedef int		 cmp_t(const void *, const void *);
+#endif
+static inline char	*med3(char *, char *, char *, cmp_t *, void *);
+static inline void	 swapfunc(char *, char *, int, int);
+
+#define min(a, b)	(a) < (b) ? a : b
+
+/*
+ * Qsort routine from Bentley & McIlroy's "Engineering a Sort Function".
+ */
+#define swapcode(TYPE, parmi, parmj, n) { 		\
+	long i = (n) / sizeof (TYPE); 			\
+	TYPE *pi = (TYPE *) (parmi); 		\
+	TYPE *pj = (TYPE *) (parmj); 		\
+	do { 						\
+		TYPE	t = *pi;		\
+		*pi++ = *pj;				\
+		*pj++ = t;				\
+        } while (--i > 0);				\
+}
+
+#define SWAPINIT(a, es) swaptype = ((char *)a - (char *)0) % sizeof(long) || \
+	es % sizeof(long) ? 2 : es == sizeof(long)? 0 : 1;
+
+static inline void
+swapfunc(a, b, n, swaptype)
+	char *a, *b;
+	int n, swaptype;
+{
+	if(swaptype <= 1)
+		swapcode(long, a, b, n)
+	else
+		swapcode(char, a, b, n)
+}
+
+#define swap(a, b)					\
+	if (swaptype == 0) {				\
+		long t = *(long *)(a);			\
+		*(long *)(a) = *(long *)(b);		\
+		*(long *)(b) = t;			\
+	} else						\
+		swapfunc(a, b, es, swaptype)
+
+#define vecswap(a, b, n) 	if ((n) > 0) swapfunc(a, b, n, swaptype)
+
+#ifdef I_AM_QSORT_R
+#define	CMP(t, x, y) (cmp((t), (x), (y)))
+#else
+#define	CMP(t, x, y) (cmp((x), (y)))
+#endif
+
+static inline char *
+med3(char *a, char *b, char *c, cmp_t *cmp, void *thunk
+#ifndef I_AM_QSORT_R
+__unused
+#endif
+)
+{
+	return CMP(thunk, a, b) < 0 ?
+	       (CMP(thunk, b, c) < 0 ? b : (CMP(thunk, a, c) < 0 ? c : a ))
+              :(CMP(thunk, b, c) > 0 ? b : (CMP(thunk, a, c) < 0 ? a : c ));
+}
+
+#ifdef I_AM_QSORT_R
+void
+qsort_r(void *a, size_t n, size_t es, void *thunk, cmp_t *cmp)
+#else
+#define thunk NULL
+void
+qsort(void *a, size_t n, size_t es, cmp_t *cmp)
+#endif
+{
+	char *pa, *pb, *pc, *pd, *pl, *pm, *pn;
+	size_t d, r;
+	int cmp_result;
+	int swaptype, swap_cnt;
+
+loop:	SWAPINIT(a, es);
+	swap_cnt = 0;
+	if (n < 7) {
+		for (pm = (char *)a + es; pm < (char *)a + n * es; pm += es)
+			for (pl = pm; 
+			     pl > (char *)a && CMP(thunk, pl - es, pl) > 0;
+			     pl -= es)
+				swap(pl, pl - es);
+		return;
+	}
+	pm = (char *)a + (n / 2) * es;
+	if (n > 7) {
+		pl = a;
+		pn = (char *)a + (n - 1) * es;
+		if (n > 40) {
+			d = (n / 8) * es;
+			pl = med3(pl, pl + d, pl + 2 * d, cmp, thunk);
+			pm = med3(pm - d, pm, pm + d, cmp, thunk);
+			pn = med3(pn - 2 * d, pn - d, pn, cmp, thunk);
+		}
+		pm = med3(pl, pm, pn, cmp, thunk);
+	}
+	swap(a, pm);
+	pa = pb = (char *)a + es;
+
+	pc = pd = (char *)a + (n - 1) * es;
+	for (;;) {
+		while (pb <= pc && (cmp_result = CMP(thunk, pb, a)) <= 0) {
+			if (cmp_result == 0) {
+				swap_cnt = 1;
+				swap(pa, pb);
+				pa += es;
+			}
+			pb += es;
+		}
+		while (pb <= pc && (cmp_result = CMP(thunk, pc, a)) >= 0) {
+			if (cmp_result == 0) {
+				swap_cnt = 1;
+				swap(pc, pd);
+				pd -= es;
+			}
+			pc -= es;
+		}
+		if (pb > pc)
+			break;
+		swap(pb, pc);
+		swap_cnt = 1;
+		pb += es;
+		pc -= es;
+	}
+	if (swap_cnt == 0) {  /* Switch to insertion sort */
+		for (pm = (char *)a + es; pm < (char *)a + n * es; pm += es)
+			for (pl = pm; 
+			     pl > (char *)a && CMP(thunk, pl - es, pl) > 0;
+			     pl -= es)
+				swap(pl, pl - es);
+		return;
+	}
+
+	pn = (char *)a + n * es;
+	r = min(pa - (char *)a, pb - pa);
+	vecswap(a, pb - r, r);
+	r = min(pd - pc, pn - pd - es);
+	vecswap(pb, pn - r, r);
+	if ((r = pb - pa) > es)
+#ifdef I_AM_QSORT_R
+		qsort_r(a, r / es, es, thunk, cmp);
+#else
+		qsort(a, r / es, es, cmp);
+#endif
+	if ((r = pd - pc) > es) {
+		/* Iterate rather than recurse to save stack space */
+		a = pn - r;
+		n = r / es;
+		goto loop;
+	}
+/*		qsort(pn - r, r / es, es, cmp);*/
+}
diff --git a/libc/upstream-freebsd/libc_private.h b/libc/upstream-freebsd/libc_private.h
new file mode 100644
index 0000000..ecdbb7e
--- /dev/null
+++ b/libc/upstream-freebsd/libc_private.h
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef _BIONIC_FREEBSD_LIBC_PRIVATE_H_included
+#define _BIONIC_FREEBSD_LIBC_PRIVATE_H_included
+
+#define FLOCKFILE(fp)   do { if (__isthreaded) flockfile(fp); } while (0)
+#define FUNLOCKFILE(fp) do { if (__isthreaded) funlockfile(fp); } while (0)
+
+#define STDIO_THREAD_LOCK()   /* TODO: until we have the FreeBSD findfp.c, this is useless. */
+#define STDIO_THREAD_UNLOCK() /* TODO: until we have the FreeBSD findfp.c, this is useless. */
+
+#define ORIENT(fp, o) /* Only needed for wide-character stream support. */
+
+#endif
diff --git a/libc/upstream-freebsd/spinlock.h b/libc/upstream-freebsd/spinlock.h
new file mode 100644
index 0000000..f5c3785
--- /dev/null
+++ b/libc/upstream-freebsd/spinlock.h
@@ -0,0 +1,22 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef _BIONIC_FREEBSD_SPINLOCK_H_included
+#define _BIONIC_FREEBSD_SPINLOCK_H_included
+
+/* TODO: until we have the FreeBSD findfp.c, this is useless. */
+
+#endif
diff --git a/libc/upstream-netbsd/port_before.h b/libc/upstream-netbsd/port_before.h
index 70eed26..9f77f79 100644
--- a/libc/upstream-netbsd/port_before.h
+++ b/libc/upstream-netbsd/port_before.h
@@ -21,7 +21,7 @@
 #include <sys/cdefs.h>
 #include <arpa_nameser.h>
 
-#define ISC_FORMAT_PRINTF(a,b) __attribute__((__format__(__printf__,a,b)))
+#define ISC_FORMAT_PRINTF(a,b) __printflike(a,b)
 #define ISC_SOCKLEN_T socklen_t
 
 #endif
diff --git a/linker/linker.cpp b/linker/linker.cpp
index 7c5165b..c97b712 100644
--- a/linker/linker.cpp
+++ b/linker/linker.cpp
@@ -1581,11 +1581,6 @@
         return false;
     }
 
-    // If this is a setuid/setgid program, close the security hole described in
-    // ftp://ftp.freebsd.org/pub/FreeBSD/CERT/advisories/FreeBSD-SA-02:23.stdio.asc
-    if (get_AT_SECURE()) {
-        nullify_closed_stdio();
-    }
     notify_gdb_of_load(si);
     return true;
 }
@@ -1614,6 +1609,12 @@
     // Initialize environment functions, and get to the ELF aux vectors table.
     linker_env_init(args);
 
+    // If this is a setuid/setgid program, close the security hole described in
+    // ftp://ftp.freebsd.org/pub/FreeBSD/CERT/advisories/FreeBSD-SA-02:23.stdio.asc
+    if (get_AT_SECURE()) {
+        nullify_closed_stdio();
+    }
+
     debuggerd_init();
 
     // Get a few environment variables.
diff --git a/tests/Android.mk b/tests/Android.mk
index dee5e33..45cb462 100644
--- a/tests/Android.mk
+++ b/tests/Android.mk
@@ -60,6 +60,8 @@
     dirent_test.cpp \
     eventfd_test.cpp \
     fenv_test.cpp \
+    fortify1_test.cpp \
+    fortify2_test.cpp \
     getauxval_test.cpp \
     getcwd_test.cpp \
     libc_logging_test.cpp \
diff --git a/tests/fortify1_test.cpp b/tests/fortify1_test.cpp
new file mode 100644
index 0000000..e237193
--- /dev/null
+++ b/tests/fortify1_test.cpp
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2013 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.
+ */
+
+#undef _FORTIFY_SOURCE
+#define _FORTIFY_SOURCE 1
+
+#include <gtest/gtest.h>
+#include <string.h>
+
+#if __BIONIC__
+// We have to say "DeathTest" here so gtest knows to run this test (which exits)
+// in its own process.
+TEST(Fortify1_DeathTest, strcpy_fortified) {
+  ::testing::FLAGS_gtest_death_test_style = "threadsafe";
+  char buf[10];
+  char *orig = strdup("0123456789");
+  ASSERT_EXIT(strcpy(buf, orig), testing::KilledBySignal(SIGSEGV), "");
+  free(orig);
+}
+
+TEST(Fortify1_DeathTest, strlen_fortified) {
+  ::testing::FLAGS_gtest_death_test_style = "threadsafe";
+  char buf[10];
+  memcpy(buf, "0123456789", sizeof(buf));
+  ASSERT_EXIT(printf("%d", strlen(buf)), testing::KilledBySignal(SIGSEGV), "");
+}
+
+TEST(Fortify1_DeathTest, strchr_fortified) {
+  ::testing::FLAGS_gtest_death_test_style = "threadsafe";
+  char buf[10];
+  memcpy(buf, "0123456789", sizeof(buf));
+  ASSERT_EXIT(printf("%s", strchr(buf, 'a')), testing::KilledBySignal(SIGSEGV), "");
+}
+
+TEST(Fortify1_DeathTest, strrchr_fortified) {
+  ::testing::FLAGS_gtest_death_test_style = "threadsafe";
+  char buf[10];
+  memcpy(buf, "0123456789", sizeof(buf));
+  ASSERT_EXIT(printf("%s", strrchr(buf, 'a')), testing::KilledBySignal(SIGSEGV), "");
+}
+#endif
+
+TEST(Fortify1_DeathTest, sprintf_fortified) {
+  ::testing::FLAGS_gtest_death_test_style = "threadsafe";
+  char buf[10];
+  char source_buf[15];
+  memcpy(source_buf, "12345678901234", 15);
+  ASSERT_EXIT(sprintf(buf, "%s", source_buf), testing::KilledBySignal(SIGSEGV), "");
+}
diff --git a/tests/fortify2_test.cpp b/tests/fortify2_test.cpp
new file mode 100644
index 0000000..ea890fe
--- /dev/null
+++ b/tests/fortify2_test.cpp
@@ -0,0 +1,108 @@
+/*
+ * Copyright (C) 2013 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.
+ */
+
+#undef _FORTIFY_SOURCE
+#define _FORTIFY_SOURCE 2
+
+#include <gtest/gtest.h>
+#include <string.h>
+
+struct foo {
+  char a[10];
+  char b[10];
+};
+
+// We have to say "DeathTest" here so gtest knows to run this test (which exits)
+// in its own process.
+TEST(Fortify2_DeathTest, strncpy_fortified2) {
+  ::testing::FLAGS_gtest_death_test_style = "threadsafe";
+  foo myfoo;
+  int copy_amt = atoi("11");
+  ASSERT_EXIT(strncpy(myfoo.a, "01234567890", copy_amt),
+              testing::KilledBySignal(SIGSEGV), "");
+}
+
+TEST(Fortify2_DeathTest, sprintf_fortified2) {
+  ::testing::FLAGS_gtest_death_test_style = "threadsafe";
+  foo myfoo;
+  char source_buf[15];
+  memcpy(source_buf, "12345678901234", 15);
+  ASSERT_EXIT(sprintf(myfoo.a, "%s", source_buf),
+              testing::KilledBySignal(SIGSEGV), "");
+}
+
+#if __BIONIC__
+TEST(Fortify2_DeathTest, strchr_fortified2) {
+  ::testing::FLAGS_gtest_death_test_style = "threadsafe";
+  foo myfoo;
+  memcpy(myfoo.a, "0123456789", sizeof(myfoo.a));
+  myfoo.b[0] = '\0';
+  ASSERT_EXIT(printf("%s", strchr(myfoo.a, 'a')),
+              testing::KilledBySignal(SIGSEGV), "");
+}
+
+TEST(Fortify2_DeathTest, strrchr_fortified2) {
+  ::testing::FLAGS_gtest_death_test_style = "threadsafe";
+  foo myfoo;
+  memcpy(myfoo.a, "0123456789", 10);
+  memcpy(myfoo.b, "01234", 6);
+  ASSERT_EXIT(printf("%s", strrchr(myfoo.a, 'a')),
+              testing::KilledBySignal(SIGSEGV), "");
+}
+#endif
+
+/***********************************************************/
+/* TESTS BELOW HERE DUPLICATE TESTS FROM fortify1_test.cpp */
+/***********************************************************/
+
+#if __BIONIC__
+TEST(Fortify2_DeathTest, strcpy_fortified) {
+  ::testing::FLAGS_gtest_death_test_style = "threadsafe";
+  char buf[10];
+  char *orig = strdup("0123456789");
+  ASSERT_EXIT(strcpy(buf, orig), testing::KilledBySignal(SIGSEGV), "");
+  free(orig);
+}
+
+TEST(Fortify2_DeathTest, strlen_fortified) {
+  ::testing::FLAGS_gtest_death_test_style = "threadsafe";
+  char buf[10];
+  memcpy(buf, "0123456789", sizeof(buf));
+  ASSERT_EXIT(printf("%d", strlen(buf)), testing::KilledBySignal(SIGSEGV), "");
+}
+
+TEST(Fortify2_DeathTest, strchr_fortified) {
+  ::testing::FLAGS_gtest_death_test_style = "threadsafe";
+  char buf[10];
+  memcpy(buf, "0123456789", sizeof(buf));
+  ASSERT_EXIT(printf("%s", strchr(buf, 'a')), testing::KilledBySignal(SIGSEGV), "");
+}
+
+TEST(Fortify2_DeathTest, strrchr_fortified) {
+  ::testing::FLAGS_gtest_death_test_style = "threadsafe";
+  char buf[10];
+  memcpy(buf, "0123456789", sizeof(buf));
+  ASSERT_EXIT(printf("%s", strrchr(buf, 'a')), testing::KilledBySignal(SIGSEGV), "");
+}
+#endif
+
+TEST(Fortify2_DeathTest, sprintf_fortified) {
+  ::testing::FLAGS_gtest_death_test_style = "threadsafe";
+  char buf[10];
+  char source_buf[15];
+  memcpy(source_buf, "12345678901234", 15);
+  ASSERT_EXIT(sprintf(buf, "%s", source_buf), testing::KilledBySignal(SIGSEGV), "");
+}
diff --git a/tests/stdio_test.cpp b/tests/stdio_test.cpp
index 4b5a1f9..2e779d8 100644
--- a/tests/stdio_test.cpp
+++ b/tests/stdio_test.cpp
@@ -193,3 +193,21 @@
 
   ASSERT_EQ(0, pclose(fp));
 }
+
+TEST(stdio, getc) {
+  FILE* fp = fopen("/proc/version", "r");
+  ASSERT_TRUE(fp != NULL);
+  ASSERT_EQ('L', getc(fp));
+  ASSERT_EQ('i', getc(fp));
+  ASSERT_EQ('n', getc(fp));
+  ASSERT_EQ('u', getc(fp));
+  ASSERT_EQ('x', getc(fp));
+  fclose(fp);
+}
+
+TEST(stdio, putc) {
+  FILE* fp = fopen("/proc/version", "r");
+  ASSERT_TRUE(fp != NULL);
+  ASSERT_EQ(EOF, putc('x', fp));
+  fclose(fp);
+}
diff --git a/tests/stdlib_test.cpp b/tests/stdlib_test.cpp
index fed39f8..e5d7812 100644
--- a/tests/stdlib_test.cpp
+++ b/tests/stdlib_test.cpp
@@ -109,3 +109,26 @@
   ASSERT_STREQ(executable_path, p);
   free(p);
 }
+
+TEST(stdlib, qsort) {
+  struct s {
+    char name[16];
+    static int comparator(const void* lhs, const void* rhs) {
+      return strcmp(reinterpret_cast<const s*>(lhs)->name, reinterpret_cast<const s*>(rhs)->name);
+    }
+  };
+  s entries[3];
+  strcpy(entries[0].name, "charlie");
+  strcpy(entries[1].name, "bravo");
+  strcpy(entries[2].name, "alpha");
+
+  qsort(entries, 3, sizeof(s), s::comparator);
+  ASSERT_STREQ("alpha", entries[0].name);
+  ASSERT_STREQ("bravo", entries[1].name);
+  ASSERT_STREQ("charlie", entries[2].name);
+
+  qsort(entries, 3, sizeof(s), s::comparator);
+  ASSERT_STREQ("alpha", entries[0].name);
+  ASSERT_STREQ("bravo", entries[1].name);
+  ASSERT_STREQ("charlie", entries[2].name);
+}
diff --git a/tests/string_test.cpp b/tests/string_test.cpp
index 1720058..63bfadb 100644
--- a/tests/string_test.cpp
+++ b/tests/string_test.cpp
@@ -209,6 +209,13 @@
   }
 }
 
+TEST(string, strchr_with_0) {
+  char buf[10];
+  const char* s = "01234";
+  memcpy(buf, s, strlen(s) + 1);
+  EXPECT_TRUE(strchr(buf, '\0') == (buf + strlen(s)));
+}
+
 TEST(string, strchr) {
   int seek_char = random() & 255;
 
@@ -307,39 +314,6 @@
 
 
 #if __BIONIC__
-// We have to say "DeathTest" here so gtest knows to run this test (which exits)
-// in its own process.
-TEST(string_DeathTest, strcpy_fortified) {
-  ::testing::FLAGS_gtest_death_test_style = "threadsafe";
-  char buf[10];
-  char *orig = strdup("0123456789");
-  ASSERT_EXIT(strcpy(buf, orig), testing::KilledBySignal(SIGSEGV), "");
-  free(orig);
-}
-
-TEST(string_DeathTest, strlen_fortified) {
-  ::testing::FLAGS_gtest_death_test_style = "threadsafe";
-  char buf[10];
-  memcpy(buf, "0123456789", sizeof(buf));
-  ASSERT_EXIT(printf("%d", strlen(buf)), testing::KilledBySignal(SIGSEGV), "");
-}
-
-TEST(string_DeathTest, strchr_fortified) {
-  ::testing::FLAGS_gtest_death_test_style = "threadsafe";
-  char buf[10];
-  memcpy(buf, "0123456789", sizeof(buf));
-  ASSERT_EXIT(printf("%s", strchr(buf, 'a')), testing::KilledBySignal(SIGSEGV), "");
-}
-
-TEST(string_DeathTest, strrchr_fortified) {
-  ::testing::FLAGS_gtest_death_test_style = "threadsafe";
-  char buf[10];
-  memcpy(buf, "0123456789", sizeof(buf));
-  ASSERT_EXIT(printf("%s", strrchr(buf, 'a')), testing::KilledBySignal(SIGSEGV), "");
-}
-#endif
-
-#if __BIONIC__
 TEST(string, strlcat) {
   StringTestState state(SMALL);
   for (size_t i = 0; i < state.n; i++) {