am 5d45fa40: am 2081fda6: Merge "Only look up A records if the system has IPv4." into gingerbread

* commit '5d45fa4049d9ba03c0d922ece18d1d2dda119dc7':
  Only look up A records if the system has IPv4.
diff --git a/libc/Android.mk b/libc/Android.mk
index 351ad02..d940753 100644
--- a/libc/Android.mk
+++ b/libc/Android.mk
@@ -229,6 +229,7 @@
 	wchar/wcsstr.c \
 	wchar/wcstok.c \
 	wchar/wcswidth.c \
+	wchar/wcsxfrm.c \
 	wchar/wmemchr.c \
 	wchar/wmemcmp.c \
 	wchar/wmemcpy.c \
@@ -270,6 +271,10 @@
 	bionic/md5.c \
 	bionic/pututline.c \
 	bionic/realpath.c \
+	bionic/sched_getaffinity.c \
+	bionic/sched_getcpu.c \
+	bionic/sched_cpualloc.c \
+	bionic/sched_cpucount.c \
 	bionic/semaphore.c \
 	bionic/sha1.c \
 	bionic/ssp.c \
diff --git a/libc/NOTICE b/libc/NOTICE
index e8076b5..d9e6818 100644
--- a/libc/NOTICE
+++ b/libc/NOTICE
@@ -1,5 +1,5 @@
 
-Copyright (c) 2005-2008, The Android Open Source Project
+Copyright (c) 2005-2010, The Android Open Source Project
 All rights reserved.
 
 Redistribution and use in source and binary forms, with or without
diff --git a/libc/SYSCALLS.TXT b/libc/SYSCALLS.TXT
index 0a08e12..5653c3c 100644
--- a/libc/SYSCALLS.TXT
+++ b/libc/SYSCALLS.TXT
@@ -85,8 +85,8 @@
 # file descriptors
 ssize_t     read (int, void*, size_t)        3
 ssize_t     write (int, const void*, size_t)       4
-ssize_t     __pread64:pread64 (int, void *, size_t, off_t, off_t) 180
-ssize_t     __pwrite64:pwrite64 (int, void *, size_t, off_t, off_t) 181
+ssize_t     pread64 (int, void *, size_t, off64_t) 180
+ssize_t     pwrite64 (int, void *, size_t, off64_t) 181
 int         __open:open (const char*, int, mode_t)  5
 int         __openat:openat (int, const char*, int, mode_t)  322,295
 int         close (int)                      6
@@ -116,6 +116,7 @@
 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         ftruncate64(int, off64_t) 194
 int         getdents:getdents64(unsigned int, struct dirent *, unsigned int)   217,220
 int         fsync(int)  118
 int         fdatasync(int) 148
@@ -229,6 +230,9 @@
 int sched_get_priority_max(int policy)  159
 int sched_get_priority_min(int policy)  160
 int sched_rr_get_interval(pid_t pid, struct timespec *interval)  161
+int sched_setaffinity(pid_t pid, size_t setsize, const cpu_set_t* set) 241
+int __sched_getaffinity:sched_getaffinity(pid_t pid, size_t setsize, cpu_set_t* set)  242
+int __getcpu:getcpu(unsigned *cpu, unsigned *node, void *unused) 345,318,318
 
 # io priorities
 int ioprio_set(int which, int who, int ioprio) 314,289,288
@@ -264,5 +268,3 @@
 # 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
-
-int     eventfd(int count, int flags) 351,323
diff --git a/libc/arch-arm/syscalls.mk b/libc/arch-arm/syscalls.mk
index c3cf785..5210d6c 100644
--- a/libc/arch-arm/syscalls.mk
+++ b/libc/arch-arm/syscalls.mk
@@ -41,8 +41,8 @@
 syscall_src += arch-arm/syscalls/acct.S
 syscall_src += arch-arm/syscalls/read.S
 syscall_src += arch-arm/syscalls/write.S
-syscall_src += arch-arm/syscalls/__pread64.S
-syscall_src += arch-arm/syscalls/__pwrite64.S
+syscall_src += arch-arm/syscalls/pread64.S
+syscall_src += arch-arm/syscalls/pwrite64.S
 syscall_src += arch-arm/syscalls/__open.S
 syscall_src += arch-arm/syscalls/__openat.S
 syscall_src += arch-arm/syscalls/close.S
@@ -70,6 +70,7 @@
 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/ftruncate64.S
 syscall_src += arch-arm/syscalls/getdents.S
 syscall_src += arch-arm/syscalls/fsync.S
 syscall_src += arch-arm/syscalls/fdatasync.S
@@ -153,6 +154,9 @@
 syscall_src += arch-arm/syscalls/sched_get_priority_max.S
 syscall_src += arch-arm/syscalls/sched_get_priority_min.S
 syscall_src += arch-arm/syscalls/sched_rr_get_interval.S
+syscall_src += arch-arm/syscalls/sched_setaffinity.S
+syscall_src += arch-arm/syscalls/__sched_getaffinity.S
+syscall_src += arch-arm/syscalls/__getcpu.S
 syscall_src += arch-arm/syscalls/ioprio_set.S
 syscall_src += arch-arm/syscalls/ioprio_get.S
 syscall_src += arch-arm/syscalls/uname.S
@@ -175,4 +179,3 @@
 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/__getcpu.S b/libc/arch-arm/syscalls/__getcpu.S
new file mode 100644
index 0000000..ed6927a
--- /dev/null
+++ b/libc/arch-arm/syscalls/__getcpu.S
@@ -0,0 +1,19 @@
+/* autogenerated by gensyscalls.py */
+#include <sys/linux-syscalls.h>
+
+    .text
+    .type __getcpu, #function
+    .globl __getcpu
+    .align 4
+    .fnstart
+
+__getcpu:
+    .save   {r4, r7}
+    stmfd   sp!, {r4, r7}
+    ldr     r7, =__NR_getcpu
+    swi     #0
+    ldmfd   sp!, {r4, r7}
+    movs    r0, r0
+    bxpl    lr
+    b       __set_syscall_errno
+    .fnend
diff --git a/libc/arch-arm/syscalls/__sched_getaffinity.S b/libc/arch-arm/syscalls/__sched_getaffinity.S
new file mode 100644
index 0000000..71f2b1d
--- /dev/null
+++ b/libc/arch-arm/syscalls/__sched_getaffinity.S
@@ -0,0 +1,19 @@
+/* autogenerated by gensyscalls.py */
+#include <sys/linux-syscalls.h>
+
+    .text
+    .type __sched_getaffinity, #function
+    .globl __sched_getaffinity
+    .align 4
+    .fnstart
+
+__sched_getaffinity:
+    .save   {r4, r7}
+    stmfd   sp!, {r4, r7}
+    ldr     r7, =__NR_sched_getaffinity
+    swi     #0
+    ldmfd   sp!, {r4, r7}
+    movs    r0, r0
+    bxpl    lr
+    b       __set_syscall_errno
+    .fnend
diff --git a/libc/arch-arm/syscalls/ftruncate64.S b/libc/arch-arm/syscalls/ftruncate64.S
new file mode 100644
index 0000000..37b4744
--- /dev/null
+++ b/libc/arch-arm/syscalls/ftruncate64.S
@@ -0,0 +1,19 @@
+/* autogenerated by gensyscalls.py */
+#include <sys/linux-syscalls.h>
+
+    .text
+    .type ftruncate64, #function
+    .globl ftruncate64
+    .align 4
+    .fnstart
+
+ftruncate64:
+    .save   {r4, r7}
+    stmfd   sp!, {r4, r7}
+    ldr     r7, =__NR_ftruncate64
+    swi     #0
+    ldmfd   sp!, {r4, r7}
+    movs    r0, r0
+    bxpl    lr
+    b       __set_syscall_errno
+    .fnend
diff --git a/libc/arch-arm/syscalls/__pread64.S b/libc/arch-arm/syscalls/pread64.S
similarity index 85%
rename from libc/arch-arm/syscalls/__pread64.S
rename to libc/arch-arm/syscalls/pread64.S
index ea645e1..a54084c 100644
--- a/libc/arch-arm/syscalls/__pread64.S
+++ b/libc/arch-arm/syscalls/pread64.S
@@ -2,12 +2,12 @@
 #include <sys/linux-syscalls.h>
 
     .text
-    .type __pread64, #function
-    .globl __pread64
+    .type pread64, #function
+    .globl pread64
     .align 4
     .fnstart
 
-__pread64:
+pread64:
     mov     ip, sp
     .save   {r4, r5, r6, r7}
     stmfd   sp!, {r4, r5, r6, r7}
diff --git a/libc/arch-arm/syscalls/__pwrite64.S b/libc/arch-arm/syscalls/pwrite64.S
similarity index 85%
rename from libc/arch-arm/syscalls/__pwrite64.S
rename to libc/arch-arm/syscalls/pwrite64.S
index d1263be..f9d56b2 100644
--- a/libc/arch-arm/syscalls/__pwrite64.S
+++ b/libc/arch-arm/syscalls/pwrite64.S
@@ -2,12 +2,12 @@
 #include <sys/linux-syscalls.h>
 
     .text
-    .type __pwrite64, #function
-    .globl __pwrite64
+    .type pwrite64, #function
+    .globl pwrite64
     .align 4
     .fnstart
 
-__pwrite64:
+pwrite64:
     mov     ip, sp
     .save   {r4, r5, r6, r7}
     stmfd   sp!, {r4, r5, r6, r7}
diff --git a/libc/arch-arm/syscalls/sched_setaffinity.S b/libc/arch-arm/syscalls/sched_setaffinity.S
new file mode 100644
index 0000000..aedf8f3
--- /dev/null
+++ b/libc/arch-arm/syscalls/sched_setaffinity.S
@@ -0,0 +1,19 @@
+/* autogenerated by gensyscalls.py */
+#include <sys/linux-syscalls.h>
+
+    .text
+    .type sched_setaffinity, #function
+    .globl sched_setaffinity
+    .align 4
+    .fnstart
+
+sched_setaffinity:
+    .save   {r4, r7}
+    stmfd   sp!, {r4, r7}
+    ldr     r7, =__NR_sched_setaffinity
+    swi     #0
+    ldmfd   sp!, {r4, r7}
+    movs    r0, r0
+    bxpl    lr
+    b       __set_syscall_errno
+    .fnend
diff --git a/libc/arch-sh/syscalls.mk b/libc/arch-sh/syscalls.mk
index a87419d..9575905 100644
--- a/libc/arch-sh/syscalls.mk
+++ b/libc/arch-sh/syscalls.mk
@@ -45,8 +45,8 @@
 syscall_src += arch-sh/syscalls/acct.S
 syscall_src += arch-sh/syscalls/read.S
 syscall_src += arch-sh/syscalls/write.S
-syscall_src += arch-sh/syscalls/__pread64.S
-syscall_src += arch-sh/syscalls/__pwrite64.S
+syscall_src += arch-sh/syscalls/pread64.S
+syscall_src += arch-sh/syscalls/pwrite64.S
 syscall_src += arch-sh/syscalls/__open.S
 syscall_src += arch-sh/syscalls/__openat.S
 syscall_src += arch-sh/syscalls/close.S
@@ -73,6 +73,7 @@
 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/ftruncate64.S
 syscall_src += arch-sh/syscalls/getdents.S
 syscall_src += arch-sh/syscalls/fsync.S
 syscall_src += arch-sh/syscalls/fdatasync.S
@@ -142,6 +143,9 @@
 syscall_src += arch-sh/syscalls/sched_get_priority_max.S
 syscall_src += arch-sh/syscalls/sched_get_priority_min.S
 syscall_src += arch-sh/syscalls/sched_rr_get_interval.S
+syscall_src += arch-sh/syscalls/sched_setaffinity.S
+syscall_src += arch-sh/syscalls/__sched_getaffinity.S
+syscall_src += arch-sh/syscalls/__getcpu.S
 syscall_src += arch-sh/syscalls/ioprio_set.S
 syscall_src += arch-sh/syscalls/ioprio_get.S
 syscall_src += arch-sh/syscalls/uname.S
diff --git a/libc/arch-sh/syscalls/__pwrite64.S b/libc/arch-sh/syscalls/__getcpu.S
similarity index 63%
copy from libc/arch-sh/syscalls/__pwrite64.S
copy to libc/arch-sh/syscalls/__getcpu.S
index a722242..125387b 100644
--- a/libc/arch-sh/syscalls/__pwrite64.S
+++ b/libc/arch-sh/syscalls/__getcpu.S
@@ -2,22 +2,19 @@
 #include <sys/linux-syscalls.h>
 
     .text
-    .type __pwrite64, @function
-    .globl __pwrite64
+    .type __getcpu, @function
+    .globl __getcpu
     .align 4
 
-__pwrite64:
-
-    /* get ready for additonal arg */
-    mov.l   @r15, r0
+__getcpu:
 
     /* invoke trap */
     mov.l   0f, r3  /* trap num */
-    trapa   #(5 + 0x10)
+    trapa   #(3 + 0x10)
 
     /* check return value */
     cmp/pz  r0
-    bt      __NR_pwrite64_end
+    bt      __NR_getcpu_end
 
     /* keep error number */
     sts.l   pr, @-r15
@@ -26,10 +23,10 @@
     mov     r0, r4
     lds.l   @r15+, pr
 
-__NR_pwrite64_end:
+__NR_getcpu_end:
     rts
     nop
 
     .align  2
-0:  .long   __NR_pwrite64
+0:  .long   __NR_getcpu
 1:  .long   __set_syscall_errno
diff --git a/libc/arch-sh/syscalls/__pwrite64.S b/libc/arch-sh/syscalls/__sched_getaffinity.S
similarity index 63%
copy from libc/arch-sh/syscalls/__pwrite64.S
copy to libc/arch-sh/syscalls/__sched_getaffinity.S
index a722242..7e8be6a 100644
--- a/libc/arch-sh/syscalls/__pwrite64.S
+++ b/libc/arch-sh/syscalls/__sched_getaffinity.S
@@ -2,22 +2,19 @@
 #include <sys/linux-syscalls.h>
 
     .text
-    .type __pwrite64, @function
-    .globl __pwrite64
+    .type __sched_getaffinity, @function
+    .globl __sched_getaffinity
     .align 4
 
-__pwrite64:
-
-    /* get ready for additonal arg */
-    mov.l   @r15, r0
+__sched_getaffinity:
 
     /* invoke trap */
     mov.l   0f, r3  /* trap num */
-    trapa   #(5 + 0x10)
+    trapa   #(3 + 0x10)
 
     /* check return value */
     cmp/pz  r0
-    bt      __NR_pwrite64_end
+    bt      __NR_sched_getaffinity_end
 
     /* keep error number */
     sts.l   pr, @-r15
@@ -26,10 +23,10 @@
     mov     r0, r4
     lds.l   @r15+, pr
 
-__NR_pwrite64_end:
+__NR_sched_getaffinity_end:
     rts
     nop
 
     .align  2
-0:  .long   __NR_pwrite64
+0:  .long   __NR_sched_getaffinity
 1:  .long   __set_syscall_errno
diff --git a/libc/arch-sh/syscalls/__pwrite64.S b/libc/arch-sh/syscalls/ftruncate64.S
similarity index 63%
copy from libc/arch-sh/syscalls/__pwrite64.S
copy to libc/arch-sh/syscalls/ftruncate64.S
index a722242..f4c7c1e 100644
--- a/libc/arch-sh/syscalls/__pwrite64.S
+++ b/libc/arch-sh/syscalls/ftruncate64.S
@@ -2,22 +2,19 @@
 #include <sys/linux-syscalls.h>
 
     .text
-    .type __pwrite64, @function
-    .globl __pwrite64
+    .type ftruncate64, @function
+    .globl ftruncate64
     .align 4
 
-__pwrite64:
-
-    /* get ready for additonal arg */
-    mov.l   @r15, r0
+ftruncate64:
 
     /* invoke trap */
     mov.l   0f, r3  /* trap num */
-    trapa   #(5 + 0x10)
+    trapa   #(3 + 0x10)
 
     /* check return value */
     cmp/pz  r0
-    bt      __NR_pwrite64_end
+    bt      __NR_ftruncate64_end
 
     /* keep error number */
     sts.l   pr, @-r15
@@ -26,10 +23,10 @@
     mov     r0, r4
     lds.l   @r15+, pr
 
-__NR_pwrite64_end:
+__NR_ftruncate64_end:
     rts
     nop
 
     .align  2
-0:  .long   __NR_pwrite64
+0:  .long   __NR_ftruncate64
 1:  .long   __set_syscall_errno
diff --git a/libc/arch-sh/syscalls/__pread64.S b/libc/arch-sh/syscalls/pread64.S
similarity index 89%
rename from libc/arch-sh/syscalls/__pread64.S
rename to libc/arch-sh/syscalls/pread64.S
index 474add3..702a402 100644
--- a/libc/arch-sh/syscalls/__pread64.S
+++ b/libc/arch-sh/syscalls/pread64.S
@@ -2,11 +2,11 @@
 #include <sys/linux-syscalls.h>
 
     .text
-    .type __pread64, @function
-    .globl __pread64
+    .type pread64, @function
+    .globl pread64
     .align 4
 
-__pread64:
+pread64:
 
     /* get ready for additonal arg */
     mov.l   @r15, r0
diff --git a/libc/arch-sh/syscalls/__pwrite64.S b/libc/arch-sh/syscalls/pwrite64.S
similarity index 89%
rename from libc/arch-sh/syscalls/__pwrite64.S
rename to libc/arch-sh/syscalls/pwrite64.S
index a722242..3f6c192 100644
--- a/libc/arch-sh/syscalls/__pwrite64.S
+++ b/libc/arch-sh/syscalls/pwrite64.S
@@ -2,11 +2,11 @@
 #include <sys/linux-syscalls.h>
 
     .text
-    .type __pwrite64, @function
-    .globl __pwrite64
+    .type pwrite64, @function
+    .globl pwrite64
     .align 4
 
-__pwrite64:
+pwrite64:
 
     /* get ready for additonal arg */
     mov.l   @r15, r0
diff --git a/libc/arch-sh/syscalls/__pwrite64.S b/libc/arch-sh/syscalls/sched_setaffinity.S
similarity index 63%
copy from libc/arch-sh/syscalls/__pwrite64.S
copy to libc/arch-sh/syscalls/sched_setaffinity.S
index a722242..9dda3b4 100644
--- a/libc/arch-sh/syscalls/__pwrite64.S
+++ b/libc/arch-sh/syscalls/sched_setaffinity.S
@@ -2,22 +2,19 @@
 #include <sys/linux-syscalls.h>
 
     .text
-    .type __pwrite64, @function
-    .globl __pwrite64
+    .type sched_setaffinity, @function
+    .globl sched_setaffinity
     .align 4
 
-__pwrite64:
-
-    /* get ready for additonal arg */
-    mov.l   @r15, r0
+sched_setaffinity:
 
     /* invoke trap */
     mov.l   0f, r3  /* trap num */
-    trapa   #(5 + 0x10)
+    trapa   #(3 + 0x10)
 
     /* check return value */
     cmp/pz  r0
-    bt      __NR_pwrite64_end
+    bt      __NR_sched_setaffinity_end
 
     /* keep error number */
     sts.l   pr, @-r15
@@ -26,10 +23,10 @@
     mov     r0, r4
     lds.l   @r15+, pr
 
-__NR_pwrite64_end:
+__NR_sched_setaffinity_end:
     rts
     nop
 
     .align  2
-0:  .long   __NR_pwrite64
+0:  .long   __NR_sched_setaffinity
 1:  .long   __set_syscall_errno
diff --git a/libc/arch-x86/syscalls.mk b/libc/arch-x86/syscalls.mk
index 420a91e..e8c6a77 100644
--- a/libc/arch-x86/syscalls.mk
+++ b/libc/arch-x86/syscalls.mk
@@ -44,8 +44,8 @@
 syscall_src += arch-x86/syscalls/acct.S
 syscall_src += arch-x86/syscalls/read.S
 syscall_src += arch-x86/syscalls/write.S
-syscall_src += arch-x86/syscalls/__pread64.S
-syscall_src += arch-x86/syscalls/__pwrite64.S
+syscall_src += arch-x86/syscalls/pread64.S
+syscall_src += arch-x86/syscalls/pwrite64.S
 syscall_src += arch-x86/syscalls/__open.S
 syscall_src += arch-x86/syscalls/__openat.S
 syscall_src += arch-x86/syscalls/close.S
@@ -73,6 +73,7 @@
 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/ftruncate64.S
 syscall_src += arch-x86/syscalls/getdents.S
 syscall_src += arch-x86/syscalls/fsync.S
 syscall_src += arch-x86/syscalls/fdatasync.S
@@ -156,6 +157,9 @@
 syscall_src += arch-x86/syscalls/sched_get_priority_max.S
 syscall_src += arch-x86/syscalls/sched_get_priority_min.S
 syscall_src += arch-x86/syscalls/sched_rr_get_interval.S
+syscall_src += arch-x86/syscalls/sched_setaffinity.S
+syscall_src += arch-x86/syscalls/__sched_getaffinity.S
+syscall_src += arch-x86/syscalls/__getcpu.S
 syscall_src += arch-x86/syscalls/ioprio_set.S
 syscall_src += arch-x86/syscalls/ioprio_get.S
 syscall_src += arch-x86/syscalls/uname.S
diff --git a/libc/arch-x86/syscalls/__getcpu.S b/libc/arch-x86/syscalls/__getcpu.S
new file mode 100644
index 0000000..0381799
--- /dev/null
+++ b/libc/arch-x86/syscalls/__getcpu.S
@@ -0,0 +1,29 @@
+/* autogenerated by gensyscalls.py */
+#include <sys/linux-syscalls.h>
+
+    .text
+    .type __getcpu, @function
+    .globl __getcpu
+    .align 4
+
+__getcpu:
+    pushl   %ebx
+    pushl   %ecx
+    pushl   %edx
+    mov     16(%esp), %ebx
+    mov     20(%esp), %ecx
+    mov     24(%esp), %edx
+    movl    $__NR_getcpu, %eax
+    int     $0x80
+    cmpl    $-129, %eax
+    jb      1f
+    negl    %eax
+    pushl   %eax
+    call    __set_errno
+    addl    $4, %esp
+    orl     $-1, %eax
+1:
+    popl    %edx
+    popl    %ecx
+    popl    %ebx
+    ret
diff --git a/libc/arch-x86/syscalls/__sched_getaffinity.S b/libc/arch-x86/syscalls/__sched_getaffinity.S
new file mode 100644
index 0000000..43bfa50
--- /dev/null
+++ b/libc/arch-x86/syscalls/__sched_getaffinity.S
@@ -0,0 +1,29 @@
+/* autogenerated by gensyscalls.py */
+#include <sys/linux-syscalls.h>
+
+    .text
+    .type __sched_getaffinity, @function
+    .globl __sched_getaffinity
+    .align 4
+
+__sched_getaffinity:
+    pushl   %ebx
+    pushl   %ecx
+    pushl   %edx
+    mov     16(%esp), %ebx
+    mov     20(%esp), %ecx
+    mov     24(%esp), %edx
+    movl    $__NR_sched_getaffinity, %eax
+    int     $0x80
+    cmpl    $-129, %eax
+    jb      1f
+    negl    %eax
+    pushl   %eax
+    call    __set_errno
+    addl    $4, %esp
+    orl     $-1, %eax
+1:
+    popl    %edx
+    popl    %ecx
+    popl    %ebx
+    ret
diff --git a/libc/arch-x86/syscalls/ftruncate64.S b/libc/arch-x86/syscalls/ftruncate64.S
new file mode 100644
index 0000000..66835ab
--- /dev/null
+++ b/libc/arch-x86/syscalls/ftruncate64.S
@@ -0,0 +1,29 @@
+/* autogenerated by gensyscalls.py */
+#include <sys/linux-syscalls.h>
+
+    .text
+    .type ftruncate64, @function
+    .globl ftruncate64
+    .align 4
+
+ftruncate64:
+    pushl   %ebx
+    pushl   %ecx
+    pushl   %edx
+    mov     16(%esp), %ebx
+    mov     20(%esp), %ecx
+    mov     24(%esp), %edx
+    movl    $__NR_ftruncate64, %eax
+    int     $0x80
+    cmpl    $-129, %eax
+    jb      1f
+    negl    %eax
+    pushl   %eax
+    call    __set_errno
+    addl    $4, %esp
+    orl     $-1, %eax
+1:
+    popl    %edx
+    popl    %ecx
+    popl    %ebx
+    ret
diff --git a/libc/arch-x86/syscalls/__pread64.S b/libc/arch-x86/syscalls/pread64.S
similarity index 90%
rename from libc/arch-x86/syscalls/__pread64.S
rename to libc/arch-x86/syscalls/pread64.S
index 3114673..eb004a9 100644
--- a/libc/arch-x86/syscalls/__pread64.S
+++ b/libc/arch-x86/syscalls/pread64.S
@@ -2,11 +2,11 @@
 #include <sys/linux-syscalls.h>
 
     .text
