Compare commits
24 Commits
android-2.
...
android-ct
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 |
@@ -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)
|
||||
{
|
||||
}
|
||||
|
@@ -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
|
||||
|
@@ -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