am ea0fe856: Merge "Bionic: Aliasing problems with frexpf"

* commit 'ea0fe8563db2a5854d30b3c770c406356f55cfe8':
  Bionic: Aliasing problems with frexpf
diff --git a/Android.mk b/Android.mk
index fcc8b96..43d5499 100644
--- a/Android.mk
+++ b/Android.mk
@@ -14,6 +14,11 @@
 # limitations under the License.
 #
 
+LOCAL_PATH := $(call my-dir)
+
 ifneq ($(TARGET_SIMULATOR),true)
   include $(call all-subdir-makefiles)
+else
+  # The host dalvikvm needs Android's concatenated & indexed timezone data.
+  include $(LOCAL_PATH)/libc/zoneinfo/Android.mk
 endif
diff --git a/ThirdPartyProject.prop b/ThirdPartyProject.prop
new file mode 100644
index 0000000..22c18cb
--- /dev/null
+++ b/ThirdPartyProject.prop
@@ -0,0 +1,10 @@
+# Copyright 2010 Google Inc. All Rights Reserved.
+#Fri Jul 16 10:03:08 PDT 2010
+currentVersion=Unknown
+version=Unknown
+isNative=true
+feedurl=http\://www.openbsd.org/security.html
+name=openbsd
+keywords=openbsd
+onDevice=true
+homepage=http\://openbsd.org
diff --git a/libc/Android.mk b/libc/Android.mk
index 39c63a2..db8e7bd 100644
--- a/libc/Android.mk
+++ b/libc/Android.mk
@@ -11,9 +11,11 @@
 	unistd/brk.c \
 	unistd/creat.c \
 	unistd/daemon.c \
+	unistd/eventfd.c \
 	unistd/exec.c \
 	unistd/fcntl.c \
 	unistd/fnmatch.c \
+	unistd/fstatfs.c \
 	unistd/ftime.c \
 	unistd/ftok.c \
 	unistd/getcwd.c \
@@ -63,7 +65,6 @@
 	unistd/sleep.c \
 	unistd/statfs.c \
 	unistd/strsignal.c \
-	unistd/sysconf.c \
 	unistd/syslog.c \
 	unistd/system.c \
 	unistd/tcgetpgrp.c \
@@ -205,6 +206,35 @@
 	string/strtok.c \
 	string/strtotimeval.c \
 	string/strxfrm.c \
+	wchar/wcpcpy.c \
+	wchar/wcpncpy.c \
+	wchar/wcscasecmp.c \
+	wchar/wcscat.c \
+	wchar/wcschr.c \
+	wchar/wcscmp.c \
+	wchar/wcscoll.c \
+	wchar/wcscpy.c \
+	wchar/wcscspn.c \
+	wchar/wcsdup.c \
+	wchar/wcslcat.c \
+	wchar/wcslcpy.c \
+	wchar/wcslen.c \
+	wchar/wcsncasecmp.c \
+	wchar/wcsncat.c \
+	wchar/wcsncmp.c \
+	wchar/wcsncpy.c \
+	wchar/wcsnlen.c \
+	wchar/wcspbrk.c \
+	wchar/wcsrchr.c \
+	wchar/wcsspn.c \
+	wchar/wcsstr.c \
+	wchar/wcstok.c \
+	wchar/wcswidth.c \
+	wchar/wmemchr.c \
+	wchar/wmemcmp.c \
+	wchar/wmemcpy.c \
+	wchar/wmemmove.c \
+	wchar/wmemset.c \
 	inet/bindresvport.c \
 	inet/inet_addr.c \
 	inet/inet_aton.c \
@@ -218,7 +248,6 @@
 	tzcode/localtime.c \
 	tzcode/strftime.c \
 	tzcode/strptime.c \
-	bionic/__errno.c \
 	bionic/__set_errno.c \
 	bionic/cpuacct.c \
 	bionic/arc4random.c \
@@ -286,6 +315,23 @@
 	regex/regexec.c \
 	regex/regfree.c \
 
+# The following files are common, but must be compiled
+# with different C flags when building a static C library.
+#
+# The reason for this is the implementation of __get_tls()
+# that will differ between the shared and static versions
+# of the library.
+#
+# See comments in private/bionic_tls.h for more details.
+#
+# NOTE: bionic/pthread.c is added later to this list
+#       because it needs special handling on ARM, see
+#       below.
+#
+libc_static_common_src_files := \
+        unistd/sysconf.c \
+        bionic/__errno.c \
+
 # Architecture specific source files go here
 # =========================================================
 ifeq ($(TARGET_ARCH),arm)
@@ -310,8 +356,6 @@
 	arch-arm/bionic/sigsetjmp.S \
 	arch-arm/bionic/strlen.c.arm \
 	arch-arm/bionic/syscall.S \
-	arch-arm/bionic/sigaction.c \
-	arch-arm/bionic/__sig_restorer.S \
 	string/memmove.c.arm \
 	string/bcopy.c \
 	string/strcmp.c \
@@ -322,11 +366,14 @@
 # can set breakpoints in them without messing
 # up any thumb code.
 libc_common_src_files += \
-	bionic/pthread.c.arm \
 	bionic/pthread-atfork.c.arm \
+	bionic/pthread-rwlocks.c.arm \
 	bionic/pthread-timers.c.arm \
 	bionic/ptrace.c.arm
 
+libc_static_common_src_files += \
+        bionic/pthread.c.arm \
+
 # these are used by the static and dynamic versions of the libc
 # respectively
 libc_arch_static_src_files := \
@@ -357,11 +404,14 @@
 	arch-x86/string/strcmp_wrapper.S \
 	arch-x86/string/strncmp_wrapper.S \
 	arch-x86/string/strlen_wrapper.S \
-	bionic/pthread.c \
 	bionic/pthread-atfork.c \
+	bionic/pthread-rwlocks.c \
 	bionic/pthread-timers.c \
 	bionic/ptrace.c
 
+libc_static_common_src_files += \
+        bionic/pthread.c \
+
 # this is needed for static versions of libc
 libc_arch_static_src_files := \
 	arch-x86/bionic/dl_iterate_phdr_static.c
@@ -394,11 +444,15 @@
 	string/strncmp.c \
 	string/memcmp.c \
 	string/strlen.c \
-	bionic/pthread.c \
 	bionic/pthread-atfork.c \
+	bionic/pthread-rwlocks.c \
 	bionic/pthread-timers.c \
 	bionic/ptrace.c \
 	unistd/socketcalls.c
+
+libc_static_common_src_files += \
+        bionic/pthread.c \
+
 endif # sh
 
 endif # !x86
@@ -414,7 +468,6 @@
 		-D_LIBC=1 			\
 		-DSOFTFLOAT                     \
 		-DFLOATING_POINT		\
-		-DNEED_PSELECT=1		\
 		-DINET6 \
 		-I$(LOCAL_PATH)/private \
 		-DUSE_DL_PREFIX \
@@ -449,6 +502,18 @@
   libc_crt_target_cflags :=
 endif # !arm
 
+# Define ANDROID_SMP appropriately.
+ifeq ($(TARGET_CPU_SMP),true)
+    libc_common_cflags += -DANDROID_SMP=1
+else
+    libc_common_cflags += -DANDROID_SMP=0
+endif
+
+# Needed to access private/__dso_handle.S from
+# crtbegin_xxx.S and crtend_xxx.S
+#
+libc_crt_target_cflags += -I$(LOCAL_PATH)/private
+
 # Define some common includes
 # ========================================================
 libc_common_c_includes := \
@@ -545,10 +610,12 @@
 
 LOCAL_SRC_FILES := \
 	$(libc_arch_static_src_files) \
+	$(libc_static_common_src_files) \
 	bionic/libc_init_static.c
 
 LOCAL_C_INCLUDES := $(libc_common_c_includes)
-LOCAL_CFLAGS := $(libc_common_cflags)
+LOCAL_CFLAGS := $(libc_common_cflags) \
+                -DLIBC_STATIC
 
 LOCAL_MODULE := libc_nomalloc
 LOCAL_WHOLE_STATIC_LIBRARIES := libc_common
@@ -564,6 +631,7 @@
 
 LOCAL_SRC_FILES := \
 	$(libc_arch_static_src_files) \
+	$(libc_static_common_src_files) \
 	bionic/dlmalloc.c \
 	bionic/malloc_debug_common.c \
 	bionic/libc_init_static.c
@@ -588,6 +656,7 @@
 
 LOCAL_SRC_FILES := \
 	$(libc_arch_dynamic_src_files) \
+	$(libc_static_common_src_files) \
 	bionic/dlmalloc.c \
 	bionic/malloc_debug_common.c \
 	bionic/libc_init_dynamic.c
diff --git a/libc/SYSCALLS.TXT b/libc/SYSCALLS.TXT
index b5a3bbe..0a08e12 100644
--- a/libc/SYSCALLS.TXT
+++ b/libc/SYSCALLS.TXT
@@ -33,7 +33,7 @@
 void    _exit_thread:exit (int)	    1
 pid_t   __fork:fork (void)           2
 pid_t   _waitpid:waitpid (pid_t, int*, int, struct rusage*)   -1,7
-int     waitid(int, pid_t, struct siginfo_t*, int,void*)          280,284
+int     __waitid:waitid(int, pid_t, struct siginfo_t*, int,void*)          280,284
 
 # NOTE: this system call is never called directly, but we list it there
 #       to have __NR_clone properly defined.
@@ -112,15 +112,17 @@
 int         fchmod(int, mode_t)  94
 int         dup(int)  41
 int         pipe(int *)  42,42,-1
+int         pipe2(int *, int) 359,331
 int         dup2(int, int)   63
 int         select:_newselect(int, struct fd_set *, struct fd_set *, struct fd_set *, struct timeval *)  142
 int         ftruncate(int, off_t)  93
 int         getdents:getdents64(unsigned int, struct dirent *, unsigned int)   217,220
 int         fsync(int)  118
+int         fdatasync(int) 148
 int         fchown:fchown32(int, uid_t, gid_t)  207
 void        sync(void)  36
 int         __fcntl64:fcntl64(int, int, void *)  221
-int         fstatfs:fstatfs64(int, size_t, struct statfs *)  267,269
+int         __fstatfs64:fstatfs64(int, size_t, struct statfs *)  267,269
 ssize_t     sendfile(int out_fd, int in_fd, off_t *offset, size_t count)  187
 int         fstatat:fstatat64(int dirfd, const char *path, struct stat *buf, int flags)   327,300
 int         mkdirat(int dirfd, const char *pathname, mode_t mode)  323,296
@@ -173,7 +175,7 @@
 int           utimes(const char*, const struct timeval tvp[2])                          269, 271
 
 # signals
-int     sigaction(int, const struct sigaction *, struct sigaction *)  -1,67,67
+int     sigaction(int, const struct sigaction *, struct sigaction *)  67
 int     sigprocmask(int, const sigset_t *, sigset_t *)  126
 int     __sigsuspend:sigsuspend(int unused1, int unused2, unsigned mask)  72
 int     __rt_sigaction:rt_sigaction (int sig, const struct sigaction *act, struct sigaction *oact, size_t sigsetsize)  174
@@ -181,9 +183,6 @@
 int     __rt_sigtimedwait:rt_sigtimedwait(const sigset_t *set, struct siginfo_t  *info, struct timespec_t  *timeout, size_t  sigset_size)  177
 int     sigpending(sigset_t *)  73
 
-# special stub for ARM, see arch-arm/bionic/sigaction.c
-int     __sigaction:sigaction(int, const struct sigaction *, struct sigaction *)  67,-1,-1
-
 # sockets
 int           socket(int, int, int)              281,-1
 int           socketpair(int, int, int, int*)    288,-1
@@ -232,8 +231,8 @@
 int sched_rr_get_interval(pid_t pid, struct timespec *interval)  161
 
 # io priorities
-int ioprio_set(int which, int who, int ioprio) 314,289
-int ioprio_get(int which, int who) 315,290
+int ioprio_set(int which, int who, int ioprio) 314,289,288
+int ioprio_get(int which, int who) 315,290,289
 
 # other
 int     uname(struct utsname *)  122
@@ -244,6 +243,7 @@
 int     init_module(void *, unsigned long, const char *)  128
 int     delete_module(const char*, unsigned int)   129
 int     klogctl:syslog(int, char *, int)   103
+int     sysinfo(struct sysinfo *)  116
 
 # futex
 int	futex(void *, int, int, void *, void *, int) 240
@@ -259,6 +259,8 @@
 
 int     poll(struct pollfd *, unsigned int, long)  168
 
+int     eventfd:eventfd2(unsigned int, int)  356,328
+
 # ARM-specific ARM_NR_BASE == 0x0f0000 == 983040
 int     __set_tls:ARM_set_tls(void*)                                 983045,-1
 int     cacheflush:ARM_cacheflush(long start, long end, long flags)  983042,-1