-    .type __pread64, @function
-    .globl __pread64
+    .type pread64, @function
+    .globl pread64
     .align 4
 
-__pread64:
+pread64:
     pushl   %ebx
     pushl   %ecx
     pushl   %edx
diff --git a/libc/arch-x86/syscalls/__pwrite64.S b/libc/arch-x86/syscalls/pwrite64.S
similarity index 90%
rename from libc/arch-x86/syscalls/__pwrite64.S
rename to libc/arch-x86/syscalls/pwrite64.S
index 28f6536..01389f8 100644
--- a/libc/arch-x86/syscalls/__pwrite64.S
+++ b/libc/arch-x86/syscalls/pwrite64.S
@@ -2,11 +2,11 @@
 #include <sys/linux-syscalls.h>
 
     .text
-    .type __pwrite64, @function
-    .globl __pwrite64
+    .type pwrite64, @function
+    .globl pwrite64
     .align 4
 
-__pwrite64:
+pwrite64:
     pushl   %ebx
     pushl   %ecx
     pushl   %edx
diff --git a/libc/arch-x86/syscalls/sched_setaffinity.S b/libc/arch-x86/syscalls/sched_setaffinity.S
new file mode 100644
index 0000000..5fa51ef
--- /dev/null
+++ b/libc/arch-x86/syscalls/sched_setaffinity.S
@@ -0,0 +1,29 @@
+/* autogenerated by gensyscalls.py */
+#include <sys/linux-syscalls.h>
+
+    .text
+    .type sched_setaffinity, @function
+    .globl sched_setaffinity
+    .align 4
+
+sched_setaffinity:
+    pushl   %ebx
+    pushl   %ecx
+    pushl   %edx
+    mov     16(%esp), %ebx
+    mov     20(%esp), %ecx
+    mov     24(%esp), %edx
+    movl    $__NR_sched_setaffinity, %eax
+    int     $0x80
+    cmpl    $-129, %eax
+    jb      1f
+    negl    %eax
+    pushl   %eax
+    call    __set_errno
+    addl    $4, %esp
+    orl     $-1, %eax
+1:
+    popl    %edx
+    popl    %ecx
+    popl    %ebx
+    ret
diff --git a/libc/bionic/malloc_debug_common.c b/libc/bionic/malloc_debug_common.c
index f05576c..ebf0006 100644
--- a/libc/bionic/malloc_debug_common.c
+++ b/libc/bionic/malloc_debug_common.c
@@ -120,6 +120,7 @@
             totalMemory == NULL || backtraceSize == NULL) {
         return;
     }
+    *totalMemory = 0;
 
     pthread_mutex_lock(&gAllocationsMutex);
 
@@ -127,7 +128,6 @@
         *info = NULL;
         *overallSize = 0;
         *infoSize = 0;
-        *totalMemory = 0;
         *backtraceSize = 0;
         goto done;
     }
diff --git a/libc/bionic/pthread.c b/libc/bionic/pthread.c
index b28cd9f..34909fb 100644
--- a/libc/bionic/pthread.c
+++ b/libc/bionic/pthread.c
@@ -196,6 +196,9 @@
 
     // Wait for our creating thread to release us. This lets it have time to
     // notify gdb about this thread before it starts doing anything.
+    //
+    // This also provides the memory barrier needed to ensure that all memory
+    // accesses previously made by the creating thread are visible to us.
     pthread_mutex_t * start_mutex = (pthread_mutex_t *)&tls[TLS_SLOT_SELF];
     pthread_mutex_lock(start_mutex);
     pthread_mutex_destroy(start_mutex);
@@ -264,7 +267,7 @@
 }
 
 /*
- * Create a new thread. The thread's stack is layed out like so:
+ * Create a new thread. The thread's stack is laid out like so:
  *
  * +---------------------------+
  * |     pthread_internal_t    |
@@ -334,6 +337,10 @@
 
     // Create a mutex for the thread in TLS_SLOT_SELF to wait on once it starts so we can keep
     // it from doing anything until after we notify the debugger about it
+    //
+    // This also provides the memory barrier we need to ensure that all
+    // memory accesses previously performed by this thread are visible to
+    // the new thread.
     start_mutex = (pthread_mutex_t *) &tls[TLS_SLOT_SELF];
     pthread_mutex_init(start_mutex, NULL);
     pthread_mutex_lock(start_mutex);
@@ -1421,6 +1428,18 @@
             break;
     }
 
+    /*
+     * Ensure that all memory accesses previously made by this thread are
+     * visible to the woken thread(s).  On the other side, the "wait"
+     * code will issue any necessary barriers when locking the mutex.
+     *
+     * This may not strictly be necessary -- if the caller follows
+     * recommended practice and holds the mutex before signaling the cond
+     * var, the mutex ops will provide correct semantics.  If they don't
+     * hold the mutex, they're subject to race conditions anyway.
+     */
+    ANDROID_MEMBAR_FULL();
+
     __futex_wake_ex(&cond->value, COND_IS_SHARED(cond), counter);
     return 0;
 }
@@ -1839,7 +1858,13 @@
      */
     int ret, old_errno = errno;
 
-    ret = __rt_sigprocmask(how, set, oset, _NSIG / 8);
+    /* Use NSIG which corresponds to the number of signals in
+     * our 32-bit sigset_t implementation. As such, this function, or
+     * anything that deals with sigset_t cannot manage real-time signals
+     * (signo >= 32). We might want to introduce sigset_rt_t as an
+     * extension to do so in the future.
+     */
+    ret = __rt_sigprocmask(how, set, oset, NSIG / 8);
     if (ret < 0)
         ret = errno;
 
@@ -1867,12 +1892,16 @@
 int  pthread_once( pthread_once_t*  once_control,  void (*init_routine)(void) )
 {
     static pthread_mutex_t   once_lock = PTHREAD_RECURSIVE_MUTEX_INITIALIZER;
+    volatile pthread_once_t* ocptr = once_control;
 
-    if (*once_control == PTHREAD_ONCE_INIT) {
+    pthread_once_t tmp = *ocptr;
+    ANDROID_MEMBAR_FULL();
+    if (tmp == PTHREAD_ONCE_INIT) {
         pthread_mutex_lock( &once_lock );
-        if (*once_control == PTHREAD_ONCE_INIT) {
+        if (*ocptr == PTHREAD_ONCE_INIT) {
             (*init_routine)();
-            *once_control = ~PTHREAD_ONCE_INIT;
+            ANDROID_MEMBAR_FULL();
+            *ocptr = ~PTHREAD_ONCE_INIT;
         }
         pthread_mutex_unlock( &once_lock );
     }
diff --git a/libc/bionic/realpath.c b/libc/bionic/realpath.c
index 274a3a0..4cb847b 100644
--- a/libc/bionic/realpath.c
+++ b/libc/bionic/realpath.c
@@ -1,9 +1,6 @@
+/*	$OpenBSD: realpath.c,v 1.13 2005/08/08 08:05:37 espie Exp $ */
 /*
- * Copyright (c) 1994
- *	The Regents of the University of California.  All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Jan-Simon Pendry.
+ * Copyright (c) 2003 Constantin S. Svintsoff <kostik@iclub.nsu.ru>
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -13,18 +10,14 @@
  * 2. Redistributions in binary form must reproduce the above copyright
  *    notice, this list of conditions and the following disclaimer in the
  *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *	This product includes software developed by the University of
- *	California, Berkeley and its contributors.
- * 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.
+ * 3. The names of the authors may not 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
+ * 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 REGENTS OR CONTRIBUTORS BE LIABLE
+ * 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)
@@ -34,133 +27,164 @@
  * SUCH DAMAGE.
  */
 
-#if defined(LIBC_SCCS) && !defined(lint)
-static char sccsid[] = "@(#)realpath.c	8.1 (Berkeley) 2/16/94";
-static char rcsid[] =
-"$FreeBSD: /repoman/r/ncvs/src/lib/libc/stdlib/realpath.c,v 1.6.2.1 2003/08/03 23:47:39 nectar Exp $";
-#endif /* LIBC_SCCS and not lint */
-
 #include <sys/param.h>
 #include <sys/stat.h>
 
 #include <errno.h>
-#include <fcntl.h>
 #include <stdlib.h>
 #include <string.h>
 #include <unistd.h>
 
 /*
- * char *realpath(const char *path, char resolved_path[MAXPATHLEN]);
+ * char *realpath(const char *path, char resolved[PATH_MAX]);
  *
  * Find the real name of path, by removing all ".", ".." and symlink
  * components.  Returns (resolved) on success, or (NULL) on failure,
  * in which case the path which caused trouble is left in (resolved).
  */
 char *
-realpath(path, resolved)
-	const char *path;
-	char *resolved;
+realpath(const char *path, char resolved[PATH_MAX])
 {
 	struct stat sb;
-	int fd, n, rootd, serrno;
-	char *p, *q, wbuf[MAXPATHLEN];
-      int symlinks = 0;
+	char *p, *q, *s;
+	size_t left_len, resolved_len;
+	unsigned symlinks;
+	int serrno, slen;
+	char left[PATH_MAX], next_token[PATH_MAX], symlink[PATH_MAX];
 
-	/* Save the starting point. */
-	if ((fd = open(".", O_RDONLY)) < 0) {
-		(void)strcpy(resolved, ".");
+	serrno = errno;
+	symlinks = 0;
+	if (path[0] == '/') {
+		resolved[0] = '/';
+		resolved[1] = '\0';
+		if (path[1] == '\0')
+			return (resolved);
+		resolved_len = 1;
+		left_len = strlcpy(left, path + 1, sizeof(left));
+	} else {
+		if (getcwd(resolved, PATH_MAX) == NULL) {
+			strlcpy(resolved, ".", PATH_MAX);
+			return (NULL);
+		}
+		resolved_len = strlen(resolved);
+		left_len = strlcpy(left, path, sizeof(left));
+	}
+	if (left_len >= sizeof(left) || resolved_len >= PATH_MAX) {
+		errno = ENAMETOOLONG;
 		return (NULL);
 	}
 
 	/*
-	 * Find the dirname and basename from the path to be resolved.
-	 * Change directory to the dirname component.
-	 * lstat the basename part.
-	 *     if it is a symlink, read in the value and loop.
-	 *     if it is a directory, then change to that directory.
-	 * get the current directory name and append the basename.
+	 * Iterate over path components in `left'.
 	 */
-	(void)strncpy(resolved, path, MAXPATHLEN - 1);
-	resolved[MAXPATHLEN - 1] = '\0';
-loop:
-	q = strrchr(resolved, '/');
-	if (q != NULL) {
-		p = q + 1;
-		if (q == resolved)
-			q = "/";
-		else {
-			do {
-				--q;
-			} while (q > resolved && *q == '/');
-			q[1] = '\0';
-			q = resolved;
-		}
-		if (chdir(q) < 0)
-			goto err1;
-	} else
-		p = resolved;
-
-	/* Deal with the last component. */
-	if (*p != '\0' && lstat(p, &sb) == 0) {
-		if (S_ISLNK(sb.st_mode)) {
-                      if (++symlinks > MAXSYMLINKS) {
-                              errno = ELOOP;
-                              goto err1;
-                      }
-			n = readlink(p, resolved, MAXPATHLEN - 1);
-			if (n < 0)
-				goto err1;
-			resolved[n] = '\0';
-			goto loop;
-		}
-		if (S_ISDIR(sb.st_mode)) {
-			if (chdir(p) < 0)
-				goto err1;
-			p = "";
-		}
-	}
-
-	/*
-	 * Save the last component name and get the full pathname of
-	 * the current directory.
-	 */
-	(void)strcpy(wbuf, p);
-	if (getcwd(resolved, MAXPATHLEN) == 0)
-		goto err1;
-
-	/*
-	 * Join the two strings together, ensuring that the right thing
-	 * happens if the last component is empty, or the dirname is root.
-	 */
-	if (resolved[0] == '/' && resolved[1] == '\0')
-		rootd = 1;
-	else
-		rootd = 0;
-
-	if (*wbuf) {
-		if (strlen(resolved) + strlen(wbuf) + (1-rootd) + 1 >
-		    MAXPATHLEN) {
+	while (left_len != 0) {
+		/*
+		 * Extract the next path component and adjust `left'
+		 * and its length.
+		 */
+		p = strchr(left, '/');
+		s = p ? p : left + left_len;
+		if (s - left >= sizeof(next_token)) {
 			errno = ENAMETOOLONG;
-			goto err1;
+			return (NULL);
 		}
-		if (rootd == 0)
-			(void)strcat(resolved, "/");
-		(void)strcat(resolved, wbuf);
+		memcpy(next_token, left, s - left);
+		next_token[s - left] = '\0';
+		left_len -= s - left;
+		if (p != NULL)
+			memmove(left, s + 1, left_len + 1);
+		if (resolved[resolved_len - 1] != '/') {
+			if (resolved_len + 1 >= PATH_MAX) {
+				errno = ENAMETOOLONG;
+				return (NULL);
+			}
+			resolved[resolved_len++] = '/';
+			resolved[resolved_len] = '\0';
+		}
+		if (next_token[0] == '\0')
+			continue;
+		else if (strcmp(next_token, ".") == 0)
+			continue;
+		else if (strcmp(next_token, "..") == 0) {
+			/*
+			 * Strip the last path component except when we have
+			 * single "/"
+			 */
+			if (resolved_len > 1) {
+				resolved[resolved_len - 1] = '\0';
+				q = strrchr(resolved, '/') + 1;
+				*q = '\0';
+				resolved_len = q - resolved;
+			}
+			continue;
+		}
+
+		/*
+		 * Append the next path component and lstat() it. If
+		 * lstat() fails we still can return successfully if
+		 * there are no more path components left.
+		 */
+		resolved_len = strlcat(resolved, next_token, PATH_MAX);
+		if (resolved_len >= PATH_MAX) {
+			errno = ENAMETOOLONG;
+			return (NULL);
+		}
+		if (lstat(resolved, &sb) != 0) {
+			if (errno == ENOENT && p == NULL) {
+				errno = serrno;
+				return (resolved);
+			}
+			return (NULL);
+		}
+		if (S_ISLNK(sb.st_mode)) {
+			if (symlinks++ > MAXSYMLINKS) {
+				errno = ELOOP;
+				return (NULL);
+			}
+			slen = readlink(resolved, symlink, sizeof(symlink) - 1);
+			if (slen < 0)
+				return (NULL);
+			symlink[slen] = '\0';
+			if (symlink[0] == '/') {
+				resolved[1] = 0;
+				resolved_len = 1;
+			} else if (resolved_len > 1) {
+				/* Strip the last path component. */
+				resolved[resolved_len - 1] = '\0';
+				q = strrchr(resolved, '/') + 1;
+				*q = '\0';
+				resolved_len = q - resolved;
+			}
+
+			/*
+			 * If there are any path components left, then
+			 * append them to symlink. The result is placed
+			 * in `left'.
+			 */
+			if (p != NULL) {
+				if (symlink[slen - 1] != '/') {
+					if (slen + 1 >= sizeof(symlink)) {
+						errno = ENAMETOOLONG;
+						return (NULL);
+					}
+					symlink[slen] = '/';
+					symlink[slen + 1] = 0;
+				}
+				left_len = strlcat(symlink, left, sizeof(left));
+				if (left_len >= sizeof(left)) {
+					errno = ENAMETOOLONG;
+					return (NULL);
+				}
+			}
+			left_len = strlcpy(left, symlink, sizeof(left));
+		}
 	}
 
-	/* Go back to where we came from. */
-	if (fchdir(fd) < 0) {
-		serrno = errno;
-		goto err2;
-	}
-
-	/* It's okay if the close fails, what's an fd more or less? */
-	(void)close(fd);
+	/*
+	 * Remove trailing slash except when the resolved pathname
+	 * is a single "/".
+	 */
+	if (resolved_len > 1 && resolved[resolved_len - 1] == '/')
+		resolved[resolved_len - 1] = '\0';
 	return (resolved);
-
-err1:	serrno = errno;
-	(void)fchdir(fd);
-err2:	(void)close(fd);
-	errno = serrno;
-	return (NULL);
 }
diff --git a/libc/bionic/sched_cpualloc.c b/libc/bionic/sched_cpualloc.c
new file mode 100644
index 0000000..30964bc
--- /dev/null
+++ b/libc/bionic/sched_cpualloc.c
@@ -0,0 +1,40 @@
+/*
+ * 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.
+ */
+#define _GNU_SOURCE 1
+#include <sched.h>
+#include <stdlib.h>
+
+cpu_set_t* __sched_cpualloc(size_t count)
+{
+    return (cpu_set_t*) malloc(CPU_ALLOC_SIZE(count));
+}
+
+void __sched_cpufree(cpu_set_t* set)
+{
+    free(set);
+}
diff --git a/libc/bionic/sched_cpucount.c b/libc/bionic/sched_cpucount.c
new file mode 100644
index 0000000..9458dc8
--- /dev/null
+++ b/libc/bionic/sched_cpucount.c
@@ -0,0 +1,40 @@
+/*
+ * 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.
+ */
+#define _GNU_SOURCE 1
+#include <sched.h>
+
+int __sched_cpucount(size_t setsize, cpu_set_t* set)
+{
+    int nn = 0, nn_max = setsize / sizeof(__CPU_BITTYPE);
+    int count = 0;
+
+    for ( ; nn < nn_max; nn++ )
+        count += __builtin_popcount(set->__bits[nn]);
+
+    return count;
+}
diff --git a/libc/bionic/sched_getaffinity.c b/libc/bionic/sched_getaffinity.c
new file mode 100644
index 0000000..7313822
--- /dev/null
+++ b/libc/bionic/sched_getaffinity.c
@@ -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.
+ */
+#define _GNU_SOURCE 1
+#include <sched.h>
+
+int  sched_getaffinity(pid_t pid, size_t setsize, cpu_set_t* set)
+{
+    int ret = __sched_getaffinity(pid, setsize, set);
+    if (ret >= 0) {
+        if ((size_t)ret < setsize) {
+            memset((char*)set + ret, '\0', setsize - (size_t)ret);
+        }
+        ret = 0;
+    }
+    return ret;
+}
diff --git a/libc/bionic/sched_getcpu.c b/libc/bionic/sched_getcpu.c
new file mode 100644
index 0000000..954df37
--- /dev/null
+++ b/libc/bionic/sched_getcpu.c
@@ -0,0 +1,40 @@
+/*
+ * 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.
+ */
+#define _GNU_SOURCE 1
+#include <sched.h>
+
+extern int  __getcpu(unsigned *cpu, unsigned *node, void* unused);
+
+int  sched_getcpu(void)
+{
+    unsigned cpu;
+    if (__getcpu(&cpu, NULL, NULL) < 0)
+        return 0;
+
+    return (int)cpu;
+}
diff --git a/libc/bionic/time64_config.h b/libc/bionic/time64_config.h
index 53bcecf..1385045 100644
--- a/libc/bionic/time64_config.h
+++ b/libc/bionic/time64_config.h
@@ -33,7 +33,7 @@
 */
 #define HAS_GMTIME_R
 #define HAS_LOCALTIME_R
-/*#define HAS_TIMEGM */
+#define HAS_TIMEGM
 
 
 /* Details of non-standard tm struct elements.
diff --git a/libc/docs/CHANGES.TXT b/libc/docs/CHANGES.TXT
index 0eab879..98b7fcf 100644
--- a/libc/docs/CHANGES.TXT
+++ b/libc/docs/CHANGES.TXT
@@ -1,7 +1,26 @@
 Bionic ChangeLog:
 -----------------
 
-Differences between current and Android 2.2:
+Differences between current and Android 2.3:
+
+- <android/api-level.h>: Added new header to define __ANDROID_API__ to
+  a constant integer corresponding to the native API level. This header
+  also exists in the NDK's platform headers.
+
+- <sys/cdefs.h>: Include <android/api-level.h>
+
+- <time.h>: Add timegm(), timelocal(), time2posix() and posix2time()
+
+- <sched.h>: Add sched_getcpu(), sched_getaffinity(), sched_setaffinity(),
+  cpu_set_t and related macros (e.g. CPU_SETSIZE, CPU_ZERO, CPU_SET, ...)
+
+- <unistd.h>: Add ftruncate64().
+
+- <signal.h>: Changed the definition of SIGRTMAX to 64. However, note that
+  sigset_t is only 32-bit and cannot deal with real-time signals.
+
+-------------------------------------------------------------------------------
+Differences between Android 2.3 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
diff --git a/libc/include/android/api-level.h b/libc/include/android/api-level.h
new file mode 100644
index 0000000..611fdfb
--- /dev/null
+++ b/libc/include/android/api-level.h
@@ -0,0 +1,33 @@
+/*
+ * 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 ANDROID_API_LEVEL_H
+#define ANDROID_API_LEVEL_H
+
+#define __ANDROID_API__ 10
+
+#endif /* ANDROID_API_LEVEL_H */
diff --git a/libc/include/netinet/in.h b/libc/include/netinet/in.h
index 0ebd926..7a4b6c7 100644
--- a/libc/include/netinet/in.h
+++ b/libc/include/netinet/in.h
@@ -38,6 +38,8 @@
 
 #define IPPORT_RESERVED  1024
 
+#define INET_ADDRSTRLEN 16
+
 extern int bindresvport (int sd, struct sockaddr_in *sin);
 
 static const struct in6_addr in6addr_any = IN6ADDR_ANY_INIT;
diff --git a/libc/include/netinet/in6.h b/libc/include/netinet/in6.h
index efd5c0a..580a510 100644
--- a/libc/include/netinet/in6.h
+++ b/libc/include/netinet/in6.h
@@ -78,6 +78,9 @@
 #define IPV6_ADDR_MC_SCOPE(a)	\
 	((a)->s6_addr[1] & 0x0f)
 
+#define IN6_IS_ADDR_MC_NODELOCAL(a)     \
+	(IN6_IS_ADDR_MULTICAST(a) &&  \
+	 (IPV6_ADDR_MC_SCOPE(a) == IPV6_ADDR_SCOPE_NODELOCAL))
 #define IN6_IS_ADDR_MC_LINKLOCAL(a)	\
 	(IN6_IS_ADDR_MULTICAST(a) &&  \
 	 (IPV6_ADDR_MC_SCOPE(a) == IPV6_ADDR_SCOPE_LINKLOCAL))
@@ -87,7 +90,9 @@
 #define IN6_IS_ADDR_MC_ORGLOCAL(a)     \
 	(IN6_IS_ADDR_MULTICAST(a) &&  \
 	 (IPV6_ADDR_MC_SCOPE(a) == IPV6_ADDR_SCOPE_ORGLOCAL))
-
+#define IN6_IS_ADDR_MC_GLOBAL(a)       \
+	(IN6_IS_ADDR_MULTICAST(a) &&  \
+	 (IPV6_ADDR_MC_SCOPE(a) == IPV6_ADDR_SCOPE_GLOBAL))
 
 #define IN6_ARE_ADDR_EQUAL(a, b)			\
     (memcmp(&(a)->s6_addr[0], &(b)->s6_addr[0], sizeof(struct in6_addr)) == 0)
diff --git a/libc/include/sched.h b/libc/include/sched.h
index e702470..ca72da7 100644
--- a/libc/include/sched.h
+++ b/libc/include/sched.h
@@ -73,6 +73,162 @@
 extern int clone(int (*fn)(void *), void *child_stack, int flags, void*  arg, ...);
 #endif
 
+/* Support for cpu thread affinity */
+#ifdef _GNU_SOURCE
+
+extern int sched_getcpu(void);
+
+
+/* Our implementation supports up to 32 independent CPUs, which is also
+ * the maximum supported by the kernel at the moment. GLibc uses 1024 by
+ * default.
+ *
+ * If you want to use more than that, you should use CPU_ALLOC() / CPU_FREE()
+ * and the CPU_XXX_S() macro variants.
+ */
+#define CPU_SETSIZE   32
+
+#define __CPU_BITTYPE    unsigned long int  /* mandated by the kernel  */
+#define __CPU_BITSHIFT   5                  /* should be log2(BITTYPE) */
+#define __CPU_BITS       (1 << __CPU_BITSHIFT)
+#define __CPU_ELT(x)     ((x) >> __CPU_BITSHIFT)
+#define __CPU_MASK(x)    ((__CPU_BITTYPE)1 << ((x) & (__CPU_BITS-1)))
+
+typedef struct {
+    __CPU_BITTYPE  __bits[ CPU_SETSIZE / __CPU_BITS ];
+} cpu_set_t;
+
+extern int sched_setaffinity(pid_t pid, size_t setsize, const cpu_set_t* set);
+
+extern int sched_getaffinity(pid_t pid, size_t setsize, cpu_set_t* set);
+
+/* Provide optimized implementation for 32-bit cpu_set_t */
+#if CPU_SETSIZE == __CPU_BITS
+
+#  define CPU_ZERO(set_)   \
+    do{ \
+        (set_)->__bits[0] = 0; \
+    }while(0)
+
+#  define CPU_SET(cpu_,set_) \
+    do {\
+        size_t __cpu = (cpu_); \
+        if (__cpu < CPU_SETSIZE) \
+            (set_)->__bits[0] |= __CPU_MASK(__cpu); \
+    }while (0)
+
+#  define CPU_CLR(cpu_,set_) \
+    do {\
+        size_t __cpu = (cpu_); \
+        if (__cpu < CPU_SETSIZE) \
+            (set_)->__bits[0] &= ~__CPU_MASK(__cpu); \
+    }while (0)
+
+#  define CPU_ISSET(cpu_, set_) \
+    (__extension__({\
+        size_t  __cpu = (cpu_); \
+        (cpu_ < CPU_SETSIZE) \
+            ? ((set_)->__bits[0] & __CPU_MASK(__cpu)) != 0 \
+            : 0; \
+    }))
+
+#  define CPU_EQUAL(set1_, set2_) \
+    ((set1_)->__bits[0] == (set2_)->__bits[0])
+
+#  define __CPU_OP(dst_, set1_, set2_, op_) \
+    do { \
+        (dst_)->__bits[0] = (set1_)->__bits[0] op_ (set2_)->__bits[0]; \
+    } while (0)
+
+#  define CPU_COUNT(set_)  __builtin_popcountl((set_)->__bits[0])
+
+#else /* CPU_SETSIZE != __CPU_BITS */
+
+#  define CPU_ZERO(set_)          CPU_ZERO_S(sizeof(cpu_set_t), set_)
+#  define CPU_SET(cpu_,set_)      CPU_SET_S(cpu_,sizeof(cpu_set_t),set_)
+#  define CPU_CLR(cpu_,set_)      CPU_CLR_S(cpu_,sizeof(cpu_set_t),set_)
+#  define CPU_ISSET(cpu_,set_)    CPU_ISSET_S(cpu_,sizeof(cpu_set_t),set_)
+#  define CPU_COUNT(set_)         CPU_COUNT_S(sizeof(cpu_set_t),set_)
+#  define CPU_EQUAL(set1_,set2_)  CPU_EQUAL_S(sizeof(cpu_set_t),set1_,set2_)
+
+#  define __CPU_OP(dst_,set1_,set2_,op_)  __CPU_OP_S(sizeof(cpu_set_t),dst_,set1_,set2_,op_)
+
+#endif /* CPU_SETSIZE != __CPU_BITS */
+
+#define CPU_AND(set1_,set2_)   __CPU_OP(set1_,set2_,&)
+#define CPU_OR(set1_,set2_)    __CPU_OP(set1_,set2_,|)
+#define CPU_XOR(set1_,set2_)   __CPU_OP(set1_,set2_,^)
+
+/* Support for dynamically-allocated cpu_set_t */
+
+#define CPU_ALLOC_SIZE(count) \
+    __CPU_ELT((count) + (__CPU_BITS-1))*sizeof(__CPU_BITTYPE)
+
+#define CPU_ALLOC(count)   __sched_cpualloc((count));
+#define CPU_FREE(set)      __sched_cpufree((set))
+
+extern cpu_set_t* __sched_cpualloc(size_t count);
+extern void       __sched_cpufree(cpu_set_t* set);
+
+#define CPU_ZERO_S(setsize_,set_)  \
+    do { \
+        size_t __nn = 0; \
+        size_t __nn_max = (setsize_)/sizeof(__CPU_BITTYPE); \
+        for (; __nn < __nn_max; __nn++) \
+            (set_)->__bits[__nn] = 0; \
+    } while (0)
+
+#define CPU_SET_S(cpu_,setsize_,set_) \
+    do { \
+        size_t __cpu = (cpu_); \
+        if (__cpu < 8*(setsize_)) \
+            (set_)->__bits[__CPU_ELT(__cpu)] |= __CPU_MASK(__cpu); \
+    } while (0)
+
+#define CPU_CLR_S(cpu_,setsize_,set_) \
+    do { \
+        size_t __cpu = (cpu_); \
+        if (__cpu < 8*(setsize_)) \
+            (set_)->__bits[__CPU_ELT(__cpu)] &= ~__CPU_MASK(__cpu); \
+    } while (0)
+
+#define CPU_ISSET_S(cpu_, setsize_, set_) \
+    (__extension__ ({ \
+        size_t __cpu = (cpu_); \
+        (__cpu < 8*(setsize_)) \
+          ? ((set_)->__bits[__CPU_ELT(__cpu)] & __CPU_MASK(__cpu)) != 0 \
+          : 0; \
+    }))
+
+#define CPU_EQUAL_S(setsize_, set1_, set2_) \
+    (__extension__ ({ \
+        __const __CPU_BITTYPE* __src1 = (set1_)->__bits; \
+        __const __CPU_BITTYPE* __src2 = (set2_)->__bits; \
+        size_t __nn = 0, __nn_max = (setsize_)/sizeof(__CPU_BITTYPE); \
+        for (; __nn < __nn_max; __nn++) { \
+            if (__src1[__nn] != __src2[__nn]) \
+                break; \
+        } \
+        __nn == __nn_max; \
+    }))
+
+#define __CPU_OP_S(setsize_, dstset_, srcset1_, srcset2_, op) \
+    do { \
+        cpu_set_t* __dst = (dstset); \
+        const __CPU_BITTYPE* __src1 = (srcset1)->__bits; \
+        const __CPU_BITTYPE* __src2 = (srcset2)->__bits; \
+        size_t __nn = 0, __nn_max = (setsize_)/sizeof(__CPU_BITTYPE); \
+        for (; __nn < __nn_max; __nn++) \
+            (__dst)->__bits[__nn] = __src1[__nn] op __src2[__nn]; \
+    } while (0)
+
+#define CPU_COUNT_S(setsize_, set_) \
+    __sched_cpucount((setsize_), (set_))
+
+extern int __sched_cpucount(size_t setsize, cpu_set_t* set);
+
+#endif /* _GNU_SOURCE */
+
 __END_DECLS
 
 #endif /* _SCHED_H_ */
diff --git a/libc/include/signal.h b/libc/include/signal.h
index 4401164..91c3b00 100644
--- a/libc/include/signal.h
+++ b/libc/include/signal.h
@@ -42,12 +42,15 @@
 
 typedef int sig_atomic_t;
 
-/* crepy NIG / _NSIG handling, just to be safe */
-#ifndef NSIG
-#  define NSIG  _NSIG
-#endif
+/* _NSIG is used by the SIGRTMAX definition under <asm/signal.h>, however
+ * its definition is part of a #if __KERNEL__ .. #endif block in the original
+ * kernel headers and is thus not part of our cleaned-up versions.
+ *
+ * Looking at the current kernel sources, it is defined as 64 for all
+ * architectures except for the 'mips' one which set it to 128.
+ */
 #ifndef _NSIG
-#  define _NSIG  NSIG
+#  define _NSIG  64
 #endif
 
 extern const char * const sys_siglist[];
diff --git a/libc/include/stdlib.h b/libc/include/stdlib.h
index 97d8e46..5dc8a87 100644
--- a/libc/include/stdlib.h
+++ b/libc/include/stdlib.h
@@ -57,6 +57,7 @@
 extern int unsetenv(const char *);
 extern int clearenv(void);
 
+extern char *mkdtemp(char *);
 extern char *mktemp (char *);
 extern int mkstemp (char *);
 
diff --git a/libc/include/sys/cdefs.h b/libc/include/sys/cdefs.h
index 849e2b8..9b6da31 100644
--- a/libc/include/sys/cdefs.h
+++ b/libc/include/sys/cdefs.h
@@ -497,5 +497,6 @@
 #endif
 
 #define  __BIONIC__   1
+#include <android/api-level.h>
 
 #endif /* !_SYS_CDEFS_H_ */
diff --git a/libc/include/sys/linux-syscalls.h b/libc/include/sys/linux-syscalls.h
index 9702a7a..cb4d5e5 100644
--- a/libc/include/sys/linux-syscalls.h
+++ b/libc/include/sys/linux-syscalls.h
@@ -71,6 +71,7 @@
 #define __NR_dup2                         (__NR_SYSCALL_BASE + 63)
 #define __NR__newselect                   (__NR_SYSCALL_BASE + 142)
 #define __NR_ftruncate                    (__NR_SYSCALL_BASE + 93)
+#define __NR_ftruncate64                  (__NR_SYSCALL_BASE + 194)
 #define __NR_fsync                        (__NR_SYSCALL_BASE + 118)
 #define __NR_fdatasync                    (__NR_SYSCALL_BASE + 148)
 #define __NR_fchown32                     (__NR_SYSCALL_BASE + 207)
@@ -120,6 +121,8 @@
 #define __NR_sched_get_priority_max       (__NR_SYSCALL_BASE + 159)
 #define __NR_sched_get_priority_min       (__NR_SYSCALL_BASE + 160)
 #define __NR_sched_rr_get_interval        (__NR_SYSCALL_BASE + 161)
+#define __NR_sched_setaffinity            (__NR_SYSCALL_BASE + 241)
+#define __NR_sched_getaffinity            (__NR_SYSCALL_BASE + 242)
 #define __NR_uname                        (__NR_SYSCALL_BASE + 122)
 #define __NR_wait4                        (__NR_SYSCALL_BASE + 114)
 #define __NR_umask                        (__NR_SYSCALL_BASE + 60)
@@ -174,6 +177,7 @@
 #define __NR_getsockopt                   (__NR_SYSCALL_BASE + 295)
 #define __NR_sendmsg                      (__NR_SYSCALL_BASE + 296)
 #define __NR_recvmsg                      (__NR_SYSCALL_BASE + 297)
+#define __NR_getcpu                       (__NR_SYSCALL_BASE + 345)
 #define __NR_ioprio_set                   (__NR_SYSCALL_BASE + 314)
 #define __NR_ioprio_get                   (__NR_SYSCALL_BASE + 315)
 #define __NR_epoll_create                 (__NR_SYSCALL_BASE + 250)
@@ -218,6 +222,7 @@
 #define __NR_timer_delete                 (__NR_SYSCALL_BASE + 263)
 #define __NR_utimes                       (__NR_SYSCALL_BASE + 271)
 #define __NR_socketcall                   (__NR_SYSCALL_BASE + 102)
+#define __NR_getcpu                       (__NR_SYSCALL_BASE + 318)
 #define __NR_ioprio_set                   (__NR_SYSCALL_BASE + 289)
 #define __NR_ioprio_get                   (__NR_SYSCALL_BASE + 290)
 #define __NR_epoll_create                 (__NR_SYSCALL_BASE + 254)
@@ -276,6 +281,7 @@
 #define __NR_socketcall                   (__NR_SYSCALL_BASE + 102)
 #define __NR_socketcall                   (__NR_SYSCALL_BASE + 102)
 #define __NR___socketcall                 (__NR_SYSCALL_BASE + 102)
+#define __NR_getcpu                       (__NR_SYSCALL_BASE + 318)
 #define __NR_ioprio_set                   (__NR_SYSCALL_BASE + 288)
 #define __NR_ioprio_get                   (__NR_SYSCALL_BASE + 289)
 #define __NR_epoll_create                 (__NR_SYSCALL_BASE + 254)
diff --git a/libc/include/sys/linux-unistd.h b/libc/include/sys/linux-unistd.h
index 51070bd..f706d00 100644
--- a/libc/include/sys/linux-unistd.h
+++ b/libc/include/sys/linux-unistd.h
@@ -52,8 +52,8 @@
 int              acct (const char*  filepath);
 ssize_t          read (int, void*, size_t);
 ssize_t          write (int, const void*, size_t);
-ssize_t          __pread64 (int, void *, size_t, off_t, off_t);
-ssize_t          __pwrite64 (int, void *, size_t, off_t, off_t);
+ssize_t          pread64 (int, void *, size_t, off64_t);
+ssize_t          pwrite64 (int, void *, size_t, off64_t);
 int              __open (const char*, int, mode_t);
 int              __openat (int, const char*, int, mode_t);
 int              close (int);
@@ -83,6 +83,7 @@
 int              dup2 (int, int);
 int              select (int, struct fd_set *, struct fd_set *, struct fd_set *, struct timeval *);
 int              ftruncate (int, off_t);
+int              ftruncate64 (int, off64_t);
 int              getdents (unsigned int, struct dirent *, unsigned int);
 int              fsync (int);
 int              fdatasync (int);
@@ -183,6 +184,9 @@
 int              sched_get_priority_max (int policy);
 int              sched_get_priority_min (int policy);
 int              sched_rr_get_interval (pid_t pid, struct timespec *interval);
+int              sched_setaffinity (pid_t pid, size_t setsize, const cpu_set_t* set);
+int              __sched_getaffinity (pid_t pid, size_t setsize, cpu_set_t* set);
+int              __getcpu (unsigned *cpu, unsigned *node, void *unused);
 int              ioprio_set (int which, int who, int ioprio);
 int              ioprio_get (int which, int who);
 int              uname (struct utsname *);
@@ -205,7 +209,6 @@
 int              eventfd (unsigned int, int);
 int              __set_tls (void*);
 int              cacheflush (long start, long end, long flags);
-int              eventfd (int count, int flags);
 #ifdef __cplusplus
 }
 #endif
diff --git a/libc/include/time.h b/libc/include/time.h
index 5d1a0e2..4ad4f7b 100644
--- a/libc/include/time.h
+++ b/libc/include/time.h
@@ -128,6 +128,11 @@
 extern int  timer_gettime(timer_t timerid, struct itimerspec *value);
 extern int  timer_getoverrun(timer_t  timerid);
 
+extern time_t timelocal(struct tm *tm);
+extern time_t timegm(struct tm* tm);
+extern time_t time2posix(time_t ti);
+extern time_t posix2time(time_t ti);
+
 __END_DECLS
 
 #endif /* _TIME_H_ */
diff --git a/libc/include/unistd.h b/libc/include/unistd.h
index 29154a2..4534fb9 100644
--- a/libc/include/unistd.h
+++ b/libc/include/unistd.h
@@ -128,12 +128,14 @@
 
 extern int close(int);
 extern off_t lseek(int, off_t, int);
-extern loff_t lseek64(int, loff_t, int);
+extern off64_t lseek64(int, off64_t, int);
 
 extern ssize_t read(int, void *, size_t);
 extern ssize_t write(int, const void *, size_t);
 extern ssize_t pread(int, void *, size_t, off_t);
-extern ssize_t pwrite(int, void *, size_t, off_t);
+extern ssize_t pread64(int, void *, size_t, off64_t);
+extern ssize_t pwrite(int, const void *, size_t, off_t);
+extern ssize_t pwrite64(int, const void *, size_t, off64_t);
 
 extern int dup(int);
 extern int dup2(int, int);
@@ -143,6 +145,7 @@
 extern int fsync(int);
 extern int fdatasync(int);
 extern int ftruncate(int, off_t);
+extern int ftruncate64(int, off64_t);
 
 extern int pause(void);
 extern unsigned int alarm(unsigned int);
diff --git a/libc/include/wchar.h b/libc/include/wchar.h
index 9b744a5..1361ff5 100644
--- a/libc/include/wchar.h
+++ b/libc/include/wchar.h
@@ -112,6 +112,7 @@
 extern int               vwprintf(const wchar_t *, va_list);
 extern int               vswprintf(wchar_t *, size_t, const wchar_t *, va_list);
 extern size_t            wcrtomb(char *, wchar_t, mbstate_t *);
+extern int               wcscasecmp(const wchar_t *, const wchar_t *);
 extern wchar_t          *wcscat(wchar_t *, const wchar_t *);
 extern wchar_t          *wcschr(const wchar_t *, wchar_t);
 extern int               wcscmp(const wchar_t *, const wchar_t *);
@@ -120,6 +121,7 @@
 extern size_t            wcscspn(const wchar_t *, const wchar_t *);
 extern size_t            wcsftime(wchar_t *, size_t, const wchar_t *, const struct tm *);
 extern size_t            wcslen(const wchar_t *);
+extern int               wcsncasecmp(const wchar_t *, const wchar_t *, size_t);
 extern wchar_t          *wcsncat(wchar_t *, const wchar_t *, size_t);
 extern int               wcsncmp(const wchar_t *, const wchar_t *, size_t);
 extern wchar_t          *wcsncpy(wchar_t *, const wchar_t *, size_t);
diff --git a/libc/kernel/arch-arm/asm/ptrace.h b/libc/kernel/arch-arm/asm/ptrace.h
index b6be08c..3faf738 100644
--- a/libc/kernel/arch-arm/asm/ptrace.h
+++ b/libc/kernel/arch-arm/asm/ptrace.h
@@ -30,6 +30,7 @@
 #define PTRACE_SETCRUNCHREGS 26
 
 #define PTRACE_GETVFPREGS 27
+#define PTRACE_SETVFPREGS 28
 
 #define USR26_MODE 0x00000000
 #define FIQ26_MODE 0x00000001
diff --git a/libc/kernel/common/linux/akm8975.h b/libc/kernel/common/linux/akm8975.h
new file mode 100644
index 0000000..1815f75
--- /dev/null
+++ b/libc/kernel/common/linux/akm8975.h
@@ -0,0 +1,72 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   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 AKM8975_H
+#define AKM8975_H
+
+#include <linux/ioctl.h>
+
+#define AK8975_MODE_SNG_MEASURE 0x01
+#define AK8975_MODE_SELF_TEST 0x08
+#define AK8975_MODE_FUSE_ACCESS 0x0F
+#define AK8975_MODE_POWER_DOWN 0x00
+
+#define RBUFF_SIZE 8  
+
+#define AK8975_REG_WIA 0x00
+#define AK8975_REG_INFO 0x01
+#define AK8975_REG_ST1 0x02
+#define AK8975_REG_HXL 0x03
+#define AK8975_REG_HXH 0x04
+#define AK8975_REG_HYL 0x05
+#define AK8975_REG_HYH 0x06
+#define AK8975_REG_HZL 0x07
+#define AK8975_REG_HZH 0x08
+#define AK8975_REG_ST2 0x09
+#define AK8975_REG_CNTL 0x0A
+#define AK8975_REG_RSV 0x0B
+#define AK8975_REG_ASTC 0x0C
+#define AK8975_REG_TS1 0x0D
+#define AK8975_REG_TS2 0x0E
+#define AK8975_REG_I2CDIS 0x0F
+
+#define AK8975_FUSE_ASAX 0x10
+#define AK8975_FUSE_ASAY 0x11
+#define AK8975_FUSE_ASAZ 0x12
+
+#define AKMIO 0xA1
+
+#define ECS_IOCTL_WRITE _IOW(AKMIO, 0x02, char[5])
+#define ECS_IOCTL_READ _IOWR(AKMIO, 0x03, char[5])
+#define ECS_IOCTL_GETDATA _IOR(AKMIO, 0x08, char[RBUFF_SIZE])
+#define ECS_IOCTL_SET_YPR _IOW(AKMIO, 0x0C, short[12])
+#define ECS_IOCTL_GET_OPEN_STATUS _IOR(AKMIO, 0x0D, int)
+#define ECS_IOCTL_GET_CLOSE_STATUS _IOR(AKMIO, 0x0E, int)
+#define ECS_IOCTL_GET_DELAY _IOR(AKMIO, 0x30, short)
+
+#define ECS_IOCTL_APP_SET_MFLAG _IOW(AKMIO, 0x11, short)
+#define ECS_IOCTL_APP_GET_MFLAG _IOW(AKMIO, 0x12, short)
+#define ECS_IOCTL_APP_SET_AFLAG _IOW(AKMIO, 0x13, short)
+#define ECS_IOCTL_APP_GET_AFLAG _IOR(AKMIO, 0x14, short)
+#define ECS_IOCTL_APP_SET_DELAY _IOW(AKMIO, 0x18, short)
+#define ECS_IOCTL_APP_GET_DELAY ECS_IOCTL_GET_DELAY
+#define ECS_IOCTL_APP_SET_MVFLAG _IOW(AKMIO, 0x19, short)  
+#define ECS_IOCTL_APP_GET_MVFLAG _IOR(AKMIO, 0x1A, short)  
+#define ECS_IOCTL_APP_SET_TFLAG _IOR(AKMIO, 0x15, short)
+
+#define ECS_INTR 140
+
+struct akm8975_platform_data {
+ int intr;
+};
+
+#endif
+
diff --git a/libc/kernel/common/linux/bmp085.h b/libc/kernel/common/linux/bmp085.h
new file mode 100644
index 0000000..650cb88
--- /dev/null
+++ b/libc/kernel/common/linux/bmp085.h
@@ -0,0 +1,29 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   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 __BMP085_H__
+#define __BMP085_H__
+
+#include <linux/ioctl.h>  
+
+#define BMP085_NAME "bmp085"
+
+#define BMP085_IOCTL_BASE 78
+
+#define BMP085_IOCTL_SET_DELAY _IOW(BMP085_IOCTL_BASE, 0, int)
+#define BMP085_IOCTL_GET_DELAY _IOR(BMP085_IOCTL_BASE, 1, int)
+#define BMP085_IOCTL_SET_ENABLE _IOW(BMP085_IOCTL_BASE, 2, int)
+#define BMP085_IOCTL_GET_ENABLE _IOR(BMP085_IOCTL_BASE, 3, int)
+#define BMP085_IOCTL_ACCURACY _IOW(BMP085_IOCTL_BASE, 4, int)
+
+#endif
+
+
diff --git a/libc/kernel/common/linux/cpcap_audio.h b/libc/kernel/common/linux/cpcap_audio.h
new file mode 100644
index 0000000..a59550f
--- /dev/null
+++ b/libc/kernel/common/linux/cpcap_audio.h
@@ -0,0 +1,65 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   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 _CPCAP_AUDIO_H
+#define _CPCAP_AUDIO_H
+
+#include <linux/ioctl.h>
+
+#define CPCAP_AUDIO_MAGIC 'c'
+
+#define CPCAP_AUDIO_OUT_SPEAKER 0
+#define CPCAP_AUDIO_OUT_HEADSET 1
+#define CPCAP_AUDIO_OUT_HEADSET_AND_SPEAKER 2
+#define CPCAP_AUDIO_OUT_STANDBY 3
+#define CPCAP_AUDIO_OUT_ANLG_DOCK_HEADSET 4
+#define CPCAP_AUDIO_OUT_MAX 4
+
+struct cpcap_audio_stream {
+ unsigned id;
+ int on;
+};
+
+#define CPCAP_AUDIO_OUT_SET_OUTPUT _IOW(CPCAP_AUDIO_MAGIC, 0,   const struct cpcap_audio_stream *)
+
+#define CPCAP_AUDIO_OUT_VOL_MIN 0
+#define CPCAP_AUDIO_OUT_VOL_MAX 15
+
+#define CPCAP_AUDIO_OUT_SET_VOLUME _IOW(CPCAP_AUDIO_MAGIC, 1, unsigned int)
+
+#define CPCAP_AUDIO_OUT_GET_OUTPUT   _IOR(CPCAP_AUDIO_MAGIC, 2, struct cpcap_audio_stream *)
+#define CPCAP_AUDIO_OUT_GET_VOLUME   _IOR(CPCAP_AUDIO_MAGIC, 3, unsigned int *)
+
+#define CPCAP_AUDIO_IN_MIC1 0
+#define CPCAP_AUDIO_IN_MIC2 1
+#define CPCAP_AUDIO_IN_STANDBY 2
+#define CPCAP_AUDIO_IN_MAX 2
+
+#define CPCAP_AUDIO_IN_SET_INPUT _IOW(CPCAP_AUDIO_MAGIC, 4,   const struct cpcap_audio_stream *)
+
+#define CPCAP_AUDIO_IN_GET_INPUT _IOR(CPCAP_AUDIO_MAGIC, 5,   struct cpcap_audio_stream *)
+
+#define CPCAP_AUDIO_IN_VOL_MIN 0
+#define CPCAP_AUDIO_IN_VOL_MAX 31
+
+#define CPCAP_AUDIO_IN_SET_VOLUME _IOW(CPCAP_AUDIO_MAGIC, 6, unsigned int)
+
+#define CPCAP_AUDIO_IN_GET_VOLUME _IOR(CPCAP_AUDIO_MAGIC, 7, unsigned int *)
+
+#define CPCAP_AUDIO_OUT_GET_RATE _IOR(CPCAP_AUDIO_MAGIC, 8, unsigned int *)
+#define CPCAP_AUDIO_OUT_SET_RATE _IOW(CPCAP_AUDIO_MAGIC, 9, unsigned int)
+#define CPCAP_AUDIO_IN_GET_RATE _IOR(CPCAP_AUDIO_MAGIC, 10, unsigned int *)
+#define CPCAP_AUDIO_IN_SET_RATE _IOW(CPCAP_AUDIO_MAGIC, 11, unsigned int)
+
+#define CPCAP_AUDIO_SET_BLUETOOTH_BYPASS _IOW(CPCAP_AUDIO_MAGIC, 12, unsigned int)
+
+#endif
+
diff --git a/libc/kernel/common/linux/hid.h b/libc/kernel/common/linux/hid.h
new file mode 100644
index 0000000..450db19
--- /dev/null
+++ b/libc/kernel/common/linux/hid.h
@@ -0,0 +1,36 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   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 __HID_H
+#define __HID_H
+
+#define USB_INTERFACE_CLASS_HID 3
+
+#define USB_INTERFACE_SUBCLASS_BOOT 1
+#define USB_INTERFACE_PROTOCOL_KEYBOARD 1
+#define USB_INTERFACE_PROTOCOL_MOUSE 2
+
+#define HID_REQ_GET_REPORT 0x01
+#define HID_REQ_GET_IDLE 0x02
+#define HID_REQ_GET_PROTOCOL 0x03
+#define HID_REQ_SET_REPORT 0x09
+#define HID_REQ_SET_IDLE 0x0A
+#define HID_REQ_SET_PROTOCOL 0x0B
+
+#define HID_DT_HID (USB_TYPE_CLASS | 0x01)
+#define HID_DT_REPORT (USB_TYPE_CLASS | 0x02)
+#define HID_DT_PHYSICAL (USB_TYPE_CLASS | 0x03)
+
+#define HID_MAX_DESCRIPTOR_SIZE 4096
+
+#endif
+
+
diff --git a/libc/kernel/common/linux/hidraw.h b/libc/kernel/common/linux/hidraw.h
new file mode 100644
index 0000000..0681ece
--- /dev/null
+++ b/libc/kernel/common/linux/hidraw.h
@@ -0,0 +1,41 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   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 _HIDRAW_H
+#define _HIDRAW_H
+
+#include <linux/hid.h>
+#include <linux/types.h>
+
+struct hidraw_report_descriptor {
+ __u32 size;
+ __u8 value[HID_MAX_DESCRIPTOR_SIZE];
+};
+
+struct hidraw_devinfo {
+ __u32 bustype;
+ __s16 vendor;
+ __s16 product;
+};
+
+#define HIDIOCGRDESCSIZE _IOR('H', 0x01, int)
+#define HIDIOCGRDESC _IOR('H', 0x02, struct hidraw_report_descriptor)
+#define HIDIOCGRAWINFO _IOR('H', 0x03, struct hidraw_devinfo)
+#define HIDIOCGRAWNAME(len) _IOC(_IOC_READ, 'H', 0x04, len)
+#define HIDIOCGRAWPHYS(len) _IOC(_IOC_READ, 'H', 0x05, len)
+
+#define HIDRAW_FIRST_MINOR 0
+#define HIDRAW_MAX_DEVICES 64
+
+#define HIDRAW_BUFFER_SIZE 64
+
+#endif
+
diff --git a/libc/kernel/common/linux/if.h b/libc/kernel/common/linux/if.h
index 47c29d9..7db4888 100644
--- a/libc/kernel/common/linux/if.h
+++ b/libc/kernel/common/linux/if.h
@@ -17,6 +17,7 @@
 #include <linux/compiler.h>  
 
 #define IFNAMSIZ 16
+#define IFALIASZ 256
 #include <linux/hdlc/ioctl.h>
 
 #define IFF_UP 0x1  
@@ -42,13 +43,24 @@
 #define IFF_LOWER_UP 0x10000  
 #define IFF_DORMANT 0x20000  
 
-#define IFF_VOLATILE (IFF_LOOPBACK|IFF_POINTOPOINT|IFF_BROADCAST|  IFF_MASTER|IFF_SLAVE|IFF_RUNNING|IFF_LOWER_UP|IFF_DORMANT)
+#define IFF_ECHO 0x40000  
+
+#define IFF_VOLATILE (IFF_LOOPBACK|IFF_POINTOPOINT|IFF_BROADCAST|IFF_ECHO|  IFF_MASTER|IFF_SLAVE|IFF_RUNNING|IFF_LOWER_UP|IFF_DORMANT)
 
 #define IFF_802_1Q_VLAN 0x1  
 #define IFF_EBRIDGE 0x2  
 #define IFF_SLAVE_INACTIVE 0x4  
 #define IFF_MASTER_8023AD 0x8  
 #define IFF_MASTER_ALB 0x10  
+#define IFF_BONDING 0x20  
+#define IFF_SLAVE_NEEDARP 0x40  
+#define IFF_ISATAP 0x80  
+#define IFF_MASTER_ARPMON 0x100  
+#define IFF_WAN_HDLC 0x200  
+#define IFF_XMIT_DST_RELEASE 0x400  
+#define IFF_DONT_BRIDGE 0x800  
+#define IFF_IN_NETPOLL 0x1000  
+#define IFF_DISABLE_NETPOLL 0x2000  
 
 #define IF_GET_IFACE 0x0001  
 #define IF_GET_PROTO 0x0002
@@ -90,8 +102,7 @@
  IF_LINK_MODE_DORMANT,
 };
 
-struct ifmap
-{
+struct ifmap {
  unsigned long mem_start;
  unsigned long mem_end;
  unsigned short base_addr;
@@ -101,8 +112,7 @@
 
 };
 
-struct if_settings
-{
+struct if_settings {
  unsigned int type;
  unsigned int size;
  union {
@@ -118,8 +128,7 @@
  } ifs_ifsu;
 };
 
-struct ifreq
-{
+struct ifreq {
 #define IFHWADDRLEN 6
  union
  {
@@ -161,11 +170,9 @@
 #define ifr_newname ifr_ifru.ifru_newname  
 #define ifr_settings ifr_ifru.ifru_settings  
 
-struct ifconf
-{
+struct ifconf {
  int ifc_len;
- union
- {
+ union {
  char __user *ifcu_buf;
  struct ifreq __user *ifcu_req;
  } ifc_ifcu;
@@ -174,3 +181,4 @@
 #define ifc_req ifc_ifcu.ifcu_req  
 
 #endif
+
diff --git a/libc/kernel/common/linux/if_vlan.h b/libc/kernel/common/linux/if_vlan.h
index d3d2df2..ab3b174 100644
--- a/libc/kernel/common/linux/if_vlan.h
+++ b/libc/kernel/common/linux/if_vlan.h
@@ -25,6 +25,12 @@
  GET_VLAN_VID_CMD
 };
 
+enum vlan_flags {
+ VLAN_FLAG_REORDER_HDR = 0x1,
+ VLAN_FLAG_GVRP = 0x2,
+ VLAN_FLAG_LOOSE_BINDING = 0x4,
+};
+
 enum vlan_name_types {
  VLAN_NAME_TYPE_PLUS_VID,
  VLAN_NAME_TYPE_RAW_PLUS_VID,
@@ -50,3 +56,4 @@
 };
 
 #endif
+
diff --git a/libc/kernel/common/linux/in_route.h b/libc/kernel/common/linux/in_route.h
new file mode 100644
index 0000000..34e14d6
--- /dev/null
+++ b/libc/kernel/common/linux/in_route.h
@@ -0,0 +1,41 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   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 _LINUX_IN_ROUTE_H
+#define _LINUX_IN_ROUTE_H
+
+#define RTCF_DEAD RTNH_F_DEAD
+#define RTCF_ONLINK RTNH_F_ONLINK
+
+#define RTCF_NOPMTUDISC RTM_F_NOPMTUDISC
+
+#define RTCF_NOTIFY 0x00010000
+#define RTCF_DIRECTDST 0x00020000  
+#define RTCF_REDIRECTED 0x00040000
+#define RTCF_TPROXY 0x00080000  
+
+#define RTCF_FAST 0x00200000  
+#define RTCF_MASQ 0x00400000  
+#define RTCF_SNAT 0x00800000  
+#define RTCF_DOREDIRECT 0x01000000
+#define RTCF_DIRECTSRC 0x04000000
+#define RTCF_DNAT 0x08000000
+#define RTCF_BROADCAST 0x10000000
+#define RTCF_MULTICAST 0x20000000
+#define RTCF_REJECT 0x40000000  
+#define RTCF_LOCAL 0x80000000
+
+#define RTCF_NAT (RTCF_DNAT|RTCF_SNAT)
+
+#define RT_TOS(tos) ((tos)&IPTOS_TOS_MASK)
+
+#endif
+
diff --git a/libc/kernel/common/linux/kxtf9.h b/libc/kernel/common/linux/kxtf9.h
new file mode 100644
index 0000000..9141364
--- /dev/null
+++ b/libc/kernel/common/linux/kxtf9.h
@@ -0,0 +1,70 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   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 __KXTF9_H__
+#define __KXTF9_H__
+
+#include <linux/ioctl.h>  
+
+#define KXTF9_IOCTL_BASE 77
+
+#define KXTF9_IOCTL_SET_DELAY _IOW(KXTF9_IOCTL_BASE, 0, int)
+#define KXTF9_IOCTL_GET_DELAY _IOR(KXTF9_IOCTL_BASE, 1, int)
+#define KXTF9_IOCTL_SET_ENABLE _IOW(KXTF9_IOCTL_BASE, 2, int)
+#define KXTF9_IOCTL_GET_ENABLE _IOR(KXTF9_IOCTL_BASE, 3, int)
+#define KXTF9_IOCTL_SET_G_RANGE _IOW(KXTF9_IOCTL_BASE, 4, int)
+
+#define KXTF9_IOCTL_SET_TILT_ENABLE _IOW(KXTF9_IOCTL_BASE, 5, int)
+#define KXTF9_IOCTL_SET_TAP_ENABLE _IOW(KXTF9_IOCTL_BASE, 6, int)
+#define KXTF9_IOCTL_SET_WAKE_ENABLE _IOW(KXTF9_IOCTL_BASE, 7, int)
+#define KXTF9_IOCTL_SET_PM_MODE _IOW(KXTF9_IOCTL_BASE, 8, int)
+#define KXTF9_IOCTL_SELF_TEST _IOW(KXTF9_IOCTL_BASE, 9, int)
+#define KXTF9_IOCTL_SET_SENSITIVITY _IOW(KXTF9_IOCTL_BASE, 10, int)
+
+#define RES_12BIT 0x40
+#define KXTF9_G_2G 0x00
+#define KXTF9_G_4G 0x08
+#define KXTF9_G_8G 0x10
+#define TPE 0x01  
+#define WUFE 0x02  
+#define TDTE 0x04  
+
+#define OTP1_6 0x00  
+#define OTP6_3 0x20
+#define OTP12_5 0x40
+#define OTP50 0x60
+#define OWUF25 0x00  
+#define OWUF50 0x01
+#define OWUF100 0x02
+#define OWUF200 0x03
+#define OTDT50 0x00  
+#define OTDT100 0x04
+#define OTDT200 0x08
+#define OTDT400 0x0C
+
+#define IEN 0x20  
+#define IEA 0x10  
+#define IEL 0x08  
+#define IEU 0x04  
+
+#define ODR800 0x06  
+#define ODR400 0x05
+#define ODR200 0x04
+#define ODR100 0x03
+#define ODR50 0x02
+#define ODR25 0x01
+#define ODR12_5 0x00
+
+#define SENSITIVITY_REGS 0x07
+
+#endif
+
+
diff --git a/libc/kernel/common/linux/l3g4200d.h b/libc/kernel/common/linux/l3g4200d.h
new file mode 100644
index 0000000..0a0f8cd
--- /dev/null
+++ b/libc/kernel/common/linux/l3g4200d.h
@@ -0,0 +1,27 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   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 __L3G4200D_H__
+#define __L3G4200D_H__
+
+#include <linux/ioctl.h>  
+
+#define L3G4200D_NAME "l3g4200d"
+
+#define L3G4200D_IOCTL_BASE 77
+
+#define L3G4200D_IOCTL_SET_DELAY _IOW(L3G4200D_IOCTL_BASE, 0, int)
+#define L3G4200D_IOCTL_GET_DELAY _IOR(L3G4200D_IOCTL_BASE, 1, int)
+#define L3G4200D_IOCTL_SET_ENABLE _IOW(L3G4200D_IOCTL_BASE, 2, int)
+#define L3G4200D_IOCTL_GET_ENABLE _IOR(L3G4200D_IOCTL_BASE, 3, int)
+
+#endif
+
diff --git a/libc/kernel/common/linux/max9635.h b/libc/kernel/common/linux/max9635.h
new file mode 100644
index 0000000..e696fa9
--- /dev/null
+++ b/libc/kernel/common/linux/max9635.h
@@ -0,0 +1,23 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   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 _LINUX_MAX9635_H__
+#define _LINUX_MAX9635_H__
+
+#define MAX9635_NAME "MAX9635_als"
+#define FOPS_MAX9635_NAME "MAX9635"
+
+#define MAX9635_IO 0xA3
+
+#define MAX9635_IOCTL_GET_ENABLE _IOR(MAX9635_IO, 0x00, char)
+#define MAX9635_IOCTL_SET_ENABLE _IOW(MAX9635_IO, 0x01, char)
+
+#endif
diff --git a/libc/kernel/common/linux/perf_event.h b/libc/kernel/common/linux/perf_event.h
new file mode 100644
index 0000000..9d3cd14
--- /dev/null
+++ b/libc/kernel/common/linux/perf_event.h
@@ -0,0 +1,240 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   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 _LINUX_PERF_EVENT_H
+#define _LINUX_PERF_EVENT_H
+
+#include <linux/types.h>
+#include <linux/ioctl.h>
+#include <asm/byteorder.h>
+
+enum perf_type_id {
+ PERF_TYPE_HARDWARE = 0,
+ PERF_TYPE_SOFTWARE = 1,
+ PERF_TYPE_TRACEPOINT = 2,
+ PERF_TYPE_HW_CACHE = 3,
+ PERF_TYPE_RAW = 4,
+ PERF_TYPE_BREAKPOINT = 5,
+
+ PERF_TYPE_MAX,
+};
+
+enum perf_hw_id {
+
+ PERF_COUNT_HW_CPU_CYCLES = 0,
+ PERF_COUNT_HW_INSTRUCTIONS = 1,
+ PERF_COUNT_HW_CACHE_REFERENCES = 2,
+ PERF_COUNT_HW_CACHE_MISSES = 3,
+ PERF_COUNT_HW_BRANCH_INSTRUCTIONS = 4,
+ PERF_COUNT_HW_BRANCH_MISSES = 5,
+ PERF_COUNT_HW_BUS_CYCLES = 6,
+
+ PERF_COUNT_HW_MAX,
+};
+
+enum perf_hw_cache_id {
+ PERF_COUNT_HW_CACHE_L1D = 0,
+ PERF_COUNT_HW_CACHE_L1I = 1,
+ PERF_COUNT_HW_CACHE_LL = 2,
+ PERF_COUNT_HW_CACHE_DTLB = 3,
+ PERF_COUNT_HW_CACHE_ITLB = 4,
+ PERF_COUNT_HW_CACHE_BPU = 5,
+
+ PERF_COUNT_HW_CACHE_MAX,
+};
+
+enum perf_hw_cache_op_id {
+ PERF_COUNT_HW_CACHE_OP_READ = 0,
+ PERF_COUNT_HW_CACHE_OP_WRITE = 1,
+ PERF_COUNT_HW_CACHE_OP_PREFETCH = 2,
+
+ PERF_COUNT_HW_CACHE_OP_MAX,
+};
+
+enum perf_hw_cache_op_result_id {
+ PERF_COUNT_HW_CACHE_RESULT_ACCESS = 0,
+ PERF_COUNT_HW_CACHE_RESULT_MISS = 1,
+
+ PERF_COUNT_HW_CACHE_RESULT_MAX,
+};
+
+enum perf_sw_ids {
+ PERF_COUNT_SW_CPU_CLOCK = 0,
+ PERF_COUNT_SW_TASK_CLOCK = 1,
+ PERF_COUNT_SW_PAGE_FAULTS = 2,
+ PERF_COUNT_SW_CONTEXT_SWITCHES = 3,
+ PERF_COUNT_SW_CPU_MIGRATIONS = 4,
+ PERF_COUNT_SW_PAGE_FAULTS_MIN = 5,
+ PERF_COUNT_SW_PAGE_FAULTS_MAJ = 6,
+ PERF_COUNT_SW_ALIGNMENT_FAULTS = 7,
+ PERF_COUNT_SW_EMULATION_FAULTS = 8,
+
+ PERF_COUNT_SW_MAX,
+};
+
+enum perf_event_sample_format {
+ PERF_SAMPLE_IP = 1U << 0,
+ PERF_SAMPLE_TID = 1U << 1,
+ PERF_SAMPLE_TIME = 1U << 2,
+ PERF_SAMPLE_ADDR = 1U << 3,
+ PERF_SAMPLE_READ = 1U << 4,
+ PERF_SAMPLE_CALLCHAIN = 1U << 5,
+ PERF_SAMPLE_ID = 1U << 6,
+ PERF_SAMPLE_CPU = 1U << 7,
+ PERF_SAMPLE_PERIOD = 1U << 8,
+ PERF_SAMPLE_STREAM_ID = 1U << 9,
+ PERF_SAMPLE_RAW = 1U << 10,
+
+ PERF_SAMPLE_MAX = 1U << 11,
+};
+
+enum perf_event_read_format {
+ PERF_FORMAT_TOTAL_TIME_ENABLED = 1U << 0,
+ PERF_FORMAT_TOTAL_TIME_RUNNING = 1U << 1,
+ PERF_FORMAT_ID = 1U << 2,
+ PERF_FORMAT_GROUP = 1U << 3,
+
+ PERF_FORMAT_MAX = 1U << 4,
+};
+
+#define PERF_ATTR_SIZE_VER0 64  
+
+struct perf_event_attr {
+
+ __u32 type;
+
+ __u32 size;
+
+ __u64 config;
+
+ union {
+ __u64 sample_period;
+ __u64 sample_freq;
+ };
+
+ __u64 sample_type;
+ __u64 read_format;
+
+ __u64 disabled : 1,
+ inherit : 1,
+ pinned : 1,
+ exclusive : 1,
+ exclude_user : 1,
+ exclude_kernel : 1,
+ exclude_hv : 1,
+ exclude_idle : 1,
+ mmap : 1,
+ comm : 1,
+ freq : 1,
+ inherit_stat : 1,
+ enable_on_exec : 1,
+ task : 1,
+ watermark : 1,
+
+ precise_ip : 2,
+
+ __reserved_1 : 47;
+
+ union {
+ __u32 wakeup_events;
+ __u32 wakeup_watermark;
+ };
+
+ __u32 bp_type;
+ __u64 bp_addr;
+ __u64 bp_len;
+};
+
+#define PERF_EVENT_IOC_ENABLE _IO ('$', 0)
+#define PERF_EVENT_IOC_DISABLE _IO ('$', 1)
+#define PERF_EVENT_IOC_REFRESH _IO ('$', 2)
+#define PERF_EVENT_IOC_RESET _IO ('$', 3)
+#define PERF_EVENT_IOC_PERIOD _IOW('$', 4, __u64)
+#define PERF_EVENT_IOC_SET_OUTPUT _IO ('$', 5)
+#define PERF_EVENT_IOC_SET_FILTER _IOW('$', 6, char *)
+
+enum perf_event_ioc_flags {
+ PERF_IOC_FLAG_GROUP = 1U << 0,
+};
+
+struct perf_event_mmap_page {
+ __u32 version;
+ __u32 compat_version;
+
+ __u32 lock;
+ __u32 index;
+ __s64 offset;
+ __u64 time_enabled;
+ __u64 time_running;
+
+ __u64 __reserved[123];
+
+ __u64 data_head;
+ __u64 data_tail;
+};
+
+#define PERF_RECORD_MISC_CPUMODE_MASK (7 << 0)
+#define PERF_RECORD_MISC_CPUMODE_UNKNOWN (0 << 0)
+#define PERF_RECORD_MISC_KERNEL (1 << 0)
+#define PERF_RECORD_MISC_USER (2 << 0)
+#define PERF_RECORD_MISC_HYPERVISOR (3 << 0)
+#define PERF_RECORD_MISC_GUEST_KERNEL (4 << 0)
+#define PERF_RECORD_MISC_GUEST_USER (5 << 0)
+
+#define PERF_RECORD_MISC_EXACT_IP (1 << 14)
+
+#define PERF_RECORD_MISC_EXT_RESERVED (1 << 15)
+
+struct perf_event_header {
+ __u32 type;
+ __u16 misc;
+ __u16 size;
+};
+
+enum perf_event_type {
+
+ PERF_RECORD_MMAP = 1,
+
+ PERF_RECORD_LOST = 2,
+
+ PERF_RECORD_COMM = 3,
+
+ PERF_RECORD_EXIT = 4,
+
+ PERF_RECORD_THROTTLE = 5,
+ PERF_RECORD_UNTHROTTLE = 6,
+
+ PERF_RECORD_FORK = 7,
+
+ PERF_RECORD_READ = 8,
+
+ PERF_RECORD_SAMPLE = 9,
+
+ PERF_RECORD_MAX,
+};
+
+enum perf_callchain_context {
+ PERF_CONTEXT_HV = (__u64)-32,
+ PERF_CONTEXT_KERNEL = (__u64)-128,
+ PERF_CONTEXT_USER = (__u64)-512,
+
+ PERF_CONTEXT_GUEST = (__u64)-2048,
+ PERF_CONTEXT_GUEST_KERNEL = (__u64)-2176,
+ PERF_CONTEXT_GUEST_USER = (__u64)-2560,
+
+ PERF_CONTEXT_MAX = (__u64)-4095,
+};
+
+#define PERF_FLAG_FD_NO_GROUP (1U << 0)
+#define PERF_FLAG_FD_OUTPUT (1U << 1)
+
+#endif
+
diff --git a/libc/kernel/common/linux/spi/cpcap.h b/libc/kernel/common/linux/spi/cpcap.h
new file mode 100644
index 0000000..24bc918
--- /dev/null
+++ b/libc/kernel/common/linux/spi/cpcap.h
@@ -0,0 +1,587 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   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 _LINUX_SPI_CPCAP_H
+#define _LINUX_SPI_CPCAP_H
+
+#include <linux/ioctl.h>
+
+#define CPCAP_DEV_NAME "cpcap"
+#define CPCAP_NUM_REG_CPCAP (CPCAP_REG_END - CPCAP_REG_START + 1)
+
+#define CPCAP_IRQ_INT1_INDEX 0
+#define CPCAP_IRQ_INT2_INDEX 16
+#define CPCAP_IRQ_INT3_INDEX 32
+#define CPCAP_IRQ_INT4_INDEX 48
+#define CPCAP_IRQ_INT5_INDEX 64
+
+#define CPCAP_HWCFG_NUM 2  
+
+#define CPCAP_HWCFG0_SEC_STBY_SW1 0x0001
+#define CPCAP_HWCFG0_SEC_STBY_SW2 0x0002
+#define CPCAP_HWCFG0_SEC_STBY_SW3 0x0004
+#define CPCAP_HWCFG0_SEC_STBY_SW4 0x0008
+#define CPCAP_HWCFG0_SEC_STBY_SW5 0x0010
+#define CPCAP_HWCFG0_SEC_STBY_VAUDIO 0x0020
+#define CPCAP_HWCFG0_SEC_STBY_VCAM 0x0040
+#define CPCAP_HWCFG0_SEC_STBY_VCSI 0x0080
+#define CPCAP_HWCFG0_SEC_STBY_VDAC 0x0100
+#define CPCAP_HWCFG0_SEC_STBY_VDIG 0x0200
+#define CPCAP_HWCFG0_SEC_STBY_VHVIO 0x0400
+#define CPCAP_HWCFG0_SEC_STBY_VPLL 0x0800
+#define CPCAP_HWCFG0_SEC_STBY_VRF1 0x1000
+#define CPCAP_HWCFG0_SEC_STBY_VRF2 0x2000
+#define CPCAP_HWCFG0_SEC_STBY_VRFREF 0x4000
+#define CPCAP_HWCFG0_SEC_STBY_VSDIO 0x8000
+
+#define CPCAP_HWCFG1_SEC_STBY_VWLAN1 0x0001
+#define CPCAP_HWCFG1_SEC_STBY_VWLAN2 0x0002
+#define CPCAP_HWCFG1_SEC_STBY_VSIM 0x0004
+#define CPCAP_HWCFG1_SEC_STBY_VSIMCARD 0x0008
+
+#define CPCAP_WHISPER_MODE_PU 0x00000001
+#define CPCAP_WHISPER_ENABLE_UART 0x00000002
+#define CPCAP_WHISPER_ACCY_MASK 0xF8000000
+#define CPCAP_WHISPER_ACCY_SHFT 27
+#define CPCAP_WHISPER_ID_SIZE 16
+#define CPCAP_WHISPER_PROP_SIZE 7
+
+enum cpcap_regulator_id {
+ CPCAP_SW2,
+ CPCAP_SW4,
+ CPCAP_SW5,
+ CPCAP_VCAM,
+ CPCAP_VCSI,
+ CPCAP_VDAC,
+ CPCAP_VDIG,
+ CPCAP_VFUSE,
+ CPCAP_VHVIO,
+ CPCAP_VSDIO,
+ CPCAP_VPLL,
+ CPCAP_VRF1,
+ CPCAP_VRF2,
+ CPCAP_VRFREF,
+ CPCAP_VWLAN1,
+ CPCAP_VWLAN2,
+ CPCAP_VSIM,
+ CPCAP_VSIMCARD,
+ CPCAP_VVIB,
+ CPCAP_VUSB,
+ CPCAP_VAUDIO,
+ CPCAP_NUM_REGULATORS
+};
+
+enum cpcap_reg {
+ CPCAP_REG_START,
+
+ CPCAP_REG_INT1 = CPCAP_REG_START,
+ CPCAP_REG_INT2,
+ CPCAP_REG_INT3,
+ CPCAP_REG_INT4,
+ CPCAP_REG_INTM1,
+ CPCAP_REG_INTM2,
+ CPCAP_REG_INTM3,
+ CPCAP_REG_INTM4,
+ CPCAP_REG_INTS1,
+ CPCAP_REG_INTS2,
+ CPCAP_REG_INTS3,
+ CPCAP_REG_INTS4,
+ CPCAP_REG_ASSIGN1,
+ CPCAP_REG_ASSIGN2,
+ CPCAP_REG_ASSIGN3,
+ CPCAP_REG_ASSIGN4,
+ CPCAP_REG_ASSIGN5,
+ CPCAP_REG_ASSIGN6,
+ CPCAP_REG_VERSC1,
+ CPCAP_REG_VERSC2,
+
+ CPCAP_REG_MI1,
+ CPCAP_REG_MIM1,
+ CPCAP_REG_MI2,
+ CPCAP_REG_MIM2,
+ CPCAP_REG_UCC1,
+ CPCAP_REG_UCC2,
+ CPCAP_REG_PC1,
+ CPCAP_REG_PC2,
+ CPCAP_REG_BPEOL,
+ CPCAP_REG_PGC,
+ CPCAP_REG_MT1,
+ CPCAP_REG_MT2,
+ CPCAP_REG_MT3,
+ CPCAP_REG_PF,
+
+ CPCAP_REG_SCC,
+ CPCAP_REG_SW1,
+ CPCAP_REG_SW2,
+ CPCAP_REG_UCTM,
+ CPCAP_REG_TOD1,
+ CPCAP_REG_TOD2,
+ CPCAP_REG_TODA1,
+ CPCAP_REG_TODA2,
+ CPCAP_REG_DAY,
+ CPCAP_REG_DAYA,
+ CPCAP_REG_VAL1,
+ CPCAP_REG_VAL2,
+
+ CPCAP_REG_SDVSPLL,
+ CPCAP_REG_SI2CC1,
+ CPCAP_REG_Si2CC2,
+ CPCAP_REG_S1C1,
+ CPCAP_REG_S1C2,
+ CPCAP_REG_S2C1,
+ CPCAP_REG_S2C2,
+ CPCAP_REG_S3C,
+ CPCAP_REG_S4C1,
+ CPCAP_REG_S4C2,
+ CPCAP_REG_S5C,
+ CPCAP_REG_S6C,
+ CPCAP_REG_VCAMC,
+ CPCAP_REG_VCSIC,
+ CPCAP_REG_VDACC,
+ CPCAP_REG_VDIGC,
+ CPCAP_REG_VFUSEC,
+ CPCAP_REG_VHVIOC,
+ CPCAP_REG_VSDIOC,
+ CPCAP_REG_VPLLC,
+ CPCAP_REG_VRF1C,
+ CPCAP_REG_VRF2C,
+ CPCAP_REG_VRFREFC,
+ CPCAP_REG_VWLAN1C,
+ CPCAP_REG_VWLAN2C,
+ CPCAP_REG_VSIMC,
+ CPCAP_REG_VVIBC,
+ CPCAP_REG_VUSBC,
+ CPCAP_REG_VUSBINT1C,
+ CPCAP_REG_VUSBINT2C,
+ CPCAP_REG_URT,
+ CPCAP_REG_URM1,
+ CPCAP_REG_URM2,
+
+ CPCAP_REG_VAUDIOC,
+ CPCAP_REG_CC,
+ CPCAP_REG_CDI,
+ CPCAP_REG_SDAC,
+ CPCAP_REG_SDACDI,
+ CPCAP_REG_TXI,
+ CPCAP_REG_TXMP,
+ CPCAP_REG_RXOA,
+ CPCAP_REG_RXVC,
+ CPCAP_REG_RXCOA,
+ CPCAP_REG_RXSDOA,
+ CPCAP_REG_RXEPOA,
+ CPCAP_REG_RXLL,
+ CPCAP_REG_A2LA,
+ CPCAP_REG_MIPIS1,
+ CPCAP_REG_MIPIS2,
+ CPCAP_REG_MIPIS3,
+ CPCAP_REG_LVAB,
+
+ CPCAP_REG_CCC1,
+ CPCAP_REG_CRM,
+ CPCAP_REG_CCCC2,
+ CPCAP_REG_CCS1,
+ CPCAP_REG_CCS2,
+ CPCAP_REG_CCA1,
+ CPCAP_REG_CCA2,
+ CPCAP_REG_CCM,
+ CPCAP_REG_CCO,
+ CPCAP_REG_CCI,
+
+ CPCAP_REG_ADCC1,
+ CPCAP_REG_ADCC2,
+ CPCAP_REG_ADCD0,
+ CPCAP_REG_ADCD1,
+ CPCAP_REG_ADCD2,
+ CPCAP_REG_ADCD3,
+ CPCAP_REG_ADCD4,
+ CPCAP_REG_ADCD5,
+ CPCAP_REG_ADCD6,
+ CPCAP_REG_ADCD7,
+ CPCAP_REG_ADCAL1,
+ CPCAP_REG_ADCAL2,
+
+ CPCAP_REG_USBC1,
+ CPCAP_REG_USBC2,
+ CPCAP_REG_USBC3,
+ CPCAP_REG_UVIDL,
+ CPCAP_REG_UVIDH,
+ CPCAP_REG_UPIDL,
+ CPCAP_REG_UPIDH,
+ CPCAP_REG_UFC1,
+ CPCAP_REG_UFC2,
+ CPCAP_REG_UFC3,
+ CPCAP_REG_UIC1,
+ CPCAP_REG_UIC2,
+ CPCAP_REG_UIC3,
+ CPCAP_REG_USBOTG1,
+ CPCAP_REG_USBOTG2,
+ CPCAP_REG_USBOTG3,
+ CPCAP_REG_UIER1,
+ CPCAP_REG_UIER2,
+ CPCAP_REG_UIER3,
+ CPCAP_REG_UIEF1,
+ CPCAP_REG_UIEF2,
+ CPCAP_REG_UIEF3,
+ CPCAP_REG_UIS,
+ CPCAP_REG_UIL,
+ CPCAP_REG_USBD,
+ CPCAP_REG_SCR1,
+ CPCAP_REG_SCR2,
+ CPCAP_REG_SCR3,
+ CPCAP_REG_VMC,
+ CPCAP_REG_OWDC,
+ CPCAP_REG_GPIO0,
+ CPCAP_REG_GPIO1,
+ CPCAP_REG_GPIO2,
+ CPCAP_REG_GPIO3,
+ CPCAP_REG_GPIO4,
+ CPCAP_REG_GPIO5,
+ CPCAP_REG_GPIO6,
+
+ CPCAP_REG_MDLC,
+ CPCAP_REG_KLC,
+ CPCAP_REG_ADLC,
+ CPCAP_REG_REDC,
+ CPCAP_REG_GREENC,
+ CPCAP_REG_BLUEC,
+ CPCAP_REG_CFC,
+ CPCAP_REG_ABC,
+ CPCAP_REG_BLEDC,
+ CPCAP_REG_CLEDC,
+
+ CPCAP_REG_OW1C,
+ CPCAP_REG_OW1D,
+ CPCAP_REG_OW1I,
+ CPCAP_REG_OW1IE,
+ CPCAP_REG_OW1,
+ CPCAP_REG_OW2C,
+ CPCAP_REG_OW2D,
+ CPCAP_REG_OW2I,
+ CPCAP_REG_OW2IE,
+ CPCAP_REG_OW2,
+ CPCAP_REG_OW3C,
+ CPCAP_REG_OW3D,
+ CPCAP_REG_OW3I,
+ CPCAP_REG_OW3IE,
+ CPCAP_REG_OW3,
+ CPCAP_REG_GCAIC,
+ CPCAP_REG_GCAIM,
+ CPCAP_REG_LGDIR,
+ CPCAP_REG_LGPU,
+ CPCAP_REG_LGPIN,
+ CPCAP_REG_LGMASK,
+ CPCAP_REG_LDEB,
+ CPCAP_REG_LGDET,
+ CPCAP_REG_LMISC,
+ CPCAP_REG_LMACE,
+
+ CPCAP_REG_END = CPCAP_REG_LMACE,
+
+ CPCAP_REG_MAX
+ = CPCAP_REG_END,
+
+ CPCAP_REG_SIZE = CPCAP_REG_MAX + 1,
+ CPCAP_REG_UNUSED = CPCAP_REG_MAX + 2,
+};
+
+enum {
+ CPCAP_IOCTL_NUM_TEST__START,
+ CPCAP_IOCTL_NUM_TEST_READ_REG,
+ CPCAP_IOCTL_NUM_TEST_WRITE_REG,
+ CPCAP_IOCTL_NUM_TEST__END,
+
+ CPCAP_IOCTL_NUM_ADC__START,
+ CPCAP_IOCTL_NUM_ADC_PHASE,
+ CPCAP_IOCTL_NUM_ADC__END,
+
+ CPCAP_IOCTL_NUM_BATT__START,
+ CPCAP_IOCTL_NUM_BATT_DISPLAY_UPDATE,
+ CPCAP_IOCTL_NUM_BATT_ATOD_ASYNC,
+ CPCAP_IOCTL_NUM_BATT_ATOD_SYNC,
+ CPCAP_IOCTL_NUM_BATT_ATOD_READ,
+ CPCAP_IOCTL_NUM_BATT__END,
+
+ CPCAP_IOCTL_NUM_UC__START,
+ CPCAP_IOCTL_NUM_UC_MACRO_START,
+ CPCAP_IOCTL_NUM_UC_MACRO_STOP,
+ CPCAP_IOCTL_NUM_UC_GET_VENDOR,
+ CPCAP_IOCTL_NUM_UC_SET_TURBO_MODE,
+ CPCAP_IOCTL_NUM_UC__END,
+
+ CPCAP_IOCTL_NUM_ACCY__START,
+ CPCAP_IOCTL_NUM_ACCY_WHISPER,
+ CPCAP_IOCTL_NUM_ACCY__END,
+};
+
+enum cpcap_irqs {
+ CPCAP_IRQ__START,
+ CPCAP_IRQ_HSCLK = CPCAP_IRQ_INT1_INDEX,
+ CPCAP_IRQ_PRIMAC,
+ CPCAP_IRQ_SECMAC,
+ CPCAP_IRQ_LOWBPL,
+ CPCAP_IRQ_SEC2PRI,
+ CPCAP_IRQ_LOWBPH,
+ CPCAP_IRQ_EOL,
+ CPCAP_IRQ_TS,
+ CPCAP_IRQ_ADCDONE,
+ CPCAP_IRQ_HS,
+ CPCAP_IRQ_MB2,
+ CPCAP_IRQ_VBUSOV,
+ CPCAP_IRQ_RVRS_CHRG,
+ CPCAP_IRQ_CHRG_DET,
+ CPCAP_IRQ_IDFLOAT,
+ CPCAP_IRQ_IDGND,
+
+ CPCAP_IRQ_SE1 = CPCAP_IRQ_INT2_INDEX,
+ CPCAP_IRQ_SESSEND,
+ CPCAP_IRQ_SESSVLD,
+ CPCAP_IRQ_VBUSVLD,
+ CPCAP_IRQ_CHRG_CURR1,
+ CPCAP_IRQ_CHRG_CURR2,
+ CPCAP_IRQ_RVRS_MODE,
+ CPCAP_IRQ_ON,
+ CPCAP_IRQ_ON2,
+ CPCAP_IRQ_CLK,
+ CPCAP_IRQ_1HZ,
+ CPCAP_IRQ_PTT,
+ CPCAP_IRQ_SE0CONN,
+ CPCAP_IRQ_CHRG_SE1B,
+ CPCAP_IRQ_UART_ECHO_OVERRUN,
+ CPCAP_IRQ_EXTMEMHD,
+
+ CPCAP_IRQ_WARM = CPCAP_IRQ_INT3_INDEX,
+ CPCAP_IRQ_SYSRSTR,
+ CPCAP_IRQ_SOFTRST,
+ CPCAP_IRQ_DIEPWRDWN,
+ CPCAP_IRQ_DIETEMPH,
+ CPCAP_IRQ_PC,
+ CPCAP_IRQ_OFLOWSW,
+ CPCAP_IRQ_TODA,
+ CPCAP_IRQ_OPT_SEL_DTCH,
+ CPCAP_IRQ_OPT_SEL_STATE,
+ CPCAP_IRQ_ONEWIRE1,
+ CPCAP_IRQ_ONEWIRE2,
+ CPCAP_IRQ_ONEWIRE3,
+ CPCAP_IRQ_UCRESET,
+ CPCAP_IRQ_PWRGOOD,
+ CPCAP_IRQ_USBDPLLCLK,
+
+ CPCAP_IRQ_DPI = CPCAP_IRQ_INT4_INDEX,
+ CPCAP_IRQ_DMI,
+ CPCAP_IRQ_UCBUSY,
+ CPCAP_IRQ_GCAI_CURR1,
+ CPCAP_IRQ_GCAI_CURR2,
+ CPCAP_IRQ_SB_MAX_RETRANSMIT_ERR,
+ CPCAP_IRQ_BATTDETB,
+ CPCAP_IRQ_PRIHALT,
+ CPCAP_IRQ_SECHALT,
+ CPCAP_IRQ_CC_CAL,
+
+ CPCAP_IRQ_UC_PRIROMR = CPCAP_IRQ_INT5_INDEX,
+ CPCAP_IRQ_UC_PRIRAMW,
+ CPCAP_IRQ_UC_PRIRAMR,
+ CPCAP_IRQ_UC_USEROFF,
+ CPCAP_IRQ_UC_PRIMACRO_4,
+ CPCAP_IRQ_UC_PRIMACRO_5,
+ CPCAP_IRQ_UC_PRIMACRO_6,
+ CPCAP_IRQ_UC_PRIMACRO_7,
+ CPCAP_IRQ_UC_PRIMACRO_8,
+ CPCAP_IRQ_UC_PRIMACRO_9,
+ CPCAP_IRQ_UC_PRIMACRO_10,
+ CPCAP_IRQ_UC_PRIMACRO_11,
+ CPCAP_IRQ_UC_PRIMACRO_12,
+ CPCAP_IRQ_UC_PRIMACRO_13,
+ CPCAP_IRQ_UC_PRIMACRO_14,
+ CPCAP_IRQ_UC_PRIMACRO_15,
+ CPCAP_IRQ__NUM
+};
+
+enum cpcap_adc_bank0 {
+ CPCAP_ADC_AD0_BATTDETB,
+ CPCAP_ADC_BATTP,
+ CPCAP_ADC_VBUS,
+ CPCAP_ADC_AD3,
+ CPCAP_ADC_BPLUS_AD4,
+ CPCAP_ADC_CHG_ISENSE,
+ CPCAP_ADC_BATTI_ADC,
+ CPCAP_ADC_USB_ID,
+
+ CPCAP_ADC_BANK0_NUM,
+};
+
+enum cpcap_adc_bank1 {
+ CPCAP_ADC_AD8,
+ CPCAP_ADC_AD9,
+ CPCAP_ADC_LICELL,
+ CPCAP_ADC_HV_BATTP,
+ CPCAP_ADC_TSX1_AD12,
+ CPCAP_ADC_TSX2_AD13,
+ CPCAP_ADC_TSY1_AD14,
+ CPCAP_ADC_TSY2_AD15,
+
+ CPCAP_ADC_BANK1_NUM,
+};
+
+enum cpcap_adc_format {
+ CPCAP_ADC_FORMAT_RAW,
+ CPCAP_ADC_FORMAT_PHASED,
+ CPCAP_ADC_FORMAT_CONVERTED,
+};
+
+enum cpcap_adc_timing {
+ CPCAP_ADC_TIMING_IMM,
+ CPCAP_ADC_TIMING_IN,
+ CPCAP_ADC_TIMING_OUT,
+};
+
+enum cpcap_adc_type {
+ CPCAP_ADC_TYPE_BANK_0,
+ CPCAP_ADC_TYPE_BANK_1,
+ CPCAP_ADC_TYPE_BATT_PI,
+};
+
+enum cpcap_macro {
+ CPCAP_MACRO_ROMR,
+ CPCAP_MACRO_RAMW,
+ CPCAP_MACRO_RAMR,
+ CPCAP_MACRO_USEROFF,
+ CPCAP_MACRO_4,
+ CPCAP_MACRO_5,
+ CPCAP_MACRO_6,
+ CPCAP_MACRO_7,
+ CPCAP_MACRO_8,
+ CPCAP_MACRO_9,
+ CPCAP_MACRO_10,
+ CPCAP_MACRO_11,
+ CPCAP_MACRO_12,
+ CPCAP_MACRO_13,
+ CPCAP_MACRO_14,
+ CPCAP_MACRO_15,
+
+ CPCAP_MACRO__END,
+};
+
+enum cpcap_vendor {
+ CPCAP_VENDOR_ST,
+ CPCAP_VENDOR_TI,
+};
+
+enum cpcap_revision {
+ CPCAP_REVISION_1_0 = 0x08,
+ CPCAP_REVISION_1_1 = 0x09,
+ CPCAP_REVISION_2_0 = 0x10,
+ CPCAP_REVISION_2_1 = 0x11,
+};
+
+enum cpcap_batt_usb_model {
+ CPCAP_BATT_USB_MODEL_NONE,
+ CPCAP_BATT_USB_MODEL_USB,
+ CPCAP_BATT_USB_MODEL_FACTORY,
+};
+
+struct cpcap_spi_init_data {
+ enum cpcap_reg reg;
+ unsigned short data;
+};
+
+struct cpcap_adc_ato {
+ unsigned short ato_in;
+ unsigned short atox_in;
+ unsigned short adc_ps_factor_in;
+ unsigned short atox_ps_factor_in;
+ unsigned short ato_out;
+ unsigned short atox_out;
+ unsigned short adc_ps_factor_out;
+ unsigned short atox_ps_factor_out;
+};
+
+struct cpcap_batt_data {
+ int status;
+ int health;
+ int present;
+ int capacity;
+ int batt_volt;
+ int batt_temp;
+};
+
+struct cpcap_batt_ac_data {
+ int online;
+};
+
+struct cpcap_batt_usb_data {
+ int online;
+ int current_now;
+ enum cpcap_batt_usb_model model;
+};
+
+struct cpcap_device;
+
+struct cpcap_adc_us_request {
+ enum cpcap_adc_format format;
+ enum cpcap_adc_timing timing;
+ enum cpcap_adc_type type;
+ int status;
+ int result[CPCAP_ADC_BANK0_NUM];
+};
+
+struct cpcap_adc_phase {
+ signed char offset_batti;
+ unsigned char slope_batti;
+ signed char offset_chrgi;
+ unsigned char slope_chrgi;
+ signed char offset_battp;
+ unsigned char slope_battp;
+ signed char offset_bp;
+ unsigned char slope_bp;
+ signed char offset_battt;
+ unsigned char slope_battt;
+ signed char offset_chrgv;
+ unsigned char slope_chrgv;
+};
+
+struct cpcap_regacc {
+ unsigned short reg;
+ unsigned short value;
+ unsigned short mask;
+};
+
+struct cpcap_whisper_request {
+ unsigned int cmd;
+ char dock_id[CPCAP_WHISPER_ID_SIZE];
+ char dock_prop[CPCAP_WHISPER_PROP_SIZE];
+};
+
+#define CPCAP_IOCTL_TEST_READ_REG   _IOWR(0, CPCAP_IOCTL_NUM_TEST_READ_REG, struct cpcap_regacc*)
+
+#define CPCAP_IOCTL_TEST_WRITE_REG   _IOWR(0, CPCAP_IOCTL_NUM_TEST_WRITE_REG, struct cpcap_regacc*)
+
+#define CPCAP_IOCTL_ADC_PHASE   _IOWR(0, CPCAP_IOCTL_NUM_ADC_PHASE, struct cpcap_adc_phase*)
+
+#define CPCAP_IOCTL_BATT_DISPLAY_UPDATE   _IOW(0, CPCAP_IOCTL_NUM_BATT_DISPLAY_UPDATE, struct cpcap_batt_data*)
+
+#define CPCAP_IOCTL_BATT_ATOD_ASYNC   _IOW(0, CPCAP_IOCTL_NUM_BATT_ATOD_ASYNC, struct cpcap_adc_us_request*)
+
+#define CPCAP_IOCTL_BATT_ATOD_SYNC   _IOWR(0, CPCAP_IOCTL_NUM_BATT_ATOD_SYNC, struct cpcap_adc_us_request*)
+
+#define CPCAP_IOCTL_BATT_ATOD_READ   _IOWR(0, CPCAP_IOCTL_NUM_BATT_ATOD_READ, struct cpcap_adc_us_request*)
+
+#define CPCAP_IOCTL_UC_MACRO_START   _IOWR(0, CPCAP_IOCTL_NUM_UC_MACRO_START, enum cpcap_macro)
+
+#define CPCAP_IOCTL_UC_MACRO_STOP   _IOWR(0, CPCAP_IOCTL_NUM_UC_MACRO_STOP, enum cpcap_macro)
+
+#define CPCAP_IOCTL_UC_GET_VENDOR   _IOWR(0, CPCAP_IOCTL_NUM_UC_GET_VENDOR, enum cpcap_vendor)
+
+#define CPCAP_IOCTL_UC_SET_TURBO_MODE   _IOW(0, CPCAP_IOCTL_NUM_UC_SET_TURBO_MODE, unsigned short)
+
+#define CPCAP_IOCTL_ACCY_WHISPER   _IOW(0, CPCAP_IOCTL_NUM_ACCY_WHISPER, struct cpcap_whisper_request*)
+
+#endif
+
diff --git a/libc/kernel/common/linux/tegra_audio.h b/libc/kernel/common/linux/tegra_audio.h
new file mode 100644
index 0000000..e18ce11
--- /dev/null
+++ b/libc/kernel/common/linux/tegra_audio.h
@@ -0,0 +1,43 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   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 _TEGRA_AUDIO_H
+#define _TEGRA_AUDIO_H
+
+#include <linux/ioctl.h>
+
+#define TEGRA_AUDIO_MAGIC 't'
+
+#define TEGRA_AUDIO_IN_START _IO(TEGRA_AUDIO_MAGIC, 0)
+#define TEGRA_AUDIO_IN_STOP _IO(TEGRA_AUDIO_MAGIC, 1)
+
+struct tegra_audio_in_config {
+ int rate;
+ int stereo;
+};
+
+#define TEGRA_AUDIO_IN_SET_CONFIG _IOW(TEGRA_AUDIO_MAGIC, 2,   const struct tegra_audio_in_config *)
+#define TEGRA_AUDIO_IN_GET_CONFIG _IOR(TEGRA_AUDIO_MAGIC, 3,   struct tegra_audio_in_config *)
+
+#define TEGRA_AUDIO_IN_SET_NUM_BUFS _IOW(TEGRA_AUDIO_MAGIC, 4,   const unsigned int *)
+#define TEGRA_AUDIO_IN_GET_NUM_BUFS _IOW(TEGRA_AUDIO_MAGIC, 5,   unsigned int *)
+#define TEGRA_AUDIO_OUT_SET_NUM_BUFS _IOW(TEGRA_AUDIO_MAGIC, 6,   const unsigned int *)
+#define TEGRA_AUDIO_OUT_GET_NUM_BUFS _IOW(TEGRA_AUDIO_MAGIC, 7,   unsigned int *)
+
+#define TEGRA_AUDIO_OUT_FLUSH _IO(TEGRA_AUDIO_MAGIC, 10)
+
+#define TEGRA_AUDIO_BIT_FORMAT_DEFAULT 0
+#define TEGRA_AUDIO_BIT_FORMAT_DSP 1
+#define TEGRA_AUDIO_SET_BIT_FORMAT _IOW(TEGRA_AUDIO_MAGIC, 11,   const unsigned int *)
+#define TEGRA_AUDIO_GET_BIT_FORMAT _IOR(TEGRA_AUDIO_MAGIC, 12,   unsigned int *)
+
+#endif
+
diff --git a/libc/kernel/common/linux/tegra_avp.h b/libc/kernel/common/linux/tegra_avp.h
new file mode 100644
index 0000000..c4a0cbd
--- /dev/null
+++ b/libc/kernel/common/linux/tegra_avp.h
@@ -0,0 +1,38 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   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 __LINUX_TEGRA_AVP_H
+#define __LINUX_TEGRA_AVP_H
+
+#include <linux/ioctl.h>
+#include <linux/types.h>
+
+#define TEGRA_AVP_LIB_MAX_NAME 32
+#define TEGRA_AVP_LIB_MAX_ARGS 220  
+
+struct tegra_avp_lib {
+ char name[TEGRA_AVP_LIB_MAX_NAME];
+ void __user *args;
+ size_t args_len;
+ int greedy;
+ unsigned long handle;
+};
+
+#define TEGRA_AVP_IOCTL_MAGIC 'r'
+
+#define TEGRA_AVP_IOCTL_LOAD_LIB _IOWR(TEGRA_AVP_IOCTL_MAGIC, 0x40, struct tegra_avp_lib)
+#define TEGRA_AVP_IOCTL_UNLOAD_LIB _IOW(TEGRA_AVP_IOCTL_MAGIC, 0x41, unsigned long)
+
+#define TEGRA_AVP_IOCTL_MIN_NR _IOC_NR(TEGRA_AVP_IOCTL_LOAD_LIB)
+#define TEGRA_AVP_IOCTL_MAX_NR _IOC_NR(TEGRA_AVP_IOCTL_UNLOAD_LIB)
+
+#endif
+
diff --git a/libc/kernel/common/linux/tegra_rpc.h b/libc/kernel/common/linux/tegra_rpc.h
new file mode 100644
index 0000000..e3c8bf2
--- /dev/null
+++ b/libc/kernel/common/linux/tegra_rpc.h
@@ -0,0 +1,35 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   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 __LINUX_TEGRA_RPC_H
+#define __LINUX_TEGRA_RPC_H
+
+#define TEGRA_RPC_MAX_MSG_LEN 256
+
+#define TEGRA_RPC_MAX_NAME_LEN 17
+
+struct tegra_rpc_port_desc {
+ char name[TEGRA_RPC_MAX_NAME_LEN];
+ int notify_fd;
+};
+
+#define TEGRA_RPC_IOCTL_MAGIC 'r'
+
+#define TEGRA_RPC_IOCTL_PORT_CREATE _IOW(TEGRA_RPC_IOCTL_MAGIC, 0x20, struct tegra_rpc_port_desc)
+#define TEGRA_RPC_IOCTL_PORT_GET_NAME _IOR(TEGRA_RPC_IOCTL_MAGIC, 0x21, char *)
+#define TEGRA_RPC_IOCTL_PORT_CONNECT _IOR(TEGRA_RPC_IOCTL_MAGIC, 0x22, long)
+#define TEGRA_RPC_IOCTL_PORT_LISTEN _IOR(TEGRA_RPC_IOCTL_MAGIC, 0x23, long)
+
+#define TEGRA_RPC_IOCTL_MIN_NR _IOC_NR(TEGRA_RPC_IOCTL_PORT_CREATE)
+#define TEGRA_RPC_IOCTL_MAX_NR _IOC_NR(TEGRA_RPC_IOCTL_PORT_LISTEN)
+
+#endif
+
diff --git a/libc/kernel/common/linux/tegra_sema.h b/libc/kernel/common/linux/tegra_sema.h
new file mode 100644
index 0000000..bb11298
--- /dev/null
+++ b/libc/kernel/common/linux/tegra_sema.h
@@ -0,0 +1,24 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   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 __LINUX_TEGRA_SEMA_H
+#define __LINUX_TEGRA_SEMA_H
+
+#define TEGRA_SEMA_IOCTL_MAGIC 'r'
+
+#define TEGRA_SEMA_IOCTL_WAIT _IOW(TEGRA_SEMA_IOCTL_MAGIC, 0x30, long *)
+#define TEGRA_SEMA_IOCTL_SIGNAL _IO(TEGRA_SEMA_IOCTL_MAGIC, 0x31)
+
+#define TEGRA_SEMA_IOCTL_MIN_NR _IOC_NR(TEGRA_SEMA_IOCTL_WAIT)
+#define TEGRA_SEMA_IOCTL_MAX_NR _IOC_NR(TEGRA_SEMA_IOCTL_SIGNAL)
+
+#endif
+
diff --git a/libc/kernel/common/linux/tegrafb.h b/libc/kernel/common/linux/tegrafb.h
new file mode 100644
index 0000000..b8e79ae
--- /dev/null
+++ b/libc/kernel/common/linux/tegrafb.h
@@ -0,0 +1,87 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   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 _LINUX_TEGRAFB_H_
+#define _LINUX_TEGRAFB_H_
+
+#include <linux/fb.h>
+#include <linux/types.h>
+#include <asm/ioctl.h>
+
+#define TEGRA_FB_WIN_FMT_P1 0
+#define TEGRA_FB_WIN_FMT_P2 1
+#define TEGRA_FB_WIN_FMT_P4 2
+#define TEGRA_FB_WIN_FMT_P8 3
+#define TEGRA_FB_WIN_FMT_B4G4R4A4 4
+#define TEGRA_FB_WIN_FMT_B5G5R5A 5
+#define TEGRA_FB_WIN_FMT_B5G6R5 6
+#define TEGRA_FB_WIN_FMT_AB5G5R5 7
+#define TEGRA_FB_WIN_FMT_B8G8R8A8 12
+#define TEGRA_FB_WIN_FMT_R8G8B8A8 13
+#define TEGRA_FB_WIN_FMT_B6x2G6x2R6x2A8 14
+#define TEGRA_FB_WIN_FMT_R6x2G6x2B6x2A8 15
+#define TEGRA_FB_WIN_FMT_YCbCr422 16
+#define TEGRA_FB_WIN_FMT_YUV422 17
+#define TEGRA_FB_WIN_FMT_YCbCr420P 18
+#define TEGRA_FB_WIN_FMT_YUV420P 19
+#define TEGRA_FB_WIN_FMT_YCbCr422P 20
+#define TEGRA_FB_WIN_FMT_YUV422P 21
+#define TEGRA_FB_WIN_FMT_YCbCr422R 22
+#define TEGRA_FB_WIN_FMT_YUV422R 23
+#define TEGRA_FB_WIN_FMT_YCbCr422RA 24
+#define TEGRA_FB_WIN_FMT_YUV422RA 25
+
+#define TEGRA_FB_WIN_BLEND_NONE 0
+#define TEGRA_FB_WIN_BLEND_PREMULT 1
+#define TEGRA_FB_WIN_BLEND_COVERAGE 2
+
+struct tegra_fb_windowattr {
+ __s32 index;
+ __u32 buff_id;
+ __u32 blend;
+ __u32 offset;
+ __u32 offset_u;
+ __u32 offset_v;
+ __u32 stride;
+ __u32 stride_uv;
+ __u32 pixformat;
+ __u32 x;
+ __u32 y;
+ __u32 w;
+ __u32 h;
+ __u32 out_x;
+ __u32 out_y;
+ __u32 out_w;
+ __u32 out_h;
+ __u32 z;
+ __u32 pre_syncpt_id;
+ __u32 pre_syncpt_val;
+};
+
+#define TEGRA_FB_FLIP_N_WINDOWS 3
+
+struct tegra_fb_flip_args {
+ struct tegra_fb_windowattr win[TEGRA_FB_FLIP_N_WINDOWS];
+ __u32 post_syncpt_id;
+ __u32 post_syncpt_val;
+};
+
+struct tegra_fb_modedb {
+ struct fb_var_screeninfo *modedb;
+ __u32 modedb_len;
+};
+
+#define FBIO_TEGRA_SET_NVMAP_FD _IOW('F', 0x40, __u32)
+#define FBIO_TEGRA_FLIP _IOW('F', 0x41, struct tegra_fb_flip_args)
+#define FBIO_TEGRA_GET_MODEDB _IOWR('F', 0x42, struct tegra_fb_modedb)
+
+#endif
+
diff --git a/libc/kernel/common/linux/ublock.h b/libc/kernel/common/linux/ublock.h
new file mode 100644
index 0000000..aa19a81
--- /dev/null
+++ b/libc/kernel/common/linux/ublock.h
@@ -0,0 +1,81 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   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 __UBLOCK_H_
+#define __UBLOCK_H_
+
+#include <linux/types.h>
+
+#define UBLOCK_VERSION 0
+
+enum {
+ UBLOCK_INIT_IN = 0,
+ UBLOCK_INIT_OUT = 1,
+ UBLOCK_READY_IN = 2,
+ UBLOCK_READY_OUT = 3,
+ UBLOCK_READ_IN = 4,
+ UBLOCK_READ_OUT = 5,
+ UBLOCK_WRITE_IN = 6,
+ UBLOCK_WRITE_OUT = 7,
+};
+
+struct ublock_in_header {
+ __u32 seq;
+ __u32 opcode;
+};
+
+struct ublock_out_header {
+ __u32 seq;
+ __u32 opcode;
+};
+
+struct ublock_init_in {
+ __u32 version;
+ __u32 max_buf;
+ __u32 index;
+};
+
+struct ublock_init_out {
+ __u32 version;
+ __u32 max_buf;
+ __u64 size;
+};
+
+struct ublock_ready_in {
+ __u32 _unused;
+};
+
+struct ublock_ready_out {
+ __u32 _unused;
+};
+
+struct ublock_read_in {
+ __u64 offset;
+ __u64 length;
+};
+
+struct ublock_read_out {
+ __s32 status;
+ __u8 data[];
+};
+
+struct ublock_write_in {
+ __u64 offset;
+ __u64 length;
+ __u8 data[];
+};
+
+struct ublock_write_out {
+ __s32 status;
+};
+
+#endif
+
diff --git a/libc/kernel/common/linux/usb/f_mtp.h b/libc/kernel/common/linux/usb/f_mtp.h
new file mode 100644
index 0000000..a9e37c2
--- /dev/null
+++ b/libc/kernel/common/linux/usb/f_mtp.h
@@ -0,0 +1,42 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   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 __LINUX_USB_F_MTP_H
+#define __LINUX_USB_F_MTP_H
+
+#define MTP_INTERFACE_MODE_MTP 0
+#define MTP_INTERFACE_MODE_PTP 1
+
+struct mtp_file_range {
+
+ int fd;
+
+ loff_t offset;
+
+ int64_t length;
+};
+
+struct mtp_event {
+
+ size_t length;
+
+ void *data;
+};
+
+#define MTP_SEND_FILE _IOW('M', 0, struct mtp_file_range)
+
+#define MTP_RECEIVE_FILE _IOW('M', 1, struct mtp_file_range)
+
+#define MTP_SET_INTERFACE_MODE _IOW('M', 2, int)
+
+#define MTP_SEND_EVENT _IOW('M', 3, struct mtp_event)
+
+#endif
diff --git a/libc/kernel/common/media/ov5650.h b/libc/kernel/common/media/ov5650.h
new file mode 100644
index 0000000..3603dc2
--- /dev/null
+++ b/libc/kernel/common/media/ov5650.h
@@ -0,0 +1,63 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   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 __OV5650_H__
+#define __OV5650_H__
+
+#include <linux/ioctl.h>  
+
+#define OV5650_IOCTL_SET_MODE _IOW('o', 1, struct ov5650_mode)
+#define OV5650_IOCTL_SET_FRAME_LENGTH _IOW('o', 2, __u32)
+#define OV5650_IOCTL_SET_COARSE_TIME _IOW('o', 3, __u32)
+#define OV5650_IOCTL_SET_GAIN _IOW('o', 4, __u16)
+#define OV5650_IOCTL_GET_STATUS _IOR('o', 5, __u8)
+#define OV5650_IOCTL_GET_OTP _IOR('o', 6, struct ov5650_otp_data)
+#define OV5650_IOCTL_TEST_PATTERN _IOW('o', 7, enum ov5650_test_pattern)
+
+enum ov5650_test_pattern {
+ TEST_PATTERN_NONE,
+ TEST_PATTERN_COLORBARS,
+ TEST_PATTERN_CHECKERBOARD
+};
+
+struct ov5650_otp_data {
+
+ __u8 sensor_serial_num[6];
+ __u8 part_num[8];
+ __u8 lens_id[1];
+ __u8 manufacture_id[2];
+ __u8 factory_id[2];
+ __u8 manufacture_date[9];
+ __u8 manufacture_line[2];
+
+ __u32 module_serial_num;
+ __u8 focuser_liftoff[2];
+ __u8 focuser_macro[2];
+ __u8 reserved1[12];
+ __u8 shutter_cal[16];
+ __u8 reserved2[183];
+
+ __u16 crc;
+ __u8 reserved3[3];
+ __u8 auto_load[2];
+} __attribute__ ((packed));
+
+struct ov5650_mode {
+ int xres;
+ int yres;
+ __u32 frame_length;
+ __u32 coarse_time;
+ __u16 gain;
+};
+
+#endif
+
+
diff --git a/libc/kernel/common/media/soc2030.h b/libc/kernel/common/media/soc2030.h
new file mode 100644
index 0000000..ad0ddfc
--- /dev/null
+++ b/libc/kernel/common/media/soc2030.h
@@ -0,0 +1,86 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   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 __SOC2030_H__
+#define __SOC2030_H__
+
+#include <linux/ioctl.h>  
+
+#define SOC2030_IOCTL_SET_MODE _IOWR('o', 1, struct soc2030_mode)
+#define SOC2030_IOCTL_GET_STATUS _IOC(_IOC_READ, 'o', 2, 10)
+#define SOC2030_IOCTL_SET_PRIVATE _IOWR('o', 3, struct soc2030_regs)
+#define SOC2030_IOCTL_GET_MODES _IO('o', 4)
+#define SOC2030_IOCTL_GET_NUM_MODES _IOR('o', 5, unsigned int)
+#define SOC2030_IOCTL_SET_EFFECT _IOWR('o', 6, unsigned int)
+#define SOC2030_IOCTL_SET_WHITEBALANCE _IOWR('o', 7, unsigned int)
+#define SOC2030_IOCTL_SET_EXP_COMP _IOWR('o', 8, int)
+
+#define SOC2030_POLL_WAITMS 50
+#define SOC2030_MAX_RETRIES 3
+#define SOC2030_POLL_RETRIES 5
+
+#define SOC2030_MAX_PRIVATE_SIZE 1024
+#define SOC2030_MAX_NUM_MODES 6
+
+#define SOC_EV_MAX 2
+#define SOC_EV_MIN -2
+#define EXP_TARGET 0x32
+
+enum {
+ REG_TABLE_END,
+ WRITE_REG_DATA,
+ WRITE_REG_BIT_H,
+ WRITE_REG_BIT_L,
+ POLL_REG_DATA,
+ POLL_REG_BIT_H,
+ POLL_REG_BIT_L,
+ WRITE_VAR_DATA,
+ POLL_VAR_DATA,
+ DELAY_MS,
+};
+
+enum {
+ EFFECT_NONE,
+ EFFECT_BW,
+ EFFECT_NEGATIVE,
+ EFFECT_POSTERIZE,
+ EFFECT_SEPIA,
+ EFFECT_SOLARIZE,
+ EFFECT_AQUA,
+ EFFECT_MAX,
+};
+
+enum {
+ WB_AUTO,
+ WB_INCANDESCENT,
+ WB_FLUORESCENT,
+ WB_DAYLIGHT,
+ WB_CLOUDYDAYLIGHT,
+ WB_NIGHT,
+ WB_MAX,
+};
+
+struct soc2030_regs {
+ __u8 op;
+ __u16 addr;
+ __u16 val;
+};
+
+struct soc2030_mode {
+ int xres;
+ int yres;
+ int fps;
+ struct soc2030_regs *regset;
+};
+
+#endif
+
+
diff --git a/libc/kernel/common/media/tegra_camera.h b/libc/kernel/common/media/tegra_camera.h
new file mode 100644
index 0000000..0f63035
--- /dev/null
+++ b/libc/kernel/common/media/tegra_camera.h
@@ -0,0 +1,33 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   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.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+enum {
+ TEGRA_CAMERA_MODULE_ISP = 0,
+ TEGRA_CAMERA_MODULE_VI,
+ TEGRA_CAMERA_MODULE_CSI,
+};
+
+enum {
+ TEGRA_CAMERA_VI_CLK,
+ TEGRA_CAMERA_VI_SENSOR_CLK,
+};
+
+struct tegra_camera_clk_info {
+ uint id;
+ uint clk_id;
+ unsigned long rate;
+};
+
+#define TEGRA_CAMERA_IOCTL_ENABLE _IOWR('i', 1, uint)
+#define TEGRA_CAMERA_IOCTL_DISABLE _IOWR('i', 2, uint)
+#define TEGRA_CAMERA_IOCTL_CLK_SET_RATE   _IOWR('i', 3, struct tegra_camera_clk_info)
+#define TEGRA_CAMERA_IOCTL_RESET _IOWR('i', 4, uint)
+
diff --git a/libc/netbsd/net/getaddrinfo.c b/libc/netbsd/net/getaddrinfo.c
index e4d8c56..bb6645c 100644
--- a/libc/netbsd/net/getaddrinfo.c
+++ b/libc/netbsd/net/getaddrinfo.c
@@ -77,10 +77,13 @@
  *	  friends.
  */
 
+#include <fcntl.h>
 #include <sys/cdefs.h>
 #include <sys/types.h>
+#include <sys/stat.h>
 #include <sys/param.h>
 #include <sys/socket.h>
+#include <sys/un.h>
 #include <net/if.h>
 #include <netinet/in.h>
 #include <arpa/inet.h>
@@ -100,6 +103,10 @@
 #include <stdarg.h>
 #include "nsswitch.h"
 
+#ifdef ANDROID_CHANGES
+#include <sys/system_properties.h>
+#endif /* ANDROID_CHANGES */
+
 typedef union sockaddr_union {
     struct sockaddr     generic;
     struct sockaddr_in  in;
@@ -391,6 +398,190 @@
         return _test_connect(PF_INET, &addr.generic, sizeof(addr.in));
 }
 
+// Returns 0 on success, else returns non-zero on error (in which case
+// getaddrinfo should continue as normal)
+static int
+android_getaddrinfo_proxy(
+    const char *hostname, const char *servname,
+    const struct addrinfo *hints, struct addrinfo **res)
+{
+	int sock;
+	const int one = 1;
+	struct sockaddr_un proxy_addr;
+	const char* cache_mode = getenv("ANDROID_DNS_MODE");
+	FILE* proxy = NULL;
+	int success = 0;
+
+	// Clear this at start, as we use its non-NULLness later (in the
+	// error path) to decide if we have to free up any memory we
+	// allocated in the process (before failing).
+	*res = NULL;
+
+	if (cache_mode != NULL && strcmp(cache_mode, "local") == 0) {
+		// Don't use the proxy in local mode.  This is used by the
+		// proxy itself.
+		return -1;
+	}
+
+	// Temporary cautious hack to disable the DNS proxy for processes
+	// requesting special treatment.  Ideally the DNS proxy should
+	// accomodate these apps, though.
+	char propname[PROP_NAME_MAX];
+	char propvalue[PROP_VALUE_MAX];
+	snprintf(propname, sizeof(propname), "net.dns1.%d", getpid());
+	if (__system_property_get(propname, propvalue) > 0) {
+		return -1;
+	}
+
+	// Bogus things we can't serialize.  Don't use the proxy.
+	if ((hostname != NULL &&
+	     strcspn(hostname, " \n\r\t^'\"") != strlen(hostname)) ||
+	    (servname != NULL &&
+	     strcspn(servname, " \n\r\t^'\"") != strlen(servname))) {
+		return -1;
+	}
+
+	sock = socket(AF_UNIX, SOCK_STREAM, 0);
+	if (sock < 0) {
+		return -1;
+	}
+
+	setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one));
+	memset(&proxy_addr, 0, sizeof(proxy_addr));
+	proxy_addr.sun_family = AF_UNIX;
+	strlcpy(proxy_addr.sun_path, "/dev/socket/dnsproxyd",
+		sizeof(proxy_addr.sun_path));
+	if (TEMP_FAILURE_RETRY(connect(sock,
+				       (const struct sockaddr*) &proxy_addr,
+				       sizeof(proxy_addr))) != 0) {
+		close(sock);
+		return -1;
+	}
+
+	// Send the request.
+	proxy = fdopen(sock, "r+");
+	if (fprintf(proxy, "getaddrinfo %s %s %d %d %d %d",
+		    hostname == NULL ? "^" : hostname,
+		    servname == NULL ? "^" : servname,
+		    hints == NULL ? -1 : hints->ai_flags,
+		    hints == NULL ? -1 : hints->ai_family,
+		    hints == NULL ? -1 : hints->ai_socktype,
+		    hints == NULL ? -1 : hints->ai_protocol) < 0) {
+		goto exit;
+	}
+	// literal NULL byte at end, required by FrameworkListener
+	if (fputc(0, proxy) == EOF ||
+	    fflush(proxy) != 0) {
+		goto exit;
+	}
+
+	int remote_rv;
+	if (fread(&remote_rv, sizeof(int), 1, proxy) != 1) {
+		goto exit;
+	}
+
+	if (remote_rv != 0) {
+		goto exit;
+	}
+
+	struct addrinfo* ai = NULL;
+	struct addrinfo** nextres = res;
+	while (1) {
+		uint32_t addrinfo_len;
+		if (fread(&addrinfo_len, sizeof(addrinfo_len),
+			  1, proxy) != 1) {
+			break;
+		}
+		addrinfo_len = ntohl(addrinfo_len);
+		if (addrinfo_len == 0) {
+			success = 1;
+			break;
+		}
+
+		if (addrinfo_len < sizeof(struct addrinfo)) {
+			break;
+		}
+		struct addrinfo* ai = calloc(1, addrinfo_len +
+					     sizeof(struct sockaddr_storage));
+		if (ai == NULL) {
+			break;
+		}
+
+		if (fread(ai, addrinfo_len, 1, proxy) != 1) {
+			// Error; fall through.
+			break;
+		}
+
+		// Zero out the pointer fields we copied which aren't
+		// valid in this address space.
+		ai->ai_addr = NULL;
+		ai->ai_canonname = NULL;
+		ai->ai_next = NULL;
+
+		// struct sockaddr
+		uint32_t addr_len;
+		if (fread(&addr_len, sizeof(addr_len), 1, proxy) != 1) {
+			break;
+		}
+		addr_len = ntohl(addr_len);
+		if (addr_len != 0) {
+			if (addr_len > sizeof(struct sockaddr_storage)) {
+				// Bogus; too big.
+				break;
+			}
+			struct sockaddr* addr = (struct sockaddr*)(ai + 1);
+			if (fread(addr, addr_len, 1, proxy) != 1) {
+				break;
+			}
+			ai->ai_addr = addr;
+		}
+
+		// cannonname
+		uint32_t name_len;
+		if (fread(&name_len, sizeof(name_len), 1, proxy) != 1) {
+			break;
+		}
+		if (name_len != 0) {
+			ai->ai_canonname = (char*) malloc(name_len);
+			if (fread(ai->ai_canonname, name_len, 1, proxy) != 1) {
+				break;
+			}
+			if (ai->ai_canonname[name_len - 1] != '\0') {
+				// The proxy should be returning this
+				// NULL-terminated.
+				break;
+			}
+		}
+
+		*nextres = ai;
+		nextres = &ai->ai_next;
+		ai = NULL;
+	}
+
+	if (ai != NULL) {
+		// Clean up partially-built addrinfo that we never ended up
+		// attaching to the response.
+		freeaddrinfo(ai);
+	}
+exit:
+	if (proxy != NULL) {
+		fclose(proxy);
+	}
+
+	if (success) {
+		return 0;
+	}
+
+	// Proxy failed; fall through to local
+	// resolver case.  But first clean up any
+	// memory we might've allocated.
+	if (*res) {
+		freeaddrinfo(*res);
+		*res = NULL;
+	}
+	return -1;
+}
+
 int
 getaddrinfo(const char *hostname, const char *servname,
     const struct addrinfo *hints, struct addrinfo **res)
@@ -537,6 +728,13 @@
 	if (pai->ai_flags & AI_NUMERICHOST)
 		ERR(EAI_NONAME);
 
+        /*
+         * BEGIN ANDROID CHANGES; proxying to the cache
+         */
+        if (android_getaddrinfo_proxy(hostname, servname, hints, res) == 0) {
+            return 0;
+        }
+
 	/*
 	 * hostname as alphabetical name.
 	 * we would like to prefer AF_INET6 than AF_INET, so we'll make a
diff --git a/libc/stdlib/sha1hash.c b/libc/stdlib/sha1hash.c
deleted file mode 100644
index 1c7aaf3..0000000
--- a/libc/stdlib/sha1hash.c
+++ /dev/null
@@ -1,316 +0,0 @@
-/*
-SHA-1 in C
-By Steve Reid <sreid@sea-to-sky.net>
-100% Public Domain
-
------------------
-Modified 7/98
-By James H. Brown <jbrown@burgoyne.com>
-Still 100% Public Domain
-
-Corrected a problem which generated improper hash values on 16 bit machines
-Routine SHA1Update changed from
-	void SHA1Update(SHA1_CTX* context, unsigned char* data, unsigned int
-len)
-to
-	void SHA1Update(SHA1_CTX* context, unsigned char* data, unsigned
-long len)
-
-The 'len' parameter was declared an int which works fine on 32 bit machines.
-However, on 16 bit machines an int is too small for the shifts being done
-against
-it.  This caused the hash function to generate incorrect values if len was
-greater than 8191 (8K - 1) due to the 'len << 3' on line 3 of SHA1Update().
-
-Since the file IO in main() reads 16K at a time, any file 8K or larger would
-be guaranteed to generate the wrong hash (e.g. Test Vector #3, a million
-"a"s).
-
-I also changed the declaration of variables i & j in SHA1Update to
-unsigned long from unsigned int for the same reason.
-
-These changes should make no difference to any 32 bit implementations since
-an
-int and a long are the same size in those environments.
-
---
-I also corrected a few compiler warnings generated by Borland C.
-1. Added #include <process.h> for exit() prototype
-2. Removed unused variable 'j' in SHA1Final
-3. Changed exit(0) to return(0) at end of main.
-
-ALL changes I made can be located by searching for comments containing 'JHB'
------------------
-Modified 8/98
-By Steve Reid <sreid@sea-to-sky.net>
-Still 100% public domain
-
-1- Removed #include <process.h> and used return() instead of exit()
-2- Fixed overwriting of finalcount in SHA1Final() (discovered by Chris Hall)
-3- Changed email address from steve@edmweb.com to sreid@sea-to-sky.net
-
------------------
-Modified 4/01
-By Saul Kravitz <Saul.Kravitz@celera.com>
-Still 100% PD
-Modified to run on Compaq Alpha hardware.
-
------------------
-Modified 2/03
-By H. Peter Anvin <hpa@zytor.com>
-Still 100% PD
-Modified to run on any hardware with <inttypes.h> and <netinet/in.h>
-Changed the driver program
-
-*/
-
-/*
-Test Vectors (from FIPS PUB 180-1)
-"abc"
-  A9993E36 4706816A BA3E2571 7850C26C 9CD0D89D
-"abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"
-  84983E44 1C3BD26E BAAE4AA1 F95129E5 E54670F1
-A million repetitions of "a"
-  34AA973C D4C4DAA4 F61EEB2B DBAD2731 6534016F
-*/
-
-/* #define SHA1HANDSOFF  */
-
-#include <stdio.h>
-#include <string.h>
-#include <inttypes.h>
-#include <netinet/in.h>		/* For htonl/ntohl/htons/ntohs */
-
-/* #include <process.h> */	/* prototype for exit() - JHB */
-/* Using return() instead of exit() - SWR */
-
-typedef struct {
-    uint32_t state[5];
-    uint32_t count[2];
-    unsigned char buffer[64];
-} SHA1_CTX;
-
-void SHA1Transform(uint32_t state[5], unsigned char buffer[64]);
-void SHA1Init(SHA1_CTX* context);
-void SHA1Update(SHA1_CTX* context, unsigned char* data, uint32_t len);	/*
-JHB */
-void SHA1Final(unsigned char digest[20], SHA1_CTX* context);
-
-#define rol(value, bits) (((value) << (bits)) | ((value) >> (32 - (bits))))
-
-/* blk0() and blk() perform the initial expand. */
-/* I got the idea of expanding during the round function from SSLeay */
-#define blk0(i) (block->l[i] = ntohl(block->l[i]))
-#define blk(i) (block->l[i&15] = rol(block->l[(i+13)&15]^block->l[(i+8)&15] \
-    ^block->l[(i+2)&15]^block->l[i&15],1))
-
-/* (R0+R1), R2, R3, R4 are the different operations used in SHA1 */
-#define R0(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk0(i)+0x5A827999+rol(v,5);w=rol(w,30);
-#define R1(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk(i)+0x5A827999+rol(v,5);w=rol(w,30);
-#define R2(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0x6ED9EBA1+rol(v,5);w=rol(w,30);
-#define R3(v,w,x,y,z,i) z+=(((w|x)&y)|(w&x))+blk(i)+0x8F1BBCDC+rol(v,5);w=rol(w,30);
-#define R4(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0xCA62C1D6+rol(v,5);w=rol(w,30);
-
-
-#ifdef VERBOSE  /* SAK */
-void SHAPrintContext(SHA1_CTX *context, char *msg){
-  printf("%s (%d,%d) %x %x %x %x %x\n",
-	 msg,
-	 context->count[0], context->count[1],
-	 context->state[0],
-	 context->state[1],
-	 context->state[2],
-	 context->state[3],
-	 context->state[4]);
-}
-#endif
-
-/* Hash a single 512-bit block. This is the core of the algorithm. */
-
-void SHA1Transform(uint32_t state[5], unsigned char buffer[64])
-{
-uint32_t a, b, c, d, e;
-typedef union {
-    unsigned char c[64];
-    uint32_t l[16];
-} CHAR64LONG16;
-CHAR64LONG16* block;
-#ifdef SHA1HANDSOFF
-static unsigned char workspace[64];
-    block = (CHAR64LONG16*)workspace;
-    memcpy(block, buffer, 64);
-#else
-    block = (CHAR64LONG16*)buffer;
-#endif
-    /* Copy context->state[] to working vars */
-    a = state[0];
-    b = state[1];
-    c = state[2];
-    d = state[3];
-    e = state[4];
-    /* 4 rounds of 20 operations each. Loop unrolled. */
-    R0(a,b,c,d,e, 0); R0(e,a,b,c,d, 1); R0(d,e,a,b,c, 2); R0(c,d,e,a,b, 3);
-    R0(b,c,d,e,a, 4); R0(a,b,c,d,e, 5); R0(e,a,b,c,d, 6); R0(d,e,a,b,c, 7);
-    R0(c,d,e,a,b, 8); R0(b,c,d,e,a, 9); R0(a,b,c,d,e,10); R0(e,a,b,c,d,11);
-    R0(d,e,a,b,c,12); R0(c,d,e,a,b,13); R0(b,c,d,e,a,14); R0(a,b,c,d,e,15);
-    R1(e,a,b,c,d,16); R1(d,e,a,b,c,17); R1(c,d,e,a,b,18); R1(b,c,d,e,a,19);
-    R2(a,b,c,d,e,20); R2(e,a,b,c,d,21); R2(d,e,a,b,c,22); R2(c,d,e,a,b,23);
-    R2(b,c,d,e,a,24); R2(a,b,c,d,e,25); R2(e,a,b,c,d,26); R2(d,e,a,b,c,27);
-    R2(c,d,e,a,b,28); R2(b,c,d,e,a,29); R2(a,b,c,d,e,30); R2(e,a,b,c,d,31);
-    R2(d,e,a,b,c,32); R2(c,d,e,a,b,33); R2(b,c,d,e,a,34); R2(a,b,c,d,e,35);
-    R2(e,a,b,c,d,36); R2(d,e,a,b,c,37); R2(c,d,e,a,b,38); R2(b,c,d,e,a,39);
-    R3(a,b,c,d,e,40); R3(e,a,b,c,d,41); R3(d,e,a,b,c,42); R3(c,d,e,a,b,43);
-    R3(b,c,d,e,a,44); R3(a,b,c,d,e,45); R3(e,a,b,c,d,46); R3(d,e,a,b,c,47);
-    R3(c,d,e,a,b,48); R3(b,c,d,e,a,49); R3(a,b,c,d,e,50); R3(e,a,b,c,d,51);
-    R3(d,e,a,b,c,52); R3(c,d,e,a,b,53); R3(b,c,d,e,a,54); R3(a,b,c,d,e,55);
-    R3(e,a,b,c,d,56); R3(d,e,a,b,c,57); R3(c,d,e,a,b,58); R3(b,c,d,e,a,59);
-    R4(a,b,c,d,e,60); R4(e,a,b,c,d,61); R4(d,e,a,b,c,62); R4(c,d,e,a,b,63);
-    R4(b,c,d,e,a,64); R4(a,b,c,d,e,65); R4(e,a,b,c,d,66); R4(d,e,a,b,c,67);
-    R4(c,d,e,a,b,68); R4(b,c,d,e,a,69); R4(a,b,c,d,e,70); R4(e,a,b,c,d,71);
-    R4(d,e,a,b,c,72); R4(c,d,e,a,b,73); R4(b,c,d,e,a,74); R4(a,b,c,d,e,75);
-    R4(e,a,b,c,d,76); R4(d,e,a,b,c,77); R4(c,d,e,a,b,78); R4(b,c,d,e,a,79);
-    /* Add the working vars back into context.state[] */
-    state[0] += a;
-    state[1] += b;
-    state[2] += c;
-    state[3] += d;
-    state[4] += e;
-    /* Wipe variables */
-    a = b = c = d = e = 0;
-}
-
-
-/* SHA1Init - Initialize new context */
-
-void SHA1Init(SHA1_CTX* context)
-{
-    /* SHA1 initialization constants */
-    context->state[0] = 0x67452301;
-    context->state[1] = 0xEFCDAB89;
-    context->state[2] = 0x98BADCFE;
-    context->state[3] = 0x10325476;
-    context->state[4] = 0xC3D2E1F0;
-    context->count[0] = context->count[1] = 0;
-}
-
-
-/* Run your data through this. */
-
-void SHA1Update(SHA1_CTX* context, unsigned char* data, uint32_t len)	/*
-JHB */
-{
-uint32_t i, j;	/* JHB */
-
-#ifdef VERBOSE
-    SHAPrintContext(context, "before");
-#endif
-    j = (context->count[0] >> 3) & 63;
-    if ((context->count[0] += len << 3) < (len << 3)) context->count[1]++;
-    context->count[1] += (len >> 29);
-    if ((j + len) > 63) {
-        memcpy(&context->buffer[j], data, (i = 64-j));
-        SHA1Transform(context->state, context->buffer);
-        for ( ; i + 63 < len; i += 64) {
-            SHA1Transform(context->state, &data[i]);
-        }
-        j = 0;
-    }
-    else i = 0;
-    memcpy(&context->buffer[j], &data[i], len - i);
-#ifdef VERBOSE
-    SHAPrintContext(context, "after ");
-#endif
-}
-
-
-/* Add padding and return the message digest. */
-
-void SHA1Final(unsigned char digest[20], SHA1_CTX* context)
-{
-uint32_t i;	/* JHB */
-unsigned char finalcount[8];
-
-    for (i = 0; i < 8; i++) {
-        finalcount[i] = (unsigned char)((context->count[(i >= 4 ? 0 : 1)]
-         >> ((3-(i & 3)) * 8) ) & 255);  /* Endian independent */
-    }
-    SHA1Update(context, (unsigned char *)"\200", 1);
-    while ((context->count[0] & 504) != 448) {
-        SHA1Update(context, (unsigned char *)"\0", 1);
-    }
-    SHA1Update(context, finalcount, 8);  /* Should cause a SHA1Transform() */
-    for (i = 0; i < 20; i++) {
-        digest[i] = (unsigned char)
-         ((context->state[i>>2] >> ((3-(i & 3)) * 8) ) & 255);
-    }
-    /* Wipe variables */
-    i = 0;	/* JHB */
-    memset(context->buffer, 0, 64);
-    memset(context->state, 0, 20);
-    memset(context->count, 0, 8);
-    memset(finalcount, 0, 8);	/* SWR */
-#ifdef SHA1HANDSOFF  /* make SHA1Transform overwrite it's own static vars */
-    SHA1Transform(context->state, context->buffer);
-#endif
-}
-
-/*************************************************************/
-
-/* This is not quite the MIME base64 algorithm: it uses _ instead of /,
-   and instead of padding the output with = characters we just make the
-   output shorter. */
-char *mybase64(uint8_t digest[20])
-{
-  static const char charz[] =
-    "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_";
-  uint8_t input[21];
-  static char output[28];
-  int i, j;
-  uint8_t *p;
-  char *q;
-  uint32_t bv;
-
-  memcpy(input, digest, 20);
-  input[20] = 0;		/* Pad to multiple of 3 bytes */
-
-  p = input;  q = output;
-  for ( i = 0 ; i < 7 ; i++ ) {
-    bv = (p[0] << 16) | (p[1] << 8) | p[2];
-    p += 3;
-    for ( j = 0 ; j < 4 ; j++ ) {
-      *q++ = charz[(bv >> 18) & 0x3f];
-      bv <<= 6;
-    }
-  }
-  *--q = '\0';			/* The last character is not significant */
-  return output;
-}
-
-int main(int argc, char** argv)
-{
-  int i;
-  SHA1_CTX context;
-  uint8_t digest[20], buffer[16384];
-  FILE* file;
-
-  if (argc < 2) {
-    file = stdin;
-  }
-  else {
-    if (!(file = fopen(argv[1], "rb"))) {
-      fputs("Unable to open file.", stderr);
-      return(-1);
-    }
-  }
-  SHA1Init(&context);
-  while (!feof(file)) {  /* note: what if ferror(file) */
-    i = fread(buffer, 1, 16384, file);
-    SHA1Update(&context, buffer, i);
-  }
-  SHA1Final(digest, &context);
-  fclose(file);
-
-  puts(mybase64(digest));
-
-  return 0;
-}
diff --git a/libc/stdlib/wchar.c b/libc/stdlib/wchar.c
index 1480212..d83613a 100644
--- a/libc/stdlib/wchar.c
+++ b/libc/stdlib/wchar.c
@@ -302,12 +302,6 @@
     return (wchar_t*) strstr( (const char*)ws1, (const char*)ws2 );
 }
 
-size_t wcsxfrm(wchar_t *ws1, const wchar_t *ws2, size_t n)
-{
-    memcpy( (char*)ws1, (const char*)ws2, n );
-    return n;
-}
-
 int wctob(wint_t c)
 {
     return c;
diff --git a/libc/tools/gensyscalls.py b/libc/tools/gensyscalls.py
index 41c9500..0535e56 100755
--- a/libc/tools/gensyscalls.py
+++ b/libc/tools/gensyscalls.py
@@ -245,6 +245,59 @@
 """
 
 
+def param_uses_64bits(param):
+    """Returns True iff a syscall parameter description corresponds
+       to a 64-bit type."""
+    param = param.strip()
+    # First, check that the param type begins with one of the known
+    # 64-bit types.
+    if not ( \
+       param.startswith("int64_t") or param.startswith("uint64_t") or \
+       param.startswith("loff_t") or param.startswith("off64_t") or \
+       param.startswith("long long") or param.startswith("unsigned long long") or
+       param.startswith("signed long long") ):
+           return False
+
+    # Second, check that there is no pointer type here
+    if param.find("*") >= 0:
+            return False
+
+    # Ok
+    return True
+
+def count_arm_param_registers(params):
+    """This function is used to count the number of register used
+       to pass parameters when invoking a thumb or ARM system call.
+       This is because the ARM EABI mandates that 64-bit quantities
+       must be passed in an even+odd register pair. So, for example,
+       something like:
+
+             foo(int fd, off64_t pos)
+
+       would actually need 4 registers:
+             r0 -> int
+             r1 -> unused
+             r2-r3 -> pos
+   """
+    count = 0
+    for param in params:
+        if param_uses_64bits(param):
+            if (count & 1) != 0:
+                count += 1
+            count += 2
+        else:
+            count += 1
+    return count
+
+def count_generic_param_registers(params):
+    count = 0
+    for param in params:
+        if param_uses_64bits(param):
+            count += 2
+        else:
+            count += 1
+    return count
+
 class State:
     def __init__(self):
         self.old_stubs = []
@@ -370,25 +423,28 @@
             syscall_name   = t["name"]
 
             if t["id"] >= 0:
+                num_regs = count_arm_param_registers(syscall_params)
                 if gen_thumb_stubs:
-                    t["asm-thumb"] = self.thumb_genstub(syscall_func,len(syscall_params),"__NR_"+syscall_name)
+                    t["asm-thumb"] = self.thumb_genstub(syscall_func,num_regs,"__NR_"+syscall_name)
                 else:
                     if gen_eabi_stubs:
-                        t["asm-arm"]   = self.arm_eabi_genstub(syscall_func,len(syscall_params),"__NR_"+syscall_name)
+                        t["asm-arm"]   = self.arm_eabi_genstub(syscall_func,num_regs,"__NR_"+syscall_name)
                     else:
-                        t["asm-arm"]   = self.arm_genstub(syscall_func,len(syscall_params),"__NR_"+syscall_name)
+                        t["asm-arm"]   = self.arm_genstub(syscall_func,num_regs,"__NR_"+syscall_name)
 
             if t["id2"] >= 0:
+                num_regs = count_generic_param_registers(syscall_params)
                 if t["cid"] >= 0:
-                    t["asm-x86"] = self.x86_genstub_cid(syscall_func, len(syscall_params), "__NR_"+syscall_name, t["cid"])
+                    t["asm-x86"] = self.x86_genstub_cid(syscall_func, num_regs, "__NR_"+syscall_name, t["cid"])
                 else:
-                    t["asm-x86"] = self.x86_genstub(syscall_func,len(syscall_params),"__NR_"+syscall_name)
+                    t["asm-x86"] = self.x86_genstub(syscall_func, num_regs, "__NR_"+syscall_name)
             elif t["cid"] >= 0:
                 E("cid for dispatch syscalls is only supported for x86 in "
                   "'%s'" % syscall_name)
                 return
             if t["id3"] >= 0:
-                t["asm-sh"] = self.superh_genstub(syscall_func,len(syscall_params),"__NR_"+syscall_name)
+                num_regs = count_generic_param_registers(syscall_params)
+                t["asm-sh"] = self.superh_genstub(syscall_func,num_regs,"__NR_"+syscall_name)
 
 
 
diff --git a/libc/tzcode/localtime.c b/libc/tzcode/localtime.c
index 85a913e..e442a03 100644
--- a/libc/tzcode/localtime.c
+++ b/libc/tzcode/localtime.c
@@ -60,6 +60,14 @@
 #  define  XLOG(x)   do{}while (0)
 #endif
 
+/* Add the following function implementations:
+ *  timelocal()
+ *  timegm()
+ *  time2posix()
+ *  posix2time()
+ */
+#define STD_INSPIRED 1
+
 /* THREAD-SAFETY SUPPORT GOES HERE */
 static pthread_mutex_t  _tzMutex = PTHREAD_MUTEX_INITIALIZER;
 
@@ -1509,7 +1517,7 @@
 }
 
 #ifdef STD_INSPIRED
-
+#if 0 /* disabled because there is no good documentation for this function */
 struct tm *
 offtime(timep, offset)
 const time_t * const    timep;
@@ -1517,7 +1525,7 @@
 {
     return gmtsub(timep, offset, &tmGlobal);
 }
-
+#endif /* 0 */
 #endif /* defined STD_INSPIRED */
 
 /*
@@ -2106,6 +2114,7 @@
     return result;
 }
 
+#if 0 /* disable due to lack of clear documentation on this function */
 time_t
 timeoff(tmp, offset)
 struct tm * const   tmp;
@@ -2120,6 +2129,7 @@
 
     return result;
 }
+#endif /* 0 */
 
 #endif /* defined STD_INSPIRED */
 
diff --git a/libc/unistd/lseek64.c b/libc/unistd/lseek64.c
index 017b331..db0c413 100644
--- a/libc/unistd/lseek64.c
+++ b/libc/unistd/lseek64.c
@@ -29,7 +29,7 @@
 
 extern int __llseek(int fd, unsigned long  offset_hi, unsigned long  offset_lo, loff_t*  result, int  whence);
 
-loff_t lseek64(int fd, loff_t off, int whence)
+off64_t lseek64(int fd, off64_t off, int whence)
 {
     loff_t  result;
 
diff --git a/libc/unistd/pread.c b/libc/unistd/pread.c
index b55623e..42fc3bc 100644
--- a/libc/unistd/pread.c
+++ b/libc/unistd/pread.c
@@ -11,24 +11,25 @@
  *    notice, this list of conditions and the following disclaimer in
  *    the documentation and/or other materials provided with the
  *    distribution.
- * 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.
- *     * Neither the name of Google Inc. 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 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/types.h>
 #include <unistd.h>
 
-extern int __pread64(int fd, void *buf, size_t nbytes, loff_t offset);
-
 ssize_t pread(int fd, void *buf, size_t nbytes, off_t offset)
 {
-    return __pread64(fd, buf, nbytes, offset);
+    return pread64(fd, buf, nbytes, (off64_t)offset);
 }
 
diff --git a/libc/unistd/pwrite.c b/libc/unistd/pwrite.c
index ea080d2..f106cb3 100644
--- a/libc/unistd/pwrite.c
+++ b/libc/unistd/pwrite.c
@@ -28,10 +28,8 @@
 #include <sys/types.h>
 #include <unistd.h>
 
-extern int __pwrite64(int fd, void *buf, size_t nbytes, loff_t offset);
-
-ssize_t pwrite(int fd, void *buf, size_t nbytes, off_t offset)
+ssize_t pwrite(int fd, const void *buf, size_t nbytes, off_t offset)
 {
-    return __pwrite64(fd, buf, nbytes, offset);
+    return pwrite64(fd, buf, nbytes, (off64_t)offset);
 }
 
diff --git a/libc/unistd/raise.c b/libc/unistd/raise.c
index de099da..7b03a7a 100644
--- a/libc/unistd/raise.c
+++ b/libc/unistd/raise.c
@@ -30,5 +30,5 @@
 
 int raise(int signum)
 {
-    return kill(getpid(), signum);
+    return kill(gettid(), signum);
 }
diff --git a/libthread_db/Android.mk b/libthread_db/Android.mk
index 3091bbc..922b9cf 100644
--- a/libthread_db/Android.mk
+++ b/libthread_db/Android.mk
@@ -21,7 +21,7 @@
 
 LOCAL_WHOLE_STATIC_LIBRARIES := libthread_db
 LOCAL_MODULE:=libthread_db
-LOCAL_SHARED_LIBRARIES := libdl
+LOCAL_SHARED_LIBRARIES := libdl libc
 
 # NOTE: Using --no-undefined results in a missing symbol that is defined inside
 # gdbserver and is resolved at runtime. Since there is no library containing
diff --git a/linker/Android.mk b/linker/Android.mk
index 27a6677..da311cd 100644
--- a/linker/Android.mk
+++ b/linker/Android.mk
@@ -4,6 +4,7 @@
 LOCAL_SRC_FILES:= \
 	arch/$(TARGET_ARCH)/begin.S \
 	linker.c \
+	linker_environ.c \
 	linker_format.c \
 	rt.c \
 	dlfcn.c \
@@ -93,6 +94,6 @@
 # just for this module
 $(LOCAL_BUILT_MODULE): TARGET_CRTBEGIN_STATIC_O :=
 # This line is not strictly necessary because the dynamic linker is built
-# as a static executable, but it won't hurt if in the future we start 
+# as a static executable, but it won't hurt if in the future we start
 # building the linker as a dynamic one.
 $(LOCAL_BUILT_MODULE): TARGET_CRTBEGIN_DYNAMIC_O :=
diff --git a/linker/linker.c b/linker/linker.c
index 42a5205..c4f54f7 100644
--- a/linker/linker.c
+++ b/linker/linker.c
@@ -48,6 +48,7 @@
 
 #include "linker.h"
 #include "linker_debug.h"
+#include "linker_environ.h"
 #include "linker_format.h"
 
 #include "ba.h"
@@ -123,6 +124,9 @@
 int debug_verbosity;
 static int pid;
 
+/* This boolean is set if the program being loaded is setuid */
+static int program_is_setuid;
+
 #if STATS
 struct _link_stats linker_stats;
 #endif
@@ -286,7 +290,7 @@
 
     /* Make sure we get a clean block of soinfo */
     memset(si, 0, sizeof(soinfo));
-    strcpy((char*) si->name, name);
+    strlcpy((char*) si->name, name, sizeof(si->name));
     sonext->next = si;
     si->ba_index = -1; /* by default, prelinked */
     si->next = NULL;
@@ -314,7 +318,7 @@
         return;
     }
 
-    /* prev will never be NULL, because the first entry in solist is 
+    /* prev will never be NULL, because the first entry in solist is
        always the static libdl_info.
     */
     prev->next = si->next;
@@ -1232,8 +1236,8 @@
     return init_library(si);
 }
 
-/* TODO: 
- *   notify gdb of unload 
+/* TODO:
+ *   notify gdb of unload
  *   for non-prelinked libraries, find a way to decrement libbase
  */
 static void call_destructors(soinfo *si);
@@ -1765,14 +1769,14 @@
             }
 #endif
             if (phdr->p_type == PT_LOAD) {
-                /* For the executable, we use the si->size field only in 
-                   dl_unwind_find_exidx(), so the meaning of si->size 
-                   is not the size of the executable; it is the last 
+                /* For the executable, we use the si->size field only in
+                   dl_unwind_find_exidx(), so the meaning of si->size
+                   is not the size of the executable; it is the last
                    virtual address of the loadable part of the executable;
                    since si->base == 0 for an executable, we use the
-                   range [0, si->size) to determine whether a PC value 
+                   range [0, si->size) to determine whether a PC value
                    falls within the executable section.  Of course, if
-                   a value is below phdr->p_vaddr, it's not in the 
+                   a value is below phdr->p_vaddr, it's not in the
                    executable section, but a) we shouldn't be asking for
                    such a value anyway, and b) if we have to provide
                    an EXIDX for such a value, then the executable's
@@ -1927,7 +1931,7 @@
         }
     }
 
-    DEBUG("%5d si->base = 0x%08x, si->strtab = %p, si->symtab = %p\n", 
+    DEBUG("%5d si->base = 0x%08x, si->strtab = %p, si->symtab = %p\n",
            pid, si->base, si->strtab, si->symtab);
 
     if((si->strtab == 0) || (si->symtab == 0)) {
@@ -2033,7 +2037,7 @@
     ftp://ftp.freebsd.org/pub/FreeBSD/CERT/advisories/FreeBSD-SA-02:23.stdio.asc
 
      */
-    if (getuid() != geteuid() || getgid() != getegid())
+    if (program_is_setuid)
         nullify_closed_stdio ();
     call_constructors(si);
     notify_gdb_of_load(si);
@@ -2045,7 +2049,7 @@
     return -1;
 }
 
-static void parse_library_path(char *path, char *delim)
+static void parse_library_path(const char *path, char *delim)
 {
     size_t len;
     char *ldpaths_bufp = ldpaths_buf;
@@ -2068,7 +2072,7 @@
     }
 }
 
-static void parse_preloads(char *path, char *delim)
+static void parse_preloads(const char *path, char *delim)
 {
     size_t len;
     char *ldpreloads_bufp = ldpreloads_buf;
@@ -2110,8 +2114,8 @@
     unsigned *vecs = (unsigned*) (argv + argc + 1);
     soinfo *si;
     struct link_map * map;
-    char *ldpath_env = NULL;
-    char *ldpreload_env = NULL;
+    const char *ldpath_env = NULL;
+    const char *ldpreload_env = NULL;
 
     /* Setup a temporary TLS area that is used to get a working
      * errno for system calls.
@@ -2135,20 +2139,32 @@
      */
     __tls_area[TLS_SLOT_BIONIC_PREINIT] = elfdata;
 
+    /* Are we setuid? */
+    program_is_setuid = (getuid() != geteuid()) || (getgid() != getegid());
+
+    /* Initialize environment functions, and get to the ELF aux vectors table */
+    vecs = linker_env_init(vecs);
+
+    /* Sanitize environment if we're loading a setuid program */
+    if (program_is_setuid)
+        linker_env_secure();
+
     debugger_init();
 
-        /* skip past the environment */
-    while(vecs[0] != 0) {
-        if(!strncmp((char*) vecs[0], "DEBUG=", 6)) {
-            debug_verbosity = atoi(((char*) vecs[0]) + 6);
-        } else if(!strncmp((char*) vecs[0], "LD_LIBRARY_PATH=", 16)) {
-            ldpath_env = (char*) vecs[0] + 16;
-        } else if(!strncmp((char*) vecs[0], "LD_PRELOAD=", 11)) {
-            ldpreload_env = (char*) vecs[0] + 11;
+    /* Get a few environment variables */
+    {
+        const char* env;
+        env = linker_env_get("DEBUG"); /* XXX: TODO: Change to LD_DEBUG */
+        if (env)
+            debug_verbosity = atoi(env);
+
+        /* Normally, these are cleaned by linker_env_secure, but the test
+         * against program_is_setuid doesn't cost us anything */
+        if (!program_is_setuid) {
+            ldpath_env = linker_env_get("LD_LIBRARY_PATH");
+            ldpreload_env = linker_env_get("LD_PRELOAD");
         }
-        vecs++;
     }
-    vecs++;
 
     INFO("[ android linker & debugger ]\n");
     DEBUG("%5d elfdata @ 0x%08x\n", pid, (unsigned)elfdata);
@@ -2176,7 +2192,7 @@
          * is.  Don't use alloc_info(), because the linker shouldn't
          * be on the soinfo list.
          */
-    strcpy((char*) linker_soinfo.name, "/system/bin/linker");
+    strlcpy((char*) linker_soinfo.name, "/system/bin/linker", sizeof linker_soinfo.name);
     linker_soinfo.flags = 0;
     linker_soinfo.base = 0;     // This is the important part; must be zero.
     insert_soinfo_into_debug_map(&linker_soinfo);
@@ -2206,10 +2222,10 @@
     si->refcount = 1;
 
         /* Use LD_LIBRARY_PATH if we aren't setuid/setgid */
-    if (ldpath_env && getuid() == geteuid() && getgid() == getegid())
+    if (ldpath_env)
         parse_library_path(ldpath_env, ":");
 
-    if (ldpreload_env && getuid() == geteuid() && getgid() == getegid()) {
+    if (ldpreload_env) {
         parse_preloads(ldpreload_env, " :");
     }
 
diff --git a/linker/linker_environ.c b/linker/linker_environ.c
new file mode 100644
index 0000000..b71dd80
--- /dev/null
+++ b/linker/linker_environ.c
@@ -0,0 +1,204 @@
+/*
+ * 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 "linker_environ.h"
+#include <stddef.h>
+
+static char** _envp;
+
+/* Returns 1 if 'str' points to a valid environment variable definition.
+ * For now, we check that:
+ *  - It is smaller than MAX_ENV_LEN (to detect non-zero terminated strings)
+ *  - It contains at least one equal sign that is not the first character
+ */
+static int
+_is_valid_definition(const char*  str)
+{
+    int   pos = 0;
+    int   first_equal_pos = -1;
+
+    /* According to its sources, the kernel uses 32*PAGE_SIZE by default
+     * as the maximum size for an env. variable definition.
+     */
+    const int MAX_ENV_LEN = 32*4096;
+
+    if (str == NULL)
+        return 0;
+
+    /* Parse the string, looking for the first '=' there, and its size */
+    do {
+        if (str[pos] == '\0')
+            break;
+        if (str[pos] == '=' && first_equal_pos < 0)
+            first_equal_pos = pos;
+        pos++;
+    } while (pos < MAX_ENV_LEN);
+
+    if (pos >= MAX_ENV_LEN)  /* Too large */
+        return 0;
+
+    if (first_equal_pos < 1)  /* No equal sign, or it is the first character */
+        return 0;
+
+    return 1;
+}
+
+unsigned*
+linker_env_init(unsigned* vecs)
+{
+    /* Store environment pointer - can't be NULL */
+    _envp = (char**) vecs;
+
+    /* Skip over all definitions */
+    while (vecs[0] != 0)
+        vecs++;
+    /* The end of the environment block is marked by two NULL pointers */
+    vecs++;
+
+    /* As a sanity check, we're going to remove all invalid variable
+     * definitions from the environment array.
+     */
+    {
+        char** readp  = _envp;
+        char** writep = _envp;
+        for ( ; readp[0] != NULL; readp++ ) {
+            if (!_is_valid_definition(readp[0]))
+                continue;
+            writep[0] = readp[0];
+            writep++;
+        }
+        writep[0] = NULL;
+    }
+
+    /* Return the address of the aux vectors table */
+    return vecs;
+}
+
+/* Check if the environment variable definition at 'envstr'
+ * starts with '<name>=', and if so return the address of the
+ * first character after the equal sign. Otherwise return NULL.
+ */
+static char*
+env_match(char* envstr, const char* name)
+{
+    size_t  cnt = 0;
+
+    while (envstr[cnt] == name[cnt] && name[cnt] != '\0')
+        cnt++;
+
+    if (name[cnt] == '\0' && envstr[cnt] == '=')
+        return envstr + cnt + 1;
+
+    return NULL;
+}
+
+#define MAX_ENV_LEN  (16*4096)
+
+const char*
+linker_env_get(const char* name)
+{
+    char** readp = _envp;
+
+    if (name == NULL || name[0] == '\0')
+        return NULL;
+
+    for ( ; readp[0] != NULL; readp++ ) {
+        char* val = env_match(readp[0], name);
+        if (val != NULL) {
+            /* Return NULL for empty strings, or if it is too large */
+            if (val[0] == '\0')
+                val = NULL;
+            return val;
+        }
+    }
+    return NULL;
+}
+
+
+void
+linker_env_unset(const char* name)
+{
+    char**  readp = _envp;
+    char**  writep = readp;
+
+    if (name == NULL || name[0] == '\0')
+        return;
+
+    for ( ; readp[0] != NULL; readp++ ) {
+        if (env_match(readp[0], name))
+            continue;
+        writep[0] = readp[0];
+        writep++;
+    }
+    /* end list with a NULL */
+    writep[0] = NULL;
+}
+
+
+
+/* Remove unsafe environment variables. This should be used when
+ * running setuid programs. */
+void
+linker_env_secure(void)
+{
+    /* The same list than GLibc at this point */
+    static const char* const unsec_vars[] = {
+        "GCONV_PATH",
+        "GETCONF_DIR",
+        "HOSTALIASES",
+        "LD_AUDIT",
+        "LD_DEBUG",
+        "LD_DEBUG_OUTPUT",
+        "LD_DYNAMIC_WEAK",
+        "LD_LIBRARY_PATH",
+        "LD_ORIGIN_PATH",
+        "LD_PRELOAD",
+        "LD_PROFILE",
+        "LD_SHOW_AUXV",
+        "LD_USE_LOAD_BIAS",
+        "LOCALDOMAIN",
+        "LOCPATH",
+        "MALLOC_TRACE",
+        "MALLOC_CHECK_",
+        "NIS_PATH",
+        "NLSPATH",
+        "RESOLV_HOST_CONF",
+        "RES_OPTIONS",
+        "TMPDIR",
+        "TZDIR",
+        "LD_AOUT_LIBRARY_PATH",
+        "LD_AOUT_PRELOAD",
+    };
+
+    const char* const* cp   = unsec_vars;
+    const char* const* endp = cp + sizeof(unsec_vars)/sizeof(unsec_vars[0]);
+
+    while (cp < endp) {
+        linker_env_unset(*cp);
+        cp++;
+    }
+}
diff --git a/linker/linker_environ.h b/linker/linker_environ.h
new file mode 100644
index 0000000..98ad1de
--- /dev/null
+++ b/linker/linker_environ.h
@@ -0,0 +1,54 @@
+/*
+ * 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 LINKER_ENVIRON_H
+#define LINKER_ENVIRON_H
+
+/* Call this function before anything else. 'vecs' must be the pointer
+ * to the environment block in the ELF data block. The function returns
+ * the start of the aux vectors after the env block.
+ */
+extern unsigned*   linker_env_init(unsigned* vecs);
+
+/* Unset a given environment variable. In case the variable is defined
+ * multiple times, unset all instances. This modifies the environment
+ * block, so any pointer returned by linker_env_get() after this call
+ * might become invalid */
+extern void        linker_env_unset(const char* name);
+
+
+/* Returns the value of environment variable 'name' if defined and not
+ * empty, or NULL otherwise. Note that the returned pointer may become
+ * invalid if linker_env_unset() or linker_env_secure() are called
+ * after this function. */
+extern const char* linker_env_get(const char* name);
+
+/* Remove unsecure environment variables. This should be used when
+ * running setuid programs. */
+extern void        linker_env_secure(void);
+
+#endif /* LINKER_ENVIRON_H */