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