diff --git a/libc/arch-arm/bionic/__sig_restorer.S b/libc/arch-arm/bionic/__sig_restorer.S
deleted file mode 100644
index 3f6f284..0000000
--- a/libc/arch-arm/bionic/__sig_restorer.S
+++ /dev/null
@@ -1,7 +0,0 @@
-.global __sig_restorer
-
-/* This is the opcode sequence GDB looks for in order to recognize
-   this stack frame as a signal trampoline (see sigaction.c) */
-__sig_restorer:
-    mov r7, #119 /* __NR_sigreturn */
-    swi #0
diff --git a/libc/arch-arm/bionic/_setjmp.S b/libc/arch-arm/bionic/_setjmp.S
index 6a27af2..5626219 100644
--- a/libc/arch-arm/bionic/_setjmp.S
+++ b/libc/arch-arm/bionic/_setjmp.S
@@ -3,6 +3,7 @@
 
 /*
  * Copyright (c) 1997 Mark Brinicombe
+ * Copyright (c) 2010 Android Open Source Project.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -35,6 +36,7 @@
 
 #include <machine/asm.h>
 #include <machine/setjmp.h>
+#include <machine/cpu-features.h>
 
 /*
  * C library -- _setjmp, _longjmp
@@ -51,18 +53,20 @@
 
 ENTRY(_setjmp)
 	ldr	r1, .L_setjmp_magic
-	str	r1, [r0], #4
-#ifdef SOFTFLOAT
-	add	r0, r0, #52
-#else
-	/* Store fp registers */
-	sfm	f4, 4, [r0], #48
-	/* Store fpsr */
-	rfs	r1
-	str	r1, [r0], #0x0004
-#endif	/* SOFTFLOAT */
-	/* Store integer registers */
-        stmia	r0, {r4-r14}
+	str	r1, [r0, #(_JB_MAGIC * 4)]
+
+	/* Store core registers */
+	add     r1, r0, #(_JB_CORE_BASE * 4)
+	stmia   r1, {r4-r14}
+
+#ifdef __ARM_HAVE_VFP
+	/* Store floating-point registers */
+	add     r1, r0, #(_JB_FLOAT_BASE * 4)
+	vstmia  r1, {d8-d15}
+	/* Store floating-point state */
+	fmrx    r1, fpscr
+	str     r1, [r0, #(_JB_FLOAT_STATE * 4)]
+#endif  /* __ARM_HAVE_VFP */
 
         mov	r0, #0x00000000
         bx      lr
@@ -72,21 +76,22 @@
 
 ENTRY(_longjmp)
 	ldr	r2, .L_setjmp_magic
-	ldr	r3, [r0], #4
+	ldr	r3, [r0, #(_JB_MAGIC * 4)]
 	teq	r2, r3
 	bne	botch
 
-#ifdef SOFTFLOAT
-	add	r0, r0, #52
-#else
-	/* Restore fp registers */
-	lfm	f4, 4, [r0], #48
-	/* Restore fpsr */
-	ldr	r4, [r0], #0x0004
-	wfs	r4
-#endif	/* SOFTFLOAT */
-       	/* Restore integer registers */
-        ldmia	r0, {r4-r14}
+#ifdef __ARM_HAVE_VFP
+	/* Restore floating-point registers */
+	add     r2, r0, #(_JB_FLOAT_BASE * 4)
+	vldmia  r2, {d8-d15}
+	/* Restore floating-point state */
+	ldr     r2, [r0, #(_JB_FLOAT_STATE * 4)]
+	fmxr    fpscr, r2
+#endif /* __ARM_HAVE_VFP */
+
+	/* Restore core registers */
+	add     r2, r0, #(_JB_CORE_BASE * 4)
+	ldmia   r2, {r4-r14}
 
 	/* Validate sp and r14 */
 	teq	sp, #0
diff --git a/libc/arch-arm/bionic/atomics_arm.S b/libc/arch-arm/bionic/atomics_arm.S
index f2e369d..d94f6b1 100644
--- a/libc/arch-arm/bionic/atomics_arm.S
+++ b/libc/arch-arm/bionic/atomics_arm.S
@@ -26,6 +26,7 @@
  * SUCH DAMAGE.
  */
 #include <sys/linux-syscalls.h>
+#include <machine/cpu-features.h>
 
 .global __atomic_cmpxchg
 .type __atomic_cmpxchg, %function
@@ -39,9 +40,73 @@
 #define FUTEX_WAIT 0
 #define FUTEX_WAKE 1
 
-#if 1
-   .equ     kernel_cmpxchg, 0xFFFF0FC0
-   .equ     kernel_atomic_base, 0xFFFF0FFF
+#if defined(__ARM_HAVE_LDREX_STREX)
+/*
+ * ===========================================================================
+ *      ARMv6+ implementation
+ * ===========================================================================
+ */
+
+/* r0(addr) -> r0(old) */
+__atomic_dec:
+    .fnstart
+    mov     r1, r0                      @ copy addr so we don't clobber it
+1:  ldrex   r0, [r1]                    @ load current value into r0
+    sub     r2, r0, #1                  @ generate new value into r2
+    strex   r3, r2, [r1]                @ try to store new value; result in r3
+    cmp     r3, #0                      @ success?
+    bxeq    lr                          @ yes, return
+    b       1b                          @ no, retry
+    .fnend
+
+/* r0(addr) -> r0(old) */
+__atomic_inc:
+    .fnstart
+    mov     r1, r0
+1:  ldrex   r0, [r1]
+    add     r2, r0, #1
+    strex   r3, r2, [r1]
+    cmp     r3, #0
+    bxeq    lr
+    b       1b
+    .fnend
+
+/* r0(old) r1(new) r2(addr) -> r0(zero_if_succeeded) */
+__atomic_cmpxchg:
+    .fnstart
+1:  mov     ip, #2                      @ ip=2 means "new != old"
+    ldrex   r3, [r2]                    @ load current value into r3
+    teq     r0, r3                      @ new == old?
+    strexeq ip, r1, [r2]                @ yes, try store, set ip to 0 or 1
+    teq     ip, #1                      @ strex failure?
+    beq     1b                          @ yes, retry
+    mov     r0, ip                      @ return 0 on success, 2 on failure
+    bx      lr
+    .fnend
+
+/* r0(new) r1(addr) -> r0(old) */
+__atomic_swap:
+    .fnstart
+1:  ldrex   r2, [r1]
+    strex   r3, r0, [r1]
+    teq     r3, #0
+    bne     1b
+    mov     r0, r2
+    bx      lr
+    .fnend
+
+#else /*not defined __ARM_HAVE_LDREX_STREX*/
+/*
+ * ===========================================================================
+ *      Pre-ARMv6 implementation
+ * ===========================================================================
+ */
+
+    /* int __kernel_cmpxchg(int oldval, int newval, int* ptr) */
+    .equ    kernel_cmpxchg, 0xFFFF0FC0
+    .equ    kernel_atomic_base, 0xFFFF0FFF
+
+/* r0(addr) -> r0(old) */
 __atomic_dec:
     .fnstart
     .save {r4, lr}
@@ -59,6 +124,7 @@
     bx      lr
     .fnend
 
+/* r0(addr) -> r0(old) */
 __atomic_inc:
     .fnstart
     .save {r4, lr}
@@ -95,64 +161,16 @@
     ldmia   sp!, {r4, lr}
     bx      lr
     .fnend
-#else
-#define KUSER_CMPXCHG 0xffffffc0
-
-/* r0(old) r1(new) r2(addr) -> r0(zero_if_succeeded) */
-__atomic_cmpxchg:
-    stmdb   sp!, {r4, lr}
-    mov     r4, r0          /* r4 = save oldvalue */
-1:  add     lr, pc, #4
-    mov     r0, r4          /* r0 = oldvalue */
-    mov     pc, #KUSER_CMPXCHG
-    bcs     2f              /* swap was made. we're good, return. */
-    ldr     r3, [r2]        /* swap not made, see if it's because *ptr!=oldvalue */
-    cmp     r3, r4
-    beq     1b
-2:  ldmia   sp!, {r4, lr}
-    bx      lr
-
-/* r0(addr) -> r0(old) */
-__atomic_dec:
-    stmdb   sp!, {r4, lr}
-    mov     r2, r0          /* address */
-1:  ldr     r0, [r2]        /* oldvalue */
-    add     lr, pc, #4
-    sub     r1, r0, #1      /* newvalue = oldvalue - 1 */
-    mov     pc, #KUSER_CMPXCHG
-    bcc     1b              /* no swap, try again until we get it right */
-    mov     r0, ip          /* swapped, return the old value */
-    ldmia   sp!, {r4, lr}
-    bx      lr
-
-/* r0(addr) -> r0(old) */
-__atomic_inc:
-    stmdb   sp!, {r4, lr}
-    mov     r2, r0          /* address */
-1:  ldr     r0, [r2]        /* oldvalue */
-    add     lr, pc, #4
-    add     r1, r0, #1      /* newvalue = oldvalue + 1 */
-    mov     pc, #KUSER_CMPXCHG
-    bcc     1b              /* no swap, try again until we get it right */
-    mov     r0, ip          /* swapped, return the old value */
-    ldmia   sp!, {r4, lr}
-    bx      lr
-#endif
 
 /* r0(new) r1(addr) -> r0(old) */
-/* replaced swp instruction with ldrex/strex for ARMv6 & ARMv7 */
 __atomic_swap:
-#if defined (__ARM_HAVE_LDREX_STREX)
-1:  ldrex   r2, [r1]
-    strex   r3, r0, [r1]
-    teq     r3, #0
-    bne     1b
-    mov     r0, r2
-    mcr     p15, 0, r0, c7, c10, 5 /* or, use dmb */
-#else
+    .fnstart
     swp     r0, r0, [r1]
-#endif
     bx      lr
+    .fnend
+
+#endif /*not defined __ARM_HAVE_LDREX_STREX*/
+
 
 /* __futex_wait(*ftx, val, *timespec) */
 /* __futex_wake(*ftx, counter) */
@@ -197,6 +215,8 @@
     .fnend
 
 __futex_wake:
+    .fnstart
+    .save   {r4, r7}
     stmdb   sp!, {r4, r7}
     mov     r2, r1
     mov     r1, #FUTEX_WAKE
@@ -204,6 +224,7 @@
     swi     #0
     ldmia   sp!, {r4, r7}
     bx      lr
+    .fnend
 
 #else
 
diff --git a/libc/arch-arm/bionic/setjmp.S b/libc/arch-arm/bionic/setjmp.S
index a9f6ea4..59aff66 100644
--- a/libc/arch-arm/bionic/setjmp.S
+++ b/libc/arch-arm/bionic/setjmp.S
@@ -3,6 +3,7 @@
 
 /*
  * Copyright (c) 1997 Mark Brinicombe
+ * Copyright (c) 2010 Android Open Source Project.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -35,6 +36,7 @@
 
 #include <machine/asm.h>
 #include <machine/setjmp.h>
+#include <machine/cpu-features.h>
 
 /*
  * C library -- setjmp, longjmp
@@ -57,24 +59,26 @@
 	ldmfd	sp!, {r0, r14}
 
 	/* Store signal mask */
-	str	r1, [r0, #(25 * 4)]
+	str	r1, [r0, #(_JB_SIGMASK * 4)]
 
 	ldr	r1, .Lsetjmp_magic
-	str	r1, [r0], #4
+	str	r1, [r0, #(_JB_MAGIC * 4)]
 
-#ifdef SOFTFLOAT
-	add	r0, r0, #52
-#else
-	/* Store fp registers */
-	sfm	f4, 4, [r0], #48
-	/* Store fpsr */
-	rfs	r1
-	str	r1, [r0], #0x0004
-#endif	/*SOFTFLOAT*/
-	/* Store integer registers */
-        stmia	r0, {r4-r14}
-        mov	r0, #0x00000000
-        bx      lr
+	/* Store core registers */
+	add     r1, r0, #(_JB_CORE_BASE * 4)
+	stmia   r1, {r4-r14}
+
+#ifdef __ARM_HAVE_VFP
+	/* Store floating-point registers */
+	add     r1, r0, #(_JB_FLOAT_BASE * 4)
+	vstmia  r1, {d8-d15}
+	/* Store floating-point state */
+	fmrx    r1, fpscr
+	str     r1, [r0, #(_JB_FLOAT_STATE * 4)]
+#endif  /* __ARM_HAVE_VFP */
+
+	mov	r0, #0x00000000
+	bx      lr
 
 .Lsetjmp_magic:
 	.word	_JB_MAGIC_SETJMP
@@ -82,12 +86,12 @@
 
 ENTRY(longjmp)
 	ldr	r2, .Lsetjmp_magic
-	ldr	r3, [r0]
+	ldr	r3, [r0, #(_JB_MAGIC * 4)]
 	teq	r2, r3
 	bne	botch
 
 	/* Fetch signal mask */
-	ldr	r2, [r0, #(25 * 4)]
+	ldr	r2, [r0, #(_JB_SIGMASK * 4)]
 
 	/* Set signal mask */
 	stmfd	sp!, {r0, r1, r14}
@@ -99,18 +103,18 @@
 	add	sp, sp, #4	/* unalign the stack */
 	ldmfd	sp!, {r0, r1, r14} 
 
-	add	r0, r0, #4
-#ifdef SOFTFLOAT
-	add	r0, r0, #52
-#else
-	/* Restore fp registers */
-	lfm	f4, 4, [r0], #48
-	/* Restore FPSR */
-	ldr	r4, [r0], #0x0004
-	wfs	r4
-#endif	/* SOFTFLOAT */
-	/* Restore integer registers */
-        ldmia	r0, {r4-r14}
+#ifdef __ARM_HAVE_VFP
+	/* Restore floating-point registers */
+	add     r2, r0, #(_JB_FLOAT_BASE * 4)
+	vldmia  r2, {d8-d15}
+	/* Restore floating-point state */
+	ldr     r2, [r0, #(_JB_FLOAT_STATE * 4)]
+	fmxr    fpscr, r2
+#endif /* __ARM_HAVE_VFP */
+
+	/* Restore core registers */
+	add     r2, r0, #(_JB_CORE_BASE * 4)
+	ldmia   r2, {r4-r14}
 
 	/* Validate sp and r14 */
 	teq	sp, #0
diff --git a/libc/arch-arm/bionic/sigaction.c b/libc/arch-arm/bionic/sigaction.c
deleted file mode 100644
index 96ca7c6..0000000
--- a/libc/arch-arm/bionic/sigaction.c
+++ /dev/null
@@ -1,29 +0,0 @@
-#include <signal.h>
-
-extern int __sigaction(int signum, const struct sigaction *act, struct sigaction *oldact);
-extern void __sig_restorer();
-
-int sigaction(int signum, const struct sigaction *act, struct sigaction *oldact)
-{
-    struct sigaction real_act;
-
-    /* If the caller has not set a custom restorer, then set up a default one.
-     * The code will function properly without this, however GDB will not be
-     * able to recognize the stack frame as a signal trampoline, because it
-     * is hardcoded to look for the instruction sequence that glibc uses in
-     * its custom restorer.  By creating our own restorer with the same
-     * sequence, we ensure that GDB correctly identifies this as a signal
-     * trampoline frame.
-     *
-     * See http://sourceware.org/ml/gdb/2010-01/msg00143.html for more
-     * information on this.*/
-    if(act && !(act->sa_flags & SA_RESTORER)) {
-        real_act = *act;
-        real_act.sa_flags |= SA_RESTORER;
-        real_act.sa_restorer = __sig_restorer;
-
-        act = &real_act;
-    }
-
-    return __sigaction(signum, act, oldact);
-}
diff --git a/libc/arch-arm/include/machine/_types.h b/libc/arch-arm/include/machine/_types.h
index 6d10e12..3e779ca 100644
--- a/libc/arch-arm/include/machine/_types.h
+++ b/libc/arch-arm/include/machine/_types.h
@@ -46,8 +46,6 @@
 typedef long           ptrdiff_t;
 #endif
 
-//#include <linux/types.h>
-
 /* 7.18.1.1 Exact-width integer types */
 typedef	__signed char		__int8_t;
 typedef	unsigned char		__uint8_t;
diff --git a/libc/arch-arm/include/machine/cpu-features.h b/libc/arch-arm/include/machine/cpu-features.h
index 902fe45..80d3fda 100644
--- a/libc/arch-arm/include/machine/cpu-features.h
+++ b/libc/arch-arm/include/machine/cpu-features.h
@@ -38,7 +38,7 @@
  * IMPORTANT: We have no intention to support anything below an ARMv4T !
  */
 
-/* _ARM_ARCH_REVISION is a number corresponding to the ARM revision
+/* __ARM_ARCH__ is a number corresponding to the ARM revision
  * we're going to support
  *
  * it looks like our toolchain doesn't define __ARM_ARCH__
@@ -142,20 +142,47 @@
  *
  *     ldr  pc, [<some address>]
  *
- * note that this affects any instruction that explicitely changes the
+ * note that this affects any instruction that explicitly changes the
  * value of the pc register, including ldm { ...,pc } or 'add pc, #offset'
  */
 #if __ARM_ARCH__ >= 5
 #  define __ARM_HAVE_PC_INTERWORK
 #endif
 
-/* define __ARM_HAVE_LDREX_STREX for ARMv6 and ARMv7 architecure to be
- * used in replacement of depricated swp instruction
+/* define __ARM_HAVE_LDREX_STREX for ARMv6 and ARMv7 architecture to be
+ * used in replacement of deprecated swp instruction
  */
 #if __ARM_ARCH__ >= 6
 #  define __ARM_HAVE_LDREX_STREX
 #endif
 
+/* define __ARM_HAVE_DMB for ARMv7 architecture
+ */
+#if __ARM_ARCH__ >= 7
+#  define __ARM_HAVE_DMB
+#endif
+
+/* define __ARM_HAVE_LDREXD for ARMv7 architecture
+ * (also present in ARMv6K, but not implemented in ARMv7-M, neither of which
+ * we care about)
+ */
+#if __ARM_ARCH__ >= 7
+#  define __ARM_HAVE_LDREXD
+#endif
+
+/* define _ARM_HAVE_VFP if we have VFPv3
+ */
+#if __ARM_ARCH__ >= 7 && defined __VFP_FP__
+#  define __ARM_HAVE_VFP
+#endif
+
+/* define _ARM_HAVE_NEON for ARMv7 architecture if we support the
+ * Neon SIMD instruction set extensions. This also implies
+ * that VFPv3-D32 is supported.
+ */
+#if __ARM_ARCH__ >= 7 && defined __ARM_NEON__
+#  define __ARM_HAVE_NEON
+#endif
 
 /* Assembly-only macros */
 #ifdef __ASSEMBLY__
diff --git a/libc/arch-arm/include/machine/setjmp.h b/libc/arch-arm/include/machine/setjmp.h
index f20cab2..0941202 100644
--- a/libc/arch-arm/include/machine/setjmp.h
+++ b/libc/arch-arm/include/machine/setjmp.h
@@ -1,87 +1,82 @@
-/*	$OpenBSD: setjmp.h,v 1.1 2004/02/01 05:09:49 drahn Exp $	*/
-/*	$NetBSD: setjmp.h,v 1.2 2001/08/25 14:45:59 bjh21 Exp $	*/
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *  * Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *  * Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
 
 /*
  * machine/setjmp.h: machine dependent setjmp-related information.
  */
 
-#ifdef __ELF__
-#define	_JBLEN	64		/* size, in longs, of a jmp_buf */
-#else
-#define	_JBLEN	29		/* size, in longs, of a jmp_buf */
-#endif
-
-/*
- * NOTE: The internal structure of a jmp_buf is *PRIVATE*
- *       This information is provided as there is software
- *       that fiddles with this with obtain the stack pointer
- *	 (yes really ! and its commercial !).
+/* _JBLEN is the size of a jmp_buf in longs.
+ * Do not modify this value or you will break the ABI !
  *
- * Description of the setjmp buffer
- *
- * word  0	magic number	(dependant on creator)
- *       1 -  3	f4		fp register 4
- *	 4 -  6	f5		fp register 5
- *	 7 -  9 f6		fp register 6
- *	10 - 12	f7		fp register 7
- *	13	fpsr		fp status register
- *	14	r4		register 4
- *	15	r5		register 5
- *	16	r6		register 6
- *	17	r7		register 7
- *	18	r8		register 8
- *	19	r9		register 9
- *	20	r10		register 10 (sl)
- *	21	r11		register 11 (fp)
- *	22	r12		register 12 (ip)
- *	23	r13		register 13 (sp)
- *	24	r14		register 14 (lr)
- *	25	signal mask	(dependant on magic)
- *	26	(con't)
- *	27	(con't)
- *	28	(con't)
- *
- * The magic number number identifies the jmp_buf and
- * how the buffer was created as well as providing
- * a sanity check
- *
- * A side note I should mention - Please do not tamper
- * with the floating point fields. While they are
- * always saved and restored at the moment this cannot
- * be garenteed especially if the compiler happens
- * to be generating soft-float code so no fp
- * registers will be used.
- *
- * Whilst this can be seen an encouraging people to
- * use the setjmp buffer in this way I think that it
- * is for the best then if changes occur compiles will
- * break rather than just having new builds falling over
- * mysteriously.
+ * This value comes from the original OpenBSD ARM-specific header
+ * that was replaced by this one.
  */
+#define _JBLEN  64
+
+/* According to the ARM AAPCS document, we only need to save
+ * the following registers:
+ *
+ *  Core   r4-r14
+ *
+ *  VFP    d8-d15  (see section 5.1.2.1)
+ *
+ *      Registers s16-s31 (d8-d15, q4-q7) must be preserved across subroutine
+ *      calls; registers s0-s15 (d0-d7, q0-q3) do not need to be preserved
+ *      (and can be used for passing arguments or returning results in standard
+ *      procedure-call variants). Registers d16-d31 (q8-q15), if present, do
+ *      not need to be preserved.
+ *
+ *  FPSCR  saved because GLibc does saves it too.
+ *
+ */
+
+/* The internal structure of a jmp_buf is totally private.
+ * Current layout (may change in the future):
+ *
+ * word   name         description
+ * 0      magic        magic number
+ * 1      sigmask      signal mask (not used with _setjmp / _longjmp)
+ * 2      float_base   base of float registers (d8 to d15)
+ * 18     float_state  floating-point status and control register
+ * 19     core_base    base of core registers (r4 to r14)
+ * 30     reserved     reserved entries (room to grow)
+ * 64
+ *
+ * NOTE: float_base must be at an even word index, since the
+ *       FP registers will be loaded/stored with instructions
+ *       that expect 8-byte alignment.
+ */
+
+#define _JB_MAGIC       0
+#define _JB_SIGMASK     (_JB_MAGIC+1)
+#define _JB_FLOAT_BASE  (_JB_SIGMASK+1)
+#define _JB_FLOAT_STATE (_JB_FLOAT_BASE + (15-8+1)*2)
+#define _JB_CORE_BASE   (_JB_FLOAT_STATE+1)
 
 #define _JB_MAGIC__SETJMP	0x4278f500
 #define _JB_MAGIC_SETJMP	0x4278f501
-
-/* Valid for all jmp_buf's */
-
-#define _JB_MAGIC		 0
-#define _JB_REG_F4		 1
-#define _JB_REG_F5		 4
-#define _JB_REG_F6		 7
-#define _JB_REG_F7		10
-#define _JB_REG_FPSR		13
-#define _JB_REG_R4		14
-#define _JB_REG_R5		15
-#define _JB_REG_R6		16
-#define _JB_REG_R7		17
-#define _JB_REG_R8		18
-#define _JB_REG_R9		19
-#define _JB_REG_R10		20
-#define _JB_REG_R11		21
-#define _JB_REG_R12		22
-#define _JB_REG_R13		23
-#define _JB_REG_R14		24
-
-/* Only valid with the _JB_MAGIC_SETJMP magic */
-
-#define _JB_SIGMASK		25
diff --git a/libc/arch-arm/syscalls.mk b/libc/arch-arm/syscalls.mk
index 9bfe70a..c3cf785 100644
--- a/libc/arch-arm/syscalls.mk
+++ b/libc/arch-arm/syscalls.mk
@@ -3,7 +3,7 @@
 syscall_src += arch-arm/syscalls/_exit.S
 syscall_src += arch-arm/syscalls/_exit_thread.S
 syscall_src += arch-arm/syscalls/__fork.S
-syscall_src += arch-arm/syscalls/waitid.S
+syscall_src += arch-arm/syscalls/__waitid.S
 syscall_src += arch-arm/syscalls/__sys_clone.S
 syscall_src += arch-arm/syscalls/execve.S
 syscall_src += arch-arm/syscalls/__setuid.S
@@ -66,15 +66,17 @@
 syscall_src += arch-arm/syscalls/fchmod.S
 syscall_src += arch-arm/syscalls/dup.S
 syscall_src += arch-arm/syscalls/pipe.S
+syscall_src += arch-arm/syscalls/pipe2.S
 syscall_src += arch-arm/syscalls/dup2.S
 syscall_src += arch-arm/syscalls/select.S
 syscall_src += arch-arm/syscalls/ftruncate.S
 syscall_src += arch-arm/syscalls/getdents.S
 syscall_src += arch-arm/syscalls/fsync.S
+syscall_src += arch-arm/syscalls/fdatasync.S
 syscall_src += arch-arm/syscalls/fchown.S
 syscall_src += arch-arm/syscalls/sync.S
 syscall_src += arch-arm/syscalls/__fcntl64.S
-syscall_src += arch-arm/syscalls/fstatfs.S
+syscall_src += arch-arm/syscalls/__fstatfs64.S
 syscall_src += arch-arm/syscalls/sendfile.S
 syscall_src += arch-arm/syscalls/fstatat.S
 syscall_src += arch-arm/syscalls/mkdirat.S
@@ -121,13 +123,13 @@
 syscall_src += arch-arm/syscalls/__timer_getoverrun.S
 syscall_src += arch-arm/syscalls/__timer_delete.S
 syscall_src += arch-arm/syscalls/utimes.S
+syscall_src += arch-arm/syscalls/sigaction.S
 syscall_src += arch-arm/syscalls/sigprocmask.S
 syscall_src += arch-arm/syscalls/__sigsuspend.S
 syscall_src += arch-arm/syscalls/__rt_sigaction.S
 syscall_src += arch-arm/syscalls/__rt_sigprocmask.S
 syscall_src += arch-arm/syscalls/__rt_sigtimedwait.S
 syscall_src += arch-arm/syscalls/sigpending.S
-syscall_src += arch-arm/syscalls/__sigaction.S
 syscall_src += arch-arm/syscalls/socket.S
 syscall_src += arch-arm/syscalls/socketpair.S
 syscall_src += arch-arm/syscalls/bind.S
@@ -161,6 +163,7 @@
 syscall_src += arch-arm/syscalls/init_module.S
 syscall_src += arch-arm/syscalls/delete_module.S
 syscall_src += arch-arm/syscalls/klogctl.S
+syscall_src += arch-arm/syscalls/sysinfo.S
 syscall_src += arch-arm/syscalls/futex.S
 syscall_src += arch-arm/syscalls/epoll_create.S
 syscall_src += arch-arm/syscalls/epoll_ctl.S
@@ -169,6 +172,7 @@
 syscall_src += arch-arm/syscalls/inotify_add_watch.S
 syscall_src += arch-arm/syscalls/inotify_rm_watch.S
 syscall_src += arch-arm/syscalls/poll.S
+syscall_src += arch-arm/syscalls/eventfd.S
 syscall_src += arch-arm/syscalls/__set_tls.S
 syscall_src += arch-arm/syscalls/cacheflush.S
 syscall_src += arch-arm/syscalls/eventfd.S
diff --git a/libc/arch-arm/syscalls/fstatfs.S b/libc/arch-arm/syscalls/__fstatfs64.S
similarity index 81%
rename from libc/arch-arm/syscalls/fstatfs.S
rename to libc/arch-arm/syscalls/__fstatfs64.S
index 88150d6..00b4e41 100644
--- a/libc/arch-arm/syscalls/fstatfs.S
+++ b/libc/arch-arm/syscalls/__fstatfs64.S
@@ -2,12 +2,12 @@
 #include <sys/linux-syscalls.h>
 
     .text
-    .type fstatfs, #function
-    .globl fstatfs
+    .type __fstatfs64, #function
+    .globl __fstatfs64
     .align 4
     .fnstart
 
-fstatfs:
+__fstatfs64:
     .save   {r4, r7}
     stmfd   sp!, {r4, r7}
     ldr     r7, =__NR_fstatfs64
diff --git a/libc/arch-arm/syscalls/waitid.S b/libc/arch-arm/syscalls/__waitid.S
similarity index 86%
rename from libc/arch-arm/syscalls/waitid.S
rename to libc/arch-arm/syscalls/__waitid.S
index 4134e53..fdd0da3 100644
--- a/libc/arch-arm/syscalls/waitid.S
+++ b/libc/arch-arm/syscalls/__waitid.S
@@ -2,12 +2,12 @@
 #include <sys/linux-syscalls.h>
 
     .text
-    .type waitid, #function
-    .globl waitid
+    .type __waitid, #function
+    .globl __waitid
     .align 4
     .fnstart
 
-waitid:
+__waitid:
     mov     ip, sp
     .save   {r4, r5, r6, r7}
     stmfd   sp!, {r4, r5, r6, r7}
diff --git a/libc/arch-arm/syscalls/eventfd.S b/libc/arch-arm/syscalls/eventfd.S
index fb0912f..8d2cce9 100644
--- a/libc/arch-arm/syscalls/eventfd.S
+++ b/libc/arch-arm/syscalls/eventfd.S
@@ -10,7 +10,7 @@
 eventfd:
     .save   {r4, r7}
     stmfd   sp!, {r4, r7}
-    ldr     r7, =__NR_eventfd
+    ldr     r7, =__NR_eventfd2
     swi     #0
     ldmfd   sp!, {r4, r7}
     movs    r0, r0
diff --git a/libc/arch-arm/syscalls/fstatfs.S b/libc/arch-arm/syscalls/fdatasync.S
similarity index 74%
copy from libc/arch-arm/syscalls/fstatfs.S
copy to libc/arch-arm/syscalls/fdatasync.S
index 88150d6..5981a80 100644
--- a/libc/arch-arm/syscalls/fstatfs.S
+++ b/libc/arch-arm/syscalls/fdatasync.S
@@ -2,15 +2,15 @@
 #include <sys/linux-syscalls.h>
 
     .text
-    .type fstatfs, #function
-    .globl fstatfs
+    .type fdatasync, #function
+    .globl fdatasync
     .align 4
     .fnstart
 
-fstatfs:
+fdatasync:
     .save   {r4, r7}
     stmfd   sp!, {r4, r7}
-    ldr     r7, =__NR_fstatfs64
+    ldr     r7, =__NR_fdatasync
     swi     #0
     ldmfd   sp!, {r4, r7}
     movs    r0, r0
diff --git a/libc/arch-arm/syscalls/fstatfs.S b/libc/arch-arm/syscalls/pipe2.S
similarity index 75%
copy from libc/arch-arm/syscalls/fstatfs.S
copy to libc/arch-arm/syscalls/pipe2.S
index 88150d6..df77094 100644
--- a/libc/arch-arm/syscalls/fstatfs.S
+++ b/libc/arch-arm/syscalls/pipe2.S
@@ -2,15 +2,15 @@
 #include <sys/linux-syscalls.h>
 
     .text
-    .type fstatfs, #function
-    .globl fstatfs
+    .type pipe2, #function
+    .globl pipe2
     .align 4
     .fnstart
 
-fstatfs:
+pipe2:
     .save   {r4, r7}
     stmfd   sp!, {r4, r7}
-    ldr     r7, =__NR_fstatfs64
+    ldr     r7, =__NR_pipe2
     swi     #0
     ldmfd   sp!, {r4, r7}
     movs    r0, r0
diff --git a/libc/arch-arm/syscalls/__sigaction.S b/libc/arch-arm/syscalls/sigaction.S
similarity index 81%
rename from libc/arch-arm/syscalls/__sigaction.S
rename to libc/arch-arm/syscalls/sigaction.S
index aba44b8..2696f1e 100644
--- a/libc/arch-arm/syscalls/__sigaction.S
+++ b/libc/arch-arm/syscalls/sigaction.S
@@ -2,12 +2,12 @@
 #include <sys/linux-syscalls.h>
 
     .text
-    .type __sigaction, #function
-    .globl __sigaction
+    .type sigaction, #function
+    .globl sigaction
     .align 4
     .fnstart
 
-__sigaction:
+sigaction:
     .save   {r4, r7}
     stmfd   sp!, {r4, r7}
     ldr     r7, =__NR_sigaction
diff --git a/libc/arch-arm/syscalls/fstatfs.S b/libc/arch-arm/syscalls/sysinfo.S
similarity index 75%
copy from libc/arch-arm/syscalls/fstatfs.S
copy to libc/arch-arm/syscalls/sysinfo.S
index 88150d6..197324d 100644
--- a/libc/arch-arm/syscalls/fstatfs.S
+++ b/libc/arch-arm/syscalls/sysinfo.S
@@ -2,15 +2,15 @@
 #include <sys/linux-syscalls.h>
 
     .text
-    .type fstatfs, #function
-    .globl fstatfs
+    .type sysinfo, #function
+    .globl sysinfo
     .align 4
     .fnstart
 
-fstatfs:
+sysinfo:
     .save   {r4, r7}
     stmfd   sp!, {r4, r7}
-    ldr     r7, =__NR_fstatfs64
+    ldr     r7, =__NR_sysinfo
     swi     #0
     ldmfd   sp!, {r4, r7}
     movs    r0, r0
diff --git a/libc/arch-sh/syscalls.mk b/libc/arch-sh/syscalls.mk
index ab2f3d1..a87419d 100644
--- a/libc/arch-sh/syscalls.mk
+++ b/libc/arch-sh/syscalls.mk
@@ -4,7 +4,7 @@
 syscall_src += arch-sh/syscalls/_exit_thread.S
 syscall_src += arch-sh/syscalls/__fork.S
 syscall_src += arch-sh/syscalls/_waitpid.S
-syscall_src += arch-sh/syscalls/waitid.S
+syscall_src += arch-sh/syscalls/__waitid.S
 syscall_src += arch-sh/syscalls/__sys_clone.S
 syscall_src += arch-sh/syscalls/execve.S
 syscall_src += arch-sh/syscalls/__setuid.S
@@ -69,15 +69,17 @@
 syscall_src += arch-sh/syscalls/flock.S
 syscall_src += arch-sh/syscalls/fchmod.S
 syscall_src += arch-sh/syscalls/dup.S
+syscall_src += arch-sh/syscalls/pipe2.S
 syscall_src += arch-sh/syscalls/dup2.S
 syscall_src += arch-sh/syscalls/select.S
 syscall_src += arch-sh/syscalls/ftruncate.S
 syscall_src += arch-sh/syscalls/getdents.S
 syscall_src += arch-sh/syscalls/fsync.S
+syscall_src += arch-sh/syscalls/fdatasync.S
 syscall_src += arch-sh/syscalls/fchown.S
 syscall_src += arch-sh/syscalls/sync.S
 syscall_src += arch-sh/syscalls/__fcntl64.S
-syscall_src += arch-sh/syscalls/fstatfs.S
+syscall_src += arch-sh/syscalls/__fstatfs64.S
 syscall_src += arch-sh/syscalls/sendfile.S
 syscall_src += arch-sh/syscalls/fstatat.S
 syscall_src += arch-sh/syscalls/mkdirat.S
@@ -150,6 +152,7 @@
 syscall_src += arch-sh/syscalls/init_module.S
 syscall_src += arch-sh/syscalls/delete_module.S
 syscall_src += arch-sh/syscalls/klogctl.S
+syscall_src += arch-sh/syscalls/sysinfo.S
 syscall_src += arch-sh/syscalls/futex.S
 syscall_src += arch-sh/syscalls/epoll_create.S
 syscall_src += arch-sh/syscalls/epoll_ctl.S
@@ -158,3 +161,4 @@
 syscall_src += arch-sh/syscalls/inotify_add_watch.S
 syscall_src += arch-sh/syscalls/inotify_rm_watch.S
 syscall_src += arch-sh/syscalls/poll.S
+syscall_src += arch-sh/syscalls/eventfd.S
diff --git a/libc/arch-sh/syscalls/fstatfs.S b/libc/arch-sh/syscalls/__fstatfs64.S
similarity index 87%
rename from libc/arch-sh/syscalls/fstatfs.S
rename to libc/arch-sh/syscalls/__fstatfs64.S
index 6adb2cb..dcf1d80 100644
--- a/libc/arch-sh/syscalls/fstatfs.S
+++ b/libc/arch-sh/syscalls/__fstatfs64.S
@@ -2,11 +2,11 @@
 #include <sys/linux-syscalls.h>
 
     .text
-    .type fstatfs, @function
-    .globl fstatfs
+    .type __fstatfs64, @function
+    .globl __fstatfs64
     .align 4
 
-fstatfs:
+__fstatfs64:
 
     /* invoke trap */
     mov.l   0f, r3  /* trap num */
diff --git a/libc/arch-sh/syscalls/waitid.S b/libc/arch-sh/syscalls/__waitid.S
similarity index 90%
rename from libc/arch-sh/syscalls/waitid.S
rename to libc/arch-sh/syscalls/__waitid.S
index 1f0432d..1f58de0 100644
--- a/libc/arch-sh/syscalls/waitid.S
+++ b/libc/arch-sh/syscalls/__waitid.S
@@ -2,11 +2,11 @@
 #include <sys/linux-syscalls.h>
 
     .text
-    .type waitid, @function
-    .globl waitid
+    .type __waitid, @function
+    .globl __waitid
     .align 4
 
-waitid:
+__waitid:
 
     /* get ready for additonal arg */
     mov.l   @r15, r0
diff --git a/libc/arch-sh/syscalls/fstatfs.S b/libc/arch-sh/syscalls/eventfd.S
similarity index 70%
copy from libc/arch-sh/syscalls/fstatfs.S
copy to libc/arch-sh/syscalls/eventfd.S
index 6adb2cb..c73bf23 100644
--- a/libc/arch-sh/syscalls/fstatfs.S
+++ b/libc/arch-sh/syscalls/eventfd.S
@@ -2,19 +2,19 @@
 #include <sys/linux-syscalls.h>
 
     .text
-    .type fstatfs, @function
-    .globl fstatfs
+    .type eventfd, @function
+    .globl eventfd
     .align 4
 
-fstatfs:
+eventfd:
 
     /* invoke trap */
     mov.l   0f, r3  /* trap num */
-    trapa   #(3 + 0x10)
+    trapa   #(2 + 0x10)
 
     /* check return value */
     cmp/pz  r0
-    bt      __NR_fstatfs64_end
+    bt      __NR_eventfd2_end
 
     /* keep error number */
     sts.l   pr, @-r15
@@ -23,10 +23,10 @@
     mov     r0, r4
     lds.l   @r15+, pr
 
-__NR_fstatfs64_end:
+__NR_eventfd2_end:
     rts
     nop
 
     .align  2
-0:  .long   __NR_fstatfs64
+0:  .long   __NR_eventfd2
 1:  .long   __set_syscall_errno
diff --git a/libc/arch-sh/syscalls/fstatfs.S b/libc/arch-sh/syscalls/fdatasync.S
similarity index 70%
copy from libc/arch-sh/syscalls/fstatfs.S
copy to libc/arch-sh/syscalls/fdatasync.S
index 6adb2cb..d81c33a 100644
--- a/libc/arch-sh/syscalls/fstatfs.S
+++ b/libc/arch-sh/syscalls/fdatasync.S
@@ -2,19 +2,19 @@
 #include <sys/linux-syscalls.h>
 
     .text
-    .type fstatfs, @function
-    .globl fstatfs
+    .type fdatasync, @function
+    .globl fdatasync
     .align 4
 
-fstatfs:
+fdatasync:
 
     /* invoke trap */
     mov.l   0f, r3  /* trap num */
-    trapa   #(3 + 0x10)
+    trapa   #(1 + 0x10)
 
     /* check return value */
     cmp/pz  r0
-    bt      __NR_fstatfs64_end
+    bt      __NR_fdatasync_end
 
     /* keep error number */
     sts.l   pr, @-r15
@@ -23,10 +23,10 @@
     mov     r0, r4
     lds.l   @r15+, pr
 
-__NR_fstatfs64_end:
+__NR_fdatasync_end:
     rts
     nop
 
     .align  2
-0:  .long   __NR_fstatfs64
+0:  .long   __NR_fdatasync
 1:  .long   __set_syscall_errno
diff --git a/libc/arch-sh/syscalls/fstatfs.S b/libc/arch-sh/syscalls/pipe2.S
similarity index 70%
copy from libc/arch-sh/syscalls/fstatfs.S
copy to libc/arch-sh/syscalls/pipe2.S
index 6adb2cb..f6d9964 100644
--- a/libc/arch-sh/syscalls/fstatfs.S
+++ b/libc/arch-sh/syscalls/pipe2.S
@@ -2,19 +2,19 @@
 #include <sys/linux-syscalls.h>
 
     .text
-    .type fstatfs, @function
-    .globl fstatfs
+    .type pipe2, @function
+    .globl pipe2
     .align 4
 
-fstatfs:
+pipe2:
 
     /* invoke trap */
     mov.l   0f, r3  /* trap num */
-    trapa   #(3 + 0x10)
+    trapa   #(2 + 0x10)
 
     /* check return value */
     cmp/pz  r0
-    bt      __NR_fstatfs64_end
+    bt      __NR_pipe2_end
 
     /* keep error number */
     sts.l   pr, @-r15
@@ -23,10 +23,10 @@
     mov     r0, r4
     lds.l   @r15+, pr
 
-__NR_fstatfs64_end:
+__NR_pipe2_end:
     rts
     nop
 
     .align  2
-0:  .long   __NR_fstatfs64
+0:  .long   __NR_pipe2
 1:  .long   __set_syscall_errno
diff --git a/libc/arch-sh/syscalls/fstatfs.S b/libc/arch-sh/syscalls/sysinfo.S
similarity index 70%
copy from libc/arch-sh/syscalls/fstatfs.S
copy to libc/arch-sh/syscalls/sysinfo.S
index 6adb2cb..ae042ab 100644
--- a/libc/arch-sh/syscalls/fstatfs.S
+++ b/libc/arch-sh/syscalls/sysinfo.S
@@ -2,19 +2,19 @@
 #include <sys/linux-syscalls.h>
 
     .text
-    .type fstatfs, @function
-    .globl fstatfs
+    .type sysinfo, @function
+    .globl sysinfo
     .align 4
 
-fstatfs:
+sysinfo:
 
     /* invoke trap */
     mov.l   0f, r3  /* trap num */
-    trapa   #(3 + 0x10)
+    trapa   #(1 + 0x10)
 
     /* check return value */
     cmp/pz  r0
-    bt      __NR_fstatfs64_end
+    bt      __NR_sysinfo_end
 
     /* keep error number */
     sts.l   pr, @-r15
@@ -23,10 +23,10 @@
     mov     r0, r4
     lds.l   @r15+, pr
 
-__NR_fstatfs64_end:
+__NR_sysinfo_end:
     rts
     nop
 
     .align  2
-0:  .long   __NR_fstatfs64
+0:  .long   __NR_sysinfo
 1:  .long   __set_syscall_errno
diff --git a/libc/arch-x86/syscalls.mk b/libc/arch-x86/syscalls.mk
index ab026fe..420a91e 100644
--- a/libc/arch-x86/syscalls.mk
+++ b/libc/arch-x86/syscalls.mk
@@ -4,7 +4,7 @@
 syscall_src += arch-x86/syscalls/_exit_thread.S
 syscall_src += arch-x86/syscalls/__fork.S
 syscall_src += arch-x86/syscalls/_waitpid.S
-syscall_src += arch-x86/syscalls/waitid.S
+syscall_src += arch-x86/syscalls/__waitid.S
 syscall_src += arch-x86/syscalls/__sys_clone.S
 syscall_src += arch-x86/syscalls/execve.S
 syscall_src += arch-x86/syscalls/__setuid.S
@@ -69,15 +69,17 @@
 syscall_src += arch-x86/syscalls/fchmod.S
 syscall_src += arch-x86/syscalls/dup.S
 syscall_src += arch-x86/syscalls/pipe.S
+syscall_src += arch-x86/syscalls/pipe2.S
 syscall_src += arch-x86/syscalls/dup2.S
 syscall_src += arch-x86/syscalls/select.S
 syscall_src += arch-x86/syscalls/ftruncate.S
 syscall_src += arch-x86/syscalls/getdents.S
 syscall_src += arch-x86/syscalls/fsync.S
+syscall_src += arch-x86/syscalls/fdatasync.S
 syscall_src += arch-x86/syscalls/fchown.S
 syscall_src += arch-x86/syscalls/sync.S
 syscall_src += arch-x86/syscalls/__fcntl64.S
-syscall_src += arch-x86/syscalls/fstatfs.S
+syscall_src += arch-x86/syscalls/__fstatfs64.S
 syscall_src += arch-x86/syscalls/sendfile.S
 syscall_src += arch-x86/syscalls/fstatat.S
 syscall_src += arch-x86/syscalls/mkdirat.S
@@ -164,6 +166,7 @@
 syscall_src += arch-x86/syscalls/init_module.S
 syscall_src += arch-x86/syscalls/delete_module.S
 syscall_src += arch-x86/syscalls/klogctl.S
+syscall_src += arch-x86/syscalls/sysinfo.S
 syscall_src += arch-x86/syscalls/futex.S
 syscall_src += arch-x86/syscalls/epoll_create.S
 syscall_src += arch-x86/syscalls/epoll_ctl.S
@@ -172,3 +175,4 @@
 syscall_src += arch-x86/syscalls/inotify_add_watch.S
 syscall_src += arch-x86/syscalls/inotify_rm_watch.S
 syscall_src += arch-x86/syscalls/poll.S
+syscall_src += arch-x86/syscalls/eventfd.S
diff --git a/libc/arch-x86/syscalls/fstatfs.S b/libc/arch-x86/syscalls/__fstatfs64.S
similarity index 87%
rename from libc/arch-x86/syscalls/fstatfs.S
rename to libc/arch-x86/syscalls/__fstatfs64.S
index f72b3d4..f755244 100644
--- a/libc/arch-x86/syscalls/fstatfs.S
+++ b/libc/arch-x86/syscalls/__fstatfs64.S
@@ -2,11 +2,11 @@
 #include <sys/linux-syscalls.h>
 
     .text
-    .type fstatfs, @function
-    .globl fstatfs
+    .type __fstatfs64, @function
+    .globl __fstatfs64
     .align 4
 
-fstatfs:
+__fstatfs64:
     pushl   %ebx
     pushl   %ecx
     pushl   %edx
diff --git a/libc/arch-x86/syscalls/waitid.S b/libc/arch-x86/syscalls/__waitid.S
similarity index 90%
rename from libc/arch-x86/syscalls/waitid.S
rename to libc/arch-x86/syscalls/__waitid.S
index 9a5328b..4dd8c11 100644
--- a/libc/arch-x86/syscalls/waitid.S
+++ b/libc/arch-x86/syscalls/__waitid.S
@@ -2,11 +2,11 @@
 #include <sys/linux-syscalls.h>
 
     .text
-    .type waitid, @function
-    .globl waitid
+    .type __waitid, @function
+    .globl __waitid
     .align 4
 
-waitid:
+__waitid:
     pushl   %ebx
     pushl   %ecx
     pushl   %edx
diff --git a/libc/arch-x86/syscalls/fstatfs.S b/libc/arch-x86/syscalls/eventfd.S
similarity index 61%
copy from libc/arch-x86/syscalls/fstatfs.S
copy to libc/arch-x86/syscalls/eventfd.S
index f72b3d4..104c842 100644
--- a/libc/arch-x86/syscalls/fstatfs.S
+++ b/libc/arch-x86/syscalls/eventfd.S
@@ -2,18 +2,16 @@
 #include <sys/linux-syscalls.h>
 
     .text
-    .type fstatfs, @function
-    .globl fstatfs
+    .type eventfd, @function
+    .globl eventfd
     .align 4
 
-fstatfs:
+eventfd:
     pushl   %ebx
     pushl   %ecx
-    pushl   %edx
-    mov     16(%esp), %ebx
-    mov     20(%esp), %ecx
-    mov     24(%esp), %edx
-    movl    $__NR_fstatfs64, %eax
+    mov     12(%esp), %ebx
+    mov     16(%esp), %ecx
+    movl    $__NR_eventfd2, %eax
     int     $0x80
     cmpl    $-129, %eax
     jb      1f
@@ -23,7 +21,6 @@
     addl    $4, %esp
     orl     $-1, %eax
 1:
-    popl    %edx
     popl    %ecx
     popl    %ebx
     ret
diff --git a/libc/arch-x86/syscalls/fdatasync.S b/libc/arch-x86/syscalls/fdatasync.S
new file mode 100644
index 0000000..b86c0f8
--- /dev/null
+++ b/libc/arch-x86/syscalls/fdatasync.S
@@ -0,0 +1,23 @@
+/* autogenerated by gensyscalls.py */
+#include <sys/linux-syscalls.h>
+
+    .text
+    .type fdatasync, @function
+    .globl fdatasync
+    .align 4
+
+fdatasync:
+    pushl   %ebx
+    mov     8(%esp), %ebx
+    movl    $__NR_fdatasync, %eax
+    int     $0x80
+    cmpl    $-129, %eax
+    jb      1f
+    negl    %eax
+    pushl   %eax
+    call    __set_errno
+    addl    $4, %esp
+    orl     $-1, %eax
+1:
+    popl    %ebx
+    ret
diff --git a/libc/arch-x86/syscalls/fstatfs.S b/libc/arch-x86/syscalls/pipe2.S
similarity index 61%
copy from libc/arch-x86/syscalls/fstatfs.S
copy to libc/arch-x86/syscalls/pipe2.S
index f72b3d4..c3354a7 100644
--- a/libc/arch-x86/syscalls/fstatfs.S
+++ b/libc/arch-x86/syscalls/pipe2.S
@@ -2,18 +2,16 @@
 #include <sys/linux-syscalls.h>
 
     .text
-    .type fstatfs, @function
-    .globl fstatfs
+    .type pipe2, @function
+    .globl pipe2
     .align 4
 
-fstatfs:
+pipe2:
     pushl   %ebx
     pushl   %ecx
-    pushl   %edx
-    mov     16(%esp), %ebx
-    mov     20(%esp), %ecx
-    mov     24(%esp), %edx
-    movl    $__NR_fstatfs64, %eax
+    mov     12(%esp), %ebx
+    mov     16(%esp), %ecx
+    movl    $__NR_pipe2, %eax
     int     $0x80
     cmpl    $-129, %eax
     jb      1f
@@ -23,7 +21,6 @@
     addl    $4, %esp
     orl     $-1, %eax
 1:
-    popl    %edx
     popl    %ecx
     popl    %ebx
     ret
diff --git a/libc/arch-x86/syscalls/sysinfo.S b/libc/arch-x86/syscalls/sysinfo.S
new file mode 100644
index 0000000..c60c37b
--- /dev/null
+++ b/libc/arch-x86/syscalls/sysinfo.S
@@ -0,0 +1,23 @@
+/* autogenerated by gensyscalls.py */
+#include <sys/linux-syscalls.h>
+
+    .text
+    .type sysinfo, @function
+    .globl sysinfo
+    .align 4
+
+sysinfo:
+    pushl   %ebx
+    mov     8(%esp), %ebx
+    movl    $__NR_sysinfo, %eax
+    int     $0x80
+    cmpl    $-129, %eax
+    jb      1f
+    negl    %eax
+    pushl   %eax
+    call    __set_errno
+    addl    $4, %esp
+    orl     $-1, %eax
+1:
+    popl    %ebx
+    ret
diff --git a/libc/bionic/clearenv.c b/libc/bionic/clearenv.c
index 9a3b2a1..0f6f066 100644
--- a/libc/bionic/clearenv.c
+++ b/libc/bionic/clearenv.c
@@ -26,14 +26,17 @@
  * SUCH DAMAGE.
  */
 
+#include <stddef.h>
+
 extern char** environ;
 
 int clearenv(void)
 {
-	char **P;
+    char **P = environ;
 
-	for (P = environ; *P; ++P)
-		*P = 0;
-
-	return 0;
+    if (P != NULL) {
+        for (; *P; ++P)
+            *P = NULL;
+    }
+    return 0;
 }
diff --git a/libc/bionic/cpuacct.c b/libc/bionic/cpuacct.c
index abdbc51..7317073 100644
--- a/libc/bionic/cpuacct.c
+++ b/libc/bionic/cpuacct.c
@@ -29,7 +29,7 @@
 #include <stdio.h>
 #include <errno.h>
 #include <sys/stat.h>
-//#include <sys/types.h>
+#include "cpuacct.h"
 
 int cpuacct_add(uid_t uid)
 {
diff --git a/libc/bionic/fork.c b/libc/bionic/fork.c
index 8d3ea4b..0eedb01 100644
--- a/libc/bionic/fork.c
+++ b/libc/bionic/fork.c
@@ -27,6 +27,7 @@
  */
 #include <unistd.h>
 #include "pthread_internal.h"
+#include "cpuacct.h"
 
 extern int  __fork(void);
 
diff --git a/libc/bionic/fts.c b/libc/bionic/fts.c
index 3dcfb28..c7770b6 100644
--- a/libc/bionic/fts.c
+++ b/libc/bionic/fts.c
@@ -548,9 +548,9 @@
 	DIR *dirp;
 	void *oldaddr;
 	size_t len, maxlen;
-	int nitems, cderrno, descend, level, nlinks, nostat, doadjust;
+	int nitems, cderrno, descend, level, nlinks, nostat = 0, doadjust;
 	int saved_errno;
-	char *cp;
+	char *cp = NULL;
 
 	/* Set current node pointer. */
 	cur = sp->fts_cur;
diff --git a/libc/bionic/libc_init_common.c b/libc/bionic/libc_init_common.c
index dd6e027..b6a6379 100644
--- a/libc/bionic/libc_init_common.c
+++ b/libc/bionic/libc_init_common.c
@@ -84,3 +84,39 @@
     /* setup system properties - requires environment */
     __system_properties_init();
 }
+
+/* This function will be called during normal program termination
+ * to run the destructors that are listed in the .fini_array section
+ * of the executable, if any.
+ *
+ * 'fini_array' points to a list of function addresses. The first
+ * entry in the list has value -1, the last one has value 0.
+ */
+void __libc_fini(void* array)
+{
+    int count;
+    void** fini_array = array;
+    const size_t  minus1 = ~(size_t)0; /* ensure proper sign extension */
+
+    /* Sanity check - first entry must be -1 */
+    if (array == NULL || (size_t)fini_array[0] != minus1) {
+        return;
+    }
+
+    /* skip over it */
+    fini_array += 1;
+
+    /* Count the number of destructors. */
+    for (count = 0; fini_array[count] != NULL; count++);
+
+    /* Now call each destructor in reverse order. */
+    while (count > 0) {
+        void (*func)() = (void (*)) fini_array[--count];
+
+        /* Sanity check, any -1 in the list is ignored */
+        if ((size_t)func == minus1)
+            continue;
+
+        func();
+    }
+}
diff --git a/libc/bionic/libc_init_common.h b/libc/bionic/libc_init_common.h
index 8663c61..6016d4d 100644
--- a/libc/bionic/libc_init_common.h
+++ b/libc/bionic/libc_init_common.h
@@ -39,5 +39,6 @@
 } structors_array_t;
 
 extern void __libc_init_common(uintptr_t *elfdata);
+extern void __libc_fini(void* finit_array);
 
 #endif
diff --git a/libc/bionic/libc_init_dynamic.c b/libc/bionic/libc_init_dynamic.c
index 97e80ea..4bb2a81 100644
--- a/libc/bionic/libc_init_dynamic.c
+++ b/libc/bionic/libc_init_dynamic.c
@@ -57,9 +57,9 @@
  * This ensures that the function is called by the dynamic linker
  * as soon as the shared library is loaded.
  */
-void __attribute__((constructor)) __libc_prenit(void);
+void __attribute__((constructor)) __libc_preinit(void);
 
-void __libc_prenit(void)
+void __libc_preinit(void)
 {
     /* Read the ELF data pointer from a special slot of the
      * TLS area, then call __libc_init_common with it.
@@ -83,14 +83,19 @@
     malloc_debug_init();
 }
 
+/* This function is called from the executable's _start entry point
+ * (see arch-$ARCH/bionic/crtbegin_dynamic.S), which is itself
+ * called by the dynamic linker after it has loaded all shared
+ * libraries the executable depends on.
+ *
+ * Note that the dynamic linker has also run all constructors in the
+ * executable at this point.
+ */
 __noreturn void __libc_init(uintptr_t *elfdata,
                        void (*onexit)(void),
                        int (*slingshot)(int, char**, char**),
                        structors_array_t const * const structors)
 {
-    /* When we reach this point, all initializers have been already
-     * run by the dynamic linker, so ignore 'structors'.
-     */
     int     argc = (int)*elfdata;
     char**  argv = (char**)(elfdata + 1);
     char**  envp = argv + argc + 1;
@@ -99,5 +104,12 @@
      * do never use it.  Therefore, we ignore it.
      */
 
+    /* The executable may have its own destructors listed in its .fini_array
+     * so we need to ensure that these are called when the program exits
+     * normally.
+     */
+    if (structors->fini_array)
+        __cxa_atexit(__libc_fini,structors->fini_array,NULL);
+
     exit(slingshot(argc, argv, envp));
 }
diff --git a/libc/bionic/libc_init_static.c b/libc/bionic/libc_init_static.c
index d097b6b..3634c7b 100644
--- a/libc/bionic/libc_init_static.c
+++ b/libc/bionic/libc_init_static.c
@@ -85,5 +85,12 @@
     argv = (char**)(elfdata + 1);
     envp = argv + argc + 1;
 
+    /* The executable may have its own destructors listed in its .fini_array
+     * so we need to ensure that these are called when the program exits
+     * normally.
+     */
+    if (structors->fini_array)
+        __cxa_atexit(__libc_fini,structors->fini_array,NULL);
+
     exit(slingshot(argc, argv, envp));
 }
diff --git a/libc/bionic/logd_write.c b/libc/bionic/logd_write.c
index 618160f..63dfd59 100644
--- a/libc/bionic/logd_write.c
+++ b/libc/bionic/logd_write.c
@@ -38,12 +38,17 @@
 #include <stdarg.h>
 #include <fcntl.h>
 
-#include <cutils/logger.h>
 #include "logd.h"
 
+/* should match system/core/include/cutils/logger.h */
+#define LOGGER_LOG_MAIN     "log/main"
+#define LOGGER_LOG_RADIO    "log/radio"
+#define LOGGER_LOG_EVENTS   "log/events"
+#define LOGGER_LOG_SYSTEM   "log/system"
+
 #include <pthread.h>
 
-#define LOG_BUF_SIZE	1024
+#define LOG_BUF_SIZE    1024
 
 typedef enum {
     LOG_ID_NONE = 0,
diff --git a/libc/bionic/malloc_debug_common.c b/libc/bionic/malloc_debug_common.c
index ec56826..f05576c 100644
--- a/libc/bionic/malloc_debug_common.c
+++ b/libc/bionic/malloc_debug_common.c
@@ -60,34 +60,43 @@
 
 static int hash_entry_compare(const void* arg1, const void* arg2)
 {
+    int result;
+
     HashEntry* e1 = *(HashEntry**)arg1;
     HashEntry* e2 = *(HashEntry**)arg2;
 
-    size_t nbAlloc1 = e1->allocations;
-    size_t nbAlloc2 = e2->allocations;
-    size_t size1 = e1->size & ~SIZE_FLAG_MASK;
-    size_t size2 = e2->size & ~SIZE_FLAG_MASK;
-    size_t alloc1 = nbAlloc1 * size1;
-    size_t alloc2 = nbAlloc2 * size2;
-
-    // sort in descending order by:
-    // 1) total size
-    // 2) number of allocations
-    //
-    // This is used for sorting, not determination of equality, so we don't
-    // need to compare the bit flags.
-    int result;
-    if (alloc1 > alloc2) {
+    // if one or both arg pointers are null, deal gracefully
+    if (e1 == NULL) {
+        result = (e2 == NULL) ? 0 : 1;
+    } else if (e2 == NULL) {
         result = -1;
-    } else if (alloc1 < alloc2) {
-        result = 1;
     } else {
-        if (nbAlloc1 > nbAlloc2) {
+        size_t nbAlloc1 = e1->allocations;
+        size_t nbAlloc2 = e2->allocations;
+        size_t size1 = e1->size & ~SIZE_FLAG_MASK;
+        size_t size2 = e2->size & ~SIZE_FLAG_MASK;
+        size_t alloc1 = nbAlloc1 * size1;
+        size_t alloc2 = nbAlloc2 * size2;
+
+        // sort in descending order by:
+        // 1) total size
+        // 2) number of allocations
+        //
+        // This is used for sorting, not determination of equality, so we don't
+        // need to compare the bit flags.
+        int result;
+        if (alloc1 > alloc2) {
             result = -1;
-        } else if (nbAlloc1 < nbAlloc2) {
+        } else if (alloc1 < alloc2) {
             result = 1;
         } else {
-            result = 0;
+            if (nbAlloc1 > nbAlloc2) {
+                result = -1;
+            } else if (nbAlloc1 < nbAlloc2) {
+                result = 1;
+            } else {
+                result = 0;
+            }
         }
     }
     return result;
diff --git a/libc/bionic/pthread-rwlocks.c b/libc/bionic/pthread-rwlocks.c
new file mode 100644
index 0000000..ca3e95c
--- /dev/null
+++ b/libc/bionic/pthread-rwlocks.c
@@ -0,0 +1,347 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *  * Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *  * Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include "pthread_internal.h"
+#include <errno.h>
+
+/* Technical note:
+ *
+ * Possible states of a read/write lock:
+ *
+ *  - no readers and no writer (unlocked)
+ *  - one or more readers sharing the lock at the same time (read-locked)
+ *  - one writer holding the lock (write-lock)
+ *
+ * Additionally:
+ *  - trying to get the write-lock while there are any readers blocks
+ *  - trying to get the read-lock while there is a writer blocks
+ *  - a single thread can acquire the lock multiple times in the same mode
+ *
+ *  - Posix states that behaviour is undefined it a thread tries to acquire
+ *    the lock in two distinct modes (e.g. write after read, or read after write).
+ *
+ *  - This implementation tries to avoid writer starvation by making the readers
+ *    block as soon as there is a waiting writer on the lock. However, it cannot
+ *    completely eliminate it: each time the lock is unlocked, all waiting threads
+ *    are woken and battle for it, which one gets it depends on the kernel scheduler
+ *    and is semi-random.
+ *
+ */
+
+#define  __likely(cond)    __builtin_expect(!!(cond), 1)
+#define  __unlikely(cond)  __builtin_expect(!!(cond), 0)
+
+#define  RWLOCKATTR_DEFAULT     0
+#define  RWLOCKATTR_SHARED_MASK 0x0010
+
+extern pthread_internal_t* __get_thread(void);
+
+/* Return a global kernel ID for the current thread */
+static int __get_thread_id(void)
+{
+    return __get_thread()->kernel_id;
+}
+
+int pthread_rwlockattr_init(pthread_rwlockattr_t *attr)
+{
+    if (!attr)
+        return EINVAL;
+
+    *attr = PTHREAD_PROCESS_PRIVATE;
+    return 0;
+}
+
+int pthread_rwlockattr_destroy(pthread_rwlockattr_t *attr)
+{
+    if (!attr)
+        return EINVAL;
+
+    *attr = -1;
+    return 0;
+}
+
+int pthread_rwlockattr_setpshared(pthread_rwlockattr_t *attr, int  pshared)
+{
+    if (!attr)
+        return EINVAL;
+
+    switch (pshared) {
+    case PTHREAD_PROCESS_PRIVATE:
+    case PTHREAD_PROCESS_SHARED:
+        *attr = pshared;
+        return 0;
+    default:
+        return EINVAL;
+    }
+}
+
+int pthread_rwlockattr_getpshared(pthread_rwlockattr_t *attr, int *pshared)
+{
+    if (!attr || !pshared)
+        return EINVAL;
+
+    *pshared = *attr;
+    return 0;
+}
+
+int pthread_rwlock_init(pthread_rwlock_t *rwlock, const pthread_rwlockattr_t *attr)
+{
+    pthread_mutexattr_t*  lock_attr = NULL;
+    pthread_condattr_t*   cond_attr = NULL;
+    pthread_mutexattr_t   lock_attr0;
+    pthread_condattr_t    cond_attr0;
+    int                   ret;
+
+    if (rwlock == NULL)
+        return EINVAL;
+
+    if (attr && *attr == PTHREAD_PROCESS_SHARED) {
+        lock_attr = &lock_attr0;
+        pthread_mutexattr_init(lock_attr);
+        pthread_mutexattr_setpshared(lock_attr, PTHREAD_PROCESS_SHARED);
+
+        cond_attr = &cond_attr0;
+        pthread_condattr_init(cond_attr);
+        pthread_condattr_setpshared(cond_attr, PTHREAD_PROCESS_SHARED);
+    }
+
+    ret = pthread_mutex_init(&rwlock->lock, lock_attr);
+    if (ret != 0)
+        return ret;
+
+    ret = pthread_cond_init(&rwlock->cond, cond_attr);
+    if (ret != 0) {
+        pthread_mutex_destroy(&rwlock->lock);
+        return ret;
+    }
+
+    rwlock->numLocks = 0;
+    rwlock->pendingReaders = 0;
+    rwlock->pendingWriters = 0;
+    rwlock->writerThreadId = 0;
+
+    return 0;
+}
+
+int pthread_rwlock_destroy(pthread_rwlock_t *rwlock)
+{
+    int  ret;
+
+    if (rwlock == NULL)
+        return EINVAL;
+
+    if (rwlock->numLocks > 0)
+        return EBUSY;
+
+    pthread_cond_destroy(&rwlock->cond);
+    pthread_mutex_destroy(&rwlock->lock);
+    return 0;
+}
+
+/* Returns TRUE iff we can acquire a read lock. */
+static __inline__ int read_precondition(pthread_rwlock_t *rwlock, int  thread_id)
+{
+    /* We can't have the lock if any writer is waiting for it (writer bias).
+     * This tries to avoid starvation when there are multiple readers racing.
+     */
+    if (rwlock->pendingWriters > 0)
+        return 0;
+
+    /* We can have the lock if there is no writer, or if we write-own it */
+    /* The second test avoids a self-dead lock in case of buggy code. */
+    if (rwlock->writerThreadId == 0 || rwlock->writerThreadId == thread_id)
+        return 1;
+
+    /* Otherwise, we can't have it */
+    return 0;
+}
+
+/* returns TRUE iff we can acquire a write lock. */
+static __inline__ int write_precondition(pthread_rwlock_t *rwlock, int  thread_id)
+{
+    /* We can get the lock if nobody has it */
+    if (rwlock->numLocks == 0)
+        return 1;
+
+    /* Or if we already own it */
+    if (rwlock->writerThreadId == thread_id)
+        return 1;
+
+    /* Otherwise, not */
+    return 0;
+}
+
+/* This function is used to waken any waiting thread contending
+ * for the lock. One of them should be able to grab it after
+ * that.
+ */
+static void _pthread_rwlock_pulse(pthread_rwlock_t *rwlock)
+{
+    if (rwlock->pendingReaders > 0 || rwlock->pendingWriters > 0)
+        pthread_cond_broadcast(&rwlock->cond);
+}
+
+
+int pthread_rwlock_rdlock(pthread_rwlock_t *rwlock)
+{
+    return pthread_rwlock_timedrdlock(rwlock, NULL);
+}
+
+int pthread_rwlock_tryrdlock(pthread_rwlock_t *rwlock)
+{
+    int ret = 0;
+
+    if (rwlock == NULL)
+        return EINVAL;
+
+    pthread_mutex_lock(&rwlock->lock);
+    if (__unlikely(!read_precondition(rwlock, __get_thread_id())))
+        ret = EBUSY;
+    else
+        rwlock->numLocks ++;
+    pthread_mutex_unlock(&rwlock->lock);
+
+    return ret;
+}
+
+int pthread_rwlock_timedrdlock(pthread_rwlock_t *rwlock, const struct timespec *abs_timeout)
+{
+    int thread_id, ret = 0;
+
+    if (rwlock == NULL)
+        return EINVAL;
+
+    pthread_mutex_lock(&rwlock->lock);
+    thread_id = __get_thread_id();
+    if (__unlikely(!read_precondition(rwlock, thread_id))) {
+        rwlock->pendingReaders += 1;
+        do {
+            ret = pthread_cond_timedwait(&rwlock->cond, &rwlock->lock, abs_timeout);
+        } while (ret == 0 && !read_precondition(rwlock, thread_id));
+        rwlock->pendingReaders -= 1;
+        if (ret != 0)
+            goto EXIT;
+    }
+    rwlock->numLocks ++;
+EXIT:
+    pthread_mutex_unlock(&rwlock->lock);
+    return ret;
+}
+
+
+int pthread_rwlock_wrlock(pthread_rwlock_t *rwlock)
+{
+    return pthread_rwlock_timedwrlock(rwlock, NULL);
+}
+
+int pthread_rwlock_trywrlock(pthread_rwlock_t *rwlock)
+{
+    int thread_id, ret = 0;
+
+    if (rwlock == NULL)
+        return EINVAL;
+
+    pthread_mutex_lock(&rwlock->lock);
+    thread_id = __get_thread_id();
+    if (__unlikely(!write_precondition(rwlock, thread_id))) {
+        ret = EBUSY;
+    } else {
+        rwlock->numLocks ++;
+        rwlock->writerThreadId = thread_id;
+    }
+    pthread_mutex_unlock(&rwlock->lock);
+    return ret;
+}
+
+int pthread_rwlock_timedwrlock(pthread_rwlock_t *rwlock, const struct timespec *abs_timeout)
+{
+    int thread_id, ret = 0;
+
+    if (rwlock == NULL)
+        return EINVAL;
+
+    pthread_mutex_lock(&rwlock->lock);
+    thread_id = __get_thread_id();
+    if (__unlikely(!write_precondition(rwlock, thread_id))) {
+        /* If we can't read yet, wait until the rwlock is unlocked
+         * and try again. Increment pendingReaders to get the
+         * cond broadcast when that happens.
+         */
+        rwlock->pendingWriters += 1;
+        do {
+            ret = pthread_cond_timedwait(&rwlock->cond, &rwlock->lock, abs_timeout);
+        } while (ret == 0 && !write_precondition(rwlock, thread_id));
+        rwlock->pendingWriters -= 1;
+        if (ret != 0)
+            goto EXIT;
+    }
+    rwlock->numLocks ++;
+    rwlock->writerThreadId = thread_id;
+EXIT:
+    pthread_mutex_unlock(&rwlock->lock);
+    return ret;
+}
+
+
+int pthread_rwlock_unlock(pthread_rwlock_t *rwlock)
+{
+    int  ret = 0;
+
+    if (rwlock == NULL)
+        return EINVAL;
+
+    pthread_mutex_lock(&rwlock->lock);
+
+    /* The lock must be held */
+    if (rwlock->numLocks == 0) {
+        ret = EPERM;
+        goto EXIT;
+    }
+
+    /* If it has only readers, writerThreadId is 0 */
+    if (rwlock->writerThreadId == 0) {
+        if (--rwlock->numLocks == 0)
+            _pthread_rwlock_pulse(rwlock);
+    }
+    /* Otherwise, it has only a single writer, which
+     * must be ourselves.
+     */
+    else {
+        if (rwlock->writerThreadId != __get_thread_id()) {
+            ret = EPERM;
+            goto EXIT;
+        }
+        if (--rwlock->numLocks == 0) {
+            rwlock->writerThreadId = 0;
+            _pthread_rwlock_pulse(rwlock);
+        }
+    }
+EXIT:
+    pthread_mutex_unlock(&rwlock->lock);
+    return ret;
+}
diff --git a/libc/bionic/pthread.c b/libc/bionic/pthread.c
index e17e366..b28cd9f 100644
--- a/libc/bionic/pthread.c
+++ b/libc/bionic/pthread.c
@@ -43,16 +43,28 @@
 #include <memory.h>
 #include <assert.h>
 #include <malloc.h>
-#include <linux/futex.h>
+#include <bionic_futex.h>
+#include <bionic_atomic_inline.h>
 #include <sys/prctl.h>
 #include <sys/stat.h>
 #include <fcntl.h>
+#include <stdio.h>
 
 extern int  __pthread_clone(int (*fn)(void*), void *child_stack, int flags, void *arg);
 extern void _exit_with_stack_teardown(void * stackBase, int stackSize, int retCode);
 extern void _exit_thread(int  retCode);
 extern int  __set_errno(int);
 
+int  __futex_wake_ex(volatile void *ftx, int pshared, int val)
+{
+    return __futex_syscall3(ftx, pshared ? FUTEX_WAKE : FUTEX_WAKE_PRIVATE, val);
+}
+
+int  __futex_wait_ex(volatile void *ftx, int pshared, int val, const struct timespec *timeout)
+{
+    return __futex_syscall4(ftx, pshared ? FUTEX_WAIT : FUTEX_WAIT_PRIVATE, val, timeout);
+}
+
 #define  __likely(cond)    __builtin_expect(!!(cond), 1)
 #define  __unlikely(cond)  __builtin_expect(!!(cond), 0)
 
@@ -715,24 +727,6 @@
 }
 
 
-int __futex_wait(volatile void *ftx, int val, const struct timespec *timeout);
-int __futex_wake(volatile void *ftx, int count);
-
-int __futex_syscall3(volatile void *ftx, int op, int val);
-int __futex_syscall4(volatile void *ftx, int op, int val, const struct timespec *timeout);
-
-#ifndef FUTEX_PRIVATE_FLAG
-#define FUTEX_PRIVATE_FLAG  128
-#endif
-
-#ifndef FUTEX_WAIT_PRIVATE
-#define FUTEX_WAIT_PRIVATE  (FUTEX_WAIT|FUTEX_PRIVATE_FLAG)
-#endif
-
-#ifndef FUTEX_WAKE_PRIVATE
-#define FUTEX_WAKE_PRIVATE  (FUTEX_WAKE|FUTEX_PRIVATE_FLAG)
-#endif
-
 // mutex lock states
 //
 // 0: unlocked
@@ -886,8 +880,13 @@
 
 int pthread_mutex_destroy(pthread_mutex_t *mutex)
 {
-    if (__unlikely(mutex == NULL))
-        return EINVAL;
+    int ret;
+
+    /* use trylock to ensure that the mutex value is
+     * valid and is not already locked. */
+    ret = pthread_mutex_trylock(mutex);
+    if (ret != 0)
+        return ret;
 
     mutex->value = 0xdead10cc;
     return 0;
@@ -934,11 +933,10 @@
          * that the mutex is in state 2 when we go to sleep on it, which
          * guarantees a wake-up call.
          */
-        int  wait_op = shared ? FUTEX_WAIT : FUTEX_WAIT_PRIVATE;
-
         while (__atomic_swap(shared|2, &mutex->value ) != (shared|0))
-            __futex_syscall4(&mutex->value, wait_op, shared|2, 0);
+            __futex_wait_ex(&mutex->value, shared, shared|2, 0);
     }
+    ANDROID_MEMBAR_FULL();
 }
 
 /*
@@ -948,6 +946,8 @@
 static __inline__ void
 _normal_unlock(pthread_mutex_t*  mutex)
 {
+    ANDROID_MEMBAR_FULL();
+
     /* We need to preserve the shared flag during operations */
     int  shared = mutex->value & MUTEX_SHARED_MASK;
 
@@ -957,7 +957,6 @@
      * if it wasn't 1 we have to do some additional work.
      */
     if (__atomic_dec(&mutex->value) != (shared|1)) {
-        int  wake_op = shared ? FUTEX_WAKE : FUTEX_WAKE_PRIVATE;
         /*
          * Start by releasing the lock.  The decrement changed it from
          * "contended lock" to "uncontended lock", which means we still
@@ -995,7 +994,7 @@
          * Either way we have correct behavior and nobody is orphaned on
          * the wait queue.
          */
-        __futex_syscall3(&mutex->value, wake_op, 1);
+        __futex_wake_ex(&mutex->value, shared, 1);
     }
 }
 
@@ -1015,7 +1014,7 @@
 
 int pthread_mutex_lock(pthread_mutex_t *mutex)
 {
-    int mtype, tid, new_lock_type, shared, wait_op;
+    int mtype, tid, new_lock_type, shared;
 
     if (__unlikely(mutex == NULL))
         return EINVAL;
@@ -1060,8 +1059,7 @@
     new_lock_type = 1;
 
     /* compute futex wait opcode and restore shared flag in mtype */
-    wait_op = shared ? FUTEX_WAIT : FUTEX_WAIT_PRIVATE;
-    mtype  |= shared;
+    mtype |= shared;
 
     for (;;) {
         int  oldv;
@@ -1087,7 +1085,7 @@
          */
         new_lock_type = 2;
 
-        __futex_syscall4(&mutex->value, wait_op, oldv, NULL);
+        __futex_wait_ex(&mutex->value, shared, oldv, NULL);
     }
     return 0;
 }
@@ -1127,8 +1125,7 @@
 
     /* Wake one waiting thread, if any */
     if ((oldv & 3) == 2) {
-        int wake_op = shared ? FUTEX_WAKE : FUTEX_WAKE_PRIVATE;
-        __futex_syscall3(&mutex->value, wake_op, 1);
+        __futex_wake_ex(&mutex->value, shared, 1);
     }
     return 0;
 }
@@ -1147,8 +1144,10 @@
     /* Handle common case first */
     if ( __likely(mtype == MUTEX_TYPE_NORMAL) )
     {
-        if (__atomic_cmpxchg(shared|0, shared|1, &mutex->value) == 0)
+        if (__atomic_cmpxchg(shared|0, shared|1, &mutex->value) == 0) {
+            ANDROID_MEMBAR_FULL();
             return 0;
+        }
 
         return EBUSY;
     }
@@ -1228,7 +1227,7 @@
     clockid_t        clock = CLOCK_MONOTONIC;
     struct timespec  abstime;
     struct timespec  ts;
-    int              mtype, tid, oldv, new_lock_type, shared, wait_op;
+    int              mtype, tid, oldv, new_lock_type, shared;
 
     /* compute absolute expiration time */
     __timespec_to_relative_msec(&abstime, msecs, clock);
@@ -1242,19 +1241,20 @@
     /* Handle common case first */
     if ( __likely(mtype == MUTEX_TYPE_NORMAL) )
     {
-        int  wait_op = shared ? FUTEX_WAIT : FUTEX_WAIT_PRIVATE;
-
-        /* fast path for unconteded lock */
-        if (__atomic_cmpxchg(shared|0, shared|1, &mutex->value) == 0)
+        /* fast path for uncontended lock */
+        if (__atomic_cmpxchg(shared|0, shared|1, &mutex->value) == 0) {
+            ANDROID_MEMBAR_FULL();
             return 0;
+        }
 
         /* loop while needed */
         while (__atomic_swap(shared|2, &mutex->value) != (shared|0)) {
             if (__timespec_to_absolute(&ts, &abstime, clock) < 0)
                 return EBUSY;
 
-            __futex_syscall4(&mutex->value, wait_op, shared|2, &ts);
+            __futex_wait_ex(&mutex->value, shared, shared|2, &ts);
         }
+        ANDROID_MEMBAR_FULL();
         return 0;
     }
 
@@ -1285,7 +1285,6 @@
     new_lock_type = 1;
 
     /* Compute wait op and restore sharing bit in mtype */
-    wait_op = shared ? FUTEX_WAIT : FUTEX_WAIT_PRIVATE;
     mtype  |= shared;
 
     for (;;) {
@@ -1316,7 +1315,7 @@
         if (__timespec_to_absolute(&ts, &abstime, clock) < 0)
             return EBUSY;
 
-        __futex_syscall4(&mutex->value, wait_op, oldv, &ts);
+        __futex_wait_ex(&mutex->value, shared, oldv, &ts);
     }
     return 0;
 }
@@ -1409,7 +1408,6 @@
 __pthread_cond_pulse(pthread_cond_t *cond, int  counter)
 {
     long flags;
-    int  wake_op;
 
     if (__unlikely(cond == NULL))
         return EINVAL;
@@ -1423,8 +1421,7 @@
             break;
     }
 
-    wake_op = COND_IS_SHARED(cond) ? FUTEX_WAKE : FUTEX_WAKE_PRIVATE;
-    __futex_syscall3(&cond->value, wake_op, counter);
+    __futex_wake_ex(&cond->value, COND_IS_SHARED(cond), counter);
     return 0;
 }
 
@@ -1449,10 +1446,9 @@
 {
     int  status;
     int  oldvalue = cond->value;
-    int  wait_op  = COND_IS_SHARED(cond) ? FUTEX_WAIT : FUTEX_WAIT_PRIVATE;
 
     pthread_mutex_unlock(mutex);
-    status = __futex_syscall4(&cond->value, wait_op, oldvalue, reltime);
+    status = __futex_wait_ex(&cond->value, COND_IS_SHARED(cond), oldvalue, reltime);
     pthread_mutex_lock(mutex);
 
     if (status == (-ETIMEDOUT)) return ETIMEDOUT;
@@ -1870,15 +1866,15 @@
  */
 int  pthread_once( pthread_once_t*  once_control,  void (*init_routine)(void) )
 {
-    static pthread_mutex_t   once_lock = PTHREAD_MUTEX_INITIALIZER;
+    static pthread_mutex_t   once_lock = PTHREAD_RECURSIVE_MUTEX_INITIALIZER;
 
     if (*once_control == PTHREAD_ONCE_INIT) {
-        _normal_lock( &once_lock );
+        pthread_mutex_lock( &once_lock );
         if (*once_control == PTHREAD_ONCE_INIT) {
             (*init_routine)();
             *once_control = ~PTHREAD_ONCE_INIT;
         }
-        _normal_unlock( &once_lock );
+        pthread_mutex_unlock( &once_lock );
     }
     return 0;
 }
diff --git a/libc/bionic/semaphore.c b/libc/bionic/semaphore.c
index 84b9314..96819ae 100644
--- a/libc/bionic/semaphore.c
+++ b/libc/bionic/semaphore.c
@@ -30,6 +30,62 @@
 #include <sys/time.h>
 #include <sys/atomics.h>
 #include <time.h>
+#include <bionic_atomic_inline.h>
+#include <bionic_futex.h>
+#include <limits.h>
+
+/* In this implementation, a semaphore contains a
+ * 31-bit signed value and a 1-bit 'shared' flag
+ * (for process-sharing purpose).
+ *
+ * We use the value -1 to indicate contention on the
+ * semaphore, 0 or more to indicate uncontended state,
+ * any value lower than -2 is invalid at runtime.
+ *
+ * State diagram:
+ *
+ * post(1)  ==> 2
+ * post(0)  ==> 1
+ * post(-1) ==> 1, then wake all waiters
+ *
+ * wait(2)  ==> 1
+ * wait(1)  ==> 0
+ * wait(0)  ==> -1 then wait for a wake up + loop
+ * wait(-1) ==> -1 then wait for a wake up + loop
+ *
+ */
+
+/* Use the upper 31-bits for the counter, and the lower one
+ * for the shared flag.
+ */
+#define SEMCOUNT_SHARED_MASK      0x00000001
+#define SEMCOUNT_VALUE_MASK       0xfffffffe
+#define SEMCOUNT_VALUE_SHIFT      1
+
+/* Maximum unsigned value that can be stored in the semaphore.
+ * One bit is used for the shared flag, another one for the
+ * sign bit, leaving us with only 30 bits.
+ */
+#define SEM_MAX_VALUE             0x3fffffff
+
+/* convert a value into the corresponding sem->count bit pattern */
+#define SEMCOUNT_FROM_VALUE(val)    (((val) << SEMCOUNT_VALUE_SHIFT) & SEMCOUNT_VALUE_MASK)
+
+/* convert a sem->count bit pattern into the corresponding signed value */
+#define SEMCOUNT_TO_VALUE(sval)  ((int)(sval) >> SEMCOUNT_VALUE_SHIFT)
+
+/* the value +1 as a sem->count bit-pattern. */
+#define SEMCOUNT_ONE              SEMCOUNT_FROM_VALUE(1)
+
+/* the value -1 as a sem->count bit-pattern. */
+#define SEMCOUNT_MINUS_ONE        SEMCOUNT_FROM_VALUE(-1)
+
+#define SEMCOUNT_DECREMENT(sval)    (((sval) - (1U << SEMCOUNT_VALUE_SHIFT)) & SEMCOUNT_VALUE_MASK)
+#define SEMCOUNT_INCREMENT(sval)    (((sval) + (1U << SEMCOUNT_VALUE_SHIFT)) & SEMCOUNT_VALUE_MASK)
+
+/* return the shared bitflag from a semaphore */
+#define SEM_GET_SHARED(sem)       ((sem)->count & SEMCOUNT_SHARED_MASK)
+
 
 int sem_init(sem_t *sem, int pshared, unsigned int value)
 {
@@ -38,26 +94,34 @@
         return -1;
     }
 
-    if (pshared != 0) {
-        errno = ENOSYS;
+    /* ensure that 'value' can be stored in the semaphore */
+    if (value > SEM_MAX_VALUE) {
+        errno = EINVAL;
         return -1;
     }
 
-    sem->count = value;
+    sem->count = SEMCOUNT_FROM_VALUE(value);
+    if (pshared != 0)
+        sem->count |= SEMCOUNT_SHARED_MASK;
+
     return 0;
 }
 
 
 int sem_destroy(sem_t *sem)
 {
+    int count;
+
     if (sem == NULL) {
         errno = EINVAL;
         return -1;
     }
-    if (sem->count == 0) {
+    count = SEMCOUNT_TO_VALUE(sem->count);
+    if (count < 0) {
         errno = EBUSY;
         return -1;
     }
+    sem->count = 0;
     return 0;
 }
 
@@ -90,38 +154,120 @@
 }
 
 
+/* Decrement a semaphore's value atomically,
+ * and return the old one. As a special case,
+ * this returns immediately if the value is
+ * negative (i.e. -1)
+ */
 static int
-__atomic_dec_if_positive( volatile unsigned int*  pvalue )
+__sem_dec(volatile unsigned int *pvalue)
 {
-    unsigned int  old;
+    unsigned int shared = (*pvalue & SEMCOUNT_SHARED_MASK);
+    unsigned int old, new;
+    int          ret;
 
     do {
-        old = *pvalue;
-    }
-    while ( old != 0 && __atomic_cmpxchg( (int)old, (int)old-1, (volatile int*)pvalue ) != 0 );
+        old = (*pvalue & SEMCOUNT_VALUE_MASK);
+        ret = SEMCOUNT_TO_VALUE(old);
+        if (ret < 0)
+            break;
 
-    return old;
+        new = SEMCOUNT_DECREMENT(old);
+    }
+    while (__atomic_cmpxchg((int)(old|shared),
+                            (int)(new|shared),
+                            (volatile int *)pvalue) != 0);
+    return ret;
 }
 
+/* Same as __sem_dec, but will not touch anything if the
+ * value is already negative *or* 0. Returns the old value.
+ */
+static int
+__sem_trydec(volatile unsigned int *pvalue)
+{
+    unsigned int shared = (*pvalue & SEMCOUNT_SHARED_MASK);
+    unsigned int old, new;
+    int          ret;
+
+    do {
+        old = (*pvalue & SEMCOUNT_VALUE_MASK);
+        ret = SEMCOUNT_TO_VALUE(old);
+        if (ret <= 0)
+            break;
+
+        new = SEMCOUNT_DECREMENT(old);
+    }
+    while (__atomic_cmpxchg((int)(old|shared),
+                            (int)(new|shared),
+                            (volatile int *)pvalue) != 0);
+
+    return ret;
+}
+
+
+/* "Increment" the value of a semaphore atomically and
+ * return its old value. Note that this implements
+ * the special case of "incrementing" any negative
+ * value to +1 directly.
+ *
+ * NOTE: The value will _not_ wrap above SEM_VALUE_MAX
+ */
+static int
+__sem_inc(volatile unsigned int *pvalue)
+{
+    unsigned int  shared = (*pvalue & SEMCOUNT_SHARED_MASK);
+    unsigned int  old, new;
+    int           ret;
+
+    do {
+        old = (*pvalue & SEMCOUNT_VALUE_MASK);
+        ret = SEMCOUNT_TO_VALUE(old);
+
+        /* Can't go higher than SEM_MAX_VALUE */
+        if (ret == SEM_MAX_VALUE)
+            break;
+
+        /* If the counter is negative, go directly to +1,
+         * otherwise just increment */
+        if (ret < 0)
+            new = SEMCOUNT_ONE;
+        else
+            new = SEMCOUNT_INCREMENT(old);
+    }
+    while ( __atomic_cmpxchg((int)(old|shared),
+                             (int)(new|shared),
+                             (volatile int*)pvalue) != 0);
+
+    return ret;
+}
+
+/* lock a semaphore */
 int sem_wait(sem_t *sem)
 {
+    unsigned shared;
+
     if (sem == NULL) {
         errno = EINVAL;
         return -1;
     }
 
+    shared = SEM_GET_SHARED(sem);
+
     for (;;) {
-        if (__atomic_dec_if_positive(&sem->count))
+        if (__sem_dec(&sem->count) > 0)
             break;
 
-        __futex_wait(&sem->count, 0, 0);
+        __futex_wait_ex(&sem->count, shared, shared|SEMCOUNT_MINUS_ONE, NULL);
     }
+    ANDROID_MEMBAR_FULL();
     return 0;
 }
 
 int sem_timedwait(sem_t *sem, const struct timespec *abs_timeout)
 {
     int  ret;
+    unsigned int shared;
 
     if (sem == NULL) {
         errno = EINVAL;
@@ -129,11 +275,15 @@
     }
 
     /* POSIX says we need to try to decrement the semaphore
-     * before checking the timeout value */
-    if (__atomic_dec_if_positive(&sem->count))
+     * before checking the timeout value. Note that if the
+     * value is currently 0, __sem_trydec() does nothing.
+     */
+    if (__sem_trydec(&sem->count) > 0) {
+        ANDROID_MEMBAR_FULL();
         return 0;
+    }
 
-    /* check it as per Posix */
+    /* Check it as per Posix */
     if (abs_timeout == NULL    ||
         abs_timeout->tv_sec < 0 ||
         abs_timeout->tv_nsec < 0 ||
@@ -143,6 +293,8 @@
         return -1;
     }
 
+    shared = SEM_GET_SHARED(sem);
+
     for (;;) {
         struct timespec ts;
         int             ret;
@@ -161,27 +313,47 @@
             return -1;
         }
 
-        ret = __futex_wait(&sem->count, 0, &ts);
+        /* Try to grab the semaphore. If the value was 0, this
+         * will also change it to -1 */
+        if (__sem_dec(&sem->count) > 0) {
+            ANDROID_MEMBAR_FULL();
+            break;
+        }
+
+        /* Contention detected. wait for a wakeup event */
+        ret = __futex_wait_ex(&sem->count, shared, shared|SEMCOUNT_MINUS_ONE, &ts);
 
         /* return in case of timeout or interrupt */
         if (ret == -ETIMEDOUT || ret == -EINTR) {
             errno = -ret;
             return -1;
         }
-
-        if (__atomic_dec_if_positive(&sem->count))
-            break;
     }
     return 0;
 }
 
+/* Unlock a semaphore */
 int sem_post(sem_t *sem)
 {
+    unsigned int shared;
+    int          old;
+
     if (sem == NULL)
         return EINVAL;
 
-    if (__atomic_inc((volatile int*)&sem->count) >= 0)
-        __futex_wake(&sem->count, 1);
+    shared = SEM_GET_SHARED(sem);
+
+    ANDROID_MEMBAR_FULL();
+    old = __sem_inc(&sem->count);
+    if (old < 0) {
+        /* contention on the semaphore, wake up all waiters */
+        __futex_wake_ex(&sem->count, shared, INT_MAX);
+    }
+    else if (old == SEM_MAX_VALUE) {
+        /* overflow detected */
+        errno = EOVERFLOW;
+        return -1;
+    }
 
     return 0;
 }
@@ -193,7 +365,8 @@
         return -1;
     }
 
-    if (__atomic_dec_if_positive(&sem->count) > 0) {
+    if (__sem_trydec(&sem->count) > 0) {
+        ANDROID_MEMBAR_FULL();
         return 0;
     } else {
         errno = EAGAIN;
@@ -201,13 +374,29 @@
     }
 }
 
+/* Note that Posix requires that sem_getvalue() returns, in
+ * case of contention, the negative of the number of waiting
+ * threads.
+ *
+ * However, code that depends on this negative value to be
+ * meaningful is most probably racy. The GLibc sem_getvalue()
+ * only returns the semaphore value, which is 0, in case of
+ * contention, so we will mimick this behaviour here instead
+ * for better compatibility.
+ */
 int  sem_getvalue(sem_t *sem, int *sval)
 {
+    int  val;
+
     if (sem == NULL || sval == NULL) {
         errno = EINVAL;
         return -1;
     }
 
-    *sval = sem->count;
+    val = SEMCOUNT_TO_VALUE(sem->count);
+    if (val < 0)
+        val = 0;
+
+    *sval = val;
     return 0;
 }
diff --git a/libc/bionic/system_properties.c b/libc/bionic/system_properties.c
index 5e3b9e7..767baa3 100644
--- a/libc/bionic/system_properties.c
+++ b/libc/bionic/system_properties.c
@@ -126,7 +126,7 @@
     for(;;) {
         serial = pi->serial;
         while(SERIAL_DIRTY(serial)) {
-            __futex_wait(&pi->serial, serial, 0);
+            __futex_wait((volatile void *)&pi->serial, serial, 0);
             serial = pi->serial;
         }
         len = SERIAL_VALUE_LEN(serial);
@@ -164,7 +164,7 @@
     } else {
         n = pi->serial;
         do {
-            __futex_wait(&pi->serial, n, 0);
+            __futex_wait((volatile void *)&pi->serial, n, 0);
         } while(n == pi->serial);
     }
     return 0;
diff --git a/libc/docs/CHANGES.TXT b/libc/docs/CHANGES.TXT
index b0725ed..0eab879 100644
--- a/libc/docs/CHANGES.TXT
+++ b/libc/docs/CHANGES.TXT
@@ -3,11 +3,89 @@
 
 Differences between current and Android 2.2:
 
+- <pthread.h>: Add reader/writer locks implementation. Add sanity
+  checking to pthread_mutex_destroy() (e.g. a locked mutex will return
+  EBUSY).
+
+- <semaphore.h>: Use private futexes for semaphore implementation,
+  unless your set 'pshared' to non-0 when calling sem_init().
+
+  Also fixed a bug in sem_post() to make it wake up all waiting
+  threads, instead of one. As a consequence, the maximum semaphore
+  value is now reduced to 0x3fffffff.
+
+- <math.h>: Added sincos(), sincosf() and sincosl() (GLibc compatibility).
+
+- <sys/sysinfo.h>: Added missing sysinfo() system call implementation
+  (the function was already declared in the header though).
+
+- sysconf() didn't work for some arguments due to a small bug in the
+  /proc line parser.
+
+- <termio.h>: added missing header (just includes <termios.h>)
+
+- <unistd.h>: add missing declaration for truncate(). The implementation
+  was already here since Android 1.5.
+
+  modify implementation of alarm() to return 0 in case of error (i.e.
+  if a value larger than 0x7fffffff seconds is passed to it). This
+  makes the implementation compliant with the GLibc behaviour.
+
+- <wchar.h>: small fixes to really support wchar_t in Bionic (not there yet).
+
+     the size of wchar_t is still 32-bit (decided by the compiler)
+
+     WCHAR_MIN: changed from 0 to INT_MIN
+     WCHAR_MAX: changed from 255 to INT_MAX
+
+     wcpcpy(), wcpncpy(), wcscat(), wcschr(), wcscmp(),
+     wcscpy(), wcscspn(), wcsdup(), wcslcat(), wcslcpy(),
+     wcslen(), wcsncat(), wcsncmp(), wcsncpy(), wcsnlen(),
+     wcspbrk(), wcsrchr(), wcsrchr(), wcsspn(), wcsstr(),
+     wcstok(), wcswidth(), wmemchr(), wmemcmp(), wmemcpy(),
+     wmemmove(), wmemset(): Added proper implementations.
+
+     wcscasecmp(), wcsncasecmp(): Added implementation limited
+     to ASCII codes for lower/upper.
+
+     wcscoll(): added dummy implementation that calls wcscmp()
+     wcsxfrm(): added dummy implementation that calls wcsncpy()
+
+  NOTE: Technically, this breaks the ABI, but we never claimed to support
+        wchar_t anyway. The wchar_t support is still *NOT* official at this
+        point. We need better multi-byte support code, and wprintf/wscanf
+        stuff too.
+
+- <inttypes.h>: add missing declarations for strntoimax abd strntoumax.
+
+- <stdlib.h>: add missing declarations for drand48() and erand48().
+
+- clearerr(): fix broken implementation.
+
+- Feature test macros like _POSIX_C_SOURCE / _XOPEN_SOURCE / _C99_SOURCE
+  are now handled correctly by our C library headers (see <sys/cdefs.h>)
+
+- <sys/select.h>: add missing declaration for pselect()
+
+- <sys/vfs.h>: fixed implementation of fstatfs() (also fixes fpathconf()
+  which uses it).
+
 - Added an implementation of pthread_atfork()
 
+- <dlfcn.h>: fixed dlopen() implementation to support dlopen(NULL, ...).
+  This allows one to look at the dynamic symbols exported by an executable.
+
+- <private/bionic_tls.h>: use kernel helper functions for static versions
+  of the C library. This is necessary because we don't know where the corresponding
+  machine code is going to run, and the optimization for __get_tls() might
+  not match the features of the target device where we run a static executable
+  linked to the C library. This fixes one of the bug that explains why gdbserver
+  didn't work well with threads.
 
 -------------------------------------------------------------------------------
-Differences between Android 2.2 and Android 2.1:
+Differences between Android 2.2. and Android 2.1:
+
+- Support FP register save/load in setjmp()/longjmp() on ARMv7 builds.
 
 - Add support for SH-4 CPU architecture !
 
diff --git a/libc/include/fcntl.h b/libc/include/fcntl.h
index 59e7135..7219dd7 100644
--- a/libc/include/fcntl.h
+++ b/libc/include/fcntl.h
@@ -39,6 +39,10 @@
 #define O_ASYNC  FASYNC
 #endif
 
+#ifndef O_CLOEXEC
+#define O_CLOEXEC  02000000
+#endif
+
 extern int  open(const char*  path, int  mode, ...);
 extern int  openat(int fd, const char*  path, int  mode, ...);
 extern int  unlinkat(int dirfd, const char *pathname, int flags);
diff --git a/libc/include/getopt.h b/libc/include/getopt.h
index 6b4954b..56f1983 100644
--- a/libc/include/getopt.h
+++ b/libc/include/getopt.h
@@ -71,14 +71,19 @@
 #ifndef _GETOPT_DEFINED_
 #define _GETOPT_DEFINED_
 int	 getopt(int, char * const *, const char *);
-int	 getsubopt(char **, char * const *, char **);
+
 
 extern   char *optarg;                  /* getopt(3) external variables */
 extern   int opterr;
 extern   int optind;
 extern   int optopt;
 extern   int optreset;
+
+#if 0 /* MISSING FROM BIONIC */
+int       getsubopt(char **, char * const *, char **);
 extern   char *suboptarg;               /* getsubopt(3) external variable */
+#endif /* MISSING */
+
 #endif
 __END_DECLS
  
diff --git a/libc/include/inttypes.h b/libc/include/inttypes.h
index ca303cb..81d2315 100644
--- a/libc/include/inttypes.h
+++ b/libc/include/inttypes.h
@@ -253,6 +253,9 @@
 imaxdiv_t	imaxdiv(intmax_t, intmax_t);
 intmax_t	strtoimax(const char *, char **, int);
 uintmax_t	strtoumax(const char *, char **, int);
+
+intmax_t	strntoimax(const char *nptr, char **endptr, int base, size_t n);
+uintmax_t	strntoumax(const char *nptr, char **endptr, int base, size_t n);
 __END_DECLS
 
 #endif /* _INTTYPES_H_ */
diff --git a/libc/include/limits.h b/libc/include/limits.h
index c204e4d..1de8ea6 100644
--- a/libc/include/limits.h
+++ b/libc/include/limits.h
@@ -86,7 +86,7 @@
 #include <sys/limits.h>
 
 #if __POSIX_VISIBLE
-#include <arch/syslimits.h>
+#include <sys/syslimits.h>
 #endif
 
 #ifndef PAGESIZE
diff --git a/libc/include/pathconf.h b/libc/include/pathconf.h
index 4677f7b..94f9787 100644
--- a/libc/include/pathconf.h
+++ b/libc/include/pathconf.h
@@ -28,6 +28,10 @@
 #ifndef _PATHCONF_H_
 #define _PATHCONF_H_
 
+#include <sys/cdefs.h>
+
+__BEGIN_DECLS
+
 /* constants to be used for the 'name' paremeter of pathconf/fpathconf */
 
 #define  _PC_FILESIZEBITS       0x0000
@@ -54,5 +58,7 @@
 extern long fpathconf(int fildes, int name);
 extern long pathconf(const char *path, int name);
 
+__END_DECLS
+
 #endif /* _PATHCONF_H_ */
 
diff --git a/libc/include/pthread.h b/libc/include/pthread.h
index ecabdb1..a43e47c 100644
--- a/libc/include/pthread.h
+++ b/libc/include/pthread.h
@@ -219,6 +219,41 @@
  */
 int pthread_mutex_lock_timeout_np(pthread_mutex_t *mutex, unsigned msecs);
 
+/* read-write lock support */
+
+typedef int pthread_rwlockattr_t;
+
+typedef struct {
+    pthread_mutex_t  lock;
+    pthread_cond_t   cond;
+    int              numLocks;
+    int              writerThreadId;
+    int              pendingReaders;
+    int              pendingWriters;
+    void*            reserved[4];  /* for future extensibility */
+} pthread_rwlock_t;
+
+#define PTHREAD_RWLOCK_INITIALIZER  { PTHREAD_MUTEX_INITIALIZER, 0, NULL, 0, 0 }
+
+int pthread_rwlockattr_init(pthread_rwlockattr_t *attr);
+int pthread_rwlockattr_destroy(pthread_rwlockattr_t *attr);
+int pthread_rwlockattr_setpshared(pthread_rwlockattr_t *attr, int  pshared);
+int pthread_rwlockattr_getpshared(pthread_rwlockattr_t *attr, int *pshared);
+
+int pthread_rwlock_init(pthread_rwlock_t *rwlock, const pthread_rwlockattr_t *attr);
+int pthread_rwlock_destroy(pthread_rwlock_t *rwlock);
+
+int pthread_rwlock_rdlock(pthread_rwlock_t *rwlock);
+int pthread_rwlock_tryrdlock(pthread_rwlock_t *rwlock);
+int pthread_rwlock_timedrdlock(pthread_rwlock_t *rwlock, const struct timespec *abs_timeout);
+
+int pthread_rwlock_wrlock(pthread_rwlock_t *rwlock);
+int pthread_rwlock_trywrlock(pthread_rwlock_t *rwlock);
+int pthread_rwlock_timedwrlock(pthread_rwlock_t *rwlock, const struct timespec *abs_timeout);
+
+int pthread_rwlock_unlock(pthread_rwlock_t *rwlock);
+
+
 int pthread_key_create(pthread_key_t *key, void (*destructor_function)(void *));
 int pthread_key_delete (pthread_key_t);
 int pthread_setspecific(pthread_key_t key, const void *value);
@@ -276,4 +311,4 @@
 #define LONG_LONG_MAX __LONG_LONG_MAX__
 #define LONG_LONG_MIN (-__LONG_LONG_MAX__ - 1)
 
-#endif // _PTHREAD_H_
+#endif /* _PTHREAD_H_ */
diff --git a/libc/include/sched.h b/libc/include/sched.h
index 33b9ad6..e702470 100644
--- a/libc/include/sched.h
+++ b/libc/include/sched.h
@@ -69,7 +69,7 @@
 #define CLONE_CHILD_SETTID   0x01000000
 #define CLONE_STOPPED        0x02000000
 
-#ifdef __GNU_SOURCE
+#ifdef _GNU_SOURCE
 extern int clone(int (*fn)(void *), void *child_stack, int flags, void*  arg, ...);
 #endif
 
diff --git a/libc/include/signal.h b/libc/include/signal.h
index 7bc3145..4401164 100644
--- a/libc/include/signal.h
+++ b/libc/include/signal.h
@@ -120,6 +120,7 @@
 extern int raise(int);
 extern int kill(pid_t, int);
 extern int killpg(int pgrp, int sig);
+extern int sigaltstack(const stack_t *ss, stack_t *oss);
 
 
 __END_DECLS
diff --git a/libc/include/stdio.h b/libc/include/stdio.h
index f0e103e..c38ed5a 100644
--- a/libc/include/stdio.h
+++ b/libc/include/stdio.h
@@ -300,12 +300,14 @@
 #define L_cuserid	9	/* size for cuserid(); UT_NAMESIZE + 1 */
 
 __BEGIN_DECLS
+#if 0 /* MISSING FROM BIONIC */
 char	*ctermid(char *);
 char	*cuserid(char *);
+#endif /* MISSING */
 FILE	*fdopen(int, const char *);
 int	 fileno(FILE *);
 
-#if (__POSIX_VISIBLE >= 199209) || 1 /* ANDROID: Bionic does include this */
+#if (__POSIX_VISIBLE >= 199209)
 int	 pclose(FILE *);
 FILE	*popen(const char *, const char *);
 #endif
diff --git a/libc/include/stdlib.h b/libc/include/stdlib.h
index 41e8d26..97d8e46 100644
--- a/libc/include/stdlib.h
+++ b/libc/include/stdlib.h
@@ -50,7 +50,6 @@
 extern __noreturn void exit(int);
 extern __noreturn void abort(void);
 extern int atexit(void (*)(void));
-extern int on_exit(void (*)(int, void *), void *);
 
 extern char *getenv(const char *);
 extern int putenv(const char *);
@@ -107,6 +106,8 @@
 extern long nrand48(unsigned short *);
 extern long lrand48(void);
 extern unsigned short *seed48(unsigned short*);
+extern double erand48(unsigned short xsubi[3]);
+extern double drand48(void);
 extern void srand48(long);
 extern unsigned int arc4random(void);
 extern void arc4random_stir(void);
@@ -135,7 +136,7 @@
 extern int    ptsname_r(int, char*, size_t);
 extern int    getpt(void);
 
-static __inline__ int grantpt(int __fd)
+static __inline__ int grantpt(int __fd __attribute((unused)))
 {
   (void)__fd;
   return 0;     /* devpts does this all for us! */
@@ -162,6 +163,7 @@
 
 extern lldiv_t   lldiv(long long, long long);
 
+#if 1 /* MISSING FROM BIONIC - ENABLED FOR STLPort and libstdc++-v3 */
 /* make STLPort happy */
 extern int      mblen(const char *, size_t);
 extern size_t   mbstowcs(wchar_t *, const char *, size_t);
@@ -170,8 +172,14 @@
 /* Likewise, make libstdc++-v3 happy.  */
 extern int	wctomb(char *, wchar_t);
 extern size_t	wcstombs(char *, const wchar_t *, size_t);
+#endif /* MISSING */
+
 #define MB_CUR_MAX 1
 
+#if 0 /* MISSING FROM BIONIC */
+extern int on_exit(void (*)(int, void *), void *);
+#endif /* MISSING */
+
 __END_DECLS
 
 #endif /* _STDLIB_H_ */
diff --git a/libc/include/sys/cdefs.h b/libc/include/sys/cdefs.h
index fe7033d..849e2b8 100644
--- a/libc/include/sys/cdefs.h
+++ b/libc/include/sys/cdefs.h
@@ -37,12 +37,6 @@
 #ifndef	_SYS_CDEFS_H_
 #define	_SYS_CDEFS_H_
 
-
-/* our implementation of wchar_t is only 8-bit - die die non-portable code */
-#undef  __WCHAR_TYPE__
-#define __WCHAR_TYPE__  unsigned char
-
-
 /*
  * Macro to test if we're using a GNU C compiler of a specific vintage
  * or later, for e.g. features that appeared in a particular version
@@ -62,11 +56,6 @@
 #define	__GNUC_PREREQ__(x, y)	0
 #endif
 
-//XXX #include <machine/cdefs.h>
-
-/* BIONIC: simpler definition */
-#define __BSD_VISIBLE   1
-
 #include <sys/cdefs_elf.h>
 
 #if defined(__cplusplus)
@@ -371,6 +360,142 @@
 
 #define	__link_set_entry(set, idx)	(__link_set_begin(set)[idx])
 
+/*
+ * Some of the recend FreeBSD sources used in Bionic need this.
+ * Originally, this is used to embed the rcs versions of each source file
+ * in the generated binary. We certainly don't want this in Bionic.
+ */
+#define	__FBSDID(s)	struct __hack
+
+/*-
+ * The following definitions are an extension of the behavior originally
+ * implemented in <sys/_posix.h>, but with a different level of granularity.
+ * POSIX.1 requires that the macros we test be defined before any standard
+ * header file is included.
+ *
+ * Here's a quick run-down of the versions:
+ *  defined(_POSIX_SOURCE)		1003.1-1988
+ *  _POSIX_C_SOURCE == 1		1003.1-1990
+ *  _POSIX_C_SOURCE == 2		1003.2-1992 C Language Binding Option
+ *  _POSIX_C_SOURCE == 199309		1003.1b-1993
+ *  _POSIX_C_SOURCE == 199506		1003.1c-1995, 1003.1i-1995,
+ *					and the omnibus ISO/IEC 9945-1: 1996
+ *  _POSIX_C_SOURCE == 200112		1003.1-2001
+ *  _POSIX_C_SOURCE == 200809		1003.1-2008
+ *
+ * In addition, the X/Open Portability Guide, which is now the Single UNIX
+ * Specification, defines a feature-test macro which indicates the version of
+ * that specification, and which subsumes _POSIX_C_SOURCE.
+ *
+ * Our macros begin with two underscores to avoid namespace screwage.
+ */
+
+/* Deal with IEEE Std. 1003.1-1990, in which _POSIX_C_SOURCE == 1. */
+#if defined(_POSIX_C_SOURCE) && _POSIX_C_SOURCE == 1
+#undef _POSIX_C_SOURCE		/* Probably illegal, but beyond caring now. */
+#define	_POSIX_C_SOURCE		199009
+#endif
+
+/* Deal with IEEE Std. 1003.2-1992, in which _POSIX_C_SOURCE == 2. */
+#if defined(_POSIX_C_SOURCE) && _POSIX_C_SOURCE == 2
+#undef _POSIX_C_SOURCE
+#define	_POSIX_C_SOURCE		199209
+#endif
+
+/* Deal with various X/Open Portability Guides and Single UNIX Spec. */
+#ifdef _XOPEN_SOURCE
+#if _XOPEN_SOURCE - 0 >= 700
+#define	__XSI_VISIBLE		700
+#undef _POSIX_C_SOURCE
+#define	_POSIX_C_SOURCE		200809
+#elif _XOPEN_SOURCE - 0 >= 600
+#define	__XSI_VISIBLE		600
+#undef _POSIX_C_SOURCE
+#define	_POSIX_C_SOURCE		200112
+#elif _XOPEN_SOURCE - 0 >= 500
+#define	__XSI_VISIBLE		500
+#undef _POSIX_C_SOURCE
+#define	_POSIX_C_SOURCE		199506
+#endif
+#endif
+
+/*
+ * Deal with all versions of POSIX.  The ordering relative to the tests above is
+ * important.
+ */
+#if defined(_POSIX_SOURCE) && !defined(_POSIX_C_SOURCE)
+#define	_POSIX_C_SOURCE		198808
+#endif
+#ifdef _POSIX_C_SOURCE
+#if _POSIX_C_SOURCE >= 200809
+#define	__POSIX_VISIBLE		200809
+#define	__ISO_C_VISIBLE		1999
+#elif _POSIX_C_SOURCE >= 200112
+#define	__POSIX_VISIBLE		200112
+#define	__ISO_C_VISIBLE		1999
+#elif _POSIX_C_SOURCE >= 199506
+#define	__POSIX_VISIBLE		199506
+#define	__ISO_C_VISIBLE		1990
+#elif _POSIX_C_SOURCE >= 199309
+#define	__POSIX_VISIBLE		199309
+#define	__ISO_C_VISIBLE		1990
+#elif _POSIX_C_SOURCE >= 199209
+#define	__POSIX_VISIBLE		199209
+#define	__ISO_C_VISIBLE		1990
+#elif _POSIX_C_SOURCE >= 199009
+#define	__POSIX_VISIBLE		199009
+#define	__ISO_C_VISIBLE		1990
+#else
+#define	__POSIX_VISIBLE		198808
+#define	__ISO_C_VISIBLE		0
+#endif /* _POSIX_C_SOURCE */
+#else
+/*-
+ * Deal with _ANSI_SOURCE:
+ * If it is defined, and no other compilation environment is explicitly
+ * requested, then define our internal feature-test macros to zero.  This
+ * makes no difference to the preprocessor (undefined symbols in preprocessing
+ * expressions are defined to have value zero), but makes it more convenient for
+ * a test program to print out the values.
+ *
+ * If a program mistakenly defines _ANSI_SOURCE and some other macro such as
+ * _POSIX_C_SOURCE, we will assume that it wants the broader compilation
+ * environment (and in fact we will never get here).
+ */
+#if defined(_ANSI_SOURCE)	/* Hide almost everything. */
+#define	__POSIX_VISIBLE		0
+#define	__XSI_VISIBLE		0
+#define	__BSD_VISIBLE		0
+#define	__ISO_C_VISIBLE		1990
+#elif defined(_C99_SOURCE)	/* Localism to specify strict C99 env. */
+#define	__POSIX_VISIBLE		0
+#define	__XSI_VISIBLE		0
+#define	__BSD_VISIBLE		0
+#define	__ISO_C_VISIBLE		1999
+#else				/* Default environment: show everything. */
+#define	__POSIX_VISIBLE		200809
+#define	__XSI_VISIBLE		700
+#define	__BSD_VISIBLE		1
+#define	__ISO_C_VISIBLE		1999
+#endif
+#endif
+
+/*
+ * Default values.
+ */
+#ifndef __XPG_VISIBLE
+# define __XPG_VISIBLE          700
+#endif
+#ifndef __POSIX_VISIBLE
+# define __POSIX_VISIBLE        200809
+#endif
+#ifndef __ISO_C_VISIBLE
+# define __ISO_C_VISIBLE        1999
+#endif
+#ifndef __BSD_VISIBLE
+# define __BSD_VISIBLE          1
+#endif
+
 #define  __BIONIC__   1
 
 #endif /* !_SYS_CDEFS_H_ */
diff --git a/libc/include/sys/eventfd.h b/libc/include/sys/eventfd.h
index 0e142fd..19244a5 100644
--- a/libc/include/sys/eventfd.h
+++ b/libc/include/sys/eventfd.h
@@ -1,14 +1,50 @@
-#ifndef _SYS_EVENTFD_H_
-#define _SYS_EVENTFD_H_
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *  * Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *  * Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+#ifndef _SYS_EVENTFD_H
+#define _SYS_EVENTFD_H
 
 #include <sys/cdefs.h>
-#include <asm/unistd.h>
-#include <asm/termbits.h>
+#include <fcntl.h>
 
 __BEGIN_DECLS
 
-extern int eventfd(int count, int flags);
+#define  EFD_CLOEXEC   O_CLOEXEC
+#define  EFD_NONBLOCK  O_NONBLOCK
+
+/* type of event counter */
+typedef uint64_t  eventfd_t;
+
+extern int eventfd(unsigned int initval, int flags);
+
+/* Compatibility with GLibc */
+extern int eventfd_read(int fd, eventfd_t *counter);
+extern int eventfd_write(int fd, const eventfd_t counter);
 
 __END_DECLS
 
-#endif /*  _SYS_EVENTFD_H_ */
+#endif /* _SYS_EVENTFD_H */
diff --git a/libc/include/sys/file.h b/libc/include/sys/file.h
index 06937ff..cf2f4b1 100644
--- a/libc/include/sys/file.h
+++ b/libc/include/sys/file.h
@@ -31,7 +31,7 @@
 #include <sys/cdefs.h>
 #include <sys/types.h>
 
-// ANDROID: needed for flock()
+/* ANDROID: needed for flock() */
 #include <unistd.h>
 #include <fcntl.h>
 
diff --git a/libc/include/sys/fsuid.h b/libc/include/sys/fsuid.h
index 3257bc0..bc47e3d 100644
--- a/libc/include/sys/fsuid.h
+++ b/libc/include/sys/fsuid.h
@@ -33,8 +33,10 @@
 
 __BEGIN_DECLS
 
+#if 0 /* MISSING FROM BIONIC */
 extern int setfsuid(uid_t);
 extern int setfsgid(gid_t);
+#endif /* MISSING */
 
 __END_DECLS
 
diff --git a/libc/include/sys/ioctl_compat.h b/libc/include/sys/ioctl_compat.h
index d79b67a..cab5c80 100644
--- a/libc/include/sys/ioctl_compat.h
+++ b/libc/include/sys/ioctl_compat.h
@@ -39,8 +39,8 @@
 #ifndef _SYS_IOCTL_COMPAT_H_
 #define	_SYS_IOCTL_COMPAT_H_
 
-//#include <sys/ttychars.h>
-//#include <sys/ttydev.h>
+/*#include <sys/ttychars.h>*/
+/*#include <sys/ttydev.h>*/
 
 struct tchars {
 	char	t_intrc;	/* interrupt */
diff --git a/libc/include/sys/linux-syscalls.h b/libc/include/sys/linux-syscalls.h
index 9fefd86..9702a7a 100644
--- a/libc/include/sys/linux-syscalls.h
+++ b/libc/include/sys/linux-syscalls.h
@@ -72,6 +72,7 @@
 #define __NR__newselect                   (__NR_SYSCALL_BASE + 142)
 #define __NR_ftruncate                    (__NR_SYSCALL_BASE + 93)
 #define __NR_fsync                        (__NR_SYSCALL_BASE + 118)
+#define __NR_fdatasync                    (__NR_SYSCALL_BASE + 148)
 #define __NR_fchown32                     (__NR_SYSCALL_BASE + 207)
 #define __NR_sync                         (__NR_SYSCALL_BASE + 36)
 #define __NR_fcntl64                      (__NR_SYSCALL_BASE + 221)
@@ -104,6 +105,7 @@
 #define __NR_nanosleep                    (__NR_SYSCALL_BASE + 162)
 #define __NR_getitimer                    (__NR_SYSCALL_BASE + 105)
 #define __NR_setitimer                    (__NR_SYSCALL_BASE + 104)
+#define __NR_sigaction                    (__NR_SYSCALL_BASE + 67)
 #define __NR_sigprocmask                  (__NR_SYSCALL_BASE + 126)
 #define __NR_sigsuspend                   (__NR_SYSCALL_BASE + 72)
 #define __NR_rt_sigaction                 (__NR_SYSCALL_BASE + 174)
@@ -126,6 +128,7 @@
 #define __NR_init_module                  (__NR_SYSCALL_BASE + 128)
 #define __NR_delete_module                (__NR_SYSCALL_BASE + 129)
 #define __NR_syslog                       (__NR_SYSCALL_BASE + 103)
+#define __NR_sysinfo                      (__NR_SYSCALL_BASE + 116)
 #define __NR_futex                        (__NR_SYSCALL_BASE + 240)
 #define __NR_poll                         (__NR_SYSCALL_BASE + 168)
 
@@ -136,6 +139,7 @@
 #define __NR_openat                       (__NR_SYSCALL_BASE + 322)
 #define __NR_madvise                      (__NR_SYSCALL_BASE + 220)
 #define __NR_mincore                      (__NR_SYSCALL_BASE + 219)
+#define __NR_pipe2                        (__NR_SYSCALL_BASE + 359)
 #define __NR_getdents64                   (__NR_SYSCALL_BASE + 217)
 #define __NR_fstatfs64                    (__NR_SYSCALL_BASE + 267)
 #define __NR_fstatat64                    (__NR_SYSCALL_BASE + 327)
@@ -155,7 +159,6 @@
 #define __NR_timer_getoverrun             (__NR_SYSCALL_BASE + 260)
 #define __NR_timer_delete                 (__NR_SYSCALL_BASE + 261)
 #define __NR_utimes                       (__NR_SYSCALL_BASE + 269)
-#define __NR_sigaction                    (__NR_SYSCALL_BASE + 67)
 #define __NR_socket                       (__NR_SYSCALL_BASE + 281)
 #define __NR_socketpair                   (__NR_SYSCALL_BASE + 288)
 #define __NR_bind                         (__NR_SYSCALL_BASE + 282)
@@ -179,9 +182,9 @@
 #define __NR_inotify_init                 (__NR_SYSCALL_BASE + 316)
 #define __NR_inotify_add_watch            (__NR_SYSCALL_BASE + 317)
 #define __NR_inotify_rm_watch             (__NR_SYSCALL_BASE + 318)
+#define __NR_eventfd2                     (__NR_SYSCALL_BASE + 356)
 #define __NR_ARM_set_tls                  (__NR_SYSCALL_BASE + 983045)
 #define __NR_ARM_cacheflush               (__NR_SYSCALL_BASE + 983042)
-#define __NR_eventfd                      (__NR_SYSCALL_BASE + 351)
 #endif
 
 #ifdef __i386__
@@ -194,6 +197,7 @@
 #define __NR_openat                       (__NR_SYSCALL_BASE + 295)
 #define __NR_madvise                      (__NR_SYSCALL_BASE + 219)
 #define __NR_mincore                      (__NR_SYSCALL_BASE + 218)
+#define __NR_pipe2                        (__NR_SYSCALL_BASE + 331)
 #define __NR_getdents64                   (__NR_SYSCALL_BASE + 220)
 #define __NR_fstatfs64                    (__NR_SYSCALL_BASE + 269)
 #define __NR_fstatat64                    (__NR_SYSCALL_BASE + 300)
@@ -213,7 +217,6 @@
 #define __NR_timer_getoverrun             (__NR_SYSCALL_BASE + 262)
 #define __NR_timer_delete                 (__NR_SYSCALL_BASE + 263)
 #define __NR_utimes                       (__NR_SYSCALL_BASE + 271)
-#define __NR_sigaction                    (__NR_SYSCALL_BASE + 67)
 #define __NR_socketcall                   (__NR_SYSCALL_BASE + 102)
 #define __NR_ioprio_set                   (__NR_SYSCALL_BASE + 289)
 #define __NR_ioprio_get                   (__NR_SYSCALL_BASE + 290)
@@ -223,7 +226,7 @@
 #define __NR_inotify_init                 (__NR_SYSCALL_BASE + 291)
 #define __NR_inotify_add_watch            (__NR_SYSCALL_BASE + 292)
 #define __NR_inotify_rm_watch             (__NR_SYSCALL_BASE + 293)
-#define __NR_eventfd                      (__NR_SYSCALL_BASE + 323)
+#define __NR_eventfd2                     (__NR_SYSCALL_BASE + 328)
 #endif
 
 #if defined(__SH3__) || defined(__SH4__) 
@@ -237,6 +240,7 @@
 #define __NR_openat                       (__NR_SYSCALL_BASE + 295)
 #define __NR_madvise                      (__NR_SYSCALL_BASE + 219)
 #define __NR_mincore                      (__NR_SYSCALL_BASE + 218)
+#define __NR_pipe2                        (__NR_SYSCALL_BASE + 331)
 #define __NR_getdents64                   (__NR_SYSCALL_BASE + 220)
 #define __NR_fstatfs64                    (__NR_SYSCALL_BASE + 269)
 #define __NR_fstatat64                    (__NR_SYSCALL_BASE + 300)
@@ -256,7 +260,6 @@
 #define __NR_timer_getoverrun             (__NR_SYSCALL_BASE + 262)
 #define __NR_timer_delete                 (__NR_SYSCALL_BASE + 263)
 #define __NR_utimes                       (__NR_SYSCALL_BASE + 271)
-#define __NR_sigaction                    (__NR_SYSCALL_BASE + 67)
 #define __NR_socketcall                   (__NR_SYSCALL_BASE + 102)
 #define __NR_socketcall                   (__NR_SYSCALL_BASE + 102)
 #define __NR_socketcall                   (__NR_SYSCALL_BASE + 102)
@@ -273,15 +276,15 @@
 #define __NR_socketcall                   (__NR_SYSCALL_BASE + 102)
 #define __NR_socketcall                   (__NR_SYSCALL_BASE + 102)
 #define __NR___socketcall                 (__NR_SYSCALL_BASE + 102)
-#define __NR_ioprio_set                   (__NR_SYSCALL_BASE + 289)
-#define __NR_ioprio_get                   (__NR_SYSCALL_BASE + 290)
+#define __NR_ioprio_set                   (__NR_SYSCALL_BASE + 288)
+#define __NR_ioprio_get                   (__NR_SYSCALL_BASE + 289)
 #define __NR_epoll_create                 (__NR_SYSCALL_BASE + 254)
 #define __NR_epoll_ctl                    (__NR_SYSCALL_BASE + 255)
 #define __NR_epoll_wait                   (__NR_SYSCALL_BASE + 256)
 #define __NR_inotify_init                 (__NR_SYSCALL_BASE + 290)
 #define __NR_inotify_add_watch            (__NR_SYSCALL_BASE + 291)
 #define __NR_inotify_rm_watch             (__NR_SYSCALL_BASE + 292)
-#define __NR_eventfd                      (__NR_SYSCALL_BASE + 323)
+#define __NR_eventfd2                     (__NR_SYSCALL_BASE + 328)
 #endif
 
 #endif
diff --git a/libc/include/sys/linux-unistd.h b/libc/include/sys/linux-unistd.h
index de5c2bb..51070bd 100644
--- a/libc/include/sys/linux-unistd.h
+++ b/libc/include/sys/linux-unistd.h
@@ -9,7 +9,7 @@
 void             _exit_thread (int);
 pid_t            __fork (void);
 pid_t            _waitpid (pid_t, int*, int, struct rusage*);
-int              waitid (int, pid_t, struct siginfo_t*, int,void*);
+int              __waitid (int, pid_t, struct siginfo_t*, int,void*);
 pid_t            __sys_clone (int, void*, int*, void*, int*);
 int              execve (const char*, char* const*, char* const*);
 int              __setuid (uid_t);
@@ -79,15 +79,17 @@
 int              fchmod (int, mode_t);
 int              dup (int);
 int              pipe (int *);
+int              pipe2 (int *, int);
 int              dup2 (int, int);
 int              select (int, struct fd_set *, struct fd_set *, struct fd_set *, struct timeval *);
 int              ftruncate (int, off_t);
 int              getdents (unsigned int, struct dirent *, unsigned int);
 int              fsync (int);
+int              fdatasync (int);
 int              fchown (int, uid_t, gid_t);
 void             sync (void);
 int              __fcntl64 (int, int, void *);
-int              fstatfs (int, size_t, struct statfs *);
+int              __fstatfs64 (int, size_t, struct statfs *);
 ssize_t          sendfile (int out_fd, int in_fd, off_t *offset, size_t count);
 int              fstatat (int dirfd, const char *path, struct stat *buf, int flags);
 int              mkdirat (int dirfd, const char *pathname, mode_t mode);
@@ -142,7 +144,6 @@
 int              __rt_sigprocmask (int  how, const sigset_t *set, sigset_t *oset, size_t sigsetsize);
 int              __rt_sigtimedwait (const sigset_t *set, struct siginfo_t  *info, struct timespec_t  *timeout, size_t  sigset_size);
 int              sigpending (sigset_t *);
-int              __sigaction (int, const struct sigaction *, struct sigaction *);
 int              socket (int, int, int);
 int              socketpair (int, int, int, int*);
 int              bind (int, struct sockaddr *, int);
@@ -192,6 +193,7 @@
 int              init_module (void *, unsigned long, const char *);
 int              delete_module (const char*, unsigned int);
 int              klogctl (int, char *, int);
+int              sysinfo (struct sysinfo *);
 int              futex (void *, int, int, void *, void *, int);
 int              epoll_create (int size);
 int              epoll_ctl (int epfd, int op, int fd, struct epoll_event *event);
@@ -200,6 +202,7 @@
 int              inotify_add_watch (int, const char *, unsigned int);
 int              inotify_rm_watch (int, unsigned int);
 int              poll (struct pollfd *, unsigned int, long);
+int              eventfd (unsigned int, int);
 int              __set_tls (void*);
 int              cacheflush (long start, long end, long flags);
 int              eventfd (int count, int flags);
diff --git a/libc/include/sys/mount.h b/libc/include/sys/mount.h
index 62c4ee2..ba88447 100644
--- a/libc/include/sys/mount.h
+++ b/libc/include/sys/mount.h
@@ -92,7 +92,10 @@
 		   const void *);
 extern int umount(const char *);
 extern int umount2(const char *, int);
+
+#if 0 /* MISSING FROM BIONIC */
 extern int pivot_root(const char *, const char *);
+#endif /* MISSING */
 
 __END_DECLS
 
diff --git a/libc/include/sys/ptrace.h b/libc/include/sys/ptrace.h
index 78a057a..848416b 100644
--- a/libc/include/sys/ptrace.h
+++ b/libc/include/sys/ptrace.h
@@ -30,7 +30,7 @@
 
 #include <sys/cdefs.h>
 #include <sys/types.h>
-// For all of the defines
+/* For all of the defines */
 #include <linux/ptrace.h>
 
 __BEGIN_DECLS
diff --git a/libc/include/sys/select.h b/libc/include/sys/select.h
index 52315b9..9d11ee8 100644
--- a/libc/include/sys/select.h
+++ b/libc/include/sys/select.h
@@ -31,12 +31,15 @@
 #include <sys/cdefs.h>
 #include <sys/time.h>
 #include <sys/types.h>
+#include <signal.h>
 
 __BEGIN_DECLS
 
 typedef __kernel_fd_set   fd_set;
 
 extern int select(int, fd_set *, fd_set *, fd_set *, struct timeval *);
+extern int pselect(int n, fd_set *readfds, fd_set *writefds, fd_set *errfds,
+                   const struct timespec *timeout, const sigset_t *sigmask);
 
 __END_DECLS
 
diff --git a/libc/include/sys/types.h b/libc/include/sys/types.h
index b071ee9..33fe30e 100644
--- a/libc/include/sys/types.h
+++ b/libc/include/sys/types.h
@@ -62,8 +62,10 @@
 typedef __kernel_key_t       key_t;
 typedef __kernel_mode_t      mode_t;
 typedef __kernel_nlink_t	 nlink_t;
+#ifndef _OFF_T_DEFINED_
 #define _OFF_T_DEFINED_
 typedef __kernel_off_t       off_t;
+#endif
 typedef __kernel_loff_t      loff_t;
 typedef loff_t               off64_t;  /* GLibc-specific */
 
diff --git a/libc/include/sys/wait.h b/libc/include/sys/wait.h
index 8ba1837..b30b7ec 100644
--- a/libc/include/sys/wait.h
+++ b/libc/include/sys/wait.h
@@ -32,6 +32,7 @@
 #include <sys/types.h>
 #include <sys/resource.h>
 #include <linux/wait.h>
+#include <signal.h>
 
 __BEGIN_DECLS
 
@@ -49,6 +50,14 @@
 extern pid_t  wait3(int *, int, struct rusage *);
 extern pid_t  wait4(pid_t, int *, int, struct rusage *);
 
+/* Posix states that idtype_t should be an enumeration type, but
+ * the kernel headers define P_ALL, P_PID and P_PGID as constant macros
+ * instead.
+ */
+typedef int idtype_t;
+
+extern int  waitid(idtype_t which, id_t id, siginfo_t *info, int options);
+
 __END_DECLS
 
 #endif /* _SYS_WAIT_H_ */
diff --git a/libc/include/termio.h b/libc/include/termio.h
new file mode 100644
index 0000000..99d3630
--- /dev/null
+++ b/libc/include/termio.h
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *  * Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *  * Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/* All definitions related to termio are in Linux kernel headers
+ * that are already included by <termios.h>
+ */
+#include <termios.h>
diff --git a/libc/include/unistd.h b/libc/include/unistd.h
index b4f1dda..29154a2 100644
--- a/libc/include/unistd.h
+++ b/libc/include/unistd.h
@@ -61,16 +61,13 @@
 extern pid_t  getpgrp(void);
 extern int    setpgrp(void);
 extern pid_t  setsid(void);
-extern pid_t  getsid(pid_t);
 
 extern int execv(const char *, char * const *);
 extern int execvp(const char *, char * const *);
 extern int execve(const char *, char * const *, char * const *);
-extern int execvpe(const char *, char * const *, char * const *);
 extern int execl(const char *, const char *, ...);
 extern int execlp(const char *, const char *, ...);
 extern int execle(const char *, const char *, ...);
-extern int execlpe(const char *, const char *, ...);
 extern int capget(cap_user_header_t hdrp, cap_user_data_t datap);
 extern int capset(cap_user_header_t hdrp, const cap_user_data_t datap);
 extern int prctl(int  option,  unsigned long arg2, unsigned long arg3,
@@ -94,11 +91,8 @@
 extern int setresgid(gid_t, gid_t, gid_t);
 extern int getresuid(uid_t *ruid, uid_t *euid, uid_t *suid);
 extern int getresgid(gid_t *rgid, gid_t *egid, gid_t *sgid);
-extern int getfsuid(uid_t);
-extern int setfsuid(uid_t);
 extern int issetugid(void);
 extern char* getlogin(void);
-extern int getlogin_r(char* name, size_t namesize);
 extern char* getusershell(void);
 extern void setusershell(void);
 extern void endusershell(void);
@@ -118,12 +112,16 @@
 extern int fchdir(int);
 extern int rmdir(const char *);
 extern int pipe(int *);
+#ifdef _GNU_SOURCE  /* GLibc compatibility */
+extern int pipe2(int *, int);
+#endif
 extern int chroot(const char *);
 extern int symlink(const char *, const char *);
 extern int readlink(const char *, char *, size_t);
 extern int chown(const char *, uid_t, gid_t);
 extern int fchown(int, uid_t, gid_t);
 extern int lchown(const char *, uid_t, gid_t);
+extern int truncate(const char *, off_t);
 extern char *getcwd(char *, size_t);
 
 extern int sync(void);
@@ -152,9 +150,6 @@
 extern int usleep(unsigned long);
 
 extern int gethostname(char *, size_t);
-extern int sethostname(const char *, size_t);
-extern int getdomainname(char *, size_t);
-extern int setdomainname(const char *, size_t);
 
 extern int getdtablesize(void);
 
@@ -191,6 +186,18 @@
 extern pid_t tcgetpgrp(int fd);
 extern int   tcsetpgrp(int fd, pid_t _pid);
 
+#if 0 /* MISSING FROM BIONIC */
+extern pid_t  getsid(pid_t);
+extern int execvpe(const char *, char * const *, char * const *);
+extern int execlpe(const char *, const char *, ...);
+extern int getfsuid(uid_t);
+extern int setfsuid(uid_t);
+extern int getlogin_r(char* name, size_t namesize);
+extern int sethostname(const char *, size_t);
+extern int getdomainname(char *, size_t);
+extern int setdomainname(const char *, size_t);
+#endif /* MISSING */
+
 /* Used to retry syscalls that can return EINTR. */
 #define TEMP_FAILURE_RETRY(exp) ({         \
     typeof (exp) _rc;                      \
diff --git a/libc/include/utmp.h b/libc/include/utmp.h
index e362b40..ffd3c92 100644
--- a/libc/include/utmp.h
+++ b/libc/include/utmp.h
@@ -87,4 +87,4 @@
 
 __END_DECLS
 
-#endif // _UTMP_H_
+#endif /* _UTMP_H_ */
diff --git a/libc/include/wchar.h b/libc/include/wchar.h
index 97e1b5c..9b744a5 100644
--- a/libc/include/wchar.h
+++ b/libc/include/wchar.h
@@ -70,9 +70,9 @@
     WC_TYPE_MAX
 } wctype_t;
 
-#define  WCHAR_MAX   255
-#define  WCHAR_MIN   0
-#define  WEOF        (-1)
+#define  WCHAR_MAX   INT_MAX
+#define  WCHAR_MIN   INT_MIN
+#define  WEOF        ((wint_t)(-1))
 
 extern wint_t            btowc(int);
 extern int               fwprintf(FILE *, const wchar_t *, ...);
diff --git a/libc/kernel/common/linux/msm_vidc_dec.h b/libc/kernel/common/linux/msm_vidc_dec.h
new file mode 100644
index 0000000..20837a7
--- /dev/null
+++ b/libc/kernel/common/linux/msm_vidc_dec.h
@@ -0,0 +1,460 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   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.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _MSM_VIDC_DEC_H_
+#define _MSM_VIDC_DEC_H_
+
+#include <linux/types.h>
+#include <linux/ioctl.h>
+
+#define VDEC_S_BASE 0x40000000
+
+#define VDEC_S_SUCCESS (VDEC_S_BASE)
+
+#define VDEC_S_EFAIL (VDEC_S_BASE + 1)
+
+#define VDEC_S_EFATAL (VDEC_S_BASE + 2)
+
+#define VDEC_S_EBADPARAM (VDEC_S_BASE + 3)
+
+#define VDEC_S_EINVALSTATE (VDEC_S_BASE + 4)
+
+#define VDEC_S_ENOSWRES (VDEC_S_BASE + 5)
+
+#define VDEC_S_ENOHWRES (VDEC_S_BASE + 6)
+
+#define VDEC_S_EINVALCMD (VDEC_S_BASE + 7)
+
+#define VDEC_S_ETIMEOUT (VDEC_S_BASE + 8)
+
+#define VDEC_S_ENOPREREQ (VDEC_S_BASE + 9)
+
+#define VDEC_S_ECMDQFULL (VDEC_S_BASE + 10)
+
+#define VDEC_S_ENOTSUPP (VDEC_S_BASE + 11)
+
+#define VDEC_S_ENOTIMPL (VDEC_S_BASE + 12)
+
+#define VDEC_S_BUSY (VDEC_S_BASE + 13)
+
+#define VDEC_INTF_VER 1
+#define VDEC_MSG_BASE 0x0000000
+
+#define VDEC_MSG_INVALID (VDEC_MSG_BASE + 0)
+#define VDEC_MSG_RESP_INPUT_BUFFER_DONE (VDEC_MSG_BASE + 1)
+#define VDEC_MSG_RESP_OUTPUT_BUFFER_DONE (VDEC_MSG_BASE + 2)
+#define VDEC_MSG_RESP_INPUT_FLUSHED (VDEC_MSG_BASE + 3)
+#define VDEC_MSG_RESP_OUTPUT_FLUSHED (VDEC_MSG_BASE + 4)
+#define VDEC_MSG_RESP_FLUSH_INPUT_DONE (VDEC_MSG_BASE + 5)
+#define VDEC_MSG_RESP_FLUSH_OUTPUT_DONE (VDEC_MSG_BASE + 6)
+#define VDEC_MSG_RESP_START_DONE (VDEC_MSG_BASE + 7)
+#define VDEC_MSG_RESP_STOP_DONE (VDEC_MSG_BASE + 8)
+#define VDEC_MSG_RESP_PAUSE_DONE (VDEC_MSG_BASE + 9)
+#define VDEC_MSG_RESP_RESUME_DONE (VDEC_MSG_BASE + 10)
+#define VDEC_MSG_RESP_RESOURCE_LOADED (VDEC_MSG_BASE + 11)
+#define VDEC_EVT_RESOURCES_LOST (VDEC_MSG_BASE + 12)
+#define VDEC_MSG_EVT_CONFIG_CHANGED (VDEC_MSG_BASE + 13)
+#define VDEC_MSG_EVT_HW_ERROR (VDEC_MSG_BASE + 14)
+
+#define VDEC_BUFFERFLAG_EOS 0x00000001
+#define VDEC_BUFFERFLAG_DECODEONLY 0x00000004
+#define VDEC_BUFFERFLAG_DATACORRUPT 0x00000008
+#define VDEC_BUFFERFLAG_ENDOFFRAME 0x00000010
+#define VDEC_BUFFERFLAG_SYNCFRAME 0x00000020
+#define VDEC_BUFFERFLAG_EXTRADATA 0x00000040
+#define VDEC_BUFFERFLAG_CODECCONFIG 0x00000080
+
+#define VDEC_EXTRADATA_QP 0x00000001
+#define VDEC_EXTRADATA_SEI 0x00000002
+#define VDEC_EXTRADATA_VUI 0x00000004
+#define VDEC_EXTRADATA_MB_ERROR_MAP 0x00000008
+
+#define VDEC_CMDBASE 0x800
+#define VDEC_CMD_SET_INTF_VERSION (VDEC_CMDBASE)
+
+#define VDEC_IOCTL_MAGIC 'v'
+
+struct vdec_ioctl_msg {
+ void *inputparam;
+ void *outputparam;
+};
+
+#define VDEC_IOCTL_GET_PROFILE_LEVEL_SUPPORTED   _IOWR(VDEC_IOCTL_MAGIC, 0, struct vdec_ioctl_msg)
+
+#define VDEC_IOCTL_GET_INTERLACE_FORMAT   _IOR(VDEC_IOCTL_MAGIC, 1, struct vdec_ioctl_msg)
+
+#define VDEC_IOCTL_GET_CURRENT_PROFILE_LEVEL   _IOWR(VDEC_IOCTL_MAGIC, 2, struct vdec_ioctl_msg)
+
+#define VDEC_IOCTL_SET_OUTPUT_FORMAT   _IOWR(VDEC_IOCTL_MAGIC, 3, struct vdec_ioctl_msg)
+#define VDEC_IOCTL_GET_OUTPUT_FORMAT   _IOWR(VDEC_IOCTL_MAGIC, 4, struct vdec_ioctl_msg)
+
+#define VDEC_IOCTL_SET_CODEC   _IOW(VDEC_IOCTL_MAGIC, 5, struct vdec_ioctl_msg)
+#define VDEC_IOCTL_GET_CODEC   _IOR(VDEC_IOCTL_MAGIC, 6, struct vdec_ioctl_msg)
+
+#define VDEC_IOCTL_SET_PICRES   _IOW(VDEC_IOCTL_MAGIC, 7, struct vdec_ioctl_msg)
+#define VDEC_IOCTL_GET_PICRES   _IOR(VDEC_IOCTL_MAGIC, 8, struct vdec_ioctl_msg)
+
+#define VDEC_IOCTL_SET_EXTRADATA   _IOW(VDEC_IOCTL_MAGIC, 9, struct vdec_ioctl_msg)
+#define VDEC_IOCTL_GET_EXTRADATA   _IOR(VDEC_IOCTL_MAGIC, 10, struct vdec_ioctl_msg)
+
+#define VDEC_IOCTL_SET_SEQUENCE_HEADER   _IOW(VDEC_IOCTL_MAGIC, 11, struct vdec_ioctl_msg)
+
+#define VDEC_IOCTL_SET_BUFFER_REQ   _IOW(VDEC_IOCTL_MAGIC, 12, struct vdec_ioctl_msg)
+#define VDEC_IOCTL_GET_BUFFER_REQ   _IOR(VDEC_IOCTL_MAGIC, 13, struct vdec_ioctl_msg)
+
+#define VDEC_IOCTL_ALLOCATE_BUFFER   _IOWR(VDEC_IOCTL_MAGIC, 14, struct vdec_ioctl_msg)
+
+#define VDEC_IOCTL_FREE_BUFFER   _IOW(VDEC_IOCTL_MAGIC, 15, struct vdec_ioctl_msg)
+
+#define VDEC_IOCTL_SET_BUFFER   _IOW(VDEC_IOCTL_MAGIC, 16, struct vdec_ioctl_msg)
+
+#define VDEC_IOCTL_FILL_OUTPUT_BUFFER   _IOW(VDEC_IOCTL_MAGIC, 17, struct vdec_ioctl_msg)
+
+#define VDEC_IOCTL_DECODE_FRAME   _IOW(VDEC_IOCTL_MAGIC, 18, struct vdec_ioctl_msg)
+
+#define VDEC_IOCTL_LOAD_RESOURCES _IO(VDEC_IOCTL_MAGIC, 19)
+#define VDEC_IOCTL_CMD_START _IO(VDEC_IOCTL_MAGIC, 20)
+#define VDEC_IOCTL_CMD_STOP _IO(VDEC_IOCTL_MAGIC, 21)
+#define VDEC_IOCTL_CMD_PAUSE _IO(VDEC_IOCTL_MAGIC, 22)
+#define VDEC_IOCTL_CMD_RESUME _IO(VDEC_IOCTL_MAGIC, 23)
+
+#define VDEC_IOCTL_CMD_FLUSH _IOW(VDEC_IOCTL_MAGIC, 24, struct vdec_ioctl_msg)
+
+#define VDEC_IOCTL_GET_NEXT_MSG   _IOR(VDEC_IOCTL_MAGIC, 25, struct vdec_ioctl_msg)
+
+#define VDEC_IOCTL_STOP_NEXT_MSG _IO(VDEC_IOCTL_MAGIC, 26)
+
+#define VDEC_IOCTL_GET_NUMBER_INSTANCES   _IOR(VDEC_IOCTL_MAGIC, 27, struct vdec_ioctl_msg)
+
+enum vdec_picture {
+ PICTURE_TYPE_I,
+ PICTURE_TYPE_P,
+ PICTURE_TYPE_B,
+ PICTURE_TYPE_BI,
+ PICTURE_TYPE_SKIP,
+ PICTURE_TYPE_UNKNOWN
+};
+
+enum vdec_buffer {
+ VDEC_BUFFER_TYPE_INPUT,
+ VDEC_BUFFER_TYPE_OUTPUT
+};
+
+struct vdec_allocatorproperty {
+ enum vdec_buffer buffer_type;
+ uint32_t mincount;
+ uint32_t maxcount;
+ uint32_t actualcount;
+ uint32_t buffer_size;
+ uint32_t alignment;
+ uint32_t buf_poolid;
+};
+
+struct vdec_bufferpayload {
+ uint8_t *bufferaddr;
+ uint32_t buffer_len;
+ int pmem_fd;
+ uint32_t offset;
+ uint32_t mmaped_size;
+};
+
+struct vdec_setbuffer_cmd {
+ enum vdec_buffer buffer_type;
+ struct vdec_bufferpayload buffer;
+};
+
+struct vdec_fillbuffer_cmd {
+ struct vdec_bufferpayload buffer;
+ void *client_data;
+};
+
+enum vdec_bufferflush {
+ VDEC_FLUSH_TYPE_INPUT,
+ VDEC_FLUSH_TYPE_OUTPUT,
+ VDEC_FLUSH_TYPE_ALL
+};
+
+enum vdec_codec {
+ VDEC_CODECTYPE_H264 = 0x1,
+ VDEC_CODECTYPE_H263 = 0x2,
+ VDEC_CODECTYPE_MPEG4 = 0x3,
+ VDEC_CODECTYPE_DIVX_3 = 0x4,
+ VDEC_CODECTYPE_DIVX_4 = 0x5,
+ VDEC_CODECTYPE_DIVX_5 = 0x6,
+ VDEC_CODECTYPE_DIVX_6 = 0x7,
+ VDEC_CODECTYPE_XVID = 0x8,
+ VDEC_CODECTYPE_MPEG1 = 0x9,
+ VDEC_CODECTYPE_MPEG2 = 0xa,
+ VDEC_CODECTYPE_VC1 = 0xb,
+ VDEC_CODECTYPE_VC1_RCV = 0xc
+};
+
+enum vdec_mpeg2_profile {
+ VDEC_MPEG2ProfileSimple = 0x1,
+ VDEC_MPEG2ProfileMain = 0x2,
+ VDEC_MPEG2Profile422 = 0x4,
+ VDEC_MPEG2ProfileSNR = 0x8,
+ VDEC_MPEG2ProfileSpatial = 0x10,
+ VDEC_MPEG2ProfileHigh = 0x20,
+ VDEC_MPEG2ProfileKhronosExtensions = 0x6F000000,
+ VDEC_MPEG2ProfileVendorStartUnused = 0x7F000000,
+ VDEC_MPEG2ProfileMax = 0x7FFFFFFF
+};
+
+enum vdec_mpeg2_level {
+
+ VDEC_MPEG2LevelLL = 0x1,
+ VDEC_MPEG2LevelML = 0x2,
+ VDEC_MPEG2LevelH14 = 0x4,
+ VDEC_MPEG2LevelHL = 0x8,
+ VDEC_MPEG2LevelKhronosExtensions = 0x6F000000,
+ VDEC_MPEG2LevelVendorStartUnused = 0x7F000000,
+ VDEC_MPEG2LevelMax = 0x7FFFFFFF
+};
+
+enum vdec_mpeg4_profile {
+ VDEC_MPEG4ProfileSimple = 0x01,
+ VDEC_MPEG4ProfileSimpleScalable = 0x02,
+ VDEC_MPEG4ProfileCore = 0x04,
+ VDEC_MPEG4ProfileMain = 0x08,
+ VDEC_MPEG4ProfileNbit = 0x10,
+ VDEC_MPEG4ProfileScalableTexture = 0x20,
+ VDEC_MPEG4ProfileSimpleFace = 0x40,
+ VDEC_MPEG4ProfileSimpleFBA = 0x80,
+ VDEC_MPEG4ProfileBasicAnimated = 0x100,
+ VDEC_MPEG4ProfileHybrid = 0x200,
+ VDEC_MPEG4ProfileAdvancedRealTime = 0x400,
+ VDEC_MPEG4ProfileCoreScalable = 0x800,
+ VDEC_MPEG4ProfileAdvancedCoding = 0x1000,
+ VDEC_MPEG4ProfileAdvancedCore = 0x2000,
+ VDEC_MPEG4ProfileAdvancedScalable = 0x4000,
+ VDEC_MPEG4ProfileAdvancedSimple = 0x8000,
+ VDEC_MPEG4ProfileKhronosExtensions = 0x6F000000,
+ VDEC_MPEG4ProfileVendorStartUnused = 0x7F000000,
+ VDEC_MPEG4ProfileMax = 0x7FFFFFFF
+};
+
+enum vdec_mpeg4_level {
+ VDEC_MPEG4Level0 = 0x01,
+ VDEC_MPEG4Level0b = 0x02,
+ VDEC_MPEG4Level1 = 0x04,
+ VDEC_MPEG4Level2 = 0x08,
+ VDEC_MPEG4Level3 = 0x10,
+ VDEC_MPEG4Level4 = 0x20,
+ VDEC_MPEG4Level4a = 0x40,
+ VDEC_MPEG4Level5 = 0x80,
+ VDEC_MPEG4LevelKhronosExtensions = 0x6F000000,
+ VDEC_MPEG4LevelVendorStartUnused = 0x7F000000,
+ VDEC_MPEG4LevelMax = 0x7FFFFFFF
+};
+
+enum vdec_avc_profile {
+ VDEC_AVCProfileBaseline = 0x01,
+ VDEC_AVCProfileMain = 0x02,
+ VDEC_AVCProfileExtended = 0x04,
+ VDEC_AVCProfileHigh = 0x08,
+ VDEC_AVCProfileHigh10 = 0x10,
+ VDEC_AVCProfileHigh422 = 0x20,
+ VDEC_AVCProfileHigh444 = 0x40,
+ VDEC_AVCProfileKhronosExtensions = 0x6F000000,
+ VDEC_AVCProfileVendorStartUnused = 0x7F000000,
+ VDEC_AVCProfileMax = 0x7FFFFFFF
+};
+
+enum vdec_avc_level {
+ VDEC_AVCLevel1 = 0x01,
+ VDEC_AVCLevel1b = 0x02,
+ VDEC_AVCLevel11 = 0x04,
+ VDEC_AVCLevel12 = 0x08,
+ VDEC_AVCLevel13 = 0x10,
+ VDEC_AVCLevel2 = 0x20,
+ VDEC_AVCLevel21 = 0x40,
+ VDEC_AVCLevel22 = 0x80,
+ VDEC_AVCLevel3 = 0x100,
+ VDEC_AVCLevel31 = 0x200,
+ VDEC_AVCLevel32 = 0x400,
+ VDEC_AVCLevel4 = 0x800,
+ VDEC_AVCLevel41 = 0x1000,
+ VDEC_AVCLevel42 = 0x2000,
+ VDEC_AVCLevel5 = 0x4000,
+ VDEC_AVCLevel51 = 0x8000,
+ VDEC_AVCLevelKhronosExtensions = 0x6F000000,
+ VDEC_AVCLevelVendorStartUnused = 0x7F000000,
+ VDEC_AVCLevelMax = 0x7FFFFFFF
+};
+
+enum vdec_divx_profile {
+ VDEC_DIVXProfile_qMobile = 0x01,
+ VDEC_DIVXProfile_Mobile = 0x02,
+ VDEC_DIVXProfile_HD = 0x04,
+ VDEC_DIVXProfile_Handheld = 0x08,
+ VDEC_DIVXProfile_Portable = 0x10,
+ VDEC_DIVXProfile_HomeTheater = 0x20
+};
+
+enum vdec_xvid_profile {
+ VDEC_XVIDProfile_Simple = 0x1,
+ VDEC_XVIDProfile_Advanced_Realtime_Simple = 0x2,
+ VDEC_XVIDProfile_Advanced_Simple = 0x4
+};
+
+enum vdec_xvid_level {
+ VDEC_XVID_LEVEL_S_L0 = 0x1,
+ VDEC_XVID_LEVEL_S_L1 = 0x2,
+ VDEC_XVID_LEVEL_S_L2 = 0x4,
+ VDEC_XVID_LEVEL_S_L3 = 0x8,
+ VDEC_XVID_LEVEL_ARTS_L1 = 0x10,
+ VDEC_XVID_LEVEL_ARTS_L2 = 0x20,
+ VDEC_XVID_LEVEL_ARTS_L3 = 0x40,
+ VDEC_XVID_LEVEL_ARTS_L4 = 0x80,
+ VDEC_XVID_LEVEL_AS_L0 = 0x100,
+ VDEC_XVID_LEVEL_AS_L1 = 0x200,
+ VDEC_XVID_LEVEL_AS_L2 = 0x400,
+ VDEC_XVID_LEVEL_AS_L3 = 0x800,
+ VDEC_XVID_LEVEL_AS_L4 = 0x1000
+};
+
+enum vdec_h263profile {
+ VDEC_H263ProfileBaseline = 0x01,
+ VDEC_H263ProfileH320Coding = 0x02,
+ VDEC_H263ProfileBackwardCompatible = 0x04,
+ VDEC_H263ProfileISWV2 = 0x08,
+ VDEC_H263ProfileISWV3 = 0x10,
+ VDEC_H263ProfileHighCompression = 0x20,
+ VDEC_H263ProfileInternet = 0x40,
+ VDEC_H263ProfileInterlace = 0x80,
+ VDEC_H263ProfileHighLatency = 0x100,
+ VDEC_H263ProfileKhronosExtensions = 0x6F000000,
+ VDEC_H263ProfileVendorStartUnused = 0x7F000000,
+ VDEC_H263ProfileMax = 0x7FFFFFFF
+};
+
+enum vdec_h263level {
+ VDEC_H263Level10 = 0x01,
+ VDEC_H263Level20 = 0x02,
+ VDEC_H263Level30 = 0x04,
+ VDEC_H263Level40 = 0x08,
+ VDEC_H263Level45 = 0x10,
+ VDEC_H263Level50 = 0x20,
+ VDEC_H263Level60 = 0x40,
+ VDEC_H263Level70 = 0x80,
+ VDEC_H263LevelKhronosExtensions = 0x6F000000,
+ VDEC_H263LevelVendorStartUnused = 0x7F000000,
+ VDEC_H263LevelMax = 0x7FFFFFFF
+};
+
+enum vdec_wmv_format {
+ VDEC_WMVFormatUnused = 0x01,
+ VDEC_WMVFormat7 = 0x02,
+ VDEC_WMVFormat8 = 0x04,
+ VDEC_WMVFormat9 = 0x08,
+ VDEC_WMFFormatKhronosExtensions = 0x6F000000,
+ VDEC_WMFFormatVendorStartUnused = 0x7F000000,
+ VDEC_WMVFormatMax = 0x7FFFFFFF
+};
+
+enum vdec_vc1_profile {
+ VDEC_VC1ProfileSimple = 0x1,
+ VDEC_VC1ProfileMain = 0x2,
+ VDEC_VC1ProfileAdvanced = 0x4
+};
+
+enum vdec_vc1_level {
+ VDEC_VC1_LEVEL_S_Low = 0x1,
+ VDEC_VC1_LEVEL_S_Medium = 0x2,
+ VDEC_VC1_LEVEL_M_Low = 0x4,
+ VDEC_VC1_LEVEL_M_Medium = 0x8,
+ VDEC_VC1_LEVEL_M_High = 0x10,
+ VDEC_VC1_LEVEL_A_L0 = 0x20,
+ VDEC_VC1_LEVEL_A_L1 = 0x40,
+ VDEC_VC1_LEVEL_A_L2 = 0x80,
+ VDEC_VC1_LEVEL_A_L3 = 0x100,
+ VDEC_VC1_LEVEL_A_L4 = 0x200
+};
+
+struct vdec_profile_level {
+ uint32_t profiles;
+ uint32_t levels;
+};
+
+enum vdec_interlaced_format {
+ VDEC_InterlaceFrameProgressive = 0x1,
+ VDEC_InterlaceInterleaveFrameTopFieldFirst = 0x2,
+ VDEC_InterlaceInterleaveFrameBottomFieldFirst = 0x4
+};
+
+enum vdec_output_fromat {
+ VDEC_YUV_FORMAT_NV12 = 0x1,
+ VDEC_YUV_FORMAT_TILE_4x2 = 0x2
+};
+
+struct vdec_picsize {
+ uint32_t frame_width;
+ uint32_t frame_height;
+ uint32_t stride;
+ uint32_t scan_lines;
+};
+
+struct vdec_seqheader {
+ uint8_t *ptr_seqheader;
+ uint32_t seq_header_len;
+ int pmem_fd;
+ uint32_t pmem_offset;
+};
+
+struct vdec_mberror {
+ uint8_t *ptr_errormap;
+ uint32_t err_mapsize;
+};
+
+struct vdec_input_frameinfo {
+ uint8_t *bufferaddr;
+ uint32_t offset;
+ uint32_t datalen;
+ uint32_t flags;
+ int64_t timestamp;
+ void *client_data;
+ int pmem_fd;
+ uint32_t pmem_offset;
+};
+
+struct vdec_framesize {
+ uint32_t left;
+ uint32_t top;
+ uint32_t right;
+ uint32_t bottom;
+};
+
+struct vdec_output_frameinfo {
+ uint8_t *phy_addr;
+ uint8_t *bufferaddr;
+ uint32_t offset;
+ uint32_t len;
+ uint32_t flags;
+ int64_t time_stamp;
+ void *client_data;
+ void *input_frame_clientdata;
+ struct vdec_framesize framesize;
+};
+
+union vdec_msgdata {
+ struct vdec_output_frameinfo output_frame;
+ void *input_frame_clientdata;
+};
+
+struct vdec_msginfo {
+ uint32_t status_code;
+ uint32_t msgcode;
+ union vdec_msgdata msgdata;
+ uint32_t msgdatasize;
+};
+#endif
+
diff --git a/libc/kernel/common/linux/msm_vidc_enc.h b/libc/kernel/common/linux/msm_vidc_enc.h
new file mode 100644
index 0000000..45437a2
--- /dev/null
+++ b/libc/kernel/common/linux/msm_vidc_enc.h
@@ -0,0 +1,402 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   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.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _MSM_VIDC_ENC_H_
+#define _MSM_VIDC_ENC_H_
+
+#include <linux/types.h>
+#include <linux/ioctl.h>
+
+#define VEN_S_BASE 0x00000000
+#define VEN_S_SUCCESS (VEN_S_BASE) 
+#define VEN_S_EFAIL (VEN_S_BASE+1) 
+#define VEN_S_EFATAL (VEN_S_BASE+2) 
+#define VEN_S_EBADPARAM (VEN_S_BASE+3) 
+
+#define VEN_S_EINVALSTATE (VEN_S_BASE+4)
+#define VEN_S_ENOSWRES (VEN_S_BASE+5) 
+#define VEN_S_ENOHWRES (VEN_S_BASE+6) 
+#define VEN_S_EBUFFREQ (VEN_S_BASE+7) 
+#define VEN_S_EINVALCMD (VEN_S_BASE+8) 
+#define VEN_S_ETIMEOUT (VEN_S_BASE+9) 
+
+#define VEN_S_ENOREATMPT (VEN_S_BASE+10)
+#define VEN_S_ENOPREREQ (VEN_S_BASE+11) 
+#define VEN_S_ECMDQFULL (VEN_S_BASE+12) 
+#define VEN_S_ENOTSUPP (VEN_S_BASE+13) 
+#define VEN_S_ENOTIMPL (VEN_S_BASE+14) 
+#define VEN_S_ENOTPMEM (VEN_S_BASE+15) 
+#define VEN_S_EFLUSHED (VEN_S_BASE+16) 
+#define VEN_S_EINSUFBUF (VEN_S_BASE+17) 
+#define VEN_S_ESAMESTATE (VEN_S_BASE+18)
+#define VEN_S_EINVALTRANS (VEN_S_BASE+19)
+
+#define VEN_INTF_VER 1
+
+#define VEN_MSG_INDICATION 0
+#define VEN_MSG_INPUT_BUFFER_DONE 1
+#define VEN_MSG_OUTPUT_BUFFER_DONE 2
+#define VEN_MSG_NEED_OUTPUT_BUFFER 3
+#define VEN_MSG_FLUSH_INPUT_DONE 4
+#define VEN_MSG_FLUSH_OUPUT_DONE 5
+#define VEN_MSG_START 6
+#define VEN_MSG_STOP 7
+#define VEN_MSG_PAUSE 8
+#define VEN_MSG_RESUME 9
+#define VEN_MSG_STOP_READING_MSG 10
+
+#define VEN_BUFFLAG_EOS 0x00000001
+#define VEN_BUFFLAG_ENDOFFRAME 0x00000010
+#define VEN_BUFFLAG_SYNCFRAME 0x00000020
+#define VEN_BUFFLAG_EXTRADATA 0x00000040
+#define VEN_BUFFLAG_CODECCONFIG 0x00000080
+
+#define VEN_FRAME_TYPE_I 1 
+#define VEN_FRAME_TYPE_P 2 
+#define VEN_FRAME_TYPE_B 3 
+
+#define VEN_CODEC_MPEG4 1 
+#define VEN_CODEC_H264 2 
+#define VEN_CODEC_H263 3 
+
+#define VEN_PROFILE_MPEG4_SP 1 
+#define VEN_PROFILE_MPEG4_ASP 2 
+#define VEN_PROFILE_H264_BASELINE 3 
+#define VEN_PROFILE_H264_MAIN 4 
+#define VEN_PROFILE_H264_HIGH 5 
+#define VEN_PROFILE_H263_BASELINE 6 
+
+#define VEN_LEVEL_MPEG4_0 0x1 
+#define VEN_LEVEL_MPEG4_1 0x2 
+#define VEN_LEVEL_MPEG4_2 0x3 
+#define VEN_LEVEL_MPEG4_3 0x4 
+#define VEN_LEVEL_MPEG4_4 0x5 
+#define VEN_LEVEL_MPEG4_5 0x6 
+#define VEN_LEVEL_MPEG4_3b 0x7 
+#define VEN_LEVEL_MPEG4_6 0x8 
+
+#define VEN_LEVEL_H264_1 0x9 
+#define VEN_LEVEL_H264_1b 0xA 
+#define VEN_LEVEL_H264_1p1 0xB 
+#define VEN_LEVEL_H264_1p2 0xC 
+#define VEN_LEVEL_H264_1p3 0xD 
+#define VEN_LEVEL_H264_2 0xE 
+#define VEN_LEVEL_H264_2p1 0xF 
+#define VEN_LEVEL_H264_2p2 0x10 
+#define VEN_LEVEL_H264_3 0x11 
+#define VEN_LEVEL_H264_3p1 0x12 
+
+#define VEN_LEVEL_H263_10 0x13 
+#define VEN_LEVEL_H263_20 0x14 
+#define VEN_LEVEL_H263_30 0x15 
+#define VEN_LEVEL_H263_40 0x16 
+#define VEN_LEVEL_H263_45 0x17 
+#define VEN_LEVEL_H263_50 0x18 
+#define VEN_LEVEL_H263_60 0x19 
+#define VEN_LEVEL_H263_70 0x1A 
+
+#define VEN_ENTROPY_MODEL_CAVLC 1
+#define VEN_ENTROPY_MODEL_CABAC 2
+
+#define VEN_CABAC_MODEL_0 1 
+#define VEN_CABAC_MODEL_1 2 
+#define VEN_CABAC_MODEL_2 3 
+
+#define VEN_DB_DISABLE 1 
+#define VEN_DB_ALL_BLKG_BNDRY 2 
+#define VEN_DB_SKIP_SLICE_BNDRY 3 
+
+#define VEN_MSLICE_OFF 1
+#define VEN_MSLICE_CNT_MB 2  
+#define VEN_MSLICE_CNT_BYTE 3  
+#define VEN_MSLICE_GOB 4  
+
+#define VEN_RC_OFF 1
+#define VEN_RC_VBR_VFR 2
+#define VEN_RC_VBR_CFR 3
+#define VEN_RC_CBR_VFR 4
+
+#define VEN_FLUSH_INPUT 1
+#define VEN_FLUSH_OUTPUT 2
+#define VEN_FLUSH_ALL 3
+
+#define VEN_INPUTFMT_NV12 1 
+#define VEN_INPUTFMT_NV21 2 
+
+#define VEN_ROTATION_0 1 
+#define VEN_ROTATION_90 2 
+#define VEN_ROTATION_180 3 
+#define VEN_ROTATION_270 4 
+
+#define VEN_TIMEOUT_INFINITE 0xffffffff
+
+#define VEN_IR_OFF 1
+#define VEN_IR_CYCLIC 2
+#define VEN_IR_RANDOM 3
+
+#define VEN_IOCTLBASE_NENC 0x800
+
+#define VEN_IOCTLBASE_ENC 0x850
+
+struct venc_ioctl_msg{
+ void *inputparam;
+ void *outputparam;
+};
+
+#define VEN_IOCTL_SET_INTF_VERSION   _IOW(VEN_IOCTLBASE_NENC, 0, struct venc_ioctl_msg)
+
+#define VEN_IOCTL_CMD_READ_NEXT_MSG   _IOWR(VEN_IOCTLBASE_NENC, 1, struct venc_ioctl_msg)
+
+#define VEN_IOCTL_CMD_STOP_READ_MSG _IO(VEN_IOCTLBASE_NENC, 2)
+
+#define VEN_IOCTL_SET_INPUT_BUFFER_REQ   _IOW(VEN_IOCTLBASE_NENC, 3, struct venc_ioctl_msg)
+#define VEN_IOCTL_GET_INPUT_BUFFER_REQ   _IOR(VEN_IOCTLBASE_NENC, 4, struct venc_ioctl_msg)
+
+#define VEN_IOCTL_CMD_ALLOC_INPUT_BUFFER   _IOW(VEN_IOCTLBASE_NENC, 5, struct venc_ioctl_msg)
+
+#define VEN_IOCTL_SET_INPUT_BUFFER   _IOW(VEN_IOCTLBASE_NENC, 6, struct venc_ioctl_msg)
+
+#define VEN_IOCTL_CMD_FREE_INPUT_BUFFER   _IOW(VEN_IOCTLBASE_NENC, 7, struct venc_ioctl_msg)
+
+#define VEN_IOCTL_SET_OUTPUT_BUFFER_REQ   _IOW(VEN_IOCTLBASE_NENC, 8, struct venc_ioctl_msg)
+#define VEN_IOCTL_GET_OUTPUT_BUFFER_REQ   _IOR(VEN_IOCTLBASE_NENC, 9, struct venc_ioctl_msg)
+
+#define VEN_IOCTL_CMD_ALLOC_OUTPUT_BUFFER   _IOW(VEN_IOCTLBASE_NENC, 10, struct venc_ioctl_msg)
+
+#define VEN_IOCTL_SET_OUTPUT_BUFFER   _IOW(VEN_IOCTLBASE_NENC, 11, struct venc_ioctl_msg)
+
+#define VEN_IOCTL_CMD_FREE_OUTPUT_BUFFER   _IOW(VEN_IOCTLBASE_NENC, 12, struct venc_ioctl_msg)
+
+#define VEN_IOCTL_CMD_START _IO(VEN_IOCTLBASE_NENC, 13)
+
+#define VEN_IOCTL_CMD_ENCODE_FRAME   _IOW(VEN_IOCTLBASE_NENC, 14, struct venc_ioctl_msg)
+
+#define VEN_IOCTL_CMD_FILL_OUTPUT_BUFFER   _IOW(VEN_IOCTLBASE_NENC, 15, struct venc_ioctl_msg)
+
+#define VEN_IOCTL_CMD_FLUSH   _IOW(VEN_IOCTLBASE_NENC, 16, struct venc_ioctl_msg)
+
+#define VEN_IOCTL_CMD_PAUSE _IO(VEN_IOCTLBASE_NENC, 17)
+
+#define VEN_IOCTL_CMD_RESUME _IO(VEN_IOCTLBASE_NENC, 18)
+
+#define VEN_IOCTL_CMD_STOP _IO(VEN_IOCTLBASE_NENC, 19)
+
+#define VEN_IOCTL_SET_BASE_CFG   _IOW(VEN_IOCTLBASE_ENC, 1, struct venc_ioctl_msg)
+#define VEN_IOCTL_GET_BASE_CFG   _IOR(VEN_IOCTLBASE_ENC, 2, struct venc_ioctl_msg)
+
+#define VEN_IOCTL_SET_LIVE_MODE   _IOW(VEN_IOCTLBASE_ENC, 3, struct venc_ioctl_msg)
+#define VEN_IOCTL_GET_LIVE_MODE   _IOR(VEN_IOCTLBASE_ENC, 4, struct venc_ioctl_msg)
+
+#define VEN_IOCTL_SET_CODEC_PROFILE   _IOW(VEN_IOCTLBASE_ENC, 5, struct venc_ioctl_msg)
+#define VEN_IOCTL_GET_CODEC_PROFILE   _IOR(VEN_IOCTLBASE_ENC, 6, struct venc_ioctl_msg)
+
+#define VEN_IOCTL_SET_PROFILE_LEVEL   _IOW(VEN_IOCTLBASE_ENC, 7, struct venc_ioctl_msg)
+
+#define VEN_IOCTL_GET_PROFILE_LEVEL   _IOR(VEN_IOCTLBASE_ENC, 8, struct venc_ioctl_msg)
+
+#define VEN_IOCTL_SET_SHORT_HDR   _IOW(VEN_IOCTLBASE_ENC, 9, struct venc_ioctl_msg)
+#define VEN_IOCTL_GET_SHORT_HDR   _IOR(VEN_IOCTLBASE_ENC, 10, struct venc_ioctl_msg)
+
+#define VEN_IOCTL_SET_SESSION_QP   _IOW(VEN_IOCTLBASE_ENC, 11, struct venc_ioctl_msg)
+#define VEN_IOCTL_GET_SESSION_QP   _IOR(VEN_IOCTLBASE_ENC, 12, struct venc_ioctl_msg)
+
+#define VEN_IOCTL_SET_INTRA_PERIOD   _IOW(VEN_IOCTLBASE_ENC, 13, struct venc_ioctl_msg)
+#define VEN_IOCTL_GET_INTRA_PERIOD   _IOR(VEN_IOCTLBASE_ENC, 14, struct venc_ioctl_msg)
+
+#define VEN_IOCTL_CMD_REQUEST_IFRAME _IO(VEN_IOCTLBASE_ENC, 15)
+
+#define VEN_IOCTL_GET_CAPABILITY   _IOR(VEN_IOCTLBASE_ENC, 16, struct venc_ioctl_msg)
+
+#define VEN_IOCTL_GET_SEQUENCE_HDR   _IOR(VEN_IOCTLBASE_ENC, 17, struct venc_ioctl_msg)
+
+#define VEN_IOCTL_SET_ENTROPY_CFG   _IOW(VEN_IOCTLBASE_ENC, 18, struct venc_ioctl_msg)
+#define VEN_IOCTL_GET_ENTROPY_CFG   _IOR(VEN_IOCTLBASE_ENC, 19, struct venc_ioctl_msg)
+
+#define VEN_IOCTL_SET_DEBLOCKING_CFG   _IOW(VEN_IOCTLBASE_ENC, 20, struct venc_ioctl_msg)
+#define VEN_IOCTL_GET_DEBLOCKING_CFG   _IOR(VEN_IOCTLBASE_ENC, 21, struct venc_ioctl_msg)
+
+#define VEN_IOCTL_SET_INTRA_REFRESH   _IOW(VEN_IOCTLBASE_ENC, 22, struct venc_ioctl_msg)
+#define VEN_IOCTL_GET_INTRA_REFRESH   _IOR(VEN_IOCTLBASE_ENC, 23, struct venc_ioctl_msg)
+
+#define VEN_IOCTL_SET_MULTI_SLICE_CFG   _IOW(VEN_IOCTLBASE_ENC, 24, struct venc_ioctl_msg)
+#define VEN_IOCTL_GET_MULTI_SLICE_CFG   _IOR(VEN_IOCTLBASE_ENC, 25, struct venc_ioctl_msg)
+
+#define VEN_IOCTL_SET_RATE_CTRL_CFG   _IOW(VEN_IOCTLBASE_ENC, 26, struct venc_ioctl_msg)
+#define VEN_IOCTL_GET_RATE_CTRL_CFG   _IOR(VEN_IOCTLBASE_ENC, 27, struct venc_ioctl_msg)
+
+#define VEN_IOCTL_SET_VOP_TIMING_CFG   _IOW(VEN_IOCTLBASE_ENC, 28, struct venc_ioctl_msg)
+#define VEN_IOCTL_GET_VOP_TIMING_CFG   _IOR(VEN_IOCTLBASE_ENC, 29, struct venc_ioctl_msg)
+
+#define VEN_IOCTL_SET_FRAME_RATE   _IOW(VEN_IOCTLBASE_ENC, 30, struct venc_ioctl_msg)
+#define VEN_IOCTL_GET_FRAME_RATE   _IOR(VEN_IOCTLBASE_ENC, 31, struct venc_ioctl_msg)
+
+#define VEN_IOCTL_SET_TARGET_BITRATE   _IOW(VEN_IOCTLBASE_ENC, 32, struct venc_ioctl_msg)
+#define VEN_IOCTL_GET_TARGET_BITRATE   _IOR(VEN_IOCTLBASE_ENC, 33, struct venc_ioctl_msg)
+
+#define VEN_IOCTL_SET_ROTATION   _IOW(VEN_IOCTLBASE_ENC, 34, struct venc_ioctl_msg)
+#define VEN_IOCTL_GET_ROTATION   _IOR(VEN_IOCTLBASE_ENC, 35, struct venc_ioctl_msg)
+
+#define VEN_IOCTL_SET_HEC   _IOW(VEN_IOCTLBASE_ENC, 36, struct venc_ioctl_msg)
+#define VEN_IOCTL_GET_HEC   _IOR(VEN_IOCTLBASE_ENC, 37, struct venc_ioctl_msg)
+
+#define VEN_IOCTL_SET_DATA_PARTITION   _IOW(VEN_IOCTLBASE_ENC, 38, struct venc_ioctl_msg)
+#define VEN_IOCTL_GET_DATA_PARTITION   _IOR(VEN_IOCTLBASE_ENC, 39, struct venc_ioctl_msg)
+
+#define VEN_IOCTL_SET_RVLC   _IOW(VEN_IOCTLBASE_ENC, 40, struct venc_ioctl_msg)
+#define VEN_IOCTL_GET_RVLC   _IOR(VEN_IOCTLBASE_ENC, 41, struct venc_ioctl_msg)
+
+#define VEN_IOCTL_SET_AC_PREDICTION   _IOW(VEN_IOCTLBASE_ENC, 42, struct venc_ioctl_msg)
+#define VEN_IOCTL_GET_AC_PREDICTION   _IOR(VEN_IOCTLBASE_ENC, 43, struct venc_ioctl_msg)
+
+#define VEN_IOCTL_SET_QP_RANGE   _IOW(VEN_IOCTLBASE_ENC, 44, struct venc_ioctl_msg)
+#define VEN_IOCTL_GET_QP_RANGE   _IOR(VEN_IOCTLBASE_ENC, 45, struct venc_ioctl_msg)
+
+struct venc_switch{
+ unsigned char status;
+};
+
+struct venc_allocatorproperty{
+ unsigned long mincount;
+ unsigned long maxcount;
+ unsigned long actualcount;
+ unsigned long datasize;
+ unsigned long suffixsize;
+ unsigned long alignment;
+ unsigned long bufpoolid;
+};
+
+struct venc_bufferpayload{
+ unsigned char *pbuffer;
+ unsigned long nsize;
+ int fd;
+ unsigned int offset;
+ unsigned int maped_size;
+ unsigned long filled_len;
+};
+
+struct venc_buffer{
+ unsigned char *ptrbuffer;
+ unsigned long size;
+ unsigned long len;
+ unsigned long offset;
+ long long timestamp;
+ unsigned long flags;
+ void *clientdata;
+};
+
+struct venc_basecfg{
+ unsigned long input_width;
+ unsigned long input_height;
+ unsigned long dvs_width;
+ unsigned long dvs_height;
+ unsigned long codectype;
+ unsigned long fps_num;
+ unsigned long fps_den;
+ unsigned long targetbitrate;
+ unsigned long inputformat;
+};
+
+struct venc_profile{
+ unsigned long profile;
+};
+struct ven_profilelevel{
+ unsigned long level;
+};
+
+struct venc_sessionqp{
+ unsigned long iframeqp;
+ unsigned long pframqp;
+};
+
+struct venc_qprange{
+ unsigned long maxqp;
+ unsigned long minqp;
+};
+struct venc_intraperiod{
+ unsigned long num_pframes;
+};
+struct venc_seqheader{
+ unsigned char *hdrbufptr;
+ unsigned long bufsize;
+ unsigned long hdrlen;
+};
+
+struct venc_capability{
+ unsigned long codec_types;
+ unsigned long maxframe_width;
+ unsigned long maxframe_height;
+ unsigned long maxtarget_bitrate;
+ unsigned long maxframe_rate;
+ unsigned long input_formats;
+ unsigned char dvs;
+};
+
+struct venc_entropycfg{
+ unsigned longentropysel;
+ unsigned long cabacmodel;
+};
+
+struct venc_dbcfg{
+ unsigned long db_mode;
+ unsigned long slicealpha_offset;
+ unsigned long slicebeta_offset;
+};
+
+struct venc_intrarefresh{
+ unsigned long irmode;
+ unsigned long mbcount;
+};
+
+struct venc_multiclicecfg{
+ unsigned long mslice_mode;
+ unsigned long mslice_size;
+};
+
+struct venc_bufferflush{
+ unsigned long flush_mode;
+};
+
+struct venc_ratectrlcfg{
+ unsigned long rcmode;
+};
+
+struct venc_voptimingcfg{
+ unsigned long voptime_resolution;
+};
+struct venc_framerate{
+ unsigned long fps_denominator;
+ unsigned long fps_numerator;
+};
+
+struct venc_targetbitrate{
+ unsigned long target_bitrate;
+};
+
+struct venc_rotation{
+ unsigned long rotation;
+};
+
+struct venc_timeout{
+ unsigned long millisec;
+};
+
+struct venc_headerextension{
+ unsigned long header_extension;
+};
+
+struct venc_msg{
+ unsigned long statuscode;
+ unsigned long msgcode;
+ struct venc_buffer buf;
+ unsigned long msgdata_size;
+};
+#endif
+
diff --git a/libc/kernel/common/linux/pn544.h b/libc/kernel/common/linux/pn544.h
new file mode 100644
index 0000000..900c373
--- /dev/null
+++ b/libc/kernel/common/linux/pn544.h
@@ -0,0 +1,21 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   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.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#define PN544_MAGIC 0xE9
+
+#define PN544_SET_PWR _IOW(0xE9, 0x01, unsigned int)
+
+struct pn544_i2c_platform_data {
+ unsigned int irq_gpio;
+ unsigned int ven_gpio;
+ unsigned int firm_gpio;
+};
+
diff --git a/libc/kernel/common/media/msm_camera.h b/libc/kernel/common/media/msm_camera.h
index da3951b..be4449c 100644
--- a/libc/kernel/common/media/msm_camera.h
+++ b/libc/kernel/common/media/msm_camera.h
@@ -72,6 +72,9 @@
 
 #define MSM_CAM_IOCTL_ENABLE_OUTPUT_IND   _IOW(MSM_CAM_IOCTL_MAGIC, 25, uint32_t *)
 
+#define MSM_CAM_IOCTL_AF_CTRL   _IOR(MSM_CAM_IOCTL_MAGIC, 26, struct msm_ctrl_cmt_t *)
+#define MSM_CAM_IOCTL_AF_CTRL_DONE   _IOW(MSM_CAM_IOCTL_MAGIC, 27, struct msm_ctrl_cmt_t *)
+
 #define MAX_SENSOR_NUM 3
 #define MAX_SENSOR_NAME 32
 
@@ -144,6 +147,31 @@
 #define CMD_STATS_ENABLE 18
 #define UPDATE_STATS_INVALID 19
 
+#define CMD_STATS_AEC_ENABLE 20
+#define CMD_STATS_AWB_ENABLE 21
+#define CMD_STATS_AEC_AXI_CFG 22
+#define CMD_STATS_AWB_AXI_CFG 23
+#define CMD_STATS_RS_AXI_CFG 24
+#define CMD_STATS_CS_AXI_CFG 25
+#define CMD_STATS_IHIST_AXI_CFG 26
+#define CMD_STATS_SKIN_AXI_CFG 27
+#define CMD_STATS_AEC_BUF_RELEASE 28
+#define CMD_STATS_AWB_BUF_RELEASE 29
+#define CMD_STATS_RS_BUF_RELEASE 30
+#define CMD_STATS_CS_BUF_RELEASE 31
+#define CMD_STATS_IHIST_BUF_RELEASE 32
+#define CMD_STATS_SKIN_BUF_RELEASE 33
+
+#define CMD_AXI_CFG_SNAP_GEMINI 34
+#define CMD_AXI_CFG_SNAP 35
+#define CMD_AXI_CFG_PREVIEW 36
+#define CMD_AXI_CFG_VIDEO 37
+
+#define CMD_STATS_IHIST_ENABLE 38
+#define CMD_STATS_RS_ENABLE 39
+#define CMD_STATS_CS_ENABLE 40
+#define CMD_AXI_CFG_O1_AND_O2 41  
+
 struct msm_vfe_cfg_cmd {
  int cmd_type;
  uint16_t length;
@@ -163,12 +191,20 @@
 #define MSM_PMEM_RAW_MAINIMG 5
 #define MSM_PMEM_AEC_AWB 6
 #define MSM_PMEM_AF 7
-#define MSM_PMEM_MAX 8
+#define MSM_PMEM_AEC 8
+#define MSM_PMEM_AWB 9
+#define MSM_PMEM_RS 10
+#define MSM_PMEM_CS 11
+#define MSM_PMEM_IHIST 12
+#define MSM_PMEM_SKIN 13
+#define MSM_PMEM_VIDEO 14
+#define MSM_PMEM_PREVIEW 15
+#define MSM_PMEM_MAX 16
 
 #define FRAME_PREVIEW_OUTPUT1 0
 #define FRAME_PREVIEW_OUTPUT2 1
 #define FRAME_SNAPSHOT 2
-#define FRAME_THUMBAIL 3
+#define FRAME_THUMBNAIL 3
 #define FRAME_RAW_SNAPSHOT 4
 #define FRAME_MAX 5
 
@@ -197,12 +233,18 @@
 #define CAMIF_TO_AXI_VIA_OUTPUT_2 3
 #define OUTPUT_1_AND_CAMIF_TO_AXI_VIA_OUTPUT_2 4
 #define OUTPUT_2_AND_CAMIF_TO_AXI_VIA_OUTPUT_1 5
-#define LAST_AXI_OUTPUT_MODE_ENUM = OUTPUT_2_AND_CAMIF_TO_AXI_VIA_OUTPUT_1 6
+#define OUTPUT_1_AND_3 6
+#define LAST_AXI_OUTPUT_MODE_ENUM = OUTPUT_1_AND_3 7  
 
 #define MSM_FRAME_PREV_1 0
 #define MSM_FRAME_PREV_2 1
 #define MSM_FRAME_ENC 2
 
+#define OUTPUT_TYPE_P 1
+#define OUTPUT_TYPE_T 2
+#define OUTPUT_TYPE_S 3
+#define OUTPUT_TYPE_V 4
+
 struct msm_frame {
  int path;
  unsigned long buffer;
@@ -216,7 +258,13 @@
 
 #define STAT_AEAW 0
 #define STAT_AF 1
-#define STAT_MAX 2
+#define STAT_AEC 2
+#define STAT_AWB 3
+#define STAT_RS 4
+#define STAT_CS 5
+#define STAT_IHIST 6
+#define STAT_SKIN 7
+#define STAT_MAX 8
 
 struct msm_stats_buf {
  int type;
diff --git a/libc/netbsd/isc/ev_timers.c b/libc/netbsd/isc/ev_timers.c
index 9674687..a584f99 100644
--- a/libc/netbsd/isc/ev_timers.c
+++ b/libc/netbsd/isc/ev_timers.c
@@ -33,6 +33,7 @@
 /* Import. */
 
 #include <errno.h>
+#include <time.h>
 
 #include <isc/assertions.h>
 #include <isc/eventlib.h>
diff --git a/libc/netbsd/nameser/ns_ttl.c b/libc/netbsd/nameser/ns_ttl.c
index 0878194..cc98331 100644
--- a/libc/netbsd/nameser/ns_ttl.c
+++ b/libc/netbsd/nameser/ns_ttl.c
@@ -47,7 +47,7 @@
 
 /* Macros. */
 
-#define T(x) if ((x) < 0) return (-1); else
+#define T(x) do { if ((x) < 0) return (-1); } while(0)
 
 /* Public. */
 
diff --git a/libc/netbsd/net/base64.c b/libc/netbsd/net/base64.c
index 70caaf7..7270703 100644
--- a/libc/netbsd/net/base64.c
+++ b/libc/netbsd/net/base64.c
@@ -141,7 +141,7 @@
 	size_t targsize;
 {
 	size_t datalength = 0;
-	u_char input[3];
+	u_char input[3] = { 0, 0, 0 };  /* make compiler happy */
 	u_char output[4];
 	size_t i;
 
diff --git a/libc/netbsd/net/getaddrinfo.c b/libc/netbsd/net/getaddrinfo.c
index 51079ae..e7564c4 100644
--- a/libc/netbsd/net/getaddrinfo.c
+++ b/libc/netbsd/net/getaddrinfo.c
@@ -100,6 +100,12 @@
 #include <stdarg.h>
 #include "nsswitch.h"
 
+typedef union sockaddr_union {
+    struct sockaddr     generic;
+    struct sockaddr_in  in;
+    struct sockaddr_in6 in6;
+} sockaddr_union;
+
 #define SUCCESS 0
 #define ANY 0
 #define YES 1
@@ -349,13 +355,14 @@
 		{{{ 0x20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }}},
 		/* scope ID */
 		0};
-	static const struct sockaddr *sa_test = (struct sockaddr *) &sin6_test;
+        sockaddr_union addr_test;
+        addr_test.in6 = sin6_test;
 	int s = socket(PF_INET6, SOCK_DGRAM, IPPROTO_UDP);
 	if (s < 0)
 		return 0;
 	int ret;
 	do {
-		ret = connect(s, sa_test, sizeof(sin6_test));
+		ret = connect(s, &addr_test.generic, sizeof(addr_test.in6));
 	} while (ret < 0 && errno == EINTR);
 	int have_ipv6 = (ret == 0);
 	do {
@@ -1261,7 +1268,7 @@
 struct addrinfo_sort_elem {
 	struct addrinfo *ai;
 	int has_src_addr;
-	struct sockaddr_in6 src_addr;  /* Large enough to hold IPv4 or IPv6. */
+	sockaddr_union src_addr;
 	int original_order;
 };
 
@@ -1433,11 +1440,11 @@
 	}
 
 	/* Rule 2: Prefer matching scope. */
-	scope_src1 = _get_scope((const struct sockaddr *)&a1->src_addr);
+	scope_src1 = _get_scope(&a1->src_addr.generic);
 	scope_dst1 = _get_scope(a1->ai->ai_addr);
 	scope_match1 = (scope_src1 == scope_dst1);
 
-	scope_src2 = _get_scope((const struct sockaddr *)&a2->src_addr);
+	scope_src2 = _get_scope(&a2->src_addr.generic);
 	scope_dst2 = _get_scope(a2->ai->ai_addr);
 	scope_match2 = (scope_src2 == scope_dst2);
 
@@ -1456,11 +1463,11 @@
 	 */
 
 	/* Rule 5: Prefer matching label. */
-	label_src1 = _get_label((const struct sockaddr *)&a1->src_addr);
+	label_src1 = _get_label(&a1->src_addr.generic);
 	label_dst1 = _get_label(a1->ai->ai_addr);
 	label_match1 = (label_src1 == label_dst1);
 
-	label_src2 = _get_label((const struct sockaddr *)&a2->src_addr);
+	label_src2 = _get_label(&a2->src_addr.generic);
 	label_dst2 = _get_label(a2->ai->ai_addr);
 	label_match2 = (label_src2 == label_dst2);
 
@@ -1493,9 +1500,9 @@
 	 */
 	if (a1->has_src_addr && a1->ai->ai_addr->sa_family == AF_INET6 &&
 	    a2->has_src_addr && a2->ai->ai_addr->sa_family == AF_INET6) {
-		const struct sockaddr_in6 *a1_src = (const struct sockaddr_in6 *)&a1->src_addr;
+		const struct sockaddr_in6 *a1_src = &a1->src_addr.in6;
 		const struct sockaddr_in6 *a1_dst = (const struct sockaddr_in6 *)a1->ai->ai_addr;
-		const struct sockaddr_in6 *a2_src = (const struct sockaddr_in6 *)&a2->src_addr;
+		const struct sockaddr_in6 *a2_src = &a2->src_addr.in6;
 		const struct sockaddr_in6 *a2_dst = (const struct sockaddr_in6 *)a2->ai->ai_addr;
 		prefixlen1 = _common_prefix_len(&a1_src->sin6_addr, &a1_dst->sin6_addr);
 		prefixlen2 = _common_prefix_len(&a2_src->sin6_addr, &a2_dst->sin6_addr);
@@ -1600,7 +1607,7 @@
 		elems[i].ai = cur;
 		elems[i].original_order = i;
 
-		has_src_addr = _find_src_addr(cur->ai_addr, (struct sockaddr *)&elems[i].src_addr);
+		has_src_addr = _find_src_addr(cur->ai_addr, &elems[i].src_addr.generic);
 		if (has_src_addr == -1) {
 			goto error;
 		}
diff --git a/libc/netbsd/net/getnameinfo.c b/libc/netbsd/net/getnameinfo.c
index db04fbf..3666443 100644
--- a/libc/netbsd/net/getnameinfo.c
+++ b/libc/netbsd/net/getnameinfo.c
@@ -339,11 +339,14 @@
 	assert(addr != NULL);
 	assert(host != NULL);
 
+	if (hostlen < 0)
+		return EAI_OVERFLOW;
+
 	if (inet_ntop(AF_INET6, addr, numaddr, sizeof(numaddr)) == NULL)
 		return EAI_SYSTEM;
 
 	numaddrlen = strlen(numaddr);
-	if (numaddrlen + 1 > hostlen) /* don't forget terminator */
+	if (numaddrlen + 1 > (size_t)hostlen) /* don't forget terminator */
 		return EAI_OVERFLOW;
 	strlcpy(host, numaddr, hostlen);
 
@@ -356,7 +359,7 @@
 		    zonebuf, sizeof(zonebuf), flags);
 		if (zonelen < 0)
 			return EAI_OVERFLOW;
-		if ((size_t) zonelen + 1 + numaddrlen + 1 > hostlen)
+		if ((size_t) zonelen + 1 + numaddrlen + 1 > (size_t)hostlen)
 			return EAI_OVERFLOW;
 		/* construct <numeric-addr><delim><zoneid> */
 		memcpy(host + numaddrlen + 1, zonebuf,
diff --git a/libc/private/bionic_atomic_inline.h b/libc/private/bionic_atomic_inline.h
new file mode 100644
index 0000000..95766e1
--- /dev/null
+++ b/libc/private/bionic_atomic_inline.h
@@ -0,0 +1,107 @@
+/*
+ * Copyright (C) 2010 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_ATOMIC_INLINE_H
+#define BIONIC_ATOMIC_INLINE_H
+
+/*
+ * Inline declarations and macros for some special-purpose atomic
+ * operations.  These are intended for rare circumstances where a
+ * memory barrier needs to be issued inline rather than as a function
+ * call.
+ *
+ * Most code should not use these.
+ *
+ * Anything that does include this file must set ANDROID_SMP to either
+ * 0 or 1, indicating compilation for UP or SMP, respectively.
+ *
+ * Macros defined in this header:
+ *
+ * void ANDROID_MEMBAR_FULL(void)
+ *   Full memory barrier.  Provides a compiler reordering barrier, and
+ *   on SMP systems emits an appropriate instruction.
+ */
+
+#if !defined(ANDROID_SMP)
+# error "Must define ANDROID_SMP before including atomic-inline.h"
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * Define the full memory barrier for an SMP system.  This is
+ * platform-specific.
+ */
+
+#ifdef __arm__
+#include <machine/cpu-features.h>
+
+/*
+ * For ARMv6K we need to issue a specific MCR instead of the DMB, since
+ * that wasn't added until v7.  For anything older, SMP isn't relevant.
+ * Since we don't have an ARMv6K to test with, we're not going to deal
+ * with that now.
+ *
+ * The DMB instruction is found in the ARM and Thumb2 instruction sets.
+ * This will fail on plain 16-bit Thumb.
+ */
+#if defined(__ARM_HAVE_DMB)
+# define _ANDROID_MEMBAR_FULL_SMP() \
+    do { __asm__ __volatile__ ("dmb" ::: "memory"); } while (0)
+#else
+# define _ANDROID_MEMBAR_FULL_SMP()  ARM_SMP_defined_but_no_DMB()
+#endif
+
+#elif defined(__i386__) || defined(__x86_64__)
+/*
+ * For recent x86, we can use the SSE2 mfence instruction.
+ */
+# define _ANDROID_MEMBAR_FULL_SMP() \
+    do { __asm__ __volatile__ ("mfence" ::: "memory"); } while (0)
+
+#else
+/*
+ * Implementation not defined for this platform.  Hopefully we're building
+ * in uniprocessor mode.
+ */
+# define _ANDROID_MEMBAR_FULL_SMP()  SMP_barrier_not_defined_for_platform()
+#endif
+
+
+/*
+ * Full barrier.  On uniprocessors this is just a compiler reorder barrier,
+ * which ensures that the statements appearing above the barrier in the C/C++
+ * code will be issued after the statements appearing below the barrier.
+ *
+ * For SMP this also includes a memory barrier instruction.  On an ARM
+ * CPU this means that the current core will flush pending writes, wait
+ * for pending reads to complete, and discard any cached reads that could
+ * be stale.  Other CPUs may do less, but the end result is equivalent.
+ */
+#if ANDROID_SMP != 0
+# define ANDROID_MEMBAR_FULL() _ANDROID_MEMBAR_FULL_SMP()
+#else
+# define ANDROID_MEMBAR_FULL() \
+    do { __asm__ __volatile__ ("" ::: "memory"); } while (0)
+#endif
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+#endif // BIONIC_ATOMIC_INLINE_H
diff --git a/libc/private/bionic_futex.h b/libc/private/bionic_futex.h
new file mode 100644
index 0000000..eb49fb7
--- /dev/null
+++ b/libc/private/bionic_futex.h
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *  * Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *  * Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+#ifndef _BIONIC_FUTEX_H
+#define _BIONIC_FUTEX_H
+
+#include <linux/futex.h>
+
+extern int __futex_wait(volatile void *ftx, int val, const struct timespec *timeout);
+extern int __futex_wake(volatile void *ftx, int count);
+
+extern int __futex_syscall3(volatile void *ftx, int op, int val);
+extern int __futex_syscall4(volatile void *ftx, int op, int val, const struct timespec *timeout);
+
+#ifndef FUTEX_PRIVATE_FLAG
+#define FUTEX_PRIVATE_FLAG  128
+#endif
+
+#ifndef FUTEX_WAIT_PRIVATE
+#define FUTEX_WAIT_PRIVATE  (FUTEX_WAIT|FUTEX_PRIVATE_FLAG)
+#endif
+
+#ifndef FUTEX_WAKE_PRIVATE
+#define FUTEX_WAKE_PRIVATE  (FUTEX_WAKE|FUTEX_PRIVATE_FLAG)
+#endif
+
+/* Like __futex_wait/wake, but take an additionnal 'pshared' argument.
+ * when non-0, this will use normal futexes. Otherwise, private futexes.
+ */
+extern int  __futex_wake_ex(volatile void *ftx, int pshared, int val);
+extern int  __futex_wait_ex(volatile void *ftx, int pshared, int val, const struct timespec *timeout);
+
+#endif /* _BIONIC_FUTEX_H */
diff --git a/libc/private/bionic_tls.h b/libc/private/bionic_tls.h
index 2412577..008fd2f 100644
--- a/libc/private/bionic_tls.h
+++ b/libc/private/bionic_tls.h
@@ -88,22 +88,48 @@
 
 /* get the TLS */
 #ifdef __arm__
-/* Linux kernel helpers for its TLS implementation */
-/* For performance reasons, avoid calling the kernel helper
+/* The standard way to get the TLS is to call a kernel helper
+ * function (i.e. a function provided at a fixed address in a
+ * "magic page" mapped in all user-space address spaces ), which
+ * contains the most appropriate code path for the target device.
+ *
+ * However, for performance reasons, we're going to use our own
+ * machine code for the system's C shared library.
+ *
+ * We cannot use this optimization in the static version of the
+ * C library, because we don't know where the corresponding code
+ * is going to run.
+ */
+#  ifdef LIBC_STATIC
+
+/* Use the kernel helper in static C library. */
+  typedef volatile void* (__kernel_get_tls_t)(void);
+#    define __get_tls() (*(__kernel_get_tls_t *)0xffff0fe0)()
+
+#  else /* !LIBC_STATIC */
+/* Use optimized code path.
  * Note that HAVE_ARM_TLS_REGISTER is build-specific
  * (it must match your kernel configuration)
  */
-#  ifdef HAVE_ARM_TLS_REGISTER
-#    define __get_tls() \
+#    ifdef HAVE_ARM_TLS_REGISTER
+ /* We can read the address directly from a coprocessor
+  * register, which avoids touching the data cache
+  * completely.
+  */
+#      define __get_tls() \
     ({ register unsigned int __val asm("r0"); \
        asm ("mrc p15, 0, r0, c13, c0, 3" : "=r"(__val) ); \
        (volatile void*)__val; })
-#  else /* !HAVE_ARM_TLS_REGISTER */
-#    define __get_tls() ( *((volatile void **) 0xffff0ff0) )
-#  endif
-#else
+#    else /* !HAVE_ARM_TLS_REGISTER */
+ /* The kernel provides the address of the TLS at a fixed
+  * address of the magic page too.
+  */
+#      define __get_tls() ( *((volatile void **) 0xffff0ff0) )
+#    endif
+#  endif /* !LIBC_STATIC */
+#else /* !ARM */
 extern void*  __get_tls( void );
-#endif
+#endif /* !ARM */
 
 /* return the stack base and size, used by our malloc debugger */
 extern void*  __get_stack_base(int  *p_stack_size);
diff --git a/libc/private/cpuacct.h b/libc/private/cpuacct.h
new file mode 100644
index 0000000..8e24c8c
--- /dev/null
+++ b/libc/private/cpuacct.h
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *  * Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *  * Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef _BIONIC_CPUACCT_H
+#define _BIONIC_CPUACCT_H
+
+#include <sys/cdefs.h>
+#include <sys/types.h>
+
+__BEGIN_DECLS
+
+extern int cpuacct_add(uid_t uid);
+
+__END_DECLS
+
+#endif /* _BIONIC_CPUACCT_H */
diff --git a/libc/regex/engine.c b/libc/regex/engine.c
index 66be3c7..eae6ff2 100644
--- a/libc/regex/engine.c
+++ b/libc/regex/engine.c
@@ -209,7 +209,7 @@
 			STATETEARDOWN(m);
 			return(REG_ESPACE);
 		}
-		for (i = 1; i <= m->g->nsub; i++)
+		for (i = 1; i <= (int)m->g->nsub; i++)
 			m->pmatch[i].rm_so = m->pmatch[i].rm_eo = -1;
 		if (!g->backrefs && !(m->eflags&REG_BACKR)) {
 			NOTE("dissecting");
@@ -267,8 +267,8 @@
 	}
 	if (nmatch > 1) {
 		assert(m->pmatch != NULL);
-		for (i = 1; i < nmatch; i++)
-			if (i <= m->g->nsub)
+		for (i = 1; i < (ssize_t)nmatch; i++)
+			if (i <= (int)m->g->nsub)
 				pmatch[i] = m->pmatch[i];
 			else {
 				pmatch[i].rm_so = -1;
diff --git a/libc/regex/regcomp.c b/libc/regex/regcomp.c
index 5b632c8..19f4790 100644
--- a/libc/regex/regcomp.c
+++ b/libc/regex/regcomp.c
@@ -249,8 +249,8 @@
 p_ere(struct parse *p, int stop)	/* character this ERE should end at */
 {
 	char c;
-	sopno prevback;
-	sopno prevfwd;
+	sopno prevback = 0;
+	sopno prevfwd = 0;
 	sopno conc;
 	int first = 1;		/* is this the first alternative? */
 
@@ -767,7 +767,7 @@
 p_b_cclass(struct parse *p, cset *cs)
 {
 	char *sp = p->next;
-	struct cclass *cp;
+	const struct cclass *cp;
 	size_t len;
 	char *u;
 	char c;
@@ -831,7 +831,7 @@
     int endc)			/* name ended by endc,']' */
 {
 	char *sp = p->next;
-	struct cname *cp;
+	const struct cname *cp;
 	int len;
 
 	while (MORE() && !SEETWO(endc, ']'))
@@ -1084,7 +1084,7 @@
 	cset *top = &p->g->sets[p->g->ncsets];
 	size_t css = (size_t)p->g->csetsize;
 
-	for (i = 0; i < css; i++)
+	for (i = 0; i < (ssize_t)css; i++)
 		CHsub(cs, i);
 	if (cs == top-1)	/* recover only the easy case */
 		p->g->ncsets--;
@@ -1112,10 +1112,10 @@
 	for (cs2 = &p->g->sets[0]; cs2 < top; cs2++)
 		if (cs2->hash == h && cs2 != cs) {
 			/* maybe */
-			for (i = 0; i < css; i++)
+			for (i = 0; i < (ssize_t)css; i++)
 				if (!!CHIN(cs2, i) != !!CHIN(cs, i))
 					break;		/* no */
-			if (i == css)
+			if (i == (ssize_t)css)
 				break;			/* yes */
 		}
 
@@ -1136,7 +1136,7 @@
 	int i;
 	size_t css = (size_t)p->g->csetsize;
 
-	for (i = 0; i < css; i++)
+	for (i = 0; i < (ssize_t)css; i++)
 		if (CHIN(cs, i))
 			return((char)i);
 	assert(never);
@@ -1153,7 +1153,7 @@
 	size_t css = (size_t)p->g->csetsize;
 	int n = 0;
 
-	for (i = 0; i < css; i++)
+	for (i = 0; i < (ssize_t)css; i++)
 		if (CHIN(cs, i))
 			n++;
 	return(n);
@@ -1412,7 +1412,7 @@
 findmust(struct parse *p, struct re_guts *g)
 {
 	sop *scan;
-	sop *start;    /* start initialized in the default case, after that */
+	sop *start = NULL;    /* start initialized in the default case, after that */
 	sop *newstart; /* newstart was initialized in the OCHAR case */
 	sopno newlen;
 	sop s;
diff --git a/libc/regex/regerror.c b/libc/regex/regerror.c
index 894a939..838ec8f 100644
--- a/libc/regex/regerror.c
+++ b/libc/regex/regerror.c
@@ -78,7 +78,7 @@
 size_t
 regerror(int errcode, const regex_t *preg, char *errbuf, size_t errbuf_size)
 {
-	struct rerr *r;
+	const struct rerr *r;
 	size_t len;
 	int target = errcode &~ REG_ITOA;
 	char *s;
@@ -117,7 +117,7 @@
 static char *
 regatoi(const regex_t *preg, char *localbuf, int localbufsize)
 {
-	struct rerr *r;
+	const struct rerr *r;
 
 	for (r = rerrs; r->code != 0; r++)
 		if (strcmp(r->name, preg->re_endp) == 0)
diff --git a/libc/regex/regexec.c b/libc/regex/regexec.c
index 7b3bfc7..6feed3b 100644
--- a/libc/regex/regexec.c
+++ b/libc/regex/regexec.c
@@ -153,7 +153,7 @@
 		return(REG_BADPAT);
 	eflags = GOODFLAGS(eflags);
 
-	if (g->nstates <= CHAR_BIT*sizeof(states1) && !(eflags&REG_LARGE))
+	if (g->nstates <= (int)(CHAR_BIT*sizeof(states1)) && !(eflags&REG_LARGE))
 		return(smatcher(g, (char *)string, nmatch, pmatch, eflags));
 	else
 		return(lmatcher(g, (char *)string, nmatch, pmatch, eflags));
diff --git a/libc/stdlib/strntoumax.c b/libc/stdlib/strntoumax.c
index a151ef5..050d718 100644
--- a/libc/stdlib/strntoumax.c
+++ b/libc/stdlib/strntoumax.c
@@ -48,7 +48,7 @@
 uintmax_t
 strntoumax(const char *nptr, char **endptr, int base, size_t n)
 {
-    const unsigned char*  p   = nptr;
+    const unsigned char*  p   = (const unsigned char *)nptr;
     const unsigned char*  end = p + n;
     int                   minus = 0;
     uintmax_t             v = 0;
diff --git a/libc/stdlib/wchar.c b/libc/stdlib/wchar.c
index 02947d4..1480212 100644
--- a/libc/stdlib/wchar.c
+++ b/libc/stdlib/wchar.c
@@ -29,6 +29,7 @@
 #include <ctype.h>
 #include <string.h>
 #include <stdlib.h>
+#include <errno.h>
 
 /* stubs for wide-char functions */
 wint_t  btowc(int c)
@@ -71,28 +72,25 @@
 
 int vwprintf(const wchar_t *format, va_list arg)
 {
-    return vprintf((const char*)format, arg);
+    return vfwprintf(stdout, format, arg);
 }
 
 int vfwprintf(FILE *stream, const wchar_t *format, va_list arg)
 {
-    return vfprintf(stream, (const char*)format, arg);
+    errno = ENOTSUP;
+    return -1;
 }
 
 int vswprintf(wchar_t *s, size_t n, const wchar_t *format, va_list arg)
 {
-    return vsnprintf( (char*)s, n, (const char*)format, arg );
+    errno = ENOTSUP;
+    return -1;
 }
 
 int fwscanf(FILE *stream, const wchar_t *format, ... )
 {
-    va_list  args;
-    int      result;
-
-    va_start (args, format);
-    result = vfscanf( stream, (const char*)format, args );
-    va_end (args);
-    return result;
+    errno = ENOTSUP;
+    return -1;
 }
 
 int wscanf(const wchar_t *format, ... )
@@ -101,20 +99,15 @@
     int      result;
 
     va_start (args, format);
-    result = vscanf( (const char*)format, args );
+    result = fwscanf(stdout, format, args );
     va_end (args);
     return result;
 }
 
 int swscanf(const wchar_t *s, const wchar_t *format, ... )
 {
-    va_list  args;
-    int      result;
-
-    va_start (args, format);
-    result = vscanf( (const char*)format, args );
-    va_end (args);
-    return result;
+    errno = ENOTSUP;
+    return -1;
 }
 
 int iswalnum(wint_t wc) { return isalnum(wc); }
@@ -150,7 +143,7 @@
 
 wint_t fgetwc(FILE *stream)
 {
-    return fgetc(stream);
+    return (wint_t)fgetc(stream);
 }
 
 wchar_t *fgetws(wchar_t *ws, int n, FILE *stream)
@@ -264,71 +257,11 @@
     return 1;
 }
 
-wchar_t *wcscat(wchar_t *ws1, const wchar_t *ws2)
-{
-    return (wchar_t*) strcat((char*)ws1, (const char*)ws2);
-}
-
-wchar_t *wcschr(const wchar_t *ws, wchar_t wc)
-{
-    return (wchar_t*)strchr( (const char*)ws, (char)wc );
-}
-
-int wcscmp(const wchar_t *ws1, const wchar_t *ws2)
-{
-    return strcmp( (const char*)ws1, (const char*)ws2 );
-}
-
-int wcscoll(const wchar_t *ws1, const wchar_t *ws2)
-{
-    return strcmp( (const char*)ws1, (const char*)ws2 );
-}
-
-wchar_t *wcscpy(wchar_t *ws1, const wchar_t *ws2)
-{
-    return (wchar_t*) strcpy( (char*)ws1, (const char*)ws2 );
-}
-
-size_t wcscspn(const wchar_t *ws1, const wchar_t *ws2)
-{
-    return strspn( (const char*)ws1, (const char*)ws2 );
-}
-
-size_t wcslen(const wchar_t *ws)
-{
-    return (size_t)strlen( (const char*)ws );
-}
-
 size_t wcsftime(wchar_t *wcs, size_t maxsize, const wchar_t *format,  const struct tm *timptr)
 {
     return strftime( (char*)wcs, maxsize, (const char*)format, timptr );
 }
 
-wchar_t *wcsncat(wchar_t *ws1, const wchar_t *ws2, size_t n)
-{
-    return (wchar_t*) strncat( (char*)ws1, (const char*)ws2, n );
-}
-
-int wcsncmp(const wchar_t *ws1, const wchar_t *ws2, size_t n)
-{
-    return strncmp( (const char*)ws1, (const char*)ws2, n );
-}
-
-wchar_t *wcsncpy(wchar_t *ws1, const wchar_t *ws2, size_t n)
-{
-    return (wchar_t*) strncpy( (char*)ws1, (const char*)ws2, n );
-}
-
-wchar_t *wcspbrk(const wchar_t *ws1, const wchar_t *ws2)
-{
-    return (wchar_t*) strpbrk( (const char*)ws1, (const char*)ws2 );
-}
-
-wchar_t *wcsrchr(const wchar_t *ws, wchar_t wc)
-{
-    return (wchar_t*) strrchr( (const char*)ws, (int)wc );
-}
-
 size_t wcsrtombs(char *dst, const wchar_t **src, size_t len, mbstate_t *ps)
 {
     const char*  s = (const char*)*src;
@@ -349,26 +282,11 @@
     return wcsrtombs(dst, &src, len, NULL);
 }
 
-size_t wcsspn(const wchar_t *ws1, const wchar_t *ws2)
-{
-    return strspn( (const char*)ws1, (const char*)ws2 );
-}
-
-wchar_t *wcsstr(const wchar_t *ws1, const wchar_t *ws2)
-{
-    return (wchar_t*) strstr( (const char*)ws1, (const char*)ws2 );
-}
-
 double wcstod(const wchar_t *nptr, wchar_t **endptr)
 {
     return strtod( (const char*)nptr, (char**)endptr );
 }
 
-wchar_t *wcstok(wchar_t *ws1, const wchar_t *ws2, wchar_t **ptr)
-{
-    return (wchar_t*) strtok_r( (char*)ws1, (const char*)ws2, (char**)ptr );
-}
-
 long int wcstol(const wchar_t *nptr, wchar_t **endptr, int base)
 {
     return strtol( (const char*)nptr, (char**)endptr, base );
@@ -384,11 +302,6 @@
     return (wchar_t*) strstr( (const char*)ws1, (const char*)ws2 );
 }
 
-int wcswidth(const wchar_t *pwcs, size_t n)
-{
-    return  strnlen( (const char*)pwcs, n );
-}
-
 size_t wcsxfrm(wchar_t *ws1, const wchar_t *ws2, size_t n)
 {
     memcpy( (char*)ws1, (const char*)ws2, n );
@@ -421,28 +334,3 @@
 {
     return (wc > 0);
 }
-
-wchar_t *wmemchr(const wchar_t *ws, wchar_t wc, size_t n)
-{
-    return (wchar_t*)  memchr( (const char*)ws, (int)wc, n );
-}
-
-int wmemcmp(const wchar_t *ws1, const wchar_t *ws2, size_t n)
-{
-    return  memcmp( (const char*)ws1, (const char*)ws2, n );
-}
-
-wchar_t *wmemcpy(wchar_t *ws1, const wchar_t *ws2, size_t n)
-{
-    return (wchar_t*) memcpy( (char*)ws1, (const char*)ws2, n );
-}
-
-wchar_t *wmemmove(wchar_t *ws1, const wchar_t *ws2, size_t n)
-{
-    return (wchar_t*)memmove( (char*)ws1, (const char*)ws2, n );
-}
-
-wchar_t *wmemset(wchar_t *ws, wchar_t wc, size_t n)
-{
-    return (wchar_t*) memset( (char*)ws, (int)wc, n );
-}
diff --git a/libc/string/memccpy.c b/libc/string/memccpy.c
index 2689e80..789fde6 100644
--- a/libc/string/memccpy.c
+++ b/libc/string/memccpy.c
@@ -38,18 +38,9 @@
     for (;;) {
         if (ch == c || p >= p_end) break;
         *q++ = ch = *p++;
-
-        if (ch == c || p >= p_end) break;
-        *q++ = ch = *p++;
-
-        if (ch == c || p >= p_end) break;
-        *q++ = ch = *p++;
-
-        if (ch == c || p >= p_end) break;
-        *q++ = ch = *p++;
     }
 
-    if (p >= p_end)
+    if (p >= p_end && ch != c)
         return NULL;
 
     return q;
diff --git a/libc/string/memmove.c b/libc/string/memmove.c
index fcaf4ee..98ecfc9 100644
--- a/libc/string/memmove.c
+++ b/libc/string/memmove.c
@@ -31,7 +31,10 @@
 {
   const char *p = src;
   char *q = dst;
-  if (__builtin_expect(q < p, 1)) {
+  /* We can use the optimized memcpy if the destination is below the
+   * source (i.e. q < p), or if it is completely over it (i.e. q >= p+n).
+   */
+  if (__builtin_expect((q < p) || ((size_t)(q - p) >= n), 1)) {
     return memcpy(dst, src, n);
   } else {
 #define PRELOAD_DISTANCE 64
diff --git a/libc/tzcode/localtime.c b/libc/tzcode/localtime.c
index 83c1011..85a913e 100644
--- a/libc/tzcode/localtime.c
+++ b/libc/tzcode/localtime.c
@@ -389,7 +389,11 @@
     if (TYPE_INTEGRAL(time_t) &&
         TYPE_BIT(time_t) - TYPE_SIGNED(time_t) < SECSPERREPEAT_BITS)
             return 0;
+#if SECSPERREPEAT_BITS <= 32  /* to avoid compiler warning (condition is always false) */
         return (t1 - t0) == SECSPERREPEAT;
+#else
+        return 0;
+#endif
 }
 
 static int toint(unsigned char *s) {
diff --git a/libc/unistd/alarm.c b/libc/unistd/alarm.c
index 01863a4..53edea9 100644
--- a/libc/unistd/alarm.c
+++ b/libc/unistd/alarm.c
@@ -51,7 +51,11 @@
 	itp->it_value.tv_sec = secs;
 	itp->it_value.tv_usec = 0;
 	if (setitimer(ITIMER_REAL, itp, &oitv) < 0)
+#if 1 /* BIONIC: Same behaviour than GLibc for errors */
+		return 0;
+#else
 		return (-1);
+#endif
 	if (oitv.it_value.tv_usec)
 		oitv.it_value.tv_sec++;
 	return (oitv.it_value.tv_sec);
diff --git a/libc/unistd/eventfd.c b/libc/unistd/eventfd.c
new file mode 100644
index 0000000..a487043
--- /dev/null
+++ b/libc/unistd/eventfd.c
@@ -0,0 +1,25 @@
+#include <sys/eventfd.h>
+#include <unistd.h>
+
+/* We duplicate the GLibc error semantics, which are poorly defined
+ * if the read() or write() does not return the proper number of bytes.
+ */
+int eventfd_read(int fd, eventfd_t *counter)
+{
+    int ret = read(fd, counter, sizeof(*counter));
+
+    if (ret == sizeof(*counter))
+        return 0;
+
+    return -1;
+}
+
+int eventfd_write(int fd, eventfd_t counter)
+{
+    int ret = write(fd, &counter, sizeof(counter));
+
+    if (ret == sizeof(counter))
+        return 0;
+
+    return -1;
+}
diff --git a/libc/unistd/fstatfs.c b/libc/unistd/fstatfs.c
new file mode 100644
index 0000000..3d7c696
--- /dev/null
+++ b/libc/unistd/fstatfs.c
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *  * Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *  * Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+#include <sys/vfs.h>
+
+extern int __fstatfs64(int, size_t, struct statfs *);
+
+int fstatfs(int fd, struct statfs*  stat)
+{
+    return __fstatfs64(fd, sizeof(struct statfs), stat);
+}
diff --git a/libc/unistd/seteuid.c b/libc/unistd/seteuid.c
index dd94932..b3ea372 100644
--- a/libc/unistd/seteuid.c
+++ b/libc/unistd/seteuid.c
@@ -26,6 +26,9 @@
  * SUCH DAMAGE.
  */
 #include <unistd.h>
+#include "cpuacct.h"
+
+extern int __setresuid(uid_t, uid_t, uid_t);
 
 int seteuid(uid_t euid)
 {
diff --git a/libc/unistd/setresuid.c b/libc/unistd/setresuid.c
index 1964881..e62b3e9 100644
--- a/libc/unistd/setresuid.c
+++ b/libc/unistd/setresuid.c
@@ -26,6 +26,9 @@
  * SUCH DAMAGE.
  */
 #include <unistd.h>
+#include "cpuacct.h"
+
+extern int __setresuid(uid_t ruid, uid_t euid, uid_t suid);
 
 int setresuid(uid_t ruid, uid_t euid, uid_t suid)
 {
diff --git a/libc/unistd/setreuid.c b/libc/unistd/setreuid.c
index 04c2826..32e70c8 100644
--- a/libc/unistd/setreuid.c
+++ b/libc/unistd/setreuid.c
@@ -26,6 +26,9 @@
  * SUCH DAMAGE.
  */
 #include <unistd.h>
+#include "cpuacct.h"
+
+extern int __setreuid(uid_t ruid, uid_t euid);
 
 int setreuid(uid_t ruid, uid_t euid)
 {
diff --git a/libc/unistd/setuid.c b/libc/unistd/setuid.c
index 8ab637d..30785d6 100644
--- a/libc/unistd/setuid.c
+++ b/libc/unistd/setuid.c
@@ -26,6 +26,9 @@
  * SUCH DAMAGE.
  */
 #include <unistd.h>
+#include "cpuacct.h"
+
+extern int __setuid(uid_t);
 
 int setuid(uid_t uid)
 {
diff --git a/libc/unistd/sysconf.c b/libc/unistd/sysconf.c
index dedc5bc..9377802 100644
--- a/libc/unistd/sysconf.c
+++ b/libc/unistd/sysconf.c
@@ -44,7 +44,7 @@
 #define  SYSTEM_MQ_OPEN_MAX     8
 #define  SYSTEM_MQ_PRIO_MAX     32768
 #define  SYSTEM_SEM_NSEMS_MAX   256
-#define  SYSTEM_SEM_VALUE_MAX   (2147483647)
+#define  SYSTEM_SEM_VALUE_MAX   0x3fffffff  /* see bionic/semaphore.c */
 #define  SYSTEM_SIGQUEUE_MAX    32
 #define  SYSTEM_TIMER_MAX       32
 #define  SYSTEM_LOGIN_NAME_MAX  256
@@ -96,7 +96,7 @@
     case _SC_COLL_WEIGHTS_MAX:  return _POSIX2_COLL_WEIGHTS_MASK;
 #endif
 #ifdef _POSIX2_EXPR_NEST_MAX
-    case _SC_EXPR_NEXT_MASK:    return _POSIX2_EXPR_NEST_MAX;
+    case _SC_EXPR_NEST_MAX:    return _POSIX2_EXPR_NEST_MAX;
 #endif
 #ifdef _POSIX2_LINE_MAX
     case _SC_LINE_MAX:          return _POSIX2_LINE_MAX;
diff --git a/libc/unistd/wait.c b/libc/unistd/wait.c
index d172419..f1db086 100644
--- a/libc/unistd/wait.c
+++ b/libc/unistd/wait.c
@@ -29,6 +29,7 @@
 #include <stddef.h>
 
 extern pid_t  __wait4 (pid_t pid, int *status, int options, struct rusage *rusage);
+extern int    __waitid(idtype_t which, id_t id, siginfo_t *info, int options, struct rusage *ru);
 
 pid_t  wait( int*  status )
 {
@@ -44,3 +45,9 @@
 {
     return __wait4( pid, status, options, NULL );
 }
+
+int  waitid(idtype_t which, id_t id, siginfo_t *info, int options)
+{
+    /* the system call takes an option struct rusage that we don't need */
+    return __waitid(which, id, info, options, NULL);
+}
diff --git a/libc/wchar/wcpcpy.c b/libc/wchar/wcpcpy.c
new file mode 100644
index 0000000..df63d72
--- /dev/null
+++ b/libc/wchar/wcpcpy.c
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 1999
+ *	David E. O'Brien
+ * Copyright (c) 1988, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)strcpy.c	8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <wchar.h>
+
+wchar_t *
+wcpcpy(wchar_t * __restrict to, const wchar_t * __restrict from)
+{
+
+	for (; (*to = *from); ++from, ++to);
+	return(to);
+}
diff --git a/libc/wchar/wcpncpy.c b/libc/wchar/wcpncpy.c
new file mode 100644
index 0000000..87b361c
--- /dev/null
+++ b/libc/wchar/wcpncpy.c
@@ -0,0 +1,45 @@
+/*-
+ * Copyright (c) 2009 David Schultz <das@FreeBSD.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <wchar.h>
+
+wchar_t *
+wcpncpy(wchar_t * __restrict dst, const wchar_t * __restrict src, size_t n)
+{
+
+	for (; n--; dst++, src++) {
+		if (!(*dst = *src)) {
+			wchar_t *ret = dst;
+			while (n--)
+				*++dst = L'\0';
+			return (ret);
+		}
+	}
+	return (dst);
+}
diff --git a/libc/wchar/wcscasecmp.c b/libc/wchar/wcscasecmp.c
new file mode 100644
index 0000000..0143543
--- /dev/null
+++ b/libc/wchar/wcscasecmp.c
@@ -0,0 +1,45 @@
+/*-
+ * Copyright (c) 2009 David Schultz <das@FreeBSD.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <wchar.h>
+#include <wctype.h>
+
+int
+wcscasecmp(const wchar_t *s1, const wchar_t *s2)
+{
+	wchar_t c1, c2;
+
+	for (; *s1; s1++, s2++) {
+		c1 = towlower(*s1);
+		c2 = towlower(*s2);
+		if (c1 != c2)
+			return ((int)c1 - c2);
+	}
+	return (-*s2);
+}
diff --git a/libc/wchar/wcscat.c b/libc/wchar/wcscat.c
new file mode 100644
index 0000000..7ae4e80
--- /dev/null
+++ b/libc/wchar/wcscat.c
@@ -0,0 +1,51 @@
+/*-
+ * Copyright (c)1999 Citrus Project,
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ *	citrus Id: wcscat.c,v 1.1 1999/12/29 21:47:45 tshiozak Exp
+ */
+
+#include <sys/cdefs.h>
+#if 0
+#if defined(LIBC_SCCS) && !defined(lint)
+__RCSID("$NetBSD: wcscat.c,v 1.1 2000/12/23 23:14:36 itojun Exp $");
+#endif /* LIBC_SCCS and not lint */
+#endif
+__FBSDID("$FreeBSD$");
+
+#include <wchar.h>
+
+wchar_t *
+wcscat(wchar_t * __restrict s1, const wchar_t * __restrict s2)
+{
+	wchar_t *cp;
+
+	cp = s1;
+	while (*cp != L'\0')
+		cp++;
+	while ((*cp++ = *s2++) != L'\0')
+		;
+
+	return (s1);
+}
diff --git a/libc/wchar/wcschr.c b/libc/wchar/wcschr.c
new file mode 100644
index 0000000..1df1fe6
--- /dev/null
+++ b/libc/wchar/wcschr.c
@@ -0,0 +1,41 @@
+/*-
+ * Copyright (c) 2002 Tim J. Robbins
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <wchar.h>
+
+wchar_t *
+wcschr(const wchar_t *s, wchar_t c)
+{
+
+	while (*s != c && *s != L'\0')
+		s++;
+	if (*s == c)
+		return ((wchar_t *)s);
+	return (NULL);
+}
diff --git a/libc/wchar/wcscmp.c b/libc/wchar/wcscmp.c
new file mode 100644
index 0000000..2d48914
--- /dev/null
+++ b/libc/wchar/wcscmp.c
@@ -0,0 +1,56 @@
+/*-
+ * 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.
+ * 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.
+ */
+
+#include <sys/cdefs.h>
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)strcmp.c	8.1 (Berkeley) 6/4/93";
+#if 0
+__RCSID("$NetBSD: wcscmp.c,v 1.3 2001/01/05 12:13:12 itojun Exp $");
+#endif
+#endif /* LIBC_SCCS and not lint */
+__FBSDID("$FreeBSD$");
+
+#include <wchar.h>
+
+/*
+ * Compare strings.
+ */
+int
+wcscmp(const wchar_t *s1, const wchar_t *s2)
+{
+
+	while (*s1 == *s2++)
+		if (*s1++ == '\0')
+			return (0);
+	/* XXX assumes wchar_t = int */
+	return (*(const unsigned int *)s1 - *(const unsigned int *)--s2);
+}
diff --git a/libc/wchar/wcscoll.c b/libc/wchar/wcscoll.c
new file mode 100644
index 0000000..6e843b7
--- /dev/null
+++ b/libc/wchar/wcscoll.c
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *  * Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *  * Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+#include <wchar.h>
+/*
+ * Compare strings using the current locale.  Since Bionic really does not
+ * support locales, we assume we always use the C locale and call wcscmp.
+ *
+ * This function is provided to make libstdc++-v3 usable.
+ */
+int
+wcscoll(const wchar_t *ws1, const wchar_t *ws2)
+{
+    return wcscmp(ws1, ws2);
+}
diff --git a/libc/wchar/wcscpy.c b/libc/wchar/wcscpy.c
new file mode 100644
index 0000000..0c6e1f2
--- /dev/null
+++ b/libc/wchar/wcscpy.c
@@ -0,0 +1,49 @@
+/*-
+ * Copyright (c)1999 Citrus Project,
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ *	citrus Id: wcscpy.c,v 1.2 2000/12/21 04:51:09 itojun Exp
+ */
+
+#include <sys/cdefs.h>
+#if 0
+#if defined(LIBC_SCCS) && !defined(lint)
+__RCSID("$NetBSD: wcscpy.c,v 1.1 2000/12/23 23:14:36 itojun Exp $");
+#endif /* LIBC_SCCS and not lint */
+#endif
+__FBSDID("$FreeBSD$");
+
+#include <wchar.h>
+
+wchar_t *
+wcscpy(wchar_t * __restrict s1, const wchar_t * __restrict s2)
+{
+	wchar_t *cp;
+
+	cp = s1;
+	while ((*cp++ = *s2++) != L'\0')
+		;
+
+	return (s1);
+}
diff --git a/libc/wchar/wcscspn.c b/libc/wchar/wcscspn.c
new file mode 100644
index 0000000..7729dc8
--- /dev/null
+++ b/libc/wchar/wcscspn.c
@@ -0,0 +1,58 @@
+/*-
+ * Copyright (c)1999 Citrus Project,
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ *	citrus Id: wcscspn.c,v 1.1 1999/12/29 21:47:45 tshiozak Exp
+ */
+
+#include <sys/cdefs.h>
+#if 0
+#if defined(LIBC_SCCS) && !defined(lint)
+__RCSID("$NetBSD: wcscspn.c,v 1.1 2000/12/23 23:14:36 itojun Exp $");
+#endif /* LIBC_SCCS and not lint */
+#endif
+__FBSDID("$FreeBSD$");
+
+#include <wchar.h>
+
+size_t
+wcscspn(const wchar_t *s, const wchar_t *set)
+{
+	const wchar_t *p;
+	const wchar_t *q;
+
+	p = s;
+	while (*p) {
+		q = set;
+		while (*q) {
+			if (*p == *q)
+				goto done;
+			q++;
+		}
+		p++;
+	}
+
+done:
+	return (p - s);
+}
diff --git a/libc/wchar/wcsdup.c b/libc/wchar/wcsdup.c
new file mode 100644
index 0000000..1e5db92
--- /dev/null
+++ b/libc/wchar/wcsdup.c
@@ -0,0 +1,43 @@
+/*-
+ * Copyright (c) 2005 Tim J. Robbins.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <stdlib.h>
+#include <wchar.h>
+
+wchar_t *
+wcsdup(const wchar_t *s)
+{
+	wchar_t *copy;
+	size_t len;
+
+	len = wcslen(s) + 1;
+	if ((copy = malloc(len * sizeof(wchar_t))) == NULL)
+		return (NULL);
+	return (wmemcpy(copy, s, len));
+}
diff --git a/libc/wchar/wcslcat.c b/libc/wchar/wcslcat.c
new file mode 100644
index 0000000..f5f1e1e
--- /dev/null
+++ b/libc/wchar/wcslcat.c
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 1998 Todd C. Miller <Todd.Miller@courtesan.com>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
+ * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *	from OpenBSD: strlcat.c,v 1.3 2000/11/24 11:10:02 itojun Exp
+ */
+
+#include <sys/cdefs.h>
+#if 0
+#if defined(LIBC_SCCS) && !defined(lint)
+__RCSID("$NetBSD: wcslcat.c,v 1.1 2000/12/23 23:14:36 itojun Exp $");
+#endif /* LIBC_SCCS and not lint */
+#endif
+__FBSDID("$FreeBSD$");
+
+#include <sys/types.h>
+#include <wchar.h>
+
+/*
+ * Appends src to string dst of size siz (unlike wcsncat, siz is the
+ * full size of dst, not space left).  At most siz-1 characters
+ * will be copied.  Always NUL terminates (unless siz == 0).
+ * Returns wcslen(initial dst) + wcslen(src); if retval >= siz,
+ * truncation occurred.
+ */
+size_t
+wcslcat(wchar_t *dst, const wchar_t *src, size_t siz)
+{
+	wchar_t *d = dst;
+	const wchar_t *s = src;
+	size_t n = siz;
+	size_t dlen;
+
+	/* Find the end of dst and adjust bytes left but don't go past end */
+	while (*d != '\0' && n-- != 0)
+		d++;
+	dlen = d - dst;
+	n = siz - dlen;
+
+	if (n == 0)
+		return(dlen + wcslen(s));
+	while (*s != '\0') {
+		if (n != 1) {
+			*d++ = *s;
+			n--;
+		}
+		s++;
+	}
+	*d = '\0';
+
+	return(dlen + (s - src));	/* count does not include NUL */
+}
diff --git a/libc/wchar/wcslcpy.c b/libc/wchar/wcslcpy.c
new file mode 100644
index 0000000..b104a06
--- /dev/null
+++ b/libc/wchar/wcslcpy.c
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 1998 Todd C. Miller <Todd.Miller@courtesan.com>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
+ * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *	from OpenBSD: strlcpy.c,v 1.4 1999/05/01 18:56:41 millert Exp
+ */
+
+#include <sys/cdefs.h>
+#if 0
+#if defined(LIBC_SCCS) && !defined(lint)
+__RCSID("$NetBSD: wcslcpy.c,v 1.1 2000/12/23 23:14:36 itojun Exp $");
+#endif /* LIBC_SCCS and not lint */
+#endif
+__FBSDID("$FreeBSD$");
+
+#include <sys/types.h>
+#include <wchar.h>
+
+/*
+ * Copy src to string dst of size siz.  At most siz-1 characters
+ * will be copied.  Always NUL terminates (unless siz == 0).
+ * Returns wcslen(src); if retval >= siz, truncation occurred.
+ */
+size_t
+wcslcpy(wchar_t *dst, const wchar_t *src, size_t siz)
+{
+	wchar_t *d = dst;
+	const wchar_t *s = src;
+	size_t n = siz;
+
+	/* Copy as many bytes as will fit */
+	if (n != 0 && --n != 0) {
+		do {
+			if ((*d++ = *s++) == 0)
+				break;
+		} while (--n != 0);
+	}
+
+	/* Not enough room in dst, add NUL and traverse rest of src */
+	if (n == 0) {
+		if (siz != 0)
+			*d = '\0';		/* NUL-terminate dst */
+		while (*s++)
+			;
+	}
+
+	return(s - src - 1);	/* count does not include NUL */
+}
diff --git a/libc/wchar/wcslen.c b/libc/wchar/wcslen.c
new file mode 100644
index 0000000..ca3004e
--- /dev/null
+++ b/libc/wchar/wcslen.c
@@ -0,0 +1,49 @@
+/*-
+ * Copyright (c)1999 Citrus Project,
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ *	citrus Id: wcslen.c,v 1.1 1999/12/29 21:47:45 tshiozak Exp
+ */
+
+#include <sys/cdefs.h>
+#if 0
+#if defined(LIBC_SCCS) && !defined(lint)
+__RCSID("$NetBSD: wcslen.c,v 1.1 2000/12/23 23:14:36 itojun Exp $");
+#endif /* LIBC_SCCS and not lint */
+#endif
+__FBSDID("$FreeBSD$");
+
+#include <wchar.h>
+
+size_t
+wcslen(const wchar_t *s)
+{
+	const wchar_t *p;
+
+	p = s;
+	while (*p)
+		p++;
+
+	return p - s;
+}
diff --git a/libc/wchar/wcsncasecmp.c b/libc/wchar/wcsncasecmp.c
new file mode 100644
index 0000000..a42d98c
--- /dev/null
+++ b/libc/wchar/wcsncasecmp.c
@@ -0,0 +1,49 @@
+/*-
+ * Copyright (c) 2009 David Schultz <das@FreeBSD.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <wchar.h>
+#include <wctype.h>
+
+int
+wcsncasecmp(const wchar_t *s1, const wchar_t *s2, size_t n)
+{
+	wchar_t c1, c2;
+
+	if (n == 0)
+		return (0);
+	for (; *s1; s1++, s2++) {
+		c1 = towlower(*s1);
+		c2 = towlower(*s2);
+		if (c1 != c2)
+			return ((int)c1 - c2);
+		if (--n == 0)
+			return (0);
+	}
+	return (-*s2);
+}
diff --git a/libc/wchar/wcsncat.c b/libc/wchar/wcsncat.c
new file mode 100644
index 0000000..44f1ff9
--- /dev/null
+++ b/libc/wchar/wcsncat.c
@@ -0,0 +1,57 @@
+/*-
+ * Copyright (c)1999 Citrus Project,
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ *	citrus Id: wcsncat.c,v 1.1 1999/12/29 21:47:45 tshiozak Exp
+ */
+
+#include <sys/cdefs.h>
+#if 0
+#if defined(LIBC_SCCS) && !defined(lint)
+__RCSID("$NetBSD: wcsncat.c,v 1.1 2000/12/23 23:14:36 itojun Exp $");
+#endif /* LIBC_SCCS and not lint */
+#endif
+__FBSDID("$FreeBSD$");
+
+#include <wchar.h>
+
+wchar_t *
+wcsncat(wchar_t * __restrict s1, const wchar_t * __restrict s2, size_t n)
+{
+	wchar_t *p;
+	wchar_t *q;
+	const wchar_t *r;
+
+	p = s1;
+	while (*p)
+		p++;
+	q = p;
+	r = s2;
+	while (*r && n) {
+		*q++ = *r++;
+		n--;
+	}
+	*q = '\0';
+	return s1;
+}
diff --git a/libc/wchar/wcsncmp.c b/libc/wchar/wcsncmp.c
new file mode 100644
index 0000000..86d7a51
--- /dev/null
+++ b/libc/wchar/wcsncmp.c
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 1989, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 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.
+ */
+
+#include <sys/cdefs.h>
+#if 0
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)strncmp.c	8.1 (Berkeley) 6/4/93";
+__RCSID("$NetBSD: wcsncmp.c,v 1.3 2001/01/05 12:13:13 itojun Exp $");
+#endif /* LIBC_SCCS and not lint */
+#endif
+__FBSDID("$FreeBSD$");
+
+#include <wchar.h>
+
+int
+wcsncmp(const wchar_t *s1, const wchar_t *s2, size_t n)
+{
+
+	if (n == 0)
+		return (0);
+	do {
+		if (*s1 != *s2++) {
+			/* XXX assumes wchar_t = int */
+			return (*(const unsigned int *)s1 -
+			    *(const unsigned int *)--s2);
+		}
+		if (*s1++ == 0)
+			break;
+	} while (--n != 0);
+	return (0);
+}
diff --git a/libc/wchar/wcsncpy.c b/libc/wchar/wcsncpy.c
new file mode 100644
index 0000000..00d986b
--- /dev/null
+++ b/libc/wchar/wcsncpy.c
@@ -0,0 +1,64 @@
+/*-
+ * 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.
+ * 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 0
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)strncpy.c	8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+#endif
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <wchar.h>
+
+/*
+ * Copy src to dst, truncating or null-padding to always copy n bytes.
+ * Return dst.
+ */
+wchar_t *
+wcsncpy(wchar_t * __restrict dst, const wchar_t * __restrict src, size_t n)
+{
+	if (n != 0) {
+		wchar_t *d = dst;
+		const wchar_t *s = src;
+
+		do {
+			if ((*d++ = *s++) == L'\0') {
+				/* NUL pad the remaining n-1 bytes */
+				while (--n != 0)
+					*d++ = L'\0';
+				break;
+			}
+		} while (--n != 0);
+	}
+	return (dst);
+}
diff --git a/libc/wchar/wcsnlen.c b/libc/wchar/wcsnlen.c
new file mode 100644
index 0000000..f03cf76
--- /dev/null
+++ b/libc/wchar/wcsnlen.c
@@ -0,0 +1,42 @@
+/*-
+ * Copyright (c) 2009 David Schultz <das@FreeBSD.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <wchar.h>
+
+size_t
+wcsnlen(const wchar_t *s, size_t maxlen)
+{
+	size_t len;
+
+	for (len = 0; len < maxlen; len++, s++) {
+		if (!*s)
+			break;
+	}
+	return (len);
+}
diff --git a/libc/wchar/wcspbrk.c b/libc/wchar/wcspbrk.c
new file mode 100644
index 0000000..2ff71ba
--- /dev/null
+++ b/libc/wchar/wcspbrk.c
@@ -0,0 +1,58 @@
+/*-
+ * Copyright (c)1999 Citrus Project,
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ *	citrus Id: wcspbrk.c,v 1.2 2000/12/21 05:07:25 itojun Exp
+ */
+
+#include <sys/cdefs.h>
+#if 0
+#if defined(LIBC_SCCS) && !defined(lint)
+__RCSID("$NetBSD: wcspbrk.c,v 1.1 2000/12/23 23:14:37 itojun Exp $");
+#endif /* LIBC_SCCS and not lint */
+#endif
+__FBSDID("$FreeBSD$");
+
+#include <wchar.h>
+
+wchar_t *
+wcspbrk(const wchar_t *s, const wchar_t *set)
+{
+	const wchar_t *p;
+	const wchar_t *q;
+
+	p = s;
+	while (*p) {
+		q = set;
+		while (*q) {
+			if (*p == *q) {
+				/* LINTED interface specification */
+				return (wchar_t *)p;
+			}
+			q++;
+		}
+		p++;
+	}
+	return NULL;
+}
diff --git a/libc/wchar/wcsrchr.c b/libc/wchar/wcsrchr.c
new file mode 100644
index 0000000..37c81ec
--- /dev/null
+++ b/libc/wchar/wcsrchr.c
@@ -0,0 +1,47 @@
+/*-
+ * Copyright (c) 2002 Tim J. Robbins
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <wchar.h>
+
+wchar_t *
+wcsrchr(const wchar_t *s, wchar_t c)
+{
+	const wchar_t *last;
+
+	last = NULL;
+	for (;;) {
+		if (*s == c)
+			last = s;
+		if (*s == L'\0')
+			break;
+		s++;
+	}
+
+	return ((wchar_t *)last);
+}
diff --git a/libc/wchar/wcsspn.c b/libc/wchar/wcsspn.c
new file mode 100644
index 0000000..6569206
--- /dev/null
+++ b/libc/wchar/wcsspn.c
@@ -0,0 +1,60 @@
+/*-
+ * Copyright (c)1999 Citrus Project,
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ *	citrus Id: wcsspn.c,v 1.1 1999/12/29 21:47:45 tshiozak Exp
+ */
+
+#include <sys/cdefs.h>
+#if 0
+#if defined(LIBC_SCCS) && !defined(lint)
+__RCSID("$NetBSD: wcsspn.c,v 1.1 2000/12/23 23:14:37 itojun Exp $");
+#endif /* LIBC_SCCS and not lint */
+#endif
+__FBSDID("$FreeBSD$");
+
+#include <wchar.h>
+
+size_t
+wcsspn(const wchar_t *s, const wchar_t *set)
+{
+	const wchar_t *p;
+	const wchar_t *q;
+
+	p = s;
+	while (*p) {
+		q = set;
+		while (*q) {
+			if (*p == *q)
+				break;
+			q++;
+		}
+		if (!*q)
+			goto done;
+		p++;
+	}
+
+done:
+	return (p - s);
+}
diff --git a/libc/wchar/wcsstr.c b/libc/wchar/wcsstr.c
new file mode 100644
index 0000000..a9dc27b
--- /dev/null
+++ b/libc/wchar/wcsstr.c
@@ -0,0 +1,63 @@
+/*-
+ * 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.
+ * 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 0
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)strstr.c	8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+#endif
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <wchar.h>
+
+/*
+ * Find the first occurrence of find in s.
+ */
+wchar_t *
+wcsstr(const wchar_t * __restrict s, const wchar_t * __restrict find)
+{
+	wchar_t c, sc;
+	size_t len;
+
+	if ((c = *find++) != L'\0') {
+		len = wcslen(find);
+		do {
+			do {
+				if ((sc = *s++) == L'\0')
+					return (NULL);
+			} while (sc != c);
+		} while (wcsncmp(s, find, len) != 0);
+		s--;
+	}
+	return ((wchar_t *)s);
+}
diff --git a/libc/wchar/wcstok.c b/libc/wchar/wcstok.c
new file mode 100644
index 0000000..5a77117
--- /dev/null
+++ b/libc/wchar/wcstok.c
@@ -0,0 +1,86 @@
+/*-
+ * Copyright (c) 1998 Softweyr LLC.  All rights reserved.
+ *
+ * strtok_r, from Berkeley strtok
+ * Oct 13, 1998 by Wes Peters <wes@softweyr.com>
+ *
+ * Copyright (c) 1988, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notices, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notices, 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 SOFTWEYR LLC, 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 SOFTWEYR LLC, THE
+ * REGENTS, OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <wchar.h>
+
+wchar_t *
+wcstok(wchar_t * __restrict s, const wchar_t * __restrict delim,
+    wchar_t ** __restrict last)
+{
+	const wchar_t *spanp;
+	wchar_t *tok;
+	wchar_t c, sc;
+
+	if (s == NULL && (s = *last) == NULL)
+		return (NULL);
+
+	/*
+	 * Skip (span) leading delimiters (s += wcsspn(s, delim), sort of).
+	 */
+cont:
+	c = *s++;
+	for (spanp = delim; (sc = *spanp++) != L'\0';) {
+		if (c == sc)
+			goto cont;
+	}
+
+	if (c == L'\0') {	/* no non-delimiter characters */
+		*last = NULL;
+		return (NULL);
+	}
+	tok = s - 1;
+
+	/*
+	 * Scan token (scan for delimiters: s += wcscspn(s, delim), sort of).
+	 * Note that delim must have one NUL; we stop if we see that, too.
+	 */
+	for (;;) {
+		c = *s++;
+		spanp = delim;
+		do {
+			if ((sc = *spanp++) == c) {
+				if (c == L'\0')
+					s = NULL;
+				else
+					s[-1] = L'\0';
+				*last = s;
+				return (tok);
+			}
+		} while (sc != L'\0');
+	}
+	/* NOTREACHED */
+}
diff --git a/libc/wchar/wcswidth.c b/libc/wchar/wcswidth.c
new file mode 100644
index 0000000..b142074
--- /dev/null
+++ b/libc/wchar/wcswidth.c
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 1989, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ * (c) UNIX System Laboratories, Inc.
+ * All or some portions of this file are derived from material licensed
+ * to the University of California by American Telephone and Telegraph
+ * Co. or Unix System Laboratories, Inc. and are reproduced herein with
+ * the permission of UNIX System Laboratories, Inc.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Paul Borman at Krystal Technologies.
+ *
+ * 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.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <wchar.h>
+
+int
+wcswidth(const wchar_t *pwcs, size_t n)
+{
+	wchar_t wc;
+	int len, l;
+
+	len = 0;
+	while (n-- > 0 && (wc = *pwcs++) != L'\0') {
+		if ((l = wcwidth(wc)) < 0)
+			return (-1);
+		len += l;
+	}
+	return (len);
+}
+
diff --git a/libc/wchar/wcsxfrm.c b/libc/wchar/wcsxfrm.c
new file mode 100644
index 0000000..042ea56
--- /dev/null
+++ b/libc/wchar/wcsxfrm.c
@@ -0,0 +1,57 @@
+/*-
+ * Copyright (c) 1995 Alex Tatmanjants <alex@elvisti.kiev.ua>
+ *		at Electronni Visti IA, Kiev, Ukraine.
+ *			All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <wchar.h>
+
+/*
+ * Placeholder wcsxfrm() implementation. See wcscoll.c for a description of
+ * the logic used.
+ */
+size_t
+wcsxfrm(wchar_t * __restrict dest, const wchar_t * __restrict src, size_t len)
+{
+    int prim, sec, l;
+    size_t slen;
+    char *mbsrc, *s, *ss;
+
+    if (*src == L'\0') {
+        if (len != 0)
+            *dest = L'\0';
+        return (0);
+    }
+
+    slen = wcslen(src);
+    if (len > 0) {
+        if (slen < len)
+            wcscpy(dest, src);
+        else {
+            wcsncpy(dest, src, len - 1);
+            dest[len - 1] = L'\0';
+        }
+    }
+    return (slen);
+}
diff --git a/libc/wchar/wmemchr.c b/libc/wchar/wmemchr.c
new file mode 100644
index 0000000..cab89c9
--- /dev/null
+++ b/libc/wchar/wmemchr.c
@@ -0,0 +1,52 @@
+/*-
+ * Copyright (c)1999 Citrus Project,
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ *	citrus Id: wmemchr.c,v 1.2 2000/12/20 14:08:31 itojun Exp
+ */
+
+#include <sys/cdefs.h>
+#if 0
+#if defined(LIBC_SCCS) && !defined(lint)
+__RCSID("$NetBSD: wmemchr.c,v 1.1 2000/12/23 23:14:37 itojun Exp $");
+#endif /* LIBC_SCCS and not lint */
+#endif
+__FBSDID("$FreeBSD$");
+
+#include <wchar.h>
+
+wchar_t	*
+wmemchr(const wchar_t *s, wchar_t c, size_t n)
+{
+	size_t i;
+
+	for (i = 0; i < n; i++) {
+		if (*s == c) {
+			/* LINTED const castaway */
+			return (wchar_t *)s;
+		}
+		s++;
+	}
+	return NULL;
+}
diff --git a/libc/wchar/wmemcmp.c b/libc/wchar/wmemcmp.c
new file mode 100644
index 0000000..fdb1f98
--- /dev/null
+++ b/libc/wchar/wmemcmp.c
@@ -0,0 +1,53 @@
+/*-
+ * Copyright (c)1999 Citrus Project,
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ *	citrus Id: wmemcmp.c,v 1.2 2000/12/20 14:08:31 itojun Exp
+ */
+
+#include <sys/cdefs.h>
+#if 0
+#if defined(LIBC_SCCS) && !defined(lint)
+__RCSID("$NetBSD: wmemcmp.c,v 1.1 2000/12/23 23:14:37 itojun Exp $");
+#endif /* LIBC_SCCS and not lint */
+#endif
+__FBSDID("$FreeBSD$");
+
+#include <wchar.h>
+
+int
+wmemcmp(const wchar_t *s1, const wchar_t *s2, size_t n)
+{
+	size_t i;
+
+	for (i = 0; i < n; i++) {
+		if (*s1 != *s2) {
+			/* wchar might be unsigned */
+			return *s1 > *s2 ? 1 : -1; 
+		}
+		s1++;
+		s2++;
+	}
+	return 0;
+}
diff --git a/libc/wchar/wmemcpy.c b/libc/wchar/wmemcpy.c
new file mode 100644
index 0000000..c10770c
--- /dev/null
+++ b/libc/wchar/wmemcpy.c
@@ -0,0 +1,44 @@
+/*-
+ * Copyright (c)1999 Citrus Project,
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ *	citrus Id: wmemcpy.c,v 1.2 2000/12/20 14:08:31 itojun Exp
+ */
+
+#include <sys/cdefs.h>
+#if 0
+#if defined(LIBC_SCCS) && !defined(lint)
+__RCSID("$NetBSD: wmemcpy.c,v 1.1 2000/12/23 23:14:37 itojun Exp $");
+#endif /* LIBC_SCCS and not lint */
+#endif
+__FBSDID("$FreeBSD$");
+
+#include <string.h>
+#include <wchar.h>
+
+wchar_t *
+wmemcpy(wchar_t * __restrict d, const wchar_t * __restrict s, size_t n)
+{
+	return (wchar_t *)memcpy(d, s, n * sizeof(wchar_t));
+}
diff --git a/libc/wchar/wmemmove.c b/libc/wchar/wmemmove.c
new file mode 100644
index 0000000..05cfd10
--- /dev/null
+++ b/libc/wchar/wmemmove.c
@@ -0,0 +1,44 @@
+/*-
+ * Copyright (c)1999 Citrus Project,
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ *	citrus Id: wmemmove.c,v 1.2 2000/12/20 14:08:31 itojun Exp
+ */
+
+#include <sys/cdefs.h>
+#if 0
+#if defined(LIBC_SCCS) && !defined(lint)
+__RCSID("$NetBSD: wmemmove.c,v 1.1 2000/12/23 23:14:37 itojun Exp $");
+#endif /* LIBC_SCCS and not lint */
+#endif
+__FBSDID("$FreeBSD$");
+
+#include <string.h>
+#include <wchar.h>
+
+wchar_t *
+wmemmove(wchar_t *d, const wchar_t *s, size_t n)
+{
+	return (wchar_t *)memmove(d, s, n * sizeof(wchar_t));
+}
diff --git a/libc/wchar/wmemset.c b/libc/wchar/wmemset.c
new file mode 100644
index 0000000..0e96356
--- /dev/null
+++ b/libc/wchar/wmemset.c
@@ -0,0 +1,51 @@
+/*-
+ * Copyright (c)1999 Citrus Project,
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ *	citrus Id: wmemset.c,v 1.2 2000/12/20 14:08:31 itojun Exp
+ */
+
+#include <sys/cdefs.h>
+#if 0
+#if defined(LIBC_SCCS) && !defined(lint)
+__RCSID("$NetBSD: wmemset.c,v 1.1 2000/12/23 23:14:37 itojun Exp $");
+#endif /* LIBC_SCCS and not lint */
+#endif
+__FBSDID("$FreeBSD$");
+
+#include <wchar.h>
+
+wchar_t	*
+wmemset(wchar_t *s, wchar_t c, size_t n)
+{
+	size_t i;
+	wchar_t *p;
+
+	p = (wchar_t *)s;
+	for (i = 0; i < n; i++) {
+		*p = c;
+		p++;
+	}
+	return s;
+}
diff --git a/libc/zoneinfo/Android.mk b/libc/zoneinfo/Android.mk
index 2f36f9b..ef700e8 100644
--- a/libc/zoneinfo/Android.mk
+++ b/libc/zoneinfo/Android.mk
@@ -12,3 +12,15 @@
 ALL_PREBUILT += $(TARGET_OUT)/usr/share/zoneinfo/zoneinfo.version
 $(TARGET_OUT)/usr/share/zoneinfo/zoneinfo.version : $(LOCAL_PATH)/zoneinfo.version | $(ACP)
 	$(transform-prebuilt-to-target)
+
+# The host build doesn't use bionic, but it does use bionic's zoneinfo data
+ifeq ($(WITH_HOST_DALVIK),true)
+    ALL_PREBUILT += $(HOST_OUT)/usr/share/zoneinfo/zoneinfo.dat
+    $(eval $(call copy-one-file,$(LOCAL_PATH)/zoneinfo.dat,$(HOST_OUT)/usr/share/zoneinfo/zoneinfo.dat))
+
+    ALL_PREBUILT += $(HOST_OUT)/usr/share/zoneinfo/zoneinfo.idx
+    $(eval $(call copy-one-file,$(LOCAL_PATH)/zoneinfo.idx,$(HOST_OUT)/usr/share/zoneinfo/zoneinfo.idx))
+
+    ALL_PREBUILT += $(HOST_OUT)/usr/share/zoneinfo/zoneinfo.version
+    $(eval $(call copy-one-file,$(LOCAL_PATH)/zoneinfo.version,$(HOST_OUT)/usr/share/zoneinfo/zoneinfo.version))
+endif
diff --git a/libc/zoneinfo/zoneinfo.dat b/libc/zoneinfo/zoneinfo.dat
index c9f0b6f..27ca5d0 100644
--- a/libc/zoneinfo/zoneinfo.dat
+++ b/libc/zoneinfo/zoneinfo.dat
Binary files differ
diff --git a/libc/zoneinfo/zoneinfo.idx b/libc/zoneinfo/zoneinfo.idx
index cb560db..09bd15f 100644
--- a/libc/zoneinfo/zoneinfo.idx
+++ b/libc/zoneinfo/zoneinfo.idx
Binary files differ
diff --git a/libc/zoneinfo/zoneinfo.version b/libc/zoneinfo/zoneinfo.version
index 57a3708..76dcafb 100644
--- a/libc/zoneinfo/zoneinfo.version
+++ b/libc/zoneinfo/zoneinfo.version
@@ -1 +1 @@
-2009s
+2010k
diff --git a/libm/Android.mk b/libm/Android.mk
index fa73aff..28e8f33 100644
--- a/libm/Android.mk
+++ b/libm/Android.mk
@@ -3,6 +3,7 @@
 libm_common_src_files:= \
 	isinf.c  \
 	fpclassify.c \
+	sincos.c \
 	bsdsrc/b_exp.c \
 	bsdsrc/b_log.c \
 	bsdsrc/b_tgamma.c \
diff --git a/libm/include/math.h b/libm/include/math.h
index ef6a9e6..3b5660f 100644
--- a/libm/include/math.h
+++ b/libm/include/math.h
@@ -480,6 +480,13 @@
 #endif
 long double	truncl(long double);
 
+/* BIONIC: GLibc compatibility - required by the ARM toolchain */
+#ifdef _GNU_SOURCE
+void  sincos(double x, double *sin, double *cos);
+void  sincosf(float x, float *sin, float *cos);
+void  sincosl(long double x, long double *sin, long double *cos);
+#endif
+
 /* #endif */ /* __ISO_C_VISIBLE >= 1999 */
 __END_DECLS
 
diff --git a/libm/sincos.c b/libm/sincos.c
new file mode 100644
index 0000000..116b151
--- /dev/null
+++ b/libm/sincos.c
@@ -0,0 +1,46 @@
+/*-
+ * Copyright (c) 2010 The Android Open Source Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ */
+#define _GNU_SOURCE 1
+#include <math.h>
+
+void  sincos(double x, double *psin, double *pcos)
+{
+    *psin = sin(x);
+    *pcos = cos(x);
+}
+
+void  sincosf(float x, float *psin, float *pcos)
+{
+    *psin = sinf(x);
+    *pcos = cosf(x);
+}
+
+void  sincosl(long double x, long double *psin, long double *pcos)
+{
+    *psin = sin(x);
+    *pcos = cos(x);
+}
diff --git a/libstdc++/Android.mk b/libstdc++/Android.mk
index df97c9f..8bc181f 100644
--- a/libstdc++/Android.mk
+++ b/libstdc++/Android.mk
@@ -1,4 +1,15 @@
 LOCAL_PATH:= $(call my-dir)
+
+# Common C++ flags to build this library.
+# Note that we need to access private Bionic headers
+# and define ANDROID_SMP accordingly.
+libstdc++_cflags := -Ibionic/libc/private
+ifeq ($(TARGET_CPU_SMP),true)
+    libstdc++_cflags += -DANDROID_SMP=1
+else
+    libstdc++_cflags += -DANDROID_SMP=0
+endif
+
 include $(CLEAR_VARS)
 
 LOCAL_SRC_FILES:= \
@@ -9,6 +20,8 @@
 
 LOCAL_MODULE:= libstdc++
 
+LOCAL_CFLAGS := $(libstdc++_cflags)
+
 LOCAL_SYSTEM_SHARED_LIBRARIES := libc
 
 include $(BUILD_SHARED_LIBRARY)
@@ -21,6 +34,8 @@
 	src/pure_virtual.cpp \
 	src/typeinfo.cpp
 
+LOCAL_CFLAGS := $(libstdc++_cflags)
+
 LOCAL_MODULE:= libstdc++
 
 LOCAL_SYSTEM_SHARED_LIBRARIES := libc
diff --git a/libstdc++/include/cctype b/libstdc++/include/cctype
index e236561..e0eb981 100644
--- a/libstdc++/include/cctype
+++ b/libstdc++/include/cctype
@@ -36,6 +36,8 @@
 
 #include <ctype.h>
 
+extern "C++" {
+
 namespace std 
 {
 using ::isalnum;
@@ -53,4 +55,6 @@
 using ::toupper;
 }  // namespace std
 
+}  // extern C++
+
 #endif  // BIONIC_LIBSTDCPP_INCLUDE_CCTYPE__
diff --git a/libstdc++/include/cmath b/libstdc++/include/cmath
index bf697ff..be70343 100644
--- a/libstdc++/include/cmath
+++ b/libstdc++/include/cmath
@@ -37,6 +37,8 @@
 #include <cstddef>
 #include <math.h>
 
+extern "C++" {
+
 namespace std
 {
 // Functions.
@@ -68,4 +70,6 @@
 using ::fmod;
 }  // namespace std
 
+}  // extern C++
+
 #endif  // BIONIC_LIBSTDCPP_INCLUDE_CMATH__
diff --git a/libstdc++/include/csetjmp b/libstdc++/include/csetjmp
index a68d127..ba82144 100644
--- a/libstdc++/include/csetjmp
+++ b/libstdc++/include/csetjmp
@@ -36,6 +36,8 @@
 
 #include <setjmp.h>
 
+extern "C++" {
+
 #ifndef setjmp
 #define setjmp(env) setjmp (env)
 #endif
@@ -46,4 +48,6 @@
 using ::longjmp;
 }  // namespace std
 
+}  // extern C++
+
 #endif  // BIONIC_LIBSTDCPP_INCLUDE_CSETJMP__
diff --git a/libstdc++/include/csignal b/libstdc++/include/csignal
index 2600a75..84f0e1d 100644
--- a/libstdc++/include/csignal
+++ b/libstdc++/include/csignal
@@ -36,6 +36,8 @@
 
 #include <signal.h>
 
+extern "C++" {
+
 namespace std
 {
 using ::sig_atomic_t;
@@ -43,4 +45,6 @@
 using ::raise;
 }  // namespace std
 
+}  // extern C++
+
 #endif  // BIONIC_LIBSTDCPP_INCLUDE_CSIGNAL__
diff --git a/libstdc++/include/cstddef b/libstdc++/include/cstddef
index fc1ca9d..cb06b49 100644
--- a/libstdc++/include/cstddef
+++ b/libstdc++/include/cstddef
@@ -38,9 +38,13 @@
  */
 #include <stddef.h>
 
+extern "C++" {
+
 namespace std {
 using ::ptrdiff_t;
 using ::size_t;
 }  // namespace std
 
+}  // extern C++
+
 #endif  // BIONIC_LIBSTDCPP_INCLUDE_CSTDDEF__
diff --git a/libstdc++/include/cstdio b/libstdc++/include/cstdio
index d46a18b..3c8b5c6 100644
--- a/libstdc++/include/cstdio
+++ b/libstdc++/include/cstdio
@@ -36,6 +36,8 @@
 #include <cstddef>
 #include <stdio.h>
 
+extern "C++" {
+
 namespace std {
 using ::FILE;
 using ::fpos_t;
@@ -89,4 +91,6 @@
 using ::vsscanf;
 }  // namespace std
 
+}  // extern C++
+
 #endif  // BIONIC_LIBSTDCPP_INCLUDE_CSTDIO__
diff --git a/libstdc++/include/cstdlib b/libstdc++/include/cstdlib
index 5e6a0b3..bb6f5a5 100644
--- a/libstdc++/include/cstdlib
+++ b/libstdc++/include/cstdlib
@@ -35,12 +35,16 @@
  */
 #include <stdlib.h>
 
+extern "C++" {
+
 namespace std {
 
 using ::exit;
 using ::abort;
 using ::atexit;
+#if 0 /* MISSING FROM BIONIC */
 using ::on_exit;
+#endif
 
 using ::getenv;
 using ::putenv;
@@ -110,4 +114,6 @@
 using ::wcstombs;
 }  // namespace std
 
+}  // extern C++
+
 #endif  // BIONIC_LIBSTDCPP_INCLUDE_CSTDLIB__
diff --git a/libstdc++/include/cstring b/libstdc++/include/cstring
index 80473cc..d3d9387 100644
--- a/libstdc++/include/cstring
+++ b/libstdc++/include/cstring
@@ -37,6 +37,8 @@
 #include <cstddef>
 #include <string.h>
 
+extern "C++" {
+
 namespace std
 {
 using ::memchr;
@@ -63,4 +65,6 @@
 using ::strxfrm;
 }  // namespace std
 
+}  // extern C++
+
 #endif  // BIONIC_LIBSTDCPP_INCLUDE_CSTRING__
diff --git a/libstdc++/include/ctime b/libstdc++/include/ctime
index 36fe7d5..9e6744f 100644
--- a/libstdc++/include/ctime
+++ b/libstdc++/include/ctime
@@ -37,6 +37,8 @@
 #include <cstddef>
 #include <time.h>
 
+extern "C++" {
+
 namespace std 
 {
 // Types.
@@ -56,4 +58,6 @@
 using ::strftime;
 }  // namespace std
 
+}  // extern C++
+
 #endif  // BIONIC_LIBSTDCPP_INCLUDE_CTIME__
diff --git a/libstdc++/include/new b/libstdc++/include/new
index 19d8185..0253e8b 100644
--- a/libstdc++/include/new
+++ b/libstdc++/include/new
@@ -4,6 +4,8 @@
 
 #include <cstddef>
 
+extern "C++" {
+
 namespace std {
     struct nothrow_t {};
     extern const nothrow_t nothrow;
@@ -25,4 +27,6 @@
 inline void  operator delete(void*, void*) { }
 inline void  operator delete[](void*, void*) { }
 
+}  // extern C++
+
 #endif // __NEW__
diff --git a/libstdc++/include/typeinfo b/libstdc++/include/typeinfo
index 8a51a54..4b48a79 100644
--- a/libstdc++/include/typeinfo
+++ b/libstdc++/include/typeinfo
@@ -1,6 +1,7 @@
 #ifndef _TYPEINFO_HEADER_GAURD
 #define _TYPEINFO_HEADER_GAURD
 
+extern "C++" {
 
 namespace std {
     class type_info;
@@ -25,4 +26,6 @@
     type_info & operator=(type_info const & right);
 };
 
+}  // C++
+
 #endif
diff --git a/libstdc++/src/one_time_construction.cpp b/libstdc++/src/one_time_construction.cpp
index 304afb8..2a44c79 100644
--- a/libstdc++/src/one_time_construction.cpp
+++ b/libstdc++/src/one_time_construction.cpp
@@ -10,10 +10,8 @@
 
 #include <stddef.h>
 #include <sys/atomics.h>
-
-extern "C" int __futex_wait(volatile void *ftx, int val, const struct timespec *timeout);
-extern "C" int __futex_wake(volatile void *ftx, int count);
-
+#include <bionic_futex.h>
+#include <bionic_atomic_inline.h>
 
 extern "C" int __cxa_guard_acquire(int volatile * gv)
 {
@@ -22,13 +20,17 @@
     // 6 untouched, wait and return 0
     // 1 untouched, return 0
 retry:
-    if (__atomic_cmpxchg(0, 0x2, gv) == 0)
+    if (__atomic_cmpxchg(0, 0x2, gv) == 0) {
+        ANDROID_MEMBAR_FULL();
         return 1;
-
+    }
     __atomic_cmpxchg(0x2, 0x6, gv); // Indicate there is a waiter
     __futex_wait(gv, 0x6, NULL);
+
     if(*gv != 1) // __cxa_guard_abort was called, let every thread try since there is no return code for this condition
         goto retry;
+
+    ANDROID_MEMBAR_FULL();
     return 0;
 }
 
@@ -36,8 +38,10 @@
 {
     // 2 -> 1
     // 6 -> 1, and wake
-    if (__atomic_cmpxchg(0x2, 0x1, gv) == 0)
+    ANDROID_MEMBAR_FULL();
+    if (__atomic_cmpxchg(0x2, 0x1, gv) == 0) {
         return;
+    }
 
     *gv = 0x1;
     __futex_wake(gv, 0x7fffffff);
@@ -45,6 +49,7 @@
 
 extern "C" void __cxa_guard_abort(int volatile * gv)
 {
+    ANDROID_MEMBAR_FULL();
     *gv = 0;
     __futex_wake(gv, 0x7fffffff);
 }
diff --git a/libthread_db/include/thread_db.h b/libthread_db/include/thread_db.h
index 9c76d40..1b36cb2 100644
--- a/libthread_db/include/thread_db.h
+++ b/libthread_db/include/thread_db.h
@@ -10,6 +10,8 @@
 #include <stdint.h>
 #include <sys/types.h>
 
+typedef void *psaddr_t;
+typedef pid_t lwpid_t;
 
 #define TD_THR_ANY_USER_FLAGS       0xffffffff
 #define TD_THR_LOWEST_PRIORITY      -20
@@ -67,6 +69,7 @@
 typedef struct
 {
     pid_t pid;
+    struct ps_prochandle *ph;
 } td_thragent_t;
 
 typedef struct
@@ -123,19 +126,37 @@
 extern "C"{
 #endif
 
-extern td_err_e td_ta_new(struct ps_prochandle const * proc_handle, td_thragent_t ** thread_agent);
+extern td_err_e td_ta_new(struct ps_prochandle * proc_handle, td_thragent_t ** thread_agent);
+
+extern td_err_e td_ta_delete(td_thragent_t * ta);
 
 extern td_err_e td_ta_set_event(td_thragent_t const * agent, td_thr_events_t * event);
 
 extern td_err_e td_ta_event_addr(td_thragent_t const * agent, td_event_e event, td_notify_t * notify);
 
+extern td_err_e td_ta_clear_event(const td_thragent_t * ta_arg,
+				  td_thr_events_t * event);
+
 extern td_err_e td_ta_event_getmsg(td_thragent_t const * agent, td_event_msg_t * event);
 
+extern td_err_e td_ta_map_lwp2thr(td_thragent_t const * agent, lwpid_t lwpid,
+				  td_thrhandle_t *th);
+
+extern td_err_e td_thr_get_info(td_thrhandle_t const * handle,
+				td_thrinfo_t * info);
+
+extern td_err_e td_thr_event_enable(td_thrhandle_t const * handle,
+				    td_event_e event);
+
 extern td_err_e td_ta_thr_iter(td_thragent_t const * agent, td_thr_iter_f * func, void * cookie,
                                td_thr_state_e state, int32_t prio, sigset_t * sigmask, uint32_t user_flags);
 
 extern char const ** td_symbol_list(void);
 
+extern td_err_e td_thr_tls_get_addr(const td_thrhandle_t * th,
+				    psaddr_t map_address, size_t offset,
+				    psaddr_t * address);
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/libthread_db/libthread_db.c b/libthread_db/libthread_db.c
index f1a78ac..2cf4d38 100644
--- a/libthread_db/libthread_db.c
+++ b/libthread_db/libthread_db.c
@@ -10,12 +10,7 @@
 #include <stdio.h>
 
 extern int ps_pglobal_lookup (void *, const char *obj, const char *name, void **sym_addr);
-
-struct ps_prochandle
-{
-    pid_t pid;
-};
-
+extern pid_t ps_getpid(struct ps_prochandle *ph);
 
 /*
  * This is the list of "special" symbols we care about whose addresses are
@@ -41,7 +36,7 @@
 
 
 td_err_e
-td_ta_new(struct ps_prochandle const * proc_handle, td_thragent_t ** agent_out)
+td_ta_new(struct ps_prochandle * proc_handle, td_thragent_t ** agent_out)
 {
     td_thragent_t * agent;
 
@@ -50,7 +45,8 @@
         return TD_MALLOC;
     }
 
-    agent->pid = proc_handle->pid;
+    agent->pid = ps_getpid(proc_handle);
+    agent->ph = proc_handle;
     *agent_out = agent;
 
     return TD_OK;
@@ -58,14 +54,28 @@
 
 
 td_err_e
+td_ta_delete(td_thragent_t * ta)
+{
+    free(ta);
+    // FIXME: anything else to do?
+    return TD_OK;
+}
+
+
+/* NOTE: not used by gdb 7.0 */
+
+td_err_e
 td_ta_set_event(td_thragent_t const * agent, td_thr_events_t * events)
 {
     return TD_OK;
 }
 
 
+/* NOTE: not used by gdb 7.0 */
 static td_thrhandle_t gEventMsgHandle;
 
+/* NOTE: not used by gdb 7.0 */
+
 static int
 _event_getmsg_helper(td_thrhandle_t const * handle, void * bkpt_addr)
 {
@@ -83,6 +93,8 @@
     return 0;
 }
 
+/* NOTE: not used by gdb 7.0 */
+
 td_err_e
 td_ta_event_getmsg(td_thragent_t const * agent, td_event_msg_t * event)
 {
@@ -107,6 +119,16 @@
 
 
 td_err_e
+td_ta_map_lwp2thr(td_thragent_t const * agent, lwpid_t lwpid,
+		  td_thrhandle_t *th)
+{
+    th->pid = ps_getpid(agent->ph);
+    th->tid = lwpid;
+    return TD_OK;
+}
+
+
+td_err_e
 td_thr_get_info(td_thrhandle_t const * handle, td_thrinfo_t * info)
 {
     info->ti_tid = handle->tid;
@@ -117,6 +139,8 @@
 }
 
 
+/* NOTE: not used by gdb 7.0 */
+
 td_err_e
 td_thr_event_enable(td_thrhandle_t const * handle, td_event_e event)
 {
@@ -125,6 +149,8 @@
 }
 
 
+/* NOTE: not used by gdb 7.0 */
+
 td_err_e
 td_ta_event_addr(td_thragent_t const * agent, td_event_e event, td_notify_t * notify_out)
 {
@@ -149,6 +175,15 @@
 
 
 td_err_e
+td_ta_clear_event(const td_thragent_t * ta_arg, td_thr_events_t * event)
+{
+    /* Given that gdb 7.0 doesn't use thread events,
+       there's nothing we need to do here.  */
+    return TD_OK;
+}
+
+
+td_err_e
 td_ta_thr_iter(td_thragent_t const * agent, td_thr_iter_f * func, void * cookie,
                td_thr_state_e state, int32_t prio, sigset_t * sigmask, uint32_t user_flags)
 {
@@ -170,8 +205,8 @@
             continue;
         }
         handle.tid = atoi(entry->d_name);
-        err = func(&handle, cookie);
-        if (err) {
+        if (func(&handle, cookie) != 0) {
+	    err = TD_DBERR;
             break;
         }
     }
@@ -181,3 +216,9 @@
     return err;
 }
 
+td_err_e
+td_thr_tls_get_addr(const td_thrhandle_t * th,
+		    psaddr_t map_address, size_t offset, psaddr_t * address)
+{
+    return TD_NOAPLIC; // FIXME: TODO
+}
diff --git a/linker/Android.mk b/linker/Android.mk
index 4647c8f..27a6677 100644
--- a/linker/Android.mk
+++ b/linker/Android.mk
@@ -60,7 +60,7 @@
 
 LOCAL_MODULE:= linker
 
-LOCAL_STATIC_LIBRARIES := libcutils libc_nomalloc
+LOCAL_STATIC_LIBRARIES := libc_nomalloc
 
 #LOCAL_FORCE_STATIC_EXECUTABLE := true # not necessary when not including BUILD_EXECUTABLE
 
diff --git a/linker/debugger.c b/linker/debugger.c
index 1bd3cc8..abb383c 100644
--- a/linker/debugger.c
+++ b/linker/debugger.c
@@ -37,7 +37,7 @@
 #include "linker.h"
 
 #include <sys/socket.h>
-#include <cutils/sockets.h>
+#include <sys/un.h>
 
 void notify_gdb_of_libraries();
 
@@ -46,6 +46,47 @@
         ret = (cond); \
     } while (ret < 0 && errno == EINTR)
 
+
+static int socket_abstract_client(const char *name, int type)
+{
+    struct sockaddr_un addr;
+    size_t namelen;
+    socklen_t alen;
+    int s, err;
+
+    namelen  = strlen(name);
+
+    // Test with length +1 for the *initial* '\0'.
+    if ((namelen + 1) > sizeof(addr.sun_path)) {
+        errno = EINVAL;
+        return -1;
+    }
+
+    /* This is used for abstract socket namespace, we need
+     * an initial '\0' at the start of the Unix socket path.
+     *
+     * Note: The path in this case is *not* supposed to be
+     * '\0'-terminated. ("man 7 unix" for the gory details.)
+     */
+    memset (&addr, 0, sizeof addr);
+    addr.sun_family = AF_LOCAL;
+    addr.sun_path[0] = 0;
+    memcpy(addr.sun_path + 1, name, namelen);
+
+    alen = namelen + offsetof(struct sockaddr_un, sun_path) + 1;
+
+    s = socket(AF_LOCAL, type, 0);
+    if(s < 0) return -1;
+
+    RETRY_ON_EINTR(err,connect(s, (struct sockaddr *) &addr, alen));
+    if (err < 0) {
+        close(s);
+        s = -1;
+    }
+
+    return s;
+}
+
 void debugger_signal_handler(int n)
 {
     unsigned tid;
@@ -55,8 +96,7 @@
     signal(SIGUSR1, SIG_IGN);
 
     tid = gettid();
-    s = socket_local_client("android:debuggerd",
-            ANDROID_SOCKET_NAMESPACE_ABSTRACT, SOCK_STREAM);
+    s = socket_abstract_client("android:debuggerd", SOCK_STREAM);
 
     if(s >= 0) {
         /* debugger knows our pid from the credentials on the
diff --git a/linker/linker.c b/linker/linker.c
index 5e04e24..42a5205 100644
--- a/linker/linker.c
+++ b/linker/linker.c
@@ -606,8 +606,8 @@
 #endif
 
 static const char *sopaths[] = {
+    "/vendor/lib",
     "/system/lib",
-    "/lib",
     0
 };
 
@@ -1200,7 +1200,17 @@
 soinfo *find_library(const char *name)
 {
     soinfo *si;
-    const char *bname = strrchr(name, '/');
+    const char *bname;
+
+#if ALLOW_SYMBOLS_FROM_MAIN
+    if (name == NULL)
+        return somain;
+#else
+    if (name == NULL)
+        return NULL;
+#endif
+
+    bname = strrchr(name, '/');
     bname = bname ? bname + 1 : name;
 
     for(si = solist; si != 0; si = si->next){
@@ -2030,7 +2040,7 @@
     return 0;
 
 fail:
-    DL_ERR("failed to link %s\n", si->name);
+    ERROR("failed to link %s\n", si->name);
     si->flags |= FLAG_ERROR;
     return -1;
 }
@@ -2193,6 +2203,7 @@
     si->dynamic = (unsigned *)-1;
     si->wrprotect_start = 0xffffffff;
     si->wrprotect_end = 0;
+    si->refcount = 1;
 
         /* Use LD_LIBRARY_PATH if we aren't setuid/setgid */
     if (ldpath_env && getuid() == geteuid() && getgid() == getegid())