resolved conflicts for merge of 50a83255 to gingerbread-plus-aosp
Change-Id: Idf1971120bbdd52676f95aa3aa69f62342dc012e
diff --git a/libc/Android.mk b/libc/Android.mk
index aae80da..65c49ac 100644
--- a/libc/Android.mk
+++ b/libc/Android.mk
@@ -187,7 +187,6 @@
string/strcat.c \
string/strchr.c \
string/strcoll.c \
- string/strcpy.c \
string/strcspn.c \
string/strdup.c \
string/strerror.c \
@@ -230,6 +229,7 @@
wchar/wcsstr.c \
wchar/wcstok.c \
wchar/wcswidth.c \
+ wchar/wcsxfrm.c \
wchar/wmemchr.c \
wchar/wmemcmp.c \
wchar/wmemcpy.c \
@@ -241,13 +241,14 @@
inet/inet_ntoa.c \
inet/inet_ntop.c \
inet/inet_pton.c \
+ inet/ether_aton.c \
+ inet/ether_ntoa.c \
tzcode/asctime.c \
tzcode/difftime.c \
tzcode/localtime.c \
tzcode/strftime.c \
tzcode/strptime.c \
bionic/__set_errno.c \
- bionic/_rand48.c \
bionic/cpuacct.c \
bionic/arc4random.c \
bionic/basename.c \
@@ -270,6 +271,10 @@
bionic/md5.c \
bionic/pututline.c \
bionic/realpath.c \
+ bionic/sched_getaffinity.c \
+ bionic/sched_getcpu.c \
+ bionic/sched_cpualloc.c \
+ bionic/sched_cpucount.c \
bionic/semaphore.c \
bionic/sha1.c \
bionic/ssp.c \
@@ -354,10 +359,11 @@
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
@@ -365,6 +371,7 @@
# can set breakpoints in them without messing
# up any thumb code.
libc_common_src_files += \
+ bionic/pthread-atfork.c.arm \
bionic/pthread-rwlocks.c.arm \
bionic/pthread-timers.c.arm \
bionic/ptrace.c.arm
@@ -391,6 +398,7 @@
arch-x86/bionic/_exit_with_stack_teardown.S \
arch-x86/bionic/setjmp.S \
arch-x86/bionic/_setjmp.S \
+ arch-x86/bionic/sigsetjmp.S \
arch-x86/bionic/vfork.S \
arch-x86/bionic/syscall.S \
arch-x86/string/bcopy_wrapper.S \
@@ -402,6 +410,8 @@
arch-x86/string/strcmp_wrapper.S \
arch-x86/string/strncmp_wrapper.S \
arch-x86/string/strlen_wrapper.S \
+ string/strcpy.c \
+ bionic/pthread-atfork.c \
bionic/pthread-rwlocks.c \
bionic/pthread-timers.c \
bionic/ptrace.c
@@ -441,6 +451,8 @@
string/strncmp.c \
string/memcmp.c \
string/strlen.c \
+ string/strcpy.c \
+ bionic/pthread-atfork.c \
bionic/pthread-rwlocks.c \
bionic/pthread-timers.c \
bionic/ptrace.c \
@@ -467,7 +479,8 @@
-DINET6 \
-I$(LOCAL_PATH)/private \
-DUSE_DL_PREFIX \
- -DPOSIX_MISTAKE
+ -DPOSIX_MISTAKE \
+ -DLOG_ON_HEAP_ERROR \
# these macro definitions are required to implement the
# 'timezone' and 'daylight' global variables, as well as
@@ -527,6 +540,10 @@
$(LOCAL_PATH)/string \
$(LOCAL_PATH)/stdio
+# Needed to access private/__dso_handle.S from
+# crtbegin_xxx.S and crtend_xxx.S
+#
+libc_crt_target_cflags += -I$(LOCAL_PATH)/private
# Define the libc run-time (crt) support object files that must be built,
# which are needed to build all other objects (shared/static libs and
diff --git a/libc/NOTICE b/libc/NOTICE
index e8076b5..d9e6818 100644
--- a/libc/NOTICE
+++ b/libc/NOTICE
@@ -1,5 +1,5 @@
-Copyright (c) 2005-2008, The Android Open Source Project
+Copyright (c) 2005-2010, The Android Open Source Project
All rights reserved.
Redistribution and use in source and binary forms, with or without
diff --git a/libc/SYSCALLS.TXT b/libc/SYSCALLS.TXT
index 0850b82..356f69b 100644
--- a/libc/SYSCALLS.TXT
+++ b/libc/SYSCALLS.TXT
@@ -76,6 +76,8 @@
pid_t vfork(void) 190,-1,190
int setregid:setregid32(gid_t, gid_t) 204
int chroot(const char *) 61
+# IMPORTANT: Even though <sys/prctl.h> declares prctl(int,...), the syscall stub must take 6 arguments
+# to match the kernel implementation.
int prctl(int option, unsigned int arg2, unsigned int arg3, unsigned int arg4, unsigned int arg5) 172
int capget(cap_user_header_t header, cap_user_data_t data) 184
int capset(cap_user_header_t header, const cap_user_data_t data) 185
@@ -85,8 +87,8 @@
# file descriptors
ssize_t read (int, void*, size_t) 3
ssize_t write (int, const void*, size_t) 4
-ssize_t __pread64:pread64 (int, void *, size_t, off_t, off_t) 180
-ssize_t __pwrite64:pwrite64 (int, void *, size_t, off_t, off_t) 181
+ssize_t pread64 (int, void *, size_t, off64_t) 180
+ssize_t pwrite64 (int, void *, size_t, off64_t) 181
int __open:open (const char*, int, mode_t) 5
int __openat:openat (int, const char*, int, mode_t) 322,295
int close (int) 6
@@ -116,6 +118,7 @@
int dup2(int, int) 63
int select:_newselect(int, struct fd_set *, struct fd_set *, struct fd_set *, struct timeval *) 142
int ftruncate(int, off_t) 93
+int ftruncate64(int, off64_t) 194
int getdents:getdents64(unsigned int, struct dirent *, unsigned int) 217,220
int fsync(int) 118
int fdatasync(int) 148
@@ -229,6 +232,9 @@
int sched_get_priority_max(int policy) 159
int sched_get_priority_min(int policy) 160
int sched_rr_get_interval(pid_t pid, struct timespec *interval) 161
+int sched_setaffinity(pid_t pid, size_t setsize, const cpu_set_t* set) 241
+int __sched_getaffinity:sched_getaffinity(pid_t pid, size_t setsize, cpu_set_t* set) 242
+int __getcpu:getcpu(unsigned *cpu, unsigned *node, void *unused) 345,318,318
# io priorities
int ioprio_set(int which, int who, int ioprio) 314,289,288
diff --git a/libc/arch-arm/bionic/strcmp.S b/libc/arch-arm/bionic/strcmp.S
new file mode 100644
index 0000000..9fdbd56
--- /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 0000000..70c353f
--- /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 04204ed..6de0889 100644
--- a/libc/arch-arm/include/endian.h
+++ b/libc/arch-arm/include/endian.h
@@ -1,10 +1,89 @@
/* $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__
+
+/*
+ * REV and REV16 weren't available on ARM5 or ARM4.
+ * We don't include <machine/cpu-features.h> because it pollutes the
+ * namespace with macros like PLD.
+ */
+#if !defined __ARM_ARCH_5__ && !defined __ARM_ARCH_5T__ && \
+ !defined __ARM_ARCH_5TE__ && !defined __ARM_ARCH_5TEJ__ && \
+ !defined __ARM_ARCH_4T__ && !defined __ARM_ARCH_4__
+
+/* 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.
+ *
+ * The +l constraint takes care of this without constraining us in ARM mode.
+ */
+#define __swap16md(x) ({ \
+ register u_int16_t _x = (x); \
+ __asm volatile ("rev16 %0, %0" : "+l" (_x)); \
+ _x; \
+})
+
+#define __swap32md(x) ({ \
+ register u_int32_t _x = (x); \
+ __asm volatile ("rev %0, %0" : "+l" (_x)); \
+ _x; \
+})
+
+#define __swap64md(x) ({ \
+ u_int64_t _swap64md_x = (x); \
+ (u_int64_t) __swap32md(_swap64md_x >> 32) | \
+ (u_int64_t) __swap32md(_swap64md_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
#define _BYTE_ORDER _LITTLE_ENDIAN
#endif
-#define __STRICT_ALIGNMENT
+#define __STRICT_ALIGNMENT
#include <sys/types.h>
#include <sys/endian.h>
+
+#endif /* !_ARM_ENDIAN_H_ */
diff --git a/libc/arch-arm/include/machine/cpu-features.h b/libc/arch-arm/include/machine/cpu-features.h
index 39c1db3..80d3fda 100644
--- a/libc/arch-arm/include/machine/cpu-features.h
+++ b/libc/arch-arm/include/machine/cpu-features.h
@@ -185,6 +185,7 @@
#endif
/* Assembly-only macros */
+#ifdef __ASSEMBLY__
/* define a handy PLD(address) macro since the cache preload
* is an optional opcode
@@ -195,4 +196,6 @@
# define PLD(reg,offset) /* nothing */
#endif
+#endif /* ! __ASSEMBLY__ */
+
#endif /* _ARM_MACHINE_CPU_FEATURES_H */
diff --git a/libc/arch-arm/syscalls.mk b/libc/arch-arm/syscalls.mk
index ba78c18..5210d6c 100644
--- a/libc/arch-arm/syscalls.mk
+++ b/libc/arch-arm/syscalls.mk
@@ -41,8 +41,8 @@
syscall_src += arch-arm/syscalls/acct.S
syscall_src += arch-arm/syscalls/read.S
syscall_src += arch-arm/syscalls/write.S
-syscall_src += arch-arm/syscalls/__pread64.S
-syscall_src += arch-arm/syscalls/__pwrite64.S
+syscall_src += arch-arm/syscalls/pread64.S
+syscall_src += arch-arm/syscalls/pwrite64.S
syscall_src += arch-arm/syscalls/__open.S
syscall_src += arch-arm/syscalls/__openat.S
syscall_src += arch-arm/syscalls/close.S
@@ -70,6 +70,7 @@
syscall_src += arch-arm/syscalls/dup2.S
syscall_src += arch-arm/syscalls/select.S
syscall_src += arch-arm/syscalls/ftruncate.S
+syscall_src += arch-arm/syscalls/ftruncate64.S
syscall_src += arch-arm/syscalls/getdents.S
syscall_src += arch-arm/syscalls/fsync.S
syscall_src += arch-arm/syscalls/fdatasync.S
@@ -153,6 +154,9 @@
syscall_src += arch-arm/syscalls/sched_get_priority_max.S
syscall_src += arch-arm/syscalls/sched_get_priority_min.S
syscall_src += arch-arm/syscalls/sched_rr_get_interval.S
+syscall_src += arch-arm/syscalls/sched_setaffinity.S
+syscall_src += arch-arm/syscalls/__sched_getaffinity.S
+syscall_src += arch-arm/syscalls/__getcpu.S
syscall_src += arch-arm/syscalls/ioprio_set.S
syscall_src += arch-arm/syscalls/ioprio_get.S
syscall_src += arch-arm/syscalls/uname.S
diff --git a/libc/arch-arm/syscalls/__getcpu.S b/libc/arch-arm/syscalls/__getcpu.S
new file mode 100644
index 0000000..ed6927a
--- /dev/null
+++ b/libc/arch-arm/syscalls/__getcpu.S
@@ -0,0 +1,19 @@
+/* autogenerated by gensyscalls.py */
+#include <sys/linux-syscalls.h>
+
+ .text
+ .type __getcpu, #function
+ .globl __getcpu
+ .align 4
+ .fnstart
+
+__getcpu:
+ .save {r4, r7}
+ stmfd sp!, {r4, r7}
+ ldr r7, =__NR_getcpu
+ swi #0
+ ldmfd sp!, {r4, r7}
+ movs r0, r0
+ bxpl lr
+ b __set_syscall_errno
+ .fnend
diff --git a/libc/arch-arm/syscalls/__sched_getaffinity.S b/libc/arch-arm/syscalls/__sched_getaffinity.S
new file mode 100644
index 0000000..71f2b1d
--- /dev/null
+++ b/libc/arch-arm/syscalls/__sched_getaffinity.S
@@ -0,0 +1,19 @@
+/* autogenerated by gensyscalls.py */
+#include <sys/linux-syscalls.h>
+
+ .text
+ .type __sched_getaffinity, #function
+ .globl __sched_getaffinity
+ .align 4
+ .fnstart
+
+__sched_getaffinity:
+ .save {r4, r7}
+ stmfd sp!, {r4, r7}
+ ldr r7, =__NR_sched_getaffinity
+ swi #0
+ ldmfd sp!, {r4, r7}
+ movs r0, r0
+ bxpl lr
+ b __set_syscall_errno
+ .fnend
diff --git a/libc/arch-arm/syscalls/ftruncate64.S b/libc/arch-arm/syscalls/ftruncate64.S
new file mode 100644
index 0000000..37b4744
--- /dev/null
+++ b/libc/arch-arm/syscalls/ftruncate64.S
@@ -0,0 +1,19 @@
+/* autogenerated by gensyscalls.py */
+#include <sys/linux-syscalls.h>
+
+ .text
+ .type ftruncate64, #function
+ .globl ftruncate64
+ .align 4
+ .fnstart
+
+ftruncate64:
+ .save {r4, r7}
+ stmfd sp!, {r4, r7}
+ ldr r7, =__NR_ftruncate64
+ swi #0
+ ldmfd sp!, {r4, r7}
+ movs r0, r0
+ bxpl lr
+ b __set_syscall_errno
+ .fnend
diff --git a/libc/arch-arm/syscalls/__pread64.S b/libc/arch-arm/syscalls/pread64.S
similarity index 85%
rename from libc/arch-arm/syscalls/__pread64.S
rename to libc/arch-arm/syscalls/pread64.S
index ea645e1..a54084c 100644
--- a/libc/arch-arm/syscalls/__pread64.S
+++ b/libc/arch-arm/syscalls/pread64.S
@@ -2,12 +2,12 @@
#include <sys/linux-syscalls.h>
.text
- .type __pread64, #function
- .globl __pread64
+ .type pread64, #function
+ .globl pread64
.align 4
.fnstart
-__pread64:
+pread64:
mov ip, sp
.save {r4, r5, r6, r7}
stmfd sp!, {r4, r5, r6, r7}
diff --git a/libc/arch-arm/syscalls/__pwrite64.S b/libc/arch-arm/syscalls/pwrite64.S
similarity index 85%
rename from libc/arch-arm/syscalls/__pwrite64.S
rename to libc/arch-arm/syscalls/pwrite64.S
index d1263be..f9d56b2 100644
--- a/libc/arch-arm/syscalls/__pwrite64.S
+++ b/libc/arch-arm/syscalls/pwrite64.S
@@ -2,12 +2,12 @@
#include <sys/linux-syscalls.h>
.text
- .type __pwrite64, #function
- .globl __pwrite64
+ .type pwrite64, #function
+ .globl pwrite64
.align 4
.fnstart
-__pwrite64:
+pwrite64:
mov ip, sp
.save {r4, r5, r6, r7}
stmfd sp!, {r4, r5, r6, r7}
diff --git a/libc/arch-arm/syscalls/sched_setaffinity.S b/libc/arch-arm/syscalls/sched_setaffinity.S
new file mode 100644
index 0000000..aedf8f3
--- /dev/null
+++ b/libc/arch-arm/syscalls/sched_setaffinity.S
@@ -0,0 +1,19 @@
+/* autogenerated by gensyscalls.py */
+#include <sys/linux-syscalls.h>
+
+ .text
+ .type sched_setaffinity, #function
+ .globl sched_setaffinity
+ .align 4
+ .fnstart
+
+sched_setaffinity:
+ .save {r4, r7}
+ stmfd sp!, {r4, r7}
+ ldr r7, =__NR_sched_setaffinity
+ swi #0
+ ldmfd sp!, {r4, r7}
+ movs r0, r0
+ bxpl lr
+ b __set_syscall_errno
+ .fnend
diff --git a/libc/arch-sh/syscalls.mk b/libc/arch-sh/syscalls.mk
index a87419d..9575905 100644
--- a/libc/arch-sh/syscalls.mk
+++ b/libc/arch-sh/syscalls.mk
@@ -45,8 +45,8 @@
syscall_src += arch-sh/syscalls/acct.S
syscall_src += arch-sh/syscalls/read.S
syscall_src += arch-sh/syscalls/write.S
-syscall_src += arch-sh/syscalls/__pread64.S
-syscall_src += arch-sh/syscalls/__pwrite64.S
+syscall_src += arch-sh/syscalls/pread64.S
+syscall_src += arch-sh/syscalls/pwrite64.S
syscall_src += arch-sh/syscalls/__open.S
syscall_src += arch-sh/syscalls/__openat.S
syscall_src += arch-sh/syscalls/close.S
@@ -73,6 +73,7 @@
syscall_src += arch-sh/syscalls/dup2.S
syscall_src += arch-sh/syscalls/select.S
syscall_src += arch-sh/syscalls/ftruncate.S
+syscall_src += arch-sh/syscalls/ftruncate64.S
syscall_src += arch-sh/syscalls/getdents.S
syscall_src += arch-sh/syscalls/fsync.S
syscall_src += arch-sh/syscalls/fdatasync.S
@@ -142,6 +143,9 @@
syscall_src += arch-sh/syscalls/sched_get_priority_max.S
syscall_src += arch-sh/syscalls/sched_get_priority_min.S
syscall_src += arch-sh/syscalls/sched_rr_get_interval.S
+syscall_src += arch-sh/syscalls/sched_setaffinity.S
+syscall_src += arch-sh/syscalls/__sched_getaffinity.S
+syscall_src += arch-sh/syscalls/__getcpu.S
syscall_src += arch-sh/syscalls/ioprio_set.S
syscall_src += arch-sh/syscalls/ioprio_get.S
syscall_src += arch-sh/syscalls/uname.S
diff --git a/libc/arch-sh/syscalls/__pwrite64.S b/libc/arch-sh/syscalls/__getcpu.S
similarity index 63%
copy from libc/arch-sh/syscalls/__pwrite64.S
copy to libc/arch-sh/syscalls/__getcpu.S
index a722242..125387b 100644
--- a/libc/arch-sh/syscalls/__pwrite64.S
+++ b/libc/arch-sh/syscalls/__getcpu.S
@@ -2,22 +2,19 @@
#include <sys/linux-syscalls.h>
.text
- .type __pwrite64, @function
- .globl __pwrite64
+ .type __getcpu, @function
+ .globl __getcpu
.align 4
-__pwrite64:
-
- /* get ready for additonal arg */
- mov.l @r15, r0
+__getcpu:
/* invoke trap */
mov.l 0f, r3 /* trap num */
- trapa #(5 + 0x10)
+ trapa #(3 + 0x10)
/* check return value */
cmp/pz r0
- bt __NR_pwrite64_end
+ bt __NR_getcpu_end
/* keep error number */
sts.l pr, @-r15
@@ -26,10 +23,10 @@
mov r0, r4
lds.l @r15+, pr
-__NR_pwrite64_end:
+__NR_getcpu_end:
rts
nop
.align 2
-0: .long __NR_pwrite64
+0: .long __NR_getcpu
1: .long __set_syscall_errno
diff --git a/libc/arch-sh/syscalls/__pwrite64.S b/libc/arch-sh/syscalls/__sched_getaffinity.S
similarity index 63%
copy from libc/arch-sh/syscalls/__pwrite64.S
copy to libc/arch-sh/syscalls/__sched_getaffinity.S
index a722242..7e8be6a 100644
--- a/libc/arch-sh/syscalls/__pwrite64.S
+++ b/libc/arch-sh/syscalls/__sched_getaffinity.S
@@ -2,22 +2,19 @@
#include <sys/linux-syscalls.h>
.text
- .type __pwrite64, @function
- .globl __pwrite64
+ .type __sched_getaffinity, @function
+ .globl __sched_getaffinity
.align 4
-__pwrite64:
-
- /* get ready for additonal arg */
- mov.l @r15, r0
+__sched_getaffinity:
/* invoke trap */
mov.l 0f, r3 /* trap num */
- trapa #(5 + 0x10)
+ trapa #(3 + 0x10)
/* check return value */
cmp/pz r0
- bt __NR_pwrite64_end
+ bt __NR_sched_getaffinity_end
/* keep error number */
sts.l pr, @-r15
@@ -26,10 +23,10 @@
mov r0, r4
lds.l @r15+, pr
-__NR_pwrite64_end:
+__NR_sched_getaffinity_end:
rts
nop
.align 2
-0: .long __NR_pwrite64
+0: .long __NR_sched_getaffinity
1: .long __set_syscall_errno
diff --git a/libc/arch-sh/syscalls/__pwrite64.S b/libc/arch-sh/syscalls/ftruncate64.S
similarity index 63%
copy from libc/arch-sh/syscalls/__pwrite64.S
copy to libc/arch-sh/syscalls/ftruncate64.S
index a722242..f4c7c1e 100644
--- a/libc/arch-sh/syscalls/__pwrite64.S
+++ b/libc/arch-sh/syscalls/ftruncate64.S
@@ -2,22 +2,19 @@
#include <sys/linux-syscalls.h>
.text
- .type __pwrite64, @function
- .globl __pwrite64
+ .type ftruncate64, @function
+ .globl ftruncate64
.align 4
-__pwrite64:
-
- /* get ready for additonal arg */
- mov.l @r15, r0
+ftruncate64:
/* invoke trap */
mov.l 0f, r3 /* trap num */
- trapa #(5 + 0x10)
+ trapa #(3 + 0x10)
/* check return value */
cmp/pz r0
- bt __NR_pwrite64_end
+ bt __NR_ftruncate64_end
/* keep error number */
sts.l pr, @-r15
@@ -26,10 +23,10 @@
mov r0, r4
lds.l @r15+, pr
-__NR_pwrite64_end:
+__NR_ftruncate64_end:
rts
nop
.align 2
-0: .long __NR_pwrite64
+0: .long __NR_ftruncate64
1: .long __set_syscall_errno
diff --git a/libc/arch-sh/syscalls/__pread64.S b/libc/arch-sh/syscalls/pread64.S
similarity index 89%
rename from libc/arch-sh/syscalls/__pread64.S
rename to libc/arch-sh/syscalls/pread64.S
index 474add3..702a402 100644
--- a/libc/arch-sh/syscalls/__pread64.S
+++ b/libc/arch-sh/syscalls/pread64.S
@@ -2,11 +2,11 @@
#include <sys/linux-syscalls.h>
.text
- .type __pread64, @function
- .globl __pread64
+ .type pread64, @function
+ .globl pread64
.align 4
-__pread64:
+pread64:
/* get ready for additonal arg */
mov.l @r15, r0
diff --git a/libc/arch-sh/syscalls/__pwrite64.S b/libc/arch-sh/syscalls/pwrite64.S
similarity index 89%
rename from libc/arch-sh/syscalls/__pwrite64.S
rename to libc/arch-sh/syscalls/pwrite64.S
index a722242..3f6c192 100644
--- a/libc/arch-sh/syscalls/__pwrite64.S
+++ b/libc/arch-sh/syscalls/pwrite64.S
@@ -2,11 +2,11 @@
#include <sys/linux-syscalls.h>
.text
- .type __pwrite64, @function
- .globl __pwrite64
+ .type pwrite64, @function
+ .globl pwrite64
.align 4
-__pwrite64:
+pwrite64:
/* get ready for additonal arg */
mov.l @r15, r0
diff --git a/libc/arch-sh/syscalls/__pwrite64.S b/libc/arch-sh/syscalls/sched_setaffinity.S
similarity index 63%
copy from libc/arch-sh/syscalls/__pwrite64.S
copy to libc/arch-sh/syscalls/sched_setaffinity.S
index a722242..9dda3b4 100644
--- a/libc/arch-sh/syscalls/__pwrite64.S
+++ b/libc/arch-sh/syscalls/sched_setaffinity.S
@@ -2,22 +2,19 @@
#include <sys/linux-syscalls.h>
.text
- .type __pwrite64, @function
- .globl __pwrite64
+ .type sched_setaffinity, @function
+ .globl sched_setaffinity
.align 4
-__pwrite64:
-
- /* get ready for additonal arg */
- mov.l @r15, r0
+sched_setaffinity:
/* invoke trap */
mov.l 0f, r3 /* trap num */
- trapa #(5 + 0x10)
+ trapa #(3 + 0x10)
/* check return value */
cmp/pz r0
- bt __NR_pwrite64_end
+ bt __NR_sched_setaffinity_end
/* keep error number */
sts.l pr, @-r15
@@ -26,10 +23,10 @@
mov r0, r4
lds.l @r15+, pr
-__NR_pwrite64_end:
+__NR_sched_setaffinity_end:
rts
nop
.align 2
-0: .long __NR_pwrite64
+0: .long __NR_sched_setaffinity
1: .long __set_syscall_errno
diff --git a/libc/arch-x86/bionic/sigsetjmp.S b/libc/arch-x86/bionic/sigsetjmp.S
new file mode 100644
index 0000000..c990a05
--- /dev/null
+++ b/libc/arch-x86/bionic/sigsetjmp.S
@@ -0,0 +1,92 @@
+/* $OpenBSD: sigsetjmp.S,v 1.7 2005/08/07 11:30:38 espie Exp $ */
+/*-
+ * Copyright (c) 1990 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * William Jolitz.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <machine/asm.h>
+
+ENTRY(sigsetjmp)
+ movl 4(%esp),%ecx
+ movl 8(%esp),%eax
+ movl %eax,28(%ecx)
+ testl %eax,%eax
+ jz 1f
+
+ PIC_PROLOGUE
+ pushl $0
+#ifdef PIC
+ call PIC_PLT(_C_LABEL(sigblock))
+#else
+ call _C_LABEL(sigblock)
+#endif
+ addl $4,%esp
+ PIC_EPILOGUE
+
+ movl 4(%esp),%ecx
+ movl %eax,24(%ecx)
+1: movl 0(%esp),%edx
+ movl %edx, 0(%ecx)
+ movl %ebx, 4(%ecx)
+ movl %esp, 8(%ecx)
+ movl %ebp,12(%ecx)
+ movl %esi,16(%ecx)
+ movl %edi,20(%ecx)
+ xorl %eax,%eax
+ ret
+
+ENTRY(siglongjmp)
+ movl 4(%esp),%edx
+ cmpl $0,28(%edx)
+ jz 1f
+
+ PIC_PROLOGUE
+ pushl 24(%edx)
+#ifdef PIC
+ call PIC_PLT(_C_LABEL(sigsetmask))
+#else
+ call _C_LABEL(sigsetmask)
+#endif
+ addl $4,%esp
+ PIC_EPILOGUE
+
+1: movl 4(%esp),%edx
+ movl 8(%esp),%eax
+ movl 0(%edx),%ecx
+ movl 4(%edx),%ebx
+ movl 8(%edx),%esp
+ movl 12(%edx),%ebp
+ movl 16(%edx),%esi
+ movl 20(%edx),%edi
+ testl %eax,%eax
+ jnz 2f
+ incl %eax
+2: movl %ecx,0(%esp)
+ ret
diff --git a/libc/arch-x86/bionic/syscall.S b/libc/arch-x86/bionic/syscall.S
index 71abe6b..3cca85c 100644
--- a/libc/arch-x86/bionic/syscall.S
+++ b/libc/arch-x86/bionic/syscall.S
@@ -20,18 +20,15 @@
.align 4
syscall:
- push %eax
push %ebx
- push %ecx
- push %edx
push %esi
push %edi
- mov 28(%esp),%eax
- mov 32(%esp),%ebx
- mov 36(%esp),%ecx
- mov 40(%esp),%edx
- mov 44(%esp),%esi
- mov 48(%esp),%edi
+ mov 16(%esp),%eax
+ mov 20(%esp),%ebx
+ mov 24(%esp),%ecx
+ mov 28(%esp),%edx
+ mov 32(%esp),%esi
+ mov 36(%esp),%edi
int $0x80
@@ -45,8 +42,5 @@
1:
pop %edi
pop %esi
- pop %edx
- pop %ecx
pop %ebx
- pop %eax
ret
diff --git a/libc/arch-x86/syscalls.mk b/libc/arch-x86/syscalls.mk
index 420a91e..e8c6a77 100644
--- a/libc/arch-x86/syscalls.mk
+++ b/libc/arch-x86/syscalls.mk
@@ -44,8 +44,8 @@
syscall_src += arch-x86/syscalls/acct.S
syscall_src += arch-x86/syscalls/read.S
syscall_src += arch-x86/syscalls/write.S
-syscall_src += arch-x86/syscalls/__pread64.S
-syscall_src += arch-x86/syscalls/__pwrite64.S
+syscall_src += arch-x86/syscalls/pread64.S
+syscall_src += arch-x86/syscalls/pwrite64.S
syscall_src += arch-x86/syscalls/__open.S
syscall_src += arch-x86/syscalls/__openat.S
syscall_src += arch-x86/syscalls/close.S
@@ -73,6 +73,7 @@
syscall_src += arch-x86/syscalls/dup2.S
syscall_src += arch-x86/syscalls/select.S
syscall_src += arch-x86/syscalls/ftruncate.S
+syscall_src += arch-x86/syscalls/ftruncate64.S
syscall_src += arch-x86/syscalls/getdents.S
syscall_src += arch-x86/syscalls/fsync.S
syscall_src += arch-x86/syscalls/fdatasync.S
@@ -156,6 +157,9 @@
syscall_src += arch-x86/syscalls/sched_get_priority_max.S
syscall_src += arch-x86/syscalls/sched_get_priority_min.S
syscall_src += arch-x86/syscalls/sched_rr_get_interval.S
+syscall_src += arch-x86/syscalls/sched_setaffinity.S
+syscall_src += arch-x86/syscalls/__sched_getaffinity.S
+syscall_src += arch-x86/syscalls/__getcpu.S
syscall_src += arch-x86/syscalls/ioprio_set.S
syscall_src += arch-x86/syscalls/ioprio_get.S
syscall_src += arch-x86/syscalls/uname.S
diff --git a/libc/arch-x86/syscalls/__getcpu.S b/libc/arch-x86/syscalls/__getcpu.S
new file mode 100644
index 0000000..0381799
--- /dev/null
+++ b/libc/arch-x86/syscalls/__getcpu.S
@@ -0,0 +1,29 @@
+/* autogenerated by gensyscalls.py */
+#include <sys/linux-syscalls.h>
+
+ .text
+ .type __getcpu, @function
+ .globl __getcpu
+ .align 4
+
+__getcpu:
+ pushl %ebx
+ pushl %ecx
+ pushl %edx
+ mov 16(%esp), %ebx
+ mov 20(%esp), %ecx
+ mov 24(%esp), %edx
+ movl $__NR_getcpu, %eax
+ int $0x80
+ cmpl $-129, %eax
+ jb 1f
+ negl %eax
+ pushl %eax
+ call __set_errno
+ addl $4, %esp
+ orl $-1, %eax
+1:
+ popl %edx
+ popl %ecx
+ popl %ebx
+ ret
diff --git a/libc/arch-x86/syscalls/__sched_getaffinity.S b/libc/arch-x86/syscalls/__sched_getaffinity.S
new file mode 100644
index 0000000..43bfa50
--- /dev/null
+++ b/libc/arch-x86/syscalls/__sched_getaffinity.S
@@ -0,0 +1,29 @@
+/* autogenerated by gensyscalls.py */
+#include <sys/linux-syscalls.h>
+
+ .text
+ .type __sched_getaffinity, @function
+ .globl __sched_getaffinity
+ .align 4
+
+__sched_getaffinity:
+ pushl %ebx
+ pushl %ecx
+ pushl %edx
+ mov 16(%esp), %ebx
+ mov 20(%esp), %ecx
+ mov 24(%esp), %edx
+ movl $__NR_sched_getaffinity, %eax
+ int $0x80
+ cmpl $-129, %eax
+ jb 1f
+ negl %eax
+ pushl %eax
+ call __set_errno
+ addl $4, %esp
+ orl $-1, %eax
+1:
+ popl %edx
+ popl %ecx
+ popl %ebx
+ ret
diff --git a/libc/arch-x86/syscalls/ftruncate64.S b/libc/arch-x86/syscalls/ftruncate64.S
new file mode 100644
index 0000000..66835ab
--- /dev/null
+++ b/libc/arch-x86/syscalls/ftruncate64.S
@@ -0,0 +1,29 @@
+/* autogenerated by gensyscalls.py */
+#include <sys/linux-syscalls.h>
+
+ .text
+ .type ftruncate64, @function
+ .globl ftruncate64
+ .align 4
+
+ftruncate64:
+ pushl %ebx
+ pushl %ecx
+ pushl %edx
+ mov 16(%esp), %ebx
+ mov 20(%esp), %ecx
+ mov 24(%esp), %edx
+ movl $__NR_ftruncate64, %eax
+ int $0x80
+ cmpl $-129, %eax
+ jb 1f
+ negl %eax
+ pushl %eax
+ call __set_errno
+ addl $4, %esp
+ orl $-1, %eax
+1:
+ popl %edx
+ popl %ecx
+ popl %ebx
+ ret
diff --git a/libc/arch-x86/syscalls/__pread64.S b/libc/arch-x86/syscalls/pread64.S
similarity index 90%
rename from libc/arch-x86/syscalls/__pread64.S
rename to libc/arch-x86/syscalls/pread64.S
index 3114673..eb004a9 100644
--- a/libc/arch-x86/syscalls/__pread64.S
+++ b/libc/arch-x86/syscalls/pread64.S
@@ -2,11 +2,11 @@
#include <sys/linux-syscalls.h>
.text
- .type __pread64, @function
- .globl __pread64
+ .type pread64, @function
+ .globl pread64
.align 4
-__pread64:
+pread64:
pushl %ebx
pushl %ecx
pushl %edx
diff --git a/libc/arch-x86/syscalls/__pwrite64.S b/libc/arch-x86/syscalls/pwrite64.S
similarity index 90%
rename from libc/arch-x86/syscalls/__pwrite64.S
rename to libc/arch-x86/syscalls/pwrite64.S
index 28f6536..01389f8 100644
--- a/libc/arch-x86/syscalls/__pwrite64.S
+++ b/libc/arch-x86/syscalls/pwrite64.S
@@ -2,11 +2,11 @@
#include <sys/linux-syscalls.h>
.text
- .type __pwrite64, @function
- .globl __pwrite64
+ .type pwrite64, @function
+ .globl pwrite64
.align 4
-__pwrite64:
+pwrite64:
pushl %ebx
pushl %ecx
pushl %edx
diff --git a/libc/arch-x86/syscalls/sched_setaffinity.S b/libc/arch-x86/syscalls/sched_setaffinity.S
new file mode 100644
index 0000000..5fa51ef
--- /dev/null
+++ b/libc/arch-x86/syscalls/sched_setaffinity.S
@@ -0,0 +1,29 @@
+/* autogenerated by gensyscalls.py */
+#include <sys/linux-syscalls.h>
+
+ .text
+ .type sched_setaffinity, @function
+ .globl sched_setaffinity
+ .align 4
+
+sched_setaffinity:
+ pushl %ebx
+ pushl %ecx
+ pushl %edx
+ mov 16(%esp), %ebx
+ mov 20(%esp), %ecx
+ mov 24(%esp), %edx
+ movl $__NR_sched_setaffinity, %eax
+ int $0x80
+ cmpl $-129, %eax
+ jb 1f
+ negl %eax
+ pushl %eax
+ call __set_errno
+ addl $4, %esp
+ orl $-1, %eax
+1:
+ popl %edx
+ popl %ecx
+ popl %ebx
+ ret
diff --git a/libc/bionic/__set_errno.c b/libc/bionic/__set_errno.c
index c72d4f7..163d404 100644
--- a/libc/bionic/__set_errno.c
+++ b/libc/bionic/__set_errno.c
@@ -40,6 +40,7 @@
* (tail-called in the case of 0-4 arg versions)
*/
+__LIBC_HIDDEN__
int __set_syscall_errno(int n)
{
/* some syscalls, mmap() for example, have valid return
diff --git a/libc/bionic/_rand48.c b/libc/bionic/_rand48.c
deleted file mode 100644
index e422781..0000000
--- a/libc/bionic/_rand48.c
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * Copyright (c) 1993 Martin Birgmeier
- * All rights reserved.
- *
- * You may redistribute unmodified or modified versions of this source
- * code provided that the above copyright notice and this and the
- * following conditions are retained.
- *
- * This software is provided ``as is'', and comes with no warranties
- * of any kind. I shall in no event be liable for anything that happens
- * to anyone/anything when using this software.
- */
-
-#include <sys/cdefs.h>
-#include "rand48.h"
-
-unsigned short _rand48_seed[3] = {
- RAND48_SEED_0,
- RAND48_SEED_1,
- RAND48_SEED_2
-};
-unsigned short _rand48_mult[3] = {
- RAND48_MULT_0,
- RAND48_MULT_1,
- RAND48_MULT_2
-};
-unsigned short _rand48_add = RAND48_ADD;
-
-void
-_dorand48(unsigned short xseed[3])
-{
- unsigned long accu;
- unsigned short temp[2];
-
- accu = (unsigned long) _rand48_mult[0] * (unsigned long) xseed[0] +
- (unsigned long) _rand48_add;
- temp[0] = (unsigned short) accu; /* lower 16 bits */
- accu >>= sizeof(unsigned short) * 8;
- accu += (unsigned long) _rand48_mult[0] * (unsigned long) xseed[1] +
- (unsigned long) _rand48_mult[1] * (unsigned long) xseed[0];
- temp[1] = (unsigned short) accu; /* middle 16 bits */
- accu >>= sizeof(unsigned short) * 8;
- accu += _rand48_mult[0] * xseed[2] + _rand48_mult[1] * xseed[1] + _rand48_mult[2] * xseed[0];
- xseed[0] = temp[0];
- xseed[1] = temp[1];
- xseed[2] = (unsigned short) accu;
-}
diff --git a/libc/bionic/dlmalloc.c b/libc/bionic/dlmalloc.c
index 19fbb75..8c75e9c 100644
--- a/libc/bionic/dlmalloc.c
+++ b/libc/bionic/dlmalloc.c
@@ -2265,13 +2265,53 @@
#else /* PROCEED_ON_ERROR */
-#ifndef CORRUPTION_ERROR_ACTION
-#define CORRUPTION_ERROR_ACTION(m) ABORT
-#endif /* CORRUPTION_ERROR_ACTION */
+/* The following Android-specific code is used to print an informative
+ * fatal error message to the log when we detect that a heap corruption
+ * was detected. We need to be careful about not using a log function
+ * that may require an allocation here!
+ */
+#ifdef LOG_ON_HEAP_ERROR
-#ifndef USAGE_ERROR_ACTION
-#define USAGE_ERROR_ACTION(m,p) ABORT
-#endif /* USAGE_ERROR_ACTION */
+# include <private/logd.h>
+
+static void __bionic_heap_error(const char* msg, const char* function)
+{
+ /* We format the buffer explicitely, i.e. without using snprintf()
+ * which may use malloc() internally. Not something we can trust
+ * if we just detected a corrupted heap.
+ */
+ char buffer[256];
+ strlcpy(buffer, "@@@ ABORTING: ", sizeof(buffer));
+ strlcat(buffer, msg, sizeof(buffer));
+ if (function != NULL) {
+ strlcat(buffer, " IN ", sizeof(buffer));
+ strlcat(buffer, function, sizeof(buffer));
+ }
+ __libc_android_log_write(ANDROID_LOG_FATAL,"libc",buffer);
+ abort();
+}
+
+# ifndef CORRUPTION_ERROR_ACTION
+# define CORRUPTION_ERROR_ACTION(m) \
+ __bionic_heap_error("HEAP MEMORY CORRUPTION", __FUNCTION__)
+# endif
+# ifndef USAGE_ERROR_ACTION
+# define USAGE_ERROR_ACTION(m,p) \
+ __bionic_heap_error("INVALID HEAP ADDRESS", __FUNCTION__)
+# endif
+
+#else /* !LOG_ON_HEAP_ERROR */
+
+# ifndef CORRUPTION_ERROR_ACTION
+# define CORRUPTION_ERROR_ACTION(m) ABORT
+# endif /* CORRUPTION_ERROR_ACTION */
+
+# ifndef USAGE_ERROR_ACTION
+# define USAGE_ERROR_ACTION(m,p) ABORT
+# endif /* USAGE_ERROR_ACTION */
+
+#endif /* !LOG_ON_HEAP_ERROR */
+
#endif /* PROCEED_ON_ERROR */
diff --git a/libc/bionic/drand48.c b/libc/bionic/drand48.c
index fd48196..93272cf 100644
--- a/libc/bionic/drand48.c
+++ b/libc/bionic/drand48.c
@@ -15,10 +15,10 @@
#include "rand48.h"
-extern unsigned short _rand48_seed[3];
+extern unsigned short __rand48_seed[3];
double
drand48(void)
{
- return erand48(_rand48_seed);
+ return erand48(__rand48_seed);
}
diff --git a/libc/bionic/erand48.c b/libc/bionic/erand48.c
index 843ff34..4ecbead 100644
--- a/libc/bionic/erand48.c
+++ b/libc/bionic/erand48.c
@@ -18,7 +18,7 @@
double
erand48(unsigned short xseed[3])
{
- _dorand48(xseed);
+ __dorand48(xseed);
return ldexp((double) xseed[0], -48) +
ldexp((double) xseed[1], -32) +
ldexp((double) xseed[2], -16);
diff --git a/libc/bionic/fork.c b/libc/bionic/fork.c
index 79b8fff..0eedb01 100644
--- a/libc/bionic/fork.c
+++ b/libc/bionic/fork.c
@@ -41,9 +41,12 @@
* of error, or in the parent process
*/
__timer_table_start_stop(1);
+ __bionic_atfork_run_prepare();
+
ret = __fork();
if (ret != 0) { /* not a child process */
__timer_table_start_stop(0);
+ __bionic_atfork_run_parent();
} else {
/*
* Newly created process must update cpu accounting.
@@ -52,6 +55,7 @@
* as a parameter.
*/
cpuacct_add(getuid());
+ __bionic_atfork_run_child();
}
return ret;
}
diff --git a/libc/bionic/libc_init_common.c b/libc/bionic/libc_init_common.c
index f7579bd..b6a6379 100644
--- a/libc/bionic/libc_init_common.c
+++ b/libc/bionic/libc_init_common.c
@@ -62,7 +62,7 @@
static pthread_internal_t thread;
static void* tls_area[BIONIC_TLS_SLOTS];
- /* setup pthread runtime and maint thread descriptor */
+ /* setup pthread runtime and main thread descriptor */
unsigned stacktop = (__get_sp() & ~(PAGE_SIZE - 1)) + PAGE_SIZE;
unsigned stacksize = 128 * 1024;
unsigned stackbottom = stacktop - stacksize;
diff --git a/libc/bionic/libc_init_dynamic.c b/libc/bionic/libc_init_dynamic.c
index f64b6f2..4bb2a81 100644
--- a/libc/bionic/libc_init_dynamic.c
+++ b/libc/bionic/libc_init_dynamic.c
@@ -61,7 +61,7 @@
void __libc_preinit(void)
{
- /* Read the ELF data pointer form a special slot of the
+ /* Read the ELF data pointer from a special slot of the
* TLS area, then call __libc_init_common with it.
*
* Note that:
diff --git a/libc/bionic/logd_write.c b/libc/bionic/logd_write.c
index 63dfd59..2bc39fa 100644
--- a/libc/bionic/logd_write.c
+++ b/libc/bionic/logd_write.c
@@ -48,6 +48,16 @@
#include <pthread.h>
+/* IMPORTANT IMPORTANT IMPORTANT: TECHNICAL NOTE
+ *
+ * Some of the functions below can be called when our malloc() implementation
+ * has detected that the heap is corrupted, or even from a signal handler.
+ *
+ * These functions should *not* use a function that allocates heap memory
+ * or is not signal-safe. Using direct system calls is acceptable, and we
+ * also assume that pthread_mutex_lock/unlock can be used too.
+ */
+
#define LOG_BUF_SIZE 1024
typedef enum {
@@ -77,9 +87,10 @@
{ __write_to_log_init, -1, "/dev/"LOGGER_LOG_RADIO }
};
+/* Important: see technical note at start of source file */
static int __write_to_log_null(log_id_t log_id, struct iovec *vec)
{
- /*
+ /*
* ALTERED behaviour from previous version
* always returns successful result
*/
@@ -97,23 +108,21 @@
* it's supposed, that log_id contains valid id always.
* this check must be performed in higher level functions
*/
+/* Important: see technical note at start of source file */
static int __write_to_log_kernel(log_id_t log_id, struct iovec *vec)
{
- ssize_t ret;
-
- do {
- ret = writev(log_channels[log_id].fd, vec, 3);
- } while ((ret < 0) && (errno == EINTR));
-
- return ret;
+ return TEMP_FAILURE_RETRY( writev(log_channels[log_id].fd, vec, 3) );
}
+/* Important: see technical note at start of source file */
static int __write_to_log_init(log_id_t log_id, struct iovec *vec)
{
if ((LOG_ID_NONE < log_id) && (log_id < LOG_ID_MAX)) {
+ int fd;
+
pthread_mutex_lock(&log_init_lock);
- int fd = open(log_channels[log_id].path, O_WRONLY);
+ fd = TEMP_FAILURE_RETRY(open(log_channels[log_id].path, O_WRONLY));
log_channels[log_id].logger =
(fd < 0) ? __write_to_log_null : __write_to_log_kernel;
@@ -130,7 +139,9 @@
return -1;
}
-static int __android_log_write(int prio, const char *tag, const char *msg)
+/* Important: see technical note at start of source file */
+__LIBC_HIDDEN__
+int __libc_android_log_write(int prio, const char *tag, const char *msg)
{
struct iovec vec[3];
log_id_t log_id = LOG_ID_MAIN;
@@ -151,7 +162,11 @@
return log_channels[log_id].logger(log_id, vec);
}
-
+/* The functions below are not designed to be called from a heap panic
+ * function or from a signal handler. As such, they are free to use complex
+ * C library functions like vsnprintf()
+ */
+__LIBC_HIDDEN__
int __libc_android_log_vprint(int prio, const char *tag, const char *fmt,
va_list ap)
{
@@ -159,9 +174,10 @@
vsnprintf(buf, LOG_BUF_SIZE, fmt, ap);
- return __android_log_write(prio, tag, buf);
+ return __libc_android_log_write(prio, tag, buf);
}
+__LIBC_HIDDEN__
int __libc_android_log_print(int prio, const char *tag, const char *fmt, ...)
{
va_list ap;
@@ -171,20 +187,21 @@
vsnprintf(buf, LOG_BUF_SIZE, fmt, ap);
va_end(ap);
- return __android_log_write(prio, tag, buf);
+ return __libc_android_log_write(prio, tag, buf);
}
+__LIBC_HIDDEN__
int __libc_android_log_assert(const char *cond, const char *tag,
const char *fmt, ...)
{
va_list ap;
- char buf[LOG_BUF_SIZE];
+ char buf[LOG_BUF_SIZE];
va_start(ap, fmt);
vsnprintf(buf, LOG_BUF_SIZE, fmt, ap);
va_end(ap);
- __android_log_write(ANDROID_LOG_FATAL, tag, buf);
+ __libc_android_log_write(ANDROID_LOG_FATAL, tag, buf);
exit(1);
diff --git a/libc/bionic/malloc_debug_common.c b/libc/bionic/malloc_debug_common.c
index f05576c..b9fcbc4 100644
--- a/libc/bionic/malloc_debug_common.c
+++ b/libc/bionic/malloc_debug_common.c
@@ -84,7 +84,6 @@
//
// 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) {
@@ -120,6 +119,7 @@
totalMemory == NULL || backtraceSize == NULL) {
return;
}
+ *totalMemory = 0;
pthread_mutex_lock(&gAllocationsMutex);
@@ -127,7 +127,6 @@
*info = NULL;
*overallSize = 0;
*infoSize = 0;
- *totalMemory = 0;
*backtraceSize = 0;
goto done;
}
diff --git a/libc/bionic/md5.c b/libc/bionic/md5.c
index 087786f..16674f1 100644
--- a/libc/bionic/md5.c
+++ b/libc/bionic/md5.c
@@ -38,6 +38,7 @@
"$NetBSD: md5.c,v 1.1.1.4 2002/09/12 12:41:42 joda Exp $");
#endif
+#include <endian.h>
#include "md5.h"
#include "hash.h"
@@ -178,8 +179,11 @@
/*
* From `Performance analysis of MD5' by Joseph D. Touch <touch@isi.edu>
*/
+#if !defined(__BYTE_ORDER) || !defined (__BIG_ENDIAN)
+#error __BYTE_ORDER macros not defined
+#endif
-#if defined(WORDS_BIGENDIAN)
+#if __BYTE_ORDER == __BIG_ENDIAN
static inline u_int32_t
swap_u_int32_t (u_int32_t t)
{
@@ -217,7 +221,7 @@
p += l;
len -= l;
if(offset == 64){
-#if defined(WORDS_BIGENDIAN)
+#if __BYTE_ORDER == __BIG_ENDIAN
int i;
u_int32_t current[16];
struct x32 *u = (struct x32*)m->save;
diff --git a/libc/bionic/pthread-atfork.c b/libc/bionic/pthread-atfork.c
new file mode 100644
index 0000000..3a5189d
--- /dev/null
+++ b/libc/bionic/pthread-atfork.c
@@ -0,0 +1,123 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+#include <stdlib.h>
+#include <errno.h>
+#include <pthread.h>
+#include <sys/queue.h>
+
+static pthread_mutex_t handler_mutex = PTHREAD_RECURSIVE_MUTEX_INITIALIZER;
+
+struct atfork_t
+{
+ CIRCLEQ_ENTRY(atfork_t) entries;
+
+ void (*prepare)(void);
+ void (*child)(void);
+ void (*parent)(void);
+};
+static CIRCLEQ_HEAD(atfork_head_t, atfork_t) atfork_head = \
+ CIRCLEQ_HEAD_INITIALIZER(atfork_head);
+
+void __bionic_atfork_run_prepare()
+{
+ struct atfork_t *cursor;
+
+ /* We will lock this here, and unlock it in the parent and child functions.
+ * This ensures that nobody can modify the handler array between the calls
+ * to the prepare and parent/child handlers.
+ *
+ * TODO: If a handler mucks with the list, it could cause problems. Right
+ * now it's ok because all they can do is add new items to the end
+ * of the list, but if/when we implement cleanup in dlclose() things
+ * will get more interesting...
+ */
+ pthread_mutex_lock(&handler_mutex);
+
+ /* Call pthread_atfork() prepare handlers. Posix states that the prepare
+ * handlers should be called in the reverse order of the parent/child
+ * handlers, so we iterate backwards.
+ */
+ for (cursor = atfork_head.cqh_last;
+ cursor != (void*)&atfork_head;
+ cursor = cursor->entries.cqe_prev) {
+ if (cursor->prepare != NULL) {
+ cursor->prepare();
+ }
+ }
+}
+
+void __bionic_atfork_run_child()
+{
+ struct atfork_t *cursor;
+
+ /* Call pthread_atfork() child handlers */
+ for (cursor = atfork_head.cqh_first;
+ cursor != (void*)&atfork_head;
+ cursor = cursor->entries.cqe_next) {
+ if (cursor->child != NULL) {
+ cursor->child();
+ }
+ }
+
+ pthread_mutex_unlock(&handler_mutex);
+}
+
+void __bionic_atfork_run_parent()
+{
+ struct atfork_t *cursor;
+
+ /* Call pthread_atfork() parent handlers */
+ for (cursor = atfork_head.cqh_first;
+ cursor != (void*)&atfork_head;
+ cursor = cursor->entries.cqe_next) {
+ if (cursor->parent != NULL) {
+ cursor->parent();
+ }
+ }
+
+ pthread_mutex_unlock(&handler_mutex);
+}
+
+int pthread_atfork(void (*prepare)(void), void (*parent)(void), void(*child)(void))
+{
+ struct atfork_t *entry = malloc(sizeof(struct atfork_t));
+
+ if (entry == NULL) {
+ return ENOMEM;
+ }
+
+ entry->prepare = prepare;
+ entry->parent = parent;
+ entry->child = child;
+
+ pthread_mutex_lock(&handler_mutex);
+ CIRCLEQ_INSERT_TAIL(&atfork_head, entry, entries);
+ pthread_mutex_unlock(&handler_mutex);
+
+ return 0;
+}
diff --git a/libc/bionic/pthread-timers.c b/libc/bionic/pthread-timers.c
index 7b9c99e..ae04029 100644
--- a/libc/bionic/pthread-timers.c
+++ b/libc/bionic/pthread-timers.c
@@ -260,7 +260,7 @@
** requirements: the timers of fork child processes must be
** disarmed but not deleted.
**/
-void
+__LIBC_HIDDEN__ void
__timer_table_start_stop( int stop )
{
if (__timer_table != NULL) {
diff --git a/libc/bionic/pthread.c b/libc/bionic/pthread.c
index 180914e..0a0854d 100644
--- a/libc/bionic/pthread.c
+++ b/libc/bionic/pthread.c
@@ -202,6 +202,9 @@
// Wait for our creating thread to release us. This lets it have time to
// notify gdb about this thread before it starts doing anything.
+ //
+ // This also provides the memory barrier needed to ensure that all memory
+ // accesses previously made by the creating thread are visible to us.
pthread_mutex_t * start_mutex = (pthread_mutex_t *)&tls[TLS_SLOT_SELF];
pthread_mutex_lock(start_mutex);
pthread_mutex_destroy(start_mutex);
@@ -270,7 +273,7 @@
}
/*
- * Create a new thread. The thread's stack is layed out like so:
+ * Create a new thread. The thread's stack is laid out like so:
*
* +---------------------------+
* | pthread_internal_t |
@@ -340,6 +343,10 @@
// Create a mutex for the thread in TLS_SLOT_SELF to wait on once it starts so we can keep
// it from doing anything until after we notify the debugger about it
+ //
+ // This also provides the memory barrier we need to ensure that all
+ // memory accesses previously performed by this thread are visible to
+ // the new thread.
start_mutex = (pthread_mutex_t *) &tls[TLS_SLOT_SELF];
pthread_mutex_init(start_mutex, NULL);
pthread_mutex_lock(start_mutex);
@@ -1427,6 +1434,18 @@
break;
}
+ /*
+ * Ensure that all memory accesses previously made by this thread are
+ * visible to the woken thread(s). On the other side, the "wait"
+ * code will issue any necessary barriers when locking the mutex.
+ *
+ * This may not strictly be necessary -- if the caller follows
+ * recommended practice and holds the mutex before signaling the cond
+ * var, the mutex ops will provide correct semantics. If they don't
+ * hold the mutex, they're subject to race conditions anyway.
+ */
+ ANDROID_MEMBAR_FULL();
+
__futex_wake_ex(&cond->value, COND_IS_SHARED(cond), counter);
return 0;
}
@@ -1845,7 +1864,13 @@
*/
int ret, old_errno = errno;
- ret = __rt_sigprocmask(how, set, oset, _NSIG / 8);
+ /* Use NSIG which corresponds to the number of signals in
+ * our 32-bit sigset_t implementation. As such, this function, or
+ * anything that deals with sigset_t cannot manage real-time signals
+ * (signo >= 32). We might want to introduce sigset_rt_t as an
+ * extension to do so in the future.
+ */
+ ret = __rt_sigprocmask(how, set, oset, NSIG / 8);
if (ret < 0)
ret = errno;
@@ -1873,12 +1898,16 @@
int pthread_once( pthread_once_t* once_control, void (*init_routine)(void) )
{
static pthread_mutex_t once_lock = PTHREAD_RECURSIVE_MUTEX_INITIALIZER;
+ volatile pthread_once_t* ocptr = once_control;
- if (*once_control == PTHREAD_ONCE_INIT) {
+ pthread_once_t tmp = *ocptr;
+ ANDROID_MEMBAR_FULL();
+ if (tmp == PTHREAD_ONCE_INIT) {
pthread_mutex_lock( &once_lock );
- if (*once_control == PTHREAD_ONCE_INIT) {
+ if (*ocptr == PTHREAD_ONCE_INIT) {
(*init_routine)();
- *once_control = ~PTHREAD_ONCE_INIT;
+ ANDROID_MEMBAR_FULL();
+ *ocptr = ~PTHREAD_ONCE_INIT;
}
pthread_mutex_unlock( &once_lock );
}
diff --git a/libc/bionic/pthread_internal.h b/libc/bionic/pthread_internal.h
index eb4e80c..655b8f3 100644
--- a/libc/bionic/pthread_internal.h
+++ b/libc/bionic/pthread_internal.h
@@ -109,6 +109,9 @@
/* needed by fork.c */
extern void __timer_table_start_stop(int stop);
+extern void __bionic_atfork_run_prepare();
+extern void __bionic_atfork_run_child();
+extern void __bionic_atfork_run_parent();
__END_DECLS
diff --git a/libc/bionic/rand48.h b/libc/bionic/rand48.h
deleted file mode 100644
index 0a3d83d..0000000
--- a/libc/bionic/rand48.h
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * Copyright (c) 1993 Martin Birgmeier
- * All rights reserved.
- *
- * You may redistribute unmodified or modified versions of this source
- * code provided that the above copyright notice and this and the
- * following conditions are retained.
- *
- * This software is provided ``as is'', and comes with no warranties
- * of any kind. I shall in no event be liable for anything that happens
- * to anyone/anything when using this software.
- *
- * $FreeBSD: src/lib/libc/gen/rand48.h,v 1.2 2002/02/01 01:32:19 obrien Exp $
- */
-
-#ifndef _RAND48_H_
-#define _RAND48_H_
-
-#include <math.h>
-#include <stdlib.h>
-
-void _dorand48(unsigned short[3]);
-
-#define RAND48_SEED_0 (0x330e)
-#define RAND48_SEED_1 (0xabcd)
-#define RAND48_SEED_2 (0x1234)
-#define RAND48_MULT_0 (0xe66d)
-#define RAND48_MULT_1 (0xdeec)
-#define RAND48_MULT_2 (0x0005)
-#define RAND48_ADD (0x000b)
-
-#endif /* _RAND48_H_ */
diff --git a/libc/bionic/realpath.c b/libc/bionic/realpath.c
index 274a3a0..4cb847b 100644
--- a/libc/bionic/realpath.c
+++ b/libc/bionic/realpath.c
@@ -1,9 +1,6 @@
+/* $OpenBSD: realpath.c,v 1.13 2005/08/08 08:05:37 espie Exp $ */
/*
- * Copyright (c) 1994
- * The Regents of the University of California. All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Jan-Simon Pendry.
+ * Copyright (c) 2003 Constantin S. Svintsoff <kostik@iclub.nsu.ru>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -13,18 +10,14 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
+ * 3. The names of the authors may not be used to endorse or promote
+ * products derived from this software without specific prior written
+ * permission.
*
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
@@ -34,133 +27,164 @@
* SUCH DAMAGE.
*/
-#if defined(LIBC_SCCS) && !defined(lint)
-static char sccsid[] = "@(#)realpath.c 8.1 (Berkeley) 2/16/94";
-static char rcsid[] =
-"$FreeBSD: /repoman/r/ncvs/src/lib/libc/stdlib/realpath.c,v 1.6.2.1 2003/08/03 23:47:39 nectar Exp $";
-#endif /* LIBC_SCCS and not lint */
-
#include <sys/param.h>
#include <sys/stat.h>
#include <errno.h>
-#include <fcntl.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
/*
- * char *realpath(const char *path, char resolved_path[MAXPATHLEN]);
+ * char *realpath(const char *path, char resolved[PATH_MAX]);
*
* Find the real name of path, by removing all ".", ".." and symlink
* components. Returns (resolved) on success, or (NULL) on failure,
* in which case the path which caused trouble is left in (resolved).
*/
char *
-realpath(path, resolved)
- const char *path;
- char *resolved;
+realpath(const char *path, char resolved[PATH_MAX])
{
struct stat sb;
- int fd, n, rootd, serrno;
- char *p, *q, wbuf[MAXPATHLEN];
- int symlinks = 0;
+ char *p, *q, *s;
+ size_t left_len, resolved_len;
+ unsigned symlinks;
+ int serrno, slen;
+ char left[PATH_MAX], next_token[PATH_MAX], symlink[PATH_MAX];
- /* Save the starting point. */
- if ((fd = open(".", O_RDONLY)) < 0) {
- (void)strcpy(resolved, ".");
+ serrno = errno;
+ symlinks = 0;
+ if (path[0] == '/') {
+ resolved[0] = '/';
+ resolved[1] = '\0';
+ if (path[1] == '\0')
+ return (resolved);
+ resolved_len = 1;
+ left_len = strlcpy(left, path + 1, sizeof(left));
+ } else {
+ if (getcwd(resolved, PATH_MAX) == NULL) {
+ strlcpy(resolved, ".", PATH_MAX);
+ return (NULL);
+ }
+ resolved_len = strlen(resolved);
+ left_len = strlcpy(left, path, sizeof(left));
+ }
+ if (left_len >= sizeof(left) || resolved_len >= PATH_MAX) {
+ errno = ENAMETOOLONG;
return (NULL);
}
/*
- * Find the dirname and basename from the path to be resolved.
- * Change directory to the dirname component.
- * lstat the basename part.
- * if it is a symlink, read in the value and loop.
- * if it is a directory, then change to that directory.
- * get the current directory name and append the basename.
+ * Iterate over path components in `left'.
*/
- (void)strncpy(resolved, path, MAXPATHLEN - 1);
- resolved[MAXPATHLEN - 1] = '\0';
-loop:
- q = strrchr(resolved, '/');
- if (q != NULL) {
- p = q + 1;
- if (q == resolved)
- q = "/";
- else {
- do {
- --q;
- } while (q > resolved && *q == '/');
- q[1] = '\0';
- q = resolved;
- }
- if (chdir(q) < 0)
- goto err1;
- } else
- p = resolved;
-
- /* Deal with the last component. */
- if (*p != '\0' && lstat(p, &sb) == 0) {
- if (S_ISLNK(sb.st_mode)) {
- if (++symlinks > MAXSYMLINKS) {
- errno = ELOOP;
- goto err1;
- }
- n = readlink(p, resolved, MAXPATHLEN - 1);
- if (n < 0)
- goto err1;
- resolved[n] = '\0';
- goto loop;
- }
- if (S_ISDIR(sb.st_mode)) {
- if (chdir(p) < 0)
- goto err1;
- p = "";
- }
- }
-
- /*
- * Save the last component name and get the full pathname of
- * the current directory.
- */
- (void)strcpy(wbuf, p);
- if (getcwd(resolved, MAXPATHLEN) == 0)
- goto err1;
-
- /*
- * Join the two strings together, ensuring that the right thing
- * happens if the last component is empty, or the dirname is root.
- */
- if (resolved[0] == '/' && resolved[1] == '\0')
- rootd = 1;
- else
- rootd = 0;
-
- if (*wbuf) {
- if (strlen(resolved) + strlen(wbuf) + (1-rootd) + 1 >
- MAXPATHLEN) {
+ while (left_len != 0) {
+ /*
+ * Extract the next path component and adjust `left'
+ * and its length.
+ */
+ p = strchr(left, '/');
+ s = p ? p : left + left_len;
+ if (s - left >= sizeof(next_token)) {
errno = ENAMETOOLONG;
- goto err1;
+ return (NULL);
}
- if (rootd == 0)
- (void)strcat(resolved, "/");
- (void)strcat(resolved, wbuf);
+ memcpy(next_token, left, s - left);
+ next_token[s - left] = '\0';
+ left_len -= s - left;
+ if (p != NULL)
+ memmove(left, s + 1, left_len + 1);
+ if (resolved[resolved_len - 1] != '/') {
+ if (resolved_len + 1 >= PATH_MAX) {
+ errno = ENAMETOOLONG;
+ return (NULL);
+ }
+ resolved[resolved_len++] = '/';
+ resolved[resolved_len] = '\0';
+ }
+ if (next_token[0] == '\0')
+ continue;
+ else if (strcmp(next_token, ".") == 0)
+ continue;
+ else if (strcmp(next_token, "..") == 0) {
+ /*
+ * Strip the last path component except when we have
+ * single "/"
+ */
+ if (resolved_len > 1) {
+ resolved[resolved_len - 1] = '\0';
+ q = strrchr(resolved, '/') + 1;
+ *q = '\0';
+ resolved_len = q - resolved;
+ }
+ continue;
+ }
+
+ /*
+ * Append the next path component and lstat() it. If
+ * lstat() fails we still can return successfully if
+ * there are no more path components left.
+ */
+ resolved_len = strlcat(resolved, next_token, PATH_MAX);
+ if (resolved_len >= PATH_MAX) {
+ errno = ENAMETOOLONG;
+ return (NULL);
+ }
+ if (lstat(resolved, &sb) != 0) {
+ if (errno == ENOENT && p == NULL) {
+ errno = serrno;
+ return (resolved);
+ }
+ return (NULL);
+ }
+ if (S_ISLNK(sb.st_mode)) {
+ if (symlinks++ > MAXSYMLINKS) {
+ errno = ELOOP;
+ return (NULL);
+ }
+ slen = readlink(resolved, symlink, sizeof(symlink) - 1);
+ if (slen < 0)
+ return (NULL);
+ symlink[slen] = '\0';
+ if (symlink[0] == '/') {
+ resolved[1] = 0;
+ resolved_len = 1;
+ } else if (resolved_len > 1) {
+ /* Strip the last path component. */
+ resolved[resolved_len - 1] = '\0';
+ q = strrchr(resolved, '/') + 1;
+ *q = '\0';
+ resolved_len = q - resolved;
+ }
+
+ /*
+ * If there are any path components left, then
+ * append them to symlink. The result is placed
+ * in `left'.
+ */
+ if (p != NULL) {
+ if (symlink[slen - 1] != '/') {
+ if (slen + 1 >= sizeof(symlink)) {
+ errno = ENAMETOOLONG;
+ return (NULL);
+ }
+ symlink[slen] = '/';
+ symlink[slen + 1] = 0;
+ }
+ left_len = strlcat(symlink, left, sizeof(left));
+ if (left_len >= sizeof(left)) {
+ errno = ENAMETOOLONG;
+ return (NULL);
+ }
+ }
+ left_len = strlcpy(left, symlink, sizeof(left));
+ }
}
- /* Go back to where we came from. */
- if (fchdir(fd) < 0) {
- serrno = errno;
- goto err2;
- }
-
- /* It's okay if the close fails, what's an fd more or less? */
- (void)close(fd);
+ /*
+ * Remove trailing slash except when the resolved pathname
+ * is a single "/".
+ */
+ if (resolved_len > 1 && resolved[resolved_len - 1] == '/')
+ resolved[resolved_len - 1] = '\0';
return (resolved);
-
-err1: serrno = errno;
- (void)fchdir(fd);
-err2: (void)close(fd);
- errno = serrno;
- return (NULL);
}
diff --git a/libc/bionic/sched_cpualloc.c b/libc/bionic/sched_cpualloc.c
new file mode 100644
index 0000000..30964bc
--- /dev/null
+++ b/libc/bionic/sched_cpualloc.c
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+#define _GNU_SOURCE 1
+#include <sched.h>
+#include <stdlib.h>
+
+cpu_set_t* __sched_cpualloc(size_t count)
+{
+ return (cpu_set_t*) malloc(CPU_ALLOC_SIZE(count));
+}
+
+void __sched_cpufree(cpu_set_t* set)
+{
+ free(set);
+}
diff --git a/libc/bionic/sched_cpucount.c b/libc/bionic/sched_cpucount.c
new file mode 100644
index 0000000..9458dc8
--- /dev/null
+++ b/libc/bionic/sched_cpucount.c
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+#define _GNU_SOURCE 1
+#include <sched.h>
+
+int __sched_cpucount(size_t setsize, cpu_set_t* set)
+{
+ int nn = 0, nn_max = setsize / sizeof(__CPU_BITTYPE);
+ int count = 0;
+
+ for ( ; nn < nn_max; nn++ )
+ count += __builtin_popcount(set->__bits[nn]);
+
+ return count;
+}
diff --git a/libc/bionic/sched_getaffinity.c b/libc/bionic/sched_getaffinity.c
new file mode 100644
index 0000000..7313822
--- /dev/null
+++ b/libc/bionic/sched_getaffinity.c
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+#define _GNU_SOURCE 1
+#include <sched.h>
+
+int sched_getaffinity(pid_t pid, size_t setsize, cpu_set_t* set)
+{
+ int ret = __sched_getaffinity(pid, setsize, set);
+ if (ret >= 0) {
+ if ((size_t)ret < setsize) {
+ memset((char*)set + ret, '\0', setsize - (size_t)ret);
+ }
+ ret = 0;
+ }
+ return ret;
+}
diff --git a/libc/bionic/sched_getcpu.c b/libc/bionic/sched_getcpu.c
new file mode 100644
index 0000000..954df37
--- /dev/null
+++ b/libc/bionic/sched_getcpu.c
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+#define _GNU_SOURCE 1
+#include <sched.h>
+
+extern int __getcpu(unsigned *cpu, unsigned *node, void* unused);
+
+int sched_getcpu(void)
+{
+ unsigned cpu;
+ if (__getcpu(&cpu, NULL, NULL) < 0)
+ return 0;
+
+ return (int)cpu;
+}
diff --git a/libc/bionic/stubs.c b/libc/bionic/stubs.c
index d495674..a01d64c 100644
--- a/libc/bionic/stubs.c
+++ b/libc/bionic/stubs.c
@@ -40,8 +40,8 @@
/** Thread-specific state for the stubs functions
**/
-pthread_once_t the_once = PTHREAD_ONCE_INIT;
-pthread_key_t the_key;
+static pthread_once_t the_once = PTHREAD_ONCE_INIT;
+static pthread_key_t the_key;
typedef struct {
struct passwd passwd;
diff --git a/libc/bionic/time64.c b/libc/bionic/time64.c
index 1e1f881..9aa5d4f 100644
--- a/libc/bionic/time64.c
+++ b/libc/bionic/time64.c
@@ -364,7 +364,7 @@
}
-void copy_tm_to_TM(const struct tm *src, struct TM *dest) {
+static void copy_tm_to_TM(const struct tm *src, struct TM *dest) {
if( src == NULL ) {
memset(dest, 0, sizeof(*dest));
}
@@ -396,7 +396,7 @@
}
-void copy_TM_to_tm(const struct TM *src, struct tm *dest) {
+static void copy_TM_to_tm(const struct TM *src, struct tm *dest) {
if( src == NULL ) {
memset(dest, 0, sizeof(*dest));
}
@@ -735,14 +735,14 @@
}
-int valid_tm_wday( const struct TM* date ) {
+static int valid_tm_wday( const struct TM* date ) {
if( 0 <= date->tm_wday && date->tm_wday <= 6 )
return 1;
else
return 0;
}
-int valid_tm_mon( const struct TM* date ) {
+static int valid_tm_mon( const struct TM* date ) {
if( 0 <= date->tm_mon && date->tm_mon <= 11 )
return 1;
else
diff --git a/libc/bionic/time64_config.h b/libc/bionic/time64_config.h
index 53bcecf..1385045 100644
--- a/libc/bionic/time64_config.h
+++ b/libc/bionic/time64_config.h
@@ -33,7 +33,7 @@
*/
#define HAS_GMTIME_R
#define HAS_LOCALTIME_R
-/*#define HAS_TIMEGM */
+#define HAS_TIMEGM
/* Details of non-standard tm struct elements.
diff --git a/libc/docs/CHANGES.TXT b/libc/docs/CHANGES.TXT
index 4d094d0..98b7fcf 100644
--- a/libc/docs/CHANGES.TXT
+++ b/libc/docs/CHANGES.TXT
@@ -1,7 +1,26 @@
Bionic ChangeLog:
-----------------
-Differences between current and Android 2.2:
+Differences between current and Android 2.3:
+
+- <android/api-level.h>: Added new header to define __ANDROID_API__ to
+ a constant integer corresponding to the native API level. This header
+ also exists in the NDK's platform headers.
+
+- <sys/cdefs.h>: Include <android/api-level.h>
+
+- <time.h>: Add timegm(), timelocal(), time2posix() and posix2time()
+
+- <sched.h>: Add sched_getcpu(), sched_getaffinity(), sched_setaffinity(),
+ cpu_set_t and related macros (e.g. CPU_SETSIZE, CPU_ZERO, CPU_SET, ...)
+
+- <unistd.h>: Add ftruncate64().
+
+- <signal.h>: Changed the definition of SIGRTMAX to 64. However, note that
+ sigset_t is only 32-bit and cannot deal with real-time signals.
+
+-------------------------------------------------------------------------------
+Differences between Android 2.3 and Android 2.2:
- <pthread.h>: Add reader/writer locks implementation. Add sanity
checking to pthread_mutex_destroy() (e.g. a locked mutex will return
@@ -70,6 +89,8 @@
- <sys/vfs.h>: fixed implementation of fstatfs() (also fixes fpathconf()
which uses it).
+- Added an implementation of pthread_atfork()
+
- <dlfcn.h>: fixed dlopen() implementation to support dlopen(NULL, ...).
This allows one to look at the dynamic symbols exported by an executable.
diff --git a/libc/include/android/api-level.h b/libc/include/android/api-level.h
new file mode 100644
index 0000000..611fdfb
--- /dev/null
+++ b/libc/include/android/api-level.h
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+#ifndef ANDROID_API_LEVEL_H
+#define ANDROID_API_LEVEL_H
+
+#define __ANDROID_API__ 10
+
+#endif /* ANDROID_API_LEVEL_H */
diff --git a/libc/include/byteswap.h b/libc/include/byteswap.h
index 16d2ad4..74b0e91 100644
--- a/libc/include/byteswap.h
+++ b/libc/include/byteswap.h
@@ -28,7 +28,8 @@
#ifndef _BYTESWAP_H_
#define _BYTESWAP_H_
-#include <sys/endian.h>
+/* endian.h rather than sys/endian.h so we get the machine-specific file. */
+#include <endian.h>
#define bswap_16(x) swap16(x)
#define bswap_32(x) swap32(x)
diff --git a/libc/include/net/if_ether.h b/libc/include/net/if_ether.h
index 121f9ac..8daa16b 100644
--- a/libc/include/net/if_ether.h
+++ b/libc/include/net/if_ether.h
@@ -34,6 +34,8 @@
#ifndef _NET_IF_ETHER_H_
#define _NET_IF_ETHER_H_
+#include <sys/types.h>
+
#ifdef _KERNEL
#ifdef _KERNEL_OPT
#include "opt_mbuftrace.h"
diff --git a/libc/include/netdb.h b/libc/include/netdb.h
index c2e08ea..9491364 100644
--- a/libc/include/netdb.h
+++ b/libc/include/netdb.h
@@ -209,8 +209,8 @@
void endprotoent(void);
void endservent(void);
void freehostent(struct hostent *);
-struct hostent *gethostbyaddr(const char *, int, int);
-int gethostbyaddr_r(const char *, int, int, struct hostent *, char *, size_t, struct hostent **, int *);
+struct hostent *gethostbyaddr(const void *, int, int);
+int gethostbyaddr_r(const void *, int, int, struct hostent *, char *, size_t, struct hostent **, int *);
struct hostent *gethostbyname(const char *);
int gethostbyname_r(const char *, struct hostent *, char *, size_t, struct hostent **, int *);
struct hostent *gethostbyname2(const char *, int);
diff --git a/libc/include/netinet/icmp6.h b/libc/include/netinet/icmp6.h
new file mode 100644
index 0000000..fbc8234
--- /dev/null
+++ b/libc/include/netinet/icmp6.h
@@ -0,0 +1,730 @@
+/* $NetBSD: icmp6.h,v 1.40 2009/10/31 22:32:17 christos Exp $ */
+/* $KAME: icmp6.h,v 1.84 2003/04/23 10:26:51 itojun Exp $ */
+
+
+/*
+ * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the project 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 PROJECT 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 PROJECT OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+ * Copyright (c) 1982, 1986, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)ip_icmp.h 8.1 (Berkeley) 6/10/93
+ */
+
+#ifndef _NETINET_ICMP6_H_
+#define _NETINET_ICMP6_H_
+
+#define ICMPV6_PLD_MAXLEN 1232 /* IPV6_MMTU - sizeof(struct ip6_hdr)
+ - sizeof(struct icmp6_hdr) */
+
+struct icmp6_hdr {
+ u_int8_t icmp6_type; /* type field */
+ u_int8_t icmp6_code; /* code field */
+ u_int16_t icmp6_cksum; /* checksum field */
+ union {
+ u_int32_t icmp6_un_data32[1]; /* type-specific field */
+ u_int16_t icmp6_un_data16[2]; /* type-specific field */
+ u_int8_t icmp6_un_data8[4]; /* type-specific field */
+ } icmp6_dataun;
+} __packed;
+
+#define icmp6_data32 icmp6_dataun.icmp6_un_data32
+#define icmp6_data16 icmp6_dataun.icmp6_un_data16
+#define icmp6_data8 icmp6_dataun.icmp6_un_data8
+#define icmp6_pptr icmp6_data32[0] /* parameter prob */
+#define icmp6_mtu icmp6_data32[0] /* packet too big */
+#define icmp6_id icmp6_data16[0] /* echo request/reply */
+#define icmp6_seq icmp6_data16[1] /* echo request/reply */
+#define icmp6_maxdelay icmp6_data16[0] /* mcast group membership */
+
+#define ICMP6_DST_UNREACH 1 /* dest unreachable, codes: */
+#define ICMP6_PACKET_TOO_BIG 2 /* packet too big */
+#define ICMP6_TIME_EXCEEDED 3 /* time exceeded, code: */
+#define ICMP6_PARAM_PROB 4 /* ip6 header bad */
+
+#define ICMP6_ECHO_REQUEST 128 /* echo service */
+#define ICMP6_ECHO_REPLY 129 /* echo reply */
+#define MLD_LISTENER_QUERY 130 /* multicast listener query */
+#define MLD_LISTENER_REPORT 131 /* multicast listener report */
+#define MLD_LISTENER_DONE 132 /* multicast listener done */
+
+/* RFC2292 decls */
+#define ICMP6_MEMBERSHIP_QUERY 130 /* group membership query */
+#define ICMP6_MEMBERSHIP_REPORT 131 /* group membership report */
+#define ICMP6_MEMBERSHIP_REDUCTION 132 /* group membership termination */
+
+#ifndef _KERNEL
+/* the followings are for backward compatibility to old KAME apps. */
+#define MLD6_LISTENER_QUERY MLD_LISTENER_QUERY
+#define MLD6_LISTENER_REPORT MLD_LISTENER_REPORT
+#define MLD6_LISTENER_DONE MLD_LISTENER_DONE
+#endif
+
+#define ND_ROUTER_SOLICIT 133 /* router solicitation */
+#define ND_ROUTER_ADVERT 134 /* router advertisement */
+#define ND_NEIGHBOR_SOLICIT 135 /* neighbor solicitation */
+#define ND_NEIGHBOR_ADVERT 136 /* neighbor advertisement */
+#define ND_REDIRECT 137 /* redirect */
+
+#define ICMP6_ROUTER_RENUMBERING 138 /* router renumbering */
+
+#define ICMP6_WRUREQUEST 139 /* who are you request */
+#define ICMP6_WRUREPLY 140 /* who are you reply */
+#define ICMP6_FQDN_QUERY 139 /* FQDN query */
+#define ICMP6_FQDN_REPLY 140 /* FQDN reply */
+#define ICMP6_NI_QUERY 139 /* node information request */
+#define ICMP6_NI_REPLY 140 /* node information reply */
+
+/* The definitions below are experimental. TBA */
+#define MLD_MTRACE_RESP 200 /* mtrace response(to sender) */
+#define MLD_MTRACE 201 /* mtrace messages */
+
+#ifndef _KERNEL
+/* the followings are for backward compatibility to old KAME apps. */
+#define MLD6_MTRACE_RESP MLD_MTRACE_RESP
+#define MLD6_MTRACE MLD_MTRACE
+#endif
+
+#define ICMP6_MAXTYPE 201
+
+#define ICMP6_DST_UNREACH_NOROUTE 0 /* no route to destination */
+#define ICMP6_DST_UNREACH_ADMIN 1 /* administratively prohibited */
+#define ICMP6_DST_UNREACH_NOTNEIGHBOR 2 /* not a neighbor(obsolete) */
+#define ICMP6_DST_UNREACH_BEYONDSCOPE 2 /* beyond scope of source address */
+#define ICMP6_DST_UNREACH_ADDR 3 /* address unreachable */
+#define ICMP6_DST_UNREACH_NOPORT 4 /* port unreachable */
+
+#define ICMP6_TIME_EXCEED_TRANSIT 0 /* ttl==0 in transit */
+#define ICMP6_TIME_EXCEED_REASSEMBLY 1 /* ttl==0 in reass */
+
+#define ICMP6_PARAMPROB_HEADER 0 /* erroneous header field */
+#define ICMP6_PARAMPROB_NEXTHEADER 1 /* unrecognized next header */
+#define ICMP6_PARAMPROB_OPTION 2 /* unrecognized option */
+
+#define ICMP6_INFOMSG_MASK 0x80 /* all informational messages */
+
+#define ICMP6_NI_SUBJ_IPV6 0 /* Query Subject is an IPv6 address */
+#define ICMP6_NI_SUBJ_FQDN 1 /* Query Subject is a Domain name */
+#define ICMP6_NI_SUBJ_IPV4 2 /* Query Subject is an IPv4 address */
+
+#define ICMP6_NI_SUCCESS 0 /* node information successful reply */
+#define ICMP6_NI_REFUSED 1 /* node information request is refused */
+#define ICMP6_NI_UNKNOWN 2 /* unknown Qtype */
+
+#define ICMP6_ROUTER_RENUMBERING_COMMAND 0 /* rr command */
+#define ICMP6_ROUTER_RENUMBERING_RESULT 1 /* rr result */
+#define ICMP6_ROUTER_RENUMBERING_SEQNUM_RESET 255 /* rr seq num reset */
+
+/* Used in kernel only */
+#define ND_REDIRECT_ONLINK 0 /* redirect to an on-link node */
+#define ND_REDIRECT_ROUTER 1 /* redirect to a better router */
+
+/*
+ * Multicast Listener Discovery
+ */
+struct mld_hdr {
+ struct icmp6_hdr mld_icmp6_hdr;
+ struct in6_addr mld_addr; /* multicast address */
+} __packed;
+
+/* definitions to provide backward compatibility to old KAME applications */
+#ifndef _KERNEL
+#define mld6_hdr mld_hdr
+#define mld6_type mld_type
+#define mld6_code mld_code
+#define mld6_cksum mld_cksum
+#define mld6_maxdelay mld_maxdelay
+#define mld6_reserved mld_reserved
+#define mld6_addr mld_addr
+#endif
+
+/* shortcut macro definitions */
+#define mld_type mld_icmp6_hdr.icmp6_type
+#define mld_code mld_icmp6_hdr.icmp6_code
+#define mld_cksum mld_icmp6_hdr.icmp6_cksum
+#define mld_maxdelay mld_icmp6_hdr.icmp6_data16[0]
+#define mld_reserved mld_icmp6_hdr.icmp6_data16[1]
+
+#define MLD_MINLEN 24
+
+/*
+ * Neighbor Discovery
+ */
+
+struct nd_router_solicit { /* router solicitation */
+ struct icmp6_hdr nd_rs_hdr;
+ /* could be followed by options */
+} __packed;
+
+#define nd_rs_type nd_rs_hdr.icmp6_type
+#define nd_rs_code nd_rs_hdr.icmp6_code
+#define nd_rs_cksum nd_rs_hdr.icmp6_cksum
+#define nd_rs_reserved nd_rs_hdr.icmp6_data32[0]
+
+struct nd_router_advert { /* router advertisement */
+ struct icmp6_hdr nd_ra_hdr;
+ u_int32_t nd_ra_reachable; /* reachable time */
+ u_int32_t nd_ra_retransmit; /* retransmit timer */
+ /* could be followed by options */
+} __packed;
+
+#define nd_ra_type nd_ra_hdr.icmp6_type
+#define nd_ra_code nd_ra_hdr.icmp6_code
+#define nd_ra_cksum nd_ra_hdr.icmp6_cksum
+#define nd_ra_curhoplimit nd_ra_hdr.icmp6_data8[0]
+#define nd_ra_flags_reserved nd_ra_hdr.icmp6_data8[1]
+#define ND_RA_FLAG_MANAGED 0x80
+#define ND_RA_FLAG_OTHER 0x40
+#define ND_RA_FLAG_HOME_AGENT 0x20
+
+/*
+ * Router preference values based on RFC4199.
+ */
+#define ND_RA_FLAG_RTPREF_MASK 0x18 /* 00011000 */
+
+#define ND_RA_FLAG_RTPREF_HIGH 0x08 /* 00001000 */
+#define ND_RA_FLAG_RTPREF_MEDIUM 0x00 /* 00000000 */
+#define ND_RA_FLAG_RTPREF_LOW 0x18 /* 00011000 */
+#define ND_RA_FLAG_RTPREF_RSV 0x10 /* 00010000 */
+
+#define nd_ra_router_lifetime nd_ra_hdr.icmp6_data16[1]
+
+struct nd_neighbor_solicit { /* neighbor solicitation */
+ struct icmp6_hdr nd_ns_hdr;
+ struct in6_addr nd_ns_target; /*target address */
+ /* could be followed by options */
+} __packed;
+
+#define nd_ns_type nd_ns_hdr.icmp6_type
+#define nd_ns_code nd_ns_hdr.icmp6_code
+#define nd_ns_cksum nd_ns_hdr.icmp6_cksum
+#define nd_ns_reserved nd_ns_hdr.icmp6_data32[0]
+
+struct nd_neighbor_advert { /* neighbor advertisement */
+ struct icmp6_hdr nd_na_hdr;
+ struct in6_addr nd_na_target; /* target address */
+ /* could be followed by options */
+} __packed;
+
+#define nd_na_type nd_na_hdr.icmp6_type
+#define nd_na_code nd_na_hdr.icmp6_code
+#define nd_na_cksum nd_na_hdr.icmp6_cksum
+#define nd_na_flags_reserved nd_na_hdr.icmp6_data32[0]
+#if BYTE_ORDER == BIG_ENDIAN
+#define ND_NA_FLAG_ROUTER 0x80000000
+#define ND_NA_FLAG_SOLICITED 0x40000000
+#define ND_NA_FLAG_OVERRIDE 0x20000000
+#else
+#if BYTE_ORDER == LITTLE_ENDIAN
+#define ND_NA_FLAG_ROUTER 0x80
+#define ND_NA_FLAG_SOLICITED 0x40
+#define ND_NA_FLAG_OVERRIDE 0x20
+#endif
+#endif
+
+struct nd_redirect { /* redirect */
+ struct icmp6_hdr nd_rd_hdr;
+ struct in6_addr nd_rd_target; /* target address */
+ struct in6_addr nd_rd_dst; /* destination address */
+ /* could be followed by options */
+} __packed;
+
+#define nd_rd_type nd_rd_hdr.icmp6_type
+#define nd_rd_code nd_rd_hdr.icmp6_code
+#define nd_rd_cksum nd_rd_hdr.icmp6_cksum
+#define nd_rd_reserved nd_rd_hdr.icmp6_data32[0]
+
+struct nd_opt_hdr { /* Neighbor discovery option header */
+ u_int8_t nd_opt_type;
+ u_int8_t nd_opt_len;
+ /* followed by option specific data*/
+} __packed;
+
+#define ND_OPT_SOURCE_LINKADDR 1
+#define ND_OPT_TARGET_LINKADDR 2
+#define ND_OPT_PREFIX_INFORMATION 3
+#define ND_OPT_REDIRECTED_HEADER 4
+#define ND_OPT_MTU 5
+#define ND_OPT_ADVINTERVAL 7
+#define ND_OPT_HOMEAGENT_INFO 8
+#define ND_OPT_SOURCE_ADDRLIST 9
+#define ND_OPT_TARGET_ADDRLIST 10
+#define ND_OPT_RDNSS 25
+/* draft-ietf-ipngwg-router-preference, not officially assigned yet */
+#define ND_OPT_ROUTE_INFO 200
+/* draft-ietf-mobileip-hmipv6, not officially assigned yet */
+#define ND_OPT_MAP 201
+
+struct nd_opt_route_info { /* route info */
+ u_int8_t nd_opt_rti_type;
+ u_int8_t nd_opt_rti_len;
+ u_int8_t nd_opt_rti_prefixlen;
+ u_int8_t nd_opt_rti_flags;
+ u_int32_t nd_opt_rti_lifetime;
+ /* prefix follows */
+};
+
+struct nd_opt_prefix_info { /* prefix information */
+ u_int8_t nd_opt_pi_type;
+ u_int8_t nd_opt_pi_len;
+ u_int8_t nd_opt_pi_prefix_len;
+ u_int8_t nd_opt_pi_flags_reserved;
+ u_int32_t nd_opt_pi_valid_time;
+ u_int32_t nd_opt_pi_preferred_time;
+ u_int32_t nd_opt_pi_reserved2;
+ struct in6_addr nd_opt_pi_prefix;
+} __packed;
+
+#define ND_OPT_PI_FLAG_ONLINK 0x80
+#define ND_OPT_PI_FLAG_AUTO 0x40
+
+struct nd_opt_rd_hdr { /* redirected header */
+ u_int8_t nd_opt_rh_type;
+ u_int8_t nd_opt_rh_len;
+ u_int16_t nd_opt_rh_reserved1;
+ u_int32_t nd_opt_rh_reserved2;
+ /* followed by IP header and data */
+} __packed;
+
+struct nd_opt_mtu { /* MTU option */
+ u_int8_t nd_opt_mtu_type;
+ u_int8_t nd_opt_mtu_len;
+ u_int16_t nd_opt_mtu_reserved;
+ u_int32_t nd_opt_mtu_mtu;
+} __packed;
+
+struct nd_opt_rdnss { /* RDNSS option RFC 5006 */
+ u_int8_t nd_opt_rdnss_type;
+ u_int8_t nd_opt_rdnss_len;
+ u_int16_t nd_opt_rdnss_reserved;
+ u_int32_t nd_opt_rdnss_lifetime;
+ /* followed by list of IP prefixes */
+} __packed;
+
+/*
+ * icmp6 namelookup
+ */
+
+struct icmp6_namelookup {
+ struct icmp6_hdr icmp6_nl_hdr;
+ u_int8_t icmp6_nl_nonce[8];
+ int32_t icmp6_nl_ttl;
+#if 0
+ u_int8_t icmp6_nl_len;
+ u_int8_t icmp6_nl_name[3];
+#endif
+ /* could be followed by options */
+} __packed;
+
+/*
+ * icmp6 node information
+ */
+struct icmp6_nodeinfo {
+ struct icmp6_hdr icmp6_ni_hdr;
+ u_int8_t icmp6_ni_nonce[8];
+ /* could be followed by reply data */
+} __packed;
+
+#define ni_type icmp6_ni_hdr.icmp6_type
+#define ni_code icmp6_ni_hdr.icmp6_code
+#define ni_cksum icmp6_ni_hdr.icmp6_cksum
+#define ni_qtype icmp6_ni_hdr.icmp6_data16[0]
+#define ni_flags icmp6_ni_hdr.icmp6_data16[1]
+
+#define NI_QTYPE_NOOP 0 /* NOOP */
+#define NI_QTYPE_SUPTYPES 1 /* Supported Qtypes */
+#define NI_QTYPE_FQDN 2 /* FQDN (draft 04) */
+#define NI_QTYPE_DNSNAME 2 /* DNS Name */
+#define NI_QTYPE_NODEADDR 3 /* Node Addresses */
+#define NI_QTYPE_IPV4ADDR 4 /* IPv4 Addresses */
+
+#if BYTE_ORDER == BIG_ENDIAN
+#define NI_SUPTYPE_FLAG_COMPRESS 0x1
+#define NI_FQDN_FLAG_VALIDTTL 0x1
+#elif BYTE_ORDER == LITTLE_ENDIAN
+#define NI_SUPTYPE_FLAG_COMPRESS 0x0100
+#define NI_FQDN_FLAG_VALIDTTL 0x0100
+#endif
+
+#ifdef NAME_LOOKUPS_04
+#if BYTE_ORDER == BIG_ENDIAN
+#define NI_NODEADDR_FLAG_LINKLOCAL 0x1
+#define NI_NODEADDR_FLAG_SITELOCAL 0x2
+#define NI_NODEADDR_FLAG_GLOBAL 0x4
+#define NI_NODEADDR_FLAG_ALL 0x8
+#define NI_NODEADDR_FLAG_TRUNCATE 0x10
+#define NI_NODEADDR_FLAG_ANYCAST 0x20 /* just experimental. not in spec */
+#elif BYTE_ORDER == LITTLE_ENDIAN
+#define NI_NODEADDR_FLAG_LINKLOCAL 0x0100
+#define NI_NODEADDR_FLAG_SITELOCAL 0x0200
+#define NI_NODEADDR_FLAG_GLOBAL 0x0400
+#define NI_NODEADDR_FLAG_ALL 0x0800
+#define NI_NODEADDR_FLAG_TRUNCATE 0x1000
+#define NI_NODEADDR_FLAG_ANYCAST 0x2000 /* just experimental. not in spec */
+#endif
+#else /* draft-ietf-ipngwg-icmp-name-lookups-05 (and later?) */
+#if BYTE_ORDER == BIG_ENDIAN
+#define NI_NODEADDR_FLAG_TRUNCATE 0x1
+#define NI_NODEADDR_FLAG_ALL 0x2
+#define NI_NODEADDR_FLAG_COMPAT 0x4
+#define NI_NODEADDR_FLAG_LINKLOCAL 0x8
+#define NI_NODEADDR_FLAG_SITELOCAL 0x10
+#define NI_NODEADDR_FLAG_GLOBAL 0x20
+#define NI_NODEADDR_FLAG_ANYCAST 0x40 /* just experimental. not in spec */
+#elif BYTE_ORDER == LITTLE_ENDIAN
+#define NI_NODEADDR_FLAG_TRUNCATE 0x0100
+#define NI_NODEADDR_FLAG_ALL 0x0200
+#define NI_NODEADDR_FLAG_COMPAT 0x0400
+#define NI_NODEADDR_FLAG_LINKLOCAL 0x0800
+#define NI_NODEADDR_FLAG_SITELOCAL 0x1000
+#define NI_NODEADDR_FLAG_GLOBAL 0x2000
+#define NI_NODEADDR_FLAG_ANYCAST 0x4000 /* just experimental. not in spec */
+#endif
+#endif
+
+struct ni_reply_fqdn {
+ u_int32_t ni_fqdn_ttl; /* TTL */
+ u_int8_t ni_fqdn_namelen; /* length in octets of the FQDN */
+ u_int8_t ni_fqdn_name[3]; /* XXX: alignment */
+} __packed;
+
+/*
+ * Router Renumbering. as router-renum-08.txt
+ */
+struct icmp6_router_renum { /* router renumbering header */
+ struct icmp6_hdr rr_hdr;
+ u_int8_t rr_segnum;
+ u_int8_t rr_flags;
+ u_int16_t rr_maxdelay;
+ u_int32_t rr_reserved;
+} __packed;
+
+#define ICMP6_RR_FLAGS_TEST 0x80
+#define ICMP6_RR_FLAGS_REQRESULT 0x40
+#define ICMP6_RR_FLAGS_FORCEAPPLY 0x20
+#define ICMP6_RR_FLAGS_SPECSITE 0x10
+#define ICMP6_RR_FLAGS_PREVDONE 0x08
+
+#define rr_type rr_hdr.icmp6_type
+#define rr_code rr_hdr.icmp6_code
+#define rr_cksum rr_hdr.icmp6_cksum
+#define rr_seqnum rr_hdr.icmp6_data32[0]
+
+struct rr_pco_match { /* match prefix part */
+ u_int8_t rpm_code;
+ u_int8_t rpm_len;
+ u_int8_t rpm_ordinal;
+ u_int8_t rpm_matchlen;
+ u_int8_t rpm_minlen;
+ u_int8_t rpm_maxlen;
+ u_int16_t rpm_reserved;
+ struct in6_addr rpm_prefix;
+} __packed;
+
+#define RPM_PCO_ADD 1
+#define RPM_PCO_CHANGE 2
+#define RPM_PCO_SETGLOBAL 3
+#define RPM_PCO_MAX 4
+
+struct rr_pco_use { /* use prefix part */
+ u_int8_t rpu_uselen;
+ u_int8_t rpu_keeplen;
+ u_int8_t rpu_ramask;
+ u_int8_t rpu_raflags;
+ u_int32_t rpu_vltime;
+ u_int32_t rpu_pltime;
+ u_int32_t rpu_flags;
+ struct in6_addr rpu_prefix;
+} __packed;
+#define ICMP6_RR_PCOUSE_RAFLAGS_ONLINK 0x80
+#define ICMP6_RR_PCOUSE_RAFLAGS_AUTO 0x40
+
+#if BYTE_ORDER == BIG_ENDIAN
+#define ICMP6_RR_PCOUSE_FLAGS_DECRVLTIME 0x80000000
+#define ICMP6_RR_PCOUSE_FLAGS_DECRPLTIME 0x40000000
+#elif BYTE_ORDER == LITTLE_ENDIAN
+#define ICMP6_RR_PCOUSE_FLAGS_DECRVLTIME 0x80
+#define ICMP6_RR_PCOUSE_FLAGS_DECRPLTIME 0x40
+#endif
+
+struct rr_result { /* router renumbering result message */
+ u_int16_t rrr_flags;
+ u_int8_t rrr_ordinal;
+ u_int8_t rrr_matchedlen;
+ u_int32_t rrr_ifid;
+ struct in6_addr rrr_prefix;
+} __packed;
+#if BYTE_ORDER == BIG_ENDIAN
+#define ICMP6_RR_RESULT_FLAGS_OOB 0x0002
+#define ICMP6_RR_RESULT_FLAGS_FORBIDDEN 0x0001
+#elif BYTE_ORDER == LITTLE_ENDIAN
+#define ICMP6_RR_RESULT_FLAGS_OOB 0x0200
+#define ICMP6_RR_RESULT_FLAGS_FORBIDDEN 0x0100
+#endif
+
+/*
+ * icmp6 filter structures.
+ */
+
+struct icmp6_filter {
+ u_int32_t icmp6_filt[8];
+};
+
+#define ICMP6_FILTER_SETPASSALL(filterp) \
+ (void)memset(filterp, 0xff, sizeof(struct icmp6_filter))
+#define ICMP6_FILTER_SETBLOCKALL(filterp) \
+ (void)memset(filterp, 0x00, sizeof(struct icmp6_filter))
+#define ICMP6_FILTER_SETPASS(type, filterp) \
+ (((filterp)->icmp6_filt[(type) >> 5]) |= (1 << ((type) & 31)))
+#define ICMP6_FILTER_SETBLOCK(type, filterp) \
+ (((filterp)->icmp6_filt[(type) >> 5]) &= ~(1 << ((type) & 31)))
+#define ICMP6_FILTER_WILLPASS(type, filterp) \
+ ((((filterp)->icmp6_filt[(type) >> 5]) & (1 << ((type) & 31))) != 0)
+#define ICMP6_FILTER_WILLBLOCK(type, filterp) \
+ ((((filterp)->icmp6_filt[(type) >> 5]) & (1 << ((type) & 31))) == 0)
+
+/*
+ * Variables related to this implementation
+ * of the internet control message protocol version 6.
+ */
+
+/*
+ * IPv6 ICMP statistics.
+ * Each counter is an unsigned 64-bit value.
+ */
+#define ICMP6_STAT_ERROR 0 /* # of calls to icmp6_error */
+#define ICMP6_STAT_CANTERROR 1 /* no error (old was icmp) */
+#define ICMP6_STAT_TOOFREQ 2 /* no error (rate limitation) */
+#define ICMP6_STAT_OUTHIST 3 /* # of output messages */
+ /* space for 256 counters */
+#define ICMP6_STAT_BADCODE 259 /* icmp6_code out of range */
+#define ICMP6_STAT_TOOSHORT 260 /* packet < sizeof(struct icmp6_hdr) */
+#define ICMP6_STAT_CHECKSUM 261 /* bad checksum */
+#define ICMP6_STAT_BADLEN 262 /* calculated bound mismatch */
+ /*
+ * number of responses; this member is inherited from the netinet code,
+ * but for netinet6 code, it is already available in outhist[].
+ */
+#define ICMP6_STAT_REFLECT 263
+#define ICMP6_STAT_INHIST 264 /* # of input messages */
+ /* space for 256 counters */
+#define ICMP6_STAT_ND_TOOMANYOPT 520 /* too many ND options */
+#define ICMP6_STAT_OUTERRHIST 521
+ /* space for 13 counters */
+#define ICMP6_STAT_PMTUCHG 534 /* path MTU changes */
+#define ICMP6_STAT_ND_BADOPT 535 /* bad ND options */
+#define ICMP6_STAT_BADNS 536 /* bad neighbor solicititation */
+#define ICMP6_STAT_BADNA 537 /* bad neighbor advertisement */
+#define ICMP6_STAT_BADRS 538 /* bad router solicitiation */
+#define ICMP6_STAT_BADRA 539 /* bad router advertisement */
+#define ICMP6_STAT_BADREDIRECT 540 /* bad redirect message */
+
+#define ICMP6_NSTATS 541
+
+#define ICMP6_ERRSTAT_DST_UNREACH_NOROUTE 0
+#define ICMP6_ERRSTAT_DST_UNREACH_ADMIN 1
+#define ICMP6_ERRSTAT_DST_UNREACH_BEYONDSCOPE 2
+#define ICMP6_ERRSTAT_DST_UNREACH_ADDR 3
+#define ICMP6_ERRSTAT_DST_UNREACH_NOPORT 4
+#define ICMP6_ERRSTAT_PACKET_TOO_BIG 5
+#define ICMP6_ERRSTAT_TIME_EXCEED_TRANSIT 6
+#define ICMP6_ERRSTAT_TIME_EXCEED_REASSEMBLY 7
+#define ICMP6_ERRSTAT_PARAMPROB_HEADER 8
+#define ICMP6_ERRSTAT_PARAMPROB_NEXTHEADER 9
+#define ICMP6_ERRSTAT_PARAMPROB_OPTION 10
+#define ICMP6_ERRSTAT_REDIRECT 11
+#define ICMP6_ERRSTAT_UNKNOWN 12
+
+/*
+ * Names for ICMP sysctl objects
+ */
+#define ICMPV6CTL_STATS 1
+#define ICMPV6CTL_REDIRACCEPT 2 /* accept/process redirects */
+#define ICMPV6CTL_REDIRTIMEOUT 3 /* redirect cache time */
+#if 0 /*obsoleted*/
+#define ICMPV6CTL_ERRRATELIMIT 5 /* ICMPv6 error rate limitation */
+#endif
+#define ICMPV6CTL_ND6_PRUNE 6
+#define ICMPV6CTL_ND6_DELAY 8
+#define ICMPV6CTL_ND6_UMAXTRIES 9
+#define ICMPV6CTL_ND6_MMAXTRIES 10
+#define ICMPV6CTL_ND6_USELOOPBACK 11
+/*#define ICMPV6CTL_ND6_PROXYALL 12 obsoleted, do not reuse here */
+#define ICMPV6CTL_NODEINFO 13
+#define ICMPV6CTL_ERRPPSLIMIT 14 /* ICMPv6 error pps limitation */
+#define ICMPV6CTL_ND6_MAXNUDHINT 15
+#define ICMPV6CTL_MTUDISC_HIWAT 16
+#define ICMPV6CTL_MTUDISC_LOWAT 17
+#define ICMPV6CTL_ND6_DEBUG 18
+#define ICMPV6CTL_ND6_DRLIST 19
+#define ICMPV6CTL_ND6_PRLIST 20
+#define ICMPV6CTL_ND6_MAXQLEN 24
+#define ICMPV6CTL_MAXID 25
+
+#define ICMPV6CTL_NAMES { \
+ { 0, 0 }, \
+ { 0, 0 }, \
+ { "rediraccept", CTLTYPE_INT }, \
+ { "redirtimeout", CTLTYPE_INT }, \
+ { 0, 0 }, \
+ { 0, 0 }, \
+ { "nd6_prune", CTLTYPE_INT }, \
+ { 0, 0 }, \
+ { "nd6_delay", CTLTYPE_INT }, \
+ { "nd6_umaxtries", CTLTYPE_INT }, \
+ { "nd6_mmaxtries", CTLTYPE_INT }, \
+ { "nd6_useloopback", CTLTYPE_INT }, \
+ { 0, 0 }, \
+ { "nodeinfo", CTLTYPE_INT }, \
+ { "errppslimit", CTLTYPE_INT }, \
+ { "nd6_maxnudhint", CTLTYPE_INT }, \
+ { "mtudisc_hiwat", CTLTYPE_INT }, \
+ { "mtudisc_lowat", CTLTYPE_INT }, \
+ { "nd6_debug", CTLTYPE_INT }, \
+ { 0, 0 }, \
+ { 0, 0 }, \
+ { 0, 0 }, \
+ { 0, 0 }, \
+ { 0, 0 }, \
+ { "nd6_maxqueuelen", CTLTYPE_INT }, \
+}
+
+#define RTF_PROBEMTU RTF_PROTO1
+
+#ifdef _KERNEL
+struct rtentry;
+struct rttimer;
+struct in6_multi;
+
+void icmp6_init(void);
+void icmp6_paramerror(struct mbuf *, int);
+void icmp6_error(struct mbuf *, int, int, int);
+void icmp6_error2(struct mbuf *, int, int, int, struct ifnet *);
+int icmp6_input(struct mbuf **, int *, int);
+void icmp6_fasttimo(void);
+void icmp6_reflect(struct mbuf *, size_t);
+void icmp6_prepare(struct mbuf *);
+void icmp6_redirect_input(struct mbuf *, int);
+void icmp6_redirect_output(struct mbuf *, struct rtentry *);
+int icmp6_sysctl(int *, u_int, void *, size_t *, void *, size_t);
+
+void icmp6_statinc(u_int);
+
+struct ip6ctlparam;
+void icmp6_mtudisc_update(struct ip6ctlparam *, int);
+void icmp6_mtudisc_callback_register(void (*)(struct in6_addr *));
+
+/* XXX: is this the right place for these macros? */
+#define icmp6_ifstat_inc(ifp, tag) \
+do { \
+ if (ifp) \
+ ((struct in6_ifextra *)((ifp)->if_afdata[AF_INET6]))->icmp6_ifstat->tag++; \
+} while (/*CONSTCOND*/ 0)
+
+#define icmp6_ifoutstat_inc(ifp, type, code) \
+do { \
+ icmp6_ifstat_inc(ifp, ifs6_out_msg); \
+ switch(type) { \
+ case ICMP6_DST_UNREACH: \
+ icmp6_ifstat_inc(ifp, ifs6_out_dstunreach); \
+ if (code == ICMP6_DST_UNREACH_ADMIN) \
+ icmp6_ifstat_inc(ifp, ifs6_out_adminprohib); \
+ break; \
+ case ICMP6_PACKET_TOO_BIG: \
+ icmp6_ifstat_inc(ifp, ifs6_out_pkttoobig); \
+ break; \
+ case ICMP6_TIME_EXCEEDED: \
+ icmp6_ifstat_inc(ifp, ifs6_out_timeexceed); \
+ break; \
+ case ICMP6_PARAM_PROB: \
+ icmp6_ifstat_inc(ifp, ifs6_out_paramprob); \
+ break; \
+ case ICMP6_ECHO_REQUEST: \
+ icmp6_ifstat_inc(ifp, ifs6_out_echo); \
+ break; \
+ case ICMP6_ECHO_REPLY: \
+ icmp6_ifstat_inc(ifp, ifs6_out_echoreply); \
+ break; \
+ case MLD_LISTENER_QUERY: \
+ icmp6_ifstat_inc(ifp, ifs6_out_mldquery); \
+ break; \
+ case MLD_LISTENER_REPORT: \
+ icmp6_ifstat_inc(ifp, ifs6_out_mldreport); \
+ break; \
+ case MLD_LISTENER_DONE: \
+ icmp6_ifstat_inc(ifp, ifs6_out_mlddone); \
+ break; \
+ case ND_ROUTER_SOLICIT: \
+ icmp6_ifstat_inc(ifp, ifs6_out_routersolicit); \
+ break; \
+ case ND_ROUTER_ADVERT: \
+ icmp6_ifstat_inc(ifp, ifs6_out_routeradvert); \
+ break; \
+ case ND_NEIGHBOR_SOLICIT: \
+ icmp6_ifstat_inc(ifp, ifs6_out_neighborsolicit); \
+ break; \
+ case ND_NEIGHBOR_ADVERT: \
+ icmp6_ifstat_inc(ifp, ifs6_out_neighboradvert); \
+ break; \
+ case ND_REDIRECT: \
+ icmp6_ifstat_inc(ifp, ifs6_out_redirect); \
+ break; \
+ } \
+} while (/*CONSTCOND*/ 0)
+
+extern int icmp6_rediraccept; /* accept/process redirects */
+extern int icmp6_redirtimeout; /* cache time for redirect routes */
+#endif /* _KERNEL */
+
+#endif /* !_NETINET_ICMP6_H_ */
diff --git a/libc/include/netinet/in.h b/libc/include/netinet/in.h
index 0ebd926..7a4b6c7 100644
--- a/libc/include/netinet/in.h
+++ b/libc/include/netinet/in.h
@@ -38,6 +38,8 @@
#define IPPORT_RESERVED 1024
+#define INET_ADDRSTRLEN 16
+
extern int bindresvport (int sd, struct sockaddr_in *sin);
static const struct in6_addr in6addr_any = IN6ADDR_ANY_INIT;
diff --git a/libc/include/netinet/in6.h b/libc/include/netinet/in6.h
index efd5c0a..580a510 100644
--- a/libc/include/netinet/in6.h
+++ b/libc/include/netinet/in6.h
@@ -78,6 +78,9 @@
#define IPV6_ADDR_MC_SCOPE(a) \
((a)->s6_addr[1] & 0x0f)
+#define IN6_IS_ADDR_MC_NODELOCAL(a) \
+ (IN6_IS_ADDR_MULTICAST(a) && \
+ (IPV6_ADDR_MC_SCOPE(a) == IPV6_ADDR_SCOPE_NODELOCAL))
#define IN6_IS_ADDR_MC_LINKLOCAL(a) \
(IN6_IS_ADDR_MULTICAST(a) && \
(IPV6_ADDR_MC_SCOPE(a) == IPV6_ADDR_SCOPE_LINKLOCAL))
@@ -87,7 +90,9 @@
#define IN6_IS_ADDR_MC_ORGLOCAL(a) \
(IN6_IS_ADDR_MULTICAST(a) && \
(IPV6_ADDR_MC_SCOPE(a) == IPV6_ADDR_SCOPE_ORGLOCAL))
-
+#define IN6_IS_ADDR_MC_GLOBAL(a) \
+ (IN6_IS_ADDR_MULTICAST(a) && \
+ (IPV6_ADDR_MC_SCOPE(a) == IPV6_ADDR_SCOPE_GLOBAL))
#define IN6_ARE_ADDR_EQUAL(a, b) \
(memcmp(&(a)->s6_addr[0], &(b)->s6_addr[0], sizeof(struct in6_addr)) == 0)
diff --git a/libc/include/netinet/ip.h b/libc/include/netinet/ip.h
index 541905c..629ed77 100644
--- a/libc/include/netinet/ip.h
+++ b/libc/include/netinet/ip.h
@@ -83,7 +83,7 @@
#define IPTOS_LOWDELAY 0x10
#define IPTOS_THROUGHPUT 0x08
#define IPTOS_RELIABILITY 0x04
-/* IPTOS_LOWCOST 0x02 XXX */
+#define IPTOS_MINCOST 0x02
#if 1
/* ECN RFC3168 obsoletes RFC2481, and these will be deprecated soon. */
#define IPTOS_CE 0x01 /* congestion experienced */
diff --git a/libc/include/netinet/ip6.h b/libc/include/netinet/ip6.h
new file mode 100644
index 0000000..aa816c2
--- /dev/null
+++ b/libc/include/netinet/ip6.h
@@ -0,0 +1,319 @@
+/* $NetBSD: ip6.h,v 1.23 2007/12/25 18:33:46 perry Exp $ */
+/* $KAME: ip6.h,v 1.45 2003/06/05 04:46:38 keiichi Exp $ */
+
+/*
+ * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the project 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 PROJECT 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 PROJECT OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+ * Copyright (c) 1982, 1986, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)ip.h 8.1 (Berkeley) 6/10/93
+ */
+
+#ifndef _NETINET_IP6_H_
+#define _NETINET_IP6_H_
+
+/*
+ * Definition for internet protocol version 6.
+ * RFC 2460
+ */
+
+struct ip6_hdr {
+ union {
+ struct ip6_hdrctl {
+ u_int32_t ip6_un1_flow; /* 20 bits of flow-ID */
+ u_int16_t ip6_un1_plen; /* payload length */
+ u_int8_t ip6_un1_nxt; /* next header */
+ u_int8_t ip6_un1_hlim; /* hop limit */
+ } ip6_un1;
+ u_int8_t ip6_un2_vfc; /* 4 bits version, top 4 bits class */
+ } ip6_ctlun;
+ struct in6_addr ip6_src; /* source address */
+ struct in6_addr ip6_dst; /* destination address */
+} __packed;
+
+#define ip6_vfc ip6_ctlun.ip6_un2_vfc
+#define ip6_flow ip6_ctlun.ip6_un1.ip6_un1_flow
+#define ip6_plen ip6_ctlun.ip6_un1.ip6_un1_plen
+#define ip6_nxt ip6_ctlun.ip6_un1.ip6_un1_nxt
+#define ip6_hlim ip6_ctlun.ip6_un1.ip6_un1_hlim
+#define ip6_hops ip6_ctlun.ip6_un1.ip6_un1_hlim
+
+#define IPV6_VERSION 0x60
+#define IPV6_VERSION_MASK 0xf0
+
+#if BYTE_ORDER == BIG_ENDIAN
+#define IPV6_FLOWINFO_MASK 0x0fffffff /* flow info (28 bits) */
+#define IPV6_FLOWLABEL_MASK 0x000fffff /* flow label (20 bits) */
+#else
+#if BYTE_ORDER == LITTLE_ENDIAN
+#define IPV6_FLOWINFO_MASK 0xffffff0f /* flow info (28 bits) */
+#define IPV6_FLOWLABEL_MASK 0xffff0f00 /* flow label (20 bits) */
+#endif /* LITTLE_ENDIAN */
+#endif
+#if 1
+/* ECN bits proposed by Sally Floyd */
+#define IP6TOS_CE 0x01 /* congestion experienced */
+#define IP6TOS_ECT 0x02 /* ECN-capable transport */
+#endif
+
+#ifdef _KERNEL
+/*
+ * for IPv6 pseudo header checksum
+ * XXX nonstandard
+ */
+struct ip6_hdr_pseudo {
+ struct in6_addr ip6ph_src;
+ struct in6_addr ip6ph_dst;
+ u_int32_t ip6ph_len;
+ u_int8_t ip6ph_zero[3];
+ u_int8_t ip6ph_nxt;
+} __packed;
+#endif
+
+/*
+ * Extension Headers
+ */
+
+struct ip6_ext {
+ u_int8_t ip6e_nxt;
+ u_int8_t ip6e_len;
+} __packed;
+
+/* Hop-by-Hop options header */
+/* XXX should we pad it to force alignment on an 8-byte boundary? */
+struct ip6_hbh {
+ u_int8_t ip6h_nxt; /* next header */
+ u_int8_t ip6h_len; /* length in units of 8 octets */
+ /* followed by options */
+} __packed;
+
+/* Destination options header */
+/* XXX should we pad it to force alignment on an 8-byte boundary? */
+struct ip6_dest {
+ u_int8_t ip6d_nxt; /* next header */
+ u_int8_t ip6d_len; /* length in units of 8 octets */
+ /* followed by options */
+} __packed;
+
+/* Option types and related macros */
+#define IP6OPT_PAD1 0x00 /* 00 0 00000 */
+#define IP6OPT_PADN 0x01 /* 00 0 00001 */
+#define IP6OPT_JUMBO 0xC2 /* 11 0 00010 = 194 */
+#define IP6OPT_NSAP_ADDR 0xC3 /* 11 0 00011 */
+#define IP6OPT_TUNNEL_LIMIT 0x04 /* 00 0 00100 */
+#define IP6OPT_RTALERT 0x05 /* 00 0 00101 (KAME definition) */
+#define IP6OPT_ROUTER_ALERT 0x05 /* (RFC3542 def, recommended) */
+
+#define IP6OPT_RTALERT_LEN 4
+#define IP6OPT_RTALERT_MLD 0 /* Datagram contains an MLD message */
+#define IP6OPT_RTALERT_RSVP 1 /* Datagram contains an RSVP message */
+#define IP6OPT_RTALERT_ACTNET 2 /* contains an Active Networks msg */
+#define IP6OPT_MINLEN 2
+
+#define IP6OPT_TYPE(o) ((o) & 0xC0)
+#define IP6OPT_TYPE_SKIP 0x00
+#define IP6OPT_TYPE_DISCARD 0x40
+#define IP6OPT_TYPE_FORCEICMP 0x80
+#define IP6OPT_TYPE_ICMP 0xC0
+
+#define IP6OPT_MUTABLE 0x20
+
+/* IPv6 options: common part */
+struct ip6_opt {
+ u_int8_t ip6o_type;
+ u_int8_t ip6o_len;
+} __packed;
+
+/* Jumbo Payload Option */
+struct ip6_opt_jumbo {
+ u_int8_t ip6oj_type;
+ u_int8_t ip6oj_len;
+ u_int8_t ip6oj_jumbo_len[4];
+} __packed;
+#define IP6OPT_JUMBO_LEN 6
+
+/* NSAP Address Option */
+struct ip6_opt_nsap {
+ u_int8_t ip6on_type;
+ u_int8_t ip6on_len;
+ u_int8_t ip6on_src_nsap_len;
+ u_int8_t ip6on_dst_nsap_len;
+ /* followed by source NSAP */
+ /* followed by destination NSAP */
+} __packed;
+
+/* Tunnel Limit Option */
+struct ip6_opt_tunnel {
+ u_int8_t ip6ot_type;
+ u_int8_t ip6ot_len;
+ u_int8_t ip6ot_encap_limit;
+} __packed;
+
+/* Router Alert Option */
+struct ip6_opt_router {
+ u_int8_t ip6or_type;
+ u_int8_t ip6or_len;
+ u_int8_t ip6or_value[2];
+} __packed;
+/* Router alert values (in network byte order) */
+#if BYTE_ORDER == BIG_ENDIAN
+#define IP6_ALERT_MLD 0x0000
+#define IP6_ALERT_RSVP 0x0001
+#define IP6_ALERT_AN 0x0002
+#else
+#if BYTE_ORDER == LITTLE_ENDIAN
+#define IP6_ALERT_MLD 0x0000
+#define IP6_ALERT_RSVP 0x0100
+#define IP6_ALERT_AN 0x0200
+#endif /* LITTLE_ENDIAN */
+#endif
+
+/* Routing header */
+struct ip6_rthdr {
+ u_int8_t ip6r_nxt; /* next header */
+ u_int8_t ip6r_len; /* length in units of 8 octets */
+ u_int8_t ip6r_type; /* routing type */
+ u_int8_t ip6r_segleft; /* segments left */
+ /* followed by routing type specific data */
+} __packed;
+
+/* Type 0 Routing header */
+struct ip6_rthdr0 {
+ u_int8_t ip6r0_nxt; /* next header */
+ u_int8_t ip6r0_len; /* length in units of 8 octets */
+ u_int8_t ip6r0_type; /* always zero */
+ u_int8_t ip6r0_segleft; /* segments left */
+ u_int32_t ip6r0_reserved; /* reserved field */
+} __packed;
+
+/* Fragment header */
+struct ip6_frag {
+ u_int8_t ip6f_nxt; /* next header */
+ u_int8_t ip6f_reserved; /* reserved field */
+ u_int16_t ip6f_offlg; /* offset, reserved, and flag */
+ u_int32_t ip6f_ident; /* identification */
+} __packed;
+
+#if BYTE_ORDER == BIG_ENDIAN
+#define IP6F_OFF_MASK 0xfff8 /* mask out offset from _offlg */
+#define IP6F_RESERVED_MASK 0x0006 /* reserved bits in ip6f_offlg */
+#define IP6F_MORE_FRAG 0x0001 /* more-fragments flag */
+#else /* BYTE_ORDER == LITTLE_ENDIAN */
+#define IP6F_OFF_MASK 0xf8ff /* mask out offset from _offlg */
+#define IP6F_RESERVED_MASK 0x0600 /* reserved bits in ip6f_offlg */
+#define IP6F_MORE_FRAG 0x0100 /* more-fragments flag */
+#endif /* BYTE_ORDER == LITTLE_ENDIAN */
+
+/*
+ * Internet implementation parameters.
+ */
+#define IPV6_MAXHLIM 255 /* maximum hoplimit */
+#define IPV6_DEFHLIM 64 /* default hlim */
+#define IPV6_FRAGTTL 120 /* ttl for fragment packets, in slowtimo tick */
+#define IPV6_HLIMDEC 1 /* subtracted when forwarding */
+
+#define IPV6_MMTU 1280 /* minimal MTU and reassembly. 1024 + 256 */
+#define IPV6_MAXPACKET 65535 /* ip6 max packet size without Jumbo payload*/
+
+#ifdef _KERNEL
+/*
+ * IP6_EXTHDR_GET ensures that intermediate protocol header (from "off" to
+ * "len") is located in single mbuf, on contiguous memory region.
+ * The pointer to the region will be returned to pointer variable "val",
+ * with type "typ".
+ * IP6_EXTHDR_GET0 does the same, except that it aligns the structure at the
+ * very top of mbuf. GET0 is likely to make memory copy than GET.
+ *
+ * XXX we're now testing this, needs m_pulldown()
+ */
+#define IP6_EXTHDR_GET(val, typ, m, off, len) \
+do { \
+ struct mbuf *_t; \
+ int _tmp; \
+ if ((m)->m_len >= (off) + (len)) \
+ (val) = (typ)(mtod((m), char *) + (off)); \
+ else { \
+ _t = m_pulldown((m), (off), (len), &_tmp); \
+ if (_t) { \
+ if (_t->m_len < _tmp + (len)) \
+ panic("m_pulldown malfunction"); \
+ (val) = (typ)(mtod(_t, char *) + _tmp); \
+ } else { \
+ (val) = (typ)NULL; \
+ (m) = NULL; \
+ } \
+ } \
+} while (/*CONSTCOND*/ 0)
+
+#define IP6_EXTHDR_GET0(val, typ, m, off, len) \
+do { \
+ struct mbuf *_t; \
+ if ((off) == 0 && (m)->m_len >= len) \
+ (val) = (typ)mtod((m), void *); \
+ else { \
+ _t = m_pulldown((m), (off), (len), NULL); \
+ if (_t) { \
+ if (_t->m_len < (len)) \
+ panic("m_pulldown malfunction"); \
+ (val) = (typ)mtod(_t, void *); \
+ } else { \
+ (val) = (typ)NULL; \
+ (m) = NULL; \
+ } \
+ } \
+} while (/*CONSTCOND*/ 0)
+#endif /*_KERNEL*/
+
+#endif /* !_NETINET_IP6_H_ */
diff --git a/libc/include/pthread.h b/libc/include/pthread.h
index 99e747a..9d05769 100644
--- a/libc/include/pthread.h
+++ b/libc/include/pthread.h
@@ -103,7 +103,7 @@
/*
* Prototypes
*/
-#if __cplusplus
+#ifdef __cplusplus
extern "C" {
#endif
@@ -233,7 +233,7 @@
void* reserved[4]; /* for future extensibility */
} pthread_rwlock_t;
-#define PTHREAD_RWLOCK_INITIALIZER { PTHREAD_MUTEX_INITIALIZER, 0, NULL, 0, 0 }
+#define PTHREAD_RWLOCK_INITIALIZER { PTHREAD_MUTEX_INITIALIZER, PTHREAD_COND_INITIALIZER, 0, 0, 0, 0, { NULL, NULL, NULL, NULL } }
int pthread_rwlockattr_init(pthread_rwlockattr_t *attr);
int pthread_rwlockattr_destroy(pthread_rwlockattr_t *attr);
@@ -268,6 +268,8 @@
int pthread_setname_np(pthread_t thid, const char *thname);
+int pthread_atfork(void (*prepare)(void), void (*parent)(void), void(*child)(void));
+
typedef void (*__pthread_cleanup_func_t)(void*);
typedef struct __pthread_cleanup_t {
@@ -300,7 +302,7 @@
__pthread_cleanup_pop( &__cleanup, (execute)); \
} while (0);
-#if __cplusplus
+#ifdef __cplusplus
} /* extern "C" */
#endif
diff --git a/libc/include/resolv.h b/libc/include/resolv.h
index 4247d68..bb21c23 100644
--- a/libc/include/resolv.h
+++ b/libc/include/resolv.h
@@ -34,6 +34,7 @@
#include <sys/socket.h>
#include <stdio.h>
#include <arpa/nameser.h>
+#include <netinet/in.h>
__BEGIN_DECLS
@@ -49,6 +50,21 @@
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/sched.h b/libc/include/sched.h
index e702470..ca72da7 100644
--- a/libc/include/sched.h
+++ b/libc/include/sched.h
@@ -73,6 +73,162 @@
extern int clone(int (*fn)(void *), void *child_stack, int flags, void* arg, ...);
#endif
+/* Support for cpu thread affinity */
+#ifdef _GNU_SOURCE
+
+extern int sched_getcpu(void);
+
+
+/* Our implementation supports up to 32 independent CPUs, which is also
+ * the maximum supported by the kernel at the moment. GLibc uses 1024 by
+ * default.
+ *
+ * If you want to use more than that, you should use CPU_ALLOC() / CPU_FREE()
+ * and the CPU_XXX_S() macro variants.
+ */
+#define CPU_SETSIZE 32
+
+#define __CPU_BITTYPE unsigned long int /* mandated by the kernel */
+#define __CPU_BITSHIFT 5 /* should be log2(BITTYPE) */
+#define __CPU_BITS (1 << __CPU_BITSHIFT)
+#define __CPU_ELT(x) ((x) >> __CPU_BITSHIFT)
+#define __CPU_MASK(x) ((__CPU_BITTYPE)1 << ((x) & (__CPU_BITS-1)))
+
+typedef struct {
+ __CPU_BITTYPE __bits[ CPU_SETSIZE / __CPU_BITS ];
+} cpu_set_t;
+
+extern int sched_setaffinity(pid_t pid, size_t setsize, const cpu_set_t* set);
+
+extern int sched_getaffinity(pid_t pid, size_t setsize, cpu_set_t* set);
+
+/* Provide optimized implementation for 32-bit cpu_set_t */
+#if CPU_SETSIZE == __CPU_BITS
+
+# define CPU_ZERO(set_) \
+ do{ \
+ (set_)->__bits[0] = 0; \
+ }while(0)
+
+# define CPU_SET(cpu_,set_) \
+ do {\
+ size_t __cpu = (cpu_); \
+ if (__cpu < CPU_SETSIZE) \
+ (set_)->__bits[0] |= __CPU_MASK(__cpu); \
+ }while (0)
+
+# define CPU_CLR(cpu_,set_) \
+ do {\
+ size_t __cpu = (cpu_); \
+ if (__cpu < CPU_SETSIZE) \
+ (set_)->__bits[0] &= ~__CPU_MASK(__cpu); \
+ }while (0)
+
+# define CPU_ISSET(cpu_, set_) \
+ (__extension__({\
+ size_t __cpu = (cpu_); \
+ (cpu_ < CPU_SETSIZE) \
+ ? ((set_)->__bits[0] & __CPU_MASK(__cpu)) != 0 \
+ : 0; \
+ }))
+
+# define CPU_EQUAL(set1_, set2_) \
+ ((set1_)->__bits[0] == (set2_)->__bits[0])
+
+# define __CPU_OP(dst_, set1_, set2_, op_) \
+ do { \
+ (dst_)->__bits[0] = (set1_)->__bits[0] op_ (set2_)->__bits[0]; \
+ } while (0)
+
+# define CPU_COUNT(set_) __builtin_popcountl((set_)->__bits[0])
+
+#else /* CPU_SETSIZE != __CPU_BITS */
+
+# define CPU_ZERO(set_) CPU_ZERO_S(sizeof(cpu_set_t), set_)
+# define CPU_SET(cpu_,set_) CPU_SET_S(cpu_,sizeof(cpu_set_t),set_)
+# define CPU_CLR(cpu_,set_) CPU_CLR_S(cpu_,sizeof(cpu_set_t),set_)
+# define CPU_ISSET(cpu_,set_) CPU_ISSET_S(cpu_,sizeof(cpu_set_t),set_)
+# define CPU_COUNT(set_) CPU_COUNT_S(sizeof(cpu_set_t),set_)
+# define CPU_EQUAL(set1_,set2_) CPU_EQUAL_S(sizeof(cpu_set_t),set1_,set2_)
+
+# define __CPU_OP(dst_,set1_,set2_,op_) __CPU_OP_S(sizeof(cpu_set_t),dst_,set1_,set2_,op_)
+
+#endif /* CPU_SETSIZE != __CPU_BITS */
+
+#define CPU_AND(set1_,set2_) __CPU_OP(set1_,set2_,&)
+#define CPU_OR(set1_,set2_) __CPU_OP(set1_,set2_,|)
+#define CPU_XOR(set1_,set2_) __CPU_OP(set1_,set2_,^)
+
+/* Support for dynamically-allocated cpu_set_t */
+
+#define CPU_ALLOC_SIZE(count) \
+ __CPU_ELT((count) + (__CPU_BITS-1))*sizeof(__CPU_BITTYPE)
+
+#define CPU_ALLOC(count) __sched_cpualloc((count));
+#define CPU_FREE(set) __sched_cpufree((set))
+
+extern cpu_set_t* __sched_cpualloc(size_t count);
+extern void __sched_cpufree(cpu_set_t* set);
+
+#define CPU_ZERO_S(setsize_,set_) \
+ do { \
+ size_t __nn = 0; \
+ size_t __nn_max = (setsize_)/sizeof(__CPU_BITTYPE); \
+ for (; __nn < __nn_max; __nn++) \
+ (set_)->__bits[__nn] = 0; \
+ } while (0)
+
+#define CPU_SET_S(cpu_,setsize_,set_) \
+ do { \
+ size_t __cpu = (cpu_); \
+ if (__cpu < 8*(setsize_)) \
+ (set_)->__bits[__CPU_ELT(__cpu)] |= __CPU_MASK(__cpu); \
+ } while (0)
+
+#define CPU_CLR_S(cpu_,setsize_,set_) \
+ do { \
+ size_t __cpu = (cpu_); \
+ if (__cpu < 8*(setsize_)) \
+ (set_)->__bits[__CPU_ELT(__cpu)] &= ~__CPU_MASK(__cpu); \
+ } while (0)
+
+#define CPU_ISSET_S(cpu_, setsize_, set_) \
+ (__extension__ ({ \
+ size_t __cpu = (cpu_); \
+ (__cpu < 8*(setsize_)) \
+ ? ((set_)->__bits[__CPU_ELT(__cpu)] & __CPU_MASK(__cpu)) != 0 \
+ : 0; \
+ }))
+
+#define CPU_EQUAL_S(setsize_, set1_, set2_) \
+ (__extension__ ({ \
+ __const __CPU_BITTYPE* __src1 = (set1_)->__bits; \
+ __const __CPU_BITTYPE* __src2 = (set2_)->__bits; \
+ size_t __nn = 0, __nn_max = (setsize_)/sizeof(__CPU_BITTYPE); \
+ for (; __nn < __nn_max; __nn++) { \
+ if (__src1[__nn] != __src2[__nn]) \
+ break; \
+ } \
+ __nn == __nn_max; \
+ }))
+
+#define __CPU_OP_S(setsize_, dstset_, srcset1_, srcset2_, op) \
+ do { \
+ cpu_set_t* __dst = (dstset); \
+ const __CPU_BITTYPE* __src1 = (srcset1)->__bits; \
+ const __CPU_BITTYPE* __src2 = (srcset2)->__bits; \
+ size_t __nn = 0, __nn_max = (setsize_)/sizeof(__CPU_BITTYPE); \
+ for (; __nn < __nn_max; __nn++) \
+ (__dst)->__bits[__nn] = __src1[__nn] op __src2[__nn]; \
+ } while (0)
+
+#define CPU_COUNT_S(setsize_, set_) \
+ __sched_cpucount((setsize_), (set_))
+
+extern int __sched_cpucount(size_t setsize, cpu_set_t* set);
+
+#endif /* _GNU_SOURCE */
+
__END_DECLS
#endif /* _SCHED_H_ */
diff --git a/libc/include/signal.h b/libc/include/signal.h
index 4401164..91c3b00 100644
--- a/libc/include/signal.h
+++ b/libc/include/signal.h
@@ -42,12 +42,15 @@
typedef int sig_atomic_t;
-/* crepy NIG / _NSIG handling, just to be safe */
-#ifndef NSIG
-# define NSIG _NSIG
-#endif
+/* _NSIG is used by the SIGRTMAX definition under <asm/signal.h>, however
+ * its definition is part of a #if __KERNEL__ .. #endif block in the original
+ * kernel headers and is thus not part of our cleaned-up versions.
+ *
+ * Looking at the current kernel sources, it is defined as 64 for all
+ * architectures except for the 'mips' one which set it to 128.
+ */
#ifndef _NSIG
-# define _NSIG NSIG
+# define _NSIG 64
#endif
extern const char * const sys_siglist[];
diff --git a/libc/include/stdint.h b/libc/include/stdint.h
index 237baa2..e791475 100644
--- a/libc/include/stdint.h
+++ b/libc/include/stdint.h
@@ -41,11 +41,6 @@
# define __STDINT_MACROS
#endif
-/* the definitions of STDINT_LIMITS depend on those of STDINT_MACROS */
-#if defined __STDINT_LIMITS && !defined __STDINT_MACROS
-# define __STDINT_MACROS
-#endif
-
#if !defined __STRICT_ANSI__ || __STDC_VERSION__ >= 199901L
# define __STDC_INT64__
#endif
@@ -185,13 +180,14 @@
# define UINT_FAST64_MAX UINT64_MAX
#endif
+#define __INT64_C(c) c ## LL
+#define __UINT64_C(c) c ## ULL
+
#ifdef __STDINT_MACROS
-# define __INT64_C(c) c ## LL
# define INT64_C(c) __INT64_C(c)
# define INT_LEAST64_C(c) INT64_C(c)
# define INT_FAST64_C(c) INT64_C(c)
-# define __UINT64_C(c) c ## ULL
# define UINT64_C(c) __UINT64_C(c)
# define UINT_LEAST64_C(c) UINT64_C(c)
# define UINT_FAST64_C(c) UINT64_C(c)
@@ -211,14 +207,20 @@
typedef int intptr_t;
typedef unsigned int uintptr_t;
+#ifdef __STDINT_LIMITS
# define INTPTR_MIN INT32_MIN
# define INTPTR_MAX INT32_MAX
# define UINTPTR_MAX UINT32_MAX
+# define PTRDIFF_MIN INT32_MIN
+# define PTRDIFF_MAX INT32_MAX
+#endif
+
+#ifdef __STDINT_MACROS
# define INTPTR_C(c) INT32_C(c)
# define UINTPTR_C(c) UINT32_C(c)
# define PTRDIFF_C(c) INT32_C(c)
-# define PTRDIFF_MIN INT32_MIN
-# define PTRDIFF_MAX INT32_MAX
+#endif
+
/*
@@ -230,24 +232,32 @@
typedef uint64_t uintmax_t;
typedef int64_t intmax_t;
-#define INTMAX_MIN INT64_MIN
-#define INTMAX_MAX INT64_MAX
-#define UINTMAX_MAX UINT64_MAX
+#ifdef __STDINT_LIMITS
+# define INTMAX_MIN INT64_MIN
+# define INTMAX_MAX INT64_MAX
+# define UINTMAX_MAX UINT64_MAX
+#endif
-#define INTMAX_C(c) INT64_C(c)
-#define UINTMAX_C(c) UINT64_C(c)
+#ifdef __STDINT_MACROS
+# define INTMAX_C(c) INT64_C(c)
+# define UINTMAX_C(c) UINT64_C(c)
+#endif
#else /* !__STDC_INT64__ */
typedef uint32_t uintmax_t;
typedef int32_t intmax_t;
-#define INTMAX_MIN INT32_MIN
-#define INTMAX_MAX INT32_MAX
-#define UINTMAX_MAX UINT32_MAX
+#ifdef __STDINT_LIMITS
+# define INTMAX_MIN INT32_MIN
+# define INTMAX_MAX INT32_MAX
+# define UINTMAX_MAX UINT32_MAX
+#endif
-#define INTMAX_C(c) INT32_C(c)
-#define UINTMAX_C(c) UINT32_C(c)
+#ifdef __STDINT_MACROS
+# define INTMAX_C(c) INT32_C(c)
+# define UINTMAX_C(c) UINT32_C(c)
+#endif
#endif /* !__STDC_INT64__ */
diff --git a/libc/include/stdlib.h b/libc/include/stdlib.h
index 97d8e46..5dc8a87 100644
--- a/libc/include/stdlib.h
+++ b/libc/include/stdlib.h
@@ -57,6 +57,7 @@
extern int unsetenv(const char *);
extern int clearenv(void);
+extern char *mkdtemp(char *);
extern char *mktemp (char *);
extern int mkstemp (char *);
diff --git a/libc/include/sys/cdefs.h b/libc/include/sys/cdefs.h
index 849e2b8..92035d4 100644
--- a/libc/include/sys/cdefs.h
+++ b/libc/include/sys/cdefs.h
@@ -79,7 +79,7 @@
#define ___STRING(x) __STRING(x)
#define ___CONCAT(x,y) __CONCAT(x,y)
-#if __STDC__ || defined(__cplusplus)
+#if defined(__STDC__) || defined(__cplusplus)
#define __P(protos) protos /* full-blown ANSI C */
#define __CONCAT(x,y) x ## y
#define __STRING(x) #x
@@ -213,7 +213,7 @@
* C99 defines the restrict type qualifier keyword, which was made available
* in GCC 2.92.
*/
-#if __STDC_VERSION__ >= 199901L
+#if defined(__STDC__VERSION__) && __STDC_VERSION__ >= 199901L
#define __restrict restrict
#else
#if !__GNUC_PREREQ__(2, 92)
@@ -225,7 +225,7 @@
* C99 defines __func__ predefined identifier, which was made available
* in GCC 2.95.
*/
-#if !(__STDC_VERSION__ >= 199901L)
+#if !defined(__STDC_VERSION__) || !(__STDC_VERSION__ >= 199901L)
#if __GNUC_PREREQ__(2, 6)
#define __func__ __PRETTY_FUNCTION__
#elif __GNUC_PREREQ__(2, 4)
@@ -497,5 +497,6 @@
#endif
#define __BIONIC__ 1
+#include <android/api-level.h>
#endif /* !_SYS_CDEFS_H_ */
diff --git a/libc/include/sys/cdefs_elf.h b/libc/include/sys/cdefs_elf.h
index e051b1d..1e57470 100644
--- a/libc/include/sys/cdefs_elf.h
+++ b/libc/include/sys/cdefs_elf.h
@@ -95,6 +95,10 @@
__asm__(".section _sec\n\t.asciz _str\n\t.previous")
#endif
+/* GCC visibility helper macro */
+#define __LIBC_HIDDEN__ \
+ __attribute__ ((visibility ("hidden")))
+
#define __IDSTRING(_n,_s) __SECTIONSTRING(.ident,_s)
#define __RCSID(_s) __IDSTRING(rcsid,_s)
diff --git a/libc/include/sys/linux-syscalls.h b/libc/include/sys/linux-syscalls.h
index 9702a7a..cb4d5e5 100644
--- a/libc/include/sys/linux-syscalls.h
+++ b/libc/include/sys/linux-syscalls.h
@@ -71,6 +71,7 @@
#define __NR_dup2 (__NR_SYSCALL_BASE + 63)
#define __NR__newselect (__NR_SYSCALL_BASE + 142)
#define __NR_ftruncate (__NR_SYSCALL_BASE + 93)
+#define __NR_ftruncate64 (__NR_SYSCALL_BASE + 194)
#define __NR_fsync (__NR_SYSCALL_BASE + 118)
#define __NR_fdatasync (__NR_SYSCALL_BASE + 148)
#define __NR_fchown32 (__NR_SYSCALL_BASE + 207)
@@ -120,6 +121,8 @@
#define __NR_sched_get_priority_max (__NR_SYSCALL_BASE + 159)
#define __NR_sched_get_priority_min (__NR_SYSCALL_BASE + 160)
#define __NR_sched_rr_get_interval (__NR_SYSCALL_BASE + 161)
+#define __NR_sched_setaffinity (__NR_SYSCALL_BASE + 241)
+#define __NR_sched_getaffinity (__NR_SYSCALL_BASE + 242)
#define __NR_uname (__NR_SYSCALL_BASE + 122)
#define __NR_wait4 (__NR_SYSCALL_BASE + 114)
#define __NR_umask (__NR_SYSCALL_BASE + 60)
@@ -174,6 +177,7 @@
#define __NR_getsockopt (__NR_SYSCALL_BASE + 295)
#define __NR_sendmsg (__NR_SYSCALL_BASE + 296)
#define __NR_recvmsg (__NR_SYSCALL_BASE + 297)
+#define __NR_getcpu (__NR_SYSCALL_BASE + 345)
#define __NR_ioprio_set (__NR_SYSCALL_BASE + 314)
#define __NR_ioprio_get (__NR_SYSCALL_BASE + 315)
#define __NR_epoll_create (__NR_SYSCALL_BASE + 250)
@@ -218,6 +222,7 @@
#define __NR_timer_delete (__NR_SYSCALL_BASE + 263)
#define __NR_utimes (__NR_SYSCALL_BASE + 271)
#define __NR_socketcall (__NR_SYSCALL_BASE + 102)
+#define __NR_getcpu (__NR_SYSCALL_BASE + 318)
#define __NR_ioprio_set (__NR_SYSCALL_BASE + 289)
#define __NR_ioprio_get (__NR_SYSCALL_BASE + 290)
#define __NR_epoll_create (__NR_SYSCALL_BASE + 254)
@@ -276,6 +281,7 @@
#define __NR_socketcall (__NR_SYSCALL_BASE + 102)
#define __NR_socketcall (__NR_SYSCALL_BASE + 102)
#define __NR___socketcall (__NR_SYSCALL_BASE + 102)
+#define __NR_getcpu (__NR_SYSCALL_BASE + 318)
#define __NR_ioprio_set (__NR_SYSCALL_BASE + 288)
#define __NR_ioprio_get (__NR_SYSCALL_BASE + 289)
#define __NR_epoll_create (__NR_SYSCALL_BASE + 254)
diff --git a/libc/include/sys/linux-unistd.h b/libc/include/sys/linux-unistd.h
index 23853da..f706d00 100644
--- a/libc/include/sys/linux-unistd.h
+++ b/libc/include/sys/linux-unistd.h
@@ -52,8 +52,8 @@
int acct (const char* filepath);
ssize_t read (int, void*, size_t);
ssize_t write (int, const void*, size_t);
-ssize_t __pread64 (int, void *, size_t, off_t, off_t);
-ssize_t __pwrite64 (int, void *, size_t, off_t, off_t);
+ssize_t pread64 (int, void *, size_t, off64_t);
+ssize_t pwrite64 (int, void *, size_t, off64_t);
int __open (const char*, int, mode_t);
int __openat (int, const char*, int, mode_t);
int close (int);
@@ -83,6 +83,7 @@
int dup2 (int, int);
int select (int, struct fd_set *, struct fd_set *, struct fd_set *, struct timeval *);
int ftruncate (int, off_t);
+int ftruncate64 (int, off64_t);
int getdents (unsigned int, struct dirent *, unsigned int);
int fsync (int);
int fdatasync (int);
@@ -183,6 +184,9 @@
int sched_get_priority_max (int policy);
int sched_get_priority_min (int policy);
int sched_rr_get_interval (pid_t pid, struct timespec *interval);
+int sched_setaffinity (pid_t pid, size_t setsize, const cpu_set_t* set);
+int __sched_getaffinity (pid_t pid, size_t setsize, cpu_set_t* set);
+int __getcpu (unsigned *cpu, unsigned *node, void *unused);
int ioprio_set (int which, int who, int ioprio);
int ioprio_get (int which, int who);
int uname (struct utsname *);
diff --git a/libc/include/sys/prctl.h b/libc/include/sys/prctl.h
index ce85bf7..359d684 100644
--- a/libc/include/sys/prctl.h
+++ b/libc/include/sys/prctl.h
@@ -32,8 +32,13 @@
__BEGIN_DECLS
-extern int prctl(int option, unsigned long arg2, unsigned long arg3 , unsigned
- long arg4, unsigned long arg5);
+/* IMPORTANT NOTE: This function is declared as taking a variable number
+ * of arguments to match the GLibc definition. However
+ * its declaration inside SYSCALLS.TXT *must* make it
+ * take 6 arguments to ensure consistency with the kernel
+ * implementation.
+ */
+extern int prctl(int option, ...);
__END_DECLS
diff --git a/libc/include/time.h b/libc/include/time.h
index 5d1a0e2..4ad4f7b 100644
--- a/libc/include/time.h
+++ b/libc/include/time.h
@@ -128,6 +128,11 @@
extern int timer_gettime(timer_t timerid, struct itimerspec *value);
extern int timer_getoverrun(timer_t timerid);
+extern time_t timelocal(struct tm *tm);
+extern time_t timegm(struct tm* tm);
+extern time_t time2posix(time_t ti);
+extern time_t posix2time(time_t ti);
+
__END_DECLS
#endif /* _TIME_H_ */
diff --git a/libc/include/unistd.h b/libc/include/unistd.h
index 29154a2..d92549f 100644
--- a/libc/include/unistd.h
+++ b/libc/include/unistd.h
@@ -70,8 +70,9 @@
extern int execle(const char *, const char *, ...);
extern int capget(cap_user_header_t hdrp, cap_user_data_t datap);
extern int capset(cap_user_header_t hdrp, const cap_user_data_t datap);
-extern int prctl(int option, unsigned long arg2, unsigned long arg3,
- unsigned long arg4, unsigned long arg5);
+
+/* IMPORTANT: See comment under <sys/prctl.h> about this declaration */
+extern int prctl(int option, ...);
extern int nice(int);
@@ -128,12 +129,14 @@
extern int close(int);
extern off_t lseek(int, off_t, int);
-extern loff_t lseek64(int, loff_t, int);
+extern off64_t lseek64(int, off64_t, int);
extern ssize_t read(int, void *, size_t);
extern ssize_t write(int, const void *, size_t);
extern ssize_t pread(int, void *, size_t, off_t);
-extern ssize_t pwrite(int, void *, size_t, off_t);
+extern ssize_t pread64(int, void *, size_t, off64_t);
+extern ssize_t pwrite(int, const void *, size_t, off_t);
+extern ssize_t pwrite64(int, const void *, size_t, off64_t);
extern int dup(int);
extern int dup2(int, int);
@@ -143,6 +146,7 @@
extern int fsync(int);
extern int fdatasync(int);
extern int ftruncate(int, off_t);
+extern int ftruncate64(int, off64_t);
extern int pause(void);
extern unsigned int alarm(unsigned int);
diff --git a/libc/include/wchar.h b/libc/include/wchar.h
index 9b744a5..1361ff5 100644
--- a/libc/include/wchar.h
+++ b/libc/include/wchar.h
@@ -112,6 +112,7 @@
extern int vwprintf(const wchar_t *, va_list);
extern int vswprintf(wchar_t *, size_t, const wchar_t *, va_list);
extern size_t wcrtomb(char *, wchar_t, mbstate_t *);
+extern int wcscasecmp(const wchar_t *, const wchar_t *);
extern wchar_t *wcscat(wchar_t *, const wchar_t *);
extern wchar_t *wcschr(const wchar_t *, wchar_t);
extern int wcscmp(const wchar_t *, const wchar_t *);
@@ -120,6 +121,7 @@
extern size_t wcscspn(const wchar_t *, const wchar_t *);
extern size_t wcsftime(wchar_t *, size_t, const wchar_t *, const struct tm *);
extern size_t wcslen(const wchar_t *);
+extern int wcsncasecmp(const wchar_t *, const wchar_t *, size_t);
extern wchar_t *wcsncat(wchar_t *, const wchar_t *, size_t);
extern int wcsncmp(const wchar_t *, const wchar_t *, size_t);
extern wchar_t *wcsncpy(wchar_t *, const wchar_t *, size_t);
diff --git a/libc/inet/ether_aton.c b/libc/inet/ether_aton.c
new file mode 100644
index 0000000..6540c07
--- /dev/null
+++ b/libc/inet/ether_aton.c
@@ -0,0 +1,89 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <net/if_ether.h>
+#include <ctype.h>
+
+static inline int
+xdigit (char c) {
+ unsigned d;
+ d = (unsigned)(c-'0');
+ if (d < 10) return (int)d;
+ d = (unsigned)(c-'a');
+ if (d < 6) return (int)(10+d);
+ d = (unsigned)(c-'A');
+ if (d < 6) return (int)(10+d);
+ return -1;
+}
+
+/*
+ * Convert Ethernet address in the standard hex-digits-and-colons to binary
+ * representation.
+ * Re-entrant version (GNU extensions)
+ */
+struct ether_addr *
+ether_aton_r (const char *asc, struct ether_addr * addr)
+{
+ int i, val0, val1;
+ for (i = 0; i < ETHER_ADDR_LEN; ++i) {
+ val0 = xdigit(*asc);
+ asc++;
+ if (val0 < 0)
+ return NULL;
+
+ val1 = xdigit(*asc);
+ asc++;
+ if (val1 < 0)
+ return NULL;
+
+ addr->ether_addr_octet[i] = (u_int8_t)((val0 << 4) + val1);
+
+ if (i < ETHER_ADDR_LEN - 1) {
+ if (*asc != ':')
+ return NULL;
+ asc++;
+ }
+ }
+ if (*asc != '\0')
+ return NULL;
+ return addr;
+}
+
+/*
+ * Convert Ethernet address in the standard hex-digits-and-colons to binary
+ * representation.
+ */
+struct ether_addr *
+ether_aton (const char *asc)
+{
+ static struct ether_addr addr;
+ return ether_aton_r(asc, &addr);
+}
diff --git a/libc/inet/ether_ntoa.c b/libc/inet/ether_ntoa.c
new file mode 100644
index 0000000..f56e48b
--- /dev/null
+++ b/libc/inet/ether_ntoa.c
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <stdio.h>
+#include <sys/types.h>
+#include <net/if_ether.h>
+
+/*
+ * Convert Ethernet address to standard hex-digits-and-colons printable form.
+ * Re-entrant version (GNU extensions).
+ */
+char *
+ether_ntoa_r (const struct ether_addr *addr, char * buf)
+{
+ snprintf(buf, 18, "%02x:%02x:%02x:%02x:%02x:%02x",
+ addr->ether_addr_octet[0], addr->ether_addr_octet[1],
+ addr->ether_addr_octet[2], addr->ether_addr_octet[3],
+ addr->ether_addr_octet[4], addr->ether_addr_octet[5]);
+ return buf;
+}
+
+/*
+ * Convert Ethernet address to standard hex-digits-and-colons printable form.
+ */
+char *
+ether_ntoa (const struct ether_addr *addr)
+{
+ static char buf[18];
+ return ether_ntoa_r(addr, buf);
+}
diff --git a/libc/kernel/arch-arm/asm/byteorder.h b/libc/kernel/arch-arm/asm/byteorder.h
index 4da37bf..b869695 100644
--- a/libc/kernel/arch-arm/asm/byteorder.h
+++ b/libc/kernel/arch-arm/asm/byteorder.h
@@ -22,7 +22,7 @@
#ifndef __thumb__
if (!__builtin_constant_p(x)) {
- asm ("eor\t%0, %1, %1, ror #16" : "=r" (t) : "r" (x));
+ __asm__ ("eor\t%0, %1, %1, ror #16" : "=r" (t) : "r" (x));
} else
#endif
t = x ^ ((x << 16) | (x >> 16));
diff --git a/libc/kernel/arch-arm/asm/ptrace.h b/libc/kernel/arch-arm/asm/ptrace.h
index b6be08c..3faf738 100644
--- a/libc/kernel/arch-arm/asm/ptrace.h
+++ b/libc/kernel/arch-arm/asm/ptrace.h
@@ -30,6 +30,7 @@
#define PTRACE_SETCRUNCHREGS 26
#define PTRACE_GETVFPREGS 27
+#define PTRACE_SETVFPREGS 28
#define USR26_MODE 0x00000000
#define FIQ26_MODE 0x00000001
diff --git a/libc/kernel/common/linux/akm8975.h b/libc/kernel/common/linux/akm8975.h
new file mode 100644
index 0000000..1815f75
--- /dev/null
+++ b/libc/kernel/common/linux/akm8975.h
@@ -0,0 +1,72 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ *** This header was automatically generated from a Linux kernel header
+ *** of the same name, to make information necessary for userspace to
+ *** call into the kernel available to libc. It contains only constants,
+ *** structures, and macros generated from the original header, and thus,
+ *** contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef AKM8975_H
+#define AKM8975_H
+
+#include <linux/ioctl.h>
+
+#define AK8975_MODE_SNG_MEASURE 0x01
+#define AK8975_MODE_SELF_TEST 0x08
+#define AK8975_MODE_FUSE_ACCESS 0x0F
+#define AK8975_MODE_POWER_DOWN 0x00
+
+#define RBUFF_SIZE 8
+
+#define AK8975_REG_WIA 0x00
+#define AK8975_REG_INFO 0x01
+#define AK8975_REG_ST1 0x02
+#define AK8975_REG_HXL 0x03
+#define AK8975_REG_HXH 0x04
+#define AK8975_REG_HYL 0x05
+#define AK8975_REG_HYH 0x06
+#define AK8975_REG_HZL 0x07
+#define AK8975_REG_HZH 0x08
+#define AK8975_REG_ST2 0x09
+#define AK8975_REG_CNTL 0x0A
+#define AK8975_REG_RSV 0x0B
+#define AK8975_REG_ASTC 0x0C
+#define AK8975_REG_TS1 0x0D
+#define AK8975_REG_TS2 0x0E
+#define AK8975_REG_I2CDIS 0x0F
+
+#define AK8975_FUSE_ASAX 0x10
+#define AK8975_FUSE_ASAY 0x11
+#define AK8975_FUSE_ASAZ 0x12
+
+#define AKMIO 0xA1
+
+#define ECS_IOCTL_WRITE _IOW(AKMIO, 0x02, char[5])
+#define ECS_IOCTL_READ _IOWR(AKMIO, 0x03, char[5])
+#define ECS_IOCTL_GETDATA _IOR(AKMIO, 0x08, char[RBUFF_SIZE])
+#define ECS_IOCTL_SET_YPR _IOW(AKMIO, 0x0C, short[12])
+#define ECS_IOCTL_GET_OPEN_STATUS _IOR(AKMIO, 0x0D, int)
+#define ECS_IOCTL_GET_CLOSE_STATUS _IOR(AKMIO, 0x0E, int)
+#define ECS_IOCTL_GET_DELAY _IOR(AKMIO, 0x30, short)
+
+#define ECS_IOCTL_APP_SET_MFLAG _IOW(AKMIO, 0x11, short)
+#define ECS_IOCTL_APP_GET_MFLAG _IOW(AKMIO, 0x12, short)
+#define ECS_IOCTL_APP_SET_AFLAG _IOW(AKMIO, 0x13, short)
+#define ECS_IOCTL_APP_GET_AFLAG _IOR(AKMIO, 0x14, short)
+#define ECS_IOCTL_APP_SET_DELAY _IOW(AKMIO, 0x18, short)
+#define ECS_IOCTL_APP_GET_DELAY ECS_IOCTL_GET_DELAY
+#define ECS_IOCTL_APP_SET_MVFLAG _IOW(AKMIO, 0x19, short)
+#define ECS_IOCTL_APP_GET_MVFLAG _IOR(AKMIO, 0x1A, short)
+#define ECS_IOCTL_APP_SET_TFLAG _IOR(AKMIO, 0x15, short)
+
+#define ECS_INTR 140
+
+struct akm8975_platform_data {
+ int intr;
+};
+
+#endif
+
diff --git a/libc/kernel/common/linux/bmp085.h b/libc/kernel/common/linux/bmp085.h
new file mode 100644
index 0000000..650cb88
--- /dev/null
+++ b/libc/kernel/common/linux/bmp085.h
@@ -0,0 +1,29 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ *** This header was automatically generated from a Linux kernel header
+ *** of the same name, to make information necessary for userspace to
+ *** call into the kernel available to libc. It contains only constants,
+ *** structures, and macros generated from the original header, and thus,
+ *** contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef __BMP085_H__
+#define __BMP085_H__
+
+#include <linux/ioctl.h>
+
+#define BMP085_NAME "bmp085"
+
+#define BMP085_IOCTL_BASE 78
+
+#define BMP085_IOCTL_SET_DELAY _IOW(BMP085_IOCTL_BASE, 0, int)
+#define BMP085_IOCTL_GET_DELAY _IOR(BMP085_IOCTL_BASE, 1, int)
+#define BMP085_IOCTL_SET_ENABLE _IOW(BMP085_IOCTL_BASE, 2, int)
+#define BMP085_IOCTL_GET_ENABLE _IOR(BMP085_IOCTL_BASE, 3, int)
+#define BMP085_IOCTL_ACCURACY _IOW(BMP085_IOCTL_BASE, 4, int)
+
+#endif
+
+
diff --git a/libc/kernel/common/linux/cpcap_audio.h b/libc/kernel/common/linux/cpcap_audio.h
new file mode 100644
index 0000000..a59550f
--- /dev/null
+++ b/libc/kernel/common/linux/cpcap_audio.h
@@ -0,0 +1,65 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ *** This header was automatically generated from a Linux kernel header
+ *** of the same name, to make information necessary for userspace to
+ *** call into the kernel available to libc. It contains only constants,
+ *** structures, and macros generated from the original header, and thus,
+ *** contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _CPCAP_AUDIO_H
+#define _CPCAP_AUDIO_H
+
+#include <linux/ioctl.h>
+
+#define CPCAP_AUDIO_MAGIC 'c'
+
+#define CPCAP_AUDIO_OUT_SPEAKER 0
+#define CPCAP_AUDIO_OUT_HEADSET 1
+#define CPCAP_AUDIO_OUT_HEADSET_AND_SPEAKER 2
+#define CPCAP_AUDIO_OUT_STANDBY 3
+#define CPCAP_AUDIO_OUT_ANLG_DOCK_HEADSET 4
+#define CPCAP_AUDIO_OUT_MAX 4
+
+struct cpcap_audio_stream {
+ unsigned id;
+ int on;
+};
+
+#define CPCAP_AUDIO_OUT_SET_OUTPUT _IOW(CPCAP_AUDIO_MAGIC, 0, const struct cpcap_audio_stream *)
+
+#define CPCAP_AUDIO_OUT_VOL_MIN 0
+#define CPCAP_AUDIO_OUT_VOL_MAX 15
+
+#define CPCAP_AUDIO_OUT_SET_VOLUME _IOW(CPCAP_AUDIO_MAGIC, 1, unsigned int)
+
+#define CPCAP_AUDIO_OUT_GET_OUTPUT _IOR(CPCAP_AUDIO_MAGIC, 2, struct cpcap_audio_stream *)
+#define CPCAP_AUDIO_OUT_GET_VOLUME _IOR(CPCAP_AUDIO_MAGIC, 3, unsigned int *)
+
+#define CPCAP_AUDIO_IN_MIC1 0
+#define CPCAP_AUDIO_IN_MIC2 1
+#define CPCAP_AUDIO_IN_STANDBY 2
+#define CPCAP_AUDIO_IN_MAX 2
+
+#define CPCAP_AUDIO_IN_SET_INPUT _IOW(CPCAP_AUDIO_MAGIC, 4, const struct cpcap_audio_stream *)
+
+#define CPCAP_AUDIO_IN_GET_INPUT _IOR(CPCAP_AUDIO_MAGIC, 5, struct cpcap_audio_stream *)
+
+#define CPCAP_AUDIO_IN_VOL_MIN 0
+#define CPCAP_AUDIO_IN_VOL_MAX 31
+
+#define CPCAP_AUDIO_IN_SET_VOLUME _IOW(CPCAP_AUDIO_MAGIC, 6, unsigned int)
+
+#define CPCAP_AUDIO_IN_GET_VOLUME _IOR(CPCAP_AUDIO_MAGIC, 7, unsigned int *)
+
+#define CPCAP_AUDIO_OUT_GET_RATE _IOR(CPCAP_AUDIO_MAGIC, 8, unsigned int *)
+#define CPCAP_AUDIO_OUT_SET_RATE _IOW(CPCAP_AUDIO_MAGIC, 9, unsigned int)
+#define CPCAP_AUDIO_IN_GET_RATE _IOR(CPCAP_AUDIO_MAGIC, 10, unsigned int *)
+#define CPCAP_AUDIO_IN_SET_RATE _IOW(CPCAP_AUDIO_MAGIC, 11, unsigned int)
+
+#define CPCAP_AUDIO_SET_BLUETOOTH_BYPASS _IOW(CPCAP_AUDIO_MAGIC, 12, unsigned int)
+
+#endif
+
diff --git a/libc/kernel/common/linux/genetlink.h b/libc/kernel/common/linux/genetlink.h
new file mode 100644
index 0000000..bc6042c
--- /dev/null
+++ b/libc/kernel/common/linux/genetlink.h
@@ -0,0 +1,94 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ *** This header was automatically generated from a Linux kernel header
+ *** of the same name, to make information necessary for userspace to
+ *** call into the kernel available to libc. It contains only constants,
+ *** structures, and macros generated from the original header, and thus,
+ *** contains no copyrightable information.
+ ***
+ *** To edit the content of this header, modify the corresponding
+ *** source file (e.g. under external/kernel-headers/original/) then
+ *** run bionic/libc/kernel/tools/update_all.py
+ ***
+ *** Any manual change here will be lost the next time this script will
+ *** be run. You've been warned!
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef __LINUX_GENERIC_NETLINK_H
+#define __LINUX_GENERIC_NETLINK_H
+#include <linux/types.h>
+#include <linux/netlink.h>
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define GENL_NAMSIZ 16
+#define GENL_MIN_ID NLMSG_MIN_TYPE
+#define GENL_MAX_ID 1023
+struct genlmsghdr {
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+ __u8 cmd;
+ __u8 version;
+ __u16 reserved;
+};
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define GENL_HDRLEN NLMSG_ALIGN(sizeof(struct genlmsghdr))
+#define GENL_ADMIN_PERM 0x01
+#define GENL_CMD_CAP_DO 0x02
+#define GENL_CMD_CAP_DUMP 0x04
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define GENL_CMD_CAP_HASPOL 0x08
+#define GENL_ID_GENERATE 0
+#define GENL_ID_CTRL NLMSG_MIN_TYPE
+enum {
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+ CTRL_CMD_UNSPEC,
+ CTRL_CMD_NEWFAMILY,
+ CTRL_CMD_DELFAMILY,
+ CTRL_CMD_GETFAMILY,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+ CTRL_CMD_NEWOPS,
+ CTRL_CMD_DELOPS,
+ CTRL_CMD_GETOPS,
+ CTRL_CMD_NEWMCAST_GRP,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+ CTRL_CMD_DELMCAST_GRP,
+ CTRL_CMD_GETMCAST_GRP,
+ __CTRL_CMD_MAX,
+};
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define CTRL_CMD_MAX (__CTRL_CMD_MAX - 1)
+enum {
+ CTRL_ATTR_UNSPEC,
+ CTRL_ATTR_FAMILY_ID,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+ CTRL_ATTR_FAMILY_NAME,
+ CTRL_ATTR_VERSION,
+ CTRL_ATTR_HDRSIZE,
+ CTRL_ATTR_MAXATTR,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+ CTRL_ATTR_OPS,
+ CTRL_ATTR_MCAST_GROUPS,
+ __CTRL_ATTR_MAX,
+};
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define CTRL_ATTR_MAX (__CTRL_ATTR_MAX - 1)
+enum {
+ CTRL_ATTR_OP_UNSPEC,
+ CTRL_ATTR_OP_ID,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+ CTRL_ATTR_OP_FLAGS,
+ __CTRL_ATTR_OP_MAX,
+};
+#define CTRL_ATTR_OP_MAX (__CTRL_ATTR_OP_MAX - 1)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+enum {
+ CTRL_ATTR_MCAST_GRP_UNSPEC,
+ CTRL_ATTR_MCAST_GRP_NAME,
+ CTRL_ATTR_MCAST_GRP_ID,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+ __CTRL_ATTR_MCAST_GRP_MAX,
+};
+#define CTRL_ATTR_MCAST_GRP_MAX (__CTRL_ATTR_MCAST_GRP_MAX - 1)
+#endif
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+
diff --git a/libc/kernel/common/linux/hid.h b/libc/kernel/common/linux/hid.h
new file mode 100644
index 0000000..450db19
--- /dev/null
+++ b/libc/kernel/common/linux/hid.h
@@ -0,0 +1,36 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ *** This header was automatically generated from a Linux kernel header
+ *** of the same name, to make information necessary for userspace to
+ *** call into the kernel available to libc. It contains only constants,
+ *** structures, and macros generated from the original header, and thus,
+ *** contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef __HID_H
+#define __HID_H
+
+#define USB_INTERFACE_CLASS_HID 3
+
+#define USB_INTERFACE_SUBCLASS_BOOT 1
+#define USB_INTERFACE_PROTOCOL_KEYBOARD 1
+#define USB_INTERFACE_PROTOCOL_MOUSE 2
+
+#define HID_REQ_GET_REPORT 0x01
+#define HID_REQ_GET_IDLE 0x02
+#define HID_REQ_GET_PROTOCOL 0x03
+#define HID_REQ_SET_REPORT 0x09
+#define HID_REQ_SET_IDLE 0x0A
+#define HID_REQ_SET_PROTOCOL 0x0B
+
+#define HID_DT_HID (USB_TYPE_CLASS | 0x01)
+#define HID_DT_REPORT (USB_TYPE_CLASS | 0x02)
+#define HID_DT_PHYSICAL (USB_TYPE_CLASS | 0x03)
+
+#define HID_MAX_DESCRIPTOR_SIZE 4096
+
+#endif
+
+
diff --git a/libc/kernel/common/linux/hidraw.h b/libc/kernel/common/linux/hidraw.h
new file mode 100644
index 0000000..0681ece
--- /dev/null
+++ b/libc/kernel/common/linux/hidraw.h
@@ -0,0 +1,41 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ *** This header was automatically generated from a Linux kernel header
+ *** of the same name, to make information necessary for userspace to
+ *** call into the kernel available to libc. It contains only constants,
+ *** structures, and macros generated from the original header, and thus,
+ *** contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _HIDRAW_H
+#define _HIDRAW_H
+
+#include <linux/hid.h>
+#include <linux/types.h>
+
+struct hidraw_report_descriptor {
+ __u32 size;
+ __u8 value[HID_MAX_DESCRIPTOR_SIZE];
+};
+
+struct hidraw_devinfo {
+ __u32 bustype;
+ __s16 vendor;
+ __s16 product;
+};
+
+#define HIDIOCGRDESCSIZE _IOR('H', 0x01, int)
+#define HIDIOCGRDESC _IOR('H', 0x02, struct hidraw_report_descriptor)
+#define HIDIOCGRAWINFO _IOR('H', 0x03, struct hidraw_devinfo)
+#define HIDIOCGRAWNAME(len) _IOC(_IOC_READ, 'H', 0x04, len)
+#define HIDIOCGRAWPHYS(len) _IOC(_IOC_READ, 'H', 0x05, len)
+
+#define HIDRAW_FIRST_MINOR 0
+#define HIDRAW_MAX_DEVICES 64
+
+#define HIDRAW_BUFFER_SIZE 64
+
+#endif
+
diff --git a/libc/kernel/common/linux/if.h b/libc/kernel/common/linux/if.h
index 47c29d9..7db4888 100644
--- a/libc/kernel/common/linux/if.h
+++ b/libc/kernel/common/linux/if.h
@@ -17,6 +17,7 @@
#include <linux/compiler.h>
#define IFNAMSIZ 16
+#define IFALIASZ 256
#include <linux/hdlc/ioctl.h>
#define IFF_UP 0x1
@@ -42,13 +43,24 @@
#define IFF_LOWER_UP 0x10000
#define IFF_DORMANT 0x20000
-#define IFF_VOLATILE (IFF_LOOPBACK|IFF_POINTOPOINT|IFF_BROADCAST| IFF_MASTER|IFF_SLAVE|IFF_RUNNING|IFF_LOWER_UP|IFF_DORMANT)
+#define IFF_ECHO 0x40000
+
+#define IFF_VOLATILE (IFF_LOOPBACK|IFF_POINTOPOINT|IFF_BROADCAST|IFF_ECHO| IFF_MASTER|IFF_SLAVE|IFF_RUNNING|IFF_LOWER_UP|IFF_DORMANT)
#define IFF_802_1Q_VLAN 0x1
#define IFF_EBRIDGE 0x2
#define IFF_SLAVE_INACTIVE 0x4
#define IFF_MASTER_8023AD 0x8
#define IFF_MASTER_ALB 0x10
+#define IFF_BONDING 0x20
+#define IFF_SLAVE_NEEDARP 0x40
+#define IFF_ISATAP 0x80
+#define IFF_MASTER_ARPMON 0x100
+#define IFF_WAN_HDLC 0x200
+#define IFF_XMIT_DST_RELEASE 0x400
+#define IFF_DONT_BRIDGE 0x800
+#define IFF_IN_NETPOLL 0x1000
+#define IFF_DISABLE_NETPOLL 0x2000
#define IF_GET_IFACE 0x0001
#define IF_GET_PROTO 0x0002
@@ -90,8 +102,7 @@
IF_LINK_MODE_DORMANT,
};
-struct ifmap
-{
+struct ifmap {
unsigned long mem_start;
unsigned long mem_end;
unsigned short base_addr;
@@ -101,8 +112,7 @@
};
-struct if_settings
-{
+struct if_settings {
unsigned int type;
unsigned int size;
union {
@@ -118,8 +128,7 @@
} ifs_ifsu;
};
-struct ifreq
-{
+struct ifreq {
#define IFHWADDRLEN 6
union
{
@@ -161,11 +170,9 @@
#define ifr_newname ifr_ifru.ifru_newname
#define ifr_settings ifr_ifru.ifru_settings
-struct ifconf
-{
+struct ifconf {
int ifc_len;
- union
- {
+ union {
char __user *ifcu_buf;
struct ifreq __user *ifcu_req;
} ifc_ifcu;
@@ -174,3 +181,4 @@
#define ifc_req ifc_ifcu.ifcu_req
#endif
+
diff --git a/libc/kernel/common/linux/if_arp.h b/libc/kernel/common/linux/if_arp.h
index a3df6c8..d8a4001 100644
--- a/libc/kernel/common/linux/if_arp.h
+++ b/libc/kernel/common/linux/if_arp.h
@@ -77,6 +77,7 @@
#define ARPHRD_PHONET 820
#define ARPHRD_PHONET_PIPE 821
+#define ARPHRD_CAIF 822
#define ARPHRD_VOID 0xFFFF
#define ARPHRD_NONE 0xFFFE
@@ -111,8 +112,7 @@
#define ATF_NETMASK 0x20
#define ATF_DONTPUB 0x40
-struct arphdr
-{
+struct arphdr {
__be16 ar_hrd;
__be16 ar_pro;
unsigned char ar_hln;
@@ -122,3 +122,4 @@
};
#endif
+
diff --git a/libc/kernel/common/linux/if_link.h b/libc/kernel/common/linux/if_link.h
index e9d77d4..4b83760 100644
--- a/libc/kernel/common/linux/if_link.h
+++ b/libc/kernel/common/linux/if_link.h
@@ -15,8 +15,7 @@
#include <linux/types.h>
#include <linux/netlink.h>
-struct rtnl_link_stats
-{
+struct rtnl_link_stats {
__u32 rx_packets;
__u32 tx_packets;
__u32 rx_bytes;
@@ -45,8 +44,36 @@
__u32 tx_compressed;
};
-struct rtnl_link_ifmap
-{
+struct rtnl_link_stats64 {
+ __u64 rx_packets;
+ __u64 tx_packets;
+ __u64 rx_bytes;
+ __u64 tx_bytes;
+ __u64 rx_errors;
+ __u64 tx_errors;
+ __u64 rx_dropped;
+ __u64 tx_dropped;
+ __u64 multicast;
+ __u64 collisions;
+
+ __u64 rx_length_errors;
+ __u64 rx_over_errors;
+ __u64 rx_crc_errors;
+ __u64 rx_frame_errors;
+ __u64 rx_fifo_errors;
+ __u64 rx_missed_errors;
+
+ __u64 tx_aborted_errors;
+ __u64 tx_carrier_errors;
+ __u64 tx_fifo_errors;
+ __u64 tx_heartbeat_errors;
+ __u64 tx_window_errors;
+
+ __u64 rx_compressed;
+ __u64 tx_compressed;
+};
+
+struct rtnl_link_ifmap {
__u64 mem_start;
__u64 mem_end;
__u64 base_addr;
@@ -55,8 +82,7 @@
__u8 port;
};
-enum
-{
+enum {
IFLA_UNSPEC,
IFLA_ADDRESS,
IFLA_BROADCAST,
@@ -87,6 +113,11 @@
#define IFLA_LINKINFO IFLA_LINKINFO
IFLA_NET_NS_PID,
IFLA_IFALIAS,
+ IFLA_NUM_VF,
+ IFLA_VFINFO_LIST,
+ IFLA_STATS64,
+ IFLA_VF_PORTS,
+ IFLA_PORT_SELF,
__IFLA_MAX
};
@@ -95,8 +126,7 @@
#define IFLA_RTA(r) ((struct rtattr*)(((char*)(r)) + NLMSG_ALIGN(sizeof(struct ifinfomsg))))
#define IFLA_PAYLOAD(n) NLMSG_PAYLOAD(n,sizeof(struct ifinfomsg))
-enum
-{
+enum {
IFLA_INET6_UNSPEC,
IFLA_INET6_FLAGS,
IFLA_INET6_CONF,
@@ -109,16 +139,14 @@
#define IFLA_INET6_MAX (__IFLA_INET6_MAX - 1)
-struct ifla_cacheinfo
-{
+struct ifla_cacheinfo {
__u32 max_reasm_len;
__u32 tstamp;
__u32 reachable_time;
__u32 retrans_time;
};
-enum
-{
+enum {
IFLA_INFO_UNSPEC,
IFLA_INFO_KIND,
IFLA_INFO_DATA,
@@ -128,8 +156,7 @@
#define IFLA_INFO_MAX (__IFLA_INFO_MAX - 1)
-enum
-{
+enum {
IFLA_VLAN_UNSPEC,
IFLA_VLAN_ID,
IFLA_VLAN_FLAGS,
@@ -145,8 +172,7 @@
__u32 mask;
};
-enum
-{
+enum {
IFLA_VLAN_QOS_UNSPEC,
IFLA_VLAN_QOS_MAPPING,
__IFLA_VLAN_QOS_MAX
@@ -154,10 +180,123 @@
#define IFLA_VLAN_QOS_MAX (__IFLA_VLAN_QOS_MAX - 1)
-struct ifla_vlan_qos_mapping
-{
+struct ifla_vlan_qos_mapping {
__u32 from;
__u32 to;
};
+enum {
+ IFLA_MACVLAN_UNSPEC,
+ IFLA_MACVLAN_MODE,
+ __IFLA_MACVLAN_MAX,
+};
+
+#define IFLA_MACVLAN_MAX (__IFLA_MACVLAN_MAX - 1)
+
+enum macvlan_mode {
+ MACVLAN_MODE_PRIVATE = 1,
+ MACVLAN_MODE_VEPA = 2,
+ MACVLAN_MODE_BRIDGE = 4,
+};
+
+enum {
+ IFLA_VF_INFO_UNSPEC,
+ IFLA_VF_INFO,
+ __IFLA_VF_INFO_MAX,
+};
+
+#define IFLA_VF_INFO_MAX (__IFLA_VF_INFO_MAX - 1)
+
+enum {
+ IFLA_VF_UNSPEC,
+ IFLA_VF_MAC,
+ IFLA_VF_VLAN,
+ IFLA_VF_TX_RATE,
+ __IFLA_VF_MAX,
+};
+
+#define IFLA_VF_MAX (__IFLA_VF_MAX - 1)
+
+struct ifla_vf_mac {
+ __u32 vf;
+ __u8 mac[32];
+};
+
+struct ifla_vf_vlan {
+ __u32 vf;
+ __u32 vlan;
+ __u32 qos;
+};
+
+struct ifla_vf_tx_rate {
+ __u32 vf;
+ __u32 rate;
+};
+
+struct ifla_vf_info {
+ __u32 vf;
+ __u8 mac[32];
+ __u32 vlan;
+ __u32 qos;
+ __u32 tx_rate;
+};
+
+enum {
+ IFLA_VF_PORT_UNSPEC,
+ IFLA_VF_PORT,
+ __IFLA_VF_PORT_MAX,
+};
+
+#define IFLA_VF_PORT_MAX (__IFLA_VF_PORT_MAX - 1)
+
+enum {
+ IFLA_PORT_UNSPEC,
+ IFLA_PORT_VF,
+ IFLA_PORT_PROFILE,
+ IFLA_PORT_VSI_TYPE,
+ IFLA_PORT_INSTANCE_UUID,
+ IFLA_PORT_HOST_UUID,
+ IFLA_PORT_REQUEST,
+ IFLA_PORT_RESPONSE,
+ __IFLA_PORT_MAX,
+};
+
+#define IFLA_PORT_MAX (__IFLA_PORT_MAX - 1)
+
+#define PORT_PROFILE_MAX 40
+#define PORT_UUID_MAX 16
+#define PORT_SELF_VF -1
+
+enum {
+ PORT_REQUEST_PREASSOCIATE = 0,
+ PORT_REQUEST_PREASSOCIATE_RR,
+ PORT_REQUEST_ASSOCIATE,
+ PORT_REQUEST_DISASSOCIATE,
+};
+
+enum {
+ PORT_VDP_RESPONSE_SUCCESS = 0,
+ PORT_VDP_RESPONSE_INVALID_FORMAT,
+ PORT_VDP_RESPONSE_INSUFFICIENT_RESOURCES,
+ PORT_VDP_RESPONSE_UNUSED_VTID,
+ PORT_VDP_RESPONSE_VTID_VIOLATION,
+ PORT_VDP_RESPONSE_VTID_VERSION_VIOALTION,
+ PORT_VDP_RESPONSE_OUT_OF_SYNC,
+
+ PORT_PROFILE_RESPONSE_SUCCESS = 0x100,
+ PORT_PROFILE_RESPONSE_INPROGRESS,
+ PORT_PROFILE_RESPONSE_INVALID,
+ PORT_PROFILE_RESPONSE_BADSTATE,
+ PORT_PROFILE_RESPONSE_INSUFFICIENT_RESOURCES,
+ PORT_PROFILE_RESPONSE_ERROR,
+};
+
+struct ifla_port_vsi {
+ __u8 vsi_mgr_id;
+ __u8 vsi_type_id[3];
+ __u8 vsi_type_version;
+ __u8 pad[3];
+};
+
#endif
+
diff --git a/libc/kernel/common/linux/if_tun.h b/libc/kernel/common/linux/if_tun.h
index c5db4e0..9ed49f1 100644
--- a/libc/kernel/common/linux/if_tun.h
+++ b/libc/kernel/common/linux/if_tun.h
@@ -12,6 +12,10 @@
#ifndef __IF_TUN_H
#define __IF_TUN_H
+#include <linux/types.h>
+#include <linux/if_ether.h>
+#include <linux/filter.h>
+
#define TUN_READQ_SIZE 500
#define TUN_TUN_DEV 0x0001
@@ -23,6 +27,7 @@
#define TUN_NO_PI 0x0040
#define TUN_ONE_QUEUE 0x0080
#define TUN_PERSIST 0x0100
+#define TUN_VNET_HDR 0x0200
#define TUNSETNOCSUM _IOW('T', 200, int)
#define TUNSETDEBUG _IOW('T', 201, int)
@@ -30,16 +35,43 @@
#define TUNSETPERSIST _IOW('T', 203, int)
#define TUNSETOWNER _IOW('T', 204, int)
#define TUNSETLINK _IOW('T', 205, int)
+#define TUNSETGROUP _IOW('T', 206, int)
+#define TUNGETFEATURES _IOR('T', 207, unsigned int)
+#define TUNSETOFFLOAD _IOW('T', 208, unsigned int)
+#define TUNSETTXFILTER _IOW('T', 209, unsigned int)
+#define TUNGETIFF _IOR('T', 210, unsigned int)
+#define TUNGETSNDBUF _IOR('T', 211, int)
+#define TUNSETSNDBUF _IOW('T', 212, int)
+#define TUNATTACHFILTER _IOW('T', 213, struct sock_fprog)
+#define TUNDETACHFILTER _IOW('T', 214, struct sock_fprog)
+#define TUNGETVNETHDRSZ _IOR('T', 215, int)
+#define TUNSETVNETHDRSZ _IOW('T', 216, int)
#define IFF_TUN 0x0001
#define IFF_TAP 0x0002
#define IFF_NO_PI 0x1000
#define IFF_ONE_QUEUE 0x2000
+#define IFF_VNET_HDR 0x4000
+#define IFF_TUN_EXCL 0x8000
-struct tun_pi {
- unsigned short flags;
- unsigned short proto;
-};
+#define TUN_F_CSUM 0x01
+#define TUN_F_TSO4 0x02
+#define TUN_F_TSO6 0x04
+#define TUN_F_TSO_ECN 0x08
+#define TUN_F_UFO 0x10
+
#define TUN_PKT_STRIP 0x0001
+struct tun_pi {
+ __u16 flags;
+ __be16 proto;
+};
+
+#define TUN_FLT_ALLMULTI 0x0001
+struct tun_filter {
+ __u16 flags;
+ __u16 count;
+ __u8 addr[0][ETH_ALEN];
+};
#endif
+
diff --git a/libc/kernel/common/linux/if_vlan.h b/libc/kernel/common/linux/if_vlan.h
index d3d2df2..ab3b174 100644
--- a/libc/kernel/common/linux/if_vlan.h
+++ b/libc/kernel/common/linux/if_vlan.h
@@ -25,6 +25,12 @@
GET_VLAN_VID_CMD
};
+enum vlan_flags {
+ VLAN_FLAG_REORDER_HDR = 0x1,
+ VLAN_FLAG_GVRP = 0x2,
+ VLAN_FLAG_LOOSE_BINDING = 0x4,
+};
+
enum vlan_name_types {
VLAN_NAME_TYPE_PLUS_VID,
VLAN_NAME_TYPE_RAW_PLUS_VID,
@@ -50,3 +56,4 @@
};
#endif
+
diff --git a/libc/kernel/common/linux/in_route.h b/libc/kernel/common/linux/in_route.h
new file mode 100644
index 0000000..34e14d6
--- /dev/null
+++ b/libc/kernel/common/linux/in_route.h
@@ -0,0 +1,41 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ *** This header was automatically generated from a Linux kernel header
+ *** of the same name, to make information necessary for userspace to
+ *** call into the kernel available to libc. It contains only constants,
+ *** structures, and macros generated from the original header, and thus,
+ *** contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _LINUX_IN_ROUTE_H
+#define _LINUX_IN_ROUTE_H
+
+#define RTCF_DEAD RTNH_F_DEAD
+#define RTCF_ONLINK RTNH_F_ONLINK
+
+#define RTCF_NOPMTUDISC RTM_F_NOPMTUDISC
+
+#define RTCF_NOTIFY 0x00010000
+#define RTCF_DIRECTDST 0x00020000
+#define RTCF_REDIRECTED 0x00040000
+#define RTCF_TPROXY 0x00080000
+
+#define RTCF_FAST 0x00200000
+#define RTCF_MASQ 0x00400000
+#define RTCF_SNAT 0x00800000
+#define RTCF_DOREDIRECT 0x01000000
+#define RTCF_DIRECTSRC 0x04000000
+#define RTCF_DNAT 0x08000000
+#define RTCF_BROADCAST 0x10000000
+#define RTCF_MULTICAST 0x20000000
+#define RTCF_REJECT 0x40000000
+#define RTCF_LOCAL 0x80000000
+
+#define RTCF_NAT (RTCF_DNAT|RTCF_SNAT)
+
+#define RT_TOS(tos) ((tos)&IPTOS_TOS_MASK)
+
+#endif
+
diff --git a/libc/kernel/common/linux/ipv6_route.h b/libc/kernel/common/linux/ipv6_route.h
new file mode 100644
index 0000000..3791e87
--- /dev/null
+++ b/libc/kernel/common/linux/ipv6_route.h
@@ -0,0 +1,55 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ *** This header was automatically generated from a Linux kernel header
+ *** of the same name, to make information necessary for userspace to
+ *** call into the kernel available to libc. It contains only constants,
+ *** structures, and macros generated from the original header, and thus,
+ *** contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _LINUX_IPV6_ROUTE_H
+#define _LINUX_IPV6_ROUTE_H
+
+#include <linux/types.h>
+
+#define RTF_DEFAULT 0x00010000
+#define RTF_ALLONLINK 0x00020000
+#define RTF_ADDRCONF 0x00040000
+#define RTF_PREFIX_RT 0x00080000
+#define RTF_ANYCAST 0x00100000
+
+#define RTF_NONEXTHOP 0x00200000
+#define RTF_EXPIRES 0x00400000
+
+#define RTF_ROUTEINFO 0x00800000
+
+#define RTF_CACHE 0x01000000
+#define RTF_FLOW 0x02000000
+#define RTF_POLICY 0x04000000
+
+#define RTF_PREF(pref) ((pref) << 27)
+#define RTF_PREF_MASK 0x18000000
+
+#define RTF_LOCAL 0x80000000
+
+struct in6_rtmsg {
+ struct in6_addr rtmsg_dst;
+ struct in6_addr rtmsg_src;
+ struct in6_addr rtmsg_gateway;
+ __u32 rtmsg_type;
+ __u16 rtmsg_dst_len;
+ __u16 rtmsg_src_len;
+ __u32 rtmsg_metric;
+ unsigned long rtmsg_info;
+ __u32 rtmsg_flags;
+ int rtmsg_ifindex;
+};
+
+#define RTMSG_NEWDEVICE 0x11
+#define RTMSG_DELDEVICE 0x12
+#define RTMSG_NEWROUTE 0x21
+#define RTMSG_DELROUTE 0x22
+
+#endif
diff --git a/libc/kernel/common/linux/kxtf9.h b/libc/kernel/common/linux/kxtf9.h
new file mode 100644
index 0000000..9141364
--- /dev/null
+++ b/libc/kernel/common/linux/kxtf9.h
@@ -0,0 +1,70 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ *** This header was automatically generated from a Linux kernel header
+ *** of the same name, to make information necessary for userspace to
+ *** call into the kernel available to libc. It contains only constants,
+ *** structures, and macros generated from the original header, and thus,
+ *** contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef __KXTF9_H__
+#define __KXTF9_H__
+
+#include <linux/ioctl.h>
+
+#define KXTF9_IOCTL_BASE 77
+
+#define KXTF9_IOCTL_SET_DELAY _IOW(KXTF9_IOCTL_BASE, 0, int)
+#define KXTF9_IOCTL_GET_DELAY _IOR(KXTF9_IOCTL_BASE, 1, int)
+#define KXTF9_IOCTL_SET_ENABLE _IOW(KXTF9_IOCTL_BASE, 2, int)
+#define KXTF9_IOCTL_GET_ENABLE _IOR(KXTF9_IOCTL_BASE, 3, int)
+#define KXTF9_IOCTL_SET_G_RANGE _IOW(KXTF9_IOCTL_BASE, 4, int)
+
+#define KXTF9_IOCTL_SET_TILT_ENABLE _IOW(KXTF9_IOCTL_BASE, 5, int)
+#define KXTF9_IOCTL_SET_TAP_ENABLE _IOW(KXTF9_IOCTL_BASE, 6, int)
+#define KXTF9_IOCTL_SET_WAKE_ENABLE _IOW(KXTF9_IOCTL_BASE, 7, int)
+#define KXTF9_IOCTL_SET_PM_MODE _IOW(KXTF9_IOCTL_BASE, 8, int)
+#define KXTF9_IOCTL_SELF_TEST _IOW(KXTF9_IOCTL_BASE, 9, int)
+#define KXTF9_IOCTL_SET_SENSITIVITY _IOW(KXTF9_IOCTL_BASE, 10, int)
+
+#define RES_12BIT 0x40
+#define KXTF9_G_2G 0x00
+#define KXTF9_G_4G 0x08
+#define KXTF9_G_8G 0x10
+#define TPE 0x01
+#define WUFE 0x02
+#define TDTE 0x04
+
+#define OTP1_6 0x00
+#define OTP6_3 0x20
+#define OTP12_5 0x40
+#define OTP50 0x60
+#define OWUF25 0x00
+#define OWUF50 0x01
+#define OWUF100 0x02
+#define OWUF200 0x03
+#define OTDT50 0x00
+#define OTDT100 0x04
+#define OTDT200 0x08
+#define OTDT400 0x0C
+
+#define IEN 0x20
+#define IEA 0x10
+#define IEL 0x08
+#define IEU 0x04
+
+#define ODR800 0x06
+#define ODR400 0x05
+#define ODR200 0x04
+#define ODR100 0x03
+#define ODR50 0x02
+#define ODR25 0x01
+#define ODR12_5 0x00
+
+#define SENSITIVITY_REGS 0x07
+
+#endif
+
+
diff --git a/libc/kernel/common/linux/l3g4200d.h b/libc/kernel/common/linux/l3g4200d.h
new file mode 100644
index 0000000..0a0f8cd
--- /dev/null
+++ b/libc/kernel/common/linux/l3g4200d.h
@@ -0,0 +1,27 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ *** This header was automatically generated from a Linux kernel header
+ *** of the same name, to make information necessary for userspace to
+ *** call into the kernel available to libc. It contains only constants,
+ *** structures, and macros generated from the original header, and thus,
+ *** contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef __L3G4200D_H__
+#define __L3G4200D_H__
+
+#include <linux/ioctl.h>
+
+#define L3G4200D_NAME "l3g4200d"
+
+#define L3G4200D_IOCTL_BASE 77
+
+#define L3G4200D_IOCTL_SET_DELAY _IOW(L3G4200D_IOCTL_BASE, 0, int)
+#define L3G4200D_IOCTL_GET_DELAY _IOR(L3G4200D_IOCTL_BASE, 1, int)
+#define L3G4200D_IOCTL_SET_ENABLE _IOW(L3G4200D_IOCTL_BASE, 2, int)
+#define L3G4200D_IOCTL_GET_ENABLE _IOR(L3G4200D_IOCTL_BASE, 3, int)
+
+#endif
+
diff --git a/libc/kernel/common/linux/max9635.h b/libc/kernel/common/linux/max9635.h
new file mode 100644
index 0000000..e696fa9
--- /dev/null
+++ b/libc/kernel/common/linux/max9635.h
@@ -0,0 +1,23 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ *** This header was automatically generated from a Linux kernel header
+ *** of the same name, to make information necessary for userspace to
+ *** call into the kernel available to libc. It contains only constants,
+ *** structures, and macros generated from the original header, and thus,
+ *** contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _LINUX_MAX9635_H__
+#define _LINUX_MAX9635_H__
+
+#define MAX9635_NAME "MAX9635_als"
+#define FOPS_MAX9635_NAME "MAX9635"
+
+#define MAX9635_IO 0xA3
+
+#define MAX9635_IOCTL_GET_ENABLE _IOR(MAX9635_IO, 0x00, char)
+#define MAX9635_IOCTL_SET_ENABLE _IOW(MAX9635_IO, 0x01, char)
+
+#endif
diff --git a/libc/kernel/common/linux/netfilter.h b/libc/kernel/common/linux/netfilter.h
index 0488344..ce8d394 100644
--- a/libc/kernel/common/linux/netfilter.h
+++ b/libc/kernel/common/linux/netfilter.h
@@ -7,30 +7,66 @@
*** structures, and macros generated from the original header, and thus,
*** contains no copyrightable information.
***
+ *** To edit the content of this header, modify the corresponding
+ *** source file (e.g. under external/kernel-headers/original/) then
+ *** run bionic/libc/kernel/tools/update_all.py
+ ***
+ *** Any manual change here will be lost the next time this script will
+ *** be run. You've been warned!
+ ***
****************************************************************************
****************************************************************************/
#ifndef __LINUX_NETFILTER_H
#define __LINUX_NETFILTER_H
-
+#include <linux/types.h>
#include <linux/compiler.h>
-
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
#define NF_DROP 0
#define NF_ACCEPT 1
#define NF_STOLEN 2
#define NF_QUEUE 3
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
#define NF_REPEAT 4
#define NF_STOP 5
#define NF_MAX_VERDICT NF_STOP
-
#define NF_VERDICT_MASK 0x0000ffff
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
#define NF_VERDICT_BITS 16
-
#define NF_VERDICT_QMASK 0xffff0000
#define NF_VERDICT_QBITS 16
-
-#define NF_QUEUE_NR(x) (((x << NF_VERDICT_QBITS) & NF_VERDICT_QMASK) | NF_QUEUE)
-
+#define NF_QUEUE_NR(x) ((((x) << NF_VERDICT_BITS) & NF_VERDICT_QMASK) | NF_QUEUE)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
#define NFC_UNKNOWN 0x4000
#define NFC_ALTERED 0x8000
-
+enum nf_inet_hooks {
+ NF_INET_PRE_ROUTING,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+ NF_INET_LOCAL_IN,
+ NF_INET_FORWARD,
+ NF_INET_LOCAL_OUT,
+ NF_INET_POST_ROUTING,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+ NF_INET_NUMHOOKS
+};
+enum {
+ NFPROTO_UNSPEC = 0,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+ NFPROTO_IPV4 = 2,
+ NFPROTO_ARP = 3,
+ NFPROTO_BRIDGE = 7,
+ NFPROTO_IPV6 = 10,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+ NFPROTO_DECNET = 12,
+ NFPROTO_NUMPROTO,
+};
+union nf_inet_addr {
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+ __u32 all[4];
+ __be32 ip;
+ __be32 ip6[4];
+ struct in_addr in;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+ struct in6_addr in6;
+};
#endif
+
diff --git a/libc/kernel/common/linux/netfilter/nfnetlink_conntrack.h b/libc/kernel/common/linux/netfilter/nfnetlink_conntrack.h
index 105dd09..0b1b356 100644
--- a/libc/kernel/common/linux/netfilter/nfnetlink_conntrack.h
+++ b/libc/kernel/common/linux/netfilter/nfnetlink_conntrack.h
@@ -7,140 +7,206 @@
*** structures, and macros generated from the original header, and thus,
*** contains no copyrightable information.
***
+ *** To edit the content of this header, modify the corresponding
+ *** source file (e.g. under external/kernel-headers/original/) then
+ *** run bionic/libc/kernel/tools/update_all.py
+ ***
+ *** Any manual change here will be lost the next time this script will
+ *** be run. You've been warned!
+ ***
****************************************************************************
****************************************************************************/
#ifndef _IPCONNTRACK_NETLINK_H
#define _IPCONNTRACK_NETLINK_H
#include <linux/netfilter/nfnetlink.h>
-
enum cntl_msg_types {
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
IPCTNL_MSG_CT_NEW,
IPCTNL_MSG_CT_GET,
IPCTNL_MSG_CT_DELETE,
IPCTNL_MSG_CT_GET_CTRZERO,
-
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
IPCTNL_MSG_MAX
};
-
enum ctnl_exp_msg_types {
IPCTNL_MSG_EXP_NEW,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
IPCTNL_MSG_EXP_GET,
IPCTNL_MSG_EXP_DELETE,
-
IPCTNL_MSG_EXP_MAX
};
-
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
enum ctattr_type {
CTA_UNSPEC,
CTA_TUPLE_ORIG,
CTA_TUPLE_REPLY,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
CTA_STATUS,
CTA_PROTOINFO,
CTA_HELP,
CTA_NAT_SRC,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
#define CTA_NAT CTA_NAT_SRC
CTA_TIMEOUT,
CTA_MARK,
CTA_COUNTERS_ORIG,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
CTA_COUNTERS_REPLY,
CTA_USE,
CTA_ID,
CTA_NAT_DST,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+ CTA_TUPLE_MASTER,
+ CTA_NAT_SEQ_ADJ_ORIG,
+ CTA_NAT_SEQ_ADJ_REPLY,
+ CTA_SECMARK,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+ CTA_ZONE,
__CTA_MAX
};
#define CTA_MAX (__CTA_MAX - 1)
-
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
enum ctattr_tuple {
CTA_TUPLE_UNSPEC,
CTA_TUPLE_IP,
CTA_TUPLE_PROTO,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
__CTA_TUPLE_MAX
};
#define CTA_TUPLE_MAX (__CTA_TUPLE_MAX - 1)
-
enum ctattr_ip {
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
CTA_IP_UNSPEC,
CTA_IP_V4_SRC,
CTA_IP_V4_DST,
CTA_IP_V6_SRC,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
CTA_IP_V6_DST,
__CTA_IP_MAX
};
#define CTA_IP_MAX (__CTA_IP_MAX - 1)
-
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
enum ctattr_l4proto {
CTA_PROTO_UNSPEC,
CTA_PROTO_NUM,
CTA_PROTO_SRC_PORT,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
CTA_PROTO_DST_PORT,
CTA_PROTO_ICMP_ID,
CTA_PROTO_ICMP_TYPE,
CTA_PROTO_ICMP_CODE,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
CTA_PROTO_ICMPV6_ID,
CTA_PROTO_ICMPV6_TYPE,
CTA_PROTO_ICMPV6_CODE,
__CTA_PROTO_MAX
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
};
#define CTA_PROTO_MAX (__CTA_PROTO_MAX - 1)
-
enum ctattr_protoinfo {
CTA_PROTOINFO_UNSPEC,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
CTA_PROTOINFO_TCP,
+ CTA_PROTOINFO_DCCP,
+ CTA_PROTOINFO_SCTP,
__CTA_PROTOINFO_MAX
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
};
#define CTA_PROTOINFO_MAX (__CTA_PROTOINFO_MAX - 1)
-
enum ctattr_protoinfo_tcp {
CTA_PROTOINFO_TCP_UNSPEC,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
CTA_PROTOINFO_TCP_STATE,
+ CTA_PROTOINFO_TCP_WSCALE_ORIGINAL,
+ CTA_PROTOINFO_TCP_WSCALE_REPLY,
+ CTA_PROTOINFO_TCP_FLAGS_ORIGINAL,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+ CTA_PROTOINFO_TCP_FLAGS_REPLY,
__CTA_PROTOINFO_TCP_MAX
};
#define CTA_PROTOINFO_TCP_MAX (__CTA_PROTOINFO_TCP_MAX - 1)
-
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+enum ctattr_protoinfo_dccp {
+ CTA_PROTOINFO_DCCP_UNSPEC,
+ CTA_PROTOINFO_DCCP_STATE,
+ CTA_PROTOINFO_DCCP_ROLE,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+ CTA_PROTOINFO_DCCP_HANDSHAKE_SEQ,
+ __CTA_PROTOINFO_DCCP_MAX,
+};
+#define CTA_PROTOINFO_DCCP_MAX (__CTA_PROTOINFO_DCCP_MAX - 1)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+enum ctattr_protoinfo_sctp {
+ CTA_PROTOINFO_SCTP_UNSPEC,
+ CTA_PROTOINFO_SCTP_STATE,
+ CTA_PROTOINFO_SCTP_VTAG_ORIGINAL,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+ CTA_PROTOINFO_SCTP_VTAG_REPLY,
+ __CTA_PROTOINFO_SCTP_MAX
+};
+#define CTA_PROTOINFO_SCTP_MAX (__CTA_PROTOINFO_SCTP_MAX - 1)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
enum ctattr_counters {
CTA_COUNTERS_UNSPEC,
CTA_COUNTERS_PACKETS,
CTA_COUNTERS_BYTES,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
CTA_COUNTERS32_PACKETS,
CTA_COUNTERS32_BYTES,
__CTA_COUNTERS_MAX
};
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
#define CTA_COUNTERS_MAX (__CTA_COUNTERS_MAX - 1)
-
enum ctattr_nat {
CTA_NAT_UNSPEC,
CTA_NAT_MINIP,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
CTA_NAT_MAXIP,
CTA_NAT_PROTO,
__CTA_NAT_MAX
};
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
#define CTA_NAT_MAX (__CTA_NAT_MAX - 1)
-
enum ctattr_protonat {
CTA_PROTONAT_UNSPEC,
CTA_PROTONAT_PORT_MIN,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
CTA_PROTONAT_PORT_MAX,
__CTA_PROTONAT_MAX
};
#define CTA_PROTONAT_MAX (__CTA_PROTONAT_MAX - 1)
-
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+enum ctattr_natseq {
+ CTA_NAT_SEQ_UNSPEC,
+ CTA_NAT_SEQ_CORRECTION_POS,
+ CTA_NAT_SEQ_OFFSET_BEFORE,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+ CTA_NAT_SEQ_OFFSET_AFTER,
+ __CTA_NAT_SEQ_MAX
+};
+#define CTA_NAT_SEQ_MAX (__CTA_NAT_SEQ_MAX - 1)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
enum ctattr_expect {
CTA_EXPECT_UNSPEC,
CTA_EXPECT_MASTER,
CTA_EXPECT_TUPLE,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
CTA_EXPECT_MASK,
CTA_EXPECT_TIMEOUT,
CTA_EXPECT_ID,
CTA_EXPECT_HELP_NAME,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+ CTA_EXPECT_ZONE,
__CTA_EXPECT_MAX
};
#define CTA_EXPECT_MAX (__CTA_EXPECT_MAX - 1)
-
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
enum ctattr_help {
CTA_HELP_UNSPEC,
CTA_HELP_NAME,
__CTA_HELP_MAX
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
};
#define CTA_HELP_MAX (__CTA_HELP_MAX - 1)
-
#endif
+
diff --git a/libc/kernel/common/linux/netfilter_ipv6/ip6_tables.h b/libc/kernel/common/linux/netfilter_ipv6/ip6_tables.h
index 1687e4f..d76a529 100644
--- a/libc/kernel/common/linux/netfilter_ipv6/ip6_tables.h
+++ b/libc/kernel/common/linux/netfilter_ipv6/ip6_tables.h
@@ -173,6 +173,15 @@
#define IP6T_ERROR_TARGET XT_ERROR_TARGET
+static __inline__ struct ip6t_entry_target *
+ip6t_get_target(struct ip6t_entry *e)
+{
+ return (void *)e + e->target_offset;
+}
+
#define IP6T_MATCH_ITERATE(e, fn, args...) ({ unsigned int __i; int __ret = 0; struct ip6t_entry_match *__m; for (__i = sizeof(struct ip6t_entry); __i < (e)->target_offset; __i += __m->u.match_size) { __m = (void *)(e) + __i; __ret = fn(__m , ## args); if (__ret != 0) break; } __ret; })
+
#define IP6T_ENTRY_ITERATE(entries, size, fn, args...) ({ unsigned int __i; int __ret = 0; struct ip6t_entry *__e; for (__i = 0; __i < (size); __i += __e->next_offset) { __e = (void *)(entries) + __i; __ret = fn(__e , ## args); if (__ret != 0) break; } __ret; })
+
#endif
+
diff --git a/libc/kernel/common/linux/perf_event.h b/libc/kernel/common/linux/perf_event.h
new file mode 100644
index 0000000..9d3cd14
--- /dev/null
+++ b/libc/kernel/common/linux/perf_event.h
@@ -0,0 +1,240 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ *** This header was automatically generated from a Linux kernel header
+ *** of the same name, to make information necessary for userspace to
+ *** call into the kernel available to libc. It contains only constants,
+ *** structures, and macros generated from the original header, and thus,
+ *** contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _LINUX_PERF_EVENT_H
+#define _LINUX_PERF_EVENT_H
+
+#include <linux/types.h>
+#include <linux/ioctl.h>
+#include <asm/byteorder.h>
+
+enum perf_type_id {
+ PERF_TYPE_HARDWARE = 0,
+ PERF_TYPE_SOFTWARE = 1,
+ PERF_TYPE_TRACEPOINT = 2,
+ PERF_TYPE_HW_CACHE = 3,
+ PERF_TYPE_RAW = 4,
+ PERF_TYPE_BREAKPOINT = 5,
+
+ PERF_TYPE_MAX,
+};
+
+enum perf_hw_id {
+
+ PERF_COUNT_HW_CPU_CYCLES = 0,
+ PERF_COUNT_HW_INSTRUCTIONS = 1,
+ PERF_COUNT_HW_CACHE_REFERENCES = 2,
+ PERF_COUNT_HW_CACHE_MISSES = 3,
+ PERF_COUNT_HW_BRANCH_INSTRUCTIONS = 4,
+ PERF_COUNT_HW_BRANCH_MISSES = 5,
+ PERF_COUNT_HW_BUS_CYCLES = 6,
+
+ PERF_COUNT_HW_MAX,
+};
+
+enum perf_hw_cache_id {
+ PERF_COUNT_HW_CACHE_L1D = 0,
+ PERF_COUNT_HW_CACHE_L1I = 1,
+ PERF_COUNT_HW_CACHE_LL = 2,
+ PERF_COUNT_HW_CACHE_DTLB = 3,
+ PERF_COUNT_HW_CACHE_ITLB = 4,
+ PERF_COUNT_HW_CACHE_BPU = 5,
+
+ PERF_COUNT_HW_CACHE_MAX,
+};
+
+enum perf_hw_cache_op_id {
+ PERF_COUNT_HW_CACHE_OP_READ = 0,
+ PERF_COUNT_HW_CACHE_OP_WRITE = 1,
+ PERF_COUNT_HW_CACHE_OP_PREFETCH = 2,
+
+ PERF_COUNT_HW_CACHE_OP_MAX,
+};
+
+enum perf_hw_cache_op_result_id {
+ PERF_COUNT_HW_CACHE_RESULT_ACCESS = 0,
+ PERF_COUNT_HW_CACHE_RESULT_MISS = 1,
+
+ PERF_COUNT_HW_CACHE_RESULT_MAX,
+};
+
+enum perf_sw_ids {
+ PERF_COUNT_SW_CPU_CLOCK = 0,
+ PERF_COUNT_SW_TASK_CLOCK = 1,
+ PERF_COUNT_SW_PAGE_FAULTS = 2,
+ PERF_COUNT_SW_CONTEXT_SWITCHES = 3,
+ PERF_COUNT_SW_CPU_MIGRATIONS = 4,
+ PERF_COUNT_SW_PAGE_FAULTS_MIN = 5,
+ PERF_COUNT_SW_PAGE_FAULTS_MAJ = 6,
+ PERF_COUNT_SW_ALIGNMENT_FAULTS = 7,
+ PERF_COUNT_SW_EMULATION_FAULTS = 8,
+
+ PERF_COUNT_SW_MAX,
+};
+
+enum perf_event_sample_format {
+ PERF_SAMPLE_IP = 1U << 0,
+ PERF_SAMPLE_TID = 1U << 1,
+ PERF_SAMPLE_TIME = 1U << 2,
+ PERF_SAMPLE_ADDR = 1U << 3,
+ PERF_SAMPLE_READ = 1U << 4,
+ PERF_SAMPLE_CALLCHAIN = 1U << 5,
+ PERF_SAMPLE_ID = 1U << 6,
+ PERF_SAMPLE_CPU = 1U << 7,
+ PERF_SAMPLE_PERIOD = 1U << 8,
+ PERF_SAMPLE_STREAM_ID = 1U << 9,
+ PERF_SAMPLE_RAW = 1U << 10,
+
+ PERF_SAMPLE_MAX = 1U << 11,
+};
+
+enum perf_event_read_format {
+ PERF_FORMAT_TOTAL_TIME_ENABLED = 1U << 0,
+ PERF_FORMAT_TOTAL_TIME_RUNNING = 1U << 1,
+ PERF_FORMAT_ID = 1U << 2,
+ PERF_FORMAT_GROUP = 1U << 3,
+
+ PERF_FORMAT_MAX = 1U << 4,
+};
+
+#define PERF_ATTR_SIZE_VER0 64
+
+struct perf_event_attr {
+
+ __u32 type;
+
+ __u32 size;
+
+ __u64 config;
+
+ union {
+ __u64 sample_period;
+ __u64 sample_freq;
+ };
+
+ __u64 sample_type;
+ __u64 read_format;
+
+ __u64 disabled : 1,
+ inherit : 1,
+ pinned : 1,
+ exclusive : 1,
+ exclude_user : 1,
+ exclude_kernel : 1,
+ exclude_hv : 1,
+ exclude_idle : 1,
+ mmap : 1,
+ comm : 1,
+ freq : 1,
+ inherit_stat : 1,
+ enable_on_exec : 1,
+ task : 1,
+ watermark : 1,
+
+ precise_ip : 2,
+
+ __reserved_1 : 47;
+
+ union {
+ __u32 wakeup_events;
+ __u32 wakeup_watermark;
+ };
+
+ __u32 bp_type;
+ __u64 bp_addr;
+ __u64 bp_len;
+};
+
+#define PERF_EVENT_IOC_ENABLE _IO ('$', 0)
+#define PERF_EVENT_IOC_DISABLE _IO ('$', 1)
+#define PERF_EVENT_IOC_REFRESH _IO ('$', 2)
+#define PERF_EVENT_IOC_RESET _IO ('$', 3)
+#define PERF_EVENT_IOC_PERIOD _IOW('$', 4, __u64)
+#define PERF_EVENT_IOC_SET_OUTPUT _IO ('$', 5)
+#define PERF_EVENT_IOC_SET_FILTER _IOW('$', 6, char *)
+
+enum perf_event_ioc_flags {
+ PERF_IOC_FLAG_GROUP = 1U << 0,
+};
+
+struct perf_event_mmap_page {
+ __u32 version;
+ __u32 compat_version;
+
+ __u32 lock;
+ __u32 index;
+ __s64 offset;
+ __u64 time_enabled;
+ __u64 time_running;
+
+ __u64 __reserved[123];
+
+ __u64 data_head;
+ __u64 data_tail;
+};
+
+#define PERF_RECORD_MISC_CPUMODE_MASK (7 << 0)
+#define PERF_RECORD_MISC_CPUMODE_UNKNOWN (0 << 0)
+#define PERF_RECORD_MISC_KERNEL (1 << 0)
+#define PERF_RECORD_MISC_USER (2 << 0)
+#define PERF_RECORD_MISC_HYPERVISOR (3 << 0)
+#define PERF_RECORD_MISC_GUEST_KERNEL (4 << 0)
+#define PERF_RECORD_MISC_GUEST_USER (5 << 0)
+
+#define PERF_RECORD_MISC_EXACT_IP (1 << 14)
+
+#define PERF_RECORD_MISC_EXT_RESERVED (1 << 15)
+
+struct perf_event_header {
+ __u32 type;
+ __u16 misc;
+ __u16 size;
+};
+
+enum perf_event_type {
+
+ PERF_RECORD_MMAP = 1,
+
+ PERF_RECORD_LOST = 2,
+
+ PERF_RECORD_COMM = 3,
+
+ PERF_RECORD_EXIT = 4,
+
+ PERF_RECORD_THROTTLE = 5,
+ PERF_RECORD_UNTHROTTLE = 6,
+
+ PERF_RECORD_FORK = 7,
+
+ PERF_RECORD_READ = 8,
+
+ PERF_RECORD_SAMPLE = 9,
+
+ PERF_RECORD_MAX,
+};
+
+enum perf_callchain_context {
+ PERF_CONTEXT_HV = (__u64)-32,
+ PERF_CONTEXT_KERNEL = (__u64)-128,
+ PERF_CONTEXT_USER = (__u64)-512,
+
+ PERF_CONTEXT_GUEST = (__u64)-2048,
+ PERF_CONTEXT_GUEST_KERNEL = (__u64)-2176,
+ PERF_CONTEXT_GUEST_USER = (__u64)-2560,
+
+ PERF_CONTEXT_MAX = (__u64)-4095,
+};
+
+#define PERF_FLAG_FD_NO_GROUP (1U << 0)
+#define PERF_FLAG_FD_OUTPUT (1U << 1)
+
+#endif
+
diff --git a/libc/kernel/common/linux/rtnetlink.h b/libc/kernel/common/linux/rtnetlink.h
index e305505..bbd991a 100644
--- a/libc/kernel/common/linux/rtnetlink.h
+++ b/libc/kernel/common/linux/rtnetlink.h
@@ -18,6 +18,10 @@
#include <linux/if_addr.h>
#include <linux/neighbour.h>
+#define RTNL_FAMILY_IPMR 128
+#define RTNL_FAMILY_IP6MR 129
+#define RTNL_FAMILY_MAX 129
+
enum {
RTM_BASE = 16,
#define RTM_BASE RTM_BASE
@@ -126,8 +130,7 @@
#define RTM_NR_FAMILIES (RTM_NR_MSGTYPES >> 2)
#define RTM_FAM(cmd) (((cmd) - RTM_BASE) >> 2)
-struct rtattr
-{
+struct rtattr {
unsigned short rta_len;
unsigned short rta_type;
};
@@ -141,8 +144,7 @@
#define RTA_DATA(rta) ((void*)(((char*)(rta)) + RTA_LENGTH(0)))
#define RTA_PAYLOAD(rta) ((int)((rta)->rta_len) - RTA_LENGTH(0))
-struct rtmsg
-{
+struct rtmsg {
unsigned char rtm_family;
unsigned char rtm_dst_len;
unsigned char rtm_src_len;
@@ -156,8 +158,7 @@
unsigned rtm_flags;
};
-enum
-{
+enum {
RTN_UNSPEC,
RTN_UNICAST,
RTN_LOCAL,
@@ -191,8 +192,7 @@
#define RTPROT_NTK 15
#define RTPROT_DHCP 16
-enum rt_scope_t
-{
+enum rt_scope_t {
RT_SCOPE_UNIVERSE=0,
RT_SCOPE_SITE=200,
@@ -206,8 +206,7 @@
#define RTM_F_EQUALIZE 0x400
#define RTM_F_PREFIX 0x800
-enum rt_class_t
-{
+enum rt_class_t {
RT_TABLE_UNSPEC=0,
RT_TABLE_COMPAT=252,
@@ -217,8 +216,7 @@
RT_TABLE_MAX=0xFFFFFFFF
};
-enum rtattr_type_t
-{
+enum rtattr_type_t {
RTA_UNSPEC,
RTA_DST,
RTA_SRC,
@@ -235,6 +233,7 @@
RTA_SESSION,
RTA_MP_ALGO,
RTA_TABLE,
+ RTA_MARK,
__RTA_MAX
};
@@ -243,8 +242,7 @@
#define RTM_RTA(r) ((struct rtattr*)(((char*)(r)) + NLMSG_ALIGN(sizeof(struct rtmsg))))
#define RTM_PAYLOAD(n) NLMSG_PAYLOAD(n,sizeof(struct rtmsg))
-struct rtnexthop
-{
+struct rtnexthop {
unsigned short rtnh_len;
unsigned char rtnh_flags;
unsigned char rtnh_hops;
@@ -263,8 +261,7 @@
#define RTNH_SPACE(len) RTNH_ALIGN(RTNH_LENGTH(len))
#define RTNH_DATA(rtnh) ((struct rtattr*)(((char*)(rtnh)) + RTNH_LENGTH(0)))
-struct rta_cacheinfo
-{
+struct rta_cacheinfo {
__u32 rta_clntref;
__u32 rta_lastuse;
__s32 rta_expires;
@@ -277,8 +274,7 @@
__u32 rta_tsage;
};
-enum
-{
+enum {
RTAX_UNSPEC,
#define RTAX_UNSPEC RTAX_UNSPEC
RTAX_LOCK,
@@ -307,6 +303,8 @@
#define RTAX_FEATURES RTAX_FEATURES
RTAX_RTO_MIN,
#define RTAX_RTO_MIN RTAX_RTO_MIN
+ RTAX_INITRWND,
+#define RTAX_INITRWND RTAX_INITRWND
__RTAX_MAX
};
@@ -317,8 +315,7 @@
#define RTAX_FEATURE_TIMESTAMP 0x00000004
#define RTAX_FEATURE_ALLFRAG 0x00000008
-struct rta_session
-{
+struct rta_session {
__u8 proto;
__u8 pad1;
__u16 pad2;
@@ -339,13 +336,11 @@
} u;
};
-struct rtgenmsg
-{
+struct rtgenmsg {
unsigned char rtgen_family;
};
-struct ifinfomsg
-{
+struct ifinfomsg {
unsigned char ifi_family;
unsigned char __ifi_pad;
unsigned short ifi_type;
@@ -354,8 +349,7 @@
unsigned ifi_change;
};
-struct prefixmsg
-{
+struct prefixmsg {
unsigned char prefix_family;
unsigned char prefix_pad1;
unsigned short prefix_pad2;
@@ -376,14 +370,12 @@
#define PREFIX_MAX (__PREFIX_MAX - 1)
-struct prefix_cacheinfo
-{
+struct prefix_cacheinfo {
__u32 preferred_time;
__u32 valid_time;
};
-struct tcmsg
-{
+struct tcmsg {
unsigned char tcm_family;
unsigned char tcm__pad1;
unsigned short tcm__pad2;
@@ -393,8 +385,7 @@
__u32 tcm_info;
};
-enum
-{
+enum {
TCA_UNSPEC,
TCA_KIND,
TCA_OPTIONS,
@@ -412,8 +403,7 @@
#define TCA_RTA(r) ((struct rtattr*)(((char*)(r)) + NLMSG_ALIGN(sizeof(struct tcmsg))))
#define TCA_PAYLOAD(n) NLMSG_PAYLOAD(n,sizeof(struct tcmsg))
-struct nduseroptmsg
-{
+struct nduseroptmsg {
unsigned char nduseropt_family;
unsigned char nduseropt_pad1;
unsigned short nduseropt_opts_len;
@@ -425,8 +415,7 @@
};
-enum
-{
+enum {
NDUSEROPT_UNSPEC,
NDUSEROPT_SRCADDR,
__NDUSEROPT_MAX
@@ -503,8 +492,7 @@
};
#define RTNLGRP_MAX (__RTNLGRP_MAX - 1)
-struct tcamsg
-{
+struct tcamsg {
unsigned char tca_family;
unsigned char tca__pad1;
unsigned short tca__pad2;
@@ -515,3 +503,4 @@
#define TCAA_MAX 1
#endif
+
diff --git a/libc/kernel/common/linux/spi/cpcap.h b/libc/kernel/common/linux/spi/cpcap.h
new file mode 100644
index 0000000..24bc918
--- /dev/null
+++ b/libc/kernel/common/linux/spi/cpcap.h
@@ -0,0 +1,587 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ *** This header was automatically generated from a Linux kernel header
+ *** of the same name, to make information necessary for userspace to
+ *** call into the kernel available to libc. It contains only constants,
+ *** structures, and macros generated from the original header, and thus,
+ *** contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _LINUX_SPI_CPCAP_H
+#define _LINUX_SPI_CPCAP_H
+
+#include <linux/ioctl.h>
+
+#define CPCAP_DEV_NAME "cpcap"
+#define CPCAP_NUM_REG_CPCAP (CPCAP_REG_END - CPCAP_REG_START + 1)
+
+#define CPCAP_IRQ_INT1_INDEX 0
+#define CPCAP_IRQ_INT2_INDEX 16
+#define CPCAP_IRQ_INT3_INDEX 32
+#define CPCAP_IRQ_INT4_INDEX 48
+#define CPCAP_IRQ_INT5_INDEX 64
+
+#define CPCAP_HWCFG_NUM 2
+
+#define CPCAP_HWCFG0_SEC_STBY_SW1 0x0001
+#define CPCAP_HWCFG0_SEC_STBY_SW2 0x0002
+#define CPCAP_HWCFG0_SEC_STBY_SW3 0x0004
+#define CPCAP_HWCFG0_SEC_STBY_SW4 0x0008
+#define CPCAP_HWCFG0_SEC_STBY_SW5 0x0010
+#define CPCAP_HWCFG0_SEC_STBY_VAUDIO 0x0020
+#define CPCAP_HWCFG0_SEC_STBY_VCAM 0x0040
+#define CPCAP_HWCFG0_SEC_STBY_VCSI 0x0080
+#define CPCAP_HWCFG0_SEC_STBY_VDAC 0x0100
+#define CPCAP_HWCFG0_SEC_STBY_VDIG 0x0200
+#define CPCAP_HWCFG0_SEC_STBY_VHVIO 0x0400
+#define CPCAP_HWCFG0_SEC_STBY_VPLL 0x0800
+#define CPCAP_HWCFG0_SEC_STBY_VRF1 0x1000
+#define CPCAP_HWCFG0_SEC_STBY_VRF2 0x2000
+#define CPCAP_HWCFG0_SEC_STBY_VRFREF 0x4000
+#define CPCAP_HWCFG0_SEC_STBY_VSDIO 0x8000
+
+#define CPCAP_HWCFG1_SEC_STBY_VWLAN1 0x0001
+#define CPCAP_HWCFG1_SEC_STBY_VWLAN2 0x0002
+#define CPCAP_HWCFG1_SEC_STBY_VSIM 0x0004
+#define CPCAP_HWCFG1_SEC_STBY_VSIMCARD 0x0008
+
+#define CPCAP_WHISPER_MODE_PU 0x00000001
+#define CPCAP_WHISPER_ENABLE_UART 0x00000002
+#define CPCAP_WHISPER_ACCY_MASK 0xF8000000
+#define CPCAP_WHISPER_ACCY_SHFT 27
+#define CPCAP_WHISPER_ID_SIZE 16
+#define CPCAP_WHISPER_PROP_SIZE 7
+
+enum cpcap_regulator_id {
+ CPCAP_SW2,
+ CPCAP_SW4,
+ CPCAP_SW5,
+ CPCAP_VCAM,
+ CPCAP_VCSI,
+ CPCAP_VDAC,
+ CPCAP_VDIG,
+ CPCAP_VFUSE,
+ CPCAP_VHVIO,
+ CPCAP_VSDIO,
+ CPCAP_VPLL,
+ CPCAP_VRF1,
+ CPCAP_VRF2,
+ CPCAP_VRFREF,
+ CPCAP_VWLAN1,
+ CPCAP_VWLAN2,
+ CPCAP_VSIM,
+ CPCAP_VSIMCARD,
+ CPCAP_VVIB,
+ CPCAP_VUSB,
+ CPCAP_VAUDIO,
+ CPCAP_NUM_REGULATORS
+};
+
+enum cpcap_reg {
+ CPCAP_REG_START,
+
+ CPCAP_REG_INT1 = CPCAP_REG_START,
+ CPCAP_REG_INT2,
+ CPCAP_REG_INT3,
+ CPCAP_REG_INT4,
+ CPCAP_REG_INTM1,
+ CPCAP_REG_INTM2,
+ CPCAP_REG_INTM3,
+ CPCAP_REG_INTM4,
+ CPCAP_REG_INTS1,
+ CPCAP_REG_INTS2,
+ CPCAP_REG_INTS3,
+ CPCAP_REG_INTS4,
+ CPCAP_REG_ASSIGN1,
+ CPCAP_REG_ASSIGN2,
+ CPCAP_REG_ASSIGN3,
+ CPCAP_REG_ASSIGN4,
+ CPCAP_REG_ASSIGN5,
+ CPCAP_REG_ASSIGN6,
+ CPCAP_REG_VERSC1,
+ CPCAP_REG_VERSC2,
+
+ CPCAP_REG_MI1,
+ CPCAP_REG_MIM1,
+ CPCAP_REG_MI2,
+ CPCAP_REG_MIM2,
+ CPCAP_REG_UCC1,
+ CPCAP_REG_UCC2,
+ CPCAP_REG_PC1,
+ CPCAP_REG_PC2,
+ CPCAP_REG_BPEOL,
+ CPCAP_REG_PGC,
+ CPCAP_REG_MT1,
+ CPCAP_REG_MT2,
+ CPCAP_REG_MT3,
+ CPCAP_REG_PF,
+
+ CPCAP_REG_SCC,
+ CPCAP_REG_SW1,
+ CPCAP_REG_SW2,
+ CPCAP_REG_UCTM,
+ CPCAP_REG_TOD1,
+ CPCAP_REG_TOD2,
+ CPCAP_REG_TODA1,
+ CPCAP_REG_TODA2,
+ CPCAP_REG_DAY,
+ CPCAP_REG_DAYA,
+ CPCAP_REG_VAL1,
+ CPCAP_REG_VAL2,
+
+ CPCAP_REG_SDVSPLL,
+ CPCAP_REG_SI2CC1,
+ CPCAP_REG_Si2CC2,
+ CPCAP_REG_S1C1,
+ CPCAP_REG_S1C2,
+ CPCAP_REG_S2C1,
+ CPCAP_REG_S2C2,
+ CPCAP_REG_S3C,
+ CPCAP_REG_S4C1,
+ CPCAP_REG_S4C2,
+ CPCAP_REG_S5C,
+ CPCAP_REG_S6C,
+ CPCAP_REG_VCAMC,
+ CPCAP_REG_VCSIC,
+ CPCAP_REG_VDACC,
+ CPCAP_REG_VDIGC,
+ CPCAP_REG_VFUSEC,
+ CPCAP_REG_VHVIOC,
+ CPCAP_REG_VSDIOC,
+ CPCAP_REG_VPLLC,
+ CPCAP_REG_VRF1C,
+ CPCAP_REG_VRF2C,
+ CPCAP_REG_VRFREFC,
+ CPCAP_REG_VWLAN1C,
+ CPCAP_REG_VWLAN2C,
+ CPCAP_REG_VSIMC,
+ CPCAP_REG_VVIBC,
+ CPCAP_REG_VUSBC,
+ CPCAP_REG_VUSBINT1C,
+ CPCAP_REG_VUSBINT2C,
+ CPCAP_REG_URT,
+ CPCAP_REG_URM1,
+ CPCAP_REG_URM2,
+
+ CPCAP_REG_VAUDIOC,
+ CPCAP_REG_CC,
+ CPCAP_REG_CDI,
+ CPCAP_REG_SDAC,
+ CPCAP_REG_SDACDI,
+ CPCAP_REG_TXI,
+ CPCAP_REG_TXMP,
+ CPCAP_REG_RXOA,
+ CPCAP_REG_RXVC,
+ CPCAP_REG_RXCOA,
+ CPCAP_REG_RXSDOA,
+ CPCAP_REG_RXEPOA,
+ CPCAP_REG_RXLL,
+ CPCAP_REG_A2LA,
+ CPCAP_REG_MIPIS1,
+ CPCAP_REG_MIPIS2,
+ CPCAP_REG_MIPIS3,
+ CPCAP_REG_LVAB,
+
+ CPCAP_REG_CCC1,
+ CPCAP_REG_CRM,
+ CPCAP_REG_CCCC2,
+ CPCAP_REG_CCS1,
+ CPCAP_REG_CCS2,
+ CPCAP_REG_CCA1,
+ CPCAP_REG_CCA2,
+ CPCAP_REG_CCM,
+ CPCAP_REG_CCO,
+ CPCAP_REG_CCI,
+
+ CPCAP_REG_ADCC1,
+ CPCAP_REG_ADCC2,
+ CPCAP_REG_ADCD0,
+ CPCAP_REG_ADCD1,
+ CPCAP_REG_ADCD2,
+ CPCAP_REG_ADCD3,
+ CPCAP_REG_ADCD4,
+ CPCAP_REG_ADCD5,
+ CPCAP_REG_ADCD6,
+ CPCAP_REG_ADCD7,
+ CPCAP_REG_ADCAL1,
+ CPCAP_REG_ADCAL2,
+
+ CPCAP_REG_USBC1,
+ CPCAP_REG_USBC2,
+ CPCAP_REG_USBC3,
+ CPCAP_REG_UVIDL,
+ CPCAP_REG_UVIDH,
+ CPCAP_REG_UPIDL,
+ CPCAP_REG_UPIDH,
+ CPCAP_REG_UFC1,
+ CPCAP_REG_UFC2,
+ CPCAP_REG_UFC3,
+ CPCAP_REG_UIC1,
+ CPCAP_REG_UIC2,
+ CPCAP_REG_UIC3,
+ CPCAP_REG_USBOTG1,
+ CPCAP_REG_USBOTG2,
+ CPCAP_REG_USBOTG3,
+ CPCAP_REG_UIER1,
+ CPCAP_REG_UIER2,
+ CPCAP_REG_UIER3,
+ CPCAP_REG_UIEF1,
+ CPCAP_REG_UIEF2,
+ CPCAP_REG_UIEF3,
+ CPCAP_REG_UIS,
+ CPCAP_REG_UIL,
+ CPCAP_REG_USBD,
+ CPCAP_REG_SCR1,
+ CPCAP_REG_SCR2,
+ CPCAP_REG_SCR3,
+ CPCAP_REG_VMC,
+ CPCAP_REG_OWDC,
+ CPCAP_REG_GPIO0,
+ CPCAP_REG_GPIO1,
+ CPCAP_REG_GPIO2,
+ CPCAP_REG_GPIO3,
+ CPCAP_REG_GPIO4,
+ CPCAP_REG_GPIO5,
+ CPCAP_REG_GPIO6,
+
+ CPCAP_REG_MDLC,
+ CPCAP_REG_KLC,
+ CPCAP_REG_ADLC,
+ CPCAP_REG_REDC,
+ CPCAP_REG_GREENC,
+ CPCAP_REG_BLUEC,
+ CPCAP_REG_CFC,
+ CPCAP_REG_ABC,
+ CPCAP_REG_BLEDC,
+ CPCAP_REG_CLEDC,
+
+ CPCAP_REG_OW1C,
+ CPCAP_REG_OW1D,
+ CPCAP_REG_OW1I,
+ CPCAP_REG_OW1IE,
+ CPCAP_REG_OW1,
+ CPCAP_REG_OW2C,
+ CPCAP_REG_OW2D,
+ CPCAP_REG_OW2I,
+ CPCAP_REG_OW2IE,
+ CPCAP_REG_OW2,
+ CPCAP_REG_OW3C,
+ CPCAP_REG_OW3D,
+ CPCAP_REG_OW3I,
+ CPCAP_REG_OW3IE,
+ CPCAP_REG_OW3,
+ CPCAP_REG_GCAIC,
+ CPCAP_REG_GCAIM,
+ CPCAP_REG_LGDIR,
+ CPCAP_REG_LGPU,
+ CPCAP_REG_LGPIN,
+ CPCAP_REG_LGMASK,
+ CPCAP_REG_LDEB,
+ CPCAP_REG_LGDET,
+ CPCAP_REG_LMISC,
+ CPCAP_REG_LMACE,
+
+ CPCAP_REG_END = CPCAP_REG_LMACE,
+
+ CPCAP_REG_MAX
+ = CPCAP_REG_END,
+
+ CPCAP_REG_SIZE = CPCAP_REG_MAX + 1,
+ CPCAP_REG_UNUSED = CPCAP_REG_MAX + 2,
+};
+
+enum {
+ CPCAP_IOCTL_NUM_TEST__START,
+ CPCAP_IOCTL_NUM_TEST_READ_REG,
+ CPCAP_IOCTL_NUM_TEST_WRITE_REG,
+ CPCAP_IOCTL_NUM_TEST__END,
+
+ CPCAP_IOCTL_NUM_ADC__START,
+ CPCAP_IOCTL_NUM_ADC_PHASE,
+ CPCAP_IOCTL_NUM_ADC__END,
+
+ CPCAP_IOCTL_NUM_BATT__START,
+ CPCAP_IOCTL_NUM_BATT_DISPLAY_UPDATE,
+ CPCAP_IOCTL_NUM_BATT_ATOD_ASYNC,
+ CPCAP_IOCTL_NUM_BATT_ATOD_SYNC,
+ CPCAP_IOCTL_NUM_BATT_ATOD_READ,
+ CPCAP_IOCTL_NUM_BATT__END,
+
+ CPCAP_IOCTL_NUM_UC__START,
+ CPCAP_IOCTL_NUM_UC_MACRO_START,
+ CPCAP_IOCTL_NUM_UC_MACRO_STOP,
+ CPCAP_IOCTL_NUM_UC_GET_VENDOR,
+ CPCAP_IOCTL_NUM_UC_SET_TURBO_MODE,
+ CPCAP_IOCTL_NUM_UC__END,
+
+ CPCAP_IOCTL_NUM_ACCY__START,
+ CPCAP_IOCTL_NUM_ACCY_WHISPER,
+ CPCAP_IOCTL_NUM_ACCY__END,
+};
+
+enum cpcap_irqs {
+ CPCAP_IRQ__START,
+ CPCAP_IRQ_HSCLK = CPCAP_IRQ_INT1_INDEX,
+ CPCAP_IRQ_PRIMAC,
+ CPCAP_IRQ_SECMAC,
+ CPCAP_IRQ_LOWBPL,
+ CPCAP_IRQ_SEC2PRI,
+ CPCAP_IRQ_LOWBPH,
+ CPCAP_IRQ_EOL,
+ CPCAP_IRQ_TS,
+ CPCAP_IRQ_ADCDONE,
+ CPCAP_IRQ_HS,
+ CPCAP_IRQ_MB2,
+ CPCAP_IRQ_VBUSOV,
+ CPCAP_IRQ_RVRS_CHRG,
+ CPCAP_IRQ_CHRG_DET,
+ CPCAP_IRQ_IDFLOAT,
+ CPCAP_IRQ_IDGND,
+
+ CPCAP_IRQ_SE1 = CPCAP_IRQ_INT2_INDEX,
+ CPCAP_IRQ_SESSEND,
+ CPCAP_IRQ_SESSVLD,
+ CPCAP_IRQ_VBUSVLD,
+ CPCAP_IRQ_CHRG_CURR1,
+ CPCAP_IRQ_CHRG_CURR2,
+ CPCAP_IRQ_RVRS_MODE,
+ CPCAP_IRQ_ON,
+ CPCAP_IRQ_ON2,
+ CPCAP_IRQ_CLK,
+ CPCAP_IRQ_1HZ,
+ CPCAP_IRQ_PTT,
+ CPCAP_IRQ_SE0CONN,
+ CPCAP_IRQ_CHRG_SE1B,
+ CPCAP_IRQ_UART_ECHO_OVERRUN,
+ CPCAP_IRQ_EXTMEMHD,
+
+ CPCAP_IRQ_WARM = CPCAP_IRQ_INT3_INDEX,
+ CPCAP_IRQ_SYSRSTR,
+ CPCAP_IRQ_SOFTRST,
+ CPCAP_IRQ_DIEPWRDWN,
+ CPCAP_IRQ_DIETEMPH,
+ CPCAP_IRQ_PC,
+ CPCAP_IRQ_OFLOWSW,
+ CPCAP_IRQ_TODA,
+ CPCAP_IRQ_OPT_SEL_DTCH,
+ CPCAP_IRQ_OPT_SEL_STATE,
+ CPCAP_IRQ_ONEWIRE1,
+ CPCAP_IRQ_ONEWIRE2,
+ CPCAP_IRQ_ONEWIRE3,
+ CPCAP_IRQ_UCRESET,
+ CPCAP_IRQ_PWRGOOD,
+ CPCAP_IRQ_USBDPLLCLK,
+
+ CPCAP_IRQ_DPI = CPCAP_IRQ_INT4_INDEX,
+ CPCAP_IRQ_DMI,
+ CPCAP_IRQ_UCBUSY,
+ CPCAP_IRQ_GCAI_CURR1,
+ CPCAP_IRQ_GCAI_CURR2,
+ CPCAP_IRQ_SB_MAX_RETRANSMIT_ERR,
+ CPCAP_IRQ_BATTDETB,
+ CPCAP_IRQ_PRIHALT,
+ CPCAP_IRQ_SECHALT,
+ CPCAP_IRQ_CC_CAL,
+
+ CPCAP_IRQ_UC_PRIROMR = CPCAP_IRQ_INT5_INDEX,
+ CPCAP_IRQ_UC_PRIRAMW,
+ CPCAP_IRQ_UC_PRIRAMR,
+ CPCAP_IRQ_UC_USEROFF,
+ CPCAP_IRQ_UC_PRIMACRO_4,
+ CPCAP_IRQ_UC_PRIMACRO_5,
+ CPCAP_IRQ_UC_PRIMACRO_6,
+ CPCAP_IRQ_UC_PRIMACRO_7,
+ CPCAP_IRQ_UC_PRIMACRO_8,
+ CPCAP_IRQ_UC_PRIMACRO_9,
+ CPCAP_IRQ_UC_PRIMACRO_10,
+ CPCAP_IRQ_UC_PRIMACRO_11,
+ CPCAP_IRQ_UC_PRIMACRO_12,
+ CPCAP_IRQ_UC_PRIMACRO_13,
+ CPCAP_IRQ_UC_PRIMACRO_14,
+ CPCAP_IRQ_UC_PRIMACRO_15,
+ CPCAP_IRQ__NUM
+};
+
+enum cpcap_adc_bank0 {
+ CPCAP_ADC_AD0_BATTDETB,
+ CPCAP_ADC_BATTP,
+ CPCAP_ADC_VBUS,
+ CPCAP_ADC_AD3,
+ CPCAP_ADC_BPLUS_AD4,
+ CPCAP_ADC_CHG_ISENSE,
+ CPCAP_ADC_BATTI_ADC,
+ CPCAP_ADC_USB_ID,
+
+ CPCAP_ADC_BANK0_NUM,
+};
+
+enum cpcap_adc_bank1 {
+ CPCAP_ADC_AD8,
+ CPCAP_ADC_AD9,
+ CPCAP_ADC_LICELL,
+ CPCAP_ADC_HV_BATTP,
+ CPCAP_ADC_TSX1_AD12,
+ CPCAP_ADC_TSX2_AD13,
+ CPCAP_ADC_TSY1_AD14,
+ CPCAP_ADC_TSY2_AD15,
+
+ CPCAP_ADC_BANK1_NUM,
+};
+
+enum cpcap_adc_format {
+ CPCAP_ADC_FORMAT_RAW,
+ CPCAP_ADC_FORMAT_PHASED,
+ CPCAP_ADC_FORMAT_CONVERTED,
+};
+
+enum cpcap_adc_timing {
+ CPCAP_ADC_TIMING_IMM,
+ CPCAP_ADC_TIMING_IN,
+ CPCAP_ADC_TIMING_OUT,
+};
+
+enum cpcap_adc_type {
+ CPCAP_ADC_TYPE_BANK_0,
+ CPCAP_ADC_TYPE_BANK_1,
+ CPCAP_ADC_TYPE_BATT_PI,
+};
+
+enum cpcap_macro {
+ CPCAP_MACRO_ROMR,
+ CPCAP_MACRO_RAMW,
+ CPCAP_MACRO_RAMR,
+ CPCAP_MACRO_USEROFF,
+ CPCAP_MACRO_4,
+ CPCAP_MACRO_5,
+ CPCAP_MACRO_6,
+ CPCAP_MACRO_7,
+ CPCAP_MACRO_8,
+ CPCAP_MACRO_9,
+ CPCAP_MACRO_10,
+ CPCAP_MACRO_11,
+ CPCAP_MACRO_12,
+ CPCAP_MACRO_13,
+ CPCAP_MACRO_14,
+ CPCAP_MACRO_15,
+
+ CPCAP_MACRO__END,
+};
+
+enum cpcap_vendor {
+ CPCAP_VENDOR_ST,
+ CPCAP_VENDOR_TI,
+};
+
+enum cpcap_revision {
+ CPCAP_REVISION_1_0 = 0x08,
+ CPCAP_REVISION_1_1 = 0x09,
+ CPCAP_REVISION_2_0 = 0x10,
+ CPCAP_REVISION_2_1 = 0x11,
+};
+
+enum cpcap_batt_usb_model {
+ CPCAP_BATT_USB_MODEL_NONE,
+ CPCAP_BATT_USB_MODEL_USB,
+ CPCAP_BATT_USB_MODEL_FACTORY,
+};
+
+struct cpcap_spi_init_data {
+ enum cpcap_reg reg;
+ unsigned short data;
+};
+
+struct cpcap_adc_ato {
+ unsigned short ato_in;
+ unsigned short atox_in;
+ unsigned short adc_ps_factor_in;
+ unsigned short atox_ps_factor_in;
+ unsigned short ato_out;
+ unsigned short atox_out;
+ unsigned short adc_ps_factor_out;
+ unsigned short atox_ps_factor_out;
+};
+
+struct cpcap_batt_data {
+ int status;
+ int health;
+ int present;
+ int capacity;
+ int batt_volt;
+ int batt_temp;
+};
+
+struct cpcap_batt_ac_data {
+ int online;
+};
+
+struct cpcap_batt_usb_data {
+ int online;
+ int current_now;
+ enum cpcap_batt_usb_model model;
+};
+
+struct cpcap_device;
+
+struct cpcap_adc_us_request {
+ enum cpcap_adc_format format;
+ enum cpcap_adc_timing timing;
+ enum cpcap_adc_type type;
+ int status;
+ int result[CPCAP_ADC_BANK0_NUM];
+};
+
+struct cpcap_adc_phase {
+ signed char offset_batti;
+ unsigned char slope_batti;
+ signed char offset_chrgi;
+ unsigned char slope_chrgi;
+ signed char offset_battp;
+ unsigned char slope_battp;
+ signed char offset_bp;
+ unsigned char slope_bp;
+ signed char offset_battt;
+ unsigned char slope_battt;
+ signed char offset_chrgv;
+ unsigned char slope_chrgv;
+};
+
+struct cpcap_regacc {
+ unsigned short reg;
+ unsigned short value;
+ unsigned short mask;
+};
+
+struct cpcap_whisper_request {
+ unsigned int cmd;
+ char dock_id[CPCAP_WHISPER_ID_SIZE];
+ char dock_prop[CPCAP_WHISPER_PROP_SIZE];
+};
+
+#define CPCAP_IOCTL_TEST_READ_REG _IOWR(0, CPCAP_IOCTL_NUM_TEST_READ_REG, struct cpcap_regacc*)
+
+#define CPCAP_IOCTL_TEST_WRITE_REG _IOWR(0, CPCAP_IOCTL_NUM_TEST_WRITE_REG, struct cpcap_regacc*)
+
+#define CPCAP_IOCTL_ADC_PHASE _IOWR(0, CPCAP_IOCTL_NUM_ADC_PHASE, struct cpcap_adc_phase*)
+
+#define CPCAP_IOCTL_BATT_DISPLAY_UPDATE _IOW(0, CPCAP_IOCTL_NUM_BATT_DISPLAY_UPDATE, struct cpcap_batt_data*)
+
+#define CPCAP_IOCTL_BATT_ATOD_ASYNC _IOW(0, CPCAP_IOCTL_NUM_BATT_ATOD_ASYNC, struct cpcap_adc_us_request*)
+
+#define CPCAP_IOCTL_BATT_ATOD_SYNC _IOWR(0, CPCAP_IOCTL_NUM_BATT_ATOD_SYNC, struct cpcap_adc_us_request*)
+
+#define CPCAP_IOCTL_BATT_ATOD_READ _IOWR(0, CPCAP_IOCTL_NUM_BATT_ATOD_READ, struct cpcap_adc_us_request*)
+
+#define CPCAP_IOCTL_UC_MACRO_START _IOWR(0, CPCAP_IOCTL_NUM_UC_MACRO_START, enum cpcap_macro)
+
+#define CPCAP_IOCTL_UC_MACRO_STOP _IOWR(0, CPCAP_IOCTL_NUM_UC_MACRO_STOP, enum cpcap_macro)
+
+#define CPCAP_IOCTL_UC_GET_VENDOR _IOWR(0, CPCAP_IOCTL_NUM_UC_GET_VENDOR, enum cpcap_vendor)
+
+#define CPCAP_IOCTL_UC_SET_TURBO_MODE _IOW(0, CPCAP_IOCTL_NUM_UC_SET_TURBO_MODE, unsigned short)
+
+#define CPCAP_IOCTL_ACCY_WHISPER _IOW(0, CPCAP_IOCTL_NUM_ACCY_WHISPER, struct cpcap_whisper_request*)
+
+#endif
+
diff --git a/libc/kernel/common/linux/tegra_audio.h b/libc/kernel/common/linux/tegra_audio.h
new file mode 100644
index 0000000..e18ce11
--- /dev/null
+++ b/libc/kernel/common/linux/tegra_audio.h
@@ -0,0 +1,43 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ *** This header was automatically generated from a Linux kernel header
+ *** of the same name, to make information necessary for userspace to
+ *** call into the kernel available to libc. It contains only constants,
+ *** structures, and macros generated from the original header, and thus,
+ *** contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _TEGRA_AUDIO_H
+#define _TEGRA_AUDIO_H
+
+#include <linux/ioctl.h>
+
+#define TEGRA_AUDIO_MAGIC 't'
+
+#define TEGRA_AUDIO_IN_START _IO(TEGRA_AUDIO_MAGIC, 0)
+#define TEGRA_AUDIO_IN_STOP _IO(TEGRA_AUDIO_MAGIC, 1)
+
+struct tegra_audio_in_config {
+ int rate;
+ int stereo;
+};
+
+#define TEGRA_AUDIO_IN_SET_CONFIG _IOW(TEGRA_AUDIO_MAGIC, 2, const struct tegra_audio_in_config *)
+#define TEGRA_AUDIO_IN_GET_CONFIG _IOR(TEGRA_AUDIO_MAGIC, 3, struct tegra_audio_in_config *)
+
+#define TEGRA_AUDIO_IN_SET_NUM_BUFS _IOW(TEGRA_AUDIO_MAGIC, 4, const unsigned int *)
+#define TEGRA_AUDIO_IN_GET_NUM_BUFS _IOW(TEGRA_AUDIO_MAGIC, 5, unsigned int *)
+#define TEGRA_AUDIO_OUT_SET_NUM_BUFS _IOW(TEGRA_AUDIO_MAGIC, 6, const unsigned int *)
+#define TEGRA_AUDIO_OUT_GET_NUM_BUFS _IOW(TEGRA_AUDIO_MAGIC, 7, unsigned int *)
+
+#define TEGRA_AUDIO_OUT_FLUSH _IO(TEGRA_AUDIO_MAGIC, 10)
+
+#define TEGRA_AUDIO_BIT_FORMAT_DEFAULT 0
+#define TEGRA_AUDIO_BIT_FORMAT_DSP 1
+#define TEGRA_AUDIO_SET_BIT_FORMAT _IOW(TEGRA_AUDIO_MAGIC, 11, const unsigned int *)
+#define TEGRA_AUDIO_GET_BIT_FORMAT _IOR(TEGRA_AUDIO_MAGIC, 12, unsigned int *)
+
+#endif
+
diff --git a/libc/kernel/common/linux/tegra_avp.h b/libc/kernel/common/linux/tegra_avp.h
new file mode 100644
index 0000000..c4a0cbd
--- /dev/null
+++ b/libc/kernel/common/linux/tegra_avp.h
@@ -0,0 +1,38 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ *** This header was automatically generated from a Linux kernel header
+ *** of the same name, to make information necessary for userspace to
+ *** call into the kernel available to libc. It contains only constants,
+ *** structures, and macros generated from the original header, and thus,
+ *** contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef __LINUX_TEGRA_AVP_H
+#define __LINUX_TEGRA_AVP_H
+
+#include <linux/ioctl.h>
+#include <linux/types.h>
+
+#define TEGRA_AVP_LIB_MAX_NAME 32
+#define TEGRA_AVP_LIB_MAX_ARGS 220
+
+struct tegra_avp_lib {
+ char name[TEGRA_AVP_LIB_MAX_NAME];
+ void __user *args;
+ size_t args_len;
+ int greedy;
+ unsigned long handle;
+};
+
+#define TEGRA_AVP_IOCTL_MAGIC 'r'
+
+#define TEGRA_AVP_IOCTL_LOAD_LIB _IOWR(TEGRA_AVP_IOCTL_MAGIC, 0x40, struct tegra_avp_lib)
+#define TEGRA_AVP_IOCTL_UNLOAD_LIB _IOW(TEGRA_AVP_IOCTL_MAGIC, 0x41, unsigned long)
+
+#define TEGRA_AVP_IOCTL_MIN_NR _IOC_NR(TEGRA_AVP_IOCTL_LOAD_LIB)
+#define TEGRA_AVP_IOCTL_MAX_NR _IOC_NR(TEGRA_AVP_IOCTL_UNLOAD_LIB)
+
+#endif
+
diff --git a/libc/kernel/common/linux/tegra_rpc.h b/libc/kernel/common/linux/tegra_rpc.h
new file mode 100644
index 0000000..e3c8bf2
--- /dev/null
+++ b/libc/kernel/common/linux/tegra_rpc.h
@@ -0,0 +1,35 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ *** This header was automatically generated from a Linux kernel header
+ *** of the same name, to make information necessary for userspace to
+ *** call into the kernel available to libc. It contains only constants,
+ *** structures, and macros generated from the original header, and thus,
+ *** contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef __LINUX_TEGRA_RPC_H
+#define __LINUX_TEGRA_RPC_H
+
+#define TEGRA_RPC_MAX_MSG_LEN 256
+
+#define TEGRA_RPC_MAX_NAME_LEN 17
+
+struct tegra_rpc_port_desc {
+ char name[TEGRA_RPC_MAX_NAME_LEN];
+ int notify_fd;
+};
+
+#define TEGRA_RPC_IOCTL_MAGIC 'r'
+
+#define TEGRA_RPC_IOCTL_PORT_CREATE _IOW(TEGRA_RPC_IOCTL_MAGIC, 0x20, struct tegra_rpc_port_desc)
+#define TEGRA_RPC_IOCTL_PORT_GET_NAME _IOR(TEGRA_RPC_IOCTL_MAGIC, 0x21, char *)
+#define TEGRA_RPC_IOCTL_PORT_CONNECT _IOR(TEGRA_RPC_IOCTL_MAGIC, 0x22, long)
+#define TEGRA_RPC_IOCTL_PORT_LISTEN _IOR(TEGRA_RPC_IOCTL_MAGIC, 0x23, long)
+
+#define TEGRA_RPC_IOCTL_MIN_NR _IOC_NR(TEGRA_RPC_IOCTL_PORT_CREATE)
+#define TEGRA_RPC_IOCTL_MAX_NR _IOC_NR(TEGRA_RPC_IOCTL_PORT_LISTEN)
+
+#endif
+
diff --git a/libc/kernel/common/linux/tegra_sema.h b/libc/kernel/common/linux/tegra_sema.h
new file mode 100644
index 0000000..bb11298
--- /dev/null
+++ b/libc/kernel/common/linux/tegra_sema.h
@@ -0,0 +1,24 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ *** This header was automatically generated from a Linux kernel header
+ *** of the same name, to make information necessary for userspace to
+ *** call into the kernel available to libc. It contains only constants,
+ *** structures, and macros generated from the original header, and thus,
+ *** contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef __LINUX_TEGRA_SEMA_H
+#define __LINUX_TEGRA_SEMA_H
+
+#define TEGRA_SEMA_IOCTL_MAGIC 'r'
+
+#define TEGRA_SEMA_IOCTL_WAIT _IOW(TEGRA_SEMA_IOCTL_MAGIC, 0x30, long *)
+#define TEGRA_SEMA_IOCTL_SIGNAL _IO(TEGRA_SEMA_IOCTL_MAGIC, 0x31)
+
+#define TEGRA_SEMA_IOCTL_MIN_NR _IOC_NR(TEGRA_SEMA_IOCTL_WAIT)
+#define TEGRA_SEMA_IOCTL_MAX_NR _IOC_NR(TEGRA_SEMA_IOCTL_SIGNAL)
+
+#endif
+
diff --git a/libc/kernel/common/linux/tegrafb.h b/libc/kernel/common/linux/tegrafb.h
new file mode 100644
index 0000000..b8e79ae
--- /dev/null
+++ b/libc/kernel/common/linux/tegrafb.h
@@ -0,0 +1,87 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ *** This header was automatically generated from a Linux kernel header
+ *** of the same name, to make information necessary for userspace to
+ *** call into the kernel available to libc. It contains only constants,
+ *** structures, and macros generated from the original header, and thus,
+ *** contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _LINUX_TEGRAFB_H_
+#define _LINUX_TEGRAFB_H_
+
+#include <linux/fb.h>
+#include <linux/types.h>
+#include <asm/ioctl.h>
+
+#define TEGRA_FB_WIN_FMT_P1 0
+#define TEGRA_FB_WIN_FMT_P2 1
+#define TEGRA_FB_WIN_FMT_P4 2
+#define TEGRA_FB_WIN_FMT_P8 3
+#define TEGRA_FB_WIN_FMT_B4G4R4A4 4
+#define TEGRA_FB_WIN_FMT_B5G5R5A 5
+#define TEGRA_FB_WIN_FMT_B5G6R5 6
+#define TEGRA_FB_WIN_FMT_AB5G5R5 7
+#define TEGRA_FB_WIN_FMT_B8G8R8A8 12
+#define TEGRA_FB_WIN_FMT_R8G8B8A8 13
+#define TEGRA_FB_WIN_FMT_B6x2G6x2R6x2A8 14
+#define TEGRA_FB_WIN_FMT_R6x2G6x2B6x2A8 15
+#define TEGRA_FB_WIN_FMT_YCbCr422 16
+#define TEGRA_FB_WIN_FMT_YUV422 17
+#define TEGRA_FB_WIN_FMT_YCbCr420P 18
+#define TEGRA_FB_WIN_FMT_YUV420P 19
+#define TEGRA_FB_WIN_FMT_YCbCr422P 20
+#define TEGRA_FB_WIN_FMT_YUV422P 21
+#define TEGRA_FB_WIN_FMT_YCbCr422R 22
+#define TEGRA_FB_WIN_FMT_YUV422R 23
+#define TEGRA_FB_WIN_FMT_YCbCr422RA 24
+#define TEGRA_FB_WIN_FMT_YUV422RA 25
+
+#define TEGRA_FB_WIN_BLEND_NONE 0
+#define TEGRA_FB_WIN_BLEND_PREMULT 1
+#define TEGRA_FB_WIN_BLEND_COVERAGE 2
+
+struct tegra_fb_windowattr {
+ __s32 index;
+ __u32 buff_id;
+ __u32 blend;
+ __u32 offset;
+ __u32 offset_u;
+ __u32 offset_v;
+ __u32 stride;
+ __u32 stride_uv;
+ __u32 pixformat;
+ __u32 x;
+ __u32 y;
+ __u32 w;
+ __u32 h;
+ __u32 out_x;
+ __u32 out_y;
+ __u32 out_w;
+ __u32 out_h;
+ __u32 z;
+ __u32 pre_syncpt_id;
+ __u32 pre_syncpt_val;
+};
+
+#define TEGRA_FB_FLIP_N_WINDOWS 3
+
+struct tegra_fb_flip_args {
+ struct tegra_fb_windowattr win[TEGRA_FB_FLIP_N_WINDOWS];
+ __u32 post_syncpt_id;
+ __u32 post_syncpt_val;
+};
+
+struct tegra_fb_modedb {
+ struct fb_var_screeninfo *modedb;
+ __u32 modedb_len;
+};
+
+#define FBIO_TEGRA_SET_NVMAP_FD _IOW('F', 0x40, __u32)
+#define FBIO_TEGRA_FLIP _IOW('F', 0x41, struct tegra_fb_flip_args)
+#define FBIO_TEGRA_GET_MODEDB _IOWR('F', 0x42, struct tegra_fb_modedb)
+
+#endif
+
diff --git a/libc/kernel/common/linux/ublock.h b/libc/kernel/common/linux/ublock.h
new file mode 100644
index 0000000..aa19a81
--- /dev/null
+++ b/libc/kernel/common/linux/ublock.h
@@ -0,0 +1,81 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ *** This header was automatically generated from a Linux kernel header
+ *** of the same name, to make information necessary for userspace to
+ *** call into the kernel available to libc. It contains only constants,
+ *** structures, and macros generated from the original header, and thus,
+ *** contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef __UBLOCK_H_
+#define __UBLOCK_H_
+
+#include <linux/types.h>
+
+#define UBLOCK_VERSION 0
+
+enum {
+ UBLOCK_INIT_IN = 0,
+ UBLOCK_INIT_OUT = 1,
+ UBLOCK_READY_IN = 2,
+ UBLOCK_READY_OUT = 3,
+ UBLOCK_READ_IN = 4,
+ UBLOCK_READ_OUT = 5,
+ UBLOCK_WRITE_IN = 6,
+ UBLOCK_WRITE_OUT = 7,
+};
+
+struct ublock_in_header {
+ __u32 seq;
+ __u32 opcode;
+};
+
+struct ublock_out_header {
+ __u32 seq;
+ __u32 opcode;
+};
+
+struct ublock_init_in {
+ __u32 version;
+ __u32 max_buf;
+ __u32 index;
+};
+
+struct ublock_init_out {
+ __u32 version;
+ __u32 max_buf;
+ __u64 size;
+};
+
+struct ublock_ready_in {
+ __u32 _unused;
+};
+
+struct ublock_ready_out {
+ __u32 _unused;
+};
+
+struct ublock_read_in {
+ __u64 offset;
+ __u64 length;
+};
+
+struct ublock_read_out {
+ __s32 status;
+ __u8 data[];
+};
+
+struct ublock_write_in {
+ __u64 offset;
+ __u64 length;
+ __u8 data[];
+};
+
+struct ublock_write_out {
+ __s32 status;
+};
+
+#endif
+
diff --git a/libc/kernel/common/linux/usb/f_mtp.h b/libc/kernel/common/linux/usb/f_mtp.h
new file mode 100644
index 0000000..a9e37c2
--- /dev/null
+++ b/libc/kernel/common/linux/usb/f_mtp.h
@@ -0,0 +1,42 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ *** This header was automatically generated from a Linux kernel header
+ *** of the same name, to make information necessary for userspace to
+ *** call into the kernel available to libc. It contains only constants,
+ *** structures, and macros generated from the original header, and thus,
+ *** contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef __LINUX_USB_F_MTP_H
+#define __LINUX_USB_F_MTP_H
+
+#define MTP_INTERFACE_MODE_MTP 0
+#define MTP_INTERFACE_MODE_PTP 1
+
+struct mtp_file_range {
+
+ int fd;
+
+ loff_t offset;
+
+ int64_t length;
+};
+
+struct mtp_event {
+
+ size_t length;
+
+ void *data;
+};
+
+#define MTP_SEND_FILE _IOW('M', 0, struct mtp_file_range)
+
+#define MTP_RECEIVE_FILE _IOW('M', 1, struct mtp_file_range)
+
+#define MTP_SET_INTERFACE_MODE _IOW('M', 2, int)
+
+#define MTP_SEND_EVENT _IOW('M', 3, struct mtp_event)
+
+#endif
diff --git a/libc/kernel/common/media/ov5650.h b/libc/kernel/common/media/ov5650.h
new file mode 100644
index 0000000..3603dc2
--- /dev/null
+++ b/libc/kernel/common/media/ov5650.h
@@ -0,0 +1,63 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ *** This header was automatically generated from a Linux kernel header
+ *** of the same name, to make information necessary for userspace to
+ *** call into the kernel available to libc. It contains only constants,
+ *** structures, and macros generated from the original header, and thus,
+ *** contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef __OV5650_H__
+#define __OV5650_H__
+
+#include <linux/ioctl.h>
+
+#define OV5650_IOCTL_SET_MODE _IOW('o', 1, struct ov5650_mode)
+#define OV5650_IOCTL_SET_FRAME_LENGTH _IOW('o', 2, __u32)
+#define OV5650_IOCTL_SET_COARSE_TIME _IOW('o', 3, __u32)
+#define OV5650_IOCTL_SET_GAIN _IOW('o', 4, __u16)
+#define OV5650_IOCTL_GET_STATUS _IOR('o', 5, __u8)
+#define OV5650_IOCTL_GET_OTP _IOR('o', 6, struct ov5650_otp_data)
+#define OV5650_IOCTL_TEST_PATTERN _IOW('o', 7, enum ov5650_test_pattern)
+
+enum ov5650_test_pattern {
+ TEST_PATTERN_NONE,
+ TEST_PATTERN_COLORBARS,
+ TEST_PATTERN_CHECKERBOARD
+};
+
+struct ov5650_otp_data {
+
+ __u8 sensor_serial_num[6];
+ __u8 part_num[8];
+ __u8 lens_id[1];
+ __u8 manufacture_id[2];
+ __u8 factory_id[2];
+ __u8 manufacture_date[9];
+ __u8 manufacture_line[2];
+
+ __u32 module_serial_num;
+ __u8 focuser_liftoff[2];
+ __u8 focuser_macro[2];
+ __u8 reserved1[12];
+ __u8 shutter_cal[16];
+ __u8 reserved2[183];
+
+ __u16 crc;
+ __u8 reserved3[3];
+ __u8 auto_load[2];
+} __attribute__ ((packed));
+
+struct ov5650_mode {
+ int xres;
+ int yres;
+ __u32 frame_length;
+ __u32 coarse_time;
+ __u16 gain;
+};
+
+#endif
+
+
diff --git a/libc/kernel/common/media/soc2030.h b/libc/kernel/common/media/soc2030.h
new file mode 100644
index 0000000..ad0ddfc
--- /dev/null
+++ b/libc/kernel/common/media/soc2030.h
@@ -0,0 +1,86 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ *** This header was automatically generated from a Linux kernel header
+ *** of the same name, to make information necessary for userspace to
+ *** call into the kernel available to libc. It contains only constants,
+ *** structures, and macros generated from the original header, and thus,
+ *** contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef __SOC2030_H__
+#define __SOC2030_H__
+
+#include <linux/ioctl.h>
+
+#define SOC2030_IOCTL_SET_MODE _IOWR('o', 1, struct soc2030_mode)
+#define SOC2030_IOCTL_GET_STATUS _IOC(_IOC_READ, 'o', 2, 10)
+#define SOC2030_IOCTL_SET_PRIVATE _IOWR('o', 3, struct soc2030_regs)
+#define SOC2030_IOCTL_GET_MODES _IO('o', 4)
+#define SOC2030_IOCTL_GET_NUM_MODES _IOR('o', 5, unsigned int)
+#define SOC2030_IOCTL_SET_EFFECT _IOWR('o', 6, unsigned int)
+#define SOC2030_IOCTL_SET_WHITEBALANCE _IOWR('o', 7, unsigned int)
+#define SOC2030_IOCTL_SET_EXP_COMP _IOWR('o', 8, int)
+
+#define SOC2030_POLL_WAITMS 50
+#define SOC2030_MAX_RETRIES 3
+#define SOC2030_POLL_RETRIES 5
+
+#define SOC2030_MAX_PRIVATE_SIZE 1024
+#define SOC2030_MAX_NUM_MODES 6
+
+#define SOC_EV_MAX 2
+#define SOC_EV_MIN -2
+#define EXP_TARGET 0x32
+
+enum {
+ REG_TABLE_END,
+ WRITE_REG_DATA,
+ WRITE_REG_BIT_H,
+ WRITE_REG_BIT_L,
+ POLL_REG_DATA,
+ POLL_REG_BIT_H,
+ POLL_REG_BIT_L,
+ WRITE_VAR_DATA,
+ POLL_VAR_DATA,
+ DELAY_MS,
+};
+
+enum {
+ EFFECT_NONE,
+ EFFECT_BW,
+ EFFECT_NEGATIVE,
+ EFFECT_POSTERIZE,
+ EFFECT_SEPIA,
+ EFFECT_SOLARIZE,
+ EFFECT_AQUA,
+ EFFECT_MAX,
+};
+
+enum {
+ WB_AUTO,
+ WB_INCANDESCENT,
+ WB_FLUORESCENT,
+ WB_DAYLIGHT,
+ WB_CLOUDYDAYLIGHT,
+ WB_NIGHT,
+ WB_MAX,
+};
+
+struct soc2030_regs {
+ __u8 op;
+ __u16 addr;
+ __u16 val;
+};
+
+struct soc2030_mode {
+ int xres;
+ int yres;
+ int fps;
+ struct soc2030_regs *regset;
+};
+
+#endif
+
+
diff --git a/libc/kernel/common/media/tegra_camera.h b/libc/kernel/common/media/tegra_camera.h
new file mode 100644
index 0000000..0f63035
--- /dev/null
+++ b/libc/kernel/common/media/tegra_camera.h
@@ -0,0 +1,33 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ *** This header was automatically generated from a Linux kernel header
+ *** of the same name, to make information necessary for userspace to
+ *** call into the kernel available to libc. It contains only constants,
+ *** structures, and macros generated from the original header, and thus,
+ *** contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+enum {
+ TEGRA_CAMERA_MODULE_ISP = 0,
+ TEGRA_CAMERA_MODULE_VI,
+ TEGRA_CAMERA_MODULE_CSI,
+};
+
+enum {
+ TEGRA_CAMERA_VI_CLK,
+ TEGRA_CAMERA_VI_SENSOR_CLK,
+};
+
+struct tegra_camera_clk_info {
+ uint id;
+ uint clk_id;
+ unsigned long rate;
+};
+
+#define TEGRA_CAMERA_IOCTL_ENABLE _IOWR('i', 1, uint)
+#define TEGRA_CAMERA_IOCTL_DISABLE _IOWR('i', 2, uint)
+#define TEGRA_CAMERA_IOCTL_CLK_SET_RATE _IOWR('i', 3, struct tegra_camera_clk_info)
+#define TEGRA_CAMERA_IOCTL_RESET _IOWR('i', 4, uint)
+
diff --git a/libc/kernel/tools/clean_header.py b/libc/kernel/tools/clean_header.py
index 28cb05e..dad9120 100755
--- a/libc/kernel/tools/clean_header.py
+++ b/libc/kernel/tools/clean_header.py
@@ -71,6 +71,7 @@
list.removeEmptyLines()
list.removeMacroDefines( kernel_ignored_macros )
list.insertDisclaimer( kernel.kernel_disclaimer )
+ list.replaceTokens( kernel_token_replacements )
out = StringOutput()
list.write(out)
diff --git a/libc/kernel/tools/cpp.py b/libc/kernel/tools/cpp.py
index 4b4bd38..8828a5d 100644
--- a/libc/kernel/tools/cpp.py
+++ b/libc/kernel/tools/cpp.py
@@ -1863,6 +1863,16 @@
tokens = tokens[:-1] # remove trailing tokLN
self.blocks = [ Block(tokens) ] + self.blocks
+ def replaceTokens(self,replacements=dict()):
+ """replace tokens according to the given dict
+ """
+ for b in self.blocks:
+ if not b.isDirective():
+ for tok in b.tokens:
+ if tok.id == tokIDENT:
+ if tok.value in replacements:
+ tok.value = replacements[tok.value]
+
class BlockParser:
"""a class used to convert an input source file into a BlockList object"""
diff --git a/libc/kernel/tools/defaults.py b/libc/kernel/tools/defaults.py
index 4227de7..ca7e6bb 100644
--- a/libc/kernel/tools/defaults.py
+++ b/libc/kernel/tools/defaults.py
@@ -43,6 +43,11 @@
"x86": {"__i386__": "1"},
}
+# Replace tokens in the output according to this mapping
+kernel_token_replacements = {
+ {"asm": "__asm__"},
+ }
+
# this is the set of known static inline functions that we want to keep
# in the final ARM headers. this is only used to keep optimized byteswapping
# static functions and stuff like that.
@@ -71,6 +76,7 @@
"__cmsg_nxthdr", # linux/socket.h
"cmsg_nxthdr", # linux/socket.h
"ipt_get_target",
+ "ip6t_get_target",
]
)
diff --git a/libc/netbsd/gethnamaddr.c b/libc/netbsd/gethnamaddr.c
index 1c219b2..fb18869 100644
--- a/libc/netbsd/gethnamaddr.c
+++ b/libc/netbsd/gethnamaddr.c
@@ -104,9 +104,9 @@
static void map_v4v6_hostent(struct hostent *, char **, char *);
static void addrsort(char **, int, res_state);
-void _sethtent(int);
-void _endhtent(void);
-struct hostent *_gethtent(void);
+static void _sethtent(int);
+static void _endhtent(void);
+static struct hostent *_gethtent(void);
void ht_sethostent(int);
void ht_endhostent(void);
struct hostent *ht_gethostbyname(char *);
@@ -114,11 +114,11 @@
void dns_service(void);
#undef dn_skipname
int dn_skipname(const u_char *, const u_char *);
-int _gethtbyaddr(void *, void *, va_list);
-int _gethtbyname(void *, void *, va_list);
-struct hostent *_gethtbyname2(const char *, int);
-int _dns_gethtbyaddr(void *, void *, va_list);
-int _dns_gethtbyname(void *, void *, va_list);
+static int _gethtbyaddr(void *, void *, va_list);
+static int _gethtbyname(void *, void *, va_list);
+static struct hostent *_gethtbyname2(const char *, int);
+static int _dns_gethtbyaddr(void *, void *, va_list);
+static int _dns_gethtbyname(void *, void *, va_list);
static struct hostent *gethostbyname_internal(const char *, int, res_state);
@@ -637,7 +637,7 @@
}
struct hostent *
-gethostbyaddr(const char *addr, /* XXX should have been def'd as u_char! */
+gethostbyaddr(const void *addr,
socklen_t len, int af)
{
const u_char *uaddr = (const u_char *)addr;
@@ -692,7 +692,7 @@
return hp;
}
-void
+static void
_sethtent(int f)
{
res_static rs = __res_get_static();
@@ -704,7 +704,7 @@
rs->stayopen = f;
}
-void
+static void
_endhtent(void)
{
res_static rs = __res_get_static();
@@ -716,7 +716,7 @@
}
}
-struct hostent *
+static struct hostent *
_gethtent(void)
{
char *p;
@@ -829,7 +829,7 @@
return NS_SUCCESS;
}
-struct hostent *
+static struct hostent *
_gethtbyname2(const char *name, int af)
{
struct hostent *p;
@@ -920,7 +920,7 @@
}
/*ARGSUSED*/
-int
+static int
_gethtbyaddr(void *rv, void *cb_data, va_list ap)
{
struct hostent *p;
@@ -1053,7 +1053,7 @@
}
/*ARGSUSED*/
-int
+static int
_dns_gethtbyname(void *rv, void *cb_data, va_list ap)
{
querybuf *buf;
@@ -1113,7 +1113,7 @@
}
/*ARGSUSED*/
-int
+static int
_dns_gethtbyaddr(void *rv, void *cb_data, va_list ap)
{
char qbuf[MAXDNAME + 1], *qp, *ep;
diff --git a/libc/netbsd/net/getaddrinfo.c b/libc/netbsd/net/getaddrinfo.c
index e4d8c56..edb4f70 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 @@
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 @@
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 3666443..d3d0011 100644
--- a/libc/netbsd/net/getnameinfo.c
+++ b/libc/netbsd/net/getnameinfo.c
@@ -64,6 +64,11 @@
#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 @@
}
}
+#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 @@
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 2621a7b..efce7dc 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 @@
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 @@
memcpy( (char*)e->answer, answer, e->answerlen );
- e->when = _time_now();
-
return e;
}
@@ -1103,17 +1158,25 @@
* 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 @@
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 @@
"*************************");
}
-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 @@
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 @@
_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 @@
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 @@
Entry key[1];
Entry* e;
Entry** lookup;
+ u_long ttl;
/* don't assume that the query has already been cached
*/
@@ -1375,6 +1505,7 @@
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 @@
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 @@
}
}
- 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 @@
/****************************************************************************/
/****************************************************************************/
-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,392 @@
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)
{
- pthread_once( &_res_cache_once, _res_cache_init );
- return _res_cache;
+ 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)
+{
+ 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)
- return;
+ pthread_once(&_res_cache_once, _res_cache_init);
+ pthread_mutex_lock(&_res_cache_list_lock);
- pthread_mutex_lock( &_res_cache->lock );
- if (_res_cache->generation != generation) {
- _cache_flush_locked(_res_cache);
- _res_cache->generation = generation;
+ 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;
+ }
}
- pthread_mutex_unlock( &_res_cache->lock );
+ 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;
+ 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;
+}
+
+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;
+ }
+ return NULL;
}
diff --git a/libc/netbsd/resolv/res_data.c b/libc/netbsd/resolv/res_data.c
index e60ecfd..014c99b 100644
--- a/libc/netbsd/resolv/res_data.c
+++ b/libc/netbsd/resolv/res_data.c
@@ -46,6 +46,7 @@
#include <unistd.h>
+__LIBC_HIDDEN__
const char * const _res_opcodes[] = {
"QUERY",
"IQUERY",
@@ -82,7 +83,7 @@
int res_ourserver_p(const res_state, const struct sockaddr *);
#ifdef ANDROID_CHANGES
-int res_need_init() {
+static int res_need_init() {
return ((_nres.options & RES_INIT) == 0U) || res_get_dns_changed();
}
#else
diff --git a/libc/netbsd/resolv/res_debug.c b/libc/netbsd/resolv/res_debug.c
index 84c6afc..721e015 100644
--- a/libc/netbsd/resolv/res_debug.c
+++ b/libc/netbsd/resolv/res_debug.c
@@ -385,7 +385,7 @@
/*
* Names of message sections.
*/
-const struct res_sym __p_default_section_syms[] = {
+static const struct res_sym __p_default_section_syms[] = {
{ns_s_qd, "QUERY", (char *)0},
{ns_s_an, "ANSWER", (char *)0},
{ns_s_ns, "AUTHORITY", (char *)0},
@@ -393,7 +393,7 @@
{0, (char *)0, (char *)0}
};
-const struct res_sym __p_update_section_syms[] = {
+static const struct res_sym __p_update_section_syms[] = {
{S_ZONE, "ZONE", (char *)0},
{S_PREREQ, "PREREQUISITE", (char *)0},
{S_UPDATE, "UPDATE", (char *)0},
diff --git a/libc/netbsd/resolv/res_init.c b/libc/netbsd/resolv/res_init.c
index 81e570f..ffd4054 100644
--- a/libc/netbsd/resolv/res_init.c
+++ b/libc/netbsd/resolv/res_init.c
@@ -113,8 +113,8 @@
#define DNS_PROP_NAME_PREFIX "net.dns"
#define DNS_CHANGE_PROP_NAME "net.dnschange"
#define DNS_SEARCH_PROP_NAME "net.dns.search"
-const prop_info *dns_change_prop;
-int dns_last_change_counter;
+static const prop_info *dns_change_prop;
+static int dns_last_change_counter;
static int _get_dns_change_count();
#else
#include <resolv.h>
@@ -170,7 +170,7 @@
}
#ifdef ANDROID_CHANGES
-int load_domain_search_list(res_state statp) {
+static int load_domain_search_list(res_state statp) {
char propvalue[PROP_VALUE_MAX];
register char *cp, **pp;
@@ -225,6 +225,9 @@
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 @@
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 696f8cf..b118956 100644
--- a/libc/netbsd/resolv/res_send.c
+++ b/libc/netbsd/resolv/res_send.c
@@ -222,7 +222,7 @@
* author:
* paul vixie, 29may94
*/
-int
+__LIBC_HIDDEN__ int
res_ourserver_p(const res_state statp, const struct sockaddr *sa) {
const struct sockaddr_in *inp, *srv;
const struct sockaddr_in6 *in6p, *srv6;
diff --git a/libc/netbsd/resolv/res_state.c b/libc/netbsd/resolv/res_state.c
index 3a2301d..322ace9 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 @@
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* rt = _rt;
+ D("%s: rt=%p for thread=%d", __FUNCTION__, rt, gettid());
+
_res_static_done(rt->_rstatic);
res_ndestroy(rt->_nres);
free(rt);
@@ -108,32 +116,65 @@
_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 );
+ 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;
}
- /* Check the serial value for any chanes to net.* properties. */
- if (rt->_pi == NULL) {
- rt->_pi = (struct prop_info*) __system_property_find("net.change");
+
+ /* 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;
}
- if (rt->_pi == NULL || rt->_serial == rt->_pi->serial) {
- return rt;
- }
- 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;
}
+__LIBC_HIDDEN__
struct __res_state _nres;
#if 0
diff --git a/libc/private/logd.h b/libc/private/logd.h
index 43fa742..4a9b62e 100644
--- a/libc/private/logd.h
+++ b/libc/private/logd.h
@@ -44,6 +44,7 @@
ANDROID_LOG_SILENT, /* only for SetMinPriority(); must be last */
};
+int __libc_android_log_write(int prio, const char* tag, const char* buffer);
int __libc_android_log_print(int prio, const char *tag, const char *fmt, ...);
int __libc_android_log_vprint(int prio, const char *tag, const char *fmt, va_list ap);
diff --git a/libc/private/resolv_cache.h b/libc/private/resolv_cache.h
index cd876fb..2a54453 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/fgetln.c b/libc/stdio/fgetln.c
index 946e1b7..95a5b31 100644
--- a/libc/stdio/fgetln.c
+++ b/libc/stdio/fgetln.c
@@ -43,7 +43,7 @@
* so we add 1 here.
#endif
*/
-int
+static int
__slbexpand(FILE *fp, size_t newsize)
{
void *p;
diff --git a/libc/stdio/findfp.c b/libc/stdio/findfp.c
index 039293f..1d0f9c5 100644
--- a/libc/stdio/findfp.c
+++ b/libc/stdio/findfp.c
@@ -55,7 +55,7 @@
static struct __sfileext usualext[FOPEN_MAX - 3];
static struct glue uglue = { 0, FOPEN_MAX - 3, usual };
-struct __sfileext __sFext[3];
+static struct __sfileext __sFext[3];
FILE __sF[3] = {
std(__SRD, STDIN_FILENO), /* stdin */
std(__SWR, STDOUT_FILENO), /* stdout */
diff --git a/libc/stdio/flockfile.c b/libc/stdio/flockfile.c
index bfb081c..e8c74c5 100644
--- a/libc/stdio/flockfile.c
+++ b/libc/stdio/flockfile.c
@@ -191,7 +191,7 @@
/* called from fclose() to remove the file lock */
-void
+__LIBC_HIDDEN__ void
__fremovelock(FILE* fp)
{
LockTable* t = lock_table_lock();
diff --git a/libc/stdio/fvwrite.c b/libc/stdio/fvwrite.c
index ee39400..57a57e6 100644
--- a/libc/stdio/fvwrite.c
+++ b/libc/stdio/fvwrite.c
@@ -44,7 +44,7 @@
* This routine is large and unsightly, but most of the ugliness due
* to the three different kinds of output buffering is handled here.
*/
-int
+__LIBC_HIDDEN__ int
__sfvwrite(FILE *fp, struct __suio *uio)
{
size_t len;
diff --git a/libc/stdio/mktemp.c b/libc/stdio/mktemp.c
index 951f803..aaa5640 100644
--- a/libc/stdio/mktemp.c
+++ b/libc/stdio/mktemp.c
@@ -65,7 +65,7 @@
char *_mktemp(char *);
-char *
+__LIBC_HIDDEN__ char *
_mktemp(char *path)
{
return(_gettemp(path, (int *)NULL, 0, 0) ? path : (char *)NULL);
diff --git a/libc/stdio/vfscanf.c b/libc/stdio/vfscanf.c
index dbd0a8b..c48dd36 100644
--- a/libc/stdio/vfscanf.c
+++ b/libc/stdio/vfscanf.c
@@ -159,7 +159,13 @@
flags |= MAXINT;
goto again;
case 'L':
- flags |= LONGDBL;
+ flags |=
+ (*fmt == 'd') ? LLONG :
+ (*fmt == 'i') ? LLONG :
+ (*fmt == 'o') ? LLONG :
+ (*fmt == 'u') ? LLONG :
+ (*fmt == 'x') ? LLONG :
+ LONGDBL;
goto again;
case 'h':
if (*fmt == 'h') {
diff --git a/libc/stdlib/sha1hash.c b/libc/stdlib/sha1hash.c
deleted file mode 100644
index 1c7aaf3..0000000
--- a/libc/stdlib/sha1hash.c
+++ /dev/null
@@ -1,316 +0,0 @@
-/*
-SHA-1 in C
-By Steve Reid <sreid@sea-to-sky.net>
-100% Public Domain
-
------------------
-Modified 7/98
-By James H. Brown <jbrown@burgoyne.com>
-Still 100% Public Domain
-
-Corrected a problem which generated improper hash values on 16 bit machines
-Routine SHA1Update changed from
- void SHA1Update(SHA1_CTX* context, unsigned char* data, unsigned int
-len)
-to
- void SHA1Update(SHA1_CTX* context, unsigned char* data, unsigned
-long len)
-
-The 'len' parameter was declared an int which works fine on 32 bit machines.
-However, on 16 bit machines an int is too small for the shifts being done
-against
-it. This caused the hash function to generate incorrect values if len was
-greater than 8191 (8K - 1) due to the 'len << 3' on line 3 of SHA1Update().
-
-Since the file IO in main() reads 16K at a time, any file 8K or larger would
-be guaranteed to generate the wrong hash (e.g. Test Vector #3, a million
-"a"s).
-
-I also changed the declaration of variables i & j in SHA1Update to
-unsigned long from unsigned int for the same reason.
-
-These changes should make no difference to any 32 bit implementations since
-an
-int and a long are the same size in those environments.
-
---
-I also corrected a few compiler warnings generated by Borland C.
-1. Added #include <process.h> for exit() prototype
-2. Removed unused variable 'j' in SHA1Final
-3. Changed exit(0) to return(0) at end of main.
-
-ALL changes I made can be located by searching for comments containing 'JHB'
------------------
-Modified 8/98
-By Steve Reid <sreid@sea-to-sky.net>
-Still 100% public domain
-
-1- Removed #include <process.h> and used return() instead of exit()
-2- Fixed overwriting of finalcount in SHA1Final() (discovered by Chris Hall)
-3- Changed email address from steve@edmweb.com to sreid@sea-to-sky.net
-
------------------
-Modified 4/01
-By Saul Kravitz <Saul.Kravitz@celera.com>
-Still 100% PD
-Modified to run on Compaq Alpha hardware.
-
------------------
-Modified 2/03
-By H. Peter Anvin <hpa@zytor.com>
-Still 100% PD
-Modified to run on any hardware with <inttypes.h> and <netinet/in.h>
-Changed the driver program
-
-*/
-
-/*
-Test Vectors (from FIPS PUB 180-1)
-"abc"
- A9993E36 4706816A BA3E2571 7850C26C 9CD0D89D
-"abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"
- 84983E44 1C3BD26E BAAE4AA1 F95129E5 E54670F1
-A million repetitions of "a"
- 34AA973C D4C4DAA4 F61EEB2B DBAD2731 6534016F
-*/
-
-/* #define SHA1HANDSOFF */
-
-#include <stdio.h>
-#include <string.h>
-#include <inttypes.h>
-#include <netinet/in.h> /* For htonl/ntohl/htons/ntohs */
-
-/* #include <process.h> */ /* prototype for exit() - JHB */
-/* Using return() instead of exit() - SWR */
-
-typedef struct {
- uint32_t state[5];
- uint32_t count[2];
- unsigned char buffer[64];
-} SHA1_CTX;
-
-void SHA1Transform(uint32_t state[5], unsigned char buffer[64]);
-void SHA1Init(SHA1_CTX* context);
-void SHA1Update(SHA1_CTX* context, unsigned char* data, uint32_t len); /*
-JHB */
-void SHA1Final(unsigned char digest[20], SHA1_CTX* context);
-
-#define rol(value, bits) (((value) << (bits)) | ((value) >> (32 - (bits))))
-
-/* blk0() and blk() perform the initial expand. */
-/* I got the idea of expanding during the round function from SSLeay */
-#define blk0(i) (block->l[i] = ntohl(block->l[i]))
-#define blk(i) (block->l[i&15] = rol(block->l[(i+13)&15]^block->l[(i+8)&15] \
- ^block->l[(i+2)&15]^block->l[i&15],1))
-
-/* (R0+R1), R2, R3, R4 are the different operations used in SHA1 */
-#define R0(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk0(i)+0x5A827999+rol(v,5);w=rol(w,30);
-#define R1(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk(i)+0x5A827999+rol(v,5);w=rol(w,30);
-#define R2(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0x6ED9EBA1+rol(v,5);w=rol(w,30);
-#define R3(v,w,x,y,z,i) z+=(((w|x)&y)|(w&x))+blk(i)+0x8F1BBCDC+rol(v,5);w=rol(w,30);
-#define R4(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0xCA62C1D6+rol(v,5);w=rol(w,30);
-
-
-#ifdef VERBOSE /* SAK */
-void SHAPrintContext(SHA1_CTX *context, char *msg){
- printf("%s (%d,%d) %x %x %x %x %x\n",
- msg,
- context->count[0], context->count[1],
- context->state[0],
- context->state[1],
- context->state[2],
- context->state[3],
- context->state[4]);
-}
-#endif
-
-/* Hash a single 512-bit block. This is the core of the algorithm. */
-
-void SHA1Transform(uint32_t state[5], unsigned char buffer[64])
-{
-uint32_t a, b, c, d, e;
-typedef union {
- unsigned char c[64];
- uint32_t l[16];
-} CHAR64LONG16;
-CHAR64LONG16* block;
-#ifdef SHA1HANDSOFF
-static unsigned char workspace[64];
- block = (CHAR64LONG16*)workspace;
- memcpy(block, buffer, 64);
-#else
- block = (CHAR64LONG16*)buffer;
-#endif
- /* Copy context->state[] to working vars */
- a = state[0];
- b = state[1];
- c = state[2];
- d = state[3];
- e = state[4];
- /* 4 rounds of 20 operations each. Loop unrolled. */
- R0(a,b,c,d,e, 0); R0(e,a,b,c,d, 1); R0(d,e,a,b,c, 2); R0(c,d,e,a,b, 3);
- R0(b,c,d,e,a, 4); R0(a,b,c,d,e, 5); R0(e,a,b,c,d, 6); R0(d,e,a,b,c, 7);
- R0(c,d,e,a,b, 8); R0(b,c,d,e,a, 9); R0(a,b,c,d,e,10); R0(e,a,b,c,d,11);
- R0(d,e,a,b,c,12); R0(c,d,e,a,b,13); R0(b,c,d,e,a,14); R0(a,b,c,d,e,15);
- R1(e,a,b,c,d,16); R1(d,e,a,b,c,17); R1(c,d,e,a,b,18); R1(b,c,d,e,a,19);
- R2(a,b,c,d,e,20); R2(e,a,b,c,d,21); R2(d,e,a,b,c,22); R2(c,d,e,a,b,23);
- R2(b,c,d,e,a,24); R2(a,b,c,d,e,25); R2(e,a,b,c,d,26); R2(d,e,a,b,c,27);
- R2(c,d,e,a,b,28); R2(b,c,d,e,a,29); R2(a,b,c,d,e,30); R2(e,a,b,c,d,31);
- R2(d,e,a,b,c,32); R2(c,d,e,a,b,33); R2(b,c,d,e,a,34); R2(a,b,c,d,e,35);
- R2(e,a,b,c,d,36); R2(d,e,a,b,c,37); R2(c,d,e,a,b,38); R2(b,c,d,e,a,39);
- R3(a,b,c,d,e,40); R3(e,a,b,c,d,41); R3(d,e,a,b,c,42); R3(c,d,e,a,b,43);
- R3(b,c,d,e,a,44); R3(a,b,c,d,e,45); R3(e,a,b,c,d,46); R3(d,e,a,b,c,47);
- R3(c,d,e,a,b,48); R3(b,c,d,e,a,49); R3(a,b,c,d,e,50); R3(e,a,b,c,d,51);
- R3(d,e,a,b,c,52); R3(c,d,e,a,b,53); R3(b,c,d,e,a,54); R3(a,b,c,d,e,55);
- R3(e,a,b,c,d,56); R3(d,e,a,b,c,57); R3(c,d,e,a,b,58); R3(b,c,d,e,a,59);
- R4(a,b,c,d,e,60); R4(e,a,b,c,d,61); R4(d,e,a,b,c,62); R4(c,d,e,a,b,63);
- R4(b,c,d,e,a,64); R4(a,b,c,d,e,65); R4(e,a,b,c,d,66); R4(d,e,a,b,c,67);
- R4(c,d,e,a,b,68); R4(b,c,d,e,a,69); R4(a,b,c,d,e,70); R4(e,a,b,c,d,71);
- R4(d,e,a,b,c,72); R4(c,d,e,a,b,73); R4(b,c,d,e,a,74); R4(a,b,c,d,e,75);
- R4(e,a,b,c,d,76); R4(d,e,a,b,c,77); R4(c,d,e,a,b,78); R4(b,c,d,e,a,79);
- /* Add the working vars back into context.state[] */
- state[0] += a;
- state[1] += b;
- state[2] += c;
- state[3] += d;
- state[4] += e;
- /* Wipe variables */
- a = b = c = d = e = 0;
-}
-
-
-/* SHA1Init - Initialize new context */
-
-void SHA1Init(SHA1_CTX* context)
-{
- /* SHA1 initialization constants */
- context->state[0] = 0x67452301;
- context->state[1] = 0xEFCDAB89;
- context->state[2] = 0x98BADCFE;
- context->state[3] = 0x10325476;
- context->state[4] = 0xC3D2E1F0;
- context->count[0] = context->count[1] = 0;
-}
-
-
-/* Run your data through this. */
-
-void SHA1Update(SHA1_CTX* context, unsigned char* data, uint32_t len) /*
-JHB */
-{
-uint32_t i, j; /* JHB */
-
-#ifdef VERBOSE
- SHAPrintContext(context, "before");
-#endif
- j = (context->count[0] >> 3) & 63;
- if ((context->count[0] += len << 3) < (len << 3)) context->count[1]++;
- context->count[1] += (len >> 29);
- if ((j + len) > 63) {
- memcpy(&context->buffer[j], data, (i = 64-j));
- SHA1Transform(context->state, context->buffer);
- for ( ; i + 63 < len; i += 64) {
- SHA1Transform(context->state, &data[i]);
- }
- j = 0;
- }
- else i = 0;
- memcpy(&context->buffer[j], &data[i], len - i);
-#ifdef VERBOSE
- SHAPrintContext(context, "after ");
-#endif
-}
-
-
-/* Add padding and return the message digest. */
-
-void SHA1Final(unsigned char digest[20], SHA1_CTX* context)
-{
-uint32_t i; /* JHB */
-unsigned char finalcount[8];
-
- for (i = 0; i < 8; i++) {
- finalcount[i] = (unsigned char)((context->count[(i >= 4 ? 0 : 1)]
- >> ((3-(i & 3)) * 8) ) & 255); /* Endian independent */
- }
- SHA1Update(context, (unsigned char *)"\200", 1);
- while ((context->count[0] & 504) != 448) {
- SHA1Update(context, (unsigned char *)"\0", 1);
- }
- SHA1Update(context, finalcount, 8); /* Should cause a SHA1Transform() */
- for (i = 0; i < 20; i++) {
- digest[i] = (unsigned char)
- ((context->state[i>>2] >> ((3-(i & 3)) * 8) ) & 255);
- }
- /* Wipe variables */
- i = 0; /* JHB */
- memset(context->buffer, 0, 64);
- memset(context->state, 0, 20);
- memset(context->count, 0, 8);
- memset(finalcount, 0, 8); /* SWR */
-#ifdef SHA1HANDSOFF /* make SHA1Transform overwrite it's own static vars */
- SHA1Transform(context->state, context->buffer);
-#endif
-}
-
-/*************************************************************/
-
-/* This is not quite the MIME base64 algorithm: it uses _ instead of /,
- and instead of padding the output with = characters we just make the
- output shorter. */
-char *mybase64(uint8_t digest[20])
-{
- static const char charz[] =
- "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_";
- uint8_t input[21];
- static char output[28];
- int i, j;
- uint8_t *p;
- char *q;
- uint32_t bv;
-
- memcpy(input, digest, 20);
- input[20] = 0; /* Pad to multiple of 3 bytes */
-
- p = input; q = output;
- for ( i = 0 ; i < 7 ; i++ ) {
- bv = (p[0] << 16) | (p[1] << 8) | p[2];
- p += 3;
- for ( j = 0 ; j < 4 ; j++ ) {
- *q++ = charz[(bv >> 18) & 0x3f];
- bv <<= 6;
- }
- }
- *--q = '\0'; /* The last character is not significant */
- return output;
-}
-
-int main(int argc, char** argv)
-{
- int i;
- SHA1_CTX context;
- uint8_t digest[20], buffer[16384];
- FILE* file;
-
- if (argc < 2) {
- file = stdin;
- }
- else {
- if (!(file = fopen(argv[1], "rb"))) {
- fputs("Unable to open file.", stderr);
- return(-1);
- }
- }
- SHA1Init(&context);
- while (!feof(file)) { /* note: what if ferror(file) */
- i = fread(buffer, 1, 16384, file);
- SHA1Update(&context, buffer, i);
- }
- SHA1Final(digest, &context);
- fclose(file);
-
- puts(mybase64(digest));
-
- return 0;
-}
diff --git a/libc/stdlib/strtod.c b/libc/stdlib/strtod.c
index 9d599b0..2851506 100644
--- a/libc/stdlib/strtod.c
+++ b/libc/stdlib/strtod.c
@@ -2062,7 +2062,7 @@
* calculation.
*/
- char *
+__LIBC_HIDDEN__ char *
__dtoa
#ifdef KR_headers
(_d, mode, ndigits, decpt, sign, rve)
diff --git a/libc/stdlib/wchar.c b/libc/stdlib/wchar.c
index 1480212..d83613a 100644
--- a/libc/stdlib/wchar.c
+++ b/libc/stdlib/wchar.c
@@ -302,12 +302,6 @@
return (wchar_t*) strstr( (const char*)ws1, (const char*)ws2 );
}
-size_t wcsxfrm(wchar_t *ws1, const wchar_t *ws2, size_t n)
-{
- memcpy( (char*)ws1, (const char*)ws2, n );
- return n;
-}
-
int wctob(wint_t c)
{
return c;
diff --git a/libc/string/memmove.c b/libc/string/memmove.c
index 98ecfc9..072104b 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 @@
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/gensyscalls.py b/libc/tools/gensyscalls.py
index 41c9500..0535e56 100755
--- a/libc/tools/gensyscalls.py
+++ b/libc/tools/gensyscalls.py
@@ -245,6 +245,59 @@
"""
+def param_uses_64bits(param):
+ """Returns True iff a syscall parameter description corresponds
+ to a 64-bit type."""
+ param = param.strip()
+ # First, check that the param type begins with one of the known
+ # 64-bit types.
+ if not ( \
+ param.startswith("int64_t") or param.startswith("uint64_t") or \
+ param.startswith("loff_t") or param.startswith("off64_t") or \
+ param.startswith("long long") or param.startswith("unsigned long long") or
+ param.startswith("signed long long") ):
+ return False
+
+ # Second, check that there is no pointer type here
+ if param.find("*") >= 0:
+ return False
+
+ # Ok
+ return True
+
+def count_arm_param_registers(params):
+ """This function is used to count the number of register used
+ to pass parameters when invoking a thumb or ARM system call.
+ This is because the ARM EABI mandates that 64-bit quantities
+ must be passed in an even+odd register pair. So, for example,
+ something like:
+
+ foo(int fd, off64_t pos)
+
+ would actually need 4 registers:
+ r0 -> int
+ r1 -> unused
+ r2-r3 -> pos
+ """
+ count = 0
+ for param in params:
+ if param_uses_64bits(param):
+ if (count & 1) != 0:
+ count += 1
+ count += 2
+ else:
+ count += 1
+ return count
+
+def count_generic_param_registers(params):
+ count = 0
+ for param in params:
+ if param_uses_64bits(param):
+ count += 2
+ else:
+ count += 1
+ return count
+
class State:
def __init__(self):
self.old_stubs = []
@@ -370,25 +423,28 @@
syscall_name = t["name"]
if t["id"] >= 0:
+ num_regs = count_arm_param_registers(syscall_params)
if gen_thumb_stubs:
- t["asm-thumb"] = self.thumb_genstub(syscall_func,len(syscall_params),"__NR_"+syscall_name)
+ t["asm-thumb"] = self.thumb_genstub(syscall_func,num_regs,"__NR_"+syscall_name)
else:
if gen_eabi_stubs:
- t["asm-arm"] = self.arm_eabi_genstub(syscall_func,len(syscall_params),"__NR_"+syscall_name)
+ t["asm-arm"] = self.arm_eabi_genstub(syscall_func,num_regs,"__NR_"+syscall_name)
else:
- t["asm-arm"] = self.arm_genstub(syscall_func,len(syscall_params),"__NR_"+syscall_name)
+ t["asm-arm"] = self.arm_genstub(syscall_func,num_regs,"__NR_"+syscall_name)
if t["id2"] >= 0:
+ num_regs = count_generic_param_registers(syscall_params)
if t["cid"] >= 0:
- t["asm-x86"] = self.x86_genstub_cid(syscall_func, len(syscall_params), "__NR_"+syscall_name, t["cid"])
+ t["asm-x86"] = self.x86_genstub_cid(syscall_func, num_regs, "__NR_"+syscall_name, t["cid"])
else:
- t["asm-x86"] = self.x86_genstub(syscall_func,len(syscall_params),"__NR_"+syscall_name)
+ t["asm-x86"] = self.x86_genstub(syscall_func, num_regs, "__NR_"+syscall_name)
elif t["cid"] >= 0:
E("cid for dispatch syscalls is only supported for x86 in "
"'%s'" % syscall_name)
return
if t["id3"] >= 0:
- t["asm-sh"] = self.superh_genstub(syscall_func,len(syscall_params),"__NR_"+syscall_name)
+ num_regs = count_generic_param_registers(syscall_params)
+ t["asm-sh"] = self.superh_genstub(syscall_func,num_regs,"__NR_"+syscall_name)
diff --git a/libc/tzcode/localtime.c b/libc/tzcode/localtime.c
index 85a913e..e442a03 100644
--- a/libc/tzcode/localtime.c
+++ b/libc/tzcode/localtime.c
@@ -60,6 +60,14 @@
# define XLOG(x) do{}while (0)
#endif
+/* Add the following function implementations:
+ * timelocal()
+ * timegm()
+ * time2posix()
+ * posix2time()
+ */
+#define STD_INSPIRED 1
+
/* THREAD-SAFETY SUPPORT GOES HERE */
static pthread_mutex_t _tzMutex = PTHREAD_MUTEX_INITIALIZER;
@@ -1509,7 +1517,7 @@
}
#ifdef STD_INSPIRED
-
+#if 0 /* disabled because there is no good documentation for this function */
struct tm *
offtime(timep, offset)
const time_t * const timep;
@@ -1517,7 +1525,7 @@
{
return gmtsub(timep, offset, &tmGlobal);
}
-
+#endif /* 0 */
#endif /* defined STD_INSPIRED */
/*
@@ -2106,6 +2114,7 @@
return result;
}
+#if 0 /* disable due to lack of clear documentation on this function */
time_t
timeoff(tmp, offset)
struct tm * const tmp;
@@ -2120,6 +2129,7 @@
return result;
}
+#endif /* 0 */
#endif /* defined STD_INSPIRED */
diff --git a/libc/tzcode/strftime.c b/libc/tzcode/strftime.c
index ab713fb..a2cc3b3 100644
--- a/libc/tzcode/strftime.c
+++ b/libc/tzcode/strftime.c
@@ -407,9 +407,9 @@
tm = *t;
mkt = mktime64(&tm);
if (TYPE_SIGNED(time64_t))
- (void) sprintf(buf, "%lld",
+ (void) snprintf(buf, sizeof(buf), "%lld",
(long long) mkt);
- else (void) sprintf(buf, "%llu",
+ else (void) snprintf(buf, sizeof(buf), "%llu",
(unsigned long long) mkt);
pt = _add(buf, pt, ptlim, modifier);
}
diff --git a/libc/unistd/abort.c b/libc/unistd/abort.c
index 3e3aab0..8b8659b 100644
--- a/libc/unistd/abort.c
+++ b/libc/unistd/abort.c
@@ -40,7 +40,7 @@
__libc_android_log_print(ANDROID_LOG_DEBUG, "libc-abort", (format), ##__VA_ARGS__ )
#ifdef __arm__
-void
+__LIBC_HIDDEN__ void
__libc_android_abort(void)
#else
void
diff --git a/libc/unistd/lseek64.c b/libc/unistd/lseek64.c
index 017b331..db0c413 100644
--- a/libc/unistd/lseek64.c
+++ b/libc/unistd/lseek64.c
@@ -29,7 +29,7 @@
extern int __llseek(int fd, unsigned long offset_hi, unsigned long offset_lo, loff_t* result, int whence);
-loff_t lseek64(int fd, loff_t off, int whence)
+off64_t lseek64(int fd, off64_t off, int whence)
{
loff_t result;
diff --git a/libc/unistd/pread.c b/libc/unistd/pread.c
index b55623e..42fc3bc 100644
--- a/libc/unistd/pread.c
+++ b/libc/unistd/pread.c
@@ -11,24 +11,25 @@
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
- * modification, are permitted provided that the following conditions are met:
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * * Neither the name of Google Inc. nor the names of its contributors may
- * be used to endorse or promote products derived from this software
- * without specific prior written permission.
*
-*/
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
#include <sys/types.h>
#include <unistd.h>
-extern int __pread64(int fd, void *buf, size_t nbytes, loff_t offset);
-
ssize_t pread(int fd, void *buf, size_t nbytes, off_t offset)
{
- return __pread64(fd, buf, nbytes, offset);
+ return pread64(fd, buf, nbytes, (off64_t)offset);
}
diff --git a/libc/unistd/pwrite.c b/libc/unistd/pwrite.c
index ea080d2..f106cb3 100644
--- a/libc/unistd/pwrite.c
+++ b/libc/unistd/pwrite.c
@@ -28,10 +28,8 @@
#include <sys/types.h>
#include <unistd.h>
-extern int __pwrite64(int fd, void *buf, size_t nbytes, loff_t offset);
-
-ssize_t pwrite(int fd, void *buf, size_t nbytes, off_t offset)
+ssize_t pwrite(int fd, const void *buf, size_t nbytes, off_t offset)
{
- return __pwrite64(fd, buf, nbytes, offset);
+ return pwrite64(fd, buf, nbytes, (off64_t)offset);
}
diff --git a/libc/unistd/raise.c b/libc/unistd/raise.c
index de099da..7b03a7a 100644
--- a/libc/unistd/raise.c
+++ b/libc/unistd/raise.c
@@ -30,5 +30,5 @@
int raise(int signum)
{
- return kill(getpid(), signum);
+ return kill(gettid(), signum);
}
diff --git a/libc/unistd/sigblock.c b/libc/unistd/sigblock.c
index 863d7da..176bc13 100644
--- a/libc/unistd/sigblock.c
+++ b/libc/unistd/sigblock.c
@@ -37,6 +37,7 @@
sigset_t the_sigset;
} in, out;
+ sigemptyset(&in.the_sigset);
in.the_mask = mask;
n = sigprocmask(SIG_BLOCK, &in.the_sigset, &out.the_sigset);
diff --git a/libc/unistd/sigsetmask.c b/libc/unistd/sigsetmask.c
index 4f46458..7842bf1 100644
--- a/libc/unistd/sigsetmask.c
+++ b/libc/unistd/sigsetmask.c
@@ -38,6 +38,7 @@
sigset_t the_sigset;
} in, out;
+ sigemptyset(&in.the_sigset);
in.the_mask = mask;
n = sigprocmask(SIG_SETMASK, &in.the_sigset, &out.the_sigset);
diff --git a/libc/unistd/time.c b/libc/unistd/time.c
index 13d7366..7b450c7 100644
--- a/libc/unistd/time.c
+++ b/libc/unistd/time.c
@@ -34,12 +34,15 @@
time(time_t *t)
{
struct timeval tt;
+ time_t ret;
if (gettimeofday(&tt, (struct timezone *)0) < 0)
- return (-1);
- if (t)
- *t = (time_t)tt.tv_sec;
- return (tt.tv_sec);
+ ret = -1;
+ else
+ ret = tt.tv_sec;
+ if (t != NULL)
+ *t = ret;
+ return ret;
}
diff --git a/libc/zoneinfo/MODULE_LICENSE_PUBLIC_DOMAIN b/libc/zoneinfo/MODULE_LICENSE_PUBLIC_DOMAIN
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/libc/zoneinfo/MODULE_LICENSE_PUBLIC_DOMAIN
diff --git a/libc/zoneinfo/zoneinfo.dat b/libc/zoneinfo/zoneinfo.dat
index 27ca5d0..bac23f0 100644
--- a/libc/zoneinfo/zoneinfo.dat
+++ b/libc/zoneinfo/zoneinfo.dat
Binary files differ
diff --git a/libc/zoneinfo/zoneinfo.idx b/libc/zoneinfo/zoneinfo.idx
index 09bd15f..7750e4d 100644
--- a/libc/zoneinfo/zoneinfo.idx
+++ b/libc/zoneinfo/zoneinfo.idx
Binary files differ
diff --git a/libc/zoneinfo/zoneinfo.version b/libc/zoneinfo/zoneinfo.version
index 76dcafb..4abe0cc 100644
--- a/libc/zoneinfo/zoneinfo.version
+++ b/libc/zoneinfo/zoneinfo.version
@@ -1 +1 @@
-2010k
+2011h
diff --git a/libm/Android.mk b/libm/Android.mk
index 28e8f33..29c75a2 100644
--- a/libm/Android.mk
+++ b/libm/Android.mk
@@ -117,6 +117,7 @@
src/s_lroundf.c \
src/s_lroundl.c \
src/s_modff.c \
+ src/s_nan.c \
src/s_nearbyint.c \
src/s_nextafter.c \
src/s_nextafterf.c \
@@ -138,6 +139,7 @@
src/s_tanf.c \
src/s_tanh.c \
src/s_tanhf.c \
+ src/s_tgammaf.c \
src/s_trunc.c \
src/s_truncf.c \
src/s_truncl.c \
diff --git a/libm/include/i387/fenv.h b/libm/include/i387/fenv.h
index 4281f10..5fe64e2 100644
--- a/libm/include/i387/fenv.h
+++ b/libm/include/i387/fenv.h
@@ -131,7 +131,8 @@
static __inline int
fegetexceptflag(fexcept_t *__flagp, int __excepts)
{
- int __mxcsr, __status;
+ int __mxcsr;
+ short __status;
__fnstsw(&__status);
if (__HAS_SSE())
diff --git a/libm/include/math.h b/libm/include/math.h
index 3b5660f..a86a16f 100644
--- a/libm/include/math.h
+++ b/libm/include/math.h
@@ -251,6 +251,7 @@
double logb(double);
long lrint(double);
long lround(double);
+double nan(const char *) __pure2;
double nextafter(double, double);
double remainder(double, double);
double remquo(double, double, int *);
@@ -343,6 +344,7 @@
float erfcf(float);
float hypotf(float, float);
float lgammaf(float);
+float tgammaf(float);
float acoshf(float);
float asinhf(float);
@@ -354,6 +356,7 @@
long long llroundf(float);
long lrintf(float);
long lroundf(float);
+float nanf(const char *) __pure2;
float nearbyintf(float);
float nextafterf(float, float);
float remainderf(float, float);
diff --git a/libm/src/s_nan.c b/libm/src/s_nan.c
new file mode 100644
index 0000000..e366e6b
--- /dev/null
+++ b/libm/src/s_nan.c
@@ -0,0 +1,131 @@
+/*-
+ * Copyright (c) 2007 David Schultz
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#include <sys/endian.h>
+#include <ctype.h>
+#include <float.h>
+#include <math.h>
+#include <stdint.h>
+#include <strings.h>
+
+#include "math_private.h"
+
+/* digittoint is in the FreeBSD C library, but not Bionic at this point */
+static int
+digittoint(char ch)
+{
+ int d;
+
+ d = ch - '0';
+ if ((unsigned)d < 10) {
+ return d;
+ }
+ d = ch - 'a';
+ if ((unsigned)d < 6) {
+ return d + 10;
+ }
+ d = ch - 'A';
+ if ((unsigned)d < 6) {
+ return d + 10;
+ }
+ return -1;
+}
+
+/*
+ * Scan a string of hexadecimal digits (the format nan(3) expects) and
+ * make a bit array (using the local endianness). We stop when we
+ * encounter an invalid character, NUL, etc. If we overflow, we do
+ * the same as gcc's __builtin_nan(), namely, discard the high order bits.
+ *
+ * The format this routine accepts needs to be compatible with what is used
+ * in contrib/gdtoa/hexnan.c (for strtod/scanf) and what is used in
+ * __builtin_nan(). In fact, we're only 100% compatible for strings we
+ * consider valid, so we might be violating the C standard. But it's
+ * impossible to use nan(3) portably anyway, so this seems good enough.
+ */
+void
+_scan_nan(uint32_t *words, int num_words, const char *s)
+{
+ int si; /* index into s */
+ int bitpos; /* index into words (in bits) */
+
+ bzero(words, num_words * sizeof(uint32_t));
+
+ /* Allow a leading '0x'. (It's expected, but redundant.) */
+ if (s[0] == '0' && (s[1] == 'x' || s[1] == 'X'))
+ s += 2;
+
+ /* Scan forwards in the string, looking for the end of the sequence. */
+ for (si = 0; isxdigit(s[si]); si++)
+ ;
+
+ /* Scan backwards, filling in the bits in words[] as we go. */
+#if _BYTE_ORDER == _LITTLE_ENDIAN
+ for (bitpos = 0; bitpos < 32 * num_words; bitpos += 4) {
+#else
+ for (bitpos = 32 * num_words - 4; bitpos >= 0; bitpos -= 4) {
+#endif
+ if (--si < 0)
+ break;
+ words[bitpos / 32] |= digittoint(s[si]) << (bitpos % 32);
+ }
+}
+
+double
+nan(const char *s)
+{
+ union {
+ double d;
+ uint32_t bits[2];
+ } u;
+
+ _scan_nan(u.bits, 2, s);
+#if _BYTE_ORDER == _LITTLE_ENDIAN
+ u.bits[1] |= 0x7ff80000;
+#else
+ u.bits[0] |= 0x7ff80000;
+#endif
+ return (u.d);
+}
+
+float
+nanf(const char *s)
+{
+ union {
+ float f;
+ uint32_t bits[1];
+ } u;
+
+ _scan_nan(u.bits, 1, s);
+ u.bits[0] |= 0x7fc00000;
+ return (u.f);
+}
+
+#if (LDBL_MANT_DIG == 53)
+__weak_alias(nanl, nan);
+#endif
diff --git a/libm/src/s_tgammaf.c b/libm/src/s_tgammaf.c
new file mode 100644
index 0000000..9993d91
--- /dev/null
+++ b/libm/src/s_tgammaf.c
@@ -0,0 +1,43 @@
+/*-
+ * Copyright (c) 2008 David Schultz <das@FreeBSD.ORG>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <math.h>
+
+/*
+ * We simply call tgamma() rather than bloating the math library with
+ * a float-optimized version of it. The reason is that tgammaf() is
+ * essentially useless, since the function is superexponential and
+ * floats have very limited range.
+ */
+float
+tgammaf(float x)
+{
+
+ return (tgamma(x));
+}
diff --git a/libstdc++/src/new.cpp b/libstdc++/src/new.cpp
index a9c92d4..ddd3dba 100644
--- a/libstdc++/src/new.cpp
+++ b/libstdc++/src/new.cpp
@@ -7,7 +7,7 @@
{
void* p = malloc(size);
if (p == NULL) {
- // abort();
+ abort();
}
return p;
}
@@ -16,7 +16,7 @@
{
void* p = malloc(size);
if (p == NULL) {
- // abort();
+ abort();
}
return p;
}
diff --git a/libthread_db/Android.mk b/libthread_db/Android.mk
index 1e6ac15..af506ed 100644
--- a/libthread_db/Android.mk
+++ b/libthread_db/Android.mk
@@ -21,7 +21,7 @@
LOCAL_WHOLE_STATIC_LIBRARIES := libthread_db
LOCAL_MODULE:=libthread_db
-LOCAL_SHARED_LIBRARIES := libdl
+LOCAL_SHARED_LIBRARIES := libdl libc
LOCAL_ALLOW_UNDEFINED_SYMBOLS := false
LOCAL_SYSTEM_SHARED_LIBRARIES :=
diff --git a/linker/Android.mk b/linker/Android.mk
index 52f7ce3..e613397 100644
--- a/linker/Android.mk
+++ b/linker/Android.mk
@@ -4,6 +4,7 @@
LOCAL_SRC_FILES:= \
arch/$(TARGET_ARCH)/begin.S \
linker.c \
+ linker_environ.c \
linker_format.c \
rt.c \
dlfcn.c \
@@ -94,6 +95,6 @@
# just for this module
$(LOCAL_BUILT_MODULE): TARGET_CRTBEGIN_STATIC_O :=
# This line is not strictly necessary because the dynamic linker is built
-# as a static executable, but it won't hurt if in the future we start
+# as a static executable, but it won't hurt if in the future we start
# building the linker as a dynamic one.
$(LOCAL_BUILT_MODULE): TARGET_CRTBEGIN_DYNAMIC_O :=
diff --git a/linker/linker.c b/linker/linker.c
index 42a5205..00f36c0 100644
--- a/linker/linker.c
+++ b/linker/linker.c
@@ -48,6 +48,7 @@
#include "linker.h"
#include "linker_debug.h"
+#include "linker_environ.h"
#include "linker_format.h"
#include "ba.h"
@@ -123,6 +124,9 @@
int debug_verbosity;
static int pid;
+/* This boolean is set if the program being loaded is setuid */
+static int program_is_setuid;
+
#if STATS
struct _link_stats linker_stats;
#endif
@@ -286,7 +290,7 @@
/* Make sure we get a clean block of soinfo */
memset(si, 0, sizeof(soinfo));
- strcpy((char*) si->name, name);
+ strlcpy((char*) si->name, name, sizeof(si->name));
sonext->next = si;
si->ba_index = -1; /* by default, prelinked */
si->next = NULL;
@@ -314,7 +318,7 @@
return;
}
- /* prev will never be NULL, because the first entry in solist is
+ /* prev will never be NULL, because the first entry in solist is
always the static libdl_info.
*/
prev->next = si->next;
@@ -818,7 +822,7 @@
static int reserve_mem_region(soinfo *si)
{
void *base = mmap((void *)si->base, si->size, PROT_READ | PROT_EXEC,
- MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
+ MAP_FIXED | MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
if (base == MAP_FAILED) {
DL_ERR("%5d can NOT map (%sprelinked) library '%s' at 0x%08x "
"as requested, will try general pool: %d (%s)",
@@ -1232,8 +1236,8 @@
return init_library(si);
}
-/* TODO:
- * notify gdb of unload
+/* TODO:
+ * notify gdb of unload
* for non-prelinked libraries, find a way to decrement libbase
*/
static void call_destructors(soinfo *si);
@@ -1765,14 +1769,14 @@
}
#endif
if (phdr->p_type == PT_LOAD) {
- /* For the executable, we use the si->size field only in
- dl_unwind_find_exidx(), so the meaning of si->size
- is not the size of the executable; it is the last
+ /* For the executable, we use the si->size field only in
+ dl_unwind_find_exidx(), so the meaning of si->size
+ is not the size of the executable; it is the last
virtual address of the loadable part of the executable;
since si->base == 0 for an executable, we use the
- range [0, si->size) to determine whether a PC value
+ range [0, si->size) to determine whether a PC value
falls within the executable section. Of course, if
- a value is below phdr->p_vaddr, it's not in the
+ a value is below phdr->p_vaddr, it's not in the
executable section, but a) we shouldn't be asking for
such a value anyway, and b) if we have to provide
an EXIDX for such a value, then the executable's
@@ -1927,7 +1931,7 @@
}
}
- DEBUG("%5d si->base = 0x%08x, si->strtab = %p, si->symtab = %p\n",
+ DEBUG("%5d si->base = 0x%08x, si->strtab = %p, si->symtab = %p\n",
pid, si->base, si->strtab, si->symtab);
if((si->strtab == 0) || (si->symtab == 0)) {
@@ -2033,7 +2037,7 @@
ftp://ftp.freebsd.org/pub/FreeBSD/CERT/advisories/FreeBSD-SA-02:23.stdio.asc
*/
- if (getuid() != geteuid() || getgid() != getegid())
+ if (program_is_setuid)
nullify_closed_stdio ();
call_constructors(si);
notify_gdb_of_load(si);
@@ -2045,7 +2049,7 @@
return -1;
}
-static void parse_library_path(char *path, char *delim)
+static void parse_library_path(const char *path, char *delim)
{
size_t len;
char *ldpaths_bufp = ldpaths_buf;
@@ -2068,7 +2072,7 @@
}
}
-static void parse_preloads(char *path, char *delim)
+static void parse_preloads(const char *path, char *delim)
{
size_t len;
char *ldpreloads_bufp = ldpreloads_buf;
@@ -2110,8 +2114,8 @@
unsigned *vecs = (unsigned*) (argv + argc + 1);
soinfo *si;
struct link_map * map;
- char *ldpath_env = NULL;
- char *ldpreload_env = NULL;
+ const char *ldpath_env = NULL;
+ const char *ldpreload_env = NULL;
/* Setup a temporary TLS area that is used to get a working
* errno for system calls.
@@ -2135,20 +2139,32 @@
*/
__tls_area[TLS_SLOT_BIONIC_PREINIT] = elfdata;
+ /* Are we setuid? */
+ program_is_setuid = (getuid() != geteuid()) || (getgid() != getegid());
+
+ /* Initialize environment functions, and get to the ELF aux vectors table */
+ vecs = linker_env_init(vecs);
+
+ /* Sanitize environment if we're loading a setuid program */
+ if (program_is_setuid)
+ linker_env_secure();
+
debugger_init();
- /* skip past the environment */
- while(vecs[0] != 0) {
- if(!strncmp((char*) vecs[0], "DEBUG=", 6)) {
- debug_verbosity = atoi(((char*) vecs[0]) + 6);
- } else if(!strncmp((char*) vecs[0], "LD_LIBRARY_PATH=", 16)) {
- ldpath_env = (char*) vecs[0] + 16;
- } else if(!strncmp((char*) vecs[0], "LD_PRELOAD=", 11)) {
- ldpreload_env = (char*) vecs[0] + 11;
+ /* Get a few environment variables */
+ {
+ const char* env;
+ env = linker_env_get("DEBUG"); /* XXX: TODO: Change to LD_DEBUG */
+ if (env)
+ debug_verbosity = atoi(env);
+
+ /* Normally, these are cleaned by linker_env_secure, but the test
+ * against program_is_setuid doesn't cost us anything */
+ if (!program_is_setuid) {
+ ldpath_env = linker_env_get("LD_LIBRARY_PATH");
+ ldpreload_env = linker_env_get("LD_PRELOAD");
}
- vecs++;
}
- vecs++;
INFO("[ android linker & debugger ]\n");
DEBUG("%5d elfdata @ 0x%08x\n", pid, (unsigned)elfdata);
@@ -2176,7 +2192,7 @@
* is. Don't use alloc_info(), because the linker shouldn't
* be on the soinfo list.
*/
- strcpy((char*) linker_soinfo.name, "/system/bin/linker");
+ strlcpy((char*) linker_soinfo.name, "/system/bin/linker", sizeof linker_soinfo.name);
linker_soinfo.flags = 0;
linker_soinfo.base = 0; // This is the important part; must be zero.
insert_soinfo_into_debug_map(&linker_soinfo);
@@ -2206,10 +2222,10 @@
si->refcount = 1;
/* Use LD_LIBRARY_PATH if we aren't setuid/setgid */
- if (ldpath_env && getuid() == geteuid() && getgid() == getegid())
+ if (ldpath_env)
parse_library_path(ldpath_env, ":");
- if (ldpreload_env && getuid() == geteuid() && getgid() == getegid()) {
+ if (ldpreload_env) {
parse_preloads(ldpreload_env, " :");
}
diff --git a/linker/linker_environ.c b/linker/linker_environ.c
new file mode 100644
index 0000000..b71dd80
--- /dev/null
+++ b/linker/linker_environ.c
@@ -0,0 +1,204 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+#include "linker_environ.h"
+#include <stddef.h>
+
+static char** _envp;
+
+/* Returns 1 if 'str' points to a valid environment variable definition.
+ * For now, we check that:
+ * - It is smaller than MAX_ENV_LEN (to detect non-zero terminated strings)
+ * - It contains at least one equal sign that is not the first character
+ */
+static int
+_is_valid_definition(const char* str)
+{
+ int pos = 0;
+ int first_equal_pos = -1;
+
+ /* According to its sources, the kernel uses 32*PAGE_SIZE by default
+ * as the maximum size for an env. variable definition.
+ */
+ const int MAX_ENV_LEN = 32*4096;
+
+ if (str == NULL)
+ return 0;
+
+ /* Parse the string, looking for the first '=' there, and its size */
+ do {
+ if (str[pos] == '\0')
+ break;
+ if (str[pos] == '=' && first_equal_pos < 0)
+ first_equal_pos = pos;
+ pos++;
+ } while (pos < MAX_ENV_LEN);
+
+ if (pos >= MAX_ENV_LEN) /* Too large */
+ return 0;
+
+ if (first_equal_pos < 1) /* No equal sign, or it is the first character */
+ return 0;
+
+ return 1;
+}
+
+unsigned*
+linker_env_init(unsigned* vecs)
+{
+ /* Store environment pointer - can't be NULL */
+ _envp = (char**) vecs;
+
+ /* Skip over all definitions */
+ while (vecs[0] != 0)
+ vecs++;
+ /* The end of the environment block is marked by two NULL pointers */
+ vecs++;
+
+ /* As a sanity check, we're going to remove all invalid variable
+ * definitions from the environment array.
+ */
+ {
+ char** readp = _envp;
+ char** writep = _envp;
+ for ( ; readp[0] != NULL; readp++ ) {
+ if (!_is_valid_definition(readp[0]))
+ continue;
+ writep[0] = readp[0];
+ writep++;
+ }
+ writep[0] = NULL;
+ }
+
+ /* Return the address of the aux vectors table */
+ return vecs;
+}
+
+/* Check if the environment variable definition at 'envstr'
+ * starts with '<name>=', and if so return the address of the
+ * first character after the equal sign. Otherwise return NULL.
+ */
+static char*
+env_match(char* envstr, const char* name)
+{
+ size_t cnt = 0;
+
+ while (envstr[cnt] == name[cnt] && name[cnt] != '\0')
+ cnt++;
+
+ if (name[cnt] == '\0' && envstr[cnt] == '=')
+ return envstr + cnt + 1;
+
+ return NULL;
+}
+
+#define MAX_ENV_LEN (16*4096)
+
+const char*
+linker_env_get(const char* name)
+{
+ char** readp = _envp;
+
+ if (name == NULL || name[0] == '\0')
+ return NULL;
+
+ for ( ; readp[0] != NULL; readp++ ) {
+ char* val = env_match(readp[0], name);
+ if (val != NULL) {
+ /* Return NULL for empty strings, or if it is too large */
+ if (val[0] == '\0')
+ val = NULL;
+ return val;
+ }
+ }
+ return NULL;
+}
+
+
+void
+linker_env_unset(const char* name)
+{
+ char** readp = _envp;
+ char** writep = readp;
+
+ if (name == NULL || name[0] == '\0')
+ return;
+
+ for ( ; readp[0] != NULL; readp++ ) {
+ if (env_match(readp[0], name))
+ continue;
+ writep[0] = readp[0];
+ writep++;
+ }
+ /* end list with a NULL */
+ writep[0] = NULL;
+}
+
+
+
+/* Remove unsafe environment variables. This should be used when
+ * running setuid programs. */
+void
+linker_env_secure(void)
+{
+ /* The same list than GLibc at this point */
+ static const char* const unsec_vars[] = {
+ "GCONV_PATH",
+ "GETCONF_DIR",
+ "HOSTALIASES",
+ "LD_AUDIT",
+ "LD_DEBUG",
+ "LD_DEBUG_OUTPUT",
+ "LD_DYNAMIC_WEAK",
+ "LD_LIBRARY_PATH",
+ "LD_ORIGIN_PATH",
+ "LD_PRELOAD",
+ "LD_PROFILE",
+ "LD_SHOW_AUXV",
+ "LD_USE_LOAD_BIAS",
+ "LOCALDOMAIN",
+ "LOCPATH",
+ "MALLOC_TRACE",
+ "MALLOC_CHECK_",
+ "NIS_PATH",
+ "NLSPATH",
+ "RESOLV_HOST_CONF",
+ "RES_OPTIONS",
+ "TMPDIR",
+ "TZDIR",
+ "LD_AOUT_LIBRARY_PATH",
+ "LD_AOUT_PRELOAD",
+ };
+
+ const char* const* cp = unsec_vars;
+ const char* const* endp = cp + sizeof(unsec_vars)/sizeof(unsec_vars[0]);
+
+ while (cp < endp) {
+ linker_env_unset(*cp);
+ cp++;
+ }
+}
diff --git a/linker/linker_environ.h b/linker/linker_environ.h
new file mode 100644
index 0000000..98ad1de
--- /dev/null
+++ b/linker/linker_environ.h
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+#ifndef LINKER_ENVIRON_H
+#define LINKER_ENVIRON_H
+
+/* Call this function before anything else. 'vecs' must be the pointer
+ * to the environment block in the ELF data block. The function returns
+ * the start of the aux vectors after the env block.
+ */
+extern unsigned* linker_env_init(unsigned* vecs);
+
+/* Unset a given environment variable. In case the variable is defined
+ * multiple times, unset all instances. This modifies the environment
+ * block, so any pointer returned by linker_env_get() after this call
+ * might become invalid */
+extern void linker_env_unset(const char* name);
+
+
+/* Returns the value of environment variable 'name' if defined and not
+ * empty, or NULL otherwise. Note that the returned pointer may become
+ * invalid if linker_env_unset() or linker_env_secure() are called
+ * after this function. */
+extern const char* linker_env_get(const char* name);
+
+/* Remove unsecure environment variables. This should be used when
+ * running setuid programs. */
+extern void linker_env_secure(void);
+
+#endif /* LINKER_ENVIRON_H */