Compare commits
	
		
			32 Commits
		
	
	
		
			android-2.
			...
			gingerbrea
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 
						 | 
					2c222c4906 | ||
| 
						 | 
					f0e5b680ba | ||
| 
						 | 
					30983c9ab9 | ||
| 
						 | 
					6cda7b6249 | ||
| 
						 | 
					50a83255d8 | ||
| 
						 | 
					c4a5e97624 | ||
| 
						 | 
					afb0167ad9 | ||
| 
						 | 
					a0aec0bd30 | ||
| 
						 | 
					3eb2657855 | ||
| 
						 | 
					3435fc600d | ||
| 
						 | 
					bf29647964 | ||
| 
						 | 
					b1dd939e90 | ||
| 
						 | 
					e0bdf2c3e2 | ||
| 
						 | 
					2cbb8f3f98 | ||
| 
						 | 
					84f8b3ad9c | ||
| 
						 | 
					4711f8faa8 | ||
| 
						 | 
					e5705524e2 | ||
| 
						 | 
					074af91700 | ||
| 
						 | 
					18142abc06 | ||
| 
						 | 
					4029e0e7cb | ||
| 
						 | 
					832a86eaba | ||
| 
						 | 
					88bb394c0d | ||
| 
						 | 
					0bbcbf0d57 | ||
| 
						 | 
					0f2dc2b60c | ||
| 
						 | 
					3f14ff34df | ||
| 
						 | 
					6139fa33ab | ||
| 
						 | 
					6bd73ed417 | ||
| 
						 | 
					2081fda69a | ||
| 
						 | 
					ba96e30fa0 | ||
| 
						 | 
					2e23e29245 | ||
| 
						 | 
					f4dca7be3b | ||
| 
						 | 
					a798b9f0e1 | 
@@ -401,7 +401,7 @@ libc_common_src_files += \
 | 
			
		||||
	arch-x86/string/memset_wrapper.S \
 | 
			
		||||
	arch-x86/string/strcmp_wrapper.S \
 | 
			
		||||
	arch-x86/string/strncmp_wrapper.S \
 | 
			
		||||
	arch-x86/string/strlen.S \
 | 
			
		||||
	arch-x86/string/strlen_wrapper.S \
 | 
			
		||||
	bionic/pthread-rwlocks.c \
 | 
			
		||||
	bionic/pthread-timers.c \
 | 
			
		||||
	bionic/ptrace.c
 | 
			
		||||
@@ -516,6 +516,10 @@ endif
 | 
			
		||||
#
 | 
			
		||||
libc_crt_target_cflags += -I$(LOCAL_PATH)/private
 | 
			
		||||
 | 
			
		||||
ifeq ($(TARGET_ARCH),arm)
 | 
			
		||||
libc_crt_target_cflags += -DCRT_LEGACY_WORKAROUND
 | 
			
		||||
endif
 | 
			
		||||
 | 
			
		||||
# Define some common includes
 | 
			
		||||
# ========================================================
 | 
			
		||||
libc_common_c_includes := \
 | 
			
		||||
@@ -540,18 +544,24 @@ ifneq ($(filter arm x86,$(TARGET_ARCH)),)
 | 
			
		||||
# that will call __cxa_finalize(&__dso_handle) in order to ensure that
 | 
			
		||||
# static C++ destructors are properly called on dlclose().
 | 
			
		||||
#
 | 
			
		||||
 | 
			
		||||
libc_crt_target_so_cflags := $(libc_crt_target_cflags)
 | 
			
		||||
ifeq ($(TARGET_ARCH),x86)
 | 
			
		||||
    # This flag must be added for x86 targets, but not for ARM
 | 
			
		||||
    libc_crt_target_so_cflags += -fPIC
 | 
			
		||||
endif
 | 
			
		||||
GEN := $(TARGET_OUT_STATIC_LIBRARIES)/crtbegin_so.o
 | 
			
		||||
$(GEN): $(LOCAL_PATH)/arch-$(TARGET_ARCH)/bionic/crtbegin_so.S
 | 
			
		||||
	@mkdir -p $(dir $@)
 | 
			
		||||
	$(TARGET_CC) $(libc_crt_target_cflags) -o $@ -c $<
 | 
			
		||||
	$(TARGET_CC) $(libc_crt_target_so_cflags) -o $@ -c $<
 | 
			
		||||
ALL_GENERATED_SOURCES += $(GEN)
 | 
			
		||||
 | 
			
		||||
GEN := $(TARGET_OUT_STATIC_LIBRARIES)/crtend_so.o
 | 
			
		||||
$(GEN): $(LOCAL_PATH)/arch-$(TARGET_ARCH)/bionic/crtend_so.S
 | 
			
		||||
	@mkdir -p $(dir $@)
 | 
			
		||||
	$(TARGET_CC) $(libc_crt_target_cflags) -o $@ -c $<
 | 
			
		||||
	$(TARGET_CC) $(libc_crt_target_so_cflags) -o $@ -c $<
 | 
			
		||||
ALL_GENERATED_SOURCES += $(GEN)
 | 
			
		||||
endif # TARGET_ARCH == x86
 | 
			
		||||
endif # TARGET_ARCH == x86 || TARGET_ARCH == arm
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GEN := $(TARGET_OUT_STATIC_LIBRARIES)/crtbegin_static.o
 | 
			
		||||
@@ -587,6 +597,9 @@ include $(CLEAR_VARS)
 | 
			
		||||
 | 
			
		||||
LOCAL_SRC_FILES := $(libc_common_src_files)
 | 
			
		||||
LOCAL_CFLAGS := $(libc_common_cflags)
 | 
			
		||||
ifeq ($(TARGET_ARCH),arm)
 | 
			
		||||
LOCAL_CFLAGS += -DCRT_LEGACY_WORKAROUND
 | 
			
		||||
endif
 | 
			
		||||
LOCAL_C_INCLUDES := $(libc_common_c_includes)
 | 
			
		||||
LOCAL_MODULE := libc_common
 | 
			
		||||
LOCAL_SYSTEM_SHARED_LIBRARIES :=
 | 
			
		||||
@@ -703,6 +716,7 @@ LOCAL_MODULE:= libc_malloc_debug_leak
 | 
			
		||||
LOCAL_SHARED_LIBRARIES := libc
 | 
			
		||||
LOCAL_WHOLE_STATIC_LIBRARIES := libc_common
 | 
			
		||||
LOCAL_SYSTEM_SHARED_LIBRARIES :=
 | 
			
		||||
LOCAL_ALLOW_UNDEFINED_SYMBOLS := true
 | 
			
		||||
# Don't prelink
 | 
			
		||||
LOCAL_PRELINK_MODULE := false
 | 
			
		||||
# Don't install on release build
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										69
									
								
								libc/arch-arm/bionic/atexit.S
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										69
									
								
								libc/arch-arm/bionic/atexit.S
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,69 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (C) 2011 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 CRT_LEGACY_WORKAROUND
 | 
			
		||||
	.arch armv5te
 | 
			
		||||
	.fpu softvfp
 | 
			
		||||
	.eabi_attribute 20, 1
 | 
			
		||||
	.eabi_attribute 21, 1
 | 
			
		||||
	.eabi_attribute 23, 3
 | 
			
		||||
	.eabi_attribute 24, 1
 | 
			
		||||
	.eabi_attribute 25, 1
 | 
			
		||||
	.eabi_attribute 26, 2
 | 
			
		||||
	.eabi_attribute 30, 4
 | 
			
		||||
	.eabi_attribute 18, 4
 | 
			
		||||
	.code	16
 | 
			
		||||
	.section	.text.atexit,"ax",%progbits
 | 
			
		||||
	.align	2
 | 
			
		||||
	.global	atexit
 | 
			
		||||
	.hidden	atexit
 | 
			
		||||
	.code	16
 | 
			
		||||
	.thumb_func
 | 
			
		||||
	.type	atexit, %function
 | 
			
		||||
atexit:
 | 
			
		||||
	.fnstart
 | 
			
		||||
.LFB0:
 | 
			
		||||
	.save	{r4, lr}
 | 
			
		||||
	push	{r4, lr}
 | 
			
		||||
.LCFI0:
 | 
			
		||||
	ldr	r3, .L3
 | 
			
		||||
	mov	r1, #0
 | 
			
		||||
	@ sp needed for prologue
 | 
			
		||||
.LPIC0:
 | 
			
		||||
	add	r3, pc
 | 
			
		||||
	ldr	r2, [r3]
 | 
			
		||||
	bl	__cxa_atexit
 | 
			
		||||
	pop	{r4, pc}
 | 
			
		||||
.L4:
 | 
			
		||||
	.align	2
 | 
			
		||||
.L3:
 | 
			
		||||
	.word	__dso_handle-(.LPIC0+4)
 | 
			
		||||
.LFE0:
 | 
			
		||||
	.fnend
 | 
			
		||||
	.size	atexit, .-atexit
 | 
			
		||||
#endif
 | 
			
		||||
@@ -85,3 +85,4 @@ __CTOR_LIST__:
 | 
			
		||||
	.long -1
 | 
			
		||||
 | 
			
		||||
#include "__dso_handle.S"
 | 
			
		||||
#include "atexit.S"
 | 
			
		||||
 
 | 
			
		||||
@@ -52,4 +52,10 @@ __FINI_ARRAY__:
 | 
			
		||||
        .long -1
 | 
			
		||||
        .long __on_dlclose
 | 
			
		||||
 | 
			
		||||
#ifdef CRT_LEGACY_WORKAROUND
 | 
			
		||||
#include "__dso_handle.S"
 | 
			
		||||
#else
 | 
			
		||||
#include "__dso_handle_so.S"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#include "atexit.S"
 | 
			
		||||
 
 | 
			
		||||
@@ -86,3 +86,4 @@ __CTOR_LIST__:
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#include "__dso_handle.S"
 | 
			
		||||
#include "atexit.S"
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										48
									
								
								libc/arch-x86/bionic/__stack_chk_fail_local.S
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										48
									
								
								libc/arch-x86/bionic/__stack_chk_fail_local.S
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,48 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (C) 2011 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.
 | 
			
		||||
 */
 | 
			
		||||
/*
 | 
			
		||||
 * Contributed by: Intel Corporation
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
	.text
 | 
			
		||||
	.p2align 4,,15
 | 
			
		||||
	.globl	__stack_chk_fail_local
 | 
			
		||||
	.hidden	__stack_chk_fail_local
 | 
			
		||||
	.type	__stack_chk_fail_local, @function
 | 
			
		||||
 | 
			
		||||
__stack_chk_fail_local:
 | 
			
		||||
#ifdef __PIC__
 | 
			
		||||
	pushl	%ebx
 | 
			
		||||
	call	__x86.get_pc_thunk.bx
 | 
			
		||||
	addl	$_GLOBAL_OFFSET_TABLE_, %ebx
 | 
			
		||||
	call	__stack_chk_fail@PLT
 | 
			
		||||
#else /* PIC */
 | 
			
		||||
	jmp   __stack_chk_fail
 | 
			
		||||
#endif /* not PIC */
 | 
			
		||||
 | 
			
		||||
	.size	__stack_chk_fail_local, .-__stack_chk_fail_local
 | 
			
		||||
							
								
								
									
										66
									
								
								libc/arch-x86/bionic/atexit.S
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										66
									
								
								libc/arch-x86/bionic/atexit.S
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,66 @@
 | 
			
		||||
/*
 | 
			
		||||
 * 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.
 | 
			
		||||
 */
 | 
			
		||||
	.text
 | 
			
		||||
	.p2align 4,,15
 | 
			
		||||
	.globl	atexit
 | 
			
		||||
	.hidden	atexit
 | 
			
		||||
	.type	atexit, @function
 | 
			
		||||
atexit:
 | 
			
		||||
	pushl	%ebp
 | 
			
		||||
	movl	%esp, %ebp
 | 
			
		||||
	pushl	%ebx
 | 
			
		||||
	call	__x86.get_pc_thunk.bx
 | 
			
		||||
	addl	$_GLOBAL_OFFSET_TABLE_, %ebx
 | 
			
		||||
	subl	$20, %esp
 | 
			
		||||
	movl	$0, 4(%esp)
 | 
			
		||||
	movl	__dso_handle@GOTOFF(%ebx), %eax
 | 
			
		||||
	movl	%eax, 8(%esp)
 | 
			
		||||
	movl	8(%ebp), %eax
 | 
			
		||||
	movl	%eax, (%esp)
 | 
			
		||||
	call	__cxa_atexit@PLT
 | 
			
		||||
	addl	$20, %esp
 | 
			
		||||
	popl	%ebx
 | 
			
		||||
	popl	%ebp
 | 
			
		||||
	ret
 | 
			
		||||
	.size	atexit, .-atexit
 | 
			
		||||
 | 
			
		||||
	.section	.text.__x86.get_pc_thunk.bx,"axG",@progbits,__x86.get_pc_thunk.bx,comdat
 | 
			
		||||
	.globl	__x86.get_pc_thunk.bx
 | 
			
		||||
	.hidden	__x86.get_pc_thunk.bx
 | 
			
		||||
	.type	__x86.get_pc_thunk.bx, @function
 | 
			
		||||
__x86.get_pc_thunk.bx:
 | 
			
		||||
	nop
 | 
			
		||||
	nop
 | 
			
		||||
	nop
 | 
			
		||||
	nop
 | 
			
		||||
	nop
 | 
			
		||||
	nop
 | 
			
		||||
	nop
 | 
			
		||||
	nop
 | 
			
		||||
	movl	(%esp), %ebx
 | 
			
		||||
	ret
 | 
			
		||||
@@ -73,100 +73,3 @@ __futex_syscall4:
 | 
			
		||||
    popl    %esi
 | 
			
		||||
    popl    %ebx
 | 
			
		||||
    ret
 | 
			
		||||
 | 
			
		||||
/* int __atomic_cmpxchg(int old, int new, volatile int* addr) */
 | 
			
		||||
 | 
			
		||||
.text
 | 
			
		||||
.globl __atomic_cmpxchg
 | 
			
		||||
.type __atomic_cmpxchg, @function
 | 
			
		||||
.align 4
 | 
			
		||||
__atomic_cmpxchg:
 | 
			
		||||
    mov     4(%esp), %eax             /* old */
 | 
			
		||||
    mov     8(%esp), %ecx             /* new */
 | 
			
		||||
    mov     12(%esp), %edx            /* addr */
 | 
			
		||||
    lock cmpxchg %ecx, (%edx)
 | 
			
		||||
    jnz 1f
 | 
			
		||||
    xor    %eax, %eax
 | 
			
		||||
    jmp 2f
 | 
			
		||||
1:
 | 
			
		||||
    movl   $1, %eax
 | 
			
		||||
2:
 | 
			
		||||
    ret                               /* 0 == success, 1 == failure */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/* int __atomic_swap(int new, volatile int* addr) */
 | 
			
		||||
 | 
			
		||||
.text
 | 
			
		||||
.globl __atomic_swap
 | 
			
		||||
.type __atomic_swap, @function
 | 
			
		||||
.align 4
 | 
			
		||||
__atomic_swap:
 | 
			
		||||
    mov     4(%esp), %ecx             /* new */
 | 
			
		||||
    mov     8(%esp), %edx             /* addr */
 | 
			
		||||
    lock xchg %ecx, (%edx)
 | 
			
		||||
    mov     %ecx, %eax
 | 
			
		||||
    ret
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * int __atomic_dec(volatile int* addr)
 | 
			
		||||
 *
 | 
			
		||||
 * My x86 asm is really rusty.. this is probably suboptimal
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
.text
 | 
			
		||||
.globl __atomic_dec
 | 
			
		||||
.type __atomic_dec, @function
 | 
			
		||||
.align 4
 | 
			
		||||
__atomic_dec:
 | 
			
		||||
   pushl    %ebx
 | 
			
		||||
   pushl    %esi
 | 
			
		||||
   movl     12(%esp), %ebx             /* addr */
 | 
			
		||||
 | 
			
		||||
1:
 | 
			
		||||
   movl     (%ebx), %esi               /* old = *addr */
 | 
			
		||||
   movl     %esi, %edx
 | 
			
		||||
   subl     $1, %edx                   /* new = old - 1 */
 | 
			
		||||
 | 
			
		||||
   pushl    %ebx
 | 
			
		||||
   pushl    %edx
 | 
			
		||||
   pushl    %esi
 | 
			
		||||
   call     __atomic_cmpxchg
 | 
			
		||||
   addl     $12, %esp
 | 
			
		||||
   test     %eax, %eax
 | 
			
		||||
   jnz      1b
 | 
			
		||||
 | 
			
		||||
   movl     %esi, %eax               /* return old */
 | 
			
		||||
   popl     %esi
 | 
			
		||||
   popl     %ebx
 | 
			
		||||
   ret
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
.text
 | 
			
		||||
/* int __atomic_inc(volatile int* addr) */
 | 
			
		||||
.globl __atomic_inc
 | 
			
		||||
.type __atomic_inc, @function
 | 
			
		||||
.align 4
 | 
			
		||||
__atomic_inc:
 | 
			
		||||
   pushl    %ebx
 | 
			
		||||
   pushl    %esi
 | 
			
		||||
   movl     12(%esp), %ebx             /* addr */
 | 
			
		||||
 | 
			
		||||
1:
 | 
			
		||||
   movl     (%ebx), %esi               /* old = *addr */
 | 
			
		||||
   movl     %esi, %edx
 | 
			
		||||
   addl     $1, %edx                   /* new = old + 1 */
 | 
			
		||||
 | 
			
		||||
   pushl    %ebx
 | 
			
		||||
   pushl    %edx
 | 
			
		||||
   pushl    %esi
 | 
			
		||||
   call     __atomic_cmpxchg
 | 
			
		||||
   addl     $12, %esp
 | 
			
		||||
   test     %eax, %eax
 | 
			
		||||
   jnz      1b
 | 
			
		||||
 | 
			
		||||
   movl     %esi, %eax               /* return old */
 | 
			
		||||
   popl     %esi
 | 
			
		||||
   popl     %ebx
 | 
			
		||||
   ret
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -20,8 +20,7 @@ __pthread_clone:
 | 
			
		||||
        movl    %eax, -12(%ecx)
 | 
			
		||||
        movl    24(%esp), %eax
 | 
			
		||||
        movl    %eax, -8(%ecx)
 | 
			
		||||
        lea     (%ecx), %eax
 | 
			
		||||
        movl    %eax, -4(%ecx)
 | 
			
		||||
        movl    %ecx, -4(%ecx)
 | 
			
		||||
 | 
			
		||||
        movl    $__NR_clone, %eax
 | 
			
		||||
        int     $0x80
 | 
			
		||||
@@ -52,4 +51,4 @@ __pthread_clone:
 | 
			
		||||
/* XXX: TODO: Add __bionic_clone here
 | 
			
		||||
 *            See bionic/bionic_clone.c and arch-arm/bionic/clone.S
 | 
			
		||||
 *            for more details...
 | 
			
		||||
 */
 | 
			
		||||
 */
 | 
			
		||||
 
 | 
			
		||||
@@ -66,14 +66,7 @@ _start:
 | 
			
		||||
1:  .long   __PREINIT_ARRAY__
 | 
			
		||||
    .long   __INIT_ARRAY__
 | 
			
		||||
    .long   __FINI_ARRAY__
 | 
			
		||||
    .long   __CTOR_LIST__
 | 
			
		||||
      
 | 
			
		||||
# the .ctors section contains a list of pointers to "constructor"
 | 
			
		||||
# functions that need to be called in order during C library initialization,
 | 
			
		||||
# just before the program is being run. This is a C++ requirement
 | 
			
		||||
#
 | 
			
		||||
# the last entry shall be 0, and is defined in crtend.S
 | 
			
		||||
#
 | 
			
		||||
 | 
			
		||||
	.section .preinit_array, "aw"
 | 
			
		||||
	.globl __PREINIT_ARRAY__
 | 
			
		||||
__PREINIT_ARRAY__:
 | 
			
		||||
@@ -83,15 +76,62 @@ __PREINIT_ARRAY__:
 | 
			
		||||
	.globl __INIT_ARRAY__
 | 
			
		||||
__INIT_ARRAY__:
 | 
			
		||||
	.long -1
 | 
			
		||||
	.long	frame_dummy
 | 
			
		||||
 | 
			
		||||
	.section .fini_array, "aw"
 | 
			
		||||
	.globl __FINI_ARRAY__
 | 
			
		||||
__FINI_ARRAY__:
 | 
			
		||||
	.long -1
 | 
			
		||||
	.long	__do_global_dtors_aux
 | 
			
		||||
 | 
			
		||||
	.section .ctors, "aw"
 | 
			
		||||
	.globl __CTOR_LIST__
 | 
			
		||||
__CTOR_LIST__:
 | 
			
		||||
	.long -1
 | 
			
		||||
	.section	.eh_frame,"a",@progbits
 | 
			
		||||
	.align 4
 | 
			
		||||
	.type	__EH_FRAME_BEGIN__, @object
 | 
			
		||||
__EH_FRAME_BEGIN__:
 | 
			
		||||
	.text
 | 
			
		||||
	.p2align 4,,15
 | 
			
		||||
	.type	__do_global_dtors_aux, @function
 | 
			
		||||
__do_global_dtors_aux:
 | 
			
		||||
	pushl	%ebp
 | 
			
		||||
	movl	%esp, %ebp
 | 
			
		||||
	subl	$24, %esp
 | 
			
		||||
	cmpb	$0, completed.4454
 | 
			
		||||
	jne	.L4
 | 
			
		||||
	movl	$__deregister_frame_info_bases, %eax
 | 
			
		||||
	testl	%eax, %eax
 | 
			
		||||
	je	.L3
 | 
			
		||||
	movl	$__EH_FRAME_BEGIN__, (%esp)
 | 
			
		||||
	call	__deregister_frame_info_bases
 | 
			
		||||
.L3:
 | 
			
		||||
	movb	$1, completed.4454
 | 
			
		||||
.L4:
 | 
			
		||||
	leave
 | 
			
		||||
	ret
 | 
			
		||||
	.text
 | 
			
		||||
	.p2align 4,,15
 | 
			
		||||
	.type	frame_dummy, @function
 | 
			
		||||
frame_dummy:
 | 
			
		||||
	pushl	%ebp
 | 
			
		||||
	movl	$__register_frame_info_bases, %eax
 | 
			
		||||
	movl	%esp, %ebp
 | 
			
		||||
	subl	$24, %esp
 | 
			
		||||
	testl	%eax, %eax
 | 
			
		||||
	je	.L7
 | 
			
		||||
	movl	%ebx, 12(%esp)
 | 
			
		||||
	movl	$0, 8(%esp)
 | 
			
		||||
	movl	$object.4466, 4(%esp)
 | 
			
		||||
	movl	$__EH_FRAME_BEGIN__, (%esp)
 | 
			
		||||
	call	__register_frame_info_bases
 | 
			
		||||
.L7:
 | 
			
		||||
	leave
 | 
			
		||||
	ret
 | 
			
		||||
	.local	completed.4454
 | 
			
		||||
	.comm	completed.4454,1,1
 | 
			
		||||
	.local	object.4466
 | 
			
		||||
	.comm	object.4466,24,4
 | 
			
		||||
	.weak	__register_frame_info_bases
 | 
			
		||||
	.weak	__deregister_frame_info_bases
 | 
			
		||||
 | 
			
		||||
#include "__dso_handle.S"
 | 
			
		||||
#include "atexit.S"
 | 
			
		||||
#include "__stack_chk_fail_local.S"
 | 
			
		||||
 
 | 
			
		||||
@@ -1,18 +1,30 @@
 | 
			
		||||
# This function is to be called when the shared library
 | 
			
		||||
# is unloaded through dlclose()
 | 
			
		||||
_on_dlclose:
 | 
			
		||||
    lea __dso_handle, %eax
 | 
			
		||||
    call __cxa_finalize
 | 
			
		||||
    ret
 | 
			
		||||
 | 
			
		||||
/* we put the _init() function here in case the user files for the shared
 | 
			
		||||
 * libs want to drop things into .init section.
 | 
			
		||||
 * We then will call our ctors from crtend_so.o */
 | 
			
		||||
.section .init
 | 
			
		||||
.align 4
 | 
			
		||||
.type _init, @function
 | 
			
		||||
.globl _init
 | 
			
		||||
_init:
 | 
			
		||||
/*
 | 
			
		||||
 * 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.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
.section .init_array, "aw"
 | 
			
		||||
.align 4
 | 
			
		||||
@@ -20,6 +32,7 @@ _init:
 | 
			
		||||
.globl __INIT_ARRAY__
 | 
			
		||||
__INIT_ARRAY__:
 | 
			
		||||
    .long -1
 | 
			
		||||
    .long frame_dummy
 | 
			
		||||
 | 
			
		||||
.section .fini_array, "aw"
 | 
			
		||||
.align 4
 | 
			
		||||
@@ -27,13 +40,72 @@ __INIT_ARRAY__:
 | 
			
		||||
.globl __FINI_ARRAY__
 | 
			
		||||
__FINI_ARRAY__:
 | 
			
		||||
    .long -1
 | 
			
		||||
    .long _on_dlclose
 | 
			
		||||
    .long __do_global_dtors_aux
 | 
			
		||||
 | 
			
		||||
.section .ctors, "aw"
 | 
			
		||||
.align 4
 | 
			
		||||
.type __CTOR_LIST__, @object
 | 
			
		||||
.globl __CTOR_LIST__
 | 
			
		||||
__CTOR_LIST__:
 | 
			
		||||
        .long -1
 | 
			
		||||
	.section	.eh_frame,"a",@progbits
 | 
			
		||||
	.align 4
 | 
			
		||||
	.type	__EH_FRAME_BEGIN__, @object
 | 
			
		||||
__EH_FRAME_BEGIN__:
 | 
			
		||||
	.text
 | 
			
		||||
	.p2align 4,,15
 | 
			
		||||
	.type	__do_global_dtors_aux, @function
 | 
			
		||||
__do_global_dtors_aux:
 | 
			
		||||
	pushl	%ebp
 | 
			
		||||
	movl	%esp, %ebp
 | 
			
		||||
	pushl	%ebx
 | 
			
		||||
	call	__x86.get_pc_thunk.bx
 | 
			
		||||
	addl	$_GLOBAL_OFFSET_TABLE_, %ebx
 | 
			
		||||
	subl	$20, %esp
 | 
			
		||||
	cmpb	$0, completed.4454@GOTOFF(%ebx)
 | 
			
		||||
	jne	.L5
 | 
			
		||||
	movl	__dso_handle@GOTOFF(%ebx), %eax
 | 
			
		||||
	movl	%eax, (%esp)
 | 
			
		||||
	call	__cxa_finalize@PLT
 | 
			
		||||
	movl	__deregister_frame_info_bases@GOT(%ebx), %eax
 | 
			
		||||
	testl	%eax, %eax
 | 
			
		||||
	je	.L4
 | 
			
		||||
	leal	__EH_FRAME_BEGIN__@GOTOFF(%ebx), %eax
 | 
			
		||||
	movl	%eax, (%esp)
 | 
			
		||||
	call	__deregister_frame_info_bases@PLT
 | 
			
		||||
.L4:
 | 
			
		||||
	movb	$1, completed.4454@GOTOFF(%ebx)
 | 
			
		||||
.L5:
 | 
			
		||||
	addl	$20, %esp
 | 
			
		||||
	popl	%ebx
 | 
			
		||||
	popl	%ebp
 | 
			
		||||
	ret
 | 
			
		||||
	.text
 | 
			
		||||
	.p2align 4,,15
 | 
			
		||||
	.type	frame_dummy, @function
 | 
			
		||||
frame_dummy:
 | 
			
		||||
	pushl	%ebp
 | 
			
		||||
	movl	%esp, %ebp
 | 
			
		||||
	pushl	%ebx
 | 
			
		||||
	call	__x86.get_pc_thunk.bx
 | 
			
		||||
	addl	$_GLOBAL_OFFSET_TABLE_, %ebx
 | 
			
		||||
	subl	$20, %esp
 | 
			
		||||
	movl	__register_frame_info_bases@GOT(%ebx), %eax
 | 
			
		||||
	testl	%eax, %eax
 | 
			
		||||
	je	.L8
 | 
			
		||||
	leal	object.4469@GOTOFF(%ebx), %eax
 | 
			
		||||
	movl	%eax, 4(%esp)
 | 
			
		||||
	leal	__EH_FRAME_BEGIN__@GOTOFF(%ebx), %eax
 | 
			
		||||
	movl	%ebx, 12(%esp)
 | 
			
		||||
	movl	$0, 8(%esp)
 | 
			
		||||
	movl	%eax, (%esp)
 | 
			
		||||
	call	__register_frame_info_bases@PLT
 | 
			
		||||
.L8:
 | 
			
		||||
	addl	$20, %esp
 | 
			
		||||
	popl	%ebx
 | 
			
		||||
	popl	%ebp
 | 
			
		||||
	ret
 | 
			
		||||
	.local	completed.4454
 | 
			
		||||
	.comm	completed.4454,1,1
 | 
			
		||||
	.local	object.4469
 | 
			
		||||
	.comm	object.4469,24,4
 | 
			
		||||
	.weak	__register_frame_info_bases
 | 
			
		||||
	.weak	__deregister_frame_info_bases
 | 
			
		||||
 | 
			
		||||
#include "__dso_handle.S"
 | 
			
		||||
#include "__dso_handle_so.S"
 | 
			
		||||
#include "atexit.S"
 | 
			
		||||
#include "__stack_chk_fail_local.S"
 | 
			
		||||
 
 | 
			
		||||
@@ -65,7 +65,6 @@ _start:
 | 
			
		||||
1:  .long   __PREINIT_ARRAY__
 | 
			
		||||
    .long   __INIT_ARRAY__
 | 
			
		||||
    .long   __FINI_ARRAY__
 | 
			
		||||
    .long   __CTOR_LIST__
 | 
			
		||||
 | 
			
		||||
	.section .preinit_array, "aw"
 | 
			
		||||
	.globl __PREINIT_ARRAY__
 | 
			
		||||
@@ -76,15 +75,62 @@ __PREINIT_ARRAY__:
 | 
			
		||||
	.globl __INIT_ARRAY__
 | 
			
		||||
__INIT_ARRAY__:
 | 
			
		||||
	.long -1
 | 
			
		||||
	.long	frame_dummy
 | 
			
		||||
 | 
			
		||||
	.section .fini_array, "aw"
 | 
			
		||||
	.globl __FINI_ARRAY__
 | 
			
		||||
__FINI_ARRAY__:
 | 
			
		||||
	.long -1
 | 
			
		||||
	.long	__do_global_dtors_aux
 | 
			
		||||
 | 
			
		||||
	.section .ctors, "aw"
 | 
			
		||||
	.globl __CTOR_LIST__
 | 
			
		||||
__CTOR_LIST__:
 | 
			
		||||
	.long -1
 | 
			
		||||
	.section	.eh_frame,"a",@progbits
 | 
			
		||||
	.align 4
 | 
			
		||||
	.type	__EH_FRAME_BEGIN__, @object
 | 
			
		||||
__EH_FRAME_BEGIN__:
 | 
			
		||||
	.text
 | 
			
		||||
	.p2align 4,,15
 | 
			
		||||
	.type	__do_global_dtors_aux, @function
 | 
			
		||||
__do_global_dtors_aux:
 | 
			
		||||
	pushl	%ebp
 | 
			
		||||
	movl	%esp, %ebp
 | 
			
		||||
	subl	$24, %esp
 | 
			
		||||
	cmpb	$0, completed.4454
 | 
			
		||||
	jne	.L4
 | 
			
		||||
	movl	$__deregister_frame_info_bases, %eax
 | 
			
		||||
	testl	%eax, %eax
 | 
			
		||||
	je	.L3
 | 
			
		||||
	movl	$__EH_FRAME_BEGIN__, (%esp)
 | 
			
		||||
	call	__deregister_frame_info_bases
 | 
			
		||||
.L3:
 | 
			
		||||
	movb	$1, completed.4454
 | 
			
		||||
.L4:
 | 
			
		||||
	leave
 | 
			
		||||
	ret
 | 
			
		||||
	.text
 | 
			
		||||
	.p2align 4,,15
 | 
			
		||||
	.type	frame_dummy, @function
 | 
			
		||||
frame_dummy:
 | 
			
		||||
	pushl	%ebp
 | 
			
		||||
	movl	$__register_frame_info_bases, %eax
 | 
			
		||||
	movl	%esp, %ebp
 | 
			
		||||
	subl	$24, %esp
 | 
			
		||||
	testl	%eax, %eax
 | 
			
		||||
	je	.L7
 | 
			
		||||
	movl	%ebx, 12(%esp)
 | 
			
		||||
	movl	$0, 8(%esp)
 | 
			
		||||
	movl	$object.4466, 4(%esp)
 | 
			
		||||
	movl	$__EH_FRAME_BEGIN__, (%esp)
 | 
			
		||||
	call	__register_frame_info_bases
 | 
			
		||||
.L7:
 | 
			
		||||
	leave
 | 
			
		||||
	ret
 | 
			
		||||
	.local	completed.4454
 | 
			
		||||
	.comm	completed.4454,1,1
 | 
			
		||||
	.local	object.4466
 | 
			
		||||
	.comm	object.4466,24,4
 | 
			
		||||
	.weak	__register_frame_info_bases
 | 
			
		||||
	.weak	__deregister_frame_info_bases
 | 
			
		||||
 | 
			
		||||
#include "__dso_handle.S"
 | 
			
		||||
#include "atexit.S"
 | 
			
		||||
#include "__stack_chk_fail_local.S"
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,3 @@
 | 
			
		||||
	
 | 
			
		||||
	.section .preinit_array, "aw"
 | 
			
		||||
	.long 0
 | 
			
		||||
 | 
			
		||||
@@ -8,6 +7,9 @@
 | 
			
		||||
	.section .fini_array, "aw"
 | 
			
		||||
	.long 0
 | 
			
		||||
 | 
			
		||||
	.section .ctors, "aw"
 | 
			
		||||
	.long 0
 | 
			
		||||
 | 
			
		||||
	.section	.eh_frame,"a",@progbits
 | 
			
		||||
	.align 4
 | 
			
		||||
	.type	__FRAME_END__, @object
 | 
			
		||||
	.size	__FRAME_END__, 4
 | 
			
		||||
__FRAME_END__:
 | 
			
		||||
	.zero	4
 | 
			
		||||
 
 | 
			
		||||
@@ -1,47 +1,12 @@
 | 
			
		||||
.text
 | 
			
		||||
.align 4
 | 
			
		||||
.type __bionic_call_ctors, @function
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * The CTORS_LIST is marked by -1 (start) and 0 (end).
 | 
			
		||||
 * We mark the end of the .ctors section with the __CTOR_END__ section so
 | 
			
		||||
 * that we can just iterate backwards from it until we hit -1 and execute
 | 
			
		||||
 * all the function pointers. This seems to be the way to do it for SVR4
 | 
			
		||||
 * derived systems.
 | 
			
		||||
 */
 | 
			
		||||
__bionic_call_ctors:
 | 
			
		||||
    pushl  %esi
 | 
			
		||||
    mov    $__CTOR_END__, %esi
 | 
			
		||||
 | 
			
		||||
0:
 | 
			
		||||
    /* now grab the next function pointer and check if its -1. If not,
 | 
			
		||||
     * call it, otherwise we're done. We use %esi since it's callee saved.
 | 
			
		||||
     */
 | 
			
		||||
    subl    $4, %esi
 | 
			
		||||
    mov     (%esi), %eax
 | 
			
		||||
    cmp     $0xffffffff, %eax
 | 
			
		||||
    je      1f
 | 
			
		||||
    call    *%eax
 | 
			
		||||
    jmp     0b
 | 
			
		||||
 | 
			
		||||
1:
 | 
			
		||||
    /* we're done */
 | 
			
		||||
    popl    %esi
 | 
			
		||||
    ret
 | 
			
		||||
 | 
			
		||||
.section .init
 | 
			
		||||
.align 4
 | 
			
		||||
    call __bionic_call_ctors
 | 
			
		||||
    ret
 | 
			
		||||
 | 
			
		||||
.section .ctors, "aw", @progbits
 | 
			
		||||
.align 4
 | 
			
		||||
.type __CTOR_END__, @object
 | 
			
		||||
__CTOR_END__:
 | 
			
		||||
    .long 0
 | 
			
		||||
 | 
			
		||||
.section .init_array, "aw"
 | 
			
		||||
    .long 0
 | 
			
		||||
 | 
			
		||||
.section .fini_array, "aw"
 | 
			
		||||
    .long 0
 | 
			
		||||
 | 
			
		||||
	.section	.eh_frame,"a",@progbits
 | 
			
		||||
	.align 4
 | 
			
		||||
	.type	__FRAME_END__, @object
 | 
			
		||||
	.size	__FRAME_END__, 4
 | 
			
		||||
__FRAME_END__:
 | 
			
		||||
	.zero	4
 | 
			
		||||
 
 | 
			
		||||
@@ -31,14 +31,14 @@
 | 
			
		||||
 | 
			
		||||
#if defined(_KERNEL) && !defined(I386_CPU)
 | 
			
		||||
#define	__swap32md(x) ({						\
 | 
			
		||||
	u_int32_t __swap32md_x = (x);					\
 | 
			
		||||
	uint32_t __swap32md_x = (x);					\
 | 
			
		||||
									\
 | 
			
		||||
	__asm ("bswap %1" : "+r" (__swap32md_x));			\
 | 
			
		||||
	__swap32md_x;							\
 | 
			
		||||
})
 | 
			
		||||
#else
 | 
			
		||||
#define	__swap32md(x) ({						\
 | 
			
		||||
	u_int32_t __swap32md_x = (x);					\
 | 
			
		||||
	uint32_t __swap32md_x = (x);					\
 | 
			
		||||
									\
 | 
			
		||||
	__asm ("rorw $8, %w1; rorl $16, %1; rorw $8, %w1" :		\
 | 
			
		||||
	    "+r" (__swap32md_x));					\
 | 
			
		||||
@@ -47,13 +47,13 @@
 | 
			
		||||
#endif	/* _KERNEL && !I386_CPU */
 | 
			
		||||
 | 
			
		||||
#define	__swap64md(x) ({						\
 | 
			
		||||
	u_int64_t __swap64md_x = (x);					\
 | 
			
		||||
	uint64_t __swap64md_x = (x);					\
 | 
			
		||||
									\
 | 
			
		||||
	(u_int64_t)__swap32md(__swap64md_x >> 32) |			\
 | 
			
		||||
	    (u_int64_t)__swap32md(__swap64md_x & 0xffffffff) << 32;	\
 | 
			
		||||
	(uint64_t)__swap32md(__swap64md_x >> 32) |			\
 | 
			
		||||
	    (uint64_t)__swap32md(__swap64md_x & 0xffffffff) << 32;	\
 | 
			
		||||
})
 | 
			
		||||
#define	__swap16md(x) ({						\
 | 
			
		||||
	u_int16_t __swap16md_x = (x);					\
 | 
			
		||||
	uint16_t __swap16md_x = (x);					\
 | 
			
		||||
									\
 | 
			
		||||
	__asm ("rorw $8, %w1" : "+r" (__swap16md_x));			\
 | 
			
		||||
	__swap16md_x;							\
 | 
			
		||||
 
 | 
			
		||||
@@ -36,8 +36,8 @@
 | 
			
		||||
#define _I386__TYPES_H_
 | 
			
		||||
 | 
			
		||||
/* the kernel defines size_t as unsigned int, but g++ wants it to be unsigned long */
 | 
			
		||||
#ifndef _SIZE_T
 | 
			
		||||
#  define _SIZE_T
 | 
			
		||||
#ifndef _SIZE_T_DEFINED_
 | 
			
		||||
#  define _SIZE_T_DEFINED_
 | 
			
		||||
#  ifdef ANDROID
 | 
			
		||||
     typedef unsigned int  size_t;
 | 
			
		||||
#  else
 | 
			
		||||
@@ -54,9 +54,6 @@ typedef long int       ssize_t;
 | 
			
		||||
typedef long           ptrdiff_t;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#define _OFF_T_DEFINED_
 | 
			
		||||
#define _SIZE_T_DEFINED_
 | 
			
		||||
 | 
			
		||||
#include <linux/types.h>
 | 
			
		||||
 | 
			
		||||
/* 7.18.1.1 Exact-width integer types */
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										65
									
								
								libc/arch-x86/include/sys/atomics.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										65
									
								
								libc/arch-x86/include/sys/atomics.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,65 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (C) 2011 The Android Open Source Project
 | 
			
		||||
 * All rights reserved.
 | 
			
		||||
 *
 | 
			
		||||
 * Redistribution and use in source and binary forms, with or without
 | 
			
		||||
 * modification, are permitted provided that the following conditions
 | 
			
		||||
 * are met:
 | 
			
		||||
 *  * Redistributions of source code must retain the above copyright
 | 
			
		||||
 *    notice, this list of conditions and the following disclaimer.
 | 
			
		||||
 *  * Redistributions in binary form must reproduce the above copyright
 | 
			
		||||
 *    notice, this list of conditions and the following disclaimer in
 | 
			
		||||
 *    the documentation and/or other materials provided with the
 | 
			
		||||
 *    distribution.
 | 
			
		||||
 *
 | 
			
		||||
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 | 
			
		||||
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 | 
			
		||||
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
 | 
			
		||||
 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
 | 
			
		||||
 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
 | 
			
		||||
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
 | 
			
		||||
 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
 | 
			
		||||
 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
 | 
			
		||||
 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 | 
			
		||||
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 | 
			
		||||
 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 | 
			
		||||
 * SUCH DAMAGE.
 | 
			
		||||
 */
 | 
			
		||||
#ifndef _SYS_ATOMICS_H
 | 
			
		||||
#define _SYS_ATOMICS_H
 | 
			
		||||
 | 
			
		||||
#include <sys/cdefs.h>
 | 
			
		||||
#include <sys/time.h>
 | 
			
		||||
 | 
			
		||||
__BEGIN_DECLS
 | 
			
		||||
 | 
			
		||||
static inline __attribute__((always_inline)) int
 | 
			
		||||
__atomic_cmpxchg(int old, int _new, volatile int *ptr)
 | 
			
		||||
{
 | 
			
		||||
  return !__sync_bool_compare_and_swap (ptr, old, _new);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline __attribute__((always_inline)) int
 | 
			
		||||
__atomic_swap(int _new, volatile int *ptr)
 | 
			
		||||
{
 | 
			
		||||
  return __sync_lock_test_and_set(ptr, _new);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline __attribute__((always_inline)) int
 | 
			
		||||
__atomic_dec(volatile int *ptr)
 | 
			
		||||
{
 | 
			
		||||
  return __sync_fetch_and_sub (ptr, 1);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline __attribute__((always_inline)) int
 | 
			
		||||
__atomic_inc(volatile int *ptr)
 | 
			
		||||
{
 | 
			
		||||
  return __sync_fetch_and_add (ptr, 1);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int __futex_wait(volatile void *ftx, int val, const struct timespec *timeout);
 | 
			
		||||
int __futex_wake(volatile void *ftx, int count);
 | 
			
		||||
 | 
			
		||||
__END_DECLS
 | 
			
		||||
 | 
			
		||||
#endif /* _SYS_ATOMICS_H */
 | 
			
		||||
@@ -31,7 +31,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 | 
			
		||||
#if defined(USE_SSSE3)
 | 
			
		||||
 | 
			
		||||
# define MEMCMP memcmp
 | 
			
		||||
# include "ssse3-memcmp3.S"
 | 
			
		||||
# include "ssse3-memcmp3-new.S"
 | 
			
		||||
 | 
			
		||||
#else
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -49,7 +49,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef cfi_restore
 | 
			
		||||
# define cfi_restore(reg)		.cfi_restore (reg)
 | 
			
		||||
# define cfi_restore(reg)		.cfi_restore reg
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef cfi_adjust_cfa_offset
 | 
			
		||||
@@ -285,7 +285,6 @@ L(32bytesormore):
 | 
			
		||||
	pxor	%xmm0, %xmm0
 | 
			
		||||
#else
 | 
			
		||||
	movd	%eax, %xmm0
 | 
			
		||||
	punpcklbw %xmm0, %xmm0
 | 
			
		||||
	pshufd	$0, %xmm0, %xmm0
 | 
			
		||||
#endif
 | 
			
		||||
	testl	$0xf, %edx
 | 
			
		||||
@@ -329,14 +328,17 @@ L(128bytesormore):
 | 
			
		||||
 | 
			
		||||
#ifdef DATA_CACHE_SIZE
 | 
			
		||||
	POP (%ebx)
 | 
			
		||||
# define RESTORE_EBX_STATE CFI_PUSH (%ebx)
 | 
			
		||||
	cmp	$DATA_CACHE_SIZE, %ecx
 | 
			
		||||
#else
 | 
			
		||||
# ifdef SHARED
 | 
			
		||||
#  define RESTORE_EBX_STATE
 | 
			
		||||
	call	__i686.get_pc_thunk.bx
 | 
			
		||||
	add	$_GLOBAL_OFFSET_TABLE_, %ebx
 | 
			
		||||
	cmp	__x86_data_cache_size@GOTOFF(%ebx), %ecx
 | 
			
		||||
# else
 | 
			
		||||
	POP (%ebx)
 | 
			
		||||
#  define RESTORE_EBX_STATE CFI_PUSH (%ebx)
 | 
			
		||||
	cmp	__x86_data_cache_size, %ecx
 | 
			
		||||
# endif
 | 
			
		||||
#endif
 | 
			
		||||
@@ -370,7 +372,7 @@ L(128bytesormore_normal):
 | 
			
		||||
	jae	L(128bytesormore_normal)
 | 
			
		||||
 | 
			
		||||
L(128bytesless_normal):
 | 
			
		||||
	lea	128(%ecx), %ecx
 | 
			
		||||
	add	$128, %ecx
 | 
			
		||||
	BRANCH_TO_JMPTBL_ENTRY (L(table_16_128bytes))
 | 
			
		||||
 | 
			
		||||
	ALIGN (4)
 | 
			
		||||
@@ -393,8 +395,13 @@ L(128bytes_L2_normal):
 | 
			
		||||
L(128bytesless_L2_normal):
 | 
			
		||||
	BRANCH_TO_JMPTBL_ENTRY (L(table_16_128bytes))
 | 
			
		||||
 | 
			
		||||
	RESTORE_EBX_STATE
 | 
			
		||||
L(128bytesormore_nt_start):
 | 
			
		||||
	sub	%ebx, %ecx
 | 
			
		||||
	mov	%ebx, %eax
 | 
			
		||||
	and	$0x7f, %eax
 | 
			
		||||
	add	%eax, %ecx
 | 
			
		||||
	movd	%xmm0, %eax
 | 
			
		||||
	ALIGN (4)
 | 
			
		||||
L(128bytesormore_shared_cache_loop):
 | 
			
		||||
	prefetcht0	0x3c0(%edx)
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										369
									
								
								libc/arch-x86/string/sse2-strlen-atom.S
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										369
									
								
								libc/arch-x86/string/sse2-strlen-atom.S
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,369 @@
 | 
			
		||||
#define STRLEN sse2_strlen_atom
 | 
			
		||||
 | 
			
		||||
#ifndef L
 | 
			
		||||
# define L(label)	.L##label
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef cfi_startproc
 | 
			
		||||
# define cfi_startproc			.cfi_startproc
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef cfi_endproc
 | 
			
		||||
# define cfi_endproc			.cfi_endproc
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef cfi_rel_offset
 | 
			
		||||
# define cfi_rel_offset(reg, off)	.cfi_rel_offset reg, off
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef cfi_restore
 | 
			
		||||
# define cfi_restore(reg)		.cfi_restore reg
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef cfi_adjust_cfa_offset
 | 
			
		||||
# define cfi_adjust_cfa_offset(off)	.cfi_adjust_cfa_offset off
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef cfi_remember_state
 | 
			
		||||
# define cfi_remember_state		.cfi_remember_state
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef cfi_restore_state
 | 
			
		||||
# define cfi_restore_state		.cfi_restore_state
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef ENTRY
 | 
			
		||||
# define ENTRY(name)			\
 | 
			
		||||
	.type name,  @function; 	\
 | 
			
		||||
	.globl name;			\
 | 
			
		||||
	.p2align 4;			\
 | 
			
		||||
name:					\
 | 
			
		||||
	cfi_startproc
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef END
 | 
			
		||||
# define END(name)			\
 | 
			
		||||
	cfi_endproc;			\
 | 
			
		||||
	.size name, .-name
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#define CFI_PUSH(REG)						\
 | 
			
		||||
  cfi_adjust_cfa_offset (4);					\
 | 
			
		||||
  cfi_rel_offset (REG, 0)
 | 
			
		||||
 | 
			
		||||
#define CFI_POP(REG)						\
 | 
			
		||||
  cfi_adjust_cfa_offset (-4);					\
 | 
			
		||||
  cfi_restore (REG)
 | 
			
		||||
 | 
			
		||||
#define PUSH(REG)	pushl REG; CFI_PUSH (REG)
 | 
			
		||||
#define POP(REG)	popl REG; CFI_POP (REG)
 | 
			
		||||
#define PARMS		4
 | 
			
		||||
#define	STR		PARMS
 | 
			
		||||
#define ENTRANCE
 | 
			
		||||
#define RETURN		ret
 | 
			
		||||
 | 
			
		||||
	.text
 | 
			
		||||
ENTRY (STRLEN)
 | 
			
		||||
	ENTRANCE
 | 
			
		||||
	mov	STR(%esp), %edx
 | 
			
		||||
	xor	%eax, %eax
 | 
			
		||||
	cmpb	$0, (%edx)
 | 
			
		||||
	jz	L(exit_tail0)
 | 
			
		||||
	cmpb	$0, 1(%edx)
 | 
			
		||||
	jz	L(exit_tail1)
 | 
			
		||||
	cmpb	$0, 2(%edx)
 | 
			
		||||
	jz	L(exit_tail2)
 | 
			
		||||
	cmpb	$0, 3(%edx)
 | 
			
		||||
	jz	L(exit_tail3)
 | 
			
		||||
	cmpb	$0, 4(%edx)
 | 
			
		||||
	jz	L(exit_tail4)
 | 
			
		||||
	cmpb	$0, 5(%edx)
 | 
			
		||||
	jz	L(exit_tail5)
 | 
			
		||||
	cmpb	$0, 6(%edx)
 | 
			
		||||
	jz	L(exit_tail6)
 | 
			
		||||
	cmpb	$0, 7(%edx)
 | 
			
		||||
	jz	L(exit_tail7)
 | 
			
		||||
	cmpb	$0, 8(%edx)
 | 
			
		||||
	jz	L(exit_tail8)
 | 
			
		||||
	cmpb	$0, 9(%edx)
 | 
			
		||||
	jz	L(exit_tail9)
 | 
			
		||||
	cmpb	$0, 10(%edx)
 | 
			
		||||
	jz	L(exit_tail10)
 | 
			
		||||
	cmpb	$0, 11(%edx)
 | 
			
		||||
	jz	L(exit_tail11)
 | 
			
		||||
	cmpb	$0, 12(%edx)
 | 
			
		||||
	jz	L(exit_tail12)
 | 
			
		||||
	cmpb	$0, 13(%edx)
 | 
			
		||||
	jz	L(exit_tail13)
 | 
			
		||||
	cmpb	$0, 14(%edx)
 | 
			
		||||
	jz	L(exit_tail14)
 | 
			
		||||
	cmpb	$0, 15(%edx)
 | 
			
		||||
	jz	L(exit_tail15)
 | 
			
		||||
	pxor	%xmm0, %xmm0
 | 
			
		||||
	mov	%edx, %eax
 | 
			
		||||
	mov	%edx, %ecx
 | 
			
		||||
	and	$-16, %eax
 | 
			
		||||
	add	$16, %ecx
 | 
			
		||||
	add	$16, %eax
 | 
			
		||||
 | 
			
		||||
	pcmpeqb	(%eax), %xmm0
 | 
			
		||||
	pmovmskb %xmm0, %edx
 | 
			
		||||
	pxor	%xmm1, %xmm1
 | 
			
		||||
	test	%edx, %edx
 | 
			
		||||
	lea	16(%eax), %eax
 | 
			
		||||
	jnz	L(exit)
 | 
			
		||||
 | 
			
		||||
	pcmpeqb	(%eax), %xmm1
 | 
			
		||||
	pmovmskb %xmm1, %edx
 | 
			
		||||
	pxor	%xmm2, %xmm2
 | 
			
		||||
	test	%edx, %edx
 | 
			
		||||
	lea	16(%eax), %eax
 | 
			
		||||
	jnz	L(exit)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	pcmpeqb	(%eax), %xmm2
 | 
			
		||||
	pmovmskb %xmm2, %edx
 | 
			
		||||
	pxor	%xmm3, %xmm3
 | 
			
		||||
	test	%edx, %edx
 | 
			
		||||
	lea	16(%eax), %eax
 | 
			
		||||
	jnz	L(exit)
 | 
			
		||||
 | 
			
		||||
	pcmpeqb	(%eax), %xmm3
 | 
			
		||||
	pmovmskb %xmm3, %edx
 | 
			
		||||
	test	%edx, %edx
 | 
			
		||||
	lea	16(%eax), %eax
 | 
			
		||||
	jnz	L(exit)
 | 
			
		||||
 | 
			
		||||
	pcmpeqb	(%eax), %xmm0
 | 
			
		||||
	pmovmskb %xmm0, %edx
 | 
			
		||||
	test	%edx, %edx
 | 
			
		||||
	lea	16(%eax), %eax
 | 
			
		||||
	jnz	L(exit)
 | 
			
		||||
 | 
			
		||||
	pcmpeqb	(%eax), %xmm1
 | 
			
		||||
	pmovmskb %xmm1, %edx
 | 
			
		||||
	test	%edx, %edx
 | 
			
		||||
	lea	16(%eax), %eax
 | 
			
		||||
	jnz	L(exit)
 | 
			
		||||
 | 
			
		||||
	pcmpeqb	(%eax), %xmm2
 | 
			
		||||
	pmovmskb %xmm2, %edx
 | 
			
		||||
	test	%edx, %edx
 | 
			
		||||
	lea	16(%eax), %eax
 | 
			
		||||
	jnz	L(exit)
 | 
			
		||||
 | 
			
		||||
	pcmpeqb	(%eax), %xmm3
 | 
			
		||||
	pmovmskb %xmm3, %edx
 | 
			
		||||
	test	%edx, %edx
 | 
			
		||||
	lea	16(%eax), %eax
 | 
			
		||||
	jnz	L(exit)
 | 
			
		||||
 | 
			
		||||
	pcmpeqb	(%eax), %xmm0
 | 
			
		||||
	pmovmskb %xmm0, %edx
 | 
			
		||||
	test	%edx, %edx
 | 
			
		||||
	lea	16(%eax), %eax
 | 
			
		||||
	jnz	L(exit)
 | 
			
		||||
 | 
			
		||||
	pcmpeqb	(%eax), %xmm1
 | 
			
		||||
	pmovmskb %xmm1, %edx
 | 
			
		||||
	test	%edx, %edx
 | 
			
		||||
	lea	16(%eax), %eax
 | 
			
		||||
	jnz	L(exit)
 | 
			
		||||
 | 
			
		||||
	pcmpeqb	(%eax), %xmm2
 | 
			
		||||
	pmovmskb %xmm2, %edx
 | 
			
		||||
	test	%edx, %edx
 | 
			
		||||
	lea	16(%eax), %eax
 | 
			
		||||
	jnz	L(exit)
 | 
			
		||||
 | 
			
		||||
	pcmpeqb	(%eax), %xmm3
 | 
			
		||||
	pmovmskb %xmm3, %edx
 | 
			
		||||
	test	%edx, %edx
 | 
			
		||||
	lea	16(%eax), %eax
 | 
			
		||||
	jnz	L(exit)
 | 
			
		||||
 | 
			
		||||
	pcmpeqb	(%eax), %xmm0
 | 
			
		||||
	pmovmskb %xmm0, %edx
 | 
			
		||||
	test	%edx, %edx
 | 
			
		||||
	lea	16(%eax), %eax
 | 
			
		||||
	jnz	L(exit)
 | 
			
		||||
 | 
			
		||||
	pcmpeqb	(%eax), %xmm1
 | 
			
		||||
	pmovmskb %xmm1, %edx
 | 
			
		||||
	test	%edx, %edx
 | 
			
		||||
	lea	16(%eax), %eax
 | 
			
		||||
	jnz	L(exit)
 | 
			
		||||
 | 
			
		||||
	pcmpeqb	(%eax), %xmm2
 | 
			
		||||
	pmovmskb %xmm2, %edx
 | 
			
		||||
	test	%edx, %edx
 | 
			
		||||
	lea	16(%eax), %eax
 | 
			
		||||
	jnz	L(exit)
 | 
			
		||||
 | 
			
		||||
	pcmpeqb	(%eax), %xmm3
 | 
			
		||||
	pmovmskb %xmm3, %edx
 | 
			
		||||
	test	%edx, %edx
 | 
			
		||||
	lea	16(%eax), %eax
 | 
			
		||||
	jnz	L(exit)
 | 
			
		||||
 | 
			
		||||
	and	$-0x40, %eax
 | 
			
		||||
	PUSH (%esi)
 | 
			
		||||
	PUSH (%edi)
 | 
			
		||||
	PUSH (%ebx)
 | 
			
		||||
	PUSH (%ebp)
 | 
			
		||||
	xor	%ebp, %ebp
 | 
			
		||||
L(aligned_64):
 | 
			
		||||
	pcmpeqb	(%eax), %xmm0
 | 
			
		||||
	pcmpeqb	16(%eax), %xmm1
 | 
			
		||||
	pcmpeqb	32(%eax), %xmm2
 | 
			
		||||
	pcmpeqb	48(%eax), %xmm3
 | 
			
		||||
	pmovmskb %xmm0, %edx
 | 
			
		||||
	pmovmskb %xmm1, %esi
 | 
			
		||||
	pmovmskb %xmm2, %edi
 | 
			
		||||
	pmovmskb %xmm3, %ebx
 | 
			
		||||
	or	%edx, %ebp
 | 
			
		||||
	or	%esi, %ebp
 | 
			
		||||
	or	%edi, %ebp
 | 
			
		||||
	or	%ebx, %ebp
 | 
			
		||||
	lea	64(%eax), %eax
 | 
			
		||||
	jz	L(aligned_64)
 | 
			
		||||
L(48leave):
 | 
			
		||||
	test	%edx, %edx
 | 
			
		||||
	jnz	L(aligned_64_exit_16)
 | 
			
		||||
	test	%esi, %esi
 | 
			
		||||
	jnz	L(aligned_64_exit_32)
 | 
			
		||||
	test	%edi, %edi
 | 
			
		||||
	jnz	L(aligned_64_exit_48)
 | 
			
		||||
	mov	%ebx, %edx
 | 
			
		||||
	lea	(%eax), %eax
 | 
			
		||||
	jmp	L(aligned_64_exit)
 | 
			
		||||
L(aligned_64_exit_48):
 | 
			
		||||
	lea	-16(%eax), %eax
 | 
			
		||||
	mov	%edi, %edx
 | 
			
		||||
	jmp	L(aligned_64_exit)
 | 
			
		||||
L(aligned_64_exit_32):
 | 
			
		||||
	lea	-32(%eax), %eax
 | 
			
		||||
	mov	%esi, %edx
 | 
			
		||||
	jmp	L(aligned_64_exit)
 | 
			
		||||
L(aligned_64_exit_16):
 | 
			
		||||
	lea	-48(%eax), %eax
 | 
			
		||||
L(aligned_64_exit):
 | 
			
		||||
	POP (%ebp)
 | 
			
		||||
	POP (%ebx)
 | 
			
		||||
	POP (%edi)
 | 
			
		||||
	POP (%esi)
 | 
			
		||||
L(exit):
 | 
			
		||||
	sub	%ecx, %eax
 | 
			
		||||
	test	%dl, %dl
 | 
			
		||||
	jz	L(exit_high)
 | 
			
		||||
	test	$0x01, %dl
 | 
			
		||||
	jnz	L(exit_tail0)
 | 
			
		||||
 | 
			
		||||
	test	$0x02, %dl
 | 
			
		||||
	jnz	L(exit_tail1)
 | 
			
		||||
 | 
			
		||||
	test	$0x04, %dl
 | 
			
		||||
	jnz	L(exit_tail2)
 | 
			
		||||
 | 
			
		||||
	test	$0x08, %dl
 | 
			
		||||
	jnz	L(exit_tail3)
 | 
			
		||||
 | 
			
		||||
	test	$0x10, %dl
 | 
			
		||||
	jnz	L(exit_tail4)
 | 
			
		||||
 | 
			
		||||
	test	$0x20, %dl
 | 
			
		||||
	jnz	L(exit_tail5)
 | 
			
		||||
 | 
			
		||||
	test	$0x40, %dl
 | 
			
		||||
	jnz	L(exit_tail6)
 | 
			
		||||
	add	$7, %eax
 | 
			
		||||
L(exit_tail0):
 | 
			
		||||
	RETURN
 | 
			
		||||
 | 
			
		||||
L(exit_high):
 | 
			
		||||
	add	$8, %eax
 | 
			
		||||
	test	$0x01, %dh
 | 
			
		||||
	jnz	L(exit_tail0)
 | 
			
		||||
 | 
			
		||||
	test	$0x02, %dh
 | 
			
		||||
	jnz	L(exit_tail1)
 | 
			
		||||
 | 
			
		||||
	test	$0x04, %dh
 | 
			
		||||
	jnz	L(exit_tail2)
 | 
			
		||||
 | 
			
		||||
	test	$0x08, %dh
 | 
			
		||||
	jnz	L(exit_tail3)
 | 
			
		||||
 | 
			
		||||
	test	$0x10, %dh
 | 
			
		||||
	jnz	L(exit_tail4)
 | 
			
		||||
 | 
			
		||||
	test	$0x20, %dh
 | 
			
		||||
	jnz	L(exit_tail5)
 | 
			
		||||
 | 
			
		||||
	test	$0x40, %dh
 | 
			
		||||
	jnz	L(exit_tail6)
 | 
			
		||||
	add	$7, %eax
 | 
			
		||||
	RETURN
 | 
			
		||||
 | 
			
		||||
	.p2align 4
 | 
			
		||||
L(exit_tail1):
 | 
			
		||||
	add	$1, %eax
 | 
			
		||||
	RETURN
 | 
			
		||||
 | 
			
		||||
L(exit_tail2):
 | 
			
		||||
	add	$2, %eax
 | 
			
		||||
	RETURN
 | 
			
		||||
 | 
			
		||||
L(exit_tail3):
 | 
			
		||||
	add	$3, %eax
 | 
			
		||||
	RETURN
 | 
			
		||||
 | 
			
		||||
L(exit_tail4):
 | 
			
		||||
	add	$4, %eax
 | 
			
		||||
	RETURN
 | 
			
		||||
 | 
			
		||||
L(exit_tail5):
 | 
			
		||||
	add	$5, %eax
 | 
			
		||||
	RETURN
 | 
			
		||||
 | 
			
		||||
L(exit_tail6):
 | 
			
		||||
	add	$6, %eax
 | 
			
		||||
	RETURN
 | 
			
		||||
 | 
			
		||||
L(exit_tail7):
 | 
			
		||||
	add	$7, %eax
 | 
			
		||||
	RETURN
 | 
			
		||||
 | 
			
		||||
L(exit_tail8):
 | 
			
		||||
	add	$8, %eax
 | 
			
		||||
	RETURN
 | 
			
		||||
 | 
			
		||||
L(exit_tail9):
 | 
			
		||||
	add	$9, %eax
 | 
			
		||||
	RETURN
 | 
			
		||||
 | 
			
		||||
L(exit_tail10):
 | 
			
		||||
	add	$10, %eax
 | 
			
		||||
	RETURN
 | 
			
		||||
 | 
			
		||||
L(exit_tail11):
 | 
			
		||||
	add	$11, %eax
 | 
			
		||||
	RETURN
 | 
			
		||||
 | 
			
		||||
L(exit_tail12):
 | 
			
		||||
	add	$12, %eax
 | 
			
		||||
	RETURN
 | 
			
		||||
 | 
			
		||||
L(exit_tail13):
 | 
			
		||||
	add	$13, %eax
 | 
			
		||||
	RETURN
 | 
			
		||||
 | 
			
		||||
L(exit_tail14):
 | 
			
		||||
	add	$14, %eax
 | 
			
		||||
	RETURN
 | 
			
		||||
 | 
			
		||||
L(exit_tail15):
 | 
			
		||||
	add	$15, %eax
 | 
			
		||||
	ret
 | 
			
		||||
 | 
			
		||||
END (STRLEN)
 | 
			
		||||
@@ -53,13 +53,21 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef cfi_restore
 | 
			
		||||
# define cfi_restore(reg)		.cfi_restore (reg)
 | 
			
		||||
# define cfi_restore(reg)		.cfi_restore reg
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef cfi_adjust_cfa_offset
 | 
			
		||||
# define cfi_adjust_cfa_offset(off)	.cfi_adjust_cfa_offset off
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef cfi_remember_state
 | 
			
		||||
# define cfi_remember_state		.cfi_remember_state
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef cfi_restore_state
 | 
			
		||||
# define cfi_restore_state		.cfi_restore_state
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef ENTRY
 | 
			
		||||
# define ENTRY(name)			\
 | 
			
		||||
	.type name,  @function; 	\
 | 
			
		||||
@@ -91,8 +99,7 @@ name:					\
 | 
			
		||||
#define BLK2		BLK1+4
 | 
			
		||||
#define LEN		BLK2+4
 | 
			
		||||
#define RETURN_END	POP (%edi); POP (%esi); POP (%ebx); ret
 | 
			
		||||
#define RETURN		RETURN_END; CFI_PUSH (%ebx); CFI_PUSH (%edi); \
 | 
			
		||||
			CFI_PUSH (%esi)
 | 
			
		||||
#define RETURN		RETURN_END; cfi_restore_state; cfi_remember_state
 | 
			
		||||
 | 
			
		||||
	.section .text.ssse3,"ax",@progbits
 | 
			
		||||
ENTRY (MEMCMP)
 | 
			
		||||
@@ -131,6 +138,7 @@ L(48bytesormore):
 | 
			
		||||
	PUSH (%ebx)
 | 
			
		||||
	PUSH (%esi)
 | 
			
		||||
	PUSH (%edi)
 | 
			
		||||
	cfi_remember_state
 | 
			
		||||
	movdqu    (%eax), %xmm3
 | 
			
		||||
	movdqu    (%edx), %xmm0
 | 
			
		||||
	movl	%eax, %edi
 | 
			
		||||
@@ -211,8 +219,8 @@ L(shr_0):
 | 
			
		||||
	POP (%esi)
 | 
			
		||||
	jmp	L(less48bytes)
 | 
			
		||||
 | 
			
		||||
	CFI_PUSH (%esi)
 | 
			
		||||
	CFI_PUSH (%edi)
 | 
			
		||||
	cfi_restore_state
 | 
			
		||||
	cfi_remember_state
 | 
			
		||||
	ALIGN (4)
 | 
			
		||||
L(shr_0_gobble):
 | 
			
		||||
	lea	-48(%ecx), %ecx
 | 
			
		||||
@@ -257,8 +265,8 @@ L(shr_0_gobble_loop_next):
 | 
			
		||||
	POP (%esi)
 | 
			
		||||
	jmp	L(less48bytes)
 | 
			
		||||
 | 
			
		||||
	CFI_PUSH (%esi)
 | 
			
		||||
	CFI_PUSH (%edi)
 | 
			
		||||
	cfi_restore_state
 | 
			
		||||
	cfi_remember_state
 | 
			
		||||
	ALIGN (4)
 | 
			
		||||
L(shr_1):
 | 
			
		||||
	cmp	$80, %ecx
 | 
			
		||||
@@ -287,8 +295,8 @@ L(shr_1):
 | 
			
		||||
	POP (%esi)
 | 
			
		||||
	jmp	L(less48bytes)
 | 
			
		||||
 | 
			
		||||
	CFI_PUSH (%esi)
 | 
			
		||||
	CFI_PUSH (%edi)
 | 
			
		||||
	cfi_restore_state
 | 
			
		||||
	cfi_remember_state
 | 
			
		||||
	ALIGN (4)
 | 
			
		||||
L(shr_1_gobble):
 | 
			
		||||
	sub	$32, %ecx
 | 
			
		||||
@@ -340,8 +348,8 @@ L(shr_1_gobble_next):
 | 
			
		||||
	POP (%esi)
 | 
			
		||||
	jmp	L(less48bytes)
 | 
			
		||||
 | 
			
		||||
	CFI_PUSH (%esi)
 | 
			
		||||
	CFI_PUSH (%edi)
 | 
			
		||||
	cfi_restore_state
 | 
			
		||||
	cfi_remember_state
 | 
			
		||||
	ALIGN (4)
 | 
			
		||||
L(shr_2):
 | 
			
		||||
	cmp	$80, %ecx
 | 
			
		||||
@@ -370,8 +378,8 @@ L(shr_2):
 | 
			
		||||
	POP (%esi)
 | 
			
		||||
	jmp	L(less48bytes)
 | 
			
		||||
 | 
			
		||||
	CFI_PUSH (%esi)
 | 
			
		||||
	CFI_PUSH (%edi)
 | 
			
		||||
	cfi_restore_state
 | 
			
		||||
	cfi_remember_state
 | 
			
		||||
	ALIGN (4)
 | 
			
		||||
L(shr_2_gobble):
 | 
			
		||||
	sub	$32, %ecx
 | 
			
		||||
@@ -423,8 +431,8 @@ L(shr_2_gobble_next):
 | 
			
		||||
	POP (%esi)
 | 
			
		||||
	jmp	L(less48bytes)
 | 
			
		||||
 | 
			
		||||
	CFI_PUSH (%esi)
 | 
			
		||||
	CFI_PUSH (%edi)
 | 
			
		||||
	cfi_restore_state
 | 
			
		||||
	cfi_remember_state
 | 
			
		||||
	ALIGN (4)
 | 
			
		||||
L(shr_3):
 | 
			
		||||
	cmp	$80, %ecx
 | 
			
		||||
@@ -453,8 +461,8 @@ L(shr_3):
 | 
			
		||||
	POP (%esi)
 | 
			
		||||
	jmp	L(less48bytes)
 | 
			
		||||
 | 
			
		||||
	CFI_PUSH (%esi)
 | 
			
		||||
	CFI_PUSH (%edi)
 | 
			
		||||
	cfi_restore_state
 | 
			
		||||
	cfi_remember_state
 | 
			
		||||
	ALIGN (4)
 | 
			
		||||
L(shr_3_gobble):
 | 
			
		||||
	sub	$32, %ecx
 | 
			
		||||
@@ -506,8 +514,8 @@ L(shr_3_gobble_next):
 | 
			
		||||
	POP (%esi)
 | 
			
		||||
	jmp	L(less48bytes)
 | 
			
		||||
 | 
			
		||||
	CFI_PUSH (%esi)
 | 
			
		||||
	CFI_PUSH (%edi)
 | 
			
		||||
	cfi_restore_state
 | 
			
		||||
	cfi_remember_state
 | 
			
		||||
	ALIGN (4)
 | 
			
		||||
L(shr_4):
 | 
			
		||||
	cmp	$80, %ecx
 | 
			
		||||
@@ -536,8 +544,8 @@ L(shr_4):
 | 
			
		||||
	POP (%esi)
 | 
			
		||||
	jmp	L(less48bytes)
 | 
			
		||||
 | 
			
		||||
	CFI_PUSH (%esi)
 | 
			
		||||
	CFI_PUSH (%edi)
 | 
			
		||||
	cfi_restore_state
 | 
			
		||||
	cfi_remember_state
 | 
			
		||||
	ALIGN (4)
 | 
			
		||||
L(shr_4_gobble):
 | 
			
		||||
	sub	$32, %ecx
 | 
			
		||||
@@ -589,8 +597,8 @@ L(shr_4_gobble_next):
 | 
			
		||||
	POP (%esi)
 | 
			
		||||
	jmp	L(less48bytes)
 | 
			
		||||
 | 
			
		||||
	CFI_PUSH (%esi)
 | 
			
		||||
	CFI_PUSH (%edi)
 | 
			
		||||
	cfi_restore_state
 | 
			
		||||
	cfi_remember_state
 | 
			
		||||
	ALIGN (4)
 | 
			
		||||
L(shr_5):
 | 
			
		||||
	cmp	$80, %ecx
 | 
			
		||||
@@ -619,8 +627,8 @@ L(shr_5):
 | 
			
		||||
	POP (%esi)
 | 
			
		||||
	jmp	L(less48bytes)
 | 
			
		||||
 | 
			
		||||
	CFI_PUSH (%esi)
 | 
			
		||||
	CFI_PUSH (%edi)
 | 
			
		||||
	cfi_restore_state
 | 
			
		||||
	cfi_remember_state
 | 
			
		||||
	ALIGN (4)
 | 
			
		||||
L(shr_5_gobble):
 | 
			
		||||
	sub	$32, %ecx
 | 
			
		||||
@@ -672,8 +680,8 @@ L(shr_5_gobble_next):
 | 
			
		||||
	POP (%esi)
 | 
			
		||||
	jmp	L(less48bytes)
 | 
			
		||||
 | 
			
		||||
	CFI_PUSH (%esi)
 | 
			
		||||
	CFI_PUSH (%edi)
 | 
			
		||||
	cfi_restore_state
 | 
			
		||||
	cfi_remember_state
 | 
			
		||||
	ALIGN (4)
 | 
			
		||||
L(shr_6):
 | 
			
		||||
	cmp	$80, %ecx
 | 
			
		||||
@@ -702,8 +710,8 @@ L(shr_6):
 | 
			
		||||
	POP (%esi)
 | 
			
		||||
	jmp	L(less48bytes)
 | 
			
		||||
 | 
			
		||||
	CFI_PUSH (%esi)
 | 
			
		||||
	CFI_PUSH (%edi)
 | 
			
		||||
	cfi_restore_state
 | 
			
		||||
	cfi_remember_state
 | 
			
		||||
	ALIGN (4)
 | 
			
		||||
L(shr_6_gobble):
 | 
			
		||||
	sub	$32, %ecx
 | 
			
		||||
@@ -755,8 +763,8 @@ L(shr_6_gobble_next):
 | 
			
		||||
	POP (%esi)
 | 
			
		||||
	jmp	L(less48bytes)
 | 
			
		||||
 | 
			
		||||
	CFI_PUSH (%esi)
 | 
			
		||||
	CFI_PUSH (%edi)
 | 
			
		||||
	cfi_restore_state
 | 
			
		||||
	cfi_remember_state
 | 
			
		||||
	ALIGN (4)
 | 
			
		||||
L(shr_7):
 | 
			
		||||
	cmp	$80, %ecx
 | 
			
		||||
@@ -785,8 +793,8 @@ L(shr_7):
 | 
			
		||||
	POP (%esi)
 | 
			
		||||
	jmp	L(less48bytes)
 | 
			
		||||
 | 
			
		||||
	CFI_PUSH (%esi)
 | 
			
		||||
	CFI_PUSH (%edi)
 | 
			
		||||
	cfi_restore_state
 | 
			
		||||
	cfi_remember_state
 | 
			
		||||
	ALIGN (4)
 | 
			
		||||
L(shr_7_gobble):
 | 
			
		||||
	sub	$32, %ecx
 | 
			
		||||
@@ -838,8 +846,8 @@ L(shr_7_gobble_next):
 | 
			
		||||
	POP (%esi)
 | 
			
		||||
	jmp	L(less48bytes)
 | 
			
		||||
 | 
			
		||||
	CFI_PUSH (%esi)
 | 
			
		||||
	CFI_PUSH (%edi)
 | 
			
		||||
	cfi_restore_state
 | 
			
		||||
	cfi_remember_state
 | 
			
		||||
	ALIGN (4)
 | 
			
		||||
L(shr_8):
 | 
			
		||||
	cmp	$80, %ecx
 | 
			
		||||
@@ -868,8 +876,8 @@ L(shr_8):
 | 
			
		||||
	POP (%esi)
 | 
			
		||||
	jmp	L(less48bytes)
 | 
			
		||||
 | 
			
		||||
	CFI_PUSH (%esi)
 | 
			
		||||
	CFI_PUSH (%edi)
 | 
			
		||||
	cfi_restore_state
 | 
			
		||||
	cfi_remember_state
 | 
			
		||||
	ALIGN (4)
 | 
			
		||||
L(shr_8_gobble):
 | 
			
		||||
	sub	$32, %ecx
 | 
			
		||||
@@ -921,8 +929,8 @@ L(shr_8_gobble_next):
 | 
			
		||||
	POP (%esi)
 | 
			
		||||
	jmp	L(less48bytes)
 | 
			
		||||
 | 
			
		||||
	CFI_PUSH (%esi)
 | 
			
		||||
	CFI_PUSH (%edi)
 | 
			
		||||
	cfi_restore_state
 | 
			
		||||
	cfi_remember_state
 | 
			
		||||
	ALIGN (4)
 | 
			
		||||
L(shr_9):
 | 
			
		||||
	cmp	$80, %ecx
 | 
			
		||||
@@ -951,8 +959,8 @@ L(shr_9):
 | 
			
		||||
	POP (%esi)
 | 
			
		||||
	jmp	L(less48bytes)
 | 
			
		||||
 | 
			
		||||
	CFI_PUSH (%esi)
 | 
			
		||||
	CFI_PUSH (%edi)
 | 
			
		||||
	cfi_restore_state
 | 
			
		||||
	cfi_remember_state
 | 
			
		||||
	ALIGN (4)
 | 
			
		||||
L(shr_9_gobble):
 | 
			
		||||
	sub	$32, %ecx
 | 
			
		||||
@@ -1004,8 +1012,8 @@ L(shr_9_gobble_next):
 | 
			
		||||
	POP (%esi)
 | 
			
		||||
	jmp	L(less48bytes)
 | 
			
		||||
 | 
			
		||||
	CFI_PUSH (%esi)
 | 
			
		||||
	CFI_PUSH (%edi)
 | 
			
		||||
	cfi_restore_state
 | 
			
		||||
	cfi_remember_state
 | 
			
		||||
	ALIGN (4)
 | 
			
		||||
L(shr_10):
 | 
			
		||||
	cmp	$80, %ecx
 | 
			
		||||
@@ -1034,8 +1042,8 @@ L(shr_10):
 | 
			
		||||
	POP (%esi)
 | 
			
		||||
	jmp	L(less48bytes)
 | 
			
		||||
 | 
			
		||||
	CFI_PUSH (%esi)
 | 
			
		||||
	CFI_PUSH (%edi)
 | 
			
		||||
	cfi_restore_state
 | 
			
		||||
	cfi_remember_state
 | 
			
		||||
	ALIGN (4)
 | 
			
		||||
L(shr_10_gobble):
 | 
			
		||||
	sub	$32, %ecx
 | 
			
		||||
@@ -1087,8 +1095,8 @@ L(shr_10_gobble_next):
 | 
			
		||||
	POP (%esi)
 | 
			
		||||
	jmp	L(less48bytes)
 | 
			
		||||
 | 
			
		||||
	CFI_PUSH (%esi)
 | 
			
		||||
	CFI_PUSH (%edi)
 | 
			
		||||
	cfi_restore_state
 | 
			
		||||
	cfi_remember_state
 | 
			
		||||
	ALIGN (4)
 | 
			
		||||
L(shr_11):
 | 
			
		||||
	cmp	$80, %ecx
 | 
			
		||||
@@ -1117,8 +1125,8 @@ L(shr_11):
 | 
			
		||||
	POP (%esi)
 | 
			
		||||
	jmp	L(less48bytes)
 | 
			
		||||
 | 
			
		||||
	CFI_PUSH (%esi)
 | 
			
		||||
	CFI_PUSH (%edi)
 | 
			
		||||
	cfi_restore_state
 | 
			
		||||
	cfi_remember_state
 | 
			
		||||
	ALIGN (4)
 | 
			
		||||
L(shr_11_gobble):
 | 
			
		||||
	sub	$32, %ecx
 | 
			
		||||
@@ -1170,8 +1178,8 @@ L(shr_11_gobble_next):
 | 
			
		||||
	POP (%esi)
 | 
			
		||||
	jmp	L(less48bytes)
 | 
			
		||||
 | 
			
		||||
	CFI_PUSH (%esi)
 | 
			
		||||
	CFI_PUSH (%edi)
 | 
			
		||||
	cfi_restore_state
 | 
			
		||||
	cfi_remember_state
 | 
			
		||||
	ALIGN (4)
 | 
			
		||||
L(shr_12):
 | 
			
		||||
	cmp	$80, %ecx
 | 
			
		||||
@@ -1200,8 +1208,8 @@ L(shr_12):
 | 
			
		||||
	POP (%esi)
 | 
			
		||||
	jmp	L(less48bytes)
 | 
			
		||||
 | 
			
		||||
	CFI_PUSH (%esi)
 | 
			
		||||
	CFI_PUSH (%edi)
 | 
			
		||||
	cfi_restore_state
 | 
			
		||||
	cfi_remember_state
 | 
			
		||||
	ALIGN (4)
 | 
			
		||||
L(shr_12_gobble):
 | 
			
		||||
	sub	$32, %ecx
 | 
			
		||||
@@ -1253,8 +1261,8 @@ L(shr_12_gobble_next):
 | 
			
		||||
	POP (%esi)
 | 
			
		||||
	jmp	L(less48bytes)
 | 
			
		||||
 | 
			
		||||
	CFI_PUSH (%esi)
 | 
			
		||||
	CFI_PUSH (%edi)
 | 
			
		||||
	cfi_restore_state
 | 
			
		||||
	cfi_remember_state
 | 
			
		||||
	ALIGN (4)
 | 
			
		||||
L(shr_13):
 | 
			
		||||
	cmp	$80, %ecx
 | 
			
		||||
@@ -1283,8 +1291,8 @@ L(shr_13):
 | 
			
		||||
	POP (%esi)
 | 
			
		||||
	jmp	L(less48bytes)
 | 
			
		||||
 | 
			
		||||
	CFI_PUSH (%esi)
 | 
			
		||||
	CFI_PUSH (%edi)
 | 
			
		||||
	cfi_restore_state
 | 
			
		||||
	cfi_remember_state
 | 
			
		||||
	ALIGN (4)
 | 
			
		||||
L(shr_13_gobble):
 | 
			
		||||
	sub	$32, %ecx
 | 
			
		||||
@@ -1336,8 +1344,8 @@ L(shr_13_gobble_next):
 | 
			
		||||
	POP (%esi)
 | 
			
		||||
	jmp	L(less48bytes)
 | 
			
		||||
 | 
			
		||||
	CFI_PUSH (%esi)
 | 
			
		||||
	CFI_PUSH (%edi)
 | 
			
		||||
	cfi_restore_state
 | 
			
		||||
	cfi_remember_state
 | 
			
		||||
	ALIGN (4)
 | 
			
		||||
L(shr_14):
 | 
			
		||||
	cmp	$80, %ecx
 | 
			
		||||
@@ -1366,8 +1374,8 @@ L(shr_14):
 | 
			
		||||
	POP (%esi)
 | 
			
		||||
	jmp	L(less48bytes)
 | 
			
		||||
 | 
			
		||||
	CFI_PUSH (%esi)
 | 
			
		||||
	CFI_PUSH (%edi)
 | 
			
		||||
	cfi_restore_state
 | 
			
		||||
	cfi_remember_state
 | 
			
		||||
	ALIGN (4)
 | 
			
		||||
L(shr_14_gobble):
 | 
			
		||||
	sub	$32, %ecx
 | 
			
		||||
@@ -1419,8 +1427,8 @@ L(shr_14_gobble_next):
 | 
			
		||||
	POP (%esi)
 | 
			
		||||
	jmp	L(less48bytes)
 | 
			
		||||
 | 
			
		||||
	CFI_PUSH (%esi)
 | 
			
		||||
	CFI_PUSH (%edi)
 | 
			
		||||
	cfi_restore_state
 | 
			
		||||
	cfi_remember_state
 | 
			
		||||
	ALIGN (4)
 | 
			
		||||
L(shr_15):
 | 
			
		||||
	cmp	$80, %ecx
 | 
			
		||||
@@ -1449,8 +1457,8 @@ L(shr_15):
 | 
			
		||||
	POP (%esi)
 | 
			
		||||
	jmp	L(less48bytes)
 | 
			
		||||
 | 
			
		||||
	CFI_PUSH (%esi)
 | 
			
		||||
	CFI_PUSH (%edi)
 | 
			
		||||
	cfi_restore_state
 | 
			
		||||
	cfi_remember_state
 | 
			
		||||
	ALIGN (4)
 | 
			
		||||
L(shr_15_gobble):
 | 
			
		||||
	sub	$32, %ecx
 | 
			
		||||
@@ -1502,8 +1510,8 @@ L(shr_15_gobble_next):
 | 
			
		||||
	POP (%esi)
 | 
			
		||||
	jmp	L(less48bytes)
 | 
			
		||||
 | 
			
		||||
	CFI_PUSH (%esi)
 | 
			
		||||
	CFI_PUSH (%edi)
 | 
			
		||||
	cfi_restore_state
 | 
			
		||||
	cfi_remember_state
 | 
			
		||||
	ALIGN (4)
 | 
			
		||||
L(exit):
 | 
			
		||||
	pmovmskb %xmm1, %ebx
 | 
			
		||||
@@ -53,13 +53,21 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef cfi_restore
 | 
			
		||||
# define cfi_restore(reg)		.cfi_restore (reg)
 | 
			
		||||
# define cfi_restore(reg)		.cfi_restore reg
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef cfi_adjust_cfa_offset
 | 
			
		||||
# define cfi_adjust_cfa_offset(off)	.cfi_adjust_cfa_offset off
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef cfi_remember_state
 | 
			
		||||
# define cfi_remember_state		.cfi_remember_state
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef cfi_restore_state
 | 
			
		||||
# define cfi_restore_state		.cfi_restore_state
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef ENTRY
 | 
			
		||||
# define ENTRY(name)			\
 | 
			
		||||
	.type name,  @function; 	\
 | 
			
		||||
@@ -118,8 +126,8 @@ name:					\
 | 
			
		||||
    jmp		*%ebx
 | 
			
		||||
 | 
			
		||||
# define BRANCH_TO_JMPTBL_ENTRY_VALUE(TABLE)			\
 | 
			
		||||
    addl	$(TABLE - .), %ebx	
 | 
			
		||||
			
 | 
			
		||||
    addl	$(TABLE - .), %ebx
 | 
			
		||||
 | 
			
		||||
# define BRANCH_TO_JMPTBL_ENTRY_TAIL(TABLE, INDEX, SCALE)	\
 | 
			
		||||
    addl	(%ebx,INDEX,SCALE), %ebx;			\
 | 
			
		||||
    /* We loaded the jump table.  Go.  */			\
 | 
			
		||||
@@ -146,7 +154,7 @@ __i686.get_pc_thunk.bx:
 | 
			
		||||
# define BRANCH_TO_JMPTBL_ENTRY(TABLE, INDEX, SCALE)		\
 | 
			
		||||
    jmp		*TABLE(,INDEX,SCALE)
 | 
			
		||||
 | 
			
		||||
# define BRANCH_TO_JMPTBL_ENTRY_VALUE(TABLE)			
 | 
			
		||||
# define BRANCH_TO_JMPTBL_ENTRY_VALUE(TABLE)
 | 
			
		||||
 | 
			
		||||
# define BRANCH_TO_JMPTBL_ENTRY_TAIL(TABLE, INDEX, SCALE)		\
 | 
			
		||||
    jmp		*TABLE(,INDEX,SCALE)
 | 
			
		||||
@@ -198,6 +206,7 @@ L(48bytesormore):
 | 
			
		||||
	movl	%edx, %edi
 | 
			
		||||
	and	$-16, %edx
 | 
			
		||||
	PUSH (%esi)
 | 
			
		||||
	cfi_remember_state
 | 
			
		||||
	add	$16, %edx
 | 
			
		||||
	movl	%edi, %esi
 | 
			
		||||
	sub	%edx, %edi
 | 
			
		||||
@@ -223,6 +232,8 @@ L(48bytesormore):
 | 
			
		||||
 | 
			
		||||
	BRANCH_TO_JMPTBL_ENTRY (L(shl_table), %edi, 4)
 | 
			
		||||
 | 
			
		||||
	cfi_restore_state
 | 
			
		||||
	cfi_remember_state
 | 
			
		||||
	ALIGN (4)
 | 
			
		||||
L(shl_0):
 | 
			
		||||
	movdqu	%xmm0, (%esi)
 | 
			
		||||
@@ -270,6 +281,7 @@ L(shl_0_end):
 | 
			
		||||
	POP (%edi)
 | 
			
		||||
	BRANCH_TO_JMPTBL_ENTRY (L(table_48bytes_fwd), %ecx, 4)
 | 
			
		||||
 | 
			
		||||
	CFI_PUSH (%edi)
 | 
			
		||||
L(shl_0_gobble):
 | 
			
		||||
 | 
			
		||||
#ifdef DATA_CACHE_SIZE_HALF
 | 
			
		||||
@@ -419,7 +431,8 @@ L(shl_0_mem_less_16bytes):
 | 
			
		||||
	add	%ecx, %eax
 | 
			
		||||
	BRANCH_TO_JMPTBL_ENTRY (L(table_48bytes_fwd), %ecx, 4)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	cfi_restore_state
 | 
			
		||||
	cfi_remember_state
 | 
			
		||||
	ALIGN (4)
 | 
			
		||||
L(shl_1):
 | 
			
		||||
	BRANCH_TO_JMPTBL_ENTRY_VALUE(L(table_48bytes_fwd))
 | 
			
		||||
@@ -463,6 +476,8 @@ L(shl_1_end):
 | 
			
		||||
	POP (%edi)
 | 
			
		||||
	BRANCH_TO_JMPTBL_ENTRY_TAIL(L(table_48bytes_fwd), %ecx, 4)
 | 
			
		||||
 | 
			
		||||
	cfi_restore_state
 | 
			
		||||
	cfi_remember_state
 | 
			
		||||
	ALIGN (4)
 | 
			
		||||
L(shl_2):
 | 
			
		||||
	BRANCH_TO_JMPTBL_ENTRY_VALUE(L(table_48bytes_fwd))
 | 
			
		||||
@@ -506,6 +521,8 @@ L(shl_2_end):
 | 
			
		||||
	POP (%edi)
 | 
			
		||||
	BRANCH_TO_JMPTBL_ENTRY_TAIL(L(table_48bytes_fwd), %ecx, 4)
 | 
			
		||||
 | 
			
		||||
	cfi_restore_state
 | 
			
		||||
	cfi_remember_state
 | 
			
		||||
	ALIGN (4)
 | 
			
		||||
L(shl_3):
 | 
			
		||||
	BRANCH_TO_JMPTBL_ENTRY_VALUE(L(table_48bytes_fwd))
 | 
			
		||||
@@ -549,6 +566,8 @@ L(shl_3_end):
 | 
			
		||||
	POP (%edi)
 | 
			
		||||
	BRANCH_TO_JMPTBL_ENTRY_TAIL(L(table_48bytes_fwd), %ecx, 4)
 | 
			
		||||
 | 
			
		||||
	cfi_restore_state
 | 
			
		||||
	cfi_remember_state
 | 
			
		||||
	ALIGN (4)
 | 
			
		||||
L(shl_4):
 | 
			
		||||
	BRANCH_TO_JMPTBL_ENTRY_VALUE(L(table_48bytes_fwd))
 | 
			
		||||
@@ -592,6 +611,8 @@ L(shl_4_end):
 | 
			
		||||
	POP (%edi)
 | 
			
		||||
	BRANCH_TO_JMPTBL_ENTRY_TAIL(L(table_48bytes_fwd), %ecx, 4)
 | 
			
		||||
 | 
			
		||||
	cfi_restore_state
 | 
			
		||||
	cfi_remember_state
 | 
			
		||||
	ALIGN (4)
 | 
			
		||||
L(shl_5):
 | 
			
		||||
	BRANCH_TO_JMPTBL_ENTRY_VALUE(L(table_48bytes_fwd))
 | 
			
		||||
@@ -635,7 +656,8 @@ L(shl_5_end):
 | 
			
		||||
	POP (%edi)
 | 
			
		||||
	BRANCH_TO_JMPTBL_ENTRY_TAIL(L(table_48bytes_fwd), %ecx, 4)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	cfi_restore_state
 | 
			
		||||
	cfi_remember_state
 | 
			
		||||
	ALIGN (4)
 | 
			
		||||
L(shl_6):
 | 
			
		||||
	BRANCH_TO_JMPTBL_ENTRY_VALUE(L(table_48bytes_fwd))
 | 
			
		||||
@@ -679,6 +701,8 @@ L(shl_6_end):
 | 
			
		||||
	POP (%edi)
 | 
			
		||||
	BRANCH_TO_JMPTBL_ENTRY_TAIL(L(table_48bytes_fwd), %ecx, 4)
 | 
			
		||||
 | 
			
		||||
	cfi_restore_state
 | 
			
		||||
	cfi_remember_state
 | 
			
		||||
	ALIGN (4)
 | 
			
		||||
L(shl_7):
 | 
			
		||||
	BRANCH_TO_JMPTBL_ENTRY_VALUE(L(table_48bytes_fwd))
 | 
			
		||||
@@ -722,6 +746,8 @@ L(shl_7_end):
 | 
			
		||||
	POP (%edi)
 | 
			
		||||
	BRANCH_TO_JMPTBL_ENTRY_TAIL(L(table_48bytes_fwd), %ecx, 4)
 | 
			
		||||
 | 
			
		||||
	cfi_restore_state
 | 
			
		||||
	cfi_remember_state
 | 
			
		||||
	ALIGN (4)
 | 
			
		||||
L(shl_8):
 | 
			
		||||
	BRANCH_TO_JMPTBL_ENTRY_VALUE(L(table_48bytes_fwd))
 | 
			
		||||
@@ -765,6 +791,8 @@ L(shl_8_end):
 | 
			
		||||
	POP (%edi)
 | 
			
		||||
	BRANCH_TO_JMPTBL_ENTRY_TAIL(L(table_48bytes_fwd), %ecx, 4)
 | 
			
		||||
 | 
			
		||||
	cfi_restore_state
 | 
			
		||||
	cfi_remember_state
 | 
			
		||||
	ALIGN (4)
 | 
			
		||||
L(shl_9):
 | 
			
		||||
	BRANCH_TO_JMPTBL_ENTRY_VALUE(L(table_48bytes_fwd))
 | 
			
		||||
@@ -808,6 +836,8 @@ L(shl_9_end):
 | 
			
		||||
	POP (%edi)
 | 
			
		||||
	BRANCH_TO_JMPTBL_ENTRY_TAIL(L(table_48bytes_fwd), %ecx, 4)
 | 
			
		||||
 | 
			
		||||
	cfi_restore_state
 | 
			
		||||
	cfi_remember_state
 | 
			
		||||
	ALIGN (4)
 | 
			
		||||
L(shl_10):
 | 
			
		||||
	BRANCH_TO_JMPTBL_ENTRY_VALUE(L(table_48bytes_fwd))
 | 
			
		||||
@@ -851,6 +881,8 @@ L(shl_10_end):
 | 
			
		||||
	POP (%edi)
 | 
			
		||||
	BRANCH_TO_JMPTBL_ENTRY_TAIL(L(table_48bytes_fwd), %ecx, 4)
 | 
			
		||||
 | 
			
		||||
	cfi_restore_state
 | 
			
		||||
	cfi_remember_state
 | 
			
		||||
	ALIGN (4)
 | 
			
		||||
L(shl_11):
 | 
			
		||||
	BRANCH_TO_JMPTBL_ENTRY_VALUE(L(table_48bytes_fwd))
 | 
			
		||||
@@ -894,6 +926,8 @@ L(shl_11_end):
 | 
			
		||||
	POP (%edi)
 | 
			
		||||
	BRANCH_TO_JMPTBL_ENTRY_TAIL(L(table_48bytes_fwd), %ecx, 4)
 | 
			
		||||
 | 
			
		||||
	cfi_restore_state
 | 
			
		||||
	cfi_remember_state
 | 
			
		||||
	ALIGN (4)
 | 
			
		||||
L(shl_12):
 | 
			
		||||
	BRANCH_TO_JMPTBL_ENTRY_VALUE(L(table_48bytes_fwd))
 | 
			
		||||
@@ -937,6 +971,8 @@ L(shl_12_end):
 | 
			
		||||
	POP (%edi)
 | 
			
		||||
	BRANCH_TO_JMPTBL_ENTRY_TAIL(L(table_48bytes_fwd), %ecx, 4)
 | 
			
		||||
 | 
			
		||||
	cfi_restore_state
 | 
			
		||||
	cfi_remember_state
 | 
			
		||||
	ALIGN (4)
 | 
			
		||||
L(shl_13):
 | 
			
		||||
	BRANCH_TO_JMPTBL_ENTRY_VALUE(L(table_48bytes_fwd))
 | 
			
		||||
@@ -980,6 +1016,8 @@ L(shl_13_end):
 | 
			
		||||
	POP (%edi)
 | 
			
		||||
	BRANCH_TO_JMPTBL_ENTRY_TAIL(L(table_48bytes_fwd), %ecx, 4)
 | 
			
		||||
 | 
			
		||||
	cfi_restore_state
 | 
			
		||||
	cfi_remember_state
 | 
			
		||||
	ALIGN (4)
 | 
			
		||||
L(shl_14):
 | 
			
		||||
	BRANCH_TO_JMPTBL_ENTRY_VALUE(L(table_48bytes_fwd))
 | 
			
		||||
@@ -1023,7 +1061,8 @@ L(shl_14_end):
 | 
			
		||||
	POP (%edi)
 | 
			
		||||
	BRANCH_TO_JMPTBL_ENTRY_TAIL(L(table_48bytes_fwd), %ecx, 4)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	cfi_restore_state
 | 
			
		||||
	cfi_remember_state
 | 
			
		||||
	ALIGN (4)
 | 
			
		||||
L(shl_15):
 | 
			
		||||
	BRANCH_TO_JMPTBL_ENTRY_VALUE(L(table_48bytes_fwd))
 | 
			
		||||
@@ -1264,8 +1303,10 @@ L(fwd_write_3bytes):
 | 
			
		||||
	movl	DEST(%esp), %eax
 | 
			
		||||
# endif
 | 
			
		||||
#endif
 | 
			
		||||
	RETURN
 | 
			
		||||
	RETURN_END
 | 
			
		||||
 | 
			
		||||
	cfi_restore_state
 | 
			
		||||
	cfi_remember_state
 | 
			
		||||
	ALIGN (4)
 | 
			
		||||
L(large_page):
 | 
			
		||||
	movdqu	(%eax), %xmm1
 | 
			
		||||
@@ -1688,6 +1729,7 @@ L(bk_write_less32bytes):
 | 
			
		||||
L(bk_write_less32bytes_2):
 | 
			
		||||
	BRANCH_TO_JMPTBL_ENTRY (L(table_48_bytes_bwd), %ecx, 4)
 | 
			
		||||
 | 
			
		||||
	CFI_PUSH (%esi)
 | 
			
		||||
	ALIGN (4)
 | 
			
		||||
L(bk_align):
 | 
			
		||||
	cmp	$8, %ecx
 | 
			
		||||
 
 | 
			
		||||
@@ -45,13 +45,21 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef cfi_restore
 | 
			
		||||
# define cfi_restore(reg)		.cfi_restore (reg)
 | 
			
		||||
# define cfi_restore(reg)		.cfi_restore reg
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef cfi_adjust_cfa_offset
 | 
			
		||||
# define cfi_adjust_cfa_offset(off)	.cfi_adjust_cfa_offset off
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef cfi_remember_state
 | 
			
		||||
# define cfi_remember_state		.cfi_remember_state
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef cfi_restore_state
 | 
			
		||||
# define cfi_restore_state		.cfi_restore_state
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef ENTRY
 | 
			
		||||
# define ENTRY(name)			\
 | 
			
		||||
	.type name,  @function; 	\
 | 
			
		||||
@@ -201,6 +209,9 @@ L(crosspage):
 | 
			
		||||
	PUSH	(%ebx)
 | 
			
		||||
	PUSH	(%edi)
 | 
			
		||||
	PUSH	(%esi)
 | 
			
		||||
#ifdef USE_AS_STRNCMP
 | 
			
		||||
	cfi_remember_state
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
	movl	%edx, %edi
 | 
			
		||||
	movl	%eax, %ecx
 | 
			
		||||
@@ -1521,17 +1532,18 @@ L(gobble_ashr_12):
 | 
			
		||||
	sub	$0xffff, %esi
 | 
			
		||||
	jnz	L(exit)
 | 
			
		||||
 | 
			
		||||
#ifdef USE_AS_STRNCMP
 | 
			
		||||
	cmp	$16, %ebp
 | 
			
		||||
	lea	-16(%ebp), %ebp
 | 
			
		||||
	jbe	L(more8byteseq)
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
	add	$16, %ecx
 | 
			
		||||
	movdqa	%xmm4, %xmm3
 | 
			
		||||
 | 
			
		||||
	add	$16, %edi
 | 
			
		||||
	jg	L(nibble_ashr_12)
 | 
			
		||||
 | 
			
		||||
#ifdef USE_AS_STRNCMP
 | 
			
		||||
	cmp	$16, %ebp
 | 
			
		||||
	lea	-16(%ebp), %ebp
 | 
			
		||||
	jbe	L(more8byteseq)
 | 
			
		||||
#endif
 | 
			
		||||
	movdqa	(%eax, %ecx), %xmm1
 | 
			
		||||
	movdqa	(%edx, %ecx), %xmm2
 | 
			
		||||
	movdqa	%xmm2, %xmm4
 | 
			
		||||
@@ -2087,10 +2099,7 @@ L(neq_bigger):
 | 
			
		||||
	RETURN
 | 
			
		||||
 | 
			
		||||
#ifdef USE_AS_STRNCMP
 | 
			
		||||
	CFI_PUSH (%ebx)
 | 
			
		||||
	CFI_PUSH (%edi)
 | 
			
		||||
	CFI_PUSH (%esi)
 | 
			
		||||
 | 
			
		||||
	cfi_restore_state
 | 
			
		||||
	.p2align 4
 | 
			
		||||
L(more8byteseq):
 | 
			
		||||
	POP	(%esi)
 | 
			
		||||
@@ -31,7 +31,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 | 
			
		||||
#if defined(USE_SSSE3)
 | 
			
		||||
 | 
			
		||||
# define ssse3_strcmp_latest strcmp
 | 
			
		||||
# include "ssse3-strcmp.S"
 | 
			
		||||
# include "ssse3-strcmp-latest.S"
 | 
			
		||||
 | 
			
		||||
#else
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										40
									
								
								libc/arch-x86/string/strlen_wrapper.S
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										40
									
								
								libc/arch-x86/string/strlen_wrapper.S
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,40 @@
 | 
			
		||||
/*
 | 
			
		||||
Copyright (c) 2010, Intel Corporation
 | 
			
		||||
All rights reserved.
 | 
			
		||||
 | 
			
		||||
Redistribution and use in source and binary forms, with or without
 | 
			
		||||
modification, are permitted provided that the following conditions are met:
 | 
			
		||||
 | 
			
		||||
    * Redistributions of source code must retain the above copyright notice,
 | 
			
		||||
    * this list of conditions and the following disclaimer.
 | 
			
		||||
 | 
			
		||||
    * Redistributions in binary form must reproduce the above copyright notice,
 | 
			
		||||
    * this list of conditions and the following disclaimer in the documentation
 | 
			
		||||
    * and/or other materials provided with the distribution.
 | 
			
		||||
 | 
			
		||||
    * Neither the name of Intel Corporation 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.
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
#if defined(USE_SSE2)
 | 
			
		||||
 | 
			
		||||
# define sse2_strlen_atom strlen
 | 
			
		||||
# include "sse2-strlen-atom.S"
 | 
			
		||||
 | 
			
		||||
#else
 | 
			
		||||
 | 
			
		||||
# include "strlen.S"
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
@@ -32,7 +32,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 | 
			
		||||
 | 
			
		||||
# define USE_AS_STRNCMP
 | 
			
		||||
# define ssse3_strcmp_latest strncmp
 | 
			
		||||
# include "ssse3-strcmp.S"
 | 
			
		||||
# include "ssse3-strcmp-latest.S"
 | 
			
		||||
 | 
			
		||||
#else
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -35,7 +35,9 @@ typedef struct
 | 
			
		||||
    void (**preinit_array)(void);
 | 
			
		||||
    void (**init_array)(void);
 | 
			
		||||
    void (**fini_array)(void);
 | 
			
		||||
#ifndef __i386__
 | 
			
		||||
    void (**ctors_array)(void);
 | 
			
		||||
#endif
 | 
			
		||||
} structors_array_t;
 | 
			
		||||
 | 
			
		||||
extern void __libc_init_common(uintptr_t *elfdata);
 | 
			
		||||
 
 | 
			
		||||
@@ -75,8 +75,10 @@ __noreturn void __libc_init(uintptr_t *elfdata,
 | 
			
		||||
    /* pre-init array. */
 | 
			
		||||
    call_array(structors->preinit_array);
 | 
			
		||||
 | 
			
		||||
#ifndef __i386__
 | 
			
		||||
    /* .ctors section initializers, for non-arm-eabi ABIs */
 | 
			
		||||
    call_array(structors->ctors_array);
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
    // call static constructors
 | 
			
		||||
    call_array(structors->init_array);
 | 
			
		||||
 
 | 
			
		||||
@@ -68,7 +68,13 @@ int  __futex_wait_ex(volatile void *ftx, int pshared, int val, const struct time
 | 
			
		||||
#define  __likely(cond)    __builtin_expect(!!(cond), 1)
 | 
			
		||||
#define  __unlikely(cond)  __builtin_expect(!!(cond), 0)
 | 
			
		||||
 | 
			
		||||
void _thread_created_hook(pid_t thread_id) __attribute__((noinline));
 | 
			
		||||
#ifdef __i386__
 | 
			
		||||
#define ATTRIBUTES __attribute__((noinline)) __attribute__((fastcall))
 | 
			
		||||
#else
 | 
			
		||||
#define ATTRIBUTES __attribute__((noinline))
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
void ATTRIBUTES _thread_created_hook(pid_t thread_id);
 | 
			
		||||
 | 
			
		||||
#define PTHREAD_ATTR_FLAG_DETACHED      0x00000001
 | 
			
		||||
#define PTHREAD_ATTR_FLAG_USER_STACK    0x00000002
 | 
			
		||||
 
 | 
			
		||||
@@ -1,63 +1,68 @@
 | 
			
		||||
/*
 | 
			
		||||
 * 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 <sys/types.h>
 | 
			
		||||
#include <sys/ptrace.h>
 | 
			
		||||
 | 
			
		||||
extern long __ptrace(int request, pid_t pid, void *addr, void *data);
 | 
			
		||||
 | 
			
		||||
long ptrace(int request, pid_t pid, void * addr, void * data)
 | 
			
		||||
{
 | 
			
		||||
    switch (request) {
 | 
			
		||||
        case PTRACE_PEEKUSR:
 | 
			
		||||
        case PTRACE_PEEKTEXT:
 | 
			
		||||
        case PTRACE_PEEKDATA:
 | 
			
		||||
        {
 | 
			
		||||
            long word;
 | 
			
		||||
            long ret;
 | 
			
		||||
            
 | 
			
		||||
            ret = __ptrace(request, pid, addr, &word);
 | 
			
		||||
            if (ret == 0) {
 | 
			
		||||
                return word;
 | 
			
		||||
            } else {
 | 
			
		||||
                // __ptrace will set errno for us
 | 
			
		||||
                return -1;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        default:
 | 
			
		||||
             return __ptrace(request, pid, addr, data);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Hook for gdb to get notified when a thread is created
 | 
			
		||||
 */
 | 
			
		||||
void _thread_created_hook(pid_t thread_id) __attribute__((noinline));
 | 
			
		||||
void _thread_created_hook(pid_t thread_id)
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
/*
 | 
			
		||||
 * 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 <sys/types.h>
 | 
			
		||||
#include <sys/ptrace.h>
 | 
			
		||||
 | 
			
		||||
extern long __ptrace(int request, pid_t pid, void *addr, void *data);
 | 
			
		||||
 | 
			
		||||
long ptrace(int request, pid_t pid, void * addr, void * data)
 | 
			
		||||
{
 | 
			
		||||
    switch (request) {
 | 
			
		||||
        case PTRACE_PEEKUSR:
 | 
			
		||||
        case PTRACE_PEEKTEXT:
 | 
			
		||||
        case PTRACE_PEEKDATA:
 | 
			
		||||
        {
 | 
			
		||||
            long word;
 | 
			
		||||
            long ret;
 | 
			
		||||
 | 
			
		||||
            ret = __ptrace(request, pid, addr, &word);
 | 
			
		||||
            if (ret == 0) {
 | 
			
		||||
                return word;
 | 
			
		||||
            } else {
 | 
			
		||||
                // __ptrace will set errno for us
 | 
			
		||||
                return -1;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        default:
 | 
			
		||||
             return __ptrace(request, pid, addr, data);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Hook for gdb to get notified when a thread is created
 | 
			
		||||
 */
 | 
			
		||||
#ifdef __i386__
 | 
			
		||||
#define ATTRIBUTES __attribute__((noinline)) __attribute__((fastcall))
 | 
			
		||||
#else
 | 
			
		||||
#define ATTRIBUTES __attribute__((noinline))
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
void ATTRIBUTES _thread_created_hook(pid_t thread_id)
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -60,6 +60,10 @@
 | 
			
		||||
#define IN6_IS_ADDR_SITELOCAL(a)	\
 | 
			
		||||
	(((a)->s6_addr[0] == 0xfe) && (((a)->s6_addr[1] & 0xc0) == 0xc0))
 | 
			
		||||
 | 
			
		||||
/* RFC 4193. */
 | 
			
		||||
#define IN6_IS_ADDR_ULA(a)	\
 | 
			
		||||
	(((a)->s6_addr[0] & 0xfe) == 0xfc)
 | 
			
		||||
 | 
			
		||||
#define IN6_IS_ADDR_MULTICAST(a)	\
 | 
			
		||||
	(((__const uint8_t *) (a))[0] == 0xff)
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -84,6 +84,7 @@
 | 
			
		||||
#define ETH_P_TRAILER 0x001C  
 | 
			
		||||
#define ETH_P_PHONET 0x00F5  
 | 
			
		||||
#define ETH_P_IEEE802154 0x00F6  
 | 
			
		||||
#define ETH_P_CAIF 0x00F7  
 | 
			
		||||
 | 
			
		||||
struct ethhdr {
 | 
			
		||||
 unsigned char h_dest[ETH_ALEN];
 | 
			
		||||
 
 | 
			
		||||
@@ -138,7 +138,8 @@ struct ucred {
 | 
			
		||||
#define AF_LLC 26  
 | 
			
		||||
#define AF_TIPC 30  
 | 
			
		||||
#define AF_BLUETOOTH 31  
 | 
			
		||||
#define AF_MAX 32  
 | 
			
		||||
#define AF_CAIF 38  
 | 
			
		||||
#define AF_MAX 39  
 | 
			
		||||
 | 
			
		||||
#define PF_UNSPEC AF_UNSPEC
 | 
			
		||||
#define PF_UNIX AF_UNIX
 | 
			
		||||
@@ -170,6 +171,7 @@ struct ucred {
 | 
			
		||||
#define PF_LLC AF_LLC
 | 
			
		||||
#define PF_TIPC AF_TIPC
 | 
			
		||||
#define PF_BLUETOOTH AF_BLUETOOTH
 | 
			
		||||
#define PF_CAIF AF_CAIF
 | 
			
		||||
#define PF_MAX AF_MAX
 | 
			
		||||
 | 
			
		||||
#define SOMAXCONN 128
 | 
			
		||||
 
 | 
			
		||||
@@ -12,4 +12,6 @@
 | 
			
		||||
#ifndef _LINUX_TTY_H
 | 
			
		||||
#define _LINUX_TTY_H
 | 
			
		||||
 | 
			
		||||
#define N_CAIF 20  
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										43
									
								
								libc/kernel/common/linux/usb/f_accessory.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										43
									
								
								libc/kernel/common/linux/usb/f_accessory.h
									
									
									
									
									
										Normal file
									
								
							@@ -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.
 | 
			
		||||
 ***
 | 
			
		||||
 ***   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_USB_F_ACCESSORY_H
 | 
			
		||||
#define __LINUX_USB_F_ACCESSORY_H
 | 
			
		||||
#define USB_ACCESSORY_VENDOR_ID 0x18D1
 | 
			
		||||
#define USB_ACCESSORY_PRODUCT_ID 0x2D00
 | 
			
		||||
/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 | 
			
		||||
#define USB_ACCESSORY_ADB_PRODUCT_ID 0x2D01
 | 
			
		||||
#define ACCESSORY_STRING_MANUFACTURER 0
 | 
			
		||||
#define ACCESSORY_STRING_MODEL 1
 | 
			
		||||
#define ACCESSORY_STRING_DESCRIPTION 2
 | 
			
		||||
/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 | 
			
		||||
#define ACCESSORY_STRING_VERSION 3
 | 
			
		||||
#define ACCESSORY_STRING_URI 4
 | 
			
		||||
#define ACCESSORY_STRING_SERIAL 5
 | 
			
		||||
#define ACCESSORY_GET_PROTOCOL 51
 | 
			
		||||
#define ACCESSORY_SEND_STRING 52
 | 
			
		||||
/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 | 
			
		||||
#define ACCESSORY_START 53
 | 
			
		||||
#define ACCESSORY_GET_STRING_MANUFACTURER _IOW('M', 1, char[256])
 | 
			
		||||
#define ACCESSORY_GET_STRING_MODEL _IOW('M', 2, char[256])
 | 
			
		||||
#define ACCESSORY_GET_STRING_DESCRIPTION _IOW('M', 3, char[256])
 | 
			
		||||
/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 | 
			
		||||
#define ACCESSORY_GET_STRING_VERSION _IOW('M', 4, char[256])
 | 
			
		||||
#define ACCESSORY_GET_STRING_URI _IOW('M', 5, char[256])
 | 
			
		||||
#define ACCESSORY_GET_STRING_SERIAL _IOW('M', 6, char[256])
 | 
			
		||||
#endif
 | 
			
		||||
@@ -340,35 +340,55 @@ str2number(const char *p)
 | 
			
		||||
		return -1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Determine whether IPv6 connectivity is available. */
 | 
			
		||||
/*
 | 
			
		||||
 * Connect a UDP socket to a given unicast address. This will cause no network
 | 
			
		||||
 * traffic, but will fail fast if the system has no or limited reachability to
 | 
			
		||||
 * the destination (e.g., no IPv4 address, no IPv6 default route, ...).
 | 
			
		||||
 */
 | 
			
		||||
static int
 | 
			
		||||
_have_ipv6() {
 | 
			
		||||
	/*
 | 
			
		||||
	 * Connect a UDP socket to an global unicast IPv6 address. This will
 | 
			
		||||
	 * cause no network traffic, but will fail fast if the system has no or
 | 
			
		||||
	 * limited IPv6 connectivity (e.g., only a link-local address).
 | 
			
		||||
	 */
 | 
			
		||||
	static const struct sockaddr_in6 sin6_test = {
 | 
			
		||||
		/* family, port, flow label */
 | 
			
		||||
		AF_INET6, 0, 0,
 | 
			
		||||
		/* 2000:: */
 | 
			
		||||
		{{{ 0x20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }}},
 | 
			
		||||
		/* scope ID */
 | 
			
		||||
		0};
 | 
			
		||||
        sockaddr_union addr_test;
 | 
			
		||||
        addr_test.in6 = sin6_test;
 | 
			
		||||
	int s = socket(PF_INET6, SOCK_DGRAM, IPPROTO_UDP);
 | 
			
		||||
_test_connect(int pf, struct sockaddr *addr, size_t addrlen) {
 | 
			
		||||
	int s = socket(pf, SOCK_DGRAM, IPPROTO_UDP);
 | 
			
		||||
	if (s < 0)
 | 
			
		||||
		return 0;
 | 
			
		||||
	int ret;
 | 
			
		||||
	do {
 | 
			
		||||
		ret = connect(s, &addr_test.generic, sizeof(addr_test.in6));
 | 
			
		||||
		ret = connect(s, addr, addrlen);
 | 
			
		||||
	} while (ret < 0 && errno == EINTR);
 | 
			
		||||
	int have_ipv6 = (ret == 0);
 | 
			
		||||
	int success = (ret == 0);
 | 
			
		||||
	do {
 | 
			
		||||
		ret = close(s);
 | 
			
		||||
	} while (ret < 0 && errno == EINTR);
 | 
			
		||||
	return have_ipv6;
 | 
			
		||||
	return success;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * The following functions determine whether IPv4 or IPv6 connectivity is
 | 
			
		||||
 * available in order to implement AI_ADDRCONFIG.
 | 
			
		||||
 *
 | 
			
		||||
 * Strictly speaking, AI_ADDRCONFIG should not look at whether connectivity is
 | 
			
		||||
 * available, but whether addresses of the specified family are "configured
 | 
			
		||||
 * on the local system". However, bionic doesn't currently support getifaddrs,
 | 
			
		||||
 * so checking for connectivity is the next best thing.
 | 
			
		||||
 */
 | 
			
		||||
static int
 | 
			
		||||
_have_ipv6() {
 | 
			
		||||
	static const struct sockaddr_in6 sin6_test = {
 | 
			
		||||
		.sin6_family = AF_INET6,
 | 
			
		||||
		.sin6_addr.s6_addr = {  // 2000::
 | 
			
		||||
			0x20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
 | 
			
		||||
		};
 | 
			
		||||
        sockaddr_union addr = { .in6 = sin6_test };
 | 
			
		||||
	return _test_connect(PF_INET6, &addr.generic, sizeof(addr.in6));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int
 | 
			
		||||
_have_ipv4() {
 | 
			
		||||
	static const struct sockaddr_in sin_test = {
 | 
			
		||||
		.sin_family = AF_INET,
 | 
			
		||||
		.sin_addr.s_addr = __constant_htonl(0x08080808L)  // 8.8.8.8
 | 
			
		||||
	};
 | 
			
		||||
        sockaddr_union addr = { .in = sin_test };
 | 
			
		||||
        return _test_connect(PF_INET, &addr.generic, sizeof(addr.in));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int
 | 
			
		||||
@@ -1299,11 +1319,13 @@ _get_scope(const struct sockaddr *addr)
 | 
			
		||||
		if (IN_LOOPBACK(na) ||                          /* 127.0.0.0/8 */
 | 
			
		||||
		    (na & 0xffff0000) == 0xa9fe0000) {          /* 169.254.0.0/16 */
 | 
			
		||||
			return IPV6_ADDR_SCOPE_LINKLOCAL;
 | 
			
		||||
		} else if ((na & 0xff000000) == 0x0a000000 ||   /* 10.0.0.0/8 */
 | 
			
		||||
			   (na & 0xfff00000) == 0xac100000 ||   /* 172.16.0.0/12 */
 | 
			
		||||
			   (na & 0xffff0000) == 0xc0a80000) {   /* 192.168.0.0/16 */
 | 
			
		||||
			return IPV6_ADDR_SCOPE_SITELOCAL;
 | 
			
		||||
		} else {
 | 
			
		||||
			/*
 | 
			
		||||
			 * According to draft-ietf-6man-rfc3484-revise-01 section 2.3,
 | 
			
		||||
			 * it is best not to treat the private IPv4 ranges
 | 
			
		||||
			 * (10.0.0.0/8, 172.16.0.0/12 and 192.168.0.0/16) as being
 | 
			
		||||
			 * in a special scope, so we don't.
 | 
			
		||||
			 */
 | 
			
		||||
			return IPV6_ADDR_SCOPE_GLOBAL;
 | 
			
		||||
		}
 | 
			
		||||
	} else {
 | 
			
		||||
@@ -1325,9 +1347,13 @@ _get_scope(const struct sockaddr *addr)
 | 
			
		||||
#define IN6_IS_ADDR_6TO4(a)	 \
 | 
			
		||||
	(((a)->s6_addr[0] == 0x20) && ((a)->s6_addr[1] == 0x02))
 | 
			
		||||
 | 
			
		||||
/* 6bone testing address area (3ffe::/16), deprecated in RFC 3701. */
 | 
			
		||||
#define IN6_IS_ADDR_6BONE(a)      \
 | 
			
		||||
	(((a)->s6_addr[0] == 0x3f) && ((a)->s6_addr[1] == 0xfe))
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Get the label for a given IPv4/IPv6 address.
 | 
			
		||||
 * RFC 3484, section 2.1, plus Teredo added in with label 5.
 | 
			
		||||
 * RFC 3484, section 2.1, plus changes from draft-ietf-6man-rfc3484-revise-01.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
/*ARGSUSED*/
 | 
			
		||||
@@ -1335,19 +1361,27 @@ static int
 | 
			
		||||
_get_label(const struct sockaddr *addr)
 | 
			
		||||
{
 | 
			
		||||
	if (addr->sa_family == AF_INET) {
 | 
			
		||||
		return 4;
 | 
			
		||||
		return 3;
 | 
			
		||||
	} else if (addr->sa_family == AF_INET6) {
 | 
			
		||||
		const struct sockaddr_in6 *addr6 = (const struct sockaddr_in6 *)addr;
 | 
			
		||||
		if (IN6_IS_ADDR_LOOPBACK(&addr6->sin6_addr)) {
 | 
			
		||||
			return 0;
 | 
			
		||||
		} else if (IN6_IS_ADDR_V4COMPAT(&addr6->sin6_addr)) {
 | 
			
		||||
		} else if (IN6_IS_ADDR_ULA(&addr6->sin6_addr)) {
 | 
			
		||||
			return 1;
 | 
			
		||||
		} else if (IN6_IS_ADDR_V4MAPPED(&addr6->sin6_addr)) {
 | 
			
		||||
			return 3;
 | 
			
		||||
		} else if (IN6_IS_ADDR_6TO4(&addr6->sin6_addr)) {
 | 
			
		||||
			return 4;
 | 
			
		||||
		} else if (IN6_IS_ADDR_TEREDO(&addr6->sin6_addr)) {
 | 
			
		||||
			return 5;
 | 
			
		||||
		} else if (IN6_IS_ADDR_6TO4(&addr6->sin6_addr)) {
 | 
			
		||||
			return 2;
 | 
			
		||||
		} else if (IN6_IS_ADDR_V4COMPAT(&addr6->sin6_addr)) {
 | 
			
		||||
			return 10;
 | 
			
		||||
		} else if (IN6_IS_ADDR_SITELOCAL(&addr6->sin6_addr)) {
 | 
			
		||||
			return 11;
 | 
			
		||||
		} else if (IN6_IS_ADDR_6BONE(&addr6->sin6_addr)) {
 | 
			
		||||
			return 12;
 | 
			
		||||
		} else {
 | 
			
		||||
			return 1;
 | 
			
		||||
			return 2;
 | 
			
		||||
		}
 | 
			
		||||
	} else {
 | 
			
		||||
		/*
 | 
			
		||||
@@ -1360,7 +1394,7 @@ _get_label(const struct sockaddr *addr)
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Get the precedence for a given IPv4/IPv6 address.
 | 
			
		||||
 * RFC 3484, section 2.1, plus Teredo added in with precedence 25.
 | 
			
		||||
 * RFC 3484, section 2.1, plus changes from draft-ietf-6man-rfc3484-revise-01.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
/*ARGSUSED*/
 | 
			
		||||
@@ -1368,22 +1402,28 @@ static int
 | 
			
		||||
_get_precedence(const struct sockaddr *addr)
 | 
			
		||||
{
 | 
			
		||||
	if (addr->sa_family == AF_INET) {
 | 
			
		||||
		return 10;
 | 
			
		||||
		return 30;
 | 
			
		||||
	} else if (addr->sa_family == AF_INET6) {
 | 
			
		||||
		const struct sockaddr_in6 *addr6 = (const struct sockaddr_in6 *)addr;
 | 
			
		||||
		if (IN6_IS_ADDR_LOOPBACK(&addr6->sin6_addr)) {
 | 
			
		||||
			return 60;
 | 
			
		||||
		} else if (IN6_IS_ADDR_ULA(&addr6->sin6_addr)) {
 | 
			
		||||
			return 50;
 | 
			
		||||
		} else if (IN6_IS_ADDR_V4COMPAT(&addr6->sin6_addr)) {
 | 
			
		||||
		} else if (IN6_IS_ADDR_V4MAPPED(&addr6->sin6_addr)) {
 | 
			
		||||
			return 30;
 | 
			
		||||
		} else if (IN6_IS_ADDR_6TO4(&addr6->sin6_addr)) {
 | 
			
		||||
			return 20;
 | 
			
		||||
		} else if (IN6_IS_ADDR_TEREDO(&addr6->sin6_addr)) {
 | 
			
		||||
			return 25;
 | 
			
		||||
		} else if (IN6_IS_ADDR_6TO4(&addr6->sin6_addr)) {
 | 
			
		||||
			return 30;
 | 
			
		||||
			return 10;
 | 
			
		||||
		} else if (IN6_IS_ADDR_V4COMPAT(&addr6->sin6_addr) ||
 | 
			
		||||
		           IN6_IS_ADDR_SITELOCAL(&addr6->sin6_addr) ||
 | 
			
		||||
		           IN6_IS_ADDR_6BONE(&addr6->sin6_addr)) {
 | 
			
		||||
			return 1;
 | 
			
		||||
		} else {
 | 
			
		||||
			return 40;
 | 
			
		||||
		}
 | 
			
		||||
	} else {
 | 
			
		||||
		return 5;
 | 
			
		||||
		return 1;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -1667,17 +1707,27 @@ _dns_getaddrinfo(void *rv, void	*cb_data, va_list ap)
 | 
			
		||||
		q.qclass = C_IN;
 | 
			
		||||
		q.answer = buf->buf;
 | 
			
		||||
		q.anslen = sizeof(buf->buf);
 | 
			
		||||
		/* If AI_ADDRCONFIG, lookup IPv6 only if we have connectivity */
 | 
			
		||||
		if (!(pai->ai_flags & AI_ADDRCONFIG) || _have_ipv6()) {
 | 
			
		||||
		int query_ipv6 = 1, query_ipv4 = 1;
 | 
			
		||||
		if (pai->ai_flags & AI_ADDRCONFIG) {
 | 
			
		||||
			query_ipv6 = _have_ipv6();
 | 
			
		||||
			query_ipv4 = _have_ipv4();
 | 
			
		||||
		}
 | 
			
		||||
		if (query_ipv6) {
 | 
			
		||||
			q.qtype = T_AAAA;
 | 
			
		||||
			q.next = &q2;
 | 
			
		||||
			q2.name = name;
 | 
			
		||||
			q2.qclass = C_IN;
 | 
			
		||||
			q2.qtype = T_A;
 | 
			
		||||
			q2.answer = buf2->buf;
 | 
			
		||||
			q2.anslen = sizeof(buf2->buf);
 | 
			
		||||
		} else {
 | 
			
		||||
			if (query_ipv4) {
 | 
			
		||||
				q.next = &q2;
 | 
			
		||||
				q2.name = name;
 | 
			
		||||
				q2.qclass = C_IN;
 | 
			
		||||
				q2.qtype = T_A;
 | 
			
		||||
				q2.answer = buf2->buf;
 | 
			
		||||
				q2.anslen = sizeof(buf2->buf);
 | 
			
		||||
			}
 | 
			
		||||
		} else if (query_ipv4) {
 | 
			
		||||
			q.qtype = T_A;
 | 
			
		||||
		} else {
 | 
			
		||||
			free(buf);
 | 
			
		||||
			free(buf2);
 | 
			
		||||
			return NS_NOTFOUND;
 | 
			
		||||
		}
 | 
			
		||||
		break;
 | 
			
		||||
	case AF_INET:
 | 
			
		||||
 
 | 
			
		||||
@@ -32,6 +32,11 @@
 | 
			
		||||
#
 | 
			
		||||
        .section .bss
 | 
			
		||||
        .align 4
 | 
			
		||||
 | 
			
		||||
#ifndef CRT_LEGACY_WORKAROUND
 | 
			
		||||
	.hidden __dso_handle
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
        .globl __dso_handle
 | 
			
		||||
__dso_handle:
 | 
			
		||||
        .long 0
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										38
									
								
								libc/private/__dso_handle_so.S
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										38
									
								
								libc/private/__dso_handle_so.S
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,38 @@
 | 
			
		||||
/*
 | 
			
		||||
 * 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.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
# The __dso_handle global variable is used by static
 | 
			
		||||
# C++ constructors and destructors in the binary.
 | 
			
		||||
# See http://www.codesourcery.com/public/cxx-abi/abi.html#dso-dtor
 | 
			
		||||
#
 | 
			
		||||
	.data
 | 
			
		||||
        .align 4
 | 
			
		||||
	.hidden __dso_handle
 | 
			
		||||
        .globl __dso_handle
 | 
			
		||||
__dso_handle:
 | 
			
		||||
        .long __dso_handle
 | 
			
		||||
@@ -104,6 +104,7 @@ unlock:
 | 
			
		||||
	return (ret);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#ifdef CRT_LEGACY_WORKAROUND
 | 
			
		||||
/*
 | 
			
		||||
 * Register a function to be performed at exit.
 | 
			
		||||
 */
 | 
			
		||||
@@ -112,6 +113,7 @@ atexit(void (*func)(void))
 | 
			
		||||
{
 | 
			
		||||
	return (__cxa_atexit((void (*)(void *))func, NULL, NULL));
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Call all handlers registered with __cxa_atexit() for the shared
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										166
									
								
								libc/tools/zoneinfo/ZoneCompactor.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										166
									
								
								libc/tools/zoneinfo/ZoneCompactor.java
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,166 @@
 | 
			
		||||
 | 
			
		||||
import java.io.*;
 | 
			
		||||
import java.util.*;
 | 
			
		||||
 | 
			
		||||
// usage: java ZoneCompiler <setup file> <top-level directory>
 | 
			
		||||
//
 | 
			
		||||
// Compile a set of tzfile-formatted files into a single file plus
 | 
			
		||||
// an index file.
 | 
			
		||||
//
 | 
			
		||||
// The compilation is controlled by a setup file, which is provided as a
 | 
			
		||||
// command-line argument.  The setup file has the form:
 | 
			
		||||
//
 | 
			
		||||
// Link <toName> <fromName>
 | 
			
		||||
// ...
 | 
			
		||||
// <zone filename>
 | 
			
		||||
// ...
 | 
			
		||||
//
 | 
			
		||||
// Note that the links must be declared prior to the zone names.  A
 | 
			
		||||
// zone name is a filename relative to the source directory such as
 | 
			
		||||
// 'GMT', 'Africa/Dakar', or 'America/Argentina/Jujuy'.
 | 
			
		||||
//
 | 
			
		||||
// Use the 'zic' command-line tool to convert from flat files
 | 
			
		||||
// (e.g., 'africa', 'northamerica') into a suitable source directory
 | 
			
		||||
// hierarchy for this tool (e.g., 'data/Africa/Abidjan').
 | 
			
		||||
//
 | 
			
		||||
// Example:
 | 
			
		||||
//     zic -d data tz2007h
 | 
			
		||||
//     javac ZoneCompactor.java
 | 
			
		||||
//     java ZoneCompactor setup data
 | 
			
		||||
//     <produces zoneinfo.dat and zoneinfo.idx>
 | 
			
		||||
 | 
			
		||||
public class ZoneCompactor {
 | 
			
		||||
 | 
			
		||||
    // Zone name synonyms
 | 
			
		||||
    Map<String,String> links = new HashMap<String,String>();
 | 
			
		||||
 | 
			
		||||
    // File starting bytes by zone name
 | 
			
		||||
    Map<String,Integer> starts = new HashMap<String,Integer>();
 | 
			
		||||
 | 
			
		||||
    // File lengths by zone name
 | 
			
		||||
    Map<String,Integer> lengths = new HashMap<String,Integer>();
 | 
			
		||||
 | 
			
		||||
    // Raw GMT offsets by zone name
 | 
			
		||||
    Map<String,Integer> offsets = new HashMap<String,Integer>();
 | 
			
		||||
    int start = 0;
 | 
			
		||||
 | 
			
		||||
    // Maximum number of characters in a zone name, including '\0' terminator
 | 
			
		||||
    private static final int MAXNAME = 40;
 | 
			
		||||
 | 
			
		||||
    // Concatenate the contents of 'inFile' onto 'out'
 | 
			
		||||
    // and return the contents as a byte array.
 | 
			
		||||
    private static byte[] copyFile(File inFile, OutputStream out)
 | 
			
		||||
        throws Exception {
 | 
			
		||||
        byte[] ret = new byte[0];
 | 
			
		||||
 | 
			
		||||
        InputStream in = new FileInputStream(inFile);
 | 
			
		||||
        byte[] buf = new byte[8192];
 | 
			
		||||
        while (true) {
 | 
			
		||||
            int nbytes = in.read(buf);
 | 
			
		||||
            if (nbytes == -1) {
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
            out.write(buf, 0, nbytes);
 | 
			
		||||
 | 
			
		||||
            byte[] nret = new byte[ret.length + nbytes];
 | 
			
		||||
            System.arraycopy(ret, 0, nret, 0, ret.length);
 | 
			
		||||
            System.arraycopy(buf, 0, nret, ret.length, nbytes);
 | 
			
		||||
            ret = nret;
 | 
			
		||||
        }
 | 
			
		||||
        out.flush();
 | 
			
		||||
        return ret;
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    // Write a 32-bit integer in network byte order
 | 
			
		||||
    private void writeInt(OutputStream os, int x) throws IOException {
 | 
			
		||||
        os.write((x >> 24) & 0xff);
 | 
			
		||||
        os.write((x >> 16) & 0xff);
 | 
			
		||||
        os.write((x >>  8) & 0xff);
 | 
			
		||||
        os.write( x        & 0xff);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public ZoneCompactor(String setupFilename, String dirName)
 | 
			
		||||
        throws Exception {
 | 
			
		||||
        File zoneInfoFile = new File("zoneinfo.dat");
 | 
			
		||||
        zoneInfoFile.delete();
 | 
			
		||||
        OutputStream zoneInfo = new FileOutputStream(zoneInfoFile);
 | 
			
		||||
 | 
			
		||||
        BufferedReader rdr = new BufferedReader(new FileReader(setupFilename));
 | 
			
		||||
    
 | 
			
		||||
        String s;
 | 
			
		||||
        while ((s = rdr.readLine()) != null) {
 | 
			
		||||
            s = s.trim();
 | 
			
		||||
            if (s.startsWith("Link")) {
 | 
			
		||||
                StringTokenizer st = new StringTokenizer(s);
 | 
			
		||||
                st.nextToken();
 | 
			
		||||
                String to = st.nextToken();
 | 
			
		||||
                String from = st.nextToken();
 | 
			
		||||
                links.put(from, to);
 | 
			
		||||
            } else {
 | 
			
		||||
                String link = links.get(s);
 | 
			
		||||
                if (link == null) {
 | 
			
		||||
                    File f = new File(dirName, s);
 | 
			
		||||
                    long length = f.length();
 | 
			
		||||
                    starts.put(s, new Integer(start));
 | 
			
		||||
                    lengths.put(s, new Integer((int)length));
 | 
			
		||||
 | 
			
		||||
                    start += length;
 | 
			
		||||
                    byte[] data = copyFile(f, zoneInfo);
 | 
			
		||||
 | 
			
		||||
                    TimeZone tz = ZoneInfo.make(s, data);
 | 
			
		||||
                    int gmtOffset = tz.getRawOffset();
 | 
			
		||||
                    offsets.put(s, new Integer(gmtOffset));
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        zoneInfo.close();
 | 
			
		||||
 | 
			
		||||
        // Fill in fields for links
 | 
			
		||||
        Iterator<String> iter = links.keySet().iterator();
 | 
			
		||||
        while (iter.hasNext()) {
 | 
			
		||||
            String from = iter.next();
 | 
			
		||||
            String to = links.get(from);
 | 
			
		||||
 | 
			
		||||
            starts.put(from, starts.get(to));
 | 
			
		||||
            lengths.put(from, lengths.get(to));
 | 
			
		||||
            offsets.put(from, offsets.get(to));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        File idxFile = new File("zoneinfo.idx");
 | 
			
		||||
        idxFile.delete();
 | 
			
		||||
        FileOutputStream idx = new FileOutputStream(idxFile);
 | 
			
		||||
 | 
			
		||||
        ArrayList<String> l = new ArrayList<String>();
 | 
			
		||||
        l.addAll(starts.keySet());
 | 
			
		||||
        Collections.sort(l);
 | 
			
		||||
        Iterator<String> ziter = l.iterator();
 | 
			
		||||
        while (ziter.hasNext()) {
 | 
			
		||||
            String zname = ziter.next();
 | 
			
		||||
            if (zname.length() >= MAXNAME) {
 | 
			
		||||
                System.err.println("Error - zone filename exceeds " +
 | 
			
		||||
                                   (MAXNAME - 1) + " characters!");
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            byte[] znameBuf = new byte[MAXNAME];
 | 
			
		||||
            for (int i = 0; i < zname.length(); i++) {
 | 
			
		||||
                znameBuf[i] = (byte)zname.charAt(i);
 | 
			
		||||
            }
 | 
			
		||||
            idx.write(znameBuf);
 | 
			
		||||
            writeInt(idx, starts.get(zname).intValue());
 | 
			
		||||
            writeInt(idx, lengths.get(zname).intValue());
 | 
			
		||||
            writeInt(idx, offsets.get(zname).intValue());
 | 
			
		||||
        }
 | 
			
		||||
        idx.close();
 | 
			
		||||
 | 
			
		||||
        // System.out.println("maxLength = " + maxLength);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static void main(String[] args) throws Exception {
 | 
			
		||||
        if (args.length != 2) {
 | 
			
		||||
            System.err.println("usage: java ZoneCompactor <setup> <data dir>");
 | 
			
		||||
            System.exit(0);
 | 
			
		||||
        }
 | 
			
		||||
        new ZoneCompactor(args[0], args[1]);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										272
									
								
								libc/tools/zoneinfo/ZoneInfo.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										272
									
								
								libc/tools/zoneinfo/ZoneInfo.java
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,272 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (C) 2007 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.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
import java.io.IOException;
 | 
			
		||||
import java.util.Arrays;
 | 
			
		||||
import java.util.Date;
 | 
			
		||||
import java.util.TimeZone;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Copied from ZoneInfo and ZoneInfoDB in dalvik.
 | 
			
		||||
 * {@hide}
 | 
			
		||||
 */
 | 
			
		||||
public class ZoneInfo extends TimeZone {
 | 
			
		||||
 | 
			
		||||
    private static final long MILLISECONDS_PER_DAY = 24 * 60 * 60 * 1000;
 | 
			
		||||
    private static final long MILLISECONDS_PER_400_YEARS =
 | 
			
		||||
        MILLISECONDS_PER_DAY * (400 * 365 + 100 - 3);
 | 
			
		||||
 | 
			
		||||
    private static final long UNIX_OFFSET = 62167219200000L;
 | 
			
		||||
 | 
			
		||||
    private static final int[] NORMAL = new int[] {
 | 
			
		||||
        0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334,
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    private static final int[] LEAP = new int[] {
 | 
			
		||||
        0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335,
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    private static String nullName(byte[] data, int where, int off) {
 | 
			
		||||
        if (off < 0)
 | 
			
		||||
            return null;
 | 
			
		||||
 | 
			
		||||
        int end = where + off;
 | 
			
		||||
        while (end < data.length && data[end] != '\0')
 | 
			
		||||
            end++;
 | 
			
		||||
 | 
			
		||||
        return new String(data, where + off, end - (where + off));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static ZoneInfo make(String name, byte[] data) {
 | 
			
		||||
        int ntransition = read4(data, 32);
 | 
			
		||||
        int ngmtoff = read4(data, 36);
 | 
			
		||||
        int base = 44;
 | 
			
		||||
 | 
			
		||||
        int[] transitions = new int[ntransition];
 | 
			
		||||
        for (int i = 0; i < ntransition; i++)
 | 
			
		||||
            transitions[i] = read4(data, base + 4 * i);
 | 
			
		||||
        base += 4 * ntransition;
 | 
			
		||||
 | 
			
		||||
        byte[] type = new byte[ntransition];
 | 
			
		||||
        for (int i = 0; i < ntransition; i++)
 | 
			
		||||
            type[i] = data[base + i];
 | 
			
		||||
        base += ntransition;
 | 
			
		||||
 | 
			
		||||
        int[] gmtoff = new int[ngmtoff];
 | 
			
		||||
        byte[] isdst = new byte[ngmtoff];
 | 
			
		||||
        byte[] abbrev = new byte[ngmtoff];
 | 
			
		||||
        for (int i = 0; i < ngmtoff; i++) {
 | 
			
		||||
            gmtoff[i] = read4(data, base + 6 * i);
 | 
			
		||||
            isdst[i] = data[base + 6 * i + 4];
 | 
			
		||||
            abbrev[i] = data[base + 6 * i + 5];
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        base += 6 * ngmtoff;
 | 
			
		||||
 | 
			
		||||
        return new ZoneInfo(name, transitions, type, gmtoff, isdst, abbrev, data, base);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private static int read4(byte[] data, int off) {
 | 
			
		||||
        return ((data[off    ] & 0xFF) << 24) |
 | 
			
		||||
               ((data[off + 1] & 0xFF) << 16) |
 | 
			
		||||
               ((data[off + 2] & 0xFF) <<  8) |
 | 
			
		||||
               ((data[off + 3] & 0xFF) <<  0);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /*package*/ ZoneInfo(String name, int[] transitions, byte[] type,
 | 
			
		||||
                     int[] gmtoff, byte[] isdst, byte[] abbrev,
 | 
			
		||||
                     byte[] data, int abbrevoff) {
 | 
			
		||||
        mTransitions = transitions;
 | 
			
		||||
        mTypes = type;
 | 
			
		||||
        mGmtOffs = gmtoff;
 | 
			
		||||
        mIsDsts = isdst;
 | 
			
		||||
        mUseDst = false;
 | 
			
		||||
        setID(name);
 | 
			
		||||
 | 
			
		||||
        // Find the latest GMT and non-GMT offsets for their abbreviations
 | 
			
		||||
 | 
			
		||||
        int lastdst;
 | 
			
		||||
        for (lastdst = mTransitions.length - 1; lastdst >= 0; lastdst--) {
 | 
			
		||||
            if (mIsDsts[mTypes[lastdst] & 0xFF] != 0)
 | 
			
		||||
                break;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        int laststd;
 | 
			
		||||
        for (laststd = mTransitions.length - 1; laststd >= 0; laststd--) {
 | 
			
		||||
            if (mIsDsts[mTypes[laststd] & 0xFF] == 0)
 | 
			
		||||
                break;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (lastdst >= 0) {
 | 
			
		||||
            mDaylightName = nullName(data, abbrevoff,
 | 
			
		||||
                                     abbrev[mTypes[lastdst] & 0xFF]);
 | 
			
		||||
        }
 | 
			
		||||
        if (laststd >= 0) {
 | 
			
		||||
            mStandardName = nullName(data, abbrevoff,
 | 
			
		||||
                                     abbrev[mTypes[laststd] & 0xFF]);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // Use the latest non-DST offset if any as the raw offset
 | 
			
		||||
 | 
			
		||||
        if (laststd < 0) {
 | 
			
		||||
            laststd = 0;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (laststd >= mTypes.length) {
 | 
			
		||||
            mRawOffset = mGmtOffs[0];
 | 
			
		||||
        } else {
 | 
			
		||||
            mRawOffset = mGmtOffs[mTypes[laststd] & 0xFF];
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // Subtract the raw offset from all offsets so it can be changed
 | 
			
		||||
        // and affect them too.
 | 
			
		||||
        // Find whether there exist any observances of DST.
 | 
			
		||||
 | 
			
		||||
        for (int i = 0; i < mGmtOffs.length; i++) {
 | 
			
		||||
            mGmtOffs[i] -= mRawOffset;
 | 
			
		||||
 | 
			
		||||
            if (mIsDsts[i] != 0) {
 | 
			
		||||
                mUseDst = true;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        mRawOffset *= 1000;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public int getOffset(@SuppressWarnings("unused") int era,
 | 
			
		||||
        int year, int month, int day,
 | 
			
		||||
        @SuppressWarnings("unused") int dayOfWeek,
 | 
			
		||||
        int millis) {
 | 
			
		||||
        // XXX This assumes Gregorian always; Calendar switches from
 | 
			
		||||
        // Julian to Gregorian in 1582.  What calendar system are the
 | 
			
		||||
        // arguments supposed to come from?
 | 
			
		||||
 | 
			
		||||
        long calc = (year / 400) * MILLISECONDS_PER_400_YEARS;
 | 
			
		||||
        year %= 400;
 | 
			
		||||
 | 
			
		||||
        calc += year * (365 * MILLISECONDS_PER_DAY);
 | 
			
		||||
        calc += ((year + 3) / 4) * MILLISECONDS_PER_DAY;
 | 
			
		||||
 | 
			
		||||
        if (year > 0)
 | 
			
		||||
            calc -= ((year - 1) / 100) * MILLISECONDS_PER_DAY;
 | 
			
		||||
 | 
			
		||||
        boolean isLeap = (year == 0 || (year % 4 == 0 && year % 100 != 0));
 | 
			
		||||
        int[] mlen = isLeap ? LEAP : NORMAL;
 | 
			
		||||
 | 
			
		||||
        calc += mlen[month] * MILLISECONDS_PER_DAY;
 | 
			
		||||
        calc += (day - 1) * MILLISECONDS_PER_DAY;
 | 
			
		||||
        calc += millis;
 | 
			
		||||
 | 
			
		||||
        calc -= mRawOffset;
 | 
			
		||||
        calc -= UNIX_OFFSET;
 | 
			
		||||
 | 
			
		||||
        return getOffset(calc);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public int getOffset(long when) {
 | 
			
		||||
        int unix = (int) (when / 1000);
 | 
			
		||||
        int trans = Arrays.binarySearch(mTransitions, unix);
 | 
			
		||||
 | 
			
		||||
        if (trans == ~0) {
 | 
			
		||||
            return mGmtOffs[0] * 1000 + mRawOffset;
 | 
			
		||||
        }
 | 
			
		||||
        if (trans < 0) {
 | 
			
		||||
            trans = ~trans - 1;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return mGmtOffs[mTypes[trans] & 0xFF] * 1000 + mRawOffset;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public int getRawOffset() {
 | 
			
		||||
        return mRawOffset;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void setRawOffset(int off) {
 | 
			
		||||
        mRawOffset = off;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public boolean inDaylightTime(Date when) {
 | 
			
		||||
        int unix = (int) (when.getTime() / 1000);
 | 
			
		||||
        int trans = Arrays.binarySearch(mTransitions, unix);
 | 
			
		||||
 | 
			
		||||
        if (trans == ~0) {
 | 
			
		||||
            return mIsDsts[0] != 0;
 | 
			
		||||
        }
 | 
			
		||||
        if (trans < 0) {
 | 
			
		||||
            trans = ~trans - 1;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return mIsDsts[mTypes[trans] & 0xFF] != 0;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public boolean useDaylightTime() {
 | 
			
		||||
        return mUseDst;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private int mRawOffset;
 | 
			
		||||
    private int[] mTransitions;
 | 
			
		||||
    private int[] mGmtOffs;
 | 
			
		||||
    private byte[] mTypes;
 | 
			
		||||
    private byte[] mIsDsts;
 | 
			
		||||
    private boolean mUseDst;
 | 
			
		||||
    private String mDaylightName;
 | 
			
		||||
    private String mStandardName;
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public boolean equals(Object obj) {
 | 
			
		||||
        if (this == obj) {
 | 
			
		||||
            return true;
 | 
			
		||||
        }
 | 
			
		||||
        if (!(obj instanceof ZoneInfo)) {
 | 
			
		||||
           return false;
 | 
			
		||||
        }
 | 
			
		||||
        ZoneInfo other = (ZoneInfo) obj;
 | 
			
		||||
        return mUseDst == other.mUseDst
 | 
			
		||||
                && (mDaylightName == null ? other.mDaylightName == null :
 | 
			
		||||
                        mDaylightName.equals(other.mDaylightName))
 | 
			
		||||
                && (mStandardName == null ? other.mStandardName == null :
 | 
			
		||||
                        mStandardName.equals(other.mStandardName))
 | 
			
		||||
                && mRawOffset == other.mRawOffset
 | 
			
		||||
                // Arrays.equals returns true if both arrays are null
 | 
			
		||||
                && Arrays.equals(mGmtOffs, other.mGmtOffs)
 | 
			
		||||
                && Arrays.equals(mIsDsts, other.mIsDsts)
 | 
			
		||||
                && Arrays.equals(mTypes, other.mTypes)
 | 
			
		||||
                && Arrays.equals(mTransitions, other.mTransitions);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public int hashCode() {
 | 
			
		||||
        final int prime = 31;
 | 
			
		||||
        int result = 1;
 | 
			
		||||
        result = prime * result + ((mDaylightName == null) ? 0 :
 | 
			
		||||
                mDaylightName.hashCode());
 | 
			
		||||
        result = prime * result + Arrays.hashCode(mGmtOffs);
 | 
			
		||||
        result = prime * result + Arrays.hashCode(mIsDsts);
 | 
			
		||||
        result = prime * result + mRawOffset;
 | 
			
		||||
        result = prime * result + ((mStandardName == null) ? 0 :
 | 
			
		||||
                mStandardName.hashCode());
 | 
			
		||||
        result = prime * result + Arrays.hashCode(mTransitions);
 | 
			
		||||
        result = prime * result + Arrays.hashCode(mTypes);
 | 
			
		||||
        result = prime * result + (mUseDst ? 1231 : 1237);
 | 
			
		||||
        return result;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										82
									
								
								libc/tools/zoneinfo/generate
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										82
									
								
								libc/tools/zoneinfo/generate
									
									
									
									
									
										Executable file
									
								
							@@ -0,0 +1,82 @@
 | 
			
		||||
#!/bin/bash
 | 
			
		||||
# Run with no arguments from any directory, with no special setup required.
 | 
			
		||||
 | 
			
		||||
# Abort if any command returns an error exit status, or if an undefined
 | 
			
		||||
# variable is used.
 | 
			
		||||
set -e
 | 
			
		||||
set -u
 | 
			
		||||
 | 
			
		||||
echo "Looking for bionic..."
 | 
			
		||||
bionic_dir=$(cd $(dirname $0)/../../.. && pwd)
 | 
			
		||||
bionic_zoneinfo_dir=$bionic_dir/libc/zoneinfo
 | 
			
		||||
bionic_zoneinfo_tools_dir=$bionic_dir/libc/tools/zoneinfo
 | 
			
		||||
if [[ ! -d "$bionic_zoneinfo_dir" || ! -d "$bionic_zoneinfo_tools_dir" ]]; then
 | 
			
		||||
  echo "Can't find bionic's zoneinfo directories!"
 | 
			
		||||
  exit 1
 | 
			
		||||
fi
 | 
			
		||||
 | 
			
		||||
echo "Switching to temporary directory..."
 | 
			
		||||
temp_dir=`mktemp -d`
 | 
			
		||||
cd $temp_dir
 | 
			
		||||
trap "rm -rf $temp_dir; exit" INT TERM EXIT
 | 
			
		||||
 | 
			
		||||
# URL from "Sources for Time Zone and Daylight Saving Time Data"
 | 
			
		||||
# http://www.twinsun.com/tz/tz-link.htm
 | 
			
		||||
echo "Looking for new tzdata..."
 | 
			
		||||
wget -N --no-verbose 'ftp://munnari.oz.au/pub/tzdata*.tar.gz'
 | 
			
		||||
zoneinfo_version_file=$bionic_zoneinfo_dir/zoneinfo.version
 | 
			
		||||
if [ -f "$zoneinfo_version_file" ]; then
 | 
			
		||||
  current_version=tzdata`sed s/\n// < $zoneinfo_version_file`
 | 
			
		||||
else
 | 
			
		||||
  current_version=missing
 | 
			
		||||
fi
 | 
			
		||||
latest_archive=`ls -r -v tzdata*.tar.gz | head -n1`
 | 
			
		||||
latest_version=`basename $latest_archive .tar.gz`
 | 
			
		||||
if [ "$current_version" == "$latest_version" ]; then
 | 
			
		||||
  echo "You already have the latest tzdata ($latest_version)!"
 | 
			
		||||
  exit 1
 | 
			
		||||
fi
 | 
			
		||||
 | 
			
		||||
md5_sum=`md5sum $latest_archive`
 | 
			
		||||
echo "MD5: $md5_sum"
 | 
			
		||||
 | 
			
		||||
echo "Extracting $latest_version..."
 | 
			
		||||
mkdir $latest_version
 | 
			
		||||
tar -C $latest_version -zxf $latest_archive
 | 
			
		||||
 | 
			
		||||
echo "Compiling $latest_version..."
 | 
			
		||||
mkdir data
 | 
			
		||||
for i in \
 | 
			
		||||
    africa \
 | 
			
		||||
    antarctica \
 | 
			
		||||
    asia \
 | 
			
		||||
    australasia \
 | 
			
		||||
    etcetera \
 | 
			
		||||
    europe \
 | 
			
		||||
    factory \
 | 
			
		||||
    northamerica \
 | 
			
		||||
    solar87 \
 | 
			
		||||
    solar88 \
 | 
			
		||||
    solar89 \
 | 
			
		||||
    southamerica
 | 
			
		||||
do
 | 
			
		||||
    zic -d data $latest_version/$i
 | 
			
		||||
done
 | 
			
		||||
 | 
			
		||||
echo "Compacting $latest_version..."
 | 
			
		||||
(
 | 
			
		||||
    cat $latest_version/* | grep '^Link' | awk '{print $1, $2, $3}'
 | 
			
		||||
    (
 | 
			
		||||
        cat $latest_version/* | grep '^Zone' | awk '{print $2}'
 | 
			
		||||
        cat $latest_version/* | grep '^Link' | awk '{print $3}'
 | 
			
		||||
    ) | LC_ALL="C" sort
 | 
			
		||||
) | grep -v Riyadh8 > setup
 | 
			
		||||
 | 
			
		||||
javac -d . \
 | 
			
		||||
    $bionic_zoneinfo_tools_dir/ZoneCompactor.java \
 | 
			
		||||
    $bionic_zoneinfo_tools_dir/ZoneInfo.java
 | 
			
		||||
java ZoneCompactor setup data
 | 
			
		||||
 | 
			
		||||
echo "Updating bionic to $latest_version..."
 | 
			
		||||
mv zoneinfo.dat zoneinfo.idx $bionic_zoneinfo_dir
 | 
			
		||||
echo $latest_version | sed 's/tzdata//' > $bionic_zoneinfo_dir/zoneinfo.version
 | 
			
		||||
@@ -35,9 +35,7 @@ int open(const char *pathname, int flags, ...)
 | 
			
		||||
{
 | 
			
		||||
    mode_t  mode = 0;
 | 
			
		||||
 | 
			
		||||
#if !defined(__i386__)
 | 
			
		||||
    flags |= O_LARGEFILE;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
    if (flags & O_CREAT)
 | 
			
		||||
    {
 | 
			
		||||
 
 | 
			
		||||
@@ -35,9 +35,7 @@ int openat(int fd, const char *pathname, int flags, ...)
 | 
			
		||||
{
 | 
			
		||||
    mode_t  mode = 0;
 | 
			
		||||
 | 
			
		||||
#if !defined(__i386__)
 | 
			
		||||
    flags |= O_LARGEFILE;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
    if (flags & O_CREAT)
 | 
			
		||||
    {
 | 
			
		||||
 
 | 
			
		||||
@@ -38,6 +38,8 @@ sigsetmask(int mask)
 | 
			
		||||
        sigset_t  the_sigset;
 | 
			
		||||
    } in, out;
 | 
			
		||||
 | 
			
		||||
    in.the_mask = mask;
 | 
			
		||||
 | 
			
		||||
    n = sigprocmask(SIG_SETMASK, &in.the_sigset, &out.the_sigset);
 | 
			
		||||
    if (n)
 | 
			
		||||
        return n;
 | 
			
		||||
 
 | 
			
		||||
										
											Binary file not shown.
										
									
								
							
										
											Binary file not shown.
										
									
								
							@@ -1 +1 @@
 | 
			
		||||
2010k
 | 
			
		||||
2011n
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										294
									
								
								libm/i387/fenv.c
									
									
									
									
									
								
							
							
						
						
									
										294
									
								
								libm/i387/fenv.c
									
									
									
									
									
								
							@@ -31,16 +31,46 @@
 | 
			
		||||
#include "npx.h"
 | 
			
		||||
#include "fenv.h"
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * As compared to the x87 control word, the SSE unit's control word
 | 
			
		||||
 * has the rounding control bits offset by 3 and the exception mask
 | 
			
		||||
 * bits offset by 7.
 | 
			
		||||
 */
 | 
			
		||||
#define	_SSE_ROUND_SHIFT	3
 | 
			
		||||
#define	_SSE_EMASK_SHIFT	7
 | 
			
		||||
 | 
			
		||||
const fenv_t __fe_dfl_env = {
 | 
			
		||||
	__INITIAL_NPXCW__,
 | 
			
		||||
	0x0000,
 | 
			
		||||
	0x0000,
 | 
			
		||||
	0x1f80,
 | 
			
		||||
	0xffffffff,
 | 
			
		||||
	__INITIAL_NPXCW__, /*__control*/
 | 
			
		||||
	0x0000,            /*__mxcsr_hi*/
 | 
			
		||||
	0x0000,            /*__status*/
 | 
			
		||||
	0x1f80,            /*__mxcsr_lo*/
 | 
			
		||||
	0xffffffff,        /*__tag*/
 | 
			
		||||
	{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 | 
			
		||||
	  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff }
 | 
			
		||||
	  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff } /*__other*/
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#define __fldcw(__cw)           __asm __volatile("fldcw %0" : : "m" (__cw))
 | 
			
		||||
#define __fldenv(__env)         __asm __volatile("fldenv %0" : : "m" (__env))
 | 
			
		||||
#define	__fldenvx(__env)	__asm __volatile("fldenv %0" : : "m" (__env)  \
 | 
			
		||||
				: "st", "st(1)", "st(2)", "st(3)", "st(4)",   \
 | 
			
		||||
				"st(5)", "st(6)", "st(7)")
 | 
			
		||||
#define __fnclex()              __asm __volatile("fnclex")
 | 
			
		||||
#define __fnstenv(__env)        __asm __volatile("fnstenv %0" : "=m" (*(__env)))
 | 
			
		||||
#define __fnstcw(__cw)          __asm __volatile("fnstcw %0" : "=m" (*(__cw)))
 | 
			
		||||
#define __fnstsw(__sw)          __asm __volatile("fnstsw %0" : "=am" (*(__sw)))
 | 
			
		||||
#define __fwait()               __asm __volatile("fwait")
 | 
			
		||||
#define __ldmxcsr(__csr)        __asm __volatile("ldmxcsr %0" : : "m" (__csr))
 | 
			
		||||
#define __stmxcsr(__csr)        __asm __volatile("stmxcsr %0" : "=m" (*(__csr)))
 | 
			
		||||
 | 
			
		||||
/* After testing for SSE support once, we cache the result in __has_sse. */
 | 
			
		||||
enum __sse_support { __SSE_YES, __SSE_NO, __SSE_UNK };
 | 
			
		||||
#ifdef __SSE__
 | 
			
		||||
#define __HAS_SSE()     1
 | 
			
		||||
#else
 | 
			
		||||
#define __HAS_SSE()     (__has_sse == __SSE_YES ||                      \
 | 
			
		||||
                         (__has_sse == __SSE_UNK && __test_sse()))
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
enum __sse_support __has_sse =
 | 
			
		||||
#ifdef __SSE__
 | 
			
		||||
	__SSE_YES;
 | 
			
		||||
@@ -48,6 +78,7 @@ enum __sse_support __has_sse =
 | 
			
		||||
	__SSE_UNK;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef __SSE__
 | 
			
		||||
#define	getfl(x)	__asm __volatile("pushfl\n\tpopl %0" : "=mr" (*(x)))
 | 
			
		||||
#define	setfl(x)	__asm __volatile("pushl %0\n\tpopfl" : : "g" (x))
 | 
			
		||||
#define	cpuid_dx(x)	__asm __volatile("pushl %%ebx\n\tmovl $1, %%eax\n\t"  \
 | 
			
		||||
@@ -82,23 +113,27 @@ __test_sse(void)
 | 
			
		||||
	__has_sse = __SSE_NO;
 | 
			
		||||
	return (0);
 | 
			
		||||
}
 | 
			
		||||
#endif /* __SSE__ */
 | 
			
		||||
 | 
			
		||||
int
 | 
			
		||||
fesetexceptflag(const fexcept_t *flagp, int excepts)
 | 
			
		||||
{
 | 
			
		||||
	fenv_t env;
 | 
			
		||||
	int mxcsr;
 | 
			
		||||
	__uint32_t mxcsr;
 | 
			
		||||
 | 
			
		||||
	__fnstenv(&env);
 | 
			
		||||
	env.__status &= ~excepts;
 | 
			
		||||
	env.__status |= *flagp & excepts;
 | 
			
		||||
	__fldenv(env);
 | 
			
		||||
 | 
			
		||||
	if (__HAS_SSE()) {
 | 
			
		||||
		__stmxcsr(&mxcsr);
 | 
			
		||||
		mxcsr &= ~excepts;
 | 
			
		||||
		mxcsr |= *flagp & excepts;
 | 
			
		||||
		__ldmxcsr(mxcsr);
 | 
			
		||||
	excepts &= FE_ALL_EXCEPT;
 | 
			
		||||
	if (excepts) { /* Do nothing if excepts is 0 */
 | 
			
		||||
		__fnstenv(&env);
 | 
			
		||||
		env.__status &= ~excepts;
 | 
			
		||||
		env.__status |= *flagp & excepts;
 | 
			
		||||
		__fnclex();
 | 
			
		||||
		__fldenv(env);
 | 
			
		||||
		if (__HAS_SSE()) {
 | 
			
		||||
			__stmxcsr(&mxcsr);
 | 
			
		||||
			mxcsr &= ~excepts;
 | 
			
		||||
			mxcsr |= *flagp & excepts;
 | 
			
		||||
			__ldmxcsr(mxcsr);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return (0);
 | 
			
		||||
@@ -117,32 +152,38 @@ feraiseexcept(int excepts)
 | 
			
		||||
int
 | 
			
		||||
fegetenv(fenv_t *envp)
 | 
			
		||||
{
 | 
			
		||||
	int control, mxcsr;
 | 
			
		||||
	__uint32_t mxcsr;
 | 
			
		||||
 | 
			
		||||
	/*
 | 
			
		||||
	 * fnstenv masks all exceptions, so we need to save and
 | 
			
		||||
	 * restore the control word to avoid this side effect.
 | 
			
		||||
	 */
 | 
			
		||||
	__fnstcw(&control);
 | 
			
		||||
	__fnstenv(envp);
 | 
			
		||||
	/*
 | 
			
		||||
	 * fnstenv masks all exceptions, so we need to restore
 | 
			
		||||
	 * the old control word to avoid this side effect.
 | 
			
		||||
	 */
 | 
			
		||||
	__fldcw(envp->__control);
 | 
			
		||||
	if (__HAS_SSE()) {
 | 
			
		||||
		__stmxcsr(&mxcsr);
 | 
			
		||||
		__set_mxcsr(*envp, mxcsr);
 | 
			
		||||
		envp->__mxcsr_hi = mxcsr >> 16;
 | 
			
		||||
		envp->__mxcsr_lo = mxcsr & 0xffff;
 | 
			
		||||
	}
 | 
			
		||||
	__fldcw(control);
 | 
			
		||||
	return (0);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int
 | 
			
		||||
feholdexcept(fenv_t *envp)
 | 
			
		||||
{
 | 
			
		||||
	int mxcsr;
 | 
			
		||||
	__uint32_t mxcsr;
 | 
			
		||||
	fenv_t env;
 | 
			
		||||
 | 
			
		||||
	__fnstenv(envp);
 | 
			
		||||
	__fnstenv(&env);
 | 
			
		||||
	*envp = env;
 | 
			
		||||
	env.__status &= ~FE_ALL_EXCEPT;
 | 
			
		||||
	env.__control |= FE_ALL_EXCEPT;
 | 
			
		||||
	__fnclex();
 | 
			
		||||
	__fldenv(env);
 | 
			
		||||
	if (__HAS_SSE()) {
 | 
			
		||||
		__stmxcsr(&mxcsr);
 | 
			
		||||
		__set_mxcsr(*envp, mxcsr);
 | 
			
		||||
		envp->__mxcsr_hi = mxcsr >> 16;
 | 
			
		||||
		envp->__mxcsr_lo = mxcsr & 0xffff;
 | 
			
		||||
		mxcsr &= ~FE_ALL_EXCEPT;
 | 
			
		||||
		mxcsr |= FE_ALL_EXCEPT << _SSE_EMASK_SHIFT;
 | 
			
		||||
		__ldmxcsr(mxcsr);
 | 
			
		||||
@@ -153,59 +194,198 @@ feholdexcept(fenv_t *envp)
 | 
			
		||||
int
 | 
			
		||||
feupdateenv(const fenv_t *envp)
 | 
			
		||||
{
 | 
			
		||||
	int mxcsr, status;
 | 
			
		||||
	__uint32_t mxcsr;
 | 
			
		||||
	__uint16_t status;
 | 
			
		||||
 | 
			
		||||
	__fnstsw(&status);
 | 
			
		||||
	if (__HAS_SSE())
 | 
			
		||||
	if (__HAS_SSE()) {
 | 
			
		||||
		__stmxcsr(&mxcsr);
 | 
			
		||||
	else
 | 
			
		||||
	} else {
 | 
			
		||||
		mxcsr = 0;
 | 
			
		||||
	}
 | 
			
		||||
	fesetenv(envp);
 | 
			
		||||
	feraiseexcept((mxcsr | status) & FE_ALL_EXCEPT);
 | 
			
		||||
	return (0);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int
 | 
			
		||||
__feenableexcept(int mask)
 | 
			
		||||
feenableexcept(int mask)
 | 
			
		||||
{
 | 
			
		||||
	int mxcsr, control, omask;
 | 
			
		||||
	__uint32_t mxcsr;
 | 
			
		||||
	__uint16_t control, omask;
 | 
			
		||||
 | 
			
		||||
	mask &= FE_ALL_EXCEPT;
 | 
			
		||||
	__fnstcw(&control);
 | 
			
		||||
	if (__HAS_SSE())
 | 
			
		||||
		__stmxcsr(&mxcsr);
 | 
			
		||||
	else
 | 
			
		||||
		mxcsr = 0;
 | 
			
		||||
	omask = (control | mxcsr >> _SSE_EMASK_SHIFT) & FE_ALL_EXCEPT;
 | 
			
		||||
	control &= ~mask;
 | 
			
		||||
	__fldcw(control);
 | 
			
		||||
	if (__HAS_SSE()) {
 | 
			
		||||
		mxcsr &= ~(mask << _SSE_EMASK_SHIFT);
 | 
			
		||||
		__ldmxcsr(mxcsr);
 | 
			
		||||
		__stmxcsr(&mxcsr);
 | 
			
		||||
	} else {
 | 
			
		||||
		mxcsr = 0;
 | 
			
		||||
	}
 | 
			
		||||
	return (~omask);
 | 
			
		||||
	omask = ~(control | mxcsr >> _SSE_EMASK_SHIFT) & FE_ALL_EXCEPT;
 | 
			
		||||
	if (mask) {
 | 
			
		||||
		control &= ~mask;
 | 
			
		||||
		__fldcw(control);
 | 
			
		||||
		if (__HAS_SSE()) {
 | 
			
		||||
			mxcsr &= ~(mask << _SSE_EMASK_SHIFT);
 | 
			
		||||
			__ldmxcsr(mxcsr);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return (omask);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int
 | 
			
		||||
__fedisableexcept(int mask)
 | 
			
		||||
fedisableexcept(int mask)
 | 
			
		||||
{
 | 
			
		||||
	int mxcsr, control, omask;
 | 
			
		||||
	__uint32_t mxcsr;
 | 
			
		||||
	__uint16_t control, omask;
 | 
			
		||||
 | 
			
		||||
	mask &= FE_ALL_EXCEPT;
 | 
			
		||||
	__fnstcw(&control);
 | 
			
		||||
	if (__HAS_SSE())
 | 
			
		||||
		__stmxcsr(&mxcsr);
 | 
			
		||||
	else
 | 
			
		||||
		mxcsr = 0;
 | 
			
		||||
	omask = (control | mxcsr >> _SSE_EMASK_SHIFT) & FE_ALL_EXCEPT;
 | 
			
		||||
	control |= mask;
 | 
			
		||||
	__fldcw(control);
 | 
			
		||||
	if (__HAS_SSE()) {
 | 
			
		||||
		mxcsr |= mask << _SSE_EMASK_SHIFT;
 | 
			
		||||
		__ldmxcsr(mxcsr);
 | 
			
		||||
		__stmxcsr(&mxcsr);
 | 
			
		||||
	} else {
 | 
			
		||||
		mxcsr = 0;
 | 
			
		||||
	}
 | 
			
		||||
	return (~omask);
 | 
			
		||||
	omask = ~(control | mxcsr >> _SSE_EMASK_SHIFT) & FE_ALL_EXCEPT;
 | 
			
		||||
	if (mask) {
 | 
			
		||||
		control |= mask;
 | 
			
		||||
		__fldcw(control);
 | 
			
		||||
		if (__HAS_SSE()) {
 | 
			
		||||
			mxcsr |= mask << _SSE_EMASK_SHIFT;
 | 
			
		||||
			__ldmxcsr(mxcsr);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return (omask);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
__weak_reference(__feenableexcept, feenableexcept);
 | 
			
		||||
__weak_reference(__fedisableexcept, fedisableexcept);
 | 
			
		||||
int
 | 
			
		||||
feclearexcept(int excepts)
 | 
			
		||||
{
 | 
			
		||||
	fenv_t env;
 | 
			
		||||
	__uint32_t mxcsr;
 | 
			
		||||
 | 
			
		||||
	excepts &= FE_ALL_EXCEPT;
 | 
			
		||||
	if (excepts) { /* Do nothing if excepts is 0 */
 | 
			
		||||
		__fnstenv(&env);
 | 
			
		||||
		env.__status &= ~excepts;
 | 
			
		||||
		__fnclex();
 | 
			
		||||
		__fldenv(env);
 | 
			
		||||
		if (__HAS_SSE()) {
 | 
			
		||||
			__stmxcsr(&mxcsr);
 | 
			
		||||
			mxcsr &= ~excepts;
 | 
			
		||||
			__ldmxcsr(mxcsr);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return (0);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int
 | 
			
		||||
fegetexceptflag(fexcept_t *flagp, int excepts)
 | 
			
		||||
{
 | 
			
		||||
	__uint32_t mxcsr;
 | 
			
		||||
	__uint16_t status;
 | 
			
		||||
 | 
			
		||||
	excepts &= FE_ALL_EXCEPT;
 | 
			
		||||
	__fnstsw(&status);
 | 
			
		||||
	if (__HAS_SSE()) {
 | 
			
		||||
		__stmxcsr(&mxcsr);
 | 
			
		||||
	} else {
 | 
			
		||||
		mxcsr = 0;
 | 
			
		||||
	}
 | 
			
		||||
	*flagp = (status | mxcsr) & excepts;
 | 
			
		||||
	return (0);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int
 | 
			
		||||
fetestexcept(int excepts)
 | 
			
		||||
{
 | 
			
		||||
	__uint32_t mxcsr;
 | 
			
		||||
	__uint16_t status;
 | 
			
		||||
 | 
			
		||||
	excepts &= FE_ALL_EXCEPT;
 | 
			
		||||
	if (excepts) { /* Do nothing if excepts is 0 */
 | 
			
		||||
		__fnstsw(&status);
 | 
			
		||||
		if (__HAS_SSE()) {
 | 
			
		||||
			__stmxcsr(&mxcsr);
 | 
			
		||||
		} else {
 | 
			
		||||
			mxcsr = 0;
 | 
			
		||||
		}
 | 
			
		||||
		return ((status | mxcsr) & excepts);
 | 
			
		||||
	}
 | 
			
		||||
	return (0);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int
 | 
			
		||||
fegetround(void)
 | 
			
		||||
{
 | 
			
		||||
	__uint16_t control;
 | 
			
		||||
 | 
			
		||||
	/*
 | 
			
		||||
	 * We assume that the x87 and the SSE unit agree on the
 | 
			
		||||
	 * rounding mode.  Reading the control word on the x87 turns
 | 
			
		||||
	 * out to be about 5 times faster than reading it on the SSE
 | 
			
		||||
	 * unit on an Opteron 244.
 | 
			
		||||
	 */
 | 
			
		||||
	__fnstcw(&control);
 | 
			
		||||
	return (control & _ROUND_MASK);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int
 | 
			
		||||
fesetround(int round)
 | 
			
		||||
{
 | 
			
		||||
	__uint32_t mxcsr;
 | 
			
		||||
	__uint16_t control;
 | 
			
		||||
 | 
			
		||||
	if (round & ~_ROUND_MASK) {
 | 
			
		||||
		return (-1);
 | 
			
		||||
	} else {
 | 
			
		||||
		__fnstcw(&control);
 | 
			
		||||
		control &= ~_ROUND_MASK;
 | 
			
		||||
		control |= round;
 | 
			
		||||
		__fldcw(control);
 | 
			
		||||
		if (__HAS_SSE()) {
 | 
			
		||||
			__stmxcsr(&mxcsr);
 | 
			
		||||
			mxcsr &= ~(_ROUND_MASK << _SSE_ROUND_SHIFT);
 | 
			
		||||
			mxcsr |= round << _SSE_ROUND_SHIFT;
 | 
			
		||||
			__ldmxcsr(mxcsr);
 | 
			
		||||
		}
 | 
			
		||||
		return (0);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int
 | 
			
		||||
fesetenv(const fenv_t *envp)
 | 
			
		||||
{
 | 
			
		||||
	fenv_t env = *envp;
 | 
			
		||||
	__uint32_t mxcsr;
 | 
			
		||||
 | 
			
		||||
	mxcsr = (env.__mxcsr_hi << 16) | (env.__mxcsr_lo);
 | 
			
		||||
	env.__mxcsr_hi = 0xffff;
 | 
			
		||||
	env.__mxcsr_lo = 0xffff;
 | 
			
		||||
	/*
 | 
			
		||||
	 * XXX Using fldenvx() instead of fldenv() tells the compiler that this
 | 
			
		||||
	 * instruction clobbers the i387 register stack.  This happens because
 | 
			
		||||
	 * we restore the tag word from the saved environment.  Normally, this
 | 
			
		||||
	 * would happen anyway and we wouldn't care, because the ABI allows
 | 
			
		||||
	 * function calls to clobber the i387 regs.  However, fesetenv() is
 | 
			
		||||
	 * inlined, so we need to be more careful.
 | 
			
		||||
	 */
 | 
			
		||||
	__fldenvx(env);
 | 
			
		||||
	if (__HAS_SSE()) {
 | 
			
		||||
		__ldmxcsr(mxcsr);
 | 
			
		||||
	}
 | 
			
		||||
	return (0);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int
 | 
			
		||||
fegetexcept(void)
 | 
			
		||||
{
 | 
			
		||||
	__uint16_t control;
 | 
			
		||||
 | 
			
		||||
	/*
 | 
			
		||||
	 * We assume that the masks for the x87 and the SSE unit are
 | 
			
		||||
	 * the same.
 | 
			
		||||
	 */
 | 
			
		||||
	__fnstcw(&control);
 | 
			
		||||
	return (~control & FE_ALL_EXCEPT);
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										240
									
								
								libm/i387/fenv.h
									
									
									
									
									
								
							
							
						
						
									
										240
									
								
								libm/i387/fenv.h
									
									
									
									
									
								
							@@ -1,240 +0,0 @@
 | 
			
		||||
/*-
 | 
			
		||||
 * Copyright (c) 2004-2005 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.
 | 
			
		||||
 *
 | 
			
		||||
 * $FreeBSD: src/lib/msun/i387/fenv.h,v 1.4 2005/03/17 22:21:46 das Exp $
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef	_FENV_H_
 | 
			
		||||
#define	_FENV_H_
 | 
			
		||||
 | 
			
		||||
#include <sys/cdefs.h>
 | 
			
		||||
#include <sys/_types.h>
 | 
			
		||||
 | 
			
		||||
/*                   
 | 
			
		||||
 * To preserve binary compatibility with FreeBSD 5.3, we pack the
 | 
			
		||||
 * mxcsr into some reserved fields, rather than changing sizeof(fenv_t).
 | 
			
		||||
 */
 | 
			
		||||
typedef struct {
 | 
			
		||||
	__uint16_t	__control;
 | 
			
		||||
	__uint16_t      __mxcsr_hi;
 | 
			
		||||
	__uint16_t	__status;
 | 
			
		||||
	__uint16_t      __mxcsr_lo;
 | 
			
		||||
	__uint32_t	__tag;
 | 
			
		||||
	char		__other[16];
 | 
			
		||||
} fenv_t;
 | 
			
		||||
 | 
			
		||||
#define	__get_mxcsr(env)	(((env).__mxcsr_hi << 16) |	\
 | 
			
		||||
				 ((env).__mxcsr_lo))
 | 
			
		||||
#define	__set_mxcsr(env, x)	do {				\
 | 
			
		||||
	(env).__mxcsr_hi = (__uint32_t)(x) >> 16;		\
 | 
			
		||||
	(env).__mxcsr_lo = (__uint16_t)(x);			\
 | 
			
		||||
} while (0)
 | 
			
		||||
 | 
			
		||||
typedef	__uint16_t	fexcept_t;
 | 
			
		||||
 | 
			
		||||
/* Exception flags */
 | 
			
		||||
#define	FE_INVALID	0x01
 | 
			
		||||
#define	FE_DENORMAL	0x02
 | 
			
		||||
#define	FE_DIVBYZERO	0x04
 | 
			
		||||
#define	FE_OVERFLOW	0x08
 | 
			
		||||
#define	FE_UNDERFLOW	0x10
 | 
			
		||||
#define	FE_INEXACT	0x20
 | 
			
		||||
#define	FE_ALL_EXCEPT	(FE_DIVBYZERO | FE_DENORMAL | FE_INEXACT | \
 | 
			
		||||
			 FE_INVALID | FE_OVERFLOW | FE_UNDERFLOW)
 | 
			
		||||
 | 
			
		||||
/* Rounding modes */
 | 
			
		||||
#define	FE_TONEAREST	0x0000
 | 
			
		||||
#define	FE_DOWNWARD	0x0400
 | 
			
		||||
#define	FE_UPWARD	0x0800
 | 
			
		||||
#define	FE_TOWARDZERO	0x0c00
 | 
			
		||||
#define	_ROUND_MASK	(FE_TONEAREST | FE_DOWNWARD | \
 | 
			
		||||
			 FE_UPWARD | FE_TOWARDZERO)
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * As compared to the x87 control word, the SSE unit's control word
 | 
			
		||||
 * has the rounding control bits offset by 3 and the exception mask
 | 
			
		||||
 * bits offset by 7.
 | 
			
		||||
 */
 | 
			
		||||
#define	_SSE_ROUND_SHIFT	3
 | 
			
		||||
#define	_SSE_EMASK_SHIFT	7
 | 
			
		||||
 | 
			
		||||
/* After testing for SSE support once, we cache the result in __has_sse. */
 | 
			
		||||
enum __sse_support { __SSE_YES, __SSE_NO, __SSE_UNK };
 | 
			
		||||
extern enum __sse_support __has_sse;
 | 
			
		||||
int __test_sse(void);
 | 
			
		||||
#ifdef __SSE__
 | 
			
		||||
#define	__HAS_SSE()	1
 | 
			
		||||
#else
 | 
			
		||||
#define	__HAS_SSE()	(__has_sse == __SSE_YES ||			\
 | 
			
		||||
			 (__has_sse == __SSE_UNK && __test_sse()))
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
__BEGIN_DECLS
 | 
			
		||||
 | 
			
		||||
/* Default floating-point environment */
 | 
			
		||||
extern const fenv_t	__fe_dfl_env;
 | 
			
		||||
#define	FE_DFL_ENV	(&__fe_dfl_env)
 | 
			
		||||
 | 
			
		||||
#define	__fldcw(__cw)		__asm __volatile("fldcw %0" : : "m" (__cw))
 | 
			
		||||
#define	__fldenv(__env)		__asm __volatile("fldenv %0" : : "m" (__env))
 | 
			
		||||
#define	__fnclex()		__asm __volatile("fnclex")
 | 
			
		||||
#define	__fnstenv(__env)	__asm __volatile("fnstenv %0" : "=m" (*(__env)))
 | 
			
		||||
#define	__fnstcw(__cw)		__asm __volatile("fnstcw %0" : "=m" (*(__cw)))
 | 
			
		||||
#define	__fnstsw(__sw)		__asm __volatile("fnstsw %0" : "=am" (*(__sw)))
 | 
			
		||||
#define	__fwait()		__asm __volatile("fwait")
 | 
			
		||||
#define	__ldmxcsr(__csr)	__asm __volatile("ldmxcsr %0" : : "m" (__csr))
 | 
			
		||||
#define	__stmxcsr(__csr)	__asm __volatile("stmxcsr %0" : "=m" (*(__csr)))
 | 
			
		||||
 | 
			
		||||
static __inline int
 | 
			
		||||
feclearexcept(int __excepts)
 | 
			
		||||
{
 | 
			
		||||
	fenv_t __env;
 | 
			
		||||
	int __mxcsr;
 | 
			
		||||
 | 
			
		||||
	if (__excepts == FE_ALL_EXCEPT) {
 | 
			
		||||
		__fnclex();
 | 
			
		||||
	} else {
 | 
			
		||||
		__fnstenv(&__env);
 | 
			
		||||
		__env.__status &= ~__excepts;
 | 
			
		||||
		__fldenv(__env);
 | 
			
		||||
	}
 | 
			
		||||
	if (__HAS_SSE()) {
 | 
			
		||||
		__stmxcsr(&__mxcsr);
 | 
			
		||||
		__mxcsr &= ~__excepts;
 | 
			
		||||
		__ldmxcsr(__mxcsr);
 | 
			
		||||
	}
 | 
			
		||||
	return (0);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static __inline int
 | 
			
		||||
fegetexceptflag(fexcept_t *__flagp, int __excepts)
 | 
			
		||||
{
 | 
			
		||||
	int __mxcsr, __status;
 | 
			
		||||
 | 
			
		||||
	__fnstsw(&__status);
 | 
			
		||||
	if (__HAS_SSE())
 | 
			
		||||
		__stmxcsr(&__mxcsr);
 | 
			
		||||
	else
 | 
			
		||||
		__mxcsr = 0;
 | 
			
		||||
	*__flagp = (__mxcsr | __status) & __excepts;
 | 
			
		||||
	return (0);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int fesetexceptflag(const fexcept_t *__flagp, int __excepts);
 | 
			
		||||
int feraiseexcept(int __excepts);
 | 
			
		||||
 | 
			
		||||
static __inline int
 | 
			
		||||
fetestexcept(int __excepts)
 | 
			
		||||
{
 | 
			
		||||
	int __mxcsr, __status;
 | 
			
		||||
 | 
			
		||||
	__fnstsw(&__status);
 | 
			
		||||
	if (__HAS_SSE())
 | 
			
		||||
		__stmxcsr(&__mxcsr);
 | 
			
		||||
	else
 | 
			
		||||
		__mxcsr = 0;
 | 
			
		||||
	return ((__status | __mxcsr) & __excepts);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static __inline int
 | 
			
		||||
fegetround(void)
 | 
			
		||||
{
 | 
			
		||||
	int __control;
 | 
			
		||||
 | 
			
		||||
	/*
 | 
			
		||||
	 * We assume that the x87 and the SSE unit agree on the
 | 
			
		||||
	 * rounding mode.  Reading the control word on the x87 turns
 | 
			
		||||
	 * out to be about 5 times faster than reading it on the SSE
 | 
			
		||||
	 * unit on an Opteron 244.
 | 
			
		||||
	 */
 | 
			
		||||
	__fnstcw(&__control);
 | 
			
		||||
	return (__control & _ROUND_MASK);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static __inline int
 | 
			
		||||
fesetround(int __round)
 | 
			
		||||
{
 | 
			
		||||
	int __mxcsr, __control;
 | 
			
		||||
 | 
			
		||||
	if (__round & ~_ROUND_MASK)
 | 
			
		||||
		return (-1);
 | 
			
		||||
 | 
			
		||||
	__fnstcw(&__control);
 | 
			
		||||
	__control &= ~_ROUND_MASK;
 | 
			
		||||
	__control |= __round;
 | 
			
		||||
	__fldcw(__control);
 | 
			
		||||
 | 
			
		||||
	if (__HAS_SSE()) {
 | 
			
		||||
		__stmxcsr(&__mxcsr);
 | 
			
		||||
		__mxcsr &= ~(_ROUND_MASK << _SSE_ROUND_SHIFT);
 | 
			
		||||
		__mxcsr |= __round << _SSE_ROUND_SHIFT;
 | 
			
		||||
		__ldmxcsr(__mxcsr);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return (0);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int fegetenv(fenv_t *__envp);
 | 
			
		||||
int feholdexcept(fenv_t *__envp);
 | 
			
		||||
 | 
			
		||||
static __inline int
 | 
			
		||||
fesetenv(const fenv_t *__envp)
 | 
			
		||||
{
 | 
			
		||||
	fenv_t __env = *__envp;
 | 
			
		||||
	int __mxcsr;
 | 
			
		||||
 | 
			
		||||
	__mxcsr = __get_mxcsr(__env);
 | 
			
		||||
	__set_mxcsr(__env, 0xffffffff);
 | 
			
		||||
	__fldenv(__env);
 | 
			
		||||
	if (__HAS_SSE())
 | 
			
		||||
		__ldmxcsr(__mxcsr);
 | 
			
		||||
	return (0);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int feupdateenv(const fenv_t *__envp);
 | 
			
		||||
 | 
			
		||||
#if __BSD_VISIBLE
 | 
			
		||||
 | 
			
		||||
int feenableexcept(int __mask);
 | 
			
		||||
int fedisableexcept(int __mask);
 | 
			
		||||
 | 
			
		||||
static __inline int
 | 
			
		||||
fegetexcept(void)
 | 
			
		||||
{
 | 
			
		||||
	int __control;
 | 
			
		||||
 | 
			
		||||
	/*
 | 
			
		||||
	 * We assume that the masks for the x87 and the SSE unit are
 | 
			
		||||
	 * the same.
 | 
			
		||||
	 */
 | 
			
		||||
	__fnstcw(&__control);
 | 
			
		||||
	return (~__control & FE_ALL_EXCEPT);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif /* __BSD_VISIBLE */
 | 
			
		||||
 | 
			
		||||
__END_DECLS
 | 
			
		||||
 | 
			
		||||
#endif	/* !_FENV_H_ */
 | 
			
		||||
@@ -45,13 +45,6 @@ typedef struct {
 | 
			
		||||
	char		__other[16];
 | 
			
		||||
} fenv_t;
 | 
			
		||||
 | 
			
		||||
#define	__get_mxcsr(env)	(((env).__mxcsr_hi << 16) |	\
 | 
			
		||||
				 ((env).__mxcsr_lo))
 | 
			
		||||
#define	__set_mxcsr(env, x)	do {				\
 | 
			
		||||
	(env).__mxcsr_hi = (__uint32_t)(x) >> 16;		\
 | 
			
		||||
	(env).__mxcsr_lo = (__uint16_t)(x);			\
 | 
			
		||||
} while (0)
 | 
			
		||||
 | 
			
		||||
typedef	__uint16_t	fexcept_t;
 | 
			
		||||
 | 
			
		||||
/* Exception flags */
 | 
			
		||||
@@ -72,166 +65,35 @@ typedef	__uint16_t	fexcept_t;
 | 
			
		||||
#define	_ROUND_MASK	(FE_TONEAREST | FE_DOWNWARD | \
 | 
			
		||||
			 FE_UPWARD | FE_TOWARDZERO)
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * As compared to the x87 control word, the SSE unit's control word
 | 
			
		||||
 * has the rounding control bits offset by 3 and the exception mask
 | 
			
		||||
 * bits offset by 7.
 | 
			
		||||
 */
 | 
			
		||||
#define	_SSE_ROUND_SHIFT	3
 | 
			
		||||
#define	_SSE_EMASK_SHIFT	7
 | 
			
		||||
 | 
			
		||||
/* After testing for SSE support once, we cache the result in __has_sse. */
 | 
			
		||||
enum __sse_support { __SSE_YES, __SSE_NO, __SSE_UNK };
 | 
			
		||||
extern enum __sse_support __has_sse;
 | 
			
		||||
int __test_sse(void);
 | 
			
		||||
#ifdef __SSE__
 | 
			
		||||
#define	__HAS_SSE()	1
 | 
			
		||||
#else
 | 
			
		||||
#define	__HAS_SSE()	(__has_sse == __SSE_YES ||			\
 | 
			
		||||
			 (__has_sse == __SSE_UNK && __test_sse()))
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
__BEGIN_DECLS
 | 
			
		||||
 | 
			
		||||
/* Default floating-point environment */
 | 
			
		||||
extern const fenv_t	__fe_dfl_env;
 | 
			
		||||
#define	FE_DFL_ENV	(&__fe_dfl_env)
 | 
			
		||||
 | 
			
		||||
#define	__fldcw(__cw)		__asm __volatile("fldcw %0" : : "m" (__cw))
 | 
			
		||||
#define	__fldenv(__env)		__asm __volatile("fldenv %0" : : "m" (__env))
 | 
			
		||||
#define	__fnclex()		__asm __volatile("fnclex")
 | 
			
		||||
#define	__fnstenv(__env)	__asm __volatile("fnstenv %0" : "=m" (*(__env)))
 | 
			
		||||
#define	__fnstcw(__cw)		__asm __volatile("fnstcw %0" : "=m" (*(__cw)))
 | 
			
		||||
#define	__fnstsw(__sw)		__asm __volatile("fnstsw %0" : "=am" (*(__sw)))
 | 
			
		||||
#define	__fwait()		__asm __volatile("fwait")
 | 
			
		||||
#define	__ldmxcsr(__csr)	__asm __volatile("ldmxcsr %0" : : "m" (__csr))
 | 
			
		||||
#define	__stmxcsr(__csr)	__asm __volatile("stmxcsr %0" : "=m" (*(__csr)))
 | 
			
		||||
/* C99 floating-point exception functions */
 | 
			
		||||
int feclearexcept(int excepts);
 | 
			
		||||
int fegetexceptflag(fexcept_t *flagp, int excepts);
 | 
			
		||||
int fesetexceptflag(const fexcept_t *flagp, int excepts);
 | 
			
		||||
/* feraiseexcept does not set the inexact flag on overflow/underflow */
 | 
			
		||||
int feraiseexcept(int excepts);
 | 
			
		||||
int fetestexcept(int excepts);
 | 
			
		||||
 | 
			
		||||
static __inline int
 | 
			
		||||
feclearexcept(int __excepts)
 | 
			
		||||
{
 | 
			
		||||
	fenv_t __env;
 | 
			
		||||
	int __mxcsr;
 | 
			
		||||
 | 
			
		||||
	if (__excepts == FE_ALL_EXCEPT) {
 | 
			
		||||
		__fnclex();
 | 
			
		||||
	} else {
 | 
			
		||||
		__fnstenv(&__env);
 | 
			
		||||
		__env.__status &= ~__excepts;
 | 
			
		||||
		__fldenv(__env);
 | 
			
		||||
	}
 | 
			
		||||
	if (__HAS_SSE()) {
 | 
			
		||||
		__stmxcsr(&__mxcsr);
 | 
			
		||||
		__mxcsr &= ~__excepts;
 | 
			
		||||
		__ldmxcsr(__mxcsr);
 | 
			
		||||
	}
 | 
			
		||||
	return (0);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static __inline int
 | 
			
		||||
fegetexceptflag(fexcept_t *__flagp, int __excepts)
 | 
			
		||||
{
 | 
			
		||||
	int __mxcsr, __status;
 | 
			
		||||
 | 
			
		||||
	__fnstsw(&__status);
 | 
			
		||||
	if (__HAS_SSE())
 | 
			
		||||
		__stmxcsr(&__mxcsr);
 | 
			
		||||
	else
 | 
			
		||||
		__mxcsr = 0;
 | 
			
		||||
	*__flagp = (__mxcsr | __status) & __excepts;
 | 
			
		||||
	return (0);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int fesetexceptflag(const fexcept_t *__flagp, int __excepts);
 | 
			
		||||
int feraiseexcept(int __excepts);
 | 
			
		||||
 | 
			
		||||
static __inline int
 | 
			
		||||
fetestexcept(int __excepts)
 | 
			
		||||
{
 | 
			
		||||
	int __mxcsr, __status;
 | 
			
		||||
 | 
			
		||||
	__fnstsw(&__status);
 | 
			
		||||
	if (__HAS_SSE())
 | 
			
		||||
		__stmxcsr(&__mxcsr);
 | 
			
		||||
	else
 | 
			
		||||
		__mxcsr = 0;
 | 
			
		||||
	return ((__status | __mxcsr) & __excepts);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static __inline int
 | 
			
		||||
fegetround(void)
 | 
			
		||||
{
 | 
			
		||||
	int __control;
 | 
			
		||||
 | 
			
		||||
	/*
 | 
			
		||||
	 * We assume that the x87 and the SSE unit agree on the
 | 
			
		||||
	 * rounding mode.  Reading the control word on the x87 turns
 | 
			
		||||
	 * out to be about 5 times faster than reading it on the SSE
 | 
			
		||||
	 * unit on an Opteron 244.
 | 
			
		||||
	 */
 | 
			
		||||
	__fnstcw(&__control);
 | 
			
		||||
	return (__control & _ROUND_MASK);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static __inline int
 | 
			
		||||
fesetround(int __round)
 | 
			
		||||
{
 | 
			
		||||
	int __mxcsr, __control;
 | 
			
		||||
 | 
			
		||||
	if (__round & ~_ROUND_MASK)
 | 
			
		||||
		return (-1);
 | 
			
		||||
 | 
			
		||||
	__fnstcw(&__control);
 | 
			
		||||
	__control &= ~_ROUND_MASK;
 | 
			
		||||
	__control |= __round;
 | 
			
		||||
	__fldcw(__control);
 | 
			
		||||
 | 
			
		||||
	if (__HAS_SSE()) {
 | 
			
		||||
		__stmxcsr(&__mxcsr);
 | 
			
		||||
		__mxcsr &= ~(_ROUND_MASK << _SSE_ROUND_SHIFT);
 | 
			
		||||
		__mxcsr |= __round << _SSE_ROUND_SHIFT;
 | 
			
		||||
		__ldmxcsr(__mxcsr);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return (0);
 | 
			
		||||
}
 | 
			
		||||
/* C99 rounding control functions */
 | 
			
		||||
int fegetround(void);
 | 
			
		||||
int fesetround(int round);
 | 
			
		||||
 | 
			
		||||
/* C99 floating-point environment functions */
 | 
			
		||||
int fegetenv(fenv_t *__envp);
 | 
			
		||||
int feholdexcept(fenv_t *__envp);
 | 
			
		||||
 | 
			
		||||
static __inline int
 | 
			
		||||
fesetenv(const fenv_t *__envp)
 | 
			
		||||
{
 | 
			
		||||
	fenv_t __env = *__envp;
 | 
			
		||||
	int __mxcsr;
 | 
			
		||||
 | 
			
		||||
	__mxcsr = __get_mxcsr(__env);
 | 
			
		||||
	__set_mxcsr(__env, 0xffffffff);
 | 
			
		||||
	__fldenv(__env);
 | 
			
		||||
	if (__HAS_SSE())
 | 
			
		||||
		__ldmxcsr(__mxcsr);
 | 
			
		||||
	return (0);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int fesetenv(const fenv_t *envp);
 | 
			
		||||
int feupdateenv(const fenv_t *__envp);
 | 
			
		||||
 | 
			
		||||
#if __BSD_VISIBLE
 | 
			
		||||
 | 
			
		||||
/* Additional support functions to set/query floating point traps */
 | 
			
		||||
int feenableexcept(int __mask);
 | 
			
		||||
int fedisableexcept(int __mask);
 | 
			
		||||
 | 
			
		||||
static __inline int
 | 
			
		||||
fegetexcept(void)
 | 
			
		||||
{
 | 
			
		||||
	int __control;
 | 
			
		||||
 | 
			
		||||
	/*
 | 
			
		||||
	 * We assume that the masks for the x87 and the SSE unit are
 | 
			
		||||
	 * the same.
 | 
			
		||||
	 */
 | 
			
		||||
	__fnstcw(&__control);
 | 
			
		||||
	return (~__control & FE_ALL_EXCEPT);
 | 
			
		||||
}
 | 
			
		||||
int fegetexcept(void);
 | 
			
		||||
 | 
			
		||||
#endif /* __BSD_VISIBLE */
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -22,12 +22,7 @@ include $(CLEAR_VARS)
 | 
			
		||||
LOCAL_WHOLE_STATIC_LIBRARIES := libthread_db
 | 
			
		||||
LOCAL_MODULE:=libthread_db
 | 
			
		||||
LOCAL_SHARED_LIBRARIES := libdl
 | 
			
		||||
 | 
			
		||||
# NOTE: Using --no-undefined results in a missing symbol that is defined inside
 | 
			
		||||
# gdbserver and is resolved at runtime. Since there is no library containing
 | 
			
		||||
# this symbol that we can link against, set LOCAL_ALLOW_UNDEFINED_SYMBOLS so
 | 
			
		||||
# that --no-undefined is removed from the linker flags.
 | 
			
		||||
LOCAL_ALLOW_UNDEFINED_SYMBOLS := true
 | 
			
		||||
LOCAL_ALLOW_UNDEFINED_SYMBOLS := false
 | 
			
		||||
LOCAL_SYSTEM_SHARED_LIBRARIES :=
 | 
			
		||||
 | 
			
		||||
include $(BUILD_SHARED_LIBRARY)
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										22
									
								
								libthread_db/include/sys/procfs.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										22
									
								
								libthread_db/include/sys/procfs.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,22 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright 2006 The Android Open Source Project
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef _SYS_PROCFS_H
 | 
			
		||||
#define _SYS_PROCFS_H
 | 
			
		||||
 | 
			
		||||
#include <sys/types.h>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
extern "C"{
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
typedef pid_t lwpid_t;
 | 
			
		||||
typedef void *psaddr_t;
 | 
			
		||||
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
@@ -9,9 +9,7 @@
 | 
			
		||||
#include <signal.h>
 | 
			
		||||
#include <stdint.h>
 | 
			
		||||
#include <sys/types.h>
 | 
			
		||||
 | 
			
		||||
typedef void *psaddr_t;
 | 
			
		||||
typedef pid_t lwpid_t;
 | 
			
		||||
#include <sys/procfs.h>
 | 
			
		||||
 | 
			
		||||
#define TD_THR_ANY_USER_FLAGS       0xffffffff
 | 
			
		||||
#define TD_THR_LOWEST_PRIORITY      -20
 | 
			
		||||
@@ -151,6 +149,10 @@ extern td_err_e td_thr_event_enable(td_thrhandle_t const * handle,
 | 
			
		||||
extern td_err_e td_ta_thr_iter(td_thragent_t const * agent, td_thr_iter_f * func, void * cookie,
 | 
			
		||||
                               td_thr_state_e state, int32_t prio, sigset_t * sigmask, uint32_t user_flags);
 | 
			
		||||
 | 
			
		||||
extern td_err_e td_thr_event_enable(td_thrhandle_t const * handle, td_event_e event);
 | 
			
		||||
 | 
			
		||||
extern td_err_e td_thr_get_info(td_thrhandle_t const * handle, td_thrinfo_t * info);
 | 
			
		||||
 | 
			
		||||
extern char const ** td_symbol_list(void);
 | 
			
		||||
 | 
			
		||||
extern td_err_e td_thr_tls_get_addr(const td_thrhandle_t * th,
 | 
			
		||||
 
 | 
			
		||||
@@ -81,6 +81,25 @@ _event_getmsg_helper(td_thrhandle_t const * handle, void * bkpt_addr)
 | 
			
		||||
{
 | 
			
		||||
    void * pc;
 | 
			
		||||
 | 
			
		||||
#ifdef __i386__
 | 
			
		||||
    /* Get the eip from offset 12*4 = 48 as defined in the struct
 | 
			
		||||
     * user_regs_struct in user_32.h
 | 
			
		||||
     */
 | 
			
		||||
    pc = (void *)ptrace(PTRACE_PEEKUSR, handle->tid, (void *)48 /* eip */, NULL);
 | 
			
		||||
    /* FIXME - pc is a non-decremented breakpoint address, hence the
 | 
			
		||||
     * addition of 1 on test.  This seems to work for the thread hook
 | 
			
		||||
     * function in libc.so but should be properly fixed.
 | 
			
		||||
     */
 | 
			
		||||
    if (pc == ((int)bkpt_addr + 1)) {
 | 
			
		||||
        /* The hook function takes the id of the new thread as it's first
 | 
			
		||||
         * param, so grab it from ecx at offset 4 in struct user_regs_struct
 | 
			
		||||
         * (using fastcall convention for x86)
 | 
			
		||||
         */
 | 
			
		||||
        gEventMsgHandle.pid = ptrace(PTRACE_PEEKUSR, handle->tid, (void *)4 /* ecx */, NULL);
 | 
			
		||||
        gEventMsgHandle.tid = gEventMsgHandle.pid;
 | 
			
		||||
        return 0x42;
 | 
			
		||||
    }
 | 
			
		||||
#else
 | 
			
		||||
    pc = (void *)ptrace(PTRACE_PEEKUSR, handle->tid, (void *)60 /* r15/pc */, NULL);
 | 
			
		||||
 | 
			
		||||
    if (pc == bkpt_addr) {
 | 
			
		||||
@@ -90,6 +109,7 @@ _event_getmsg_helper(td_thrhandle_t const * handle, void * bkpt_addr)
 | 
			
		||||
        gEventMsgHandle.tid = gEventMsgHandle.pid;
 | 
			
		||||
        return 0x42;
 | 
			
		||||
    }
 | 
			
		||||
#endif
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -156,7 +176,7 @@ td_ta_event_addr(td_thragent_t const * agent, td_event_e event, td_notify_t * no
 | 
			
		||||
{
 | 
			
		||||
    int32_t err;
 | 
			
		||||
 | 
			
		||||
    /* 
 | 
			
		||||
    /*
 | 
			
		||||
     * This is nasty, ps_pglobal_lookup is implemented in gdbserver and looks up
 | 
			
		||||
     * the symbol from it's cache, which is populated at start time with the
 | 
			
		||||
     * symbols returned from td_symbol_list via calls back to the host.
 | 
			
		||||
 
 | 
			
		||||
@@ -49,6 +49,7 @@ LOCAL_CFLAGS += -DANDROID_ARM_LINKER
 | 
			
		||||
else
 | 
			
		||||
  ifeq ($(TARGET_ARCH),x86)
 | 
			
		||||
    LOCAL_CFLAGS += -DANDROID_X86_LINKER
 | 
			
		||||
    LOCAL_CFLAGS += -I$(LOCAL_PATH)/../libc/arch-x86/bionic
 | 
			
		||||
  else
 | 
			
		||||
    ifeq ($(TARGET_ARCH),sh)
 | 
			
		||||
      LOCAL_CFLAGS += -DANDROID_SH_LINKER
 | 
			
		||||
 
 | 
			
		||||
@@ -44,9 +44,5 @@ _start:
 | 
			
		||||
        popl   %esp
 | 
			
		||||
        jmp    *%eax
 | 
			
		||||
 | 
			
		||||
.section .ctors, "wa"
 | 
			
		||||
.globl __CTOR_LIST__
 | 
			
		||||
 | 
			
		||||
__CTOR_LIST__:
 | 
			
		||||
        .long -1
 | 
			
		||||
 | 
			
		||||
#include "__stack_chk_fail_local.S"
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user