From 9b67cc0ba439bf17c247123c657b9e73181149b6 Mon Sep 17 00:00:00 2001 From: Andy McFadden Date: Fri, 7 May 2010 14:45:43 -0700 Subject: [PATCH 01/12] Include cpu-features.h. Needed for code that tests for _ARM_HAVE_LDREX_STREX. Change-Id: I3504eeda935a444900236722e8de70b58b8bd8d1 --- libc/arch-arm/bionic/atomics_arm.S | 1 + 1 file changed, 1 insertion(+) diff --git a/libc/arch-arm/bionic/atomics_arm.S b/libc/arch-arm/bionic/atomics_arm.S index 047541fc2..3006a9d37 100644 --- a/libc/arch-arm/bionic/atomics_arm.S +++ b/libc/arch-arm/bionic/atomics_arm.S @@ -26,6 +26,7 @@ * SUCH DAMAGE. */ #include +#include .global __atomic_cmpxchg .type __atomic_cmpxchg, %function From b4637f4f1f7a7be75b981d72e3c75a9ae79d1d7e Mon Sep 17 00:00:00 2001 From: Andy McFadden Date: Wed, 19 May 2010 22:38:07 -0700 Subject: [PATCH 02/12] Atomic/SMP update. [manual merge to dalvik-dev] Added an underscore to _ARM_HAVE_LDREX_STREX to make it match the others. Added __ARM_HAVE_DMB and __ARM_HAVE_LDREXD when appropriate. Fixed some typos. Change-Id: I85ca1980192b509a09190dd84f1ca4a361e9c3a2 --- libc/arch-arm/bionic/atomics_arm.S | 2 +- libc/arch-arm/include/machine/cpu-features.h | 24 ++++++++++++++++---- 2 files changed, 20 insertions(+), 6 deletions(-) diff --git a/libc/arch-arm/bionic/atomics_arm.S b/libc/arch-arm/bionic/atomics_arm.S index 3006a9d37..78182285c 100644 --- a/libc/arch-arm/bionic/atomics_arm.S +++ b/libc/arch-arm/bionic/atomics_arm.S @@ -143,7 +143,7 @@ __atomic_inc: /* r0(new) r1(addr) -> r0(old) */ /* replaced swp instruction with ldrex/strex for ARMv6 & ARMv7 */ __atomic_swap: -#if defined (_ARM_HAVE_LDREX_STREX) +#if defined (__ARM_HAVE_LDREX_STREX) 1: ldrex r2, [r1] strex r3, r0, [r1] teq r3, #0 diff --git a/libc/arch-arm/include/machine/cpu-features.h b/libc/arch-arm/include/machine/cpu-features.h index ecf6ff6f3..0f969fa1e 100644 --- a/libc/arch-arm/include/machine/cpu-features.h +++ b/libc/arch-arm/include/machine/cpu-features.h @@ -38,7 +38,7 @@ * IMPORTANT: We have no intention to support anything below an ARMv4T ! */ -/* _ARM_ARCH_REVISION is a number corresponding to the ARM revision +/* __ARM_ARCH__ is a number corresponding to the ARM revision * we're going to support * * it looks like our toolchain doesn't define __ARM_ARCH__ @@ -142,18 +142,32 @@ * * ldr pc, [] * - * note that this affects any instruction that explicitely changes the + * note that this affects any instruction that explicitly changes the * value of the pc register, including ldm { ...,pc } or 'add pc, #offset' */ #if __ARM_ARCH__ >= 5 # define __ARM_HAVE_PC_INTERWORK #endif -/* define _ARM_HAVE_LDREX_STREX for ARMv6 and ARMv7 architecure to be - * used in replacement of depricated swp instruction +/* define __ARM_HAVE_LDREX_STREX for ARMv6 and ARMv7 architecture to be + * used in replacement of deprecated swp instruction */ #if __ARM_ARCH__ >= 6 -# define _ARM_HAVE_LDREX_STREX +# define __ARM_HAVE_LDREX_STREX +#endif + +/* define __ARM_HAVE_DMB for ARMv7 architecture + */ +#if __ARM_ARCH__ >= 7 +# define __ARM_HAVE_DMB +#endif + +/* define __ARM_HAVE_LDREXD for ARMv7 architecture + * (also present in ARMv6K, but not implemented in ARMv7-M, neither of which + * we care about) + */ +#if __ARM_ARCH__ >= 7 +# define __ARM_HAVE_LDREXD #endif From 7c99c1856fce65c0394cd578c2a8ed37da2f288d Mon Sep 17 00:00:00 2001 From: Andy McFadden Date: Fri, 28 May 2010 13:31:45 -0700 Subject: [PATCH 03/12] Atomic/SMP update, part 3. (manual merge) Update ARM atomic ops to use LDREX/STREX. Stripped out #if 0 chunk. Insert explicit memory barriers in pthread and semaphore code. For bug 2721865. Change-Id: I595cc8e5a8d1e4906b6641115e46208a7e9e755a --- libc/Android.mk | 8 ++ libc/arch-arm/bionic/atomics_arm.S | 132 +++++++++++++++++------------ libc/bionic/pthread.c | 15 +++- libc/bionic/semaphore.c | 14 ++- 4 files changed, 108 insertions(+), 61 deletions(-) diff --git a/libc/Android.mk b/libc/Android.mk index d2e5e1f40..24833d063 100644 --- a/libc/Android.mk +++ b/libc/Android.mk @@ -440,6 +440,14 @@ else # !arm endif # x86 endif # !arm +# Define ANDROID_SMP appropriately. +ifeq ($(TARGET_CPU_SMP),true) + libc_common_cflags += -DANDROID_SMP=1 +else + libc_common_cflags += -DANDROID_SMP=0 +endif + + # Define some common includes # ======================================================== libc_common_c_includes := \ diff --git a/libc/arch-arm/bionic/atomics_arm.S b/libc/arch-arm/bionic/atomics_arm.S index 78182285c..d94f6b14d 100644 --- a/libc/arch-arm/bionic/atomics_arm.S +++ b/libc/arch-arm/bionic/atomics_arm.S @@ -40,9 +40,73 @@ #define FUTEX_WAIT 0 #define FUTEX_WAKE 1 -#if 1 - .equ kernel_cmpxchg, 0xFFFF0FC0 - .equ kernel_atomic_base, 0xFFFF0FFF +#if defined(__ARM_HAVE_LDREX_STREX) +/* + * =========================================================================== + * ARMv6+ implementation + * =========================================================================== + */ + +/* r0(addr) -> r0(old) */ +__atomic_dec: + .fnstart + mov r1, r0 @ copy addr so we don't clobber it +1: ldrex r0, [r1] @ load current value into r0 + sub r2, r0, #1 @ generate new value into r2 + strex r3, r2, [r1] @ try to store new value; result in r3 + cmp r3, #0 @ success? + bxeq lr @ yes, return + b 1b @ no, retry + .fnend + +/* r0(addr) -> r0(old) */ +__atomic_inc: + .fnstart + mov r1, r0 +1: ldrex r0, [r1] + add r2, r0, #1 + strex r3, r2, [r1] + cmp r3, #0 + bxeq lr + b 1b + .fnend + +/* r0(old) r1(new) r2(addr) -> r0(zero_if_succeeded) */ +__atomic_cmpxchg: + .fnstart +1: mov ip, #2 @ ip=2 means "new != old" + ldrex r3, [r2] @ load current value into r3 + teq r0, r3 @ new == old? + strexeq ip, r1, [r2] @ yes, try store, set ip to 0 or 1 + teq ip, #1 @ strex failure? + beq 1b @ yes, retry + mov r0, ip @ return 0 on success, 2 on failure + bx lr + .fnend + +/* r0(new) r1(addr) -> r0(old) */ +__atomic_swap: + .fnstart +1: ldrex r2, [r1] + strex r3, r0, [r1] + teq r3, #0 + bne 1b + mov r0, r2 + bx lr + .fnend + +#else /*not defined __ARM_HAVE_LDREX_STREX*/ +/* + * =========================================================================== + * Pre-ARMv6 implementation + * =========================================================================== + */ + + /* int __kernel_cmpxchg(int oldval, int newval, int* ptr) */ + .equ kernel_cmpxchg, 0xFFFF0FC0 + .equ kernel_atomic_base, 0xFFFF0FFF + +/* r0(addr) -> r0(old) */ __atomic_dec: .fnstart .save {r4, lr} @@ -60,6 +124,7 @@ __atomic_dec: bx lr .fnend +/* r0(addr) -> r0(old) */ __atomic_inc: .fnstart .save {r4, lr} @@ -96,64 +161,16 @@ __atomic_cmpxchg: ldmia sp!, {r4, lr} bx lr .fnend -#else -#define KUSER_CMPXCHG 0xffffffc0 - -/* r0(old) r1(new) r2(addr) -> r0(zero_if_succeeded) */ -__atomic_cmpxchg: - stmdb sp!, {r4, lr} - mov r4, r0 /* r4 = save oldvalue */ -1: add lr, pc, #4 - mov r0, r4 /* r0 = oldvalue */ - mov pc, #KUSER_CMPXCHG - bcs 2f /* swap was made. we're good, return. */ - ldr r3, [r2] /* swap not made, see if it's because *ptr!=oldvalue */ - cmp r3, r4 - beq 1b -2: ldmia sp!, {r4, lr} - bx lr - -/* r0(addr) -> r0(old) */ -__atomic_dec: - stmdb sp!, {r4, lr} - mov r2, r0 /* address */ -1: ldr r0, [r2] /* oldvalue */ - add lr, pc, #4 - sub r1, r0, #1 /* newvalue = oldvalue - 1 */ - mov pc, #KUSER_CMPXCHG - bcc 1b /* no swap, try again until we get it right */ - mov r0, ip /* swapped, return the old value */ - ldmia sp!, {r4, lr} - bx lr - -/* r0(addr) -> r0(old) */ -__atomic_inc: - stmdb sp!, {r4, lr} - mov r2, r0 /* address */ -1: ldr r0, [r2] /* oldvalue */ - add lr, pc, #4 - add r1, r0, #1 /* newvalue = oldvalue + 1 */ - mov pc, #KUSER_CMPXCHG - bcc 1b /* no swap, try again until we get it right */ - mov r0, ip /* swapped, return the old value */ - ldmia sp!, {r4, lr} - bx lr -#endif /* r0(new) r1(addr) -> r0(old) */ -/* replaced swp instruction with ldrex/strex for ARMv6 & ARMv7 */ __atomic_swap: -#if defined (__ARM_HAVE_LDREX_STREX) -1: ldrex r2, [r1] - strex r3, r0, [r1] - teq r3, #0 - bne 1b - mov r0, r2 - mcr p15, 0, r0, c7, c10, 5 /* or, use dmb */ -#else + .fnstart swp r0, r0, [r1] -#endif bx lr + .fnend + +#endif /*not defined __ARM_HAVE_LDREX_STREX*/ + /* __futex_wait(*ftx, val, *timespec) */ /* __futex_wake(*ftx, counter) */ @@ -198,6 +215,8 @@ __futex_wait: .fnend __futex_wake: + .fnstart + .save {r4, r7} stmdb sp!, {r4, r7} mov r2, r1 mov r1, #FUTEX_WAKE @@ -205,6 +224,7 @@ __futex_wake: swi #0 ldmia sp!, {r4, r7} bx lr + .fnend #else diff --git a/libc/bionic/pthread.c b/libc/bionic/pthread.c index ae44b067a..709e61255 100644 --- a/libc/bionic/pthread.c +++ b/libc/bionic/pthread.c @@ -44,6 +44,7 @@ #include #include #include +#include extern int __pthread_clone(int (*fn)(void*), void *child_stack, int flags, void *arg); extern void _exit_with_stack_teardown(void * stackBase, int stackSize, int retCode); @@ -936,6 +937,7 @@ _normal_lock(pthread_mutex_t* mutex) while (__atomic_swap(shared|2, &mutex->value ) != (shared|0)) __futex_syscall4(&mutex->value, wait_op, shared|2, 0); } + ANDROID_MEMBAR_FULL(); } /* @@ -945,6 +947,8 @@ _normal_lock(pthread_mutex_t* mutex) static __inline__ void _normal_unlock(pthread_mutex_t* mutex) { + ANDROID_MEMBAR_FULL(); + /* We need to preserve the shared flag during operations */ int shared = mutex->value & MUTEX_SHARED_MASK; @@ -1144,8 +1148,10 @@ int pthread_mutex_trylock(pthread_mutex_t *mutex) /* Handle common case first */ if ( __likely(mtype == MUTEX_TYPE_NORMAL) ) { - if (__atomic_cmpxchg(shared|0, shared|1, &mutex->value) == 0) + if (__atomic_cmpxchg(shared|0, shared|1, &mutex->value) == 0) { + ANDROID_MEMBAR_FULL(); return 0; + } return EBUSY; } @@ -1241,9 +1247,11 @@ int pthread_mutex_lock_timeout_np(pthread_mutex_t *mutex, unsigned msecs) { int wait_op = shared ? FUTEX_WAIT : FUTEX_WAIT_PRIVATE; - /* fast path for unconteded lock */ - if (__atomic_cmpxchg(shared|0, shared|1, &mutex->value) == 0) + /* fast path for uncontended lock */ + if (__atomic_cmpxchg(shared|0, shared|1, &mutex->value) == 0) { + ANDROID_MEMBAR_FULL(); return 0; + } /* loop while needed */ while (__atomic_swap(shared|2, &mutex->value) != (shared|0)) { @@ -1252,6 +1260,7 @@ int pthread_mutex_lock_timeout_np(pthread_mutex_t *mutex, unsigned msecs) __futex_syscall4(&mutex->value, wait_op, shared|2, &ts); } + ANDROID_MEMBAR_FULL(); return 0; } diff --git a/libc/bionic/semaphore.c b/libc/bionic/semaphore.c index 84b931479..b624943f9 100644 --- a/libc/bionic/semaphore.c +++ b/libc/bionic/semaphore.c @@ -30,6 +30,7 @@ #include #include #include +#include int sem_init(sem_t *sem, int pshared, unsigned int value) { @@ -103,6 +104,7 @@ __atomic_dec_if_positive( volatile unsigned int* pvalue ) return old; } +/* lock a semaphore */ int sem_wait(sem_t *sem) { if (sem == NULL) { @@ -116,6 +118,7 @@ int sem_wait(sem_t *sem) __futex_wait(&sem->count, 0, 0); } + ANDROID_MEMBAR_FULL(); return 0; } @@ -130,8 +133,10 @@ int sem_timedwait(sem_t *sem, const struct timespec *abs_timeout) /* POSIX says we need to try to decrement the semaphore * before checking the timeout value */ - if (__atomic_dec_if_positive(&sem->count)) + if (__atomic_dec_if_positive(&sem->count)) { + ANDROID_MEMBAR_FULL(); return 0; + } /* check it as per Posix */ if (abs_timeout == NULL || @@ -169,17 +174,21 @@ int sem_timedwait(sem_t *sem, const struct timespec *abs_timeout) return -1; } - if (__atomic_dec_if_positive(&sem->count)) + if (__atomic_dec_if_positive(&sem->count)) { + ANDROID_MEMBAR_FULL(); break; + } } return 0; } +/* unlock a semaphore */ int sem_post(sem_t *sem) { if (sem == NULL) return EINVAL; + ANDROID_MEMBAR_FULL(); if (__atomic_inc((volatile int*)&sem->count) >= 0) __futex_wake(&sem->count, 1); @@ -194,6 +203,7 @@ int sem_trywait(sem_t *sem) } if (__atomic_dec_if_positive(&sem->count) > 0) { + ANDROID_MEMBAR_FULL(); return 0; } else { errno = EAGAIN; From 18a859aff4e1b97d644429b7ecdb366b18d5a708 Mon Sep 17 00:00:00 2001 From: Elliott Hughes Date: Wed, 11 Aug 2010 10:53:40 -0700 Subject: [PATCH 04/12] Apply https://android-git.corp.google.com/g/60855 to dalvik-dev. (We've been missing the zoneinfo.* files for the host dalvikvm. My fix for gingerbread will have to wait for someone to return from vacation, but I can commit here in advance, and I need to so that I can submit https://android-git.corp.google.com/g/60790 which -- amongst other things -- makes lack of time zone data a hard failure, rather than just silently pretending all time zones are UTC.) Bug: 2870945 Change-Id: I95163629c229c6da646af9aae4a0ba976ad5fe6c --- Android.mk | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/Android.mk b/Android.mk index fcc8b96a7..43d5499e3 100644 --- a/Android.mk +++ b/Android.mk @@ -14,6 +14,11 @@ # limitations under the License. # +LOCAL_PATH := $(call my-dir) + ifneq ($(TARGET_SIMULATOR),true) include $(call all-subdir-makefiles) +else + # The host dalvikvm needs Android's concatenated & indexed timezone data. + include $(LOCAL_PATH)/libc/zoneinfo/Android.mk endif From a7a86dc5538389d5882459eb81ddef83f6a3f971 Mon Sep 17 00:00:00 2001 From: Jesse Wilson Date: Tue, 31 Aug 2010 13:16:25 -0700 Subject: [PATCH 05/12] Make timezones available to the host build. --- libc/zoneinfo/Android.mk | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/libc/zoneinfo/Android.mk b/libc/zoneinfo/Android.mk index 2f36f9be4..ef700e83d 100644 --- a/libc/zoneinfo/Android.mk +++ b/libc/zoneinfo/Android.mk @@ -12,3 +12,15 @@ $(TARGET_OUT)/usr/share/zoneinfo/zoneinfo.idx : $(LOCAL_PATH)/zoneinfo.idx | $(A ALL_PREBUILT += $(TARGET_OUT)/usr/share/zoneinfo/zoneinfo.version $(TARGET_OUT)/usr/share/zoneinfo/zoneinfo.version : $(LOCAL_PATH)/zoneinfo.version | $(ACP) $(transform-prebuilt-to-target) + +# The host build doesn't use bionic, but it does use bionic's zoneinfo data +ifeq ($(WITH_HOST_DALVIK),true) + ALL_PREBUILT += $(HOST_OUT)/usr/share/zoneinfo/zoneinfo.dat + $(eval $(call copy-one-file,$(LOCAL_PATH)/zoneinfo.dat,$(HOST_OUT)/usr/share/zoneinfo/zoneinfo.dat)) + + ALL_PREBUILT += $(HOST_OUT)/usr/share/zoneinfo/zoneinfo.idx + $(eval $(call copy-one-file,$(LOCAL_PATH)/zoneinfo.idx,$(HOST_OUT)/usr/share/zoneinfo/zoneinfo.idx)) + + ALL_PREBUILT += $(HOST_OUT)/usr/share/zoneinfo/zoneinfo.version + $(eval $(call copy-one-file,$(LOCAL_PATH)/zoneinfo.version,$(HOST_OUT)/usr/share/zoneinfo/zoneinfo.version)) +endif From 02bee5724266c447fc4699c00e70d2cd0c19f6e1 Mon Sep 17 00:00:00 2001 From: Jim Huang Date: Tue, 31 Aug 2010 14:51:44 +0800 Subject: [PATCH 06/12] Use ARMv6 instruction for handling byte order ARMv6 ISA has several instructions to handle data in different byte order. For endian conversion (byte swapping) of single data words, it might be a good idea to use the REV/REV16 instruction simply. (git cherry-pick -e aa35095517b78b3d2e8ee282cab93ef058479fcf) Change-Id: Id6cca2e5e0a978f5abbee6d48876dfa8fa198f6a --- libc/arch-arm/include/endian.h | 83 ++++++++++++++++++++++++++++++++++ 1 file changed, 83 insertions(+) diff --git a/libc/arch-arm/include/endian.h b/libc/arch-arm/include/endian.h index 04204ed4c..e34872fcb 100644 --- a/libc/arch-arm/include/endian.h +++ b/libc/arch-arm/include/endian.h @@ -1,5 +1,86 @@ /* $OpenBSD: endian.h,v 1.3 2005/12/13 00:35:23 millert Exp $ */ +/* + * Copyright (C) 2010 The Android Open Source Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef _ARM_ENDIAN_H_ +#define _ARM_ENDIAN_H_ + +#ifdef __GNUC__ + +/* NOTE: header could not be included directly + * since it defines extra macros, such as PLD. + */ +#if defined(__ARM_ARCH_7A__) || defined(__ARM_ARCH_7R__) || \ + defined(__ARM_ARCH_7__) || \ + defined(__ARM_ARCH_6__) || defined(__ARM_ARCH_6J__) || \ + defined(__ARM_ARCH_6K__) || defined(__ARM_ARCH_6Z__) || \ + defined(__ARM_ARCH_6ZK__) || defined(__ARM_ARCH_6T2__) + +/* According to RealView Assembler User's Guide, REV and REV16 are available + * in Thumb code and 16-bit instructions when used in Thumb-2 code. + * + * REV Rd, Rm + * Rd and Rm must both be Lo registers. + * + * REV16 Rd, Rm + * Rd and Rm must both be Lo registers. + */ +#ifdef __thumb__ +#define REV_LO_REG asm("r4") +#else +#define REV_LO_REG +#endif + +#define __swap16md(x) ({ \ + register u_int16_t _x REV_LO_REG = (x); \ + __asm volatile ("rev16 %0, %0" : "+r" (_x)); \ + _x; \ +}) + +#define __swap32md(x) ({ \ + register u_int32_t _x REV_LO_REG = (x); \ + __asm volatile ("rev %0, %0" : "+r" (_x)); \ + _x; \ +}) + +#define __swap64md(x) ({ \ + u_int64_t _x = (x); \ + (u_int64_t) __swap32md(_x >> 32) | \ + (u_int64_t) __swap32md(_x & 0xffffffff) << 32; \ +}) + +/* Tell sys/endian.h we have MD variants of the swap macros. */ +#define MD_SWAP + +#endif /* __ARM_ARCH__ */ +#endif /* __GNUC__ */ + #ifdef __ARMEB__ #define _BYTE_ORDER _BIG_ENDIAN #else @@ -8,3 +89,5 @@ #define __STRICT_ALIGNMENT #include #include + +#endif /* !_ARM_ENDIAN_H_ */ From 570cb2449813b967263dad80842282e07011aa5d Mon Sep 17 00:00:00 2001 From: Elliott Hughes Date: Fri, 24 Sep 2010 17:55:58 -0700 Subject: [PATCH 07/12] Fixes for the ARM-specific bswap_16, bswap_32, and bswap_64. 1. Make the feature test work by excluding known-deficient processors, so we don't have to maintain a complete list of all the processors that support REV and REV16. 2. Don't abuse 'register' to get an effect similar to GCC's +l constraint, but which was unnecessarily restrictive. 3. Fix __swap64md so _x isn't clobbered, breaking 64-bit swaps. 4. Make (which declars bswap_16 and friends) use rather than , so we get the machine-dependent implementations. (git cherry-pick of 3cf53d1a7814e1520df09d24b009c16f4f27db0d) --- libc/arch-arm/include/endian.h | 54 ++++++++++++++++------------------ libc/include/byteswap.h | 3 +- 2 files changed, 27 insertions(+), 30 deletions(-) diff --git a/libc/arch-arm/include/endian.h b/libc/arch-arm/include/endian.h index e34872fcb..6de0889ef 100644 --- a/libc/arch-arm/include/endian.h +++ b/libc/arch-arm/include/endian.h @@ -33,14 +33,14 @@ #ifdef __GNUC__ -/* NOTE: header could not be included directly - * since it defines extra macros, such as PLD. +/* + * REV and REV16 weren't available on ARM5 or ARM4. + * We don't include because it pollutes the + * namespace with macros like PLD. */ -#if defined(__ARM_ARCH_7A__) || defined(__ARM_ARCH_7R__) || \ - defined(__ARM_ARCH_7__) || \ - defined(__ARM_ARCH_6__) || defined(__ARM_ARCH_6J__) || \ - defined(__ARM_ARCH_6K__) || defined(__ARM_ARCH_6Z__) || \ - defined(__ARM_ARCH_6ZK__) || defined(__ARM_ARCH_6T2__) +#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. @@ -50,44 +50,40 @@ * * REV16 Rd, Rm * Rd and Rm must both be Lo registers. + * + * The +l constraint takes care of this without constraining us in ARM mode. */ -#ifdef __thumb__ -#define REV_LO_REG asm("r4") -#else -#define REV_LO_REG -#endif - -#define __swap16md(x) ({ \ - register u_int16_t _x REV_LO_REG = (x); \ - __asm volatile ("rev16 %0, %0" : "+r" (_x)); \ - _x; \ +#define __swap16md(x) ({ \ + register u_int16_t _x = (x); \ + __asm volatile ("rev16 %0, %0" : "+l" (_x)); \ + _x; \ }) -#define __swap32md(x) ({ \ - register u_int32_t _x REV_LO_REG = (x); \ - __asm volatile ("rev %0, %0" : "+r" (_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 _x = (x); \ - (u_int64_t) __swap32md(_x >> 32) | \ - (u_int64_t) __swap32md(_x & 0xffffffff) << 32; \ +#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__ */ +#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 #include -#endif /* !_ARM_ENDIAN_H_ */ +#endif /* !_ARM_ENDIAN_H_ */ diff --git a/libc/include/byteswap.h b/libc/include/byteswap.h index 16d2ad4f9..74b0e9180 100644 --- a/libc/include/byteswap.h +++ b/libc/include/byteswap.h @@ -28,7 +28,8 @@ #ifndef _BYTESWAP_H_ #define _BYTESWAP_H_ -#include +/* endian.h rather than sys/endian.h so we get the machine-specific file. */ +#include #define bswap_16(x) swap16(x) #define bswap_32(x) swap32(x) From 81a844a0fc3c6850afc6cf8580e0d9c10267a879 Mon Sep 17 00:00:00 2001 From: Andy McFadden Date: Fri, 4 Feb 2011 14:45:57 -0800 Subject: [PATCH 08/12] Added _memmove_words Added a memmove() variant for Dalvik's System.arraycopy() implementation. It guarantees 16-bit or 32-bit atomicity depending on the alignment of the arguments. Bug 3398352 (cherry-pick from master) Change-Id: I5e64de1c76971ba234bf2dd05477ba390e0412a4 --- libc/Android.mk | 1 + libc/bionic/memmove_words.c | 147 ++++++++++++++++++++++++++++++++++++ 2 files changed, 148 insertions(+) create mode 100644 libc/bionic/memmove_words.c diff --git a/libc/Android.mk b/libc/Android.mk index d94075376..647739ea4 100644 --- a/libc/Android.mk +++ b/libc/Android.mk @@ -269,6 +269,7 @@ libc_common_src_files := \ bionic/libc_init_common.c \ bionic/logd_write.c \ bionic/md5.c \ + bionic/memmove_words.c \ bionic/pututline.c \ bionic/realpath.c \ bionic/sched_getaffinity.c \ diff --git a/libc/bionic/memmove_words.c b/libc/bionic/memmove_words.c new file mode 100644 index 000000000..22058bce8 --- /dev/null +++ b/libc/bionic/memmove_words.c @@ -0,0 +1,147 @@ +/* + * Copyright (C) 2011 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include + +/* + * Works like memmove(), except: + * - if all arguments are at least 32-bit aligned, we guarantee that we + * will use operations that preserve atomicity of 32-bit values + * - if not, we guarantee atomicity of 16-bit values + * + * If all three arguments are not at least 16-bit aligned, the behavior + * of this function is undefined. (We could remove this restriction by + * testing for unaligned values and punting to memmove(), but that's + * not currently useful.) + * + * TODO: add loop for 64-bit alignment + * TODO: use __builtin_prefetch + * TODO: write an ARM-optimized version + */ +void _memmove_words(void* dest, const void* src, size_t n) +{ + assert((((uintptr_t) dest | (uintptr_t) src | n) & 0x01) == 0); + + char* d = (char*) dest; + const char* s = (const char*) src; + size_t copyCount; + + /* + * If the source and destination pointers are the same, this is + * an expensive no-op. Testing for an empty move now allows us + * to skip a check later. + */ + if (n == 0 || d == s) + return; + + /* + * Determine if the source and destination buffers will overlap if + * we copy data forward (i.e. *dest++ = *src++). + * + * It's okay if the destination buffer starts before the source and + * there is some overlap, because the reader is always ahead of the + * writer. + */ + if (__builtin_expect((d < s) || ((size_t)(d - s) >= n), 1)) { + /* + * Copy forward. We prefer 32-bit loads and stores even for 16-bit + * data, so sort that out. + */ + if ((((uintptr_t) d | (uintptr_t) s) & 0x03) != 0) { + /* + * Not 32-bit aligned. Two possibilities: + * (1) Congruent, we can align to 32-bit by copying one 16-bit val + * (2) Non-congruent, we can do one of: + * a. copy whole buffer as a series of 16-bit values + * b. load/store 32 bits, using shifts to ensure alignment + * c. just copy the as 32-bit values and assume the CPU + * will do a reasonable job + * + * We're currently using (a), which is suboptimal. + */ + if ((((uintptr_t) d ^ (uintptr_t) s) & 0x03) != 0) { + copyCount = n; + } else { + copyCount = 2; + } + n -= copyCount; + copyCount /= sizeof(uint16_t); + + while (copyCount--) { + *(uint16_t*)d = *(uint16_t*)s; + d += sizeof(uint16_t); + s += sizeof(uint16_t); + } + } + + /* + * Copy 32-bit aligned words. + */ + copyCount = n / sizeof(uint32_t); + while (copyCount--) { + *(uint32_t*)d = *(uint32_t*)s; + d += sizeof(uint32_t); + s += sizeof(uint32_t); + } + + /* + * Check for leftovers. Either we finished exactly, or we have + * one remaining 16-bit chunk. + */ + if ((n & 0x02) != 0) { + *(uint16_t*)d = *(uint16_t*)s; + } + } else { + /* + * Copy backward, starting at the end. + */ + d += n; + s += n; + + if ((((uintptr_t) d | (uintptr_t) s) & 0x03) != 0) { + /* try for 32-bit alignment */ + if ((((uintptr_t) d ^ (uintptr_t) s) & 0x03) != 0) { + copyCount = n; + } else { + copyCount = 2; + } + n -= copyCount; + copyCount /= sizeof(uint16_t); + + while (copyCount--) { + d -= sizeof(uint16_t); + s -= sizeof(uint16_t); + *(uint16_t*)d = *(uint16_t*)s; + } + } + + /* copy 32-bit aligned words */ + copyCount = n / sizeof(uint32_t); + while (copyCount--) { + d -= sizeof(uint32_t); + s -= sizeof(uint32_t); + *(uint32_t*)d = *(uint32_t*)s; + } + + /* copy leftovers */ + if ((n & 0x02) != 0) { + d -= sizeof(uint16_t); + s -= sizeof(uint16_t); + *(uint16_t*)d = *(uint16_t*)s; + } + } +} From bf018299bd556867ffcd573417c11f6c83f601cd Mon Sep 17 00:00:00 2001 From: Elliott Hughes Date: Fri, 13 May 2011 10:53:53 -0700 Subject: [PATCH 09/12] Fix strerror(3) for errno 0. Everyone else's C library says "Success". We say "Unknown error: 0", which isn't really true. Change-Id: I9f9054779123eda996634e5f7a277789b6805809 --- libc/include/sys/_errdefs.h | 1 + libc/string/strerror_r.c | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/libc/include/sys/_errdefs.h b/libc/include/sys/_errdefs.h index e27ab7ae7..51d921ba0 100644 --- a/libc/include/sys/_errdefs.h +++ b/libc/include/sys/_errdefs.h @@ -36,6 +36,7 @@ #ifndef __BIONIC_ERRDEF #error "__BIONIC_ERRDEF must be defined before including this file" #endif +__BIONIC_ERRDEF( 0 , 0, "Success" ) __BIONIC_ERRDEF( EPERM , 1, "Operation not permitted" ) __BIONIC_ERRDEF( ENOENT , 2, "No such file or directory" ) __BIONIC_ERRDEF( ESRCH , 3, "No such process" ) diff --git a/libc/string/strerror_r.c b/libc/string/strerror_r.c index f43d417bd..2f26f173c 100644 --- a/libc/string/strerror_r.c +++ b/libc/string/strerror_r.c @@ -21,7 +21,7 @@ __code_string_lookup( const CodeString* strings, for (;;) { - if (strings[nn].code == 0) + if (strings[nn].msg == NULL) break; if (strings[nn].code == code) From e80227c2d3135443b9088f565fc6302805217296 Mon Sep 17 00:00:00 2001 From: Elliott Hughes Date: Thu, 12 May 2011 18:52:06 -0700 Subject: [PATCH 10/12] Implement getpwnam_r(3) and getpwuid_r(3). These functions were already declared in , but hadn't been implemented yet. Change-Id: I9cddafa4c7f19a40eec566d3f3b221bd5a680e85 --- libc/bionic/stubs.c | 73 ++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 72 insertions(+), 1 deletion(-) diff --git a/libc/bionic/stubs.c b/libc/bionic/stubs.c index a01d64c2f..5f6342722 100644 --- a/libc/bionic/stubs.c +++ b/libc/bionic/stubs.c @@ -37,6 +37,78 @@ #include #include +static int do_getpw_r(int by_name, const char* name, uid_t uid, + struct passwd* dst, char* buf, size_t byte_count, struct passwd** result) +{ + /* + * getpwnam_r and getpwuid_r don't modify errno, but library calls we + * make might. + */ + int old_errno = errno; + int rc = 0; + *result = NULL; + + const struct passwd* src = by_name ? getpwnam(name) : getpwuid(uid); + + /* + * POSIX allows failure to find a match to be considered a non-error. + * Reporting success (0) but with *result NULL is glibc's behavior. + */ + if (src == NULL) { + rc = (errno == ENOENT) ? 0 : errno; + goto failure; + } + + /* + * Work out where our strings will go in 'buf', and whether we've got + * enough space. + */ + size_t required_byte_count = 0; + dst->pw_name = buf; + required_byte_count += strlen(src->pw_name) + 1; + dst->pw_dir = buf + required_byte_count; + required_byte_count += strlen(src->pw_dir) + 1; + dst->pw_shell = buf + required_byte_count; + required_byte_count += strlen(src->pw_shell) + 1; + if (byte_count < required_byte_count) { + rc = ERANGE; + goto failure; + } + + /* Copy the strings. */ + snprintf(buf, byte_count, "%s%c%s%c%s", + src->pw_name, 0, src->pw_dir, 0, src->pw_shell); + + /* + * pw_passwd is non-POSIX and unused (always NULL) in bionic. + * pw_gecos is non-POSIX and missing in bionic. + */ + dst->pw_passwd = NULL; + + /* Copy the integral fields. */ + dst->pw_gid = src->pw_gid; + dst->pw_uid = src->pw_uid; + +success: + rc = 0; + *result = dst; +failure: + errno = old_errno; + return rc; +} + +int getpwnam_r(const char* name, struct passwd* pwd, + char* buf, size_t byte_count, struct passwd** result) +{ + return do_getpw_r(1, name, -1, pwd, buf, byte_count, result); +} + +int getpwuid_r(uid_t uid, struct passwd* pwd, + char* buf, size_t byte_count, struct passwd** result) +{ + return do_getpw_r(0, NULL, uid, pwd, buf, byte_count, result); +} + /** Thread-specific state for the stubs functions **/ @@ -400,4 +472,3 @@ void endusershell(void) { fprintf(stderr, "FIX ME! implement %s() %s:%d\n", __FUNCTION__, __FILE__, __LINE__); } - From b1fd729d638d2646bdc915a7f4612fe85725a407 Mon Sep 17 00:00:00 2001 From: Elliott Hughes Date: Wed, 8 Jun 2011 17:17:53 -0700 Subject: [PATCH 11/12] Update to the latest NetBSD inet_pton.c. Bug: 4580520 Change-Id: I1079574b14e78e153e10ac527ca406ef560af310 --- libc/inet/inet_pton.c | 242 ++++++++++++++++++++++++++++++------------ 1 file changed, 172 insertions(+), 70 deletions(-) diff --git a/libc/inet/inet_pton.c b/libc/inet/inet_pton.c index 4caf9812b..16a24840c 100644 --- a/libc/inet/inet_pton.c +++ b/libc/inet/inet_pton.c @@ -1,36 +1,62 @@ -/* $OpenBSD: inet_pton.c,v 1.7 2006/12/30 23:37:37 itojun Exp $ */ +/* $NetBSD: inet_pton.c,v 1.6.10.1 2011/01/10 00:42:17 riz Exp $ */ -/* Copyright (c) 1996 by Internet Software Consortium. +/* + * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC") + * Copyright (c) 1996,1999 by Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * - * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS - * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE - * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR - * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS - * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS - * SOFTWARE. + * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +#include +#if defined(LIBC_SCCS) && !defined(lint) +#if 0 +static const char rcsid[] = "Id: inet_pton.c,v 1.5 2005/07/28 06:51:47 marka Exp"; +#else +__RCSID("$NetBSD: inet_pton.c,v 1.6.10.1 2011/01/10 00:42:17 riz Exp $"); +#endif +#endif /* LIBC_SCCS and not lint */ + +// BEGIN android-added +#define _DIAGASSERT(exp) assert(exp) +#include "../private/arpa_nameser.h" +// END android-added + +// android-removed: #include "port_before.h" + +// android-removed: #include "namespace.h" #include #include #include #include #include -#include "arpa_nameser.h" +#include #include +#include +#include #include -/* +// android-removed: #include "port_after.h" + +#ifdef __weak_alias +__weak_alias(inet_pton,_inet_pton) +#endif + +/*% * WARNING: Don't even consider trying to compile this on a system where * sizeof(int) < 4. sizeof(int) > 4 is fine; all the world's not a VAX. */ -static int inet_pton4(const char *src, u_char *dst); +static int inet_pton4(const char *src, u_char *dst, int pton); static int inet_pton6(const char *src, u_char *dst); /* int @@ -47,9 +73,13 @@ static int inet_pton6(const char *src, u_char *dst); int inet_pton(int af, const char *src, void *dst) { + + _DIAGASSERT(src != NULL); + _DIAGASSERT(dst != NULL); + switch (af) { case AF_INET: - return (inet_pton4(src, dst)); + return (inet_pton4(src, dst, 1)); case AF_INET6: return (inet_pton6(src, dst)); default: @@ -60,51 +90,123 @@ inet_pton(int af, const char *src, void *dst) } /* int - * inet_pton4(src, dst) - * like inet_aton() but without all the hexadecimal and shorthand. + * inet_pton4(src, dst, pton) + * when last arg is 0: inet_aton(). with hexadecimal, octal and shorthand. + * when last arg is 1: inet_pton(). decimal dotted-quad only. * return: - * 1 if `src' is a valid dotted quad, else 0. + * 1 if `src' is a valid input, else 0. * notice: * does not touch `dst' unless it's returning 1. * author: * Paul Vixie, 1996. */ static int -inet_pton4(const char *src, u_char *dst) +inet_pton4(const char *src, u_char *dst, int pton) { - static const char digits[] = "0123456789"; - int saw_digit, octets, ch; - u_char tmp[INADDRSZ], *tp; + u_int32_t val; + u_int digit, base; + int n; + unsigned char c; + u_int parts[4]; + register u_int *pp = parts; - saw_digit = 0; - octets = 0; - *(tp = tmp) = 0; - while ((ch = *src++) != '\0') { - const char *pch; + _DIAGASSERT(src != NULL); + _DIAGASSERT(dst != NULL); - if ((pch = strchr(digits, ch)) != NULL) { - u_int new = *tp * 10 + (pch - digits); - - if (new > 255) - return (0); - if (! saw_digit) { - if (++octets > 4) - return (0); - saw_digit = 1; - } - *tp = new; - } else if (ch == '.' && saw_digit) { - if (octets == 4) - return (0); - *++tp = 0; - saw_digit = 0; - } else + c = *src; + for (;;) { + /* + * Collect number up to ``.''. + * Values are specified as for C: + * 0x=hex, 0=octal, isdigit=decimal. + */ + if (!isdigit(c)) return (0); + val = 0; base = 10; + if (c == '0') { + c = *++src; + if (c == 'x' || c == 'X') + base = 16, c = *++src; + else if (isdigit(c) && c != '9') + base = 8; + } + /* inet_pton() takes decimal only */ + if (pton && base != 10) + return (0); + for (;;) { + if (isdigit(c)) { + digit = c - '0'; + if (digit >= base) + break; + val = (val * base) + digit; + c = *++src; + } else if (base == 16 && isxdigit(c)) { + digit = c + 10 - (islower(c) ? 'a' : 'A'); + if (digit >= 16) + break; + val = (val << 4) | digit; + c = *++src; + } else + break; + } + if (c == '.') { + /* + * Internet format: + * a.b.c.d + * a.b.c (with c treated as 16 bits) + * a.b (with b treated as 24 bits) + * a (with a treated as 32 bits) + */ + if (pp >= parts + 3) + return (0); + *pp++ = val; + c = *++src; + } else + break; } - if (octets < 4) + /* + * Check for trailing characters. + */ + if (c != '\0' && !isspace(c)) return (0); + /* + * Concoct the address according to + * the number of parts specified. + */ + n = pp - parts + 1; + /* inet_pton() takes dotted-quad only. it does not take shorthand. */ + if (pton && n != 4) + return (0); + switch (n) { - memcpy(dst, tmp, INADDRSZ); + case 0: + return (0); /* initial nondigit */ + + case 1: /* a -- 32 bits */ + break; + + case 2: /* a.b -- 8.24 bits */ + if (parts[0] > 0xff || val > 0xffffff) + return (0); + val |= parts[0] << 24; + break; + + case 3: /* a.b.c -- 8.8.16 bits */ + if ((parts[0] | parts[1]) > 0xff || val > 0xffff) + return (0); + val |= (parts[0] << 24) | (parts[1] << 16); + break; + + case 4: /* a.b.c.d -- 8.8.8.8 bits */ + if ((parts[0] | parts[1] | parts[2] | val) > 0xff) + return (0); + val |= (parts[0] << 24) | (parts[1] << 16) | (parts[2] << 8); + break; + } + if (dst) { + val = htonl(val); + memcpy(dst, &val, NS_INADDRSZ); + } return (1); } @@ -126,20 +228,23 @@ inet_pton6(const char *src, u_char *dst) { static const char xdigits_l[] = "0123456789abcdef", xdigits_u[] = "0123456789ABCDEF"; - u_char tmp[IN6ADDRSZ], *tp, *endp, *colonp; + u_char tmp[NS_IN6ADDRSZ], *tp, *endp, *colonp; const char *xdigits, *curtok; - int ch, saw_xdigit, count_xdigit; + int ch, seen_xdigits; u_int val; - memset((tp = tmp), '\0', IN6ADDRSZ); - endp = tp + IN6ADDRSZ; + _DIAGASSERT(src != NULL); + _DIAGASSERT(dst != NULL); + + memset((tp = tmp), '\0', NS_IN6ADDRSZ); + endp = tp + NS_IN6ADDRSZ; colonp = NULL; /* Leading :: requires some special handling. */ if (*src == ':') if (*++src != ':') return (0); curtok = src; - saw_xdigit = count_xdigit = 0; + seen_xdigits = 0; val = 0; while ((ch = *src++) != '\0') { const char *pch; @@ -147,46 +252,39 @@ inet_pton6(const char *src, u_char *dst) if ((pch = strchr((xdigits = xdigits_l), ch)) == NULL) pch = strchr((xdigits = xdigits_u), ch); if (pch != NULL) { - if (count_xdigit >= 4) - return (0); val <<= 4; val |= (pch - xdigits); - if (val > 0xffff) + if (++seen_xdigits > 4) return (0); - saw_xdigit = 1; - count_xdigit++; continue; } if (ch == ':') { curtok = src; - if (!saw_xdigit) { + if (!seen_xdigits) { if (colonp) return (0); colonp = tp; continue; - } else if (*src == '\0') { + } else if (*src == '\0') return (0); - } - if (tp + INT16SZ > endp) + if (tp + NS_INT16SZ > endp) return (0); *tp++ = (u_char) (val >> 8) & 0xff; *tp++ = (u_char) val & 0xff; - saw_xdigit = 0; - count_xdigit = 0; + seen_xdigits = 0; val = 0; continue; } - if (ch == '.' && ((tp + INADDRSZ) <= endp) && - inet_pton4(curtok, tp) > 0) { - tp += INADDRSZ; - saw_xdigit = 0; - count_xdigit = 0; - break; /* '\0' was seen by inet_pton4(). */ + if (ch == '.' && ((tp + NS_INADDRSZ) <= endp) && + inet_pton4(curtok, tp, 1) > 0) { + tp += NS_INADDRSZ; + seen_xdigits = 0; + break; /*%< '\\0' was seen by inet_pton4(). */ } return (0); } - if (saw_xdigit) { - if (tp + INT16SZ > endp) + if (seen_xdigits) { + if (tp + NS_INT16SZ > endp) return (0); *tp++ = (u_char) (val >> 8) & 0xff; *tp++ = (u_char) val & 0xff; @@ -199,6 +297,8 @@ inet_pton6(const char *src, u_char *dst) const int n = tp - colonp; int i; + if (tp == endp) + return (0); for (i = 1; i <= n; i++) { endp[- i] = colonp[n - i]; colonp[n - i] = 0; @@ -207,6 +307,8 @@ inet_pton6(const char *src, u_char *dst) } if (tp != endp) return (0); - memcpy(dst, tmp, IN6ADDRSZ); + memcpy(dst, tmp, NS_IN6ADDRSZ); return (1); } + +/*! \file */ From 3398ee9c15278b90bc2934afca6bdf83b6b605e6 Mon Sep 17 00:00:00 2001 From: Elliott Hughes Date: Thu, 9 Jun 2011 13:03:03 -0700 Subject: [PATCH 12/12] Fix build. prebuilt/linux-x86/toolchain/arm-linux-androideabi-4.4.x/bin/../lib/gcc/arm-linux-androideabi/4.4.3/../../../../arm-linux-androideabi/bin/ld: out/target/product/stingray/obj/lib/libc.so: error: undefined reference to '_inet_pton' Change-Id: Iee9f1ee87d0a37fa6aa91ecfb6283a7e03fb91c2 --- libc/inet/inet_pton.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/libc/inet/inet_pton.c b/libc/inet/inet_pton.c index 16a24840c..6e74e6af0 100644 --- a/libc/inet/inet_pton.c +++ b/libc/inet/inet_pton.c @@ -47,9 +47,11 @@ __RCSID("$NetBSD: inet_pton.c,v 1.6.10.1 2011/01/10 00:42:17 riz Exp $"); // android-removed: #include "port_after.h" -#ifdef __weak_alias -__weak_alias(inet_pton,_inet_pton) -#endif +// BEGIN android-removed +// #ifdef __weak_alias +// __weak_alias(inet_pton,_inet_pton) +// #endif +// END android-removed /*% * WARNING: Don't even consider trying to compile this on a system where