aboutsummaryrefslogtreecommitdiffstats
path: root/libc
diff options
context:
space:
mode:
Diffstat (limited to 'libc')
-rw-r--r--libc/Android.mk23
-rw-r--r--libc/SYSCALLS.TXT8
-rw-r--r--libc/arch-arm/bionic/arm_memcpy.S123
-rw-r--r--libc/arch-arm/bionic/ffs.S35
-rw-r--r--libc/arch-arm/bionic/memcpy.S3
-rw-r--r--libc/arch-arm/bionic/strcmp.S321
-rw-r--r--libc/arch-arm/bionic/strcpy.S138
-rw-r--r--libc/arch-arm/include/endian.h83
-rw-r--r--libc/arch-arm/syscalls.mk5
-rw-r--r--libc/arch-arm/syscalls/adjtimex.S19
-rw-r--r--libc/arch-arm/syscalls/getsid.S19
-rw-r--r--libc/arch-arm/syscalls/stime.S19
-rw-r--r--libc/arch-arm/syscalls/swapoff.S19
-rw-r--r--libc/arch-arm/syscalls/swapon.S19
-rw-r--r--libc/arch-sh/syscalls.mk5
-rw-r--r--libc/arch-sh/syscalls/adjtimex.S32
-rw-r--r--libc/arch-sh/syscalls/getsid.S32
-rw-r--r--libc/arch-sh/syscalls/readlinkat.S32
-rw-r--r--libc/arch-sh/syscalls/signalfd.S32
-rw-r--r--libc/arch-sh/syscalls/stime.S32
-rw-r--r--libc/arch-sh/syscalls/swapoff.S32
-rw-r--r--libc/arch-sh/syscalls/swapon.S32
-rw-r--r--libc/arch-x86/syscalls.mk5
-rw-r--r--libc/arch-x86/syscalls/adjtimex.S23
-rw-r--r--libc/arch-x86/syscalls/getsid.S23
-rw-r--r--libc/arch-x86/syscalls/stime.S23
-rw-r--r--libc/arch-x86/syscalls/swapoff.S23
-rw-r--r--libc/arch-x86/syscalls/swapon.S26
-rw-r--r--libc/bionic/dlmalloc.c19
-rw-r--r--libc/bionic/malloc_debug_common.c1
-rw-r--r--libc/bionic/pthread.c7
-rw-r--r--libc/include/errno.h1
-rw-r--r--libc/include/mntent.h1
-rw-r--r--libc/include/pthread.h5
-rw-r--r--libc/include/resolv.h18
-rw-r--r--libc/include/sys/_system_properties.h3
-rw-r--r--libc/include/sys/linux-syscalls.h5
-rw-r--r--libc/include/sys/linux-unistd.h5
-rw-r--r--libc/kernel/common/linux/akm8975.h92
-rw-r--r--libc/kernel/common/linux/android_pmem.h44
-rw-r--r--libc/kernel/common/linux/msm_audio_7X30.h329
-rw-r--r--libc/kernel/common/linux/msm_audio_aac.h78
-rw-r--r--libc/kernel/common/linux/msm_mdp.h153
-rw-r--r--libc/kernel/common/linux/msm_q6vdec.h8
-rwxr-xr-xlibc/kernel/common/linux/msm_rotator.h61
-rw-r--r--libc/kernel/common/linux/msm_vidc_dec.h88
-rw-r--r--libc/kernel/common/linux/msm_vidc_enc.h67
-rw-r--r--libc/kernel/common/linux/spi_aic3254.h151
-rw-r--r--libc/kernel/common/linux/tpa2051d3.h52
-rw-r--r--libc/kernel/common/linux/videodev2.h3
-rw-r--r--libc/netbsd/net/getaddrinfo.c199
-rw-r--r--libc/netbsd/net/getnameinfo.c110
-rw-r--r--libc/netbsd/resolv/res_cache.c622
-rw-r--r--libc/netbsd/resolv/res_init.c6
-rw-r--r--libc/netbsd/resolv/res_send.c2
-rw-r--r--libc/netbsd/resolv/res_state.c99
-rw-r--r--libc/private/bionic_tls.h7
-rw-r--r--libc/private/resolv_cache.h38
-rw-r--r--libc/stdio/wcio.h2
-rw-r--r--libc/string/memmove.c37
-rwxr-xr-xlibc/tools/checksyscalls.py4
-rw-r--r--libc/unistd/exec.c6
-rw-r--r--libc/unistd/raise.c3
63 files changed, 3241 insertions, 271 deletions
diff --git a/libc/Android.mk b/libc/Android.mk
index aae80da5d..30af6ca12 100644
--- a/libc/Android.mk
+++ b/libc/Android.mk
@@ -187,7 +187,6 @@ libc_common_src_files := \
string/strcat.c \
string/strchr.c \
string/strcoll.c \
- string/strcpy.c \
string/strcspn.c \
string/strdup.c \
string/strerror.c \
@@ -354,13 +353,16 @@ libc_common_src_files += \
arch-arm/bionic/setjmp.S \
arch-arm/bionic/sigsetjmp.S \
arch-arm/bionic/strlen.c.arm \
+ arch-arm/bionic/strcpy.S \
+ arch-arm/bionic/strcmp.S \
arch-arm/bionic/syscall.S \
string/memmove.c.arm \
string/bcopy.c \
- string/strcmp.c \
string/strncmp.c \
unistd/socketcalls.c
+
+
# These files need to be arm so that gdbserver
# can set breakpoints in them without messing
# up any thumb code.
@@ -403,6 +405,7 @@ libc_common_src_files += \
arch-x86/string/strncmp_wrapper.S \
arch-x86/string/strlen_wrapper.S \
bionic/pthread-rwlocks.c \
+ string/strcpy.c \
bionic/pthread-timers.c \
bionic/ptrace.c
@@ -442,6 +445,7 @@ libc_common_src_files += \
string/memcmp.c \
string/strlen.c \
bionic/pthread-rwlocks.c \
+ string/strcpy.c \
bionic/pthread-timers.c \
bionic/ptrace.c \
unistd/socketcalls.c
@@ -494,6 +498,9 @@ ifeq ($(TARGET_ARCH),arm)
ifeq ($(ARCH_ARM_HAVE_TLS_REGISTER),true)
libc_common_cflags += -DHAVE_ARM_TLS_REGISTER
endif
+ ifeq ($(TARGET_HAVE_TEGRA_ERRATA_657451),true)
+ libc_common_cflags += -DHAVE_TEGRA_ERRATA_657451
+ endif
else # !arm
ifeq ($(TARGET_ARCH),x86)
libc_crt_target_cflags := -m32
@@ -516,6 +523,10 @@ endif
#
libc_crt_target_cflags += -I$(LOCAL_PATH)/private
+ifeq ($(BOARD_USE_NASTY_PTHREAD_CREATE_HACK),true)
+ libc_common_cflags += -DNASTY_PTHREAD_CREATE_HACK
+endif
+
ifeq ($(TARGET_ARCH),arm)
libc_crt_target_cflags += -DCRT_LEGACY_WORKAROUND
endif
@@ -597,6 +608,14 @@ include $(CLEAR_VARS)
LOCAL_SRC_FILES := $(libc_common_src_files)
LOCAL_CFLAGS := $(libc_common_cflags)
+ifdef NEEDS_ARM_ERRATA_754319_754320
+asm_flags := \
+ --defsym NEEDS_ARM_ERRATA_754319_754320_ASM=1
+
+LOCAL_CFLAGS+= \
+ $(foreach f,$(asm_flags),-Wa,"$(f)")
+endif
+
ifeq ($(TARGET_ARCH),arm)
LOCAL_CFLAGS += -DCRT_LEGACY_WORKAROUND
endif
diff --git a/libc/SYSCALLS.TXT b/libc/SYSCALLS.TXT
index 0850b8282..a2b7a32ce 100644
--- a/libc/SYSCALLS.TXT
+++ b/libc/SYSCALLS.TXT
@@ -173,7 +173,7 @@ int __timer_gettime:timer_gettime(timer_t, struct itimerspec*)
int __timer_getoverrun:timer_getoverrun(timer_t) 260,262
int __timer_delete:timer_delete(timer_t) 261,263
int utimes(const char*, const struct timeval tvp[2]) 269, 271
-
+int adjtimex(struct timex *) 124
# signals
int sigaction(int, const struct sigaction *, struct sigaction *) 67
int sigprocmask(int, const sigset_t *, sigset_t *) 126
@@ -264,3 +264,9 @@ 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
+
+# busybox: 2010-01-17
+int stime(time_t *) 25
+int swapon(const char *, int) 87
+int swapoff(const char *) 115
+pid_t getsid(pid_t pid) 147
diff --git a/libc/arch-arm/bionic/arm_memcpy.S b/libc/arch-arm/bionic/arm_memcpy.S
new file mode 100644
index 000000000..ae1cf1ad1
--- /dev/null
+++ b/libc/arch-arm/bionic/arm_memcpy.S
@@ -0,0 +1,123 @@
+/*
+ * Copyright (C) 2011 Texas Instruments
+ * 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.
+ */
+
+ .text
+ .fpu neon
+ .code 32
+ .align 4
+
+
+/* r0 - dest */
+/* r1 - src */
+/* r2 - length */
+ .global memcpy
+memcpy:
+ .fnstart
+#if defined TARGET_BOARD_PLATFORM == omap4
+#define CACHE_LINE_SIZE 32
+#else
+#define CACHE_LINE_SIZE 64
+#endif
+ CMP r2,#3
+ BLS _BMLIB_memcpy_lastbytes
+ ANDS r12,r0,#3
+ BEQ l1;
+ LDRB r3,[r1],#1
+ CMP r12,#2
+ ADD r2,r2,r12
+ LDRLSB r12, [r1], #1
+ STRB r3,[r0],#1
+ LDRCCB r3,[r1],#1
+ STRLSB r12,[r0],#1
+ SUB r2,r2,#4
+ STRCCB r3,[r0],#1
+l1:
+ ANDS r3,r1,#3
+ BEQ _BMLIB_aeabi_memcpy4
+l3:
+ SUBS r2,r2,#8
+ BCC l2
+ LDR r3,[r1],#4
+ LDR r12,[r1],#4
+ STR r3,[r0],#4
+ STR r12,[r0],#4
+ B l3
+l2:
+ ADDS r2,r2,#4
+ LDRPL r3,[r1],#4
+ STRPL r3,[r0],#4
+ MOV r0,r0
+_BMLIB_memcpy_lastbytes:
+ LSLS r2,r2,#31
+ LDRCSB r3,[r1],#1
+ LDRCSB r12,[r1],#1
+ LDRMIB r2,[r1],#1
+ STRCSB r3,[r0],#1
+ STRCSB r12,[r0],#1
+ STRMIB r2,[r0],#1
+ BX lr
+
+_BMLIB_aeabi_memcpy4:
+ PUSH {r4-r8,lr}
+ SUBS r2,r2,#0x20
+ BCC l4
+ DSB
+#ifndef NOPLD
+ PLD [r1, #0]
+ PLD [r1, #(CACHE_LINE_SIZE*1)]
+ PLD [r1, #(CACHE_LINE_SIZE*2)]
+ PLD [r1, #(CACHE_LINE_SIZE*3)]
+ PLD [r1, #(CACHE_LINE_SIZE*4)]
+#endif
+l5:
+#ifndef NOPLD
+ PLD [r1, #(CACHE_LINE_SIZE*5)]
+#endif
+ LDMCS r1!,{r3-r8,r12,lr}
+ STMCS r0!,{r3-r8,r12,lr}
+ SUBS r2,r2,#0x20
+ BCS l5
+l4:
+ LSLS r12,r2,#28
+ LDMCS r1!,{r3,r4,r12,lr}
+ STMCS r0!,{r3,r4,r12,lr}
+ LDMMI r1!,{r3,r4}
+ STMMI r0!,{r3,r4}
+ POP {r4-r8,lr}
+ LSLS r12,r2,#30
+ LDRCS r3,[r1],#4
+ STRCS r3,[r0],#4
+ BXEQ lr
+_BMLIB_memcpy_lastbytes_aligned:
+ LSLS r2,r2,#31
+ LDRCSH r3,[r1],#2
+ LDRMIB r2,[r1],#1
+ STRCSH r3,[r0],#2
+ STRMIB r2,[r0],#1
+ BX lr
+ .fnend
diff --git a/libc/arch-arm/bionic/ffs.S b/libc/arch-arm/bionic/ffs.S
index f11141c97..052b46a53 100644
--- a/libc/arch-arm/bionic/ffs.S
+++ b/libc/arch-arm/bionic/ffs.S
@@ -36,47 +36,14 @@
* 6 bits as an index into the table. This algorithm should be a win
* over the checking each bit in turn as per the C compiled version.
*
- * under ARMv5 there's an instruction called CLZ (count leading Zero's) that
- * could be used
- *
- * This is the ffs algorithm devised by d.seal and posted to comp.sys.arm on
- * 16 Feb 1994.
+ * since ARMv5 there's an instruction called CLZ (count leading Zero's)
*/
ENTRY(ffs)
/* Standard trick to isolate bottom bit in r0 or 0 if r0 = 0 on entry */
rsb r1, r0, #0
ands r0, r0, r1
-#ifndef __ARM_ARCH_5__
- /*
- * now r0 has at most one set bit, call this X
- * if X = 0, all further instructions are skipped
- */
- adrne r2, .L_ffs_table
- orrne r0, r0, r0, lsl #4 /* r0 = X * 0x11 */
- orrne r0, r0, r0, lsl #6 /* r0 = X * 0x451 */
- rsbne r0, r0, r0, lsl #16 /* r0 = X * 0x0450fbaf */
-
- /* now lookup in table indexed on top 6 bits of r0 */
- ldrneb r0, [ r2, r0, lsr #26 ]
-
- bx lr
-
-.text;
-.type .L_ffs_table, _ASM_TYPE_OBJECT;
-.L_ffs_table:
-/* 0 1 2 3 4 5 6 7 */
- .byte 0, 1, 2, 13, 3, 7, 0, 14 /* 0- 7 */
- .byte 4, 0, 8, 0, 0, 0, 0, 15 /* 8-15 */
- .byte 11, 5, 0, 0, 9, 0, 0, 26 /* 16-23 */
- .byte 0, 0, 0, 0, 0, 22, 28, 16 /* 24-31 */
- .byte 32, 12, 6, 0, 0, 0, 0, 0 /* 32-39 */
- .byte 10, 0, 0, 25, 0, 0, 21, 27 /* 40-47 */
- .byte 31, 0, 0, 0, 0, 24, 0, 20 /* 48-55 */
- .byte 30, 0, 23, 19, 29, 18, 17, 0 /* 56-63 */
-#else
clzne r0, r0
rsbne r0, r0, #32
bx lr
-#endif
diff --git a/libc/arch-arm/bionic/memcpy.S b/libc/arch-arm/bionic/memcpy.S
index ba55996ec..79e878951 100644
--- a/libc/arch-arm/bionic/memcpy.S
+++ b/libc/arch-arm/bionic/memcpy.S
@@ -141,6 +141,9 @@ memcpy:
strcsb ip, [r0], #1
strcsb lr, [r0], #1
+.ifdef NEEDS_ARM_ERRATA_754319_754320_ASM
+ VMOV s0,s0 @ NOP for ARM Errata
+.endif
ldmfd sp!, {r0, lr}
bx lr
.fnend
diff --git a/libc/arch-arm/bionic/strcmp.S b/libc/arch-arm/bionic/strcmp.S
new file mode 100644
index 000000000..9fdbd567e
--- /dev/null
+++ b/libc/arch-arm/bionic/strcmp.S
@@ -0,0 +1,321 @@
+/*
+ * Copyright (c) 2011 The Android Open Source Project
+ * Copyright (c) 2008 ARM Ltd
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the company may not be used to endorse or promote
+ * products derived from this software without specific prior written
+ * permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY ARM LTD ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL ARM LTD BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <machine/cpu-features.h>
+
+ .text
+
+ .global strcmp
+ .type strcmp, %function
+ .align 4
+
+#ifdef __ARMEB__
+#define SHFT2LSB lsl
+#define SHFT2LSBEQ lsleq
+#define SHFT2MSB lsr
+#define SHFT2MSBEQ lsreq
+#define MSB 0x000000ff
+#define LSB 0xff000000
+#else
+#define SHFT2LSB lsr
+#define SHFT2LSBEQ lsreq
+#define SHFT2MSB lsl
+#define SHFT2MSBEQ lsleq
+#define MSB 0xff000000
+#define LSB 0x000000ff
+#endif
+
+#define magic1(REG) REG
+#define magic2(REG) REG, lsl #7
+
+strcmp:
+ .fnstart
+ PLD(r0, #0)
+ PLD(r1, #0)
+ eor r2, r0, r1
+ tst r2, #3
+
+ /* Strings not at same byte offset from a word boundary. */
+ bne .Lstrcmp_unaligned
+ ands r2, r0, #3
+ bic r0, r0, #3
+ bic r1, r1, #3
+ ldr ip, [r0], #4
+ it eq
+ ldreq r3, [r1], #4
+ beq 1f
+
+ /* Although s1 and s2 have identical initial alignment, they are
+ * not currently word aligned. Rather than comparing bytes,
+ * make sure that any bytes fetched from before the addressed
+ * bytes are forced to 0xff. Then they will always compare
+ * equal.
+ */
+ eor r2, r2, #3
+ lsl r2, r2, #3
+ mvn r3, #MSB
+ SHFT2LSB r2, r3, r2
+ ldr r3, [r1], #4
+ orr ip, ip, r2
+ orr r3, r3, r2
+1:
+ /* Load the 'magic' constant 0x01010101. */
+ str r4, [sp, #-4]!
+ mov r4, #1
+ orr r4, r4, r4, lsl #8
+ orr r4, r4, r4, lsl #16
+ .p2align 2
+4:
+ PLD(r0, #8)
+ PLD(r1, #8)
+ sub r2, ip, magic1(r4)
+ cmp ip, r3
+ itttt eq
+
+ /* check for any zero bytes in first word */
+ biceq r2, r2, ip
+ tsteq r2, magic2(r4)
+ ldreq ip, [r0], #4
+ ldreq r3, [r1], #4
+ beq 4b
+2:
+ /* There's a zero or a different byte in the word */
+ SHFT2MSB r0, ip, #24
+ SHFT2LSB ip, ip, #8
+ cmp r0, #1
+ it cs
+ cmpcs r0, r3, SHFT2MSB #24
+ it eq
+ SHFT2LSBEQ r3, r3, #8
+ beq 2b
+ /* On a big-endian machine, r0 contains the desired byte in bits
+ * 0-7; on a little-endian machine they are in bits 24-31. In
+ * both cases the other bits in r0 are all zero. For r3 the
+ * interesting byte is at the other end of the word, but the
+ * other bits are not necessarily zero. We need a signed result
+ * representing the differnece in the unsigned bytes, so for the
+ * little-endian case we can't just shift the interesting bits up.
+ */
+#ifdef __ARMEB__
+ sub r0, r0, r3, lsr #24
+#else
+ and r3, r3, #255
+ /* No RSB instruction in Thumb2 */
+#ifdef __thumb2__
+ lsr r0, r0, #24
+ sub r0, r0, r3
+#else
+ rsb r0, r3, r0, lsr #24
+#endif
+#endif
+ ldr r4, [sp], #4
+ bx lr
+ .fnend
+
+.Lstrcmp_unaligned:
+ wp1 .req r0
+ wp2 .req r1
+ b1 .req r2
+ w1 .req r4
+ w2 .req r5
+ t1 .req ip
+ @ r3 is scratch
+
+ /* First of all, compare bytes until wp1(sp1) is word-aligned. */
+1:
+ tst wp1, #3
+ beq 2f
+ ldrb r2, [wp1], #1
+ ldrb r3, [wp2], #1
+ cmp r2, #1
+ it cs
+ cmpcs r2, r3
+ beq 1b
+ sub r0, r2, r3
+ bx lr
+
+2:
+ str r5, [sp, #-4]!
+ str r4, [sp, #-4]!
+ mov b1, #1
+ orr b1, b1, b1, lsl #8
+ orr b1, b1, b1, lsl #16
+
+ and t1, wp2, #3
+ bic wp2, wp2, #3
+ ldr w1, [wp1], #4
+ ldr w2, [wp2], #4
+ cmp t1, #2
+ beq 2f
+ bhi 3f
+
+ /* Critical inner Loop: Block with 3 bytes initial overlap */
+ .p2align 2
+1:
+ bic t1, w1, #MSB
+ cmp t1, w2, SHFT2LSB #8
+ sub r3, w1, b1
+ bic r3, r3, w1
+ bne 4f
+ ands r3, r3, b1, lsl #7
+ it eq
+ ldreq w2, [wp2], #4
+ bne 5f
+ eor t1, t1, w1
+ cmp t1, w2, SHFT2MSB #24
+ bne 6f
+ ldr w1, [wp1], #4
+ b 1b
+4:
+ SHFT2LSB w2, w2, #8
+ b 8f
+
+5:
+#ifdef __ARMEB__
+ /* The syndrome value may contain false ones if the string ends
+ * with the bytes 0x01 0x00
+ */
+ tst w1, #0xff000000
+ itt ne
+ tstne w1, #0x00ff0000
+ tstne w1, #0x0000ff00
+ beq 7f
+#else
+ bics r3, r3, #0xff000000
+ bne 7f
+#endif
+ ldrb w2, [wp2]
+ SHFT2LSB t1, w1, #24
+#ifdef __ARMEB__
+ lsl w2, w2, #24
+#endif
+ b 8f
+
+6:
+ SHFT2LSB t1, w1, #24
+ and w2, w2, #LSB
+ b 8f
+
+ /* Critical inner Loop: Block with 2 bytes initial overlap */
+ .p2align 2
+2:
+ SHFT2MSB t1, w1, #16
+ sub r3, w1, b1
+ SHFT2LSB t1, t1, #16
+ bic r3, r3, w1
+ cmp t1, w2, SHFT2LSB #16
+ bne 4f
+ ands r3, r3, b1, lsl #7
+ it eq
+ ldreq w2, [wp2], #4
+ bne 5f
+ eor t1, t1, w1
+ cmp t1, w2, SHFT2MSB #16
+ bne 6f
+ ldr w1, [wp1], #4
+ b 2b
+
+5:
+#ifdef __ARMEB__
+ /* The syndrome value may contain false ones if the string ends
+ * with the bytes 0x01 0x00
+ */
+ tst w1, #0xff000000
+ it ne
+ tstne w1, #0x00ff0000
+ beq 7f
+#else
+ lsls r3, r3, #16
+ bne 7f
+#endif
+ ldrh w2, [wp2]
+ SHFT2LSB t1, w1, #16
+#ifdef __ARMEB__
+ lsl w2, w2, #16
+#endif
+ b 8f
+
+6:
+ SHFT2MSB w2, w2, #16
+ SHFT2LSB t1, w1, #16
+4:
+ SHFT2LSB w2, w2, #16
+ b 8f
+
+ /* Critical inner Loop: Block with 1 byte initial overlap */
+ .p2align 2
+3:
+ and t1, w1, #LSB
+ cmp t1, w2, SHFT2LSB #24
+ sub r3, w1, b1
+ bic r3, r3, w1
+ bne 4f
+ ands r3, r3, b1, lsl #7
+ it eq
+ ldreq w2, [wp2], #4
+ bne 5f
+ eor t1, t1, w1
+ cmp t1, w2, SHFT2MSB #8
+ bne 6f
+ ldr w1, [wp1], #4
+ b 3b
+4:
+ SHFT2LSB w2, w2, #24
+ b 8f
+5:
+ /* The syndrome value may contain false ones if the string ends
+ * with the bytes 0x01 0x00
+ */
+ tst w1, #LSB
+ beq 7f
+ ldr w2, [wp2], #4
+6:
+ SHFT2LSB t1, w1, #8
+ bic w2, w2, #MSB
+ b 8f
+7:
+ mov r0, #0
+ ldr r4, [sp], #4
+ ldr r5, [sp], #4
+ bx lr
+
+8:
+ and r2, t1, #LSB
+ and r0, w2, #LSB
+ cmp r0, #1
+ it cs
+ cmpcs r0, r2
+ itt eq
+ SHFT2LSBEQ t1, t1, #8
+ SHFT2LSBEQ w2, w2, #8
+ beq 8b
+ sub r0, r2, r0
+ ldr r4, [sp], #4
+ ldr r5, [sp], #4
+ bx lr
diff --git a/libc/arch-arm/bionic/strcpy.S b/libc/arch-arm/bionic/strcpy.S
new file mode 100644
index 000000000..70c353f79
--- /dev/null
+++ b/libc/arch-arm/bionic/strcpy.S
@@ -0,0 +1,138 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ * Copyright (c) 2008 ARM Ltd
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the company may not be used to endorse or promote
+ * products derived from this software without specific prior written
+ * permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY ARM LTD ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL ARM LTD BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Android adaptation and tweak by Jim Huang <jserv@0xlab.org>.
+ */
+
+#include <machine/cpu-features.h>
+
+ .text
+
+ .global strcpy
+ .type strcpy, %function
+ .align 4
+
+strcpy:
+ .fnstart
+ PLD(r1, #0)
+ eor r2, r0, r1
+ mov ip, r0
+ tst r2, #3
+ bne 4f
+ tst r1, #3
+ bne 3f
+5:
+ str r5, [sp, #-4]!
+ mov r5, #0x01
+ orr r5, r5, r5, lsl #8
+ orr r5, r5, r5, lsl #16
+
+ str r4, [sp, #-4]!
+ tst r1, #4
+ ldr r3, [r1], #4
+ beq 2f
+ sub r2, r3, r5
+ bics r2, r2, r3
+ tst r2, r5, lsl #7
+ itt eq
+ streq r3, [ip], #4
+ ldreq r3, [r1], #4
+ bne 1f
+ /* Inner loop. We now know that r1 is 64-bit aligned, so we
+ can safely fetch up to two words. This allows us to avoid
+ load stalls. */
+ .p2align 2
+2:
+ PLD(r1, #8)
+ ldr r4, [r1], #4
+ sub r2, r3, r5
+ bics r2, r2, r3
+ tst r2, r5, lsl #7
+ sub r2, r4, r5
+ bne 1f
+ str r3, [ip], #4
+ bics r2, r2, r4
+ tst r2, r5, lsl #7
+ itt eq
+ ldreq r3, [r1], #4
+ streq r4, [ip], #4
+ beq 2b
+ mov r3, r4
+1:
+#ifdef __ARMEB__
+ rors r3, r3, #24
+#endif
+ strb r3, [ip], #1
+ tst r3, #0xff
+#ifdef __ARMEL__
+ ror r3, r3, #8
+#endif
+ bne 1b
+ ldr r4, [sp], #4
+ ldr r5, [sp], #4
+ bx lr
+
+ /* Strings have the same offset from word alignment, but it's
+ not zero. */
+3:
+ tst r1, #1
+ beq 1f
+ ldrb r2, [r1], #1
+ strb r2, [ip], #1
+ cmp r2, #0
+ it eq
+ bxeq lr
+1:
+ tst r1, #2
+ beq 5b
+ ldrh r2, [r1], #2
+#ifdef __ARMEB__
+ tst r2, #0xff00
+ iteet ne
+ strneh r2, [ip], #2
+ lsreq r2, r2, #8
+ streqb r2, [ip]
+ tstne r2, #0xff
+#else
+ tst r2, #0xff
+ itet ne
+ strneh r2, [ip], #2
+ streqb r2, [ip]
+ tstne r2, #0xff00
+#endif
+ bne 5b
+ bx lr
+
+ /* src and dst do not have a common word-alignement. Fall back to
+ byte copying. */
+4:
+ ldrb r2, [r1], #1
+ strb r2, [ip], #1
+ cmp r2, #0
+ bne 4b
+ bx lr
diff --git a/libc/arch-arm/include/endian.h b/libc/arch-arm/include/endian.h
index 04204ed4c..e34872fcb 100644
--- a/libc/arch-arm/include/endian.h
+++ b/libc/arch-arm/include/endian.h
@@ -1,5 +1,86 @@
/* $OpenBSD: endian.h,v 1.3 2005/12/13 00:35:23 millert 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.
+ */
+
+#ifndef _ARM_ENDIAN_H_
+#define _ARM_ENDIAN_H_
+
+#ifdef __GNUC__
+
+/* NOTE: header <machine/cpu-features.h> could not be included directly
+ * since it defines extra macros, such as PLD.
+ */
+#if defined(__ARM_ARCH_7A__) || defined(__ARM_ARCH_7R__) || \
+ defined(__ARM_ARCH_7__) || \
+ defined(__ARM_ARCH_6__) || defined(__ARM_ARCH_6J__) || \
+ defined(__ARM_ARCH_6K__) || defined(__ARM_ARCH_6Z__) || \
+ defined(__ARM_ARCH_6ZK__) || defined(__ARM_ARCH_6T2__)
+
+/* According to RealView Assembler User's Guide, REV and REV16 are available
+ * in Thumb code and 16-bit instructions when used in Thumb-2 code.
+ *
+ * REV Rd, Rm
+ * Rd and Rm must both be Lo registers.
+ *
+ * REV16 Rd, Rm
+ * Rd and Rm must both be Lo registers.
+ */
+#ifdef __thumb__
+#define REV_LO_REG asm("r4")
+#else
+#define REV_LO_REG
+#endif
+
+#define __swap16md(x) ({ \
+ register u_int16_t _x REV_LO_REG = (x); \
+ __asm volatile ("rev16 %0, %0" : "+r" (_x)); \
+ _x; \
+})
+
+#define __swap32md(x) ({ \
+ register u_int32_t _x REV_LO_REG = (x); \
+ __asm volatile ("rev %0, %0" : "+r" (_x)); \
+ _x; \
+})
+
+#define __swap64md(x) ({ \
+ u_int64_t _x = (x); \
+ (u_int64_t) __swap32md(_x >> 32) | \
+ (u_int64_t) __swap32md(_x & 0xffffffff) << 32; \
+})
+
+/* Tell sys/endian.h we have MD variants of the swap macros. */
+#define MD_SWAP
+
+#endif /* __ARM_ARCH__ */
+#endif /* __GNUC__ */
+
#ifdef __ARMEB__
#define _BYTE_ORDER _BIG_ENDIAN
#else
@@ -8,3 +89,5 @@
#define __STRICT_ALIGNMENT
#include <sys/types.h>
#include <sys/endian.h>
+
+#endif /* !_ARM_ENDIAN_H_ */
diff --git a/libc/arch-arm/syscalls.mk b/libc/arch-arm/syscalls.mk
index ba78c1846..869e61377 100644
--- a/libc/arch-arm/syscalls.mk
+++ b/libc/arch-arm/syscalls.mk
@@ -123,6 +123,7 @@ syscall_src += arch-arm/syscalls/__timer_gettime.S
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/adjtimex.S
syscall_src += arch-arm/syscalls/sigaction.S
syscall_src += arch-arm/syscalls/sigprocmask.S
syscall_src += arch-arm/syscalls/__sigsuspend.S
@@ -175,3 +176,7 @@ 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/stime.S
+syscall_src += arch-arm/syscalls/swapon.S
+syscall_src += arch-arm/syscalls/swapoff.S
+syscall_src += arch-arm/syscalls/getsid.S
diff --git a/libc/arch-arm/syscalls/adjtimex.S b/libc/arch-arm/syscalls/adjtimex.S
new file mode 100644
index 000000000..c89ff1bf2
--- /dev/null
+++ b/libc/arch-arm/syscalls/adjtimex.S
@@ -0,0 +1,19 @@
+/* autogenerated by gensyscalls.py */
+#include <sys/linux-syscalls.h>
+
+ .text
+ .type adjtimex, #function
+ .globl adjtimex
+ .align 4
+ .fnstart
+
+adjtimex:
+ .save {r4, r7}
+ stmfd sp!, {r4, r7}
+ ldr r7, =__NR_adjtimex
+ swi #0
+ ldmfd sp!, {r4, r7}
+ movs r0, r0
+ bxpl lr
+ b __set_syscall_errno
+ .fnend
diff --git a/libc/arch-arm/syscalls/getsid.S b/libc/arch-arm/syscalls/getsid.S
new file mode 100644
index 000000000..6d9b3afea
--- /dev/null
+++ b/libc/arch-arm/syscalls/getsid.S
@@ -0,0 +1,19 @@
+/* autogenerated by gensyscalls.py */
+#include <sys/linux-syscalls.h>
+
+ .text
+ .type getsid, #function
+ .globl getsid
+ .align 4
+ .fnstart
+
+getsid:
+ .save {r4, r7}
+ stmfd sp!, {r4, r7}
+ ldr r7, =__NR_getsid
+ swi #0
+ ldmfd sp!, {r4, r7}
+ movs r0, r0
+ bxpl lr
+ b __set_syscall_errno
+ .fnend
diff --git a/libc/arch-arm/syscalls/stime.S b/libc/arch-arm/syscalls/stime.S
new file mode 100644
index 000000000..05f131bb8
--- /dev/null
+++ b/libc/arch-arm/syscalls/stime.S
@@ -0,0 +1,19 @@
+/* autogenerated by gensyscalls.py */
+#include <sys/linux-syscalls.h>
+
+ .text
+ .type stime, #function
+ .globl stime
+ .align 4
+ .fnstart
+
+stime:
+ .save {r4, r7}
+ stmfd sp!, {r4, r7}
+ ldr r7, =__NR_stime
+ swi #0
+ ldmfd sp!, {r4, r7}
+ movs r0, r0
+ bxpl lr
+ b __set_syscall_errno
+ .fnend
diff --git a/libc/arch-arm/syscalls/swapoff.S b/libc/arch-arm/syscalls/swapoff.S
new file mode 100644
index 000000000..f1faae13c
--- /dev/null
+++ b/libc/arch-arm/syscalls/swapoff.S
@@ -0,0 +1,19 @@
+/* autogenerated by gensyscalls.py */
+#include <sys/linux-syscalls.h>
+
+ .text
+ .type swapoff, #function
+ .globl swapoff
+ .align 4
+ .fnstart
+
+swapoff:
+ .save {r4, r7}
+ stmfd sp!, {r4, r7}
+ ldr r7, =__NR_swapoff
+ swi #0
+ ldmfd sp!, {r4, r7}
+ movs r0, r0
+ bxpl lr
+ b __set_syscall_errno
+ .fnend
diff --git a/libc/arch-arm/syscalls/swapon.S b/libc/arch-arm/syscalls/swapon.S
new file mode 100644
index 000000000..fb67d8168
--- /dev/null
+++ b/libc/arch-arm/syscalls/swapon.S
@@ -0,0 +1,19 @@
+/* autogenerated by gensyscalls.py */
+#include <sys/linux-syscalls.h>
+
+ .text
+ .type swapon, #function
+ .globl swapon
+ .align 4
+ .fnstart
+
+swapon:
+ .save {r4, r7}
+ stmfd sp!, {r4, r7}
+ ldr r7, =__NR_swapon
+ swi #0
+ ldmfd sp!, {r4, r7}
+ movs r0, r0
+ bxpl lr
+ b __set_syscall_errno
+ .fnend
diff --git a/libc/arch-sh/syscalls.mk b/libc/arch-sh/syscalls.mk
index a87419d96..891678594 100644
--- a/libc/arch-sh/syscalls.mk
+++ b/libc/arch-sh/syscalls.mk
@@ -126,6 +126,7 @@ syscall_src += arch-sh/syscalls/__timer_gettime.S
syscall_src += arch-sh/syscalls/__timer_getoverrun.S
syscall_src += arch-sh/syscalls/__timer_delete.S
syscall_src += arch-sh/syscalls/utimes.S
+syscall_src += arch-sh/syscalls/adjtimex.S
syscall_src += arch-sh/syscalls/sigaction.S
syscall_src += arch-sh/syscalls/sigprocmask.S
syscall_src += arch-sh/syscalls/__sigsuspend.S
@@ -162,3 +163,7 @@ 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
+syscall_src += arch-sh/syscalls/stime.S
+syscall_src += arch-sh/syscalls/swapon.S
+syscall_src += arch-sh/syscalls/swapoff.S
+syscall_src += arch-sh/syscalls/getsid.S
diff --git a/libc/arch-sh/syscalls/adjtimex.S b/libc/arch-sh/syscalls/adjtimex.S
new file mode 100644
index 000000000..255bd4734
--- /dev/null
+++ b/libc/arch-sh/syscalls/adjtimex.S
@@ -0,0 +1,32 @@
+/* autogenerated by gensyscalls.py */
+#include <sys/linux-syscalls.h>
+
+ .text
+ .type adjtimex, @function
+ .globl adjtimex
+ .align 4
+
+adjtimex:
+
+ /* invoke trap */
+ mov.l 0f, r3 /* trap num */
+ trapa #(1 + 0x10)
+
+ /* check return value */
+ cmp/pz r0
+ bt __NR_adjtimex_end
+
+ /* keep error number */
+ sts.l pr, @-r15
+ mov.l 1f, r1
+ jsr @r1
+ mov r0, r4
+ lds.l @r15+, pr
+
+__NR_adjtimex_end:
+ rts
+ nop
+
+ .align 2
+0: .long __NR_adjtimex
+1: .long __set_syscall_errno
diff --git a/libc/arch-sh/syscalls/getsid.S b/libc/arch-sh/syscalls/getsid.S
new file mode 100644
index 000000000..73d5e3201
--- /dev/null
+++ b/libc/arch-sh/syscalls/getsid.S
@@ -0,0 +1,32 @@
+/* autogenerated by gensyscalls.py */
+#include <sys/linux-syscalls.h>
+
+ .text
+ .type getsid, @function
+ .globl getsid
+ .align 4
+
+getsid:
+
+ /* invoke trap */
+ mov.l 0f, r3 /* trap num */
+ trapa #(1 + 0x10)
+
+ /* check return value */
+ cmp/pz r0
+ bt __NR_getsid_end
+
+ /* keep error number */
+ sts.l pr, @-r15
+ mov.l 1f, r1
+ jsr @r1
+ mov r0, r4
+ lds.l @r15+, pr
+
+__NR_getsid_end:
+ rts
+ nop
+
+ .align 2
+0: .long __NR_getsid
+1: .long __set_syscall_errno
diff --git a/libc/arch-sh/syscalls/readlinkat.S b/libc/arch-sh/syscalls/readlinkat.S
new file mode 100644
index 000000000..5b23060b3
--- /dev/null
+++ b/libc/arch-sh/syscalls/readlinkat.S
@@ -0,0 +1,32 @@
+/* autogenerated by gensyscalls.py */
+#include <sys/linux-syscalls.h>
+
+ .text
+ .type readlinkat, @function
+ .globl readlinkat
+ .align 4
+
+readlinkat:
+
+ /* invoke trap */
+ mov.l 0f, r3 /* trap num */
+ trapa #(4 + 0x10)
+
+ /* check return value */
+ cmp/pz r0
+ bt __NR_readlinkat_end
+
+ /* keep error number */
+ sts.l pr, @-r15
+ mov.l 1f, r1
+ jsr @r1
+ mov r0, r4
+ lds.l @r15+, pr
+
+__NR_readlinkat_end:
+ rts
+ nop
+
+ .align 2
+0: .long __NR_readlinkat
+1: .long __set_syscall_errno
diff --git a/libc/arch-sh/syscalls/signalfd.S b/libc/arch-sh/syscalls/signalfd.S
new file mode 100644
index 000000000..896e90900
--- /dev/null
+++ b/libc/arch-sh/syscalls/signalfd.S
@@ -0,0 +1,32 @@
+/* autogenerated by gensyscalls.py */
+#include <sys/linux-syscalls.h>
+
+ .text
+ .type signalfd, @function
+ .globl signalfd
+ .align 4
+
+signalfd:
+
+ /* invoke trap */
+ mov.l 0f, r3 /* trap num */
+ trapa #(3 + 0x10)
+
+ /* check return value */
+ cmp/pz r0
+ bt __NR_signalfd_end
+
+ /* keep error number */
+ sts.l pr, @-r15
+ mov.l 1f, r1
+ jsr @r1
+ mov r0, r4
+ lds.l @r15+, pr
+
+__NR_signalfd_end:
+ rts
+ nop
+
+ .align 2
+0: .long __NR_signalfd
+1: .long __set_syscall_errno
diff --git a/libc/arch-sh/syscalls/stime.S b/libc/arch-sh/syscalls/stime.S
new file mode 100644
index 000000000..687cdff3e
--- /dev/null
+++ b/libc/arch-sh/syscalls/stime.S
@@ -0,0 +1,32 @@
+/* autogenerated by gensyscalls.py */
+#include <sys/linux-syscalls.h>
+
+ .text
+ .type stime, @function
+ .globl stime
+ .align 4
+
+stime:
+
+ /* invoke trap */
+ mov.l 0f, r3 /* trap num */
+ trapa #(1 + 0x10)
+
+ /* check return value */
+ cmp/pz r0
+ bt __NR_stime_end
+
+ /* keep error number */
+ sts.l pr, @-r15
+ mov.l 1f, r1
+ jsr @r1
+ mov r0, r4
+ lds.l @r15+, pr
+
+__NR_stime_end:
+ rts
+ nop
+
+ .align 2
+0: .long __NR_stime
+1: .long __set_syscall_errno
diff --git a/libc/arch-sh/syscalls/swapoff.S b/libc/arch-sh/syscalls/swapoff.S
new file mode 100644
index 000000000..be980c689
--- /dev/null
+++ b/libc/arch-sh/syscalls/swapoff.S
@@ -0,0 +1,32 @@
+/* autogenerated by gensyscalls.py */
+#include <sys/linux-syscalls.h>
+
+ .text
+ .type swapoff, @function
+ .globl swapoff
+ .align 4
+
+swapoff:
+
+ /* invoke trap */
+ mov.l 0f, r3 /* trap num */
+ trapa #(1 + 0x10)
+
+ /* check return value */
+ cmp/pz r0
+ bt __NR_swapoff_end
+
+ /* keep error number */
+ sts.l pr, @-r15
+ mov.l 1f, r1
+ jsr @r1
+ mov r0, r4
+ lds.l @r15+, pr
+
+__NR_swapoff_end:
+ rts
+ nop
+
+ .align 2
+0: .long __NR_swapoff
+1: .long __set_syscall_errno
diff --git a/libc/arch-sh/syscalls/swapon.S b/libc/arch-sh/syscalls/swapon.S
new file mode 100644
index 000000000..7c2e1fcf4
--- /dev/null
+++ b/libc/arch-sh/syscalls/swapon.S
@@ -0,0 +1,32 @@
+/* autogenerated by gensyscalls.py */
+#include <sys/linux-syscalls.h>
+
+ .text
+ .type swapon, @function
+ .globl swapon
+ .align 4
+
+swapon:
+
+ /* invoke trap */
+ mov.l 0f, r3 /* trap num */
+ trapa #(2 + 0x10)
+
+ /* check return value */
+ cmp/pz r0
+ bt __NR_swapon_end
+
+ /* keep error number */
+ sts.l pr, @-r15
+ mov.l 1f, r1
+ jsr @r1
+ mov r0, r4
+ lds.l @r15+, pr
+
+__NR_swapon_end:
+ rts
+ nop
+
+ .align 2
+0: .long __NR_swapon
+1: .long __set_syscall_errno
diff --git a/libc/arch-x86/syscalls.mk b/libc/arch-x86/syscalls.mk
index 420a91eb0..5a8daf94d 100644
--- a/libc/arch-x86/syscalls.mk
+++ b/libc/arch-x86/syscalls.mk
@@ -126,6 +126,7 @@ syscall_src += arch-x86/syscalls/__timer_gettime.S
syscall_src += arch-x86/syscalls/__timer_getoverrun.S
syscall_src += arch-x86/syscalls/__timer_delete.S
syscall_src += arch-x86/syscalls/utimes.S
+syscall_src += arch-x86/syscalls/adjtimex.S
syscall_src += arch-x86/syscalls/sigaction.S
syscall_src += arch-x86/syscalls/sigprocmask.S
syscall_src += arch-x86/syscalls/__sigsuspend.S
@@ -176,3 +177,7 @@ 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
+syscall_src += arch-x86/syscalls/stime.S
+syscall_src += arch-x86/syscalls/swapon.S
+syscall_src += arch-x86/syscalls/swapoff.S
+syscall_src += arch-x86/syscalls/getsid.S
diff --git a/libc/arch-x86/syscalls/adjtimex.S b/libc/arch-x86/syscalls/adjtimex.S
new file mode 100644
index 000000000..b21260651
--- /dev/null
+++ b/libc/arch-x86/syscalls/adjtimex.S
@@ -0,0 +1,23 @@
+/* autogenerated by gensyscalls.py */
+#include <sys/linux-syscalls.h>
+
+ .text
+ .type adjtimex, @function
+ .globl adjtimex
+ .align 4
+
+adjtimex:
+ pushl %ebx
+ mov 8(%esp), %ebx
+ movl $__NR_adjtimex, %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/getsid.S b/libc/arch-x86/syscalls/getsid.S
new file mode 100644
index 000000000..7046b9a01
--- /dev/null
+++ b/libc/arch-x86/syscalls/getsid.S
@@ -0,0 +1,23 @@
+/* autogenerated by gensyscalls.py */
+#include <sys/linux-syscalls.h>
+
+ .text
+ .type getsid, @function
+ .globl getsid
+ .align 4
+
+getsid:
+ pushl %ebx
+ mov 8(%esp), %ebx
+ movl $__NR_getsid, %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/stime.S b/libc/arch-x86/syscalls/stime.S
new file mode 100644
index 000000000..609aed33f
--- /dev/null
+++ b/libc/arch-x86/syscalls/stime.S
@@ -0,0 +1,23 @@
+/* autogenerated by gensyscalls.py */
+#include <sys/linux-syscalls.h>
+
+ .text
+ .type stime, @function
+ .globl stime
+ .align 4
+
+stime:
+ pushl %ebx
+ mov 8(%esp), %ebx
+ movl $__NR_stime, %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/swapoff.S b/libc/arch-x86/syscalls/swapoff.S
new file mode 100644
index 000000000..6782c3c56
--- /dev/null
+++ b/libc/arch-x86/syscalls/swapoff.S
@@ -0,0 +1,23 @@
+/* autogenerated by gensyscalls.py */
+#include <sys/linux-syscalls.h>
+
+ .text
+ .type swapoff, @function
+ .globl swapoff
+ .align 4
+
+swapoff:
+ pushl %ebx
+ mov 8(%esp), %ebx
+ movl $__NR_swapoff, %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/swapon.S b/libc/arch-x86/syscalls/swapon.S
new file mode 100644
index 000000000..f33af2886
--- /dev/null
+++ b/libc/arch-x86/syscalls/swapon.S
@@ -0,0 +1,26 @@
+/* autogenerated by gensyscalls.py */
+#include <sys/linux-syscalls.h>
+
+ .text
+ .type swapon, @function
+ .globl swapon
+ .align 4
+
+swapon:
+ pushl %ebx
+ pushl %ecx
+ mov 12(%esp), %ebx
+ mov 16(%esp), %ecx
+ movl $__NR_swapon, %eax
+ int $0x80
+ cmpl $-129, %eax
+ jb 1f
+ negl %eax
+ pushl %eax
+ call __set_errno
+ addl $4, %esp
+ orl $-1, %eax
+1:
+ popl %ecx
+ popl %ebx
+ ret
diff --git a/libc/bionic/dlmalloc.c b/libc/bionic/dlmalloc.c
index 19fbb7521..d30ec30ef 100644
--- a/libc/bionic/dlmalloc.c
+++ b/libc/bionic/dlmalloc.c
@@ -465,6 +465,13 @@ DEFAULT_MMAP_THRESHOLD default: 256K
*/
+#ifdef ANDROID
+#define USE_BUILTIN_FFS 1
+#ifdef __arm__
+#include <machine/cpu-features.h>
+#endif
+#endif /* ANDROID */
+
#ifndef WIN32
#ifdef _WIN32
#define WIN32 1
@@ -2394,6 +2401,17 @@ static size_t traverse_and_check(mstate m);
}
#else /* GNUC */
+#if defined(__ARM_ARCH__) && __ARM_ARCH__ >= 7
+#define compute_bit2idx(X, I) \
+{ \
+ unsigned int J; \
+ __asm__ ("rbit %0, %1\n" \
+ "clz %0, %0" \
+ : "=r" (J) : "r" (X)); \
+ I = (bindex_t) J; \
+}
+
+#else /* ARM_ARCH */
#if USE_BUILTIN_FFS
#define compute_bit2idx(X, I) I = ffs(X)-1
@@ -2409,6 +2427,7 @@ static size_t traverse_and_check(mstate m);
N += K = Y >> (1-0) & 1; Y >>= K;\
I = (bindex_t)(N + Y);\
}
+#endif /* ARM_ARCH */
#endif /* USE_BUILTIN_FFS */
#endif /* GNUC */
diff --git a/libc/bionic/malloc_debug_common.c b/libc/bionic/malloc_debug_common.c
index f05576c4f..a7bd8fc85 100644
--- a/libc/bionic/malloc_debug_common.c
+++ b/libc/bionic/malloc_debug_common.c
@@ -84,7 +84,6 @@ static int hash_entry_compare(const void* arg1, const void* arg2)
//
// 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 (alloc1 < alloc2) {
diff --git a/libc/bionic/pthread.c b/libc/bionic/pthread.c
index 180914e2f..6b0183074 100644
--- a/libc/bionic/pthread.c
+++ b/libc/bionic/pthread.c
@@ -378,6 +378,13 @@ int pthread_create(pthread_t *thread_out, pthread_attr_t const * attr,
return 0;
}
+#ifdef NASTY_PTHREAD_CREATE_HACK
+int _debug_pthread_create(void *debug0, void *debug1, pthread_t *thread,
+ const pthread_attr_t *attr, void *(*start_routine) (void *), void *arg)
+{
+ return pthread_create(thread, attr, start_routine, arg);
+}
+#endif
int pthread_attr_init(pthread_attr_t * attr)
{
diff --git a/libc/include/errno.h b/libc/include/errno.h
index 2b2685af4..cae0e3b78 100644
--- a/libc/include/errno.h
+++ b/libc/include/errno.h
@@ -45,6 +45,7 @@ __BEGIN_DECLS
extern int __set_errno(int error);
/* internal function returning the address of the thread-specific errno */
+__attribute__((const))
extern volatile int* __errno(void);
/* a macro expanding to the errno l-value */
diff --git a/libc/include/mntent.h b/libc/include/mntent.h
index b83da1f2f..d45e69448 100644
--- a/libc/include/mntent.h
+++ b/libc/include/mntent.h
@@ -28,6 +28,7 @@
#ifndef _MNTENT_H_
#define _MNTENT_H_
+#include <sys/cdefs.h>
#include <stdio.h>
#define MNTTYPE_IGNORE "ignore"
diff --git a/libc/include/pthread.h b/libc/include/pthread.h
index 99e747aa5..6407a1991 100644
--- a/libc/include/pthread.h
+++ b/libc/include/pthread.h
@@ -138,10 +138,15 @@ int pthread_getattr_np(pthread_t thid, pthread_attr_t * attr);
int pthread_create(pthread_t *thread, pthread_attr_t const * attr,
void *(*start_routine)(void *), void * arg);
+#ifdef NASTY_PTHREAD_CREATE_HACK
+int _debug_pthread_create(void *debug0, void *debug1, pthread_t *thread,
+ const pthread_attr_t *attr, void *(*start_routine) (void *), void *arg);
+#endif
void pthread_exit(void * retval);
int pthread_join(pthread_t thid, void ** ret_val);
int pthread_detach(pthread_t thid);
+__attribute__((const))
pthread_t pthread_self(void);
int pthread_equal(pthread_t one, pthread_t two);
diff --git a/libc/include/resolv.h b/libc/include/resolv.h
index 4247d68b7..7257d343d 100644
--- a/libc/include/resolv.h
+++ b/libc/include/resolv.h
@@ -34,12 +34,13 @@
#include <sys/socket.h>
#include <stdio.h>
#include <arpa/nameser.h>
+#include <netinet/in.h>
__BEGIN_DECLS
struct res_state;
-extern struct __res_state *__res_state(void);
+extern struct __res_state *__res_state(void) __attribute__((const));
#define _res (*__res_state())
/* Base-64 functions - because some code expects it there */
@@ -49,6 +50,21 @@ extern struct __res_state *__res_state(void);
extern int b64_ntop(u_char const *, size_t, char *, size_t);
extern int b64_pton(char const *, u_char *, size_t);
+/* Set name of default interface */
+extern void _resolv_set_default_iface(const char* ifname);
+
+/* set name servers for an interface */
+extern void _resolv_set_nameservers_for_iface(const char* ifname, char** servers, int numservers);
+
+/* tell resolver of the address of an interface */
+extern void _resolv_set_addr_of_iface(const char* ifname, struct in_addr* addr);
+
+/* flush the cache associated with the default interface */
+extern void _resolv_flush_cache_for_default_iface();
+
+/* flush the cache associated with a certain interface */
+extern void _resolv_flush_cache_for_iface(const char* ifname);
+
__END_DECLS
#endif /* _RESOLV_H_ */
diff --git a/libc/include/sys/_system_properties.h b/libc/include/sys/_system_properties.h
index 42a7f6c0f..95652c322 100644
--- a/libc/include/sys/_system_properties.h
+++ b/libc/include/sys/_system_properties.h
@@ -74,7 +74,8 @@ struct prop_msg
};
#define PROP_MSG_SETPROP 1
-
+#define PROP_MSG_SETPROP_SYNC 2
+
/*
** Rules:
**
diff --git a/libc/include/sys/linux-syscalls.h b/libc/include/sys/linux-syscalls.h
index 9702a7a73..cb214fa30 100644
--- a/libc/include/sys/linux-syscalls.h
+++ b/libc/include/sys/linux-syscalls.h
@@ -105,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_adjtimex (__NR_SYSCALL_BASE + 124)
#define __NR_sigaction (__NR_SYSCALL_BASE + 67)
#define __NR_sigprocmask (__NR_SYSCALL_BASE + 126)
#define __NR_sigsuspend (__NR_SYSCALL_BASE + 72)
@@ -131,6 +132,10 @@
#define __NR_sysinfo (__NR_SYSCALL_BASE + 116)
#define __NR_futex (__NR_SYSCALL_BASE + 240)
#define __NR_poll (__NR_SYSCALL_BASE + 168)
+#define __NR_stime (__NR_SYSCALL_BASE + 25)
+#define __NR_swapon (__NR_SYSCALL_BASE + 87)
+#define __NR_swapoff (__NR_SYSCALL_BASE + 115)
+#define __NR_getsid (__NR_SYSCALL_BASE + 147)
#ifdef __arm__
#define __NR_exit_group (__NR_SYSCALL_BASE + 248)
diff --git a/libc/include/sys/linux-unistd.h b/libc/include/sys/linux-unistd.h
index 23853dac1..2c11db39e 100644
--- a/libc/include/sys/linux-unistd.h
+++ b/libc/include/sys/linux-unistd.h
@@ -137,6 +137,7 @@ int __timer_gettime (timer_t, struct itimerspec*);
int __timer_getoverrun (timer_t);
int __timer_delete (timer_t);
int utimes (const char*, const struct timeval tvp[2]);
+int adjtimex (struct timex *);
int sigaction (int, const struct sigaction *, struct sigaction *);
int sigprocmask (int, const sigset_t *, sigset_t *);
int __sigsuspend (int unused1, int unused2, unsigned mask);
@@ -205,6 +206,10 @@ 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 stime (time_t *);
+int swapon (const char *, int);
+int swapoff (const char *);
+pid_t getsid (pid_t pid);
#ifdef __cplusplus
}
#endif
diff --git a/libc/kernel/common/linux/akm8975.h b/libc/kernel/common/linux/akm8975.h
new file mode 100644
index 000000000..3e83c8d2f
--- /dev/null
+++ b/libc/kernel/common/linux/akm8975.h
@@ -0,0 +1,92 @@
+/*
+ * Definitions for akm8975 compass chip.
+ */
+#ifndef AKM8975_H
+#define AKM8975_H
+
+#include <linux/ioctl.h>
+
+#define AKM8975_I2C_NAME "akm8975"
+
+/* Compass device dependent definition */
+
+/*! \name AK8975 register address
+\anchor AK8975_REG
+Defines a register address of the AK8975.*/
+#define AK8975_REG_WIA 0x00
+#define AK8975_REG_INFO 0x01
+#define AK8975_REG_ST1 0x02
+#define AK8975_REG_HXL 0x03
+#define AK8975_REG_HXH 0x04
+#define AK8975_REG_HYL 0x05
+#define AK8975_REG_HYH 0x06
+#define AK8975_REG_HZL 0x07
+#define AK8975_REG_HZH 0x08
+#define AK8975_REG_ST2 0x09
+#define AK8975_REG_CNTL 0x0A
+#define AK8975_REG_RSV 0x0B
+#define AK8975_REG_ASTC 0x0C
+#define AK8975_REG_TS1 0x0D
+#define AK8975_REG_TS2 0x0E
+#define AK8975_REG_I2CDIS 0x0F
+
+
+/*! \name AK8975 fuse-rom address
+\anchor AK8975_FUSE
+Defines a read-only address of the fuse ROM of the AK8975.*/
+
+#define AK8975_FUSE_ASAX 0x10
+#define AK8975_FUSE_ASAY 0x11
+#define AK8975_FUSE_ASAZ 0x12
+
+/*! \name AK8975 register value
+\anchor AK8975_CNTL
+Defines a value to be set in the Control Registers (\c CNTL) of AK8975. */
+
+#define AK8975_CNTL_SNG_MEASURE 0x01
+#define AK8975_CNTL_CONT_MEASURE 0x02
+#define AK8975_CNTL_TRIG_MEASURE 0x04
+#define AK8975_CNTL_SELF_TEST 0x08
+#define AK8975_CNTL_FUSE_ACCESS 0x0F
+#define AK8975_CNTL_POWER_DOWN 0x00
+
+#define RBUFF_SIZE_8975 8 /* Rx buffer size */
+
+#define AKMIO 0xA1
+
+/* IOCTLs for AKM library */
+#define ECS_IOCTL_WRITE _IOW(AKMIO, 0x01, char[5])
+#define ECS_IOCTL_READ _IOWR(AKMIO, 0x02, char[5])
+#define ECS_IOCTL_SET_MODE _IOW(AKMIO, 0x0F, short)
+#define ECS_IOCTL_GETDATA _IOR(AKMIO, 0x05, char[RBUFF_SIZE_8975+1])
+#define ECS_IOCTL_SET_YPR _IOW(AKMIO, 0x06, short[12])
+#define ECS_IOCTL_GET_OPEN_STATUS _IOR(AKMIO, 0x07, int)
+#define ECS_IOCTL_GET_CLOSE_STATUS _IOR(AKMIO, 0x08, int)
+#define ECS_IOCTL_GET_DELAY _IOR(AKMIO, 0x30, short)
+#define ECS_IOCTL_GET_MATRIX _IOR(AKMIO, 0x0E, short [4][3][3])
+
+/* IOCTLs for APPs */
+#define ECS_IOCTL_APP_SET_MODE _IOW(AKMIO, 0x10, short)
+#define ECS_IOCTL_APP_SET_MFLAG _IOW(AKMIO, 0x11, short)
+#define ECS_IOCTL_APP_GET_MFLAG _IOW(AKMIO, 0x12, short)
+#define ECS_IOCTL_APP_SET_AFLAG _IOW(AKMIO, 0x13, short)
+#define ECS_IOCTL_APP_GET_AFLAG _IOR(AKMIO, 0x14, short)
+#define ECS_IOCTL_APP_SET_TFLAG _IOR(AKMIO, 0x15, short)
+#define ECS_IOCTL_APP_GET_TFLAG _IOR(AKMIO, 0x16, short)
+#define ECS_IOCTL_APP_RESET_PEDOMETER _IO(AKMIO, 0x17)
+#define ECS_IOCTL_APP_SET_DELAY _IOW(AKMIO, 0x18, short)
+#define ECS_IOCTL_APP_GET_DELAY ECS_IOCTL_GET_DELAY
+
+/* Set raw magnetic vector flag */
+#define ECS_IOCTL_APP_SET_MVFLAG _IOW(AKMIO, 0x19, short)
+
+/* Get raw magnetic vector flag */
+#define ECS_IOCTL_APP_GET_MVFLAG _IOR(AKMIO, 0x1A, short)
+
+struct akm8975_platform_data {
+ short layouts[4][3][3];
+ short irq_trigger;
+};
+
+#endif
+
diff --git a/libc/kernel/common/linux/android_pmem.h b/libc/kernel/common/linux/android_pmem.h
index be0b34221..ba8522774 100644
--- a/libc/kernel/common/linux/android_pmem.h
+++ b/libc/kernel/common/linux/android_pmem.h
@@ -12,6 +12,15 @@
#ifndef _ANDROID_PMEM_H_
#define _ANDROID_PMEM_H_
+#include <linux/fs.h>
+
+#define PMEM_KERNEL_TEST_MAGIC 0xc0
+#define PMEM_KERNEL_TEST_NOMINAL_TEST_IOCTL _IO(PMEM_KERNEL_TEST_MAGIC, 1)
+#define PMEM_KERNEL_TEST_ADVERSARIAL_TEST_IOCTL _IO(PMEM_KERNEL_TEST_MAGIC, 2)
+#define PMEM_KERNEL_TEST_HUGE_ALLOCATION_TEST_IOCTL _IO(PMEM_KERNEL_TEST_MAGIC, 3)
+#define PMEM_KERNEL_TEST_FREE_UNALLOCATED_TEST_IOCTL _IO(PMEM_KERNEL_TEST_MAGIC, 4)
+#define PMEM_KERNEL_TEST_LARGE_REGION_NUMBER_TEST_IOCTL _IO(PMEM_KERNEL_TEST_MAGIC, 5)
+
#define PMEM_IOCTL_MAGIC 'p'
#define PMEM_GET_PHYS _IOW(PMEM_IOCTL_MAGIC, 1, unsigned int)
#define PMEM_MAP _IOW(PMEM_IOCTL_MAGIC, 2, unsigned int)
@@ -23,27 +32,34 @@
#define PMEM_CONNECT _IOW(PMEM_IOCTL_MAGIC, 6, unsigned int)
#define PMEM_GET_TOTAL_SIZE _IOW(PMEM_IOCTL_MAGIC, 7, unsigned int)
-#define PMEM_CACHE_FLUSH _IOW(PMEM_IOCTL_MAGIC, 8, unsigned int)
-struct android_pmem_platform_data
-{
- const char* name;
+#define PMEM_CACHE_FLUSH _IOW(PMEM_IOCTL_MAGIC, 8, unsigned int)
- unsigned long start;
+#define PMEM_CLEAN_INV_CACHES _IOW(PMEM_IOCTL_MAGIC, 11, unsigned int)
+#define PMEM_CLEAN_CACHES _IOW(PMEM_IOCTL_MAGIC, 12, unsigned int)
+#define PMEM_INV_CACHES _IOW(PMEM_IOCTL_MAGIC, 13, unsigned int)
- unsigned long size;
-
- unsigned no_allocator;
+#define PMEM_GET_FREE_SPACE _IOW(PMEM_IOCTL_MAGIC, 14, unsigned int)
+#define PMEM_ALLOCATE_ALIGNED _IOW(PMEM_IOCTL_MAGIC, 15, unsigned int)
+struct pmem_region {
+ unsigned long offset;
+ unsigned long len;
+};
- unsigned cached;
+struct pmem_addr {
+ unsigned long vaddr;
+ unsigned long offset;
+ unsigned long length;
+};
- unsigned buffered;
+struct pmem_freespace {
+ unsigned long total;
+ unsigned long largest;
};
-struct pmem_region {
- unsigned long offset;
- unsigned long len;
+struct pmem_allocation {
+ unsigned long size;
+ unsigned int align;
};
#endif
-
diff --git a/libc/kernel/common/linux/msm_audio_7X30.h b/libc/kernel/common/linux/msm_audio_7X30.h
new file mode 100644
index 000000000..6185a6cec
--- /dev/null
+++ b/libc/kernel/common/linux/msm_audio_7X30.h
@@ -0,0 +1,329 @@
+/* include/linux/msm_audio.h
+ *
+ * Copyright (C) 2008 Google, Inc.
+ * Copyright (c) 2009, Code Aurora Forum. All rights reserved.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#ifndef __LINUX_MSM_AUDIO_H
+#define __LINUX_MSM_AUDIO_H
+
+#include <linux/types.h>
+#include <linux/ioctl.h>
+#include <asm/sizes.h>
+
+/* PCM Audio */
+
+#define AUDIO_IOCTL_MAGIC 'a'
+
+#define AUDIO_START _IOW(AUDIO_IOCTL_MAGIC, 0, unsigned)
+#define AUDIO_STOP _IOW(AUDIO_IOCTL_MAGIC, 1, unsigned)
+#define AUDIO_FLUSH _IOW(AUDIO_IOCTL_MAGIC, 2, unsigned)
+#define AUDIO_GET_CONFIG _IOR(AUDIO_IOCTL_MAGIC, 3, unsigned)
+#define AUDIO_SET_CONFIG _IOW(AUDIO_IOCTL_MAGIC, 4, unsigned)
+#define AUDIO_GET_STATS _IOR(AUDIO_IOCTL_MAGIC, 5, unsigned)
+#define AUDIO_ENABLE_AUDPP _IOW(AUDIO_IOCTL_MAGIC, 6, unsigned)
+#define AUDIO_SET_ADRC _IOW(AUDIO_IOCTL_MAGIC, 7, unsigned)
+#define AUDIO_SET_EQ _IOW(AUDIO_IOCTL_MAGIC, 8, unsigned)
+#define AUDIO_SET_RX_IIR _IOW(AUDIO_IOCTL_MAGIC, 9, unsigned)
+#define AUDIO_SET_VOLUME _IOW(AUDIO_IOCTL_MAGIC, 10, unsigned)
+#define AUDIO_PAUSE _IOW(AUDIO_IOCTL_MAGIC, 11, unsigned)
+#define AUDIO_PLAY_DTMF _IOW(AUDIO_IOCTL_MAGIC, 12, unsigned)
+#define AUDIO_GET_EVENT _IOR(AUDIO_IOCTL_MAGIC, 13, unsigned)
+#define AUDIO_ABORT_GET_EVENT _IOW(AUDIO_IOCTL_MAGIC, 14, unsigned)
+#define AUDIO_REGISTER_PMEM _IOW(AUDIO_IOCTL_MAGIC, 15, unsigned)
+#define AUDIO_DEREGISTER_PMEM _IOW(AUDIO_IOCTL_MAGIC, 16, unsigned)
+#define AUDIO_ASYNC_WRITE _IOW(AUDIO_IOCTL_MAGIC, 17, unsigned)
+#define AUDIO_ASYNC_READ _IOW(AUDIO_IOCTL_MAGIC, 18, unsigned)
+#define AUDIO_SET_INCALL _IOW(AUDIO_IOCTL_MAGIC, 19, struct msm_voicerec_mode)
+#define AUDIO_GET_NUM_SND_DEVICE _IOR(AUDIO_IOCTL_MAGIC, 20, unsigned)
+#define AUDIO_GET_SND_DEVICES _IOWR(AUDIO_IOCTL_MAGIC, 21, \
+ struct msm_snd_device_list)
+#define AUDIO_ENABLE_SND_DEVICE _IOW(AUDIO_IOCTL_MAGIC, 22, unsigned)
+#define AUDIO_DISABLE_SND_DEVICE _IOW(AUDIO_IOCTL_MAGIC, 23, unsigned)
+#define AUDIO_ROUTE_STREAM _IOW(AUDIO_IOCTL_MAGIC, 24, \
+ struct msm_audio_route_config)
+#define AUDIO_GET_PCM_CONFIG _IOR(AUDIO_IOCTL_MAGIC, 30, unsigned)
+#define AUDIO_SET_PCM_CONFIG _IOW(AUDIO_IOCTL_MAGIC, 31, unsigned)
+#define AUDIO_SWITCH_DEVICE _IOW(AUDIO_IOCTL_MAGIC, 32, unsigned)
+#define AUDIO_SET_MUTE _IOW(AUDIO_IOCTL_MAGIC, 33, unsigned)
+#define AUDIO_UPDATE_ACDB _IOW(AUDIO_IOCTL_MAGIC, 34, unsigned)
+#define AUDIO_START_VOICE _IOW(AUDIO_IOCTL_MAGIC, 35, unsigned)
+#define AUDIO_STOP_VOICE _IOW(AUDIO_IOCTL_MAGIC, 36, unsigned)
+#define AUDIO_REINIT_ACDB _IOW(AUDIO_IOCTL_MAGIC, 39, unsigned)
+#define AUDIO_OUTPORT_FLUSH _IOW(AUDIO_IOCTL_MAGIC, 40, unsigned short)
+#define AUDIO_SET_ERR_THRESHOLD_VALUE _IOW(AUDIO_IOCTL_MAGIC, 41, \
+ unsigned short)
+#define AUDIO_GET_BITSTREAM_ERROR_INFO _IOR(AUDIO_IOCTL_MAGIC, 42, \
+ struct msm_audio_bitstream_error_info)
+/* Qualcomm extensions */
+#define AUDIO_SET_STREAM_CONFIG _IOW(AUDIO_IOCTL_MAGIC, 80, \
+ struct msm_audio_stream_config)
+#define AUDIO_GET_STREAM_CONFIG _IOR(AUDIO_IOCTL_MAGIC, 81, \
+ struct msm_audio_stream_config)
+#define AUDIO_GET_SESSION_ID _IOR(AUDIO_IOCTL_MAGIC, 82, unsigned short)
+#define AUDIO_GET_STREAM_INFO _IOR(AUDIO_IOCTL_MAGIC, 83, \
+ struct msm_audio_bitstream_info)
+#define AUDIO_SET_PAN _IOW(AUDIO_IOCTL_MAGIC, 84, unsigned)
+#define AUDIO_SET_QCONCERT_PLUS _IOW(AUDIO_IOCTL_MAGIC, 85, unsigned)
+#define AUDIO_SET_MBADRC _IOW(AUDIO_IOCTL_MAGIC, 86, unsigned)
+#define AUDIO_SET_VOLUME_PATH _IOW(AUDIO_IOCTL_MAGIC, 87, \
+ struct msm_vol_info)
+#define AUDIO_SET_MAX_VOL_ALL _IOW(AUDIO_IOCTL_MAGIC, 88, unsigned)
+#define AUDIO_ENABLE_AUDPRE _IOW(AUDIO_IOCTL_MAGIC, 89, unsigned)
+#define AUDIO_SET_AGC _IOW(AUDIO_IOCTL_MAGIC, 90, unsigned)
+#define AUDIO_SET_NS _IOW(AUDIO_IOCTL_MAGIC, 91, unsigned)
+#define AUDIO_SET_TX_IIR _IOW(AUDIO_IOCTL_MAGIC, 92, unsigned)
+
+#define AUDIO_MAX_COMMON_IOCTL_NUM 100
+
+
+#define HANDSET_MIC 0x01
+#define HANDSET_SPKR 0x02
+#define HEADSET_MIC 0x03
+#define HEADSET_SPKR_MONO 0x04
+#define HEADSET_SPKR_STEREO 0x05
+#define SPKR_PHONE_MIC 0x06
+#define SPKR_PHONE_MONO 0x07
+#define SPKR_PHONE_STEREO 0x08
+#define BT_SCO_MIC 0x09
+#define BT_SCO_SPKR 0x0A
+#define BT_A2DP_SPKR 0x0B
+#define TTY_HEADSET_MIC 0x0C
+#define TTY_HEADSET_SPKR 0x0D
+
+/* Default devices are not supported in a */
+/* device switching context. Only supported */
+/* for stream devices. */
+/* DO NOT USE */
+#define DEFAULT_TX 0x0E
+#define DEFAULT_RX 0x0F
+
+#define BT_A2DP_TX 0x10
+
+#define HEADSET_MONO_PLUS_SPKR_MONO_RX 0x11
+#define HEADSET_MONO_PLUS_SPKR_STEREO_RX 0x12
+#define HEADSET_STEREO_PLUS_SPKR_MONO_RX 0x13
+#define HEADSET_STEREO_PLUS_SPKR_STEREO_RX 0x14
+
+#define I2S_RX 0x20
+#define I2S_TX 0x21
+
+#define ADRC_ENABLE 0x0001
+#define EQ_ENABLE 0x0002
+#define IIR_ENABLE 0x0004
+#define QCONCERT_PLUS_ENABLE 0x0008
+#define MBADRC_ENABLE 0x0010
+
+#define AGC_ENABLE 0x0001
+#define NS_ENABLE 0x0002
+#define TX_IIR_ENABLE 0x0004
+
+#define VOC_REC_UPLINK 0x00
+#define VOC_REC_DOWNLINK 0x01
+#define VOC_REC_BOTH 0x02
+
+struct msm_audio_config {
+ uint32_t buffer_size;
+ uint32_t buffer_count;
+ uint32_t channel_count;
+ uint32_t sample_rate;
+ uint32_t type;
+ uint32_t meta_field;
+ uint32_t bits;
+ uint32_t unused[3];
+};
+
+struct msm_audio_stream_config {
+ uint32_t buffer_size;
+ uint32_t buffer_count;
+};
+
+struct msm_audio_stats {
+ uint32_t byte_count;
+ uint32_t sample_count;
+ uint32_t unused[2];
+};
+
+struct msm_audio_pmem_info {
+ int fd;
+ void *vaddr;
+};
+
+struct msm_audio_aio_buf {
+ void *buf_addr;
+ uint32_t buf_len;
+ uint32_t data_len;
+ void *private_data;
+ unsigned short mfield_sz; /*only useful for data has meta field */
+};
+
+/* Audio routing */
+
+#define SND_IOCTL_MAGIC 's'
+
+#define SND_MUTE_UNMUTED 0
+#define SND_MUTE_MUTED 1
+
+struct msm_mute_info {
+ uint32_t mute;
+ uint32_t path;
+};
+
+struct msm_vol_info {
+ uint32_t vol;
+ uint32_t path;
+};
+
+struct msm_voicerec_mode {
+ uint32_t rec_mode;
+};
+
+struct msm_snd_device_config {
+ uint32_t device;
+ uint32_t ear_mute;
+ uint32_t mic_mute;
+};
+
+#define SND_SET_DEVICE _IOW(SND_IOCTL_MAGIC, 2, struct msm_device_config *)
+
+#define SND_METHOD_VOICE 0
+
+struct msm_snd_volume_config {
+ uint32_t device;
+ uint32_t method;
+ uint32_t volume;
+};
+
+#define SND_SET_VOLUME _IOW(SND_IOCTL_MAGIC, 3, struct msm_snd_volume_config *)
+
+/* Returns the number of SND endpoints supported. */
+
+#define SND_GET_NUM_ENDPOINTS _IOR(SND_IOCTL_MAGIC, 4, unsigned *)
+
+struct msm_snd_endpoint {
+ int id; /* input and output */
+ char name[64]; /* output only */
+};
+
+/* Takes an index between 0 and one less than the number returned by
+ * SND_GET_NUM_ENDPOINTS, and returns the SND index and name of a
+ * SND endpoint. On input, the .id field contains the number of the
+ * endpoint, and on exit it contains the SND index, while .name contains
+ * the description of the endpoint.
+ */
+
+#define SND_GET_ENDPOINT _IOWR(SND_IOCTL_MAGIC, 5, struct msm_snd_endpoint *)
+
+
+#define SND_AVC_CTL _IOW(SND_IOCTL_MAGIC, 6, unsigned *)
+#define SND_AGC_CTL _IOW(SND_IOCTL_MAGIC, 7, unsigned *)
+
+struct msm_audio_pcm_config {
+ uint32_t pcm_feedback; /* 0 - disable > 0 - enable */
+ uint32_t buffer_count; /* Number of buffers to allocate */
+ uint32_t buffer_size; /* Size of buffer for capturing of
+ PCM samples */
+};
+
+#define AUDIO_EVENT_SUSPEND 0
+#define AUDIO_EVENT_RESUME 1
+#define AUDIO_EVENT_WRITE_DONE 2
+#define AUDIO_EVENT_READ_DONE 3
+#define AUDIO_EVENT_STREAM_INFO 4
+#define AUDIO_EVENT_BITSTREAM_ERROR_INFO 5
+
+#define AUDIO_CODEC_TYPE_MP3 0
+#define AUDIO_CODEC_TYPE_AAC 1
+
+struct msm_audio_bitstream_info {
+ uint32_t codec_type;
+ uint32_t chan_info;
+ uint32_t sample_rate;
+ uint32_t bit_stream_info;
+ uint32_t bit_rate;
+ uint32_t unused[3];
+};
+
+struct msm_audio_bitstream_error_info {
+ uint32_t dec_id;
+ uint32_t err_msg_indicator;
+ uint32_t err_type;
+};
+
+union msm_audio_event_payload {
+ struct msm_audio_aio_buf aio_buf;
+ struct msm_audio_bitstream_info stream_info;
+ struct msm_audio_bitstream_error_info error_info;
+ int reserved;
+};
+
+struct msm_audio_event {
+ int event_type;
+ int timeout_ms;
+ union msm_audio_event_payload event_payload;
+};
+
+#define MSM_SNDDEV_CAP_RX 0x1
+#define MSM_SNDDEV_CAP_TX 0x2
+#define MSM_SNDDEV_CAP_VOICE 0x4
+
+struct msm_snd_device_info {
+ uint32_t dev_id;
+ uint32_t dev_cap; /* bitmask describe capability of device */
+ char dev_name[64];
+};
+
+struct msm_snd_device_list {
+ uint32_t num_dev; /* Indicate number of device info to be retrieved */
+ struct msm_snd_device_info *list;
+};
+
+struct msm_dtmf_config {
+ uint16_t path;
+ uint16_t dtmf_hi;
+ uint16_t dtmf_low;
+ uint16_t duration;
+ uint16_t tx_gain;
+ uint16_t rx_gain;
+ uint16_t mixing;
+};
+
+#define AUDIO_ROUTE_STREAM_VOICE_RX 0
+#define AUDIO_ROUTE_STREAM_VOICE_TX 1
+#define AUDIO_ROUTE_STREAM_PLAYBACK 2
+#define AUDIO_ROUTE_STREAM_REC 3
+
+struct msm_audio_route_config {
+ uint32_t stream_type;
+ uint32_t stream_id;
+ uint32_t dev_id;
+};
+
+#define AUDIO_MAX_EQ_BANDS 12
+
+struct msm_audio_eq_band {
+ uint16_t band_idx; /* The band index, 0 .. 11 */
+ uint32_t filter_type; /* Filter band type */
+ uint32_t center_freq_hz; /* Filter band center frequency */
+ uint32_t filter_gain; /* Filter band initial gain (dB) */
+ /* Range is +12 dB to -12 dB with 1dB increments. */
+ uint32_t q_factor;
+} __attribute__ ((packed));
+
+struct msm_audio_eq_stream_config {
+ uint32_t enable; /* Number of consequtive bands specified */
+ uint32_t num_bands;
+ struct msm_audio_eq_band eq_bands[AUDIO_MAX_EQ_BANDS];
+} __attribute__ ((packed));
+
+#endif
diff --git a/libc/kernel/common/linux/msm_audio_aac.h b/libc/kernel/common/linux/msm_audio_aac.h
new file mode 100644
index 000000000..d9d300f30
--- /dev/null
+++ b/libc/kernel/common/linux/msm_audio_aac.h
@@ -0,0 +1,78 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ *** 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_AUDIO_AAC_H
+#define __MSM_AUDIO_AAC_H
+
+#include <linux/msm_audio.h>
+
+#define AUDIO_SET_AAC_CONFIG _IOW(AUDIO_IOCTL_MAGIC, (AUDIO_MAX_COMMON_IOCTL_NUM+0), unsigned)
+#define AUDIO_GET_AAC_CONFIG _IOR(AUDIO_IOCTL_MAGIC, (AUDIO_MAX_COMMON_IOCTL_NUM+1), unsigned)
+
+#define AUDIO_SET_AAC_ENC_CONFIG _IOW(AUDIO_IOCTL_MAGIC, (AUDIO_MAX_COMMON_IOCTL_NUM+3), struct msm_audio_aac_enc_config)
+
+#define AUDIO_GET_AAC_ENC_CONFIG _IOR(AUDIO_IOCTL_MAGIC, (AUDIO_MAX_COMMON_IOCTL_NUM+4), struct msm_audio_aac_enc_config)
+
+#define AUDIO_AAC_FORMAT_ADTS -1
+#define AUDIO_AAC_FORMAT_RAW 0x0000
+#define AUDIO_AAC_FORMAT_PSUEDO_RAW 0x0001
+#define AUDIO_AAC_FORMAT_LOAS 0x0002
+
+#define AUDIO_AAC_OBJECT_LC 0x0002
+#define AUDIO_AAC_OBJECT_LTP 0x0004
+#define AUDIO_AAC_OBJECT_ERLC 0x0011
+#define AUDIO_AAC_OBJECT_BSAC 0x0016
+
+#define AUDIO_AAC_SEC_DATA_RES_ON 0x0001
+#define AUDIO_AAC_SEC_DATA_RES_OFF 0x0000
+
+#define AUDIO_AAC_SCA_DATA_RES_ON 0x0001
+#define AUDIO_AAC_SCA_DATA_RES_OFF 0x0000
+
+#define AUDIO_AAC_SPEC_DATA_RES_ON 0x0001
+#define AUDIO_AAC_SPEC_DATA_RES_OFF 0x0000
+
+#define AUDIO_AAC_SBR_ON_FLAG_ON 0x0001
+#define AUDIO_AAC_SBR_ON_FLAG_OFF 0x0000
+
+#define AUDIO_AAC_SBR_PS_ON_FLAG_ON 0x0001
+#define AUDIO_AAC_SBR_PS_ON_FLAG_OFF 0x0000
+
+#define AUDIO_AAC_DUAL_MONO_PL_PR 0
+
+#define AUDIO_AAC_DUAL_MONO_SL_SR 1
+
+#define AUDIO_AAC_DUAL_MONO_SL_PR 2
+
+#define AUDIO_AAC_DUAL_MONO_PL_SR 3
+
+struct msm_audio_aac_config {
+ signed short format;
+ unsigned short audio_object;
+ unsigned short ep_config;
+ unsigned short aac_section_data_resilience_flag;
+ unsigned short aac_scalefactor_data_resilience_flag;
+ unsigned short aac_spectral_data_resilience_flag;
+ unsigned short sbr_on_flag;
+ unsigned short sbr_ps_on_flag;
+ unsigned short dual_mono_mode;
+ unsigned short channel_configuration;
+};
+
+struct msm_audio_aac_enc_config {
+ uint32_t channels;
+ uint32_t sample_rate;
+ uint32_t bit_rate;
+ uint32_t stream_format;
+};
+
+#endif
+
diff --git a/libc/kernel/common/linux/msm_mdp.h b/libc/kernel/common/linux/msm_mdp.h
index c35521880..e8e815af8 100644
--- a/libc/kernel/common/linux/msm_mdp.h
+++ b/libc/kernel/common/linux/msm_mdp.h
@@ -1,86 +1,143 @@
-/****************************************************************************
- ****************************************************************************
- ***
- *** 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.
- ***
- ****************************************************************************
- ****************************************************************************/
+/* include/linux/msm_mdp.h
+ *
+ * Copyright (C) 2007 Google Incorporated
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
#ifndef _MSM_MDP_H_
#define _MSM_MDP_H_
#include <linux/types.h>
#define MSMFB_IOCTL_MAGIC 'm'
-#define MSMFB_GRP_DISP _IOW(MSMFB_IOCTL_MAGIC, 1, unsigned int)
-#define MSMFB_BLIT _IOW(MSMFB_IOCTL_MAGIC, 2, unsigned int)
+#define MSMFB_GRP_DISP _IOW(MSMFB_IOCTL_MAGIC, 1, unsigned int)
+#define MSMFB_BLIT _IOW(MSMFB_IOCTL_MAGIC, 2, unsigned int)
+#ifdef CONFIG_MSM_MDP40
+#define MSMFB_OVERLAY_SET _IOWR(MSMFB_IOCTL_MAGIC, 135, \
+ struct mdp_overlay)
+#define MSMFB_OVERLAY_UNSET _IOW(MSMFB_IOCTL_MAGIC, 136, unsigned int)
+#define MSMFB_OVERLAY_PLAY _IOW(MSMFB_IOCTL_MAGIC, 137, \
+ struct msmfb_overlay_data)
+#define MSMFB_OVERLAY_GET _IOR(MSMFB_IOCTL_MAGIC, 140, \
+ struct mdp_overlay)
+#endif
enum {
- MDP_RGB_565,
- MDP_XRGB_8888,
- MDP_Y_CBCR_H2V2,
- MDP_ARGB_8888,
- MDP_RGB_888,
- MDP_Y_CRCB_H2V2,
- MDP_YCRYCB_H2V1,
- MDP_Y_CRCB_H2V1,
- MDP_Y_CBCR_H2V1,
- MDP_RGBA_8888,
- MDP_BGRA_8888,
- MDP_RGBX_8888,
- MDP_IMGTYPE_LIMIT
+ MDP_RGB_565, // RGB 565 planer
+ MDP_XRGB_8888, // RGB 888 padded
+ MDP_Y_CBCR_H2V2, // Y and CbCr, pseudo planer w/ Cb is in MSB
+ MDP_ARGB_8888, // ARGB 888
+ MDP_RGB_888, // RGB 888 planer
+ MDP_Y_CRCB_H2V2, // Y and CrCb, pseudo planer w/ Cr is in MSB
+ MDP_YCRYCB_H2V1, // YCrYCb interleave
+ MDP_Y_CRCB_H2V1, // Y and CrCb, pseduo planer w/ Cr is in MSB
+ MDP_Y_CBCR_H2V1, // Y and CrCb, pseduo planer w/ Cr is in MSB
+ MDP_RGBA_8888, // ARGB 888
+ MDP_BGRA_8888, // ARGB 888
+ MDP_RGBX_8888, // RGBX 888
+#ifdef CONFIG_MSM_MDP40
+ MDP_Y_CRCB_H2V2_TILE, /* Y and CrCb, pseudo planer tile */
+ MDP_Y_CBCR_H2V2_TILE, /* Y and CbCr, pseudo planer tile */
+#endif
+ MDP_IMGTYPE_LIMIT, // Non valid image type after this enum
+ MDP_IMGTYPE2_START = 0x10000,
+ MDP_BGR_565 = MDP_IMGTYPE2_START, /* BGR 565 planer */
+ MDP_FB_FORMAT, /* framebuffer format */
+ MDP_IMGTYPE_LIMIT2 /* Non valid image type after this enum */
};
enum {
- PMEM_IMG,
- FB_IMG,
+ PMEM_IMG,
+ FB_IMG,
};
+/* flag values */
#define MDP_ROT_NOP 0
#define MDP_FLIP_LR 0x1
#define MDP_FLIP_UD 0x2
#define MDP_ROT_90 0x4
#define MDP_ROT_180 (MDP_FLIP_UD|MDP_FLIP_LR)
#define MDP_ROT_270 (MDP_ROT_90|MDP_FLIP_UD|MDP_FLIP_LR)
+#define MDP_ROT_MASK 0x7
#define MDP_DITHER 0x8
#define MDP_BLUR 0x10
#define MDP_BLEND_FG_PREMULT 0x20000
-
+#define MDP_DEINTERLACE 0x80000000
+#define MDP_SHARPENING 0x40000000
#define MDP_TRANSP_NOP 0xffffffff
#define MDP_ALPHA_NOP 0xff
struct mdp_rect {
- uint32_t x;
- uint32_t y;
- uint32_t w;
- uint32_t h;
+ uint32_t x;
+ uint32_t y;
+ uint32_t w;
+ uint32_t h;
};
struct mdp_img {
- uint32_t width;
- uint32_t height;
- uint32_t format;
- uint32_t offset;
- int memory_id;
+ uint32_t width;
+ uint32_t height;
+ uint32_t format;
+ uint32_t offset;
+ int memory_id; /* the file descriptor */
};
struct mdp_blit_req {
- struct mdp_img src;
- struct mdp_img dst;
- struct mdp_rect src_rect;
- struct mdp_rect dst_rect;
- uint32_t alpha;
- uint32_t transp_mask;
- uint32_t flags;
+ struct mdp_img src;
+ struct mdp_img dst;
+ struct mdp_rect src_rect;
+ struct mdp_rect dst_rect;
+ uint32_t alpha;
+ uint32_t transp_mask;
+ uint32_t flags;
+#ifdef CONFIG_MSM_MDP40
+ int sharpening_strength; /* -127 <--> 127, default 64 */
+#endif
};
struct mdp_blit_req_list {
- uint32_t count;
- struct mdp_blit_req req[];
+ uint32_t count;
+ struct mdp_blit_req req[];
};
-#endif
+#ifdef CONFIG_MSM_MDP40
+struct msmfb_data {
+ uint32_t offset;
+ int memory_id;
+ int id;
+};
+
+#define MSMFB_NEW_REQUEST -1
+struct msmfb_overlay_data {
+ uint32_t id;
+ struct msmfb_data data;
+};
+
+struct msmfb_img {
+ uint32_t width;
+ uint32_t height;
+ uint32_t format;
+};
+
+struct mdp_overlay {
+ struct msmfb_img src;
+ struct mdp_rect src_rect;
+ struct mdp_rect dst_rect;
+ uint32_t z_order; /* stage number */
+ uint32_t is_fg; /* control alpha & transp */
+ uint32_t alpha;
+ uint32_t transp_mask;
+ uint32_t flags;
+ uint32_t id;
+ uint32_t user_data[8];
+};
+#endif
+#endif //_MSM_MDP_H_
diff --git a/libc/kernel/common/linux/msm_q6vdec.h b/libc/kernel/common/linux/msm_q6vdec.h
index 0182bfbf7..c82e12ff4 100644
--- a/libc/kernel/common/linux/msm_q6vdec.h
+++ b/libc/kernel/common/linux/msm_q6vdec.h
@@ -26,6 +26,7 @@
#define VDEC_IOCTL_CLOSE _IO(VDEC_IOCTL_MAGIC, 8)
#define VDEC_IOCTL_FREEBUFFERS _IOW(VDEC_IOCTL_MAGIC, 9, struct vdec_buf_info)
#define VDEC_IOCTL_GETDECATTRIBUTES _IOR(VDEC_IOCTL_MAGIC, 10, struct vdec_dec_attributes)
+#define VDEC_IOCTL_GETVERSION _IOR(VDEC_IOCTL_MAGIC, 11, struct vdec_version)
enum {
VDEC_FRAME_DECODE_OK,
@@ -99,7 +100,7 @@ struct vdec_config {
u32 h264_nal_len_size;
u32 postproc_flag;
u32 fruc_enable;
- u32 reserved;
+ u32 color_format;
};
struct vdec_vc1_panscan_regions {
@@ -208,5 +209,10 @@ struct vdec_dec_attributes {
struct vdec_buf_desc dec_req2;
};
+struct vdec_version {
+ u32 major;
+ u32 minor;
+};
+
#endif
diff --git a/libc/kernel/common/linux/msm_rotator.h b/libc/kernel/common/linux/msm_rotator.h
new file mode 100755
index 000000000..8246c89c5
--- /dev/null
+++ b/libc/kernel/common/linux/msm_rotator.h
@@ -0,0 +1,61 @@
+/* Copyright (c) 2009, Code Aurora Forum. 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.
+ * * Neither the name of Code Aurora nor
+ * the names of its contributors may be used to endorse or promote
+ * products derived from this software without specific prior written
+ * permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NON-INFRINGEMENT 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 __MSM_ROTATOR_H__
+
+#include <linux/types.h>
+#include <linux/msm_mdp.h>
+
+#define MSM_ROTATOR_IOCTL_MAGIC 'R'
+
+#define MSM_ROTATOR_IOCTL_START \
+ _IOWR(MSM_ROTATOR_IOCTL_MAGIC, 1, struct msm_rotator_img_info)
+#define MSM_ROTATOR_IOCTL_ROTATE \
+ _IOW(MSM_ROTATOR_IOCTL_MAGIC, 2, struct msm_rotator_data_info)
+#define MSM_ROTATOR_IOCTL_FINISH \
+ _IOW(MSM_ROTATOR_IOCTL_MAGIC, 3, int)
+
+struct msm_rotator_img_info {
+ unsigned int session_id;
+ struct msmfb_img src;
+ struct msmfb_img dst;
+ struct mdp_rect src_rect;
+ unsigned int dst_x;
+ unsigned int dst_y;
+ unsigned char rotations;
+ int enable;
+};
+
+struct msm_rotator_data_info {
+ int session_id;
+ struct msmfb_data src;
+ struct msmfb_data dst;
+};
+
+#endif
+
diff --git a/libc/kernel/common/linux/msm_vidc_dec.h b/libc/kernel/common/linux/msm_vidc_dec.h
index 20837a739..47ea37f97 100644
--- a/libc/kernel/common/linux/msm_vidc_dec.h
+++ b/libc/kernel/common/linux/msm_vidc_dec.h
@@ -72,10 +72,12 @@
#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_EXTRADATA_NONE 0x001
+#define VDEC_EXTRADATA_QP 0x004
+#define VDEC_EXTRADATA_MB_ERROR_MAP 0x008
+#define VDEC_EXTRADATA_SEI 0x010
+#define VDEC_EXTRADATA_VUI 0x020
+#define VDEC_EXTRADATA_VC1 0x040
#define VDEC_CMDBASE 0x800
#define VDEC_CMD_SET_INTF_VERSION (VDEC_CMDBASE)
@@ -83,8 +85,8 @@
#define VDEC_IOCTL_MAGIC 'v'
struct vdec_ioctl_msg {
- void *inputparam;
- void *outputparam;
+ void __user *in;
+ void __user *out;
};
#define VDEC_IOCTL_GET_PROFILE_LEVEL_SUPPORTED _IOWR(VDEC_IOCTL_MAGIC, 0, struct vdec_ioctl_msg)
@@ -134,6 +136,16 @@ struct vdec_ioctl_msg {
#define VDEC_IOCTL_GET_NUMBER_INSTANCES _IOR(VDEC_IOCTL_MAGIC, 27, struct vdec_ioctl_msg)
+#define VDEC_IOCTL_SET_PICTURE_ORDER _IOW(VDEC_IOCTL_MAGIC, 28, struct vdec_ioctl_msg)
+
+#define VDEC_IOCTL_SET_FRAME_RATE _IOW(VDEC_IOCTL_MAGIC, 29, struct vdec_ioctl_msg)
+
+#define VDEC_IOCTL_SET_H264_MV_BUFFER _IOW(VDEC_IOCTL_MAGIC, 30, struct vdec_ioctl_msg)
+
+#define VDEC_IOCTL_FREE_H264_MV_BUFFER _IOW(VDEC_IOCTL_MAGIC, 31, struct vdec_ioctl_msg)
+
+#define VDEC_IOCTL_GET_MV_BUFFER_SIZE _IOR(VDEC_IOCTL_MAGIC, 32, struct vdec_ioctl_msg)
+
enum vdec_picture {
PICTURE_TYPE_I,
PICTURE_TYPE_P,
@@ -153,17 +165,17 @@ struct vdec_allocatorproperty {
uint32_t mincount;
uint32_t maxcount;
uint32_t actualcount;
- uint32_t buffer_size;
+ size_t buffer_size;
uint32_t alignment;
uint32_t buf_poolid;
};
struct vdec_bufferpayload {
- uint8_t *bufferaddr;
- uint32_t buffer_len;
+ void __user *bufferaddr;
+ size_t buffer_len;
int pmem_fd;
- uint32_t offset;
- uint32_t mmaped_size;
+ size_t offset;
+ size_t mmaped_size;
};
struct vdec_setbuffer_cmd {
@@ -396,6 +408,11 @@ enum vdec_output_fromat {
VDEC_YUV_FORMAT_TILE_4x2 = 0x2
};
+enum vdec_output_order {
+ VDEC_ORDER_DISPLAY = 0x1,
+ VDEC_ORDER_DECODE = 0x2
+};
+
struct vdec_picsize {
uint32_t frame_width;
uint32_t frame_height;
@@ -404,26 +421,26 @@ struct vdec_picsize {
};
struct vdec_seqheader {
- uint8_t *ptr_seqheader;
- uint32_t seq_header_len;
+ void __user *ptr_seqheader;
+ size_t seq_header_len;
int pmem_fd;
- uint32_t pmem_offset;
+ size_t pmem_offset;
};
struct vdec_mberror {
- uint8_t *ptr_errormap;
- uint32_t err_mapsize;
+ void __user *ptr_errormap;
+ size_t err_mapsize;
};
struct vdec_input_frameinfo {
- uint8_t *bufferaddr;
- uint32_t offset;
- uint32_t datalen;
+ void __user *bufferaddr;
+ size_t offset;
+ size_t datalen;
uint32_t flags;
int64_t timestamp;
void *client_data;
int pmem_fd;
- uint32_t pmem_offset;
+ size_t pmem_offset;
};
struct vdec_framesize {
@@ -434,12 +451,12 @@ struct vdec_framesize {
};
struct vdec_output_frameinfo {
- uint8_t *phy_addr;
- uint8_t *bufferaddr;
- uint32_t offset;
- uint32_t len;
+ void __user *bufferaddr;
+ size_t offset;
+ size_t len;
uint32_t flags;
int64_t time_stamp;
+ enum vdec_picture pic_type;
void *client_data;
void *input_frame_clientdata;
struct vdec_framesize framesize;
@@ -454,7 +471,26 @@ struct vdec_msginfo {
uint32_t status_code;
uint32_t msgcode;
union vdec_msgdata msgdata;
- uint32_t msgdatasize;
+ size_t msgdatasize;
};
-#endif
+struct vdec_framerate {
+ unsigned long fps_denominator;
+ unsigned long fps_numerator;
+};
+
+struct vdec_h264_mv{
+ size_t size;
+ int count;
+ int pmem_fd;
+ int offset;
+};
+
+struct vdec_mv_buff_size{
+ int width;
+ int height;
+ int size;
+ int alignment;
+};
+
+#endif
diff --git a/libc/kernel/common/linux/msm_vidc_enc.h b/libc/kernel/common/linux/msm_vidc_enc.h
index 45437a2cf..58cc1ee2d 100644
--- a/libc/kernel/common/linux/msm_vidc_enc.h
+++ b/libc/kernel/common/linux/msm_vidc_enc.h
@@ -91,17 +91,18 @@
#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_LEVEL_H264_3 0x11
+#define VEN_LEVEL_H264_3p1 0x12
+#define VEN_LEVEL_H264_4 0x13
+
+#define VEN_LEVEL_H263_10 0x14
+#define VEN_LEVEL_H263_20 0x15
+#define VEN_LEVEL_H263_30 0x16
+#define VEN_LEVEL_H263_40 0x17
+#define VEN_LEVEL_H263_45 0x18
+#define VEN_LEVEL_H263_50 0x19
+#define VEN_LEVEL_H263_60 0x1A
+#define VEN_LEVEL_H263_70 0x1B
#define VEN_ENTROPY_MODEL_CAVLC 1
#define VEN_ENTROPY_MODEL_CABAC 2
@@ -123,17 +124,19 @@
#define VEN_RC_VBR_VFR 2
#define VEN_RC_VBR_CFR 3
#define VEN_RC_CBR_VFR 4
+#define VEN_RC_CBR_CFR 5
#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_INPUTFMT_NV12 1
+#define VEN_INPUTFMT_NV21 2
+#define VEN_INPUTFMT_NV12_16M2KA 3
-#define VEN_ROTATION_0 1
-#define VEN_ROTATION_90 2
-#define VEN_ROTATION_180 3
+#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
@@ -147,8 +150,8 @@
#define VEN_IOCTLBASE_ENC 0x850
struct venc_ioctl_msg{
- void *inputparam;
- void *outputparam;
+ void __user *in;
+ void __user *out;
};
#define VEN_IOCTL_SET_INTF_VERSION _IOW(VEN_IOCTLBASE_NENC, 0, struct venc_ioctl_msg)
@@ -189,6 +192,12 @@ struct venc_ioctl_msg{
#define VEN_IOCTL_CMD_STOP _IO(VEN_IOCTLBASE_NENC, 19)
+#define VEN_IOCTL_SET_RECON_BUFFER _IOW(VEN_IOCTLBASE_NENC, 20, struct venc_ioctl_msg)
+
+#define VEN_IOCTL_FREE_RECON_BUFFER _IOW(VEN_IOCTLBASE_NENC, 21, struct venc_ioctl_msg)
+
+#define VEN_IOCTL_GET_RECON_BUFFER_SIZE _IOW(VEN_IOCTLBASE_NENC, 22, struct venc_ioctl_msg)
+
#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)
@@ -259,6 +268,8 @@ 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)
+#define VEN_IOCTL_GET_NUMBER_INSTANCES _IOR(VEN_IOCTLBASE_ENC, 46, struct venc_ioctl_msg)
+
struct venc_switch{
unsigned char status;
};
@@ -275,7 +286,7 @@ struct venc_allocatorproperty{
struct venc_bufferpayload{
unsigned char *pbuffer;
- unsigned long nsize;
+ size_t sz;
int fd;
unsigned int offset;
unsigned int maped_size;
@@ -284,7 +295,7 @@ struct venc_bufferpayload{
struct venc_buffer{
unsigned char *ptrbuffer;
- unsigned long size;
+ unsigned long sz;
unsigned long len;
unsigned long offset;
long long timestamp;
@@ -322,6 +333,7 @@ struct venc_qprange{
};
struct venc_intraperiod{
unsigned long num_pframes;
+ unsigned long num_bframes;
};
struct venc_seqheader{
unsigned char *hdrbufptr;
@@ -398,5 +410,18 @@ struct venc_msg{
struct venc_buffer buf;
unsigned long msgdata_size;
};
-#endif
+struct venc_recon_addr{
+ unsigned long buffer_size;
+ unsigned long pmem_fd;
+ unsigned long offset;
+};
+
+struct venc_recon_buff_size{
+ int width;
+ int height;
+ int size;
+ int alignment;
+};
+
+#endif
diff --git a/libc/kernel/common/linux/spi_aic3254.h b/libc/kernel/common/linux/spi_aic3254.h
new file mode 100644
index 000000000..392d7ae00
--- /dev/null
+++ b/libc/kernel/common/linux/spi_aic3254.h
@@ -0,0 +1,151 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ *** 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 __SPI_AIC3254_H__
+#define __SPI_AIC3254_H__
+
+#include <linux/ioctl.h>
+
+typedef struct _CODEC_SPI_CMD {
+ unsigned char act;
+ unsigned char reg;
+ unsigned char data;
+} CODEC_SPI_CMD;
+
+typedef struct _CODEC_SPI_CMD_PARAM {
+ CODEC_SPI_CMD *data;
+ unsigned int len;
+} CODEC_SPI_CMD_PARAM;
+
+struct AIC3254_PARAM {
+ unsigned int row_num;
+ unsigned int col_num;
+ void *cmd_data;
+};
+
+struct CODEC_CFG {
+ unsigned char tb_idx;
+ unsigned char index;
+};
+
+#define AIC3254_IOCTL_MAGIC 's'
+#define AIC3254_SET_TX_PARAM _IOW(AIC3254_IOCTL_MAGIC, 0x10, unsigned)
+#define AIC3254_SET_RX_PARAM _IOW(AIC3254_IOCTL_MAGIC, 0x11, unsigned)
+#define AIC3254_CONFIG_TX _IOW(AIC3254_IOCTL_MAGIC, 0x12, unsigned int)
+#define AIC3254_CONFIG_RX _IOW(AIC3254_IOCTL_MAGIC, 0x13, unsigned int)
+#define AIC3254_SET_DSP_PARAM _IOW(AIC3254_IOCTL_MAGIC, 0x20, unsigned)
+#define AIC3254_CONFIG_MEDIA _IOW(AIC3254_IOCTL_MAGIC, 0x21, unsigned int)
+#define AIC3254_CONFIG_VOICE _IOW(AIC3254_IOCTL_MAGIC, 0x22, unsigned int)
+#define AIC3254_CONFIG_VOLUME_L _IOW(AIC3254_IOCTL_MAGIC, 0x23, unsigned int)
+#define AIC3254_CONFIG_VOLUME_R _IOW(AIC3254_IOCTL_MAGIC, 0x24, unsigned int)
+#define AIC3254_POWERDOWN _IOW(AIC3254_IOCTL_MAGIC, 0x25, unsigned int)
+#define AIC3254_LOOPBACK _IOW(AIC3254_IOCTL_MAGIC, 0x26, unsigned int)
+#define AIC3254_DUMP_PAGES _IOW(AIC3254_IOCTL_MAGIC, 0x30, unsigned int)
+#define AIC3254_READ_REG _IOWR(AIC3254_IOCTL_MAGIC, 0x31, unsigned)
+#define AIC3254_WRITE_REG _IOW(AIC3254_IOCTL_MAGIC, 0x32, unsigned)
+#define AIC3254_RESET _IOW(AIC3254_IOCTL_MAGIC, 0x33, unsigned int)
+
+#define AIC3254_MAX_PAGES 255
+#define AIC3254_MAX_REGS 128
+#define AIC3254_MAX_RETRY 10
+
+#define IO_CTL_ROW_MAX 64
+#define IO_CTL_COL_MAX 1024
+#define MINIDSP_ROW_MAX 32
+#define MINIDSP_COL_MAX 16384
+
+enum aic3254_uplink_mode {
+ INITIAL = 0,
+ CALL_UPLINK_IMIC_RECEIVER = 1,
+ CALL_UPLINK_EMIC_HEADSET,
+ CALL_UPLINK_IMIC_HEADSET,
+ CALL_UPLINK_IMIC_SPEAKER,
+ CALL_UPLINK_IMIC_RECEIVER_DUALMIC,
+ CALL_UPLINK_EMIC_HEADSET_DUALMIC,
+ CALL_UPLINK_IMIC_SPEAKER_DUALMIC,
+ CALL_UPLINK_IMIC_RECIVER_TESTSIM,
+ CALL_UPLINK_EMIC_HEADSET_TESTSIM,
+ CALL_UPLINK_IMIC_SPEAKER_TESTSIM,
+ VOICERECORD_IMIC = 15,
+ VOICERECORD_EMIC,
+ VIDEORECORD_IMIC,
+ VIDEORECORD_EMIC,
+ VOICERECOGNITION_IMIC,
+ VOICERECOGNITION_EMIC,
+ FM_IN_SPEAKER,
+ FM_IN_HEADSET,
+ TTY_IN_HCO,
+ TTY_IN_VCO,
+ TTY_IN_FULL,
+ UPLINK_OFF = 29,
+ UPLINK_WAKEUP,
+ POWER_OFF,
+ SLEEP_WITH_HP_IN,
+ VOICERECORD_IMIC_PLAYBACK_SPEAKER,
+ VOICERECORD_EMIC_PLAYBACK_HEADSET,
+ VOICERECORD_IMIC_PLAYBACK_HEADSET,
+};
+
+enum aic3254_downlink_mode {
+ CALL_DOWNLINK_IMIC_RECEIVER = 1,
+ CALL_DOWNLINK_EMIC_HEADSET,
+ CALL_DOWNLINK_IMIC_HEADSET,
+ CALL_DOWNLINK_IMIC_SPEAKER,
+ CALL_DOWNLINK_IMIC_RECEIVER_DUALMIC,
+ CALL_DOWNLINK_EMIC_HEADSET_DUALMIC,
+ CALL_DOWNLINK_IMIC_SPEAKER_DUALMIC,
+ CALL_DOWNLINK_IMIC_RECIVER_TESTSIM,
+ CALL_DOWNLINK_EMIC_HEADSET_TESTSIM,
+ CALL_DOWNLINK_IMIC_SPEAKER_TESTSIM,
+ PLAYBACK_RECEIVER,
+ PLAYBACK_HEADSET,
+ PLAYBACK_SPEAKER = 13,
+ RING_HEADSET_SPEAKER,
+ PLAYBACK_SPEAKER_ALT,
+ USB_AUDIO,
+ FM_OUT_SPEAKER = 21,
+ FM_OUT_HEADSET,
+ TTY_OUT_HCO,
+ TTY_OUT_VCO,
+ TTY_OUT_FULL,
+ MUSE,
+ HAC,
+ LPM_IMIC_RECEIVER,
+ DOWNLINK_OFF = 29,
+ DOWNLINK_WAKEUP,
+};
+
+struct aic3254_ctl_ops {
+ void (*tx_amp_enable)(int en);
+ void (*rx_amp_enable)(int en);
+ int (*panel_sleep_in)(void);
+ void (*reset_3254)(void);
+ void (*spibus_enable)(int en);
+ CODEC_SPI_CMD_PARAM *downlink_off;
+ CODEC_SPI_CMD_PARAM *uplink_off;
+ CODEC_SPI_CMD_PARAM *downlink_on;
+ CODEC_SPI_CMD_PARAM *uplink_on;
+ CODEC_SPI_CMD_PARAM *lb_dsp_init;
+ CODEC_SPI_CMD_PARAM *lb_downlink_receiver;
+ CODEC_SPI_CMD_PARAM *lb_downlink_speaker;
+ CODEC_SPI_CMD_PARAM *lb_downlink_headset;
+ CODEC_SPI_CMD_PARAM *lb_uplink_imic;
+ CODEC_SPI_CMD_PARAM *lb_uplink_emic;
+ CODEC_SPI_CMD_PARAM *lb_receiver_imic;
+ CODEC_SPI_CMD_PARAM *lb_speaker_imic;
+ CODEC_SPI_CMD_PARAM *lb_headset_emic;
+ CODEC_SPI_CMD_PARAM *lb_receiver_bmic;
+ CODEC_SPI_CMD_PARAM *lb_speaker_bmic;
+ CODEC_SPI_CMD_PARAM *lb_headset_bmic;
+};
+
+#endif
+
diff --git a/libc/kernel/common/linux/tpa2051d3.h b/libc/kernel/common/linux/tpa2051d3.h
new file mode 100644
index 000000000..446db99ee
--- /dev/null
+++ b/libc/kernel/common/linux/tpa2051d3.h
@@ -0,0 +1,52 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ *** 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 TPA2051D3_H
+#define TPA2051D3_H
+
+#include <linux/ioctl.h>
+
+#define TPA2051D3_I2C_NAME "tpa2051d3"
+#define SPKR_OUTPUT 0
+#define HEADSET_OUTPUT 1
+#define DUAL_OUTPUT 2
+#define HANDSET_OUTPUT 3
+#define MODE_CMD_LEM 9
+struct tpa2051d3_platform_data {
+ uint32_t gpio_tpa2051_spk_en;
+};
+
+struct tpa2051_config_data {
+ unsigned int data_len;
+ unsigned int mode_num;
+ unsigned char *cmd_data;
+};
+
+enum TPA2051_Mode {
+ TPA2051_MODE_OFF,
+ TPA2051_MODE_PLAYBACK_SPKR,
+ TPA2051_MODE_PLAYBACK_HEADSET,
+ TPA2051_MODE_RING,
+ TPA2051_MODE_VOICECALL_SPKR,
+ TPA2051_MODE_VOICECALL_HEADSET,
+ TPA2051_MODE_FM_SPKR,
+ TPA2051_MODE_FM_HEADSET,
+ TPA2051_MODE_HANDSET,
+ TPA2051_MAX_MODE
+};
+#define TPA2051_IOCTL_MAGIC 'a'
+#define TPA2051_SET_CONFIG _IOW(TPA2051_IOCTL_MAGIC, 0x01, unsigned)
+#define TPA2051_READ_CONFIG _IOW(TPA2051_IOCTL_MAGIC, 0x02, unsigned)
+#define TPA2051_SET_MODE _IOW(TPA2051_IOCTL_MAGIC, 0x03, unsigned)
+#define TPA2051_SET_PARAM _IOW(TPA2051_IOCTL_MAGIC, 0x04, unsigned)
+
+#endif
+
diff --git a/libc/kernel/common/linux/videodev2.h b/libc/kernel/common/linux/videodev2.h
index 3a91510a2..5e52ce48e 100644
--- a/libc/kernel/common/linux/videodev2.h
+++ b/libc/kernel/common/linux/videodev2.h
@@ -413,6 +413,9 @@ struct v4l2_window {
__u32 clipcount;
void __user *bitmap;
__u8 global_alpha;
+#ifdef OMAP_ENHANCEMENT
+ __u8 zorder;
+#endif
};
struct v4l2_captureparm {
diff --git a/libc/netbsd/net/getaddrinfo.c b/libc/netbsd/net/getaddrinfo.c
index e4d8c56a7..edb4f707e 100644
--- a/libc/netbsd/net/getaddrinfo.c
+++ b/libc/netbsd/net/getaddrinfo.c
@@ -77,10 +77,13 @@
* friends.
*/
+#include <fcntl.h>
#include <sys/cdefs.h>
#include <sys/types.h>
+#include <sys/stat.h>
#include <sys/param.h>
#include <sys/socket.h>
+#include <sys/un.h>
#include <net/if.h>
#include <netinet/in.h>
#include <arpa/inet.h>
@@ -100,6 +103,10 @@
#include <stdarg.h>
#include "nsswitch.h"
+#ifdef ANDROID_CHANGES
+#include <sys/system_properties.h>
+#endif /* ANDROID_CHANGES */
+
typedef union sockaddr_union {
struct sockaddr generic;
struct sockaddr_in in;
@@ -391,6 +398,191 @@ _have_ipv4() {
return _test_connect(PF_INET, &addr.generic, sizeof(addr.in));
}
+// Returns 0 on success, else returns non-zero on error (in which case
+// getaddrinfo should continue as normal)
+static int
+android_getaddrinfo_proxy(
+ const char *hostname, const char *servname,
+ const struct addrinfo *hints, struct addrinfo **res)
+{
+ int sock;
+ const int one = 1;
+ struct sockaddr_un proxy_addr;
+ const char* cache_mode = getenv("ANDROID_DNS_MODE");
+ FILE* proxy = NULL;
+ int success = 0;
+
+ // Clear this at start, as we use its non-NULLness later (in the
+ // error path) to decide if we have to free up any memory we
+ // allocated in the process (before failing).
+ *res = NULL;
+
+ if (cache_mode != NULL && strcmp(cache_mode, "local") == 0) {
+ // Don't use the proxy in local mode. This is used by the
+ // proxy itself.
+ return -1;
+ }
+
+ // Temporary cautious hack to disable the DNS proxy for processes
+ // requesting special treatment. Ideally the DNS proxy should
+ // accomodate these apps, though.
+ char propname[PROP_NAME_MAX];
+ char propvalue[PROP_VALUE_MAX];
+ snprintf(propname, sizeof(propname), "net.dns1.%d", getpid());
+ if (__system_property_get(propname, propvalue) > 0) {
+ return -1;
+ }
+
+ // Bogus things we can't serialize. Don't use the proxy.
+ if ((hostname != NULL &&
+ strcspn(hostname, " \n\r\t^'\"") != strlen(hostname)) ||
+ (servname != NULL &&
+ strcspn(servname, " \n\r\t^'\"") != strlen(servname))) {
+ return -1;
+ }
+
+ sock = socket(AF_UNIX, SOCK_STREAM, 0);
+ if (sock < 0) {
+ return -1;
+ }
+
+ setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one));
+ memset(&proxy_addr, 0, sizeof(proxy_addr));
+ proxy_addr.sun_family = AF_UNIX;
+ strlcpy(proxy_addr.sun_path, "/dev/socket/dnsproxyd",
+ sizeof(proxy_addr.sun_path));
+ if (TEMP_FAILURE_RETRY(connect(sock,
+ (const struct sockaddr*) &proxy_addr,
+ sizeof(proxy_addr))) != 0) {
+ close(sock);
+ return -1;
+ }
+
+ // Send the request.
+ proxy = fdopen(sock, "r+");
+ if (fprintf(proxy, "getaddrinfo %s %s %d %d %d %d",
+ hostname == NULL ? "^" : hostname,
+ servname == NULL ? "^" : servname,
+ hints == NULL ? -1 : hints->ai_flags,
+ hints == NULL ? -1 : hints->ai_family,
+ hints == NULL ? -1 : hints->ai_socktype,
+ hints == NULL ? -1 : hints->ai_protocol) < 0) {
+ goto exit;
+ }
+ // literal NULL byte at end, required by FrameworkListener
+ if (fputc(0, proxy) == EOF ||
+ fflush(proxy) != 0) {
+ goto exit;
+ }
+
+ int remote_rv;
+ if (fread(&remote_rv, sizeof(int), 1, proxy) != 1) {
+ goto exit;
+ }
+
+ if (remote_rv != 0) {
+ goto exit;
+ }
+
+ struct addrinfo* ai = NULL;
+ struct addrinfo** nextres = res;
+ while (1) {
+ uint32_t addrinfo_len;
+ if (fread(&addrinfo_len, sizeof(addrinfo_len),
+ 1, proxy) != 1) {
+ break;
+ }
+ addrinfo_len = ntohl(addrinfo_len);
+ if (addrinfo_len == 0) {
+ success = 1;
+ break;
+ }
+
+ if (addrinfo_len < sizeof(struct addrinfo)) {
+ break;
+ }
+ struct addrinfo* ai = calloc(1, addrinfo_len +
+ sizeof(struct sockaddr_storage));
+ if (ai == NULL) {
+ break;
+ }
+
+ if (fread(ai, addrinfo_len, 1, proxy) != 1) {
+ // Error; fall through.
+ break;
+ }
+
+ // Zero out the pointer fields we copied which aren't
+ // valid in this address space.
+ ai->ai_addr = NULL;
+ ai->ai_canonname = NULL;
+ ai->ai_next = NULL;
+
+ // struct sockaddr
+ uint32_t addr_len;
+ if (fread(&addr_len, sizeof(addr_len), 1, proxy) != 1) {
+ break;
+ }
+ addr_len = ntohl(addr_len);
+ if (addr_len != 0) {
+ if (addr_len > sizeof(struct sockaddr_storage)) {
+ // Bogus; too big.
+ break;
+ }
+ struct sockaddr* addr = (struct sockaddr*)(ai + 1);
+ if (fread(addr, addr_len, 1, proxy) != 1) {
+ break;
+ }
+ ai->ai_addr = addr;
+ }
+
+ // cannonname
+ uint32_t name_len;
+ if (fread(&name_len, sizeof(name_len), 1, proxy) != 1) {
+ break;
+ }
+ name_len = ntohl(name_len);
+ if (name_len != 0) {
+ ai->ai_canonname = (char*) malloc(name_len);
+ if (fread(ai->ai_canonname, name_len, 1, proxy) != 1) {
+ break;
+ }
+ if (ai->ai_canonname[name_len - 1] != '\0') {
+ // The proxy should be returning this
+ // NULL-terminated.
+ break;
+ }
+ }
+
+ *nextres = ai;
+ nextres = &ai->ai_next;
+ ai = NULL;
+ }
+
+ if (ai != NULL) {
+ // Clean up partially-built addrinfo that we never ended up
+ // attaching to the response.
+ freeaddrinfo(ai);
+ }
+exit:
+ if (proxy != NULL) {
+ fclose(proxy);
+ }
+
+ if (success) {
+ return 0;
+ }
+
+ // Proxy failed; fall through to local
+ // resolver case. But first clean up any
+ // memory we might've allocated.
+ if (*res) {
+ freeaddrinfo(*res);
+ *res = NULL;
+ }
+ return -1;
+}
+
int
getaddrinfo(const char *hostname, const char *servname,
const struct addrinfo *hints, struct addrinfo **res)
@@ -537,6 +729,13 @@ getaddrinfo(const char *hostname, const char *servname,
if (pai->ai_flags & AI_NUMERICHOST)
ERR(EAI_NONAME);
+ /*
+ * BEGIN ANDROID CHANGES; proxying to the cache
+ */
+ if (android_getaddrinfo_proxy(hostname, servname, hints, res) == 0) {
+ return 0;
+ }
+
/*
* hostname as alphabetical name.
* we would like to prefer AF_INET6 than AF_INET, so we'll make a
diff --git a/libc/netbsd/net/getnameinfo.c b/libc/netbsd/net/getnameinfo.c
index 36664435d..d3d0011b9 100644
--- a/libc/netbsd/net/getnameinfo.c
+++ b/libc/netbsd/net/getnameinfo.c
@@ -64,6 +64,11 @@ __RCSID("$NetBSD: getnameinfo.c,v 1.43 2006/02/17 15:58:26 ginsbach Exp $");
#include <netdb.h>
#ifdef ANDROID_CHANGES
#include "resolv_private.h"
+#include <sys/system_properties.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <sys/un.h>
+#include <errno.h>
#else
#include <resolv.h>
#endif
@@ -124,7 +129,98 @@ int getnameinfo(const struct sockaddr* sa, socklen_t salen, char* host, size_t h
}
}
+#ifdef ANDROID_CHANGES
+/* On success length of the host name is returned. A return
+ * value of 0 means there's no host name associated with
+ * the address. On failure -1 is returned in which case
+ * normal execution flow shall continue. */
+static int
+android_gethostbyaddr_proxy(struct hostent* hp, const void *addr, socklen_t addrLen, int addrFamily) {
+
+ int sock;
+ const int one = 1;
+ struct sockaddr_un proxy_addr;
+ const char* cache_mode = getenv("ANDROID_DNS_MODE");
+ FILE* proxy = NULL;
+ int result = -1;
+
+ if (cache_mode != NULL && strcmp(cache_mode, "local") == 0) {
+ // Don't use the proxy in local mode. This is used by the
+ // proxy itself.
+ return -1;
+ }
+
+ // Temporary cautious hack to disable the DNS proxy for processes
+ // requesting special treatment. Ideally the DNS proxy should
+ // accomodate these apps, though.
+ char propname[PROP_NAME_MAX];
+ char propvalue[PROP_VALUE_MAX];
+ snprintf(propname, sizeof(propname), "net.dns1.%d", getpid());
+ if (__system_property_get(propname, propvalue) > 0) {
+ return -1;
+ }
+ // create socket
+ sock = socket(AF_UNIX, SOCK_STREAM, 0);
+ if (sock < 0) {
+ return -1;
+ }
+ setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one));
+ memset(&proxy_addr, 0, sizeof(proxy_addr));
+ proxy_addr.sun_family = AF_UNIX;
+ strlcpy(proxy_addr.sun_path, "/dev/socket/dnsproxyd",
+ sizeof(proxy_addr.sun_path));
+ if (TEMP_FAILURE_RETRY(connect(sock, (const struct sockaddr*) (void*) &proxy_addr,
+ sizeof(proxy_addr))) != 0) {
+ close(sock);
+ return -1;
+ }
+
+ // send request to DnsProxyListener
+ proxy = fdopen(sock,"r+");
+ if (proxy == NULL) {
+ goto exit;
+ }
+
+ char buf[INET6_ADDRSTRLEN]; // big enough for IPv4 and IPv6
+ const char* addrStr = inet_ntop(addrFamily, addr, &buf, sizeof(buf));
+ if (addrStr == NULL) {
+ goto exit;
+ }
+ if (fprintf(proxy, "gethostbyaddr %s %d %d", addrStr, addrLen, addrFamily) < 0) {
+ goto exit;
+ }
+
+ // literal NULL byte at end, required by FrameworkListener
+ if (fputc(0, proxy) == EOF || fflush(proxy) != 0) {
+ goto exit;
+ }
+
+ result = 0;
+ uint32_t name_len;
+ if (fread(&name_len, sizeof(name_len), 1, proxy) != 1) {
+ goto exit;
+ }
+
+ name_len = ntohl(name_len);
+ if (name_len <= 0) {
+ goto exit;
+ }
+
+ if (fread(hp->h_name, name_len, 1, proxy) != 1) {
+ goto exit;
+ }
+
+ result = name_len;
+
+ exit:
+ if (proxy != NULL) {
+ fclose(proxy);
+ }
+
+ return result;
+}
+#endif
/*
* getnameinfo_inet():
* Format an IPv4 or IPv6 sockaddr into a printable string.
@@ -277,7 +373,21 @@ getnameinfo_inet(sa, salen, host, hostlen, serv, servlen, flags)
break;
}
} else {
+#ifdef ANDROID_CHANGES
+ struct hostent android_proxy_hostent;
+ char android_proxy_buf[MAXDNAME];
+ android_proxy_hostent.h_name = android_proxy_buf;
+
+ int hostnamelen = android_gethostbyaddr_proxy(&android_proxy_hostent,
+ addr, afd->a_addrlen, afd->a_af);
+ if (hostnamelen >= 0) {
+ hp = (hostnamelen > 0) ? &android_proxy_hostent : NULL;
+ } else {
+ hp = gethostbyaddr(addr, afd->a_addrlen, afd->a_af);
+ }
+#else
hp = gethostbyaddr(addr, afd->a_addrlen, afd->a_af);
+#endif
if (hp) {
#if 0
diff --git a/libc/netbsd/resolv/res_cache.c b/libc/netbsd/resolv/res_cache.c
index 2621a7bbf..20f37e106 100644
--- a/libc/netbsd/resolv/res_cache.c
+++ b/libc/netbsd/resolv/res_cache.c
@@ -27,17 +27,28 @@
*/
#include "resolv_cache.h"
+#include <resolv.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include "pthread.h"
+#include <errno.h>
+#include "arpa_nameser.h"
+#include <sys/system_properties.h>
+#include <net/if.h>
+#include <netdb.h>
+#include <linux/if.h>
+
+#include <arpa/inet.h>
+#include "resolv_private.h"
+
/* This code implements a small and *simple* DNS resolver cache.
*
- * It is only used to cache DNS answers for a maximum of CONFIG_SECONDS seconds
- * in order to reduce DNS traffic. It is not supposed to be a full DNS cache,
- * since we plan to implement that in the future in a dedicated process running
- * on the system.
+ * It is only used to cache DNS answers for a time defined by the smallest TTL
+ * among the answer records in order to reduce DNS traffic. It is not supposed
+ * to be a full DNS cache, since we plan to implement that in the future in a
+ * dedicated process running on the system.
*
* Note that its design is kept simple very intentionally, i.e.:
*
@@ -47,9 +58,8 @@
* (this means that two similar queries that encode the DNS name
* differently will be treated distinctly).
*
- * - the TTLs of answer RRs are ignored. our DNS resolver library does not use
- * them anyway, but it means that records with a TTL smaller than
- * CONFIG_SECONDS will be kept in the cache anyway.
+ * the smallest TTL value among the answer records are used as the time
+ * to keep an answer in the cache.
*
* this is bad, but we absolutely want to avoid parsing the answer packets
* (and should be solved by the later full DNS cache process).
@@ -104,7 +114,7 @@
*/
#define CONFIG_SECONDS (60*10) /* 10 minutes */
-/* maximum number of entries kept in the cache. This value has been
+/* default number of entries kept in the cache. This value has been
* determined by browsing through various sites and counting the number
* of corresponding requests. Keep in mind that our framework is currently
* performing two requests per name lookup (one for IPv4, the other for IPv6)
@@ -123,10 +133,16 @@
* most high-level websites use lots of media/ad servers with different names
* but these are generally reused when browsing through the site.
*
- * As such, a valud of 64 should be relatively conformtable at the moment.
+ * As such, a value of 64 should be relatively comfortable at the moment.
+ *
+ * The system property ro.net.dns_cache_size can be used to override the default
+ * value with a custom value
*/
#define CONFIG_MAX_ENTRIES 64
+/* name of the system property that can be used to set the cache size */
+#define DNS_CACHE_SIZE_PROP_NAME "ro.net.dns_cache_size"
+
/****************************************************************************/
/****************************************************************************/
/***** *****/
@@ -141,6 +157,7 @@
/* set to 1 to debug query data */
#define DEBUG_DATA 0
+#undef XLOG
#if DEBUG
# include <logd.h>
# define XLOG(...) \
@@ -987,10 +1004,50 @@ typedef struct Entry {
int querylen;
const uint8_t* answer;
int answerlen;
- time_t when; /* time_t when entry was added to table */
- int id; /* for debugging purpose */
+ time_t expires; /* time_t when the entry isn't valid any more */
+ int id; /* for debugging purpose */
} Entry;
+/**
+ * Parse the answer records and find the smallest
+ * TTL among the answer records.
+ *
+ * The returned TTL is the number of seconds to
+ * keep the answer in the cache.
+ *
+ * In case of parse error zero (0) is returned which
+ * indicates that the answer shall not be cached.
+ */
+static u_long
+answer_getTTL(const void* answer, int answerlen)
+{
+ ns_msg handle;
+ int ancount, n;
+ u_long result, ttl;
+ ns_rr rr;
+
+ result = 0;
+ if (ns_initparse(answer, answerlen, &handle) >= 0) {
+ // get number of answer records
+ ancount = ns_msg_count(handle, ns_s_an);
+ for (n = 0; n < ancount; n++) {
+ if (ns_parserr(&handle, ns_s_an, n, &rr) == 0) {
+ ttl = ns_rr_ttl(rr);
+ if (n == 0 || ttl < result) {
+ result = ttl;
+ }
+ } else {
+ XLOG("ns_parserr failed ancount no = %d. errno = %s\n", n, strerror(errno));
+ }
+ }
+ } else {
+ XLOG("ns_parserr failed. %s\n", strerror(errno));
+ }
+
+ XLOG("TTL = %d\n", result);
+
+ return result;
+}
static void
entry_free( Entry* e )
@@ -1072,8 +1129,6 @@ entry_alloc( const Entry* init, const void* answer, int answerlen )
memcpy( (char*)e->answer, answer, e->answerlen );
- e->when = _time_now();
-
return e;
}
@@ -1103,17 +1158,25 @@ entry_equals( const Entry* e1, const Entry* e2 )
* for simplicity, the hash-table fields 'hash' and 'hlink' are
* inlined in the Entry structure.
*/
-#define MAX_HASH_ENTRIES (2*CONFIG_MAX_ENTRIES)
typedef struct resolv_cache {
+ int max_entries;
int num_entries;
Entry mru_list;
pthread_mutex_t lock;
unsigned generation;
int last_id;
- Entry* entries[ MAX_HASH_ENTRIES ];
+ Entry* entries;
} Cache;
+typedef struct resolv_cache_info {
+ char ifname[IF_NAMESIZE + 1];
+ struct in_addr ifaddr;
+ Cache* cache;
+ struct resolv_cache_info* next;
+ char* nameservers[MAXNS +1];
+ struct addrinfo* nsaddrinfo[MAXNS + 1];
+} CacheInfo;
#define HTABLE_VALID(x) ((x) != NULL && (x) != HTABLE_DELETED)
@@ -1123,9 +1186,9 @@ _cache_flush_locked( Cache* cache )
int nn;
time_t now = _time_now();
- for (nn = 0; nn < MAX_HASH_ENTRIES; nn++)
+ for (nn = 0; nn < cache->max_entries; nn++)
{
- Entry** pnode = &cache->entries[nn];
+ Entry** pnode = (Entry**) &cache->entries[nn];
while (*pnode != NULL) {
Entry* node = *pnode;
@@ -1143,17 +1206,48 @@ _cache_flush_locked( Cache* cache )
"*************************");
}
-struct resolv_cache*
+/* Return max number of entries allowed in the cache,
+ * i.e. cache size. The cache size is either defined
+ * by system property ro.net.dns_cache_size or by
+ * CONFIG_MAX_ENTRIES if system property not set
+ * or set to invalid value. */
+static int
+_res_cache_get_max_entries( void )
+{
+ int result = -1;
+ char cache_size[PROP_VALUE_MAX];
+
+ if (__system_property_get(DNS_CACHE_SIZE_PROP_NAME, cache_size) > 0) {
+ result = atoi(cache_size);
+ }
+
+ // ro.net.dns_cache_size not set or set to negative value
+ if (result <= 0) {
+ result = CONFIG_MAX_ENTRIES;
+ }
+
+ XLOG("cache size: %d", result);
+ return result;
+}
+
+static struct resolv_cache*
_resolv_cache_create( void )
{
struct resolv_cache* cache;
cache = calloc(sizeof(*cache), 1);
if (cache) {
- cache->generation = ~0U;
- pthread_mutex_init( &cache->lock, NULL );
- cache->mru_list.mru_prev = cache->mru_list.mru_next = &cache->mru_list;
- XLOG("%s: cache created\n", __FUNCTION__);
+ cache->max_entries = _res_cache_get_max_entries();
+ cache->entries = calloc(sizeof(*cache->entries), cache->max_entries);
+ if (cache->entries) {
+ cache->generation = ~0U;
+ pthread_mutex_init( &cache->lock, NULL );
+ cache->mru_list.mru_prev = cache->mru_list.mru_next = &cache->mru_list;
+ XLOG("%s: cache created\n", __FUNCTION__);
+ } else {
+ free(cache);
+ cache = NULL;
+ }
}
return cache;
}
@@ -1183,12 +1277,47 @@ _cache_dump_mru( Cache* cache )
XLOG("%s", temp);
}
+
+static void
+_dump_answer(const void* answer, int answerlen)
+{
+ res_state statep;
+ FILE* fp;
+ char* buf;
+ int fileLen;
+
+ fp = fopen("/data/reslog.txt", "w+");
+ if (fp != NULL) {
+ statep = __res_get_state();
+
+ res_pquery(statep, answer, answerlen, fp);
+
+ //Get file length
+ fseek(fp, 0, SEEK_END);
+ fileLen=ftell(fp);
+ fseek(fp, 0, SEEK_SET);
+ buf = (char *)malloc(fileLen+1);
+ if (buf != NULL) {
+ //Read file contents into buffer
+ fread(buf, fileLen, 1, fp);
+ XLOG("%s\n", buf);
+ free(buf);
+ }
+ fclose(fp);
+ remove("/data/reslog.txt");
+ }
+ else {
+ XLOG("_dump_answer: can't open file\n");
+ }
+}
#endif
#if DEBUG
# define XLOG_QUERY(q,len) _dump_query((q), (len))
+# define XLOG_ANSWER(a, len) _dump_answer((a), (len))
#else
# define XLOG_QUERY(q,len) ((void)0)
+# define XLOG_ANSWER(a,len) ((void)0)
#endif
/* This function tries to find a key within the hash table
@@ -1209,8 +1338,8 @@ static Entry**
_cache_lookup_p( Cache* cache,
Entry* key )
{
- int index = key->hash % MAX_HASH_ENTRIES;
- Entry** pnode = &cache->entries[ key->hash % MAX_HASH_ENTRIES ];
+ int index = key->hash % cache->max_entries;
+ Entry** pnode = (Entry**) &cache->entries[ index ];
while (*pnode != NULL) {
Entry* node = *pnode;
@@ -1322,7 +1451,7 @@ _resolv_cache_lookup( struct resolv_cache* cache,
now = _time_now();
/* remove stale entries here */
- if ( (unsigned)(now - e->when) >= CONFIG_SECONDS ) {
+ if (now >= e->expires) {
XLOG( " NOT IN CACHE (STALE ENTRY %p DISCARDED)", *lookup );
_cache_remove_p(cache, lookup);
goto Exit;
@@ -1363,6 +1492,7 @@ _resolv_cache_add( struct resolv_cache* cache,
Entry key[1];
Entry* e;
Entry** lookup;
+ u_long ttl;
/* don't assume that the query has already been cached
*/
@@ -1375,6 +1505,7 @@ _resolv_cache_add( struct resolv_cache* cache,
XLOG( "%s: query:", __FUNCTION__ );
XLOG_QUERY(query,querylen);
+ XLOG_ANSWER(answer, answerlen);
#if DEBUG_DATA
XLOG( "answer:");
XLOG_BYTES(answer,answerlen);
@@ -1389,7 +1520,7 @@ _resolv_cache_add( struct resolv_cache* cache,
goto Exit;
}
- if (cache->num_entries >= CONFIG_MAX_ENTRIES) {
+ if (cache->num_entries >= cache->max_entries) {
_cache_remove_oldest(cache);
/* need to lookup again */
lookup = _cache_lookup_p(cache, key);
@@ -1401,9 +1532,13 @@ _resolv_cache_add( struct resolv_cache* cache,
}
}
- e = entry_alloc( key, answer, answerlen );
- if (e != NULL) {
- _cache_add_p(cache, lookup, e);
+ ttl = answer_getTTL(answer, answerlen);
+ if (ttl > 0) {
+ e = entry_alloc(key, answer, answerlen);
+ if (e != NULL) {
+ e->expires = ttl + _time_now();
+ _cache_add_p(cache, lookup, e);
+ }
}
#if DEBUG
_cache_dump_mru(cache);
@@ -1420,11 +1555,47 @@ Exit:
/****************************************************************************/
/****************************************************************************/
-static struct resolv_cache* _res_cache;
static pthread_once_t _res_cache_once;
+// Head of the list of caches. Protected by _res_cache_list_lock.
+static struct resolv_cache_info _res_cache_list;
+
+// name of the current default inteface
+static char _res_default_ifname[IF_NAMESIZE + 1];
+
+// lock protecting everything in the _resolve_cache_info structs (next ptr, etc)
+static pthread_mutex_t _res_cache_list_lock;
+
+
+/* lookup the default interface name */
+static char *_get_default_iface_locked();
+/* insert resolv_cache_info into the list of resolv_cache_infos */
+static void _insert_cache_info_locked(struct resolv_cache_info* cache_info);
+/* creates a resolv_cache_info */
+static struct resolv_cache_info* _create_cache_info( void );
+/* gets cache associated with an interface name, or NULL if none exists */
+static struct resolv_cache* _find_named_cache_locked(const char* ifname);
+/* gets a resolv_cache_info associated with an interface name, or NULL if not found */
+static struct resolv_cache_info* _find_cache_info_locked(const char* ifname);
+/* free dns name server list of a resolv_cache_info structure */
+static void _free_nameservers(struct resolv_cache_info* cache_info);
+/* look up the named cache, and creates one if needed */
+static struct resolv_cache* _get_res_cache_for_iface_locked(const char* ifname);
+/* empty the named cache */
+static void _flush_cache_for_iface_locked(const char* ifname);
+/* empty the nameservers set for the named cache */
+static void _free_nameservers_locked(struct resolv_cache_info* cache_info);
+/* lookup the namserver for the name interface */
+static int _get_nameserver_locked(const char* ifname, int n, char* addr, int addrLen);
+/* lookup the addr of the nameserver for the named interface */
+static struct addrinfo* _get_nameserver_addr_locked(const char* ifname, int n);
+/* lookup the inteface's address */
+static struct in_addr* _get_addr_locked(const char * ifname);
+
+
+
static void
-_res_cache_init( void )
+_res_cache_init(void)
{
const char* env = getenv(CONFIG_ENV);
@@ -1433,29 +1604,394 @@ _res_cache_init( void )
return;
}
- _res_cache = _resolv_cache_create();
+ memset(&_res_default_ifname, 0, sizeof(_res_default_ifname));
+ memset(&_res_cache_list, 0, sizeof(_res_cache_list));
+ pthread_mutex_init(&_res_cache_list_lock, NULL);
}
-
struct resolv_cache*
-__get_res_cache( void )
+__get_res_cache(void)
+{
+ struct resolv_cache *cache;
+
+ pthread_once(&_res_cache_once, _res_cache_init);
+
+ pthread_mutex_lock(&_res_cache_list_lock);
+
+ char* ifname = _get_default_iface_locked();
+
+ // if default interface not set then use the first cache
+ // associated with an interface as the default one.
+ if (ifname[0] == '\0') {
+ struct resolv_cache_info* cache_info = _res_cache_list.next;
+ while (cache_info) {
+ if (cache_info->ifname[0] != '\0') {
+ ifname = cache_info->ifname;
+ }
+
+ cache_info = cache_info->next;
+ }
+ }
+ cache = _get_res_cache_for_iface_locked(ifname);
+
+ pthread_mutex_unlock(&_res_cache_list_lock);
+ XLOG("_get_res_cache. default_ifname = %s\n", ifname);
+ return cache;
+}
+
+static struct resolv_cache*
+_get_res_cache_for_iface_locked(const char* ifname)
{
- pthread_once( &_res_cache_once, _res_cache_init );
- return _res_cache;
+ if (ifname == NULL)
+ return NULL;
+
+ struct resolv_cache* cache = _find_named_cache_locked(ifname);
+ if (!cache) {
+ struct resolv_cache_info* cache_info = _create_cache_info();
+ if (cache_info) {
+ cache = _resolv_cache_create();
+ if (cache) {
+ int len = sizeof(cache_info->ifname);
+ cache_info->cache = cache;
+ strncpy(cache_info->ifname, ifname, len - 1);
+ cache_info->ifname[len - 1] = '\0';
+
+ _insert_cache_info_locked(cache_info);
+ } else {
+ free(cache_info);
+ }
+ }
+ }
+ return cache;
}
void
-_resolv_cache_reset( unsigned generation )
+_resolv_cache_reset(unsigned generation)
{
XLOG("%s: generation=%d", __FUNCTION__, generation);
- if (_res_cache == NULL)
+ pthread_once(&_res_cache_once, _res_cache_init);
+ pthread_mutex_lock(&_res_cache_list_lock);
+
+ char* ifname = _get_default_iface_locked();
+ // if default interface not set then use the first cache
+ // associated with an interface as the default one.
+ // Note: Copied the code from __get_res_cache since this
+ // method will be deleted/obsolete when cache per interface
+ // implemented all over
+ if (ifname[0] == '\0') {
+ struct resolv_cache_info* cache_info = _res_cache_list.next;
+ while (cache_info) {
+ if (cache_info->ifname[0] != '\0') {
+ ifname = cache_info->ifname;
+ }
+
+ cache_info = cache_info->next;
+ }
+ }
+ struct resolv_cache* cache = _get_res_cache_for_iface_locked(ifname);
+
+ if (cache == NULL) {
+ pthread_mutex_unlock(&_res_cache_list_lock);
return;
+ }
+
+ pthread_mutex_lock( &cache->lock );
+ if (cache->generation != generation) {
+ _cache_flush_locked(cache);
+ cache->generation = generation;
+ }
+ pthread_mutex_unlock( &cache->lock );
+
+ pthread_mutex_unlock(&_res_cache_list_lock);
+}
+
+void
+_resolv_flush_cache_for_default_iface(void)
+{
+ char* ifname;
+
+ pthread_once(&_res_cache_once, _res_cache_init);
+ pthread_mutex_lock(&_res_cache_list_lock);
+
+ ifname = _get_default_iface_locked();
+ _flush_cache_for_iface_locked(ifname);
+
+ pthread_mutex_unlock(&_res_cache_list_lock);
+}
+
+void
+_resolv_flush_cache_for_iface(const char* ifname)
+{
+ pthread_once(&_res_cache_once, _res_cache_init);
+ pthread_mutex_lock(&_res_cache_list_lock);
+
+ _flush_cache_for_iface_locked(ifname);
+
+ pthread_mutex_unlock(&_res_cache_list_lock);
+}
+
+static void
+_flush_cache_for_iface_locked(const char* ifname)
+{
+ struct resolv_cache* cache = _find_named_cache_locked(ifname);
+ if (cache) {
+ pthread_mutex_lock(&cache->lock);
+ _cache_flush_locked(cache);
+ pthread_mutex_unlock(&cache->lock);
+ }
+}
+
+static struct resolv_cache_info*
+_create_cache_info(void)
+{
+ struct resolv_cache_info* cache_info;
+
+ cache_info = calloc(sizeof(*cache_info), 1);
+ return cache_info;
+}
+
+static void
+_insert_cache_info_locked(struct resolv_cache_info* cache_info)
+{
+ struct resolv_cache_info* last;
+
+ for (last = &_res_cache_list; last->next; last = last->next);
+
+ last->next = cache_info;
+
+}
+
+static struct resolv_cache*
+_find_named_cache_locked(const char* ifname) {
+
+ struct resolv_cache_info* info = _find_cache_info_locked(ifname);
+
+ if (info != NULL) return info->cache;
+
+ return NULL;
+}
+
+static struct resolv_cache_info*
+_find_cache_info_locked(const char* ifname)
+{
+ if (ifname == NULL)
+ return NULL;
+
+ struct resolv_cache_info* cache_info = _res_cache_list.next;
+
+ while (cache_info) {
+ if (strcmp(cache_info->ifname, ifname) == 0) {
+ break;
+ }
+
+ cache_info = cache_info->next;
+ }
+ return cache_info;
+}
+
+static char*
+_get_default_iface_locked(void)
+{
+ char* iface = _res_default_ifname;
+
+ return iface;
+}
+
+void
+_resolv_set_default_iface(const char* ifname)
+{
+ XLOG("_resolv_set_default_if ifname %s\n",ifname);
+
+ pthread_once(&_res_cache_once, _res_cache_init);
+ pthread_mutex_lock(&_res_cache_list_lock);
+
+ int size = sizeof(_res_default_ifname);
+ memset(_res_default_ifname, 0, size);
+ strncpy(_res_default_ifname, ifname, size - 1);
+ _res_default_ifname[size - 1] = '\0';
+
+ pthread_mutex_unlock(&_res_cache_list_lock);
+}
+
+void
+_resolv_set_nameservers_for_iface(const char* ifname, char** servers, int numservers)
+{
+ int i, rt, index;
+ struct addrinfo hints;
+ char sbuf[NI_MAXSERV];
+
+ pthread_once(&_res_cache_once, _res_cache_init);
+
+ pthread_mutex_lock(&_res_cache_list_lock);
+ // creates the cache if not created
+ _get_res_cache_for_iface_locked(ifname);
+
+ struct resolv_cache_info* cache_info = _find_cache_info_locked(ifname);
+
+ if (cache_info != NULL) {
+ // free current before adding new
+ _free_nameservers_locked(cache_info);
+
+ memset(&hints, 0, sizeof(hints));
+ hints.ai_family = PF_UNSPEC;
+ hints.ai_socktype = SOCK_DGRAM; /*dummy*/
+ hints.ai_flags = AI_NUMERICHOST;
+ sprintf(sbuf, "%u", NAMESERVER_PORT);
+
+ index = 0;
+ for (i = 0; i < numservers && i < MAXNS; i++) {
+ rt = getaddrinfo(servers[i], sbuf, &hints, &cache_info->nsaddrinfo[index]);
+ if (rt == 0) {
+ cache_info->nameservers[index] = strdup(servers[i]);
+ index++;
+ } else {
+ cache_info->nsaddrinfo[index] = NULL;
+ }
+ }
+ }
+ pthread_mutex_unlock(&_res_cache_list_lock);
+}
+
+static void
+_free_nameservers_locked(struct resolv_cache_info* cache_info)
+{
+ int i;
+ for (i = 0; i <= MAXNS; i++) {
+ free(cache_info->nameservers[i]);
+ cache_info->nameservers[i] = NULL;
+ if (cache_info->nsaddrinfo[i] != NULL) {
+ freeaddrinfo(cache_info->nsaddrinfo[i]);
+ cache_info->nsaddrinfo[i] = NULL;
+ }
+ }
+}
+
+int
+_resolv_cache_get_nameserver(int n, char* addr, int addrLen)
+{
+ char *ifname;
+ int result = 0;
+
+ pthread_once(&_res_cache_once, _res_cache_init);
+ pthread_mutex_lock(&_res_cache_list_lock);
+
+ ifname = _get_default_iface_locked();
+ result = _get_nameserver_locked(ifname, n, addr, addrLen);
+
+ pthread_mutex_unlock(&_res_cache_list_lock);
+ return result;
+}
+
+static int
+_get_nameserver_locked(const char* ifname, int n, char* addr, int addrLen)
+{
+ int len = 0;
+ char* ns;
+ struct resolv_cache_info* cache_info;
+
+ if (n < 1 || n > MAXNS || !addr)
+ return 0;
+
+ cache_info = _find_cache_info_locked(ifname);
+ if (cache_info) {
+ ns = cache_info->nameservers[n - 1];
+ if (ns) {
+ len = strlen(ns);
+ if (len < addrLen) {
+ strncpy(addr, ns, len);
+ addr[len] = '\0';
+ } else {
+ len = 0;
+ }
+ }
+ }
+
+ return len;
+}
+
+struct addrinfo*
+_cache_get_nameserver_addr(int n)
+{
+ struct addrinfo *result;
+ char* ifname;
+
+ pthread_once(&_res_cache_once, _res_cache_init);
+ pthread_mutex_lock(&_res_cache_list_lock);
+
+ ifname = _get_default_iface_locked();
+
+ result = _get_nameserver_addr_locked(ifname, n);
+ pthread_mutex_unlock(&_res_cache_list_lock);
+ return result;
+}
- pthread_mutex_lock( &_res_cache->lock );
- if (_res_cache->generation != generation) {
- _cache_flush_locked(_res_cache);
- _res_cache->generation = generation;
+static struct addrinfo*
+_get_nameserver_addr_locked(const char* ifname, int n)
+{
+ struct addrinfo* ai = NULL;
+ struct resolv_cache_info* cache_info;
+
+ if (n < 1 || n > MAXNS)
+ return NULL;
+
+ cache_info = _find_cache_info_locked(ifname);
+ if (cache_info) {
+ ai = cache_info->nsaddrinfo[n - 1];
+ }
+ return ai;
+}
+
+void
+_resolv_set_addr_of_iface(const char* ifname, struct in_addr* addr)
+{
+ pthread_once(&_res_cache_once, _res_cache_init);
+ pthread_mutex_lock(&_res_cache_list_lock);
+ struct resolv_cache_info* cache_info = _find_cache_info_locked(ifname);
+ if (cache_info) {
+ memcpy(&cache_info->ifaddr, addr, sizeof(*addr));
+
+ if (DEBUG) {
+ char* addr_s = inet_ntoa(cache_info->ifaddr);
+ XLOG("address of interface %s is %s\n", ifname, addr_s);
+ }
+ }
+ pthread_mutex_unlock(&_res_cache_list_lock);
+}
+
+struct in_addr*
+_resolv_get_addr_of_default_iface(void)
+{
+ struct in_addr* ai = NULL;
+ char* ifname;
+
+ pthread_once(&_res_cache_once, _res_cache_init);
+ pthread_mutex_lock(&_res_cache_list_lock);
+ ifname = _get_default_iface_locked();
+ ai = _get_addr_locked(ifname);
+ pthread_mutex_unlock(&_res_cache_list_lock);
+
+ return ai;
+}
+
+struct in_addr*
+_resolv_get_addr_of_iface(const char* ifname)
+{
+ struct in_addr* ai = NULL;
+
+ pthread_once(&_res_cache_once, _res_cache_init);
+ pthread_mutex_lock(&_res_cache_list_lock);
+ ai =_get_addr_locked(ifname);
+ pthread_mutex_unlock(&_res_cache_list_lock);
+ return ai;
+}
+
+static struct in_addr*
+_get_addr_locked(const char * ifname)
+{
+ struct resolv_cache_info* cache_info = _find_cache_info_locked(ifname);
+ if (cache_info) {
+ return &cache_info->ifaddr;
}
- pthread_mutex_unlock( &_res_cache->lock );
+ return NULL;
}
diff --git a/libc/netbsd/resolv/res_init.c b/libc/netbsd/resolv/res_init.c
index 81e570f77..1cdfc534a 100644
--- a/libc/netbsd/resolv/res_init.c
+++ b/libc/netbsd/resolv/res_init.c
@@ -225,6 +225,9 @@ __res_vinit(res_state statp, int preinit) {
char dnsProperty[PROP_VALUE_MAX];
#endif
+ if ((statp->options & RES_INIT) != 0U)
+ res_ndestroy(statp);
+
if (!preinit) {
statp->retrans = RES_TIMEOUT;
statp->retry = RES_DFLRETRY;
@@ -232,9 +235,6 @@ __res_vinit(res_state statp, int preinit) {
statp->id = res_randomid();
}
- if ((statp->options & RES_INIT) != 0U)
- res_ndestroy(statp);
-
memset(u, 0, sizeof(u));
#ifdef USELOOPBACK
u[nserv].sin.sin_addr = inet_makeaddr(IN_LOOPBACKNET, 1);
diff --git a/libc/netbsd/resolv/res_send.c b/libc/netbsd/resolv/res_send.c
index 696f8cfeb..94ba9693f 100644
--- a/libc/netbsd/resolv/res_send.c
+++ b/libc/netbsd/resolv/res_send.c
@@ -413,7 +413,7 @@ res_nsend(res_state statp,
if (EXT(statp).nssocks[ns] == -1)
continue;
peerlen = sizeof(peer);
- if (getsockname(EXT(statp).nssocks[ns],
+ if (getpeername(EXT(statp).nssocks[ns],
(struct sockaddr *)(void *)&peer, &peerlen) < 0) {
needclose++;
break;
diff --git a/libc/netbsd/resolv/res_state.c b/libc/netbsd/resolv/res_state.c
index 3a2301d2e..94c62bfc9 100644
--- a/libc/netbsd/resolv/res_state.c
+++ b/libc/netbsd/resolv/res_state.c
@@ -38,21 +38,32 @@
#define _REALLY_INCLUDE_SYS__SYSTEM_PROPERTIES_H_
#include <sys/_system_properties.h>
+/* Set to 1 to enable debug traces */
+#define DEBUG 0
+
+#if DEBUG
+# include <logd.h>
+# include <unistd.h> /* for gettid() */
+# define D(...) __libc_android_log_print(ANDROID_LOG_DEBUG,"libc", __VA_ARGS__)
+#else
+# define D(...) do{}while(0)
+#endif
+
static pthread_key_t _res_key;
static pthread_once_t _res_once;
typedef struct {
- int _h_errno;
- struct __res_state _nres[1];
- unsigned _serial;
- struct prop_info* _pi;
- struct res_static _rstatic[1];
+ int _h_errno;
+ struct __res_state _nres[1];
+ unsigned _serial;
+ struct prop_info* _pi;
+ struct res_static _rstatic[1];
} _res_thread;
static _res_thread*
_res_thread_alloc(void)
{
- _res_thread* rt = malloc(sizeof(*rt));
+ _res_thread* rt = calloc(1, sizeof(*rt));
if (rt) {
rt->_h_errno = 0;
@@ -62,12 +73,7 @@ _res_thread_alloc(void)
if (rt->_pi) {
rt->_serial = rt->_pi->serial;
}
- if ( res_ninit( rt->_nres ) < 0 ) {
- free(rt);
- rt = NULL;
- } else {
- memset(rt->_rstatic, 0, sizeof rt->_rstatic);
- }
+ memset(rt->_rstatic, 0, sizeof rt->_rstatic);
}
return rt;
}
@@ -91,6 +97,8 @@ _res_thread_free( void* _rt )
{
_res_thread* rt = _rt;
+ D("%s: rt=%p for thread=%d", __FUNCTION__, rt, gettid());
+
_res_static_done(rt->_rstatic);
res_ndestroy(rt->_nres);
free(rt);
@@ -108,29 +116,60 @@ _res_thread_get(void)
_res_thread* rt;
pthread_once( &_res_once, _res_init_key );
rt = pthread_getspecific( _res_key );
- if (rt == NULL) {
- if ((rt = _res_thread_alloc()) == NULL) {
- return NULL;
+
+ if (rt != NULL) {
+ /* We already have one thread-specific DNS state object.
+ * Check the serial value for any changes to net.* properties */
+ D("%s: Called for tid=%d rt=%p rt->pi=%p rt->serial=%d",
+ __FUNCTION__, gettid(), rt, rt->_pi, rt->_serial);
+ if (rt->_pi == NULL) {
+ /* The property wasn't created when _res_thread_get() was
+ * called the last time. This should only happen very
+ * early during the boot sequence. First, let's try to see if it
+ * is here now. */
+ rt->_pi = (struct prop_info*) __system_property_find("net.change");
+ if (rt->_pi == NULL) {
+ /* Still nothing, return current state */
+ D("%s: exiting for tid=%d rt=%d since system property not found",
+ __FUNCTION__, gettid(), rt);
+ return rt;
+ }
}
- rt->_h_errno = 0;
- rt->_serial = 0;
- pthread_setspecific( _res_key, rt );
- }
- /* Check the serial value for any chanes to net.* properties. */
- if (rt->_pi == NULL) {
- rt->_pi = (struct prop_info*) __system_property_find("net.change");
+ if (rt->_serial == rt->_pi->serial) {
+ /* Nothing changed, so return the current state */
+ D("%s: tid=%d rt=%p nothing changed, returning",
+ __FUNCTION__, gettid(), rt);
+ return rt;
+ }
+ /* Update the recorded serial number, and go reset the state */
+ rt->_serial = rt->_pi->serial;
+ goto RESET_STATE;
}
- if (rt->_pi == NULL || rt->_serial == rt->_pi->serial) {
- return rt;
+
+ /* It is the first time this function is called in this thread,
+ * we need to create a new thread-specific DNS resolver state. */
+ rt = _res_thread_alloc();
+ if (rt == NULL) {
+ return NULL;
}
- rt->_serial = rt->_pi->serial;
- /* Reload from system properties. */
+ pthread_setspecific( _res_key, rt );
+ D("%s: tid=%d Created new DNS state rt=%p",
+ __FUNCTION__, gettid(), rt);
+
+RESET_STATE:
+ /* Reset the state, note that res_ninit() can now properly reset
+ * an existing state without leaking memory.
+ */
+ D("%s: tid=%d, rt=%p, resetting DNS state (options RES_INIT=%d)",
+ __FUNCTION__, gettid(), rt, (rt->_nres->options & RES_INIT) != 0);
if ( res_ninit( rt->_nres ) < 0 ) {
- free(rt);
- rt = NULL;
- pthread_setspecific( _res_key, rt );
+ /* This should not happen */
+ D("%s: tid=%d rt=%p, woot, res_ninit() returned < 0",
+ __FUNCTION__, gettid(), rt);
+ _res_thread_free(rt);
+ pthread_setspecific( _res_key, NULL );
+ return NULL;
}
- _resolv_cache_reset(rt->_serial);
return rt;
}
diff --git a/libc/private/bionic_tls.h b/libc/private/bionic_tls.h
index 008fd2ff7..94a81cd51 100644
--- a/libc/private/bionic_tls.h
+++ b/libc/private/bionic_tls.h
@@ -111,6 +111,12 @@ extern int __set_tls(void *ptr);
* Note that HAVE_ARM_TLS_REGISTER is build-specific
* (it must match your kernel configuration)
*/
+# ifdef HAVE_TEGRA_ERRATA_657451
+# define __munge_tls(_v) ( ((_v)&~((1ul<<20)|1ul)) | (((_v)&0x1)<<20) )
+# else
+# define __munge_tls(_v) (_v)
+#endif
+
# ifdef HAVE_ARM_TLS_REGISTER
/* We can read the address directly from a coprocessor
* register, which avoids touching the data cache
@@ -119,6 +125,7 @@ extern int __set_tls(void *ptr);
# define __get_tls() \
({ register unsigned int __val asm("r0"); \
asm ("mrc p15, 0, r0, c13, c0, 3" : "=r"(__val) ); \
+ __val = __munge_tls(__val); \
(volatile void*)__val; })
# else /* !HAVE_ARM_TLS_REGISTER */
/* The kernel provides the address of the TLS at a fixed
diff --git a/libc/private/resolv_cache.h b/libc/private/resolv_cache.h
index cd876fb28..2a5445355 100644
--- a/libc/private/resolv_cache.h
+++ b/libc/private/resolv_cache.h
@@ -30,13 +30,45 @@
struct resolv_cache; /* forward */
-/* get cache instance, can be NULL if cache is disabled
- * (e.g. through an environment variable) */
+/* gets the cache for the default interface. Might be NULL*/
extern struct resolv_cache* __get_res_cache(void);
+/* get the cache for a specified interface. Can be NULL*/
+extern struct resolv_cache* __get_res_cache_for_iface(const char* ifname);
+
/* this gets called everytime we detect some changes in the DNS configuration
* and will flush the cache */
-extern void _resolv_cache_reset( unsigned generation );
+extern void _resolv_cache_reset( unsigned generation );
+
+/* Gets the address of the n:th name server for the default interface
+ * Return length of address on success else 0.
+ * Note: The first name server is at n = 1 */
+extern int _resolv_cache_get_nameserver(int n, char* addr, int addrLen);
+
+/* Gets the address of the n:th name server for a certain interface
+ * Return length of address on success else 0.
+ * Note: The first name server is at n = 1 */
+extern int _resolv_cache_get_nameserver_for_iface(const char* ifname, int n,
+ char* addr, int addrLen);
+
+/* Gets addrinfo of the n:th name server associated with an interface.
+ * NULL is returned if no address if found.
+ * Note: The first name server is at n = 1. */
+extern struct addrinfo* _resolv_cache_get_nameserver_addr_for_iface(const char* ifname, int n);
+
+/* Gets addrinfo of the n:th name server associated with the default interface
+ * NULL is returned if no address if found.
+ * Note: The first name server is at n = 1. */
+extern struct addrinfo* _resolv_cache_get_nameserver_addr(int n);
+
+/* gets the address associated with the default interface */
+extern struct in_addr* _resolv_get_addr_of_default_iface();
+
+/* gets the address associated with the specified interface */
+extern struct in_addr* _resolv_get_addr_of_iface(const char* ifname);
+
+/* Get name of default interface */
+extern char* _resolv_get_default_iface();
typedef enum {
RESOLV_CACHE_UNSUPPORTED, /* the cache can't handle that kind of queries */
diff --git a/libc/stdio/wcio.h b/libc/stdio/wcio.h
index f8ac1b21e..dd6db21a0 100644
--- a/libc/stdio/wcio.h
+++ b/libc/stdio/wcio.h
@@ -41,7 +41,7 @@ struct wchar_io_data {
/* BIONIC: disable wchar support */
#define WCIO_GET(fp) \
- ((struct whcar_io_data*) 0)
+ ((struct wchar_io_data*) 0)
#define _SET_ORIENTATION(fp, mode) ((void)0)
diff --git a/libc/string/memmove.c b/libc/string/memmove.c
index 98ecfc90b..072104b6c 100644
--- a/libc/string/memmove.c
+++ b/libc/string/memmove.c
@@ -26,6 +26,7 @@
* SUCH DAMAGE.
*/
#include <string.h>
+#include <strings.h>
void *memmove(void *dst, const void *src, size_t n)
{
@@ -37,39 +38,7 @@ void *memmove(void *dst, const void *src, size_t n)
if (__builtin_expect((q < p) || ((size_t)(q - p) >= n), 1)) {
return memcpy(dst, src, n);
} else {
-#define PRELOAD_DISTANCE 64
- /* a semi-optimized memmove(). we're preloading the src and dst buffers
- * as we go */
- size_t c0, c1, i;
- p += n;
- q += n;
- /* note: we preload the destination as well, because the 1-byte at a time
- * copy below doesn't take advantage of the write-buffer, we need
- * to use the cache instead as a poor man's write-combiner */
- __builtin_prefetch(p-1);
- __builtin_prefetch(q-1);
- if (PRELOAD_DISTANCE > 32) {
- __builtin_prefetch(p-(32+1));
- __builtin_prefetch(q-(32+1));
- }
- /* do the prefetech as soon as possible, prevent the compiler to
- * reorder the instructions above the prefetch */
- asm volatile("":::"memory");
- c0 = n & 0x1F; /* cache-line is 32 bytes */
- c1 = n >> 5;
- while ( c1-- ) {
- /* ARMv6 can have up to 3 memory access outstanding */
- __builtin_prefetch(p - (PRELOAD_DISTANCE+1));
- __builtin_prefetch(q - (PRELOAD_DISTANCE+1));
- asm volatile("":::"memory");
- for (i=0 ; i<32 ; i++) {
- *--q = *--p;
- }
- }
- while ( c0-- ) {
- *--q = *--p;
- }
+ bcopy(src, dst, n);
+ return dst;
}
-
- return dst;
}
diff --git a/libc/tools/checksyscalls.py b/libc/tools/checksyscalls.py
index 9edb39044..f6182f368 100755
--- a/libc/tools/checksyscalls.py
+++ b/libc/tools/checksyscalls.py
@@ -132,10 +132,10 @@ if not os.path.exists(arm_unistd):
# with two distinct unistd_32.h and unistd_64.h definition files.
# take care of this here
#
-x86_unistd = linux_root + "/include/asm-i386/unistd.h"
+x86_unistd = linux_root + "/include/asm-i386/unistd_32.h"
if not os.path.exists(x86_unistd):
x86_unistd1 = x86_unistd
- x86_unistd = linux_root + "/include/asm-x86/unistd_32.h"
+ x86_unistd = linux_root + "/include/asm-x86/unistd.h"
if not os.path.exists(x86_unistd):
print "WEIRD: could not locate the i386/x86 unistd.h header file"
print "tried searching in '%s' and '%s'" % (x86_unistd1, x86_unistd)
diff --git a/libc/unistd/exec.c b/libc/unistd/exec.c
index cbb98b366..89396ac31 100644
--- a/libc/unistd/exec.c
+++ b/libc/unistd/exec.c
@@ -194,9 +194,9 @@ execvp(const char *name, char * const *argv)
(void)writev(STDERR_FILENO, iov, 3);
continue;
}
- bcopy(p, buf, lp);
+ memcpy(buf, p, lp);
buf[lp] = '/';
- bcopy(name, buf + lp + 1, ln);
+ memcpy(buf + lp + 1, name, ln);
buf[lp + ln + 1] = '\0';
retry: (void)execve(bp, argv, environ);
@@ -216,7 +216,7 @@ retry: (void)execve(bp, argv, environ);
goto done;
memp[0] = "sh";
memp[1] = bp;
- bcopy(argv + 1, memp + 2, cnt * sizeof(char *));
+ memcpy(memp + 2, argv + 1, cnt * sizeof(char *));
(void)execve(_PATH_BSHELL, memp, environ);
goto done;
case ENOMEM:
diff --git a/libc/unistd/raise.c b/libc/unistd/raise.c
index de099da25..d15bcdf96 100644
--- a/libc/unistd/raise.c
+++ b/libc/unistd/raise.c
@@ -27,8 +27,9 @@
*/
#include <unistd.h>
#include <signal.h>
+#include <pthread.h>
int raise(int signum)
{
- return kill(getpid(), signum);
+ return pthread_kill(pthread_self(), signum);
}