diff options
author | The Android Open Source Project <initial-contribution@android.com> | 2009-03-03 19:28:35 -0800 |
---|---|---|
committer | The Android Open Source Project <initial-contribution@android.com> | 2009-03-03 19:28:35 -0800 |
commit | 1dc9e472e19acfe6dc7f41e429236e7eef7ceda1 (patch) | |
tree | 3be0c520fae17689bbf5584e1136fb820caef26f /libc/arch-arm/bionic | |
parent | 1767f908af327fa388b1c66883760ad851267013 (diff) | |
download | bionic-1dc9e472e19acfe6dc7f41e429236e7eef7ceda1.zip bionic-1dc9e472e19acfe6dc7f41e429236e7eef7ceda1.tar.gz bionic-1dc9e472e19acfe6dc7f41e429236e7eef7ceda1.tar.bz2 |
auto import from //depot/cupcake/@135843
Diffstat (limited to 'libc/arch-arm/bionic')
-rw-r--r-- | libc/arch-arm/bionic/__get_pc.S | 33 | ||||
-rw-r--r-- | libc/arch-arm/bionic/__get_sp.S | 33 | ||||
-rw-r--r-- | libc/arch-arm/bionic/_exit_with_stack_teardown.S | 55 | ||||
-rw-r--r-- | libc/arch-arm/bionic/_setjmp.S | 106 | ||||
-rw-r--r-- | libc/arch-arm/bionic/atomics_arm.S | 178 | ||||
-rw-r--r-- | libc/arch-arm/bionic/clone.S | 74 | ||||
-rw-r--r-- | libc/arch-arm/bionic/crtbegin_dynamic.S | 92 | ||||
-rw-r--r-- | libc/arch-arm/bionic/crtbegin_static.S | 92 | ||||
-rw-r--r-- | libc/arch-arm/bionic/crtend.S | 40 | ||||
-rw-r--r-- | libc/arch-arm/bionic/exidx_dynamic.c | 47 | ||||
-rw-r--r-- | libc/arch-arm/bionic/exidx_static.c | 45 | ||||
-rw-r--r-- | libc/arch-arm/bionic/ffs.S | 82 | ||||
-rw-r--r-- | libc/arch-arm/bionic/kill.S | 53 | ||||
-rw-r--r-- | libc/arch-arm/bionic/memcmp.S | 285 | ||||
-rw-r--r-- | libc/arch-arm/bionic/memcmp16.S | 236 | ||||
-rw-r--r-- | libc/arch-arm/bionic/memcpy.S | 387 | ||||
-rw-r--r-- | libc/arch-arm/bionic/memset.S | 117 | ||||
-rw-r--r-- | libc/arch-arm/bionic/setjmp.S | 136 | ||||
-rw-r--r-- | libc/arch-arm/bionic/sigsetjmp.S | 62 | ||||
-rw-r--r-- | libc/arch-arm/bionic/strlen.c | 129 | ||||
-rw-r--r-- | libc/arch-arm/bionic/syscall.S | 71 | ||||
-rw-r--r-- | libc/arch-arm/bionic/tkill.S | 53 |
22 files changed, 2406 insertions, 0 deletions
diff --git a/libc/arch-arm/bionic/__get_pc.S b/libc/arch-arm/bionic/__get_pc.S new file mode 100644 index 0000000..d1377c7 --- /dev/null +++ b/libc/arch-arm/bionic/__get_pc.S @@ -0,0 +1,33 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ +.global __get_pc + +__get_pc: + mov r0, pc + bx lr + diff --git a/libc/arch-arm/bionic/__get_sp.S b/libc/arch-arm/bionic/__get_sp.S new file mode 100644 index 0000000..9acaf3d --- /dev/null +++ b/libc/arch-arm/bionic/__get_sp.S @@ -0,0 +1,33 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ +.global __get_sp + +__get_sp: + mov r0, sp + bx lr + diff --git a/libc/arch-arm/bionic/_exit_with_stack_teardown.S b/libc/arch-arm/bionic/_exit_with_stack_teardown.S new file mode 100644 index 0000000..89f6c90 --- /dev/null +++ b/libc/arch-arm/bionic/_exit_with_stack_teardown.S @@ -0,0 +1,55 @@ +/* + * 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 <asm/unistd.h> + +.text +.type _exit_with_stack_teardown, #function +.globl _exit_with_stack_teardown +.align 4 + +@ void _exit_with_stack_teardown(void * stackBase, int stackSize, int retCode) + +_exit_with_stack_teardown: + +#if __ARM_EABI__ + mov lr, r2 + ldr r7, =__NR_munmap + swi #0 @ the stack is destroyed by this call + mov r0, lr + ldr r7, =__NR_exit + swi #0 +#else + mov lr, r2 + swi # __NR_munmap @ the stack is destroyed by this call + mov r0, lr + swi # __NR_exit +#endif + + @ exit() should never return, cause a crash if it does + mov r0, #0 + ldr r0, [r0] diff --git a/libc/arch-arm/bionic/_setjmp.S b/libc/arch-arm/bionic/_setjmp.S new file mode 100644 index 0000000..6a27af2 --- /dev/null +++ b/libc/arch-arm/bionic/_setjmp.S @@ -0,0 +1,106 @@ +/* $OpenBSD: _setjmp.S,v 1.2 2004/02/01 05:40:52 drahn Exp $ */ +/* $NetBSD: _setjmp.S,v 1.5 2003/04/05 23:08:51 bjh21 Exp $ */ + +/* + * Copyright (c) 1997 Mark Brinicombe + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Mark Brinicombe + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include <machine/asm.h> +#include <machine/setjmp.h> + +/* + * C library -- _setjmp, _longjmp + * + * _longjmp(a,v) + * will generate a "return(v)" from the last call to + * _setjmp(a) + * by restoring registers from the stack. + * The previous signal state is NOT restored. + * + * Note: r0 is the return value + * r1-r3 are scratch registers in functions + */ + +ENTRY(_setjmp) + ldr r1, .L_setjmp_magic + str r1, [r0], #4 +#ifdef SOFTFLOAT + add r0, r0, #52 +#else + /* Store fp registers */ + sfm f4, 4, [r0], #48 + /* Store fpsr */ + rfs r1 + str r1, [r0], #0x0004 +#endif /* SOFTFLOAT */ + /* Store integer registers */ + stmia r0, {r4-r14} + + mov r0, #0x00000000 + bx lr + +.L_setjmp_magic: + .word _JB_MAGIC__SETJMP + +ENTRY(_longjmp) + ldr r2, .L_setjmp_magic + ldr r3, [r0], #4 + teq r2, r3 + bne botch + +#ifdef SOFTFLOAT + add r0, r0, #52 +#else + /* Restore fp registers */ + lfm f4, 4, [r0], #48 + /* Restore fpsr */ + ldr r4, [r0], #0x0004 + wfs r4 +#endif /* SOFTFLOAT */ + /* Restore integer registers */ + ldmia r0, {r4-r14} + + /* Validate sp and r14 */ + teq sp, #0 + teqne r14, #0 + beq botch + + /* Set return value */ + mov r0, r1 + teq r0, #0x00000000 + moveq r0, #0x00000001 + bx lr + + /* validation failed, die die die. */ +botch: + bl PIC_SYM(_C_LABEL(longjmperror), PLT) + bl PIC_SYM(_C_LABEL(abort), PLT) + b . - 8 /* Cannot get here */ diff --git a/libc/arch-arm/bionic/atomics_arm.S b/libc/arch-arm/bionic/atomics_arm.S new file mode 100644 index 0000000..b2da09f --- /dev/null +++ b/libc/arch-arm/bionic/atomics_arm.S @@ -0,0 +1,178 @@ +/* + * 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/linux-syscalls.h> + +.global __atomic_cmpxchg +.global __atomic_swap +.global __atomic_dec +.global __atomic_inc +.global __futex_wait +.global __futex_wake + +#define FUTEX_WAIT 0 +#define FUTEX_WAKE 1 + +#if 1 + .equ kernel_cmpxchg, 0xFFFF0FC0 + .equ kernel_atomic_base, 0xFFFF0FFF +__atomic_dec: + stmdb sp!, {r4, lr} + mov r2, r0 +1: @ atomic_dec + ldr r0, [r2] + mov r3, #kernel_atomic_base + add lr, pc, #4 + sub r1, r0, #1 + add pc, r3, #(kernel_cmpxchg - kernel_atomic_base) + bcc 1b + add r0, r1, #1 + ldmia sp!, {r4, lr} + bx lr + +__atomic_inc: + stmdb sp!, {r4, lr} + mov r2, r0 +1: @ atomic_inc + ldr r0, [r2] + mov r3, #kernel_atomic_base + add lr, pc, #4 + add r1, r0, #1 + add pc, r3, #(kernel_cmpxchg - kernel_atomic_base) + bcc 1b + sub r0, r1, #1 + ldmia sp!, {r4, lr} + bx lr + +/* r0(old) r1(new) r2(addr) -> r0(zero_if_succeeded) */ +__atomic_cmpxchg: + stmdb sp!, {r4, lr} + mov r4, r0 /* r4 = save oldvalue */ +1: @ atomic_cmpxchg + mov r3, #kernel_atomic_base + add lr, pc, #4 + mov r0, r4 /* r0 = oldvalue */ + add pc, r3, #(kernel_cmpxchg - kernel_atomic_base) + bcs 2f /* swap was made. we're good, return. */ + ldr r3, [r2] /* swap not made, see if it's because *ptr!=oldvalue */ + cmp r3, r4 + beq 1b +2: @ atomic_cmpxchg + ldmia sp!, {r4, lr} + bx lr +#else +#define KUSER_CMPXCHG 0xffffffc0 + +/* r0(old) r1(new) r2(addr) -> r0(zero_if_succeeded) */ +__atomic_cmpxchg: + stmdb sp!, {r4, lr} + mov r4, r0 /* r4 = save oldvalue */ +1: add lr, pc, #4 + mov r0, r4 /* r0 = oldvalue */ + mov pc, #KUSER_CMPXCHG + bcs 2f /* swap was made. we're good, return. */ + ldr r3, [r2] /* swap not made, see if it's because *ptr!=oldvalue */ + cmp r3, r4 + beq 1b +2: ldmia sp!, {r4, lr} + bx lr + +/* r0(addr) -> r0(old) */ +__atomic_dec: + stmdb sp!, {r4, lr} + mov r2, r0 /* address */ +1: ldr r0, [r2] /* oldvalue */ + add lr, pc, #4 + sub r1, r0, #1 /* newvalue = oldvalue - 1 */ + mov pc, #KUSER_CMPXCHG + bcc 1b /* no swap, try again until we get it right */ + mov r0, ip /* swapped, return the old value */ + ldmia sp!, {r4, lr} + bx lr + +/* r0(addr) -> r0(old) */ +__atomic_inc: + stmdb sp!, {r4, lr} + mov r2, r0 /* address */ +1: ldr r0, [r2] /* oldvalue */ + add lr, pc, #4 + add r1, r0, #1 /* newvalue = oldvalue + 1 */ + mov pc, #KUSER_CMPXCHG + bcc 1b /* no swap, try again until we get it right */ + mov r0, ip /* swapped, return the old value */ + ldmia sp!, {r4, lr} + bx lr +#endif + +/* r0(new) r1(addr) -> r0(old) */ +__atomic_swap: + swp r0, r0, [r1] + bx lr + +/* __futex_wait(*ftx, val, *timespec) */ +/* __futex_syscall(*ftx, op, val, *timespec, *addr2, val3) */ + +#if __ARM_EABI__ + +__futex_wait: + .fnstart + stmdb sp!, {r4, r7} + .save {r4, r7} + mov r3, r2 + mov r2, r1 + mov r1, #FUTEX_WAIT + ldr r7, =__NR_futex + swi #0 + ldmia sp!, {r4, r7} + bx lr + .fnend + +__futex_wake: + stmdb sp!, {r4, r7} + mov r2, r1 + mov r1, #FUTEX_WAKE + ldr r7, =__NR_futex + swi #0 + ldmia sp!, {r4, r7} + bx lr + +#else + +__futex_wait: + mov r3, r2 + mov r2, r1 + mov r1, #FUTEX_WAIT + swi #__NR_futex + bx lr + +__futex_wake: + mov r2, r1 + mov r1, #FUTEX_WAKE + swi #__NR_futex + bx lr + +#endif diff --git a/libc/arch-arm/bionic/clone.S b/libc/arch-arm/bionic/clone.S new file mode 100644 index 0000000..791c73d --- /dev/null +++ b/libc/arch-arm/bionic/clone.S @@ -0,0 +1,74 @@ +/* + * 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/linux-syscalls.h> + + .text + .type __pthread_clone, #function + .global __pthread_clone + .align 4 + +__pthread_clone: + @ insert the args onto the new stack + str r0, [r1, #-4] + str r3, [r1, #-8] + + @ do the system call + @ get flags + + mov r0, r2 + + @ new sp is already in r1 + +#if __ARM_EABI__ + stmfd sp!, {r4, r7} + ldr r7, =__NR_clone + swi #0 +#else + swi #__NR_clone +#endif + + movs r0, r0 +#if __ARM_EABI__ + ldmnefd sp!, {r4, r7} +#endif + blt __error + bxne lr + + + @ pick the function arg and call address off the stack and jump + @ to the C __thread_entry function which does some setup and then + @ calls the thread's start function + + ldr r0, [sp, #-4] + ldr r1, [sp, #-8] + mov r2, sp @ __thread_entry needs the TLS pointer + b __thread_entry + +__error: + mov r0, #-1 + bx lr diff --git a/libc/arch-arm/bionic/crtbegin_dynamic.S b/libc/arch-arm/bionic/crtbegin_dynamic.S new file mode 100644 index 0000000..e265923 --- /dev/null +++ b/libc/arch-arm/bionic/crtbegin_dynamic.S @@ -0,0 +1,92 @@ +/* + * 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 + .align 4 + .type _start,#function + .globl _start + +# this is the small startup code that is first run when +# any executable that is statically-linked with Bionic +# runs. +# +# it's purpose is to call __libc_init with appropriate +# arguments, which are: +# +# - the address of the raw data block setup by the Linux +# kernel ELF loader +# +# - address of an "onexit" function, not used on any +# platform supported by Bionic +# +# - address of the "main" function of the program. We +# can't hard-code it in the adr pseudo instruction +# so we use a tiny trampoline that will get relocated +# by the dynamic linker before this code runs +# +# - address of the constructor list +# +_start: + mov r0, sp + mov r1, #0 + adr r2, 0f + adr r3, 1f + b __libc_init + +0: b main + +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__: + .long -1 + + .section .init_array, "aw" + .globl __INIT_ARRAY__ +__INIT_ARRAY__: + .long -1 + + .section .fini_array, "aw" + .globl __FINI_ARRAY__ +__FINI_ARRAY__: + .long -1 + + .section .ctors, "aw" + .globl __CTOR_LIST__ +__CTOR_LIST__: + .long -1 + diff --git a/libc/arch-arm/bionic/crtbegin_static.S b/libc/arch-arm/bionic/crtbegin_static.S new file mode 100644 index 0000000..e265923 --- /dev/null +++ b/libc/arch-arm/bionic/crtbegin_static.S @@ -0,0 +1,92 @@ +/* + * 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 + .align 4 + .type _start,#function + .globl _start + +# this is the small startup code that is first run when +# any executable that is statically-linked with Bionic +# runs. +# +# it's purpose is to call __libc_init with appropriate +# arguments, which are: +# +# - the address of the raw data block setup by the Linux +# kernel ELF loader +# +# - address of an "onexit" function, not used on any +# platform supported by Bionic +# +# - address of the "main" function of the program. We +# can't hard-code it in the adr pseudo instruction +# so we use a tiny trampoline that will get relocated +# by the dynamic linker before this code runs +# +# - address of the constructor list +# +_start: + mov r0, sp + mov r1, #0 + adr r2, 0f + adr r3, 1f + b __libc_init + +0: b main + +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__: + .long -1 + + .section .init_array, "aw" + .globl __INIT_ARRAY__ +__INIT_ARRAY__: + .long -1 + + .section .fini_array, "aw" + .globl __FINI_ARRAY__ +__FINI_ARRAY__: + .long -1 + + .section .ctors, "aw" + .globl __CTOR_LIST__ +__CTOR_LIST__: + .long -1 + diff --git a/libc/arch-arm/bionic/crtend.S b/libc/arch-arm/bionic/crtend.S new file mode 100644 index 0000000..2f3b1ed --- /dev/null +++ b/libc/arch-arm/bionic/crtend.S @@ -0,0 +1,40 @@ +/* + * 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 .preinit_array, "aw" + .long 0 + + .section .init_array, "aw" + .long 0 + + .section .fini_array, "aw" + .long 0 + + .section .ctors, "aw" + .long 0 + diff --git a/libc/arch-arm/bionic/exidx_dynamic.c b/libc/arch-arm/bionic/exidx_dynamic.c new file mode 100644 index 0000000..962606f --- /dev/null +++ b/libc/arch-arm/bionic/exidx_dynamic.c @@ -0,0 +1,47 @@ +/* + * 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. + */ +typedef long unsigned int *_Unwind_Ptr; + +/* Stubbed out in libdl and defined in the dynamic linker. + * Same semantics as __gnu_Unwind_Find_exidx(). + */ +extern _Unwind_Ptr dl_unwind_find_exidx(_Unwind_Ptr pc, int *pcount); + +/* For a given PC, find the .so that it belongs to. + * Returns the base address of the .ARM.exidx section + * for that .so, and the number of 8-byte entries + * in that section (via *pcount). + * + * libgcc declares __gnu_Unwind_Find_exidx() as a weak symbol, with + * the expectation that libc will define it and call through to + * a differently-named function in the dynamic linker. + */ +_Unwind_Ptr __gnu_Unwind_Find_exidx(_Unwind_Ptr pc, int *pcount) +{ + return dl_unwind_find_exidx(pc, pcount); +} diff --git a/libc/arch-arm/bionic/exidx_static.c b/libc/arch-arm/bionic/exidx_static.c new file mode 100644 index 0000000..e79e951 --- /dev/null +++ b/libc/arch-arm/bionic/exidx_static.c @@ -0,0 +1,45 @@ +/* + * 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. + */ +typedef long unsigned int *_Unwind_Ptr; + +/* Find the .ARM.exidx section (which in the case of a static executable + * can be identified through its start and end symbols), and return its + * beginning and numbe of entries to the caller. Note that for static + * executables we do not need to use the value of the PC to find the + * EXIDX section. + */ + +extern unsigned __exidx_end; +extern unsigned __exidx_start; + +_Unwind_Ptr __gnu_Unwind_Find_exidx(_Unwind_Ptr pc __attribute__((unused)), + int *pcount) +{ + *pcount = (__exidx_end-__exidx_start)/8; + return (_Unwind_Ptr)__exidx_start; +} diff --git a/libc/arch-arm/bionic/ffs.S b/libc/arch-arm/bionic/ffs.S new file mode 100644 index 0000000..f11141c --- /dev/null +++ b/libc/arch-arm/bionic/ffs.S @@ -0,0 +1,82 @@ +/* $NetBSD: ffs.S,v 1.5 2003/04/05 23:08:52 bjh21 Exp $ */ +/* + * Copyright (c) 2001 Christopher Gilbert + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the company nor the name of the author may be used to + * endorse or promote products derived from this software without specific + * prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include <machine/asm.h> + +/* + * ffs - find first set bit, this algorithm isolates the first set + * bit, then multiplies the number by 0x0450fbaf which leaves the top + * 6 bits as an index into the table. This algorithm should be a win + * over the checking each bit in turn as per the C compiled version. + * + * under ARMv5 there's an instruction called CLZ (count leading Zero's) that + * could be used + * + * This is the ffs algorithm devised by d.seal and posted to comp.sys.arm on + * 16 Feb 1994. + */ + +ENTRY(ffs) + /* Standard trick to isolate bottom bit in r0 or 0 if r0 = 0 on entry */ + rsb r1, r0, #0 + ands r0, r0, r1 +#ifndef __ARM_ARCH_5__ + /* + * now r0 has at most one set bit, call this X + * if X = 0, all further instructions are skipped + */ + adrne r2, .L_ffs_table + orrne r0, r0, r0, lsl #4 /* r0 = X * 0x11 */ + orrne r0, r0, r0, lsl #6 /* r0 = X * 0x451 */ + rsbne r0, r0, r0, lsl #16 /* r0 = X * 0x0450fbaf */ + + /* now lookup in table indexed on top 6 bits of r0 */ + ldrneb r0, [ r2, r0, lsr #26 ] + + bx lr + +.text; +.type .L_ffs_table, _ASM_TYPE_OBJECT; +.L_ffs_table: +/* 0 1 2 3 4 5 6 7 */ + .byte 0, 1, 2, 13, 3, 7, 0, 14 /* 0- 7 */ + .byte 4, 0, 8, 0, 0, 0, 0, 15 /* 8-15 */ + .byte 11, 5, 0, 0, 9, 0, 0, 26 /* 16-23 */ + .byte 0, 0, 0, 0, 0, 22, 28, 16 /* 24-31 */ + .byte 32, 12, 6, 0, 0, 0, 0, 0 /* 32-39 */ + .byte 10, 0, 0, 25, 0, 0, 21, 27 /* 40-47 */ + .byte 31, 0, 0, 0, 0, 24, 0, 20 /* 48-55 */ + .byte 30, 0, 23, 19, 29, 18, 17, 0 /* 56-63 */ +#else + clzne r0, r0 + rsbne r0, r0, #32 + bx lr +#endif + diff --git a/libc/arch-arm/bionic/kill.S b/libc/arch-arm/bionic/kill.S new file mode 100644 index 0000000..2954091 --- /dev/null +++ b/libc/arch-arm/bionic/kill.S @@ -0,0 +1,53 @@ +/* + * 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. + */ +/* unlike our auto-generated syscall stubs, this code saves lr + on the stack, as well as a few other registers. this makes + our stack unwinder happy, when we generate debug stack + traces after the C library or other parts of the system + abort due to a fatal runtime error (e.g. detection + of a corrupted malloc heap). +*/ +#include <sys/linux-syscalls.h> + +#ifndef __NR_kill +#define __NR_kill 37 +#endif + + .text + .type kill, #function + .globl kill + .align 4 + +kill: + stmfd sp!, {r4-r7, ip, lr} + ldr r7, =__NR_kill + swi #0 + ldmfd sp!, {r4-r7, ip, lr} + movs r0, r0 + bxpl lr + b __set_syscall_errno diff --git a/libc/arch-arm/bionic/memcmp.S b/libc/arch-arm/bionic/memcmp.S new file mode 100644 index 0000000..f45b56b --- /dev/null +++ b/libc/arch-arm/bionic/memcmp.S @@ -0,0 +1,285 @@ +/* + * 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 <machine/cpu-features.h> + + .text + + .global memcmp + .type memcmp, %function + .align 4 + +/* + * Optimized memcmp() for ARM9. + * This would not be optimal on XScale or ARM11, where more prefetching + * and use of PLD will be needed. + * The 2 major optimzations here are + * (1) The main loop compares 16 bytes at a time + * (2) The loads are scheduled in a way they won't stall + */ + +memcmp: + PLD (r0, #0) + PLD (r1, #0) + + /* take of the case where length is 0 or the buffers are the same */ + cmp r0, r1 + cmpne r2, #0 + moveq r0, #0 + bxeq lr + + /* save registers */ + stmfd sp!, {r4, lr} + + PLD (r0, #32) + PLD (r1, #32) + + /* since r0 hold the result, move the first source + * pointer somewhere else + */ + + mov r4, r0 + + /* make sure we have at least 8+4 bytes, this simplify things below + * and avoid some overhead for small blocks + */ + cmp r2, #(8+4) + bmi 8f + + /* align first pointer to word boundary + * offset = -src & 3 + */ + rsb r3, r4, #0 + ands r3, r3, #3 + beq 0f + + /* align first pointer */ + sub r2, r2, r3 +1: ldrb r0, [r4], #1 + ldrb ip, [r1], #1 + subs r0, r0, ip + bne 9f + subs r3, r3, #1 + bne 1b + + +0: /* here the first pointer is aligned, and we have at least 4 bytes + * to process. + */ + + /* see if the pointers are congruent */ + eor r0, r4, r1 + ands r0, r0, #3 + bne 5f + + /* congruent case, 32 bytes per iteration + * We need to make sure there are at least 32+4 bytes left + * because we effectively read ahead one word, and we could + * read past the buffer (and segfault) if we're not careful. + */ + + ldr ip, [r1] + subs r2, r2, #(32 + 4) + bmi 1f + +0: PLD (r4, #64) + PLD (r1, #64) + ldr r0, [r4], #4 + ldr lr, [r1, #4]! + eors r0, r0, ip + ldreq r0, [r4], #4 + ldreq ip, [r1, #4]! + eoreqs r0, r0, lr + ldreq r0, [r4], #4 + ldreq lr, [r1, #4]! + eoreqs r0, r0, ip + ldreq r0, [r4], #4 + ldreq ip, [r1, #4]! + eoreqs r0, r0, lr + ldreq r0, [r4], #4 + ldreq lr, [r1, #4]! + eoreqs r0, r0, ip + ldreq r0, [r4], #4 + ldreq ip, [r1, #4]! + eoreqs r0, r0, lr + ldreq r0, [r4], #4 + ldreq lr, [r1, #4]! + eoreqs r0, r0, ip + ldreq r0, [r4], #4 + ldreq ip, [r1, #4]! + eoreqs r0, r0, lr + bne 2f + subs r2, r2, #32 + bhs 0b + + /* do we have at least 4 bytes left? */ +1: adds r2, r2, #(32 - 4 + 4) + bmi 4f + + /* finish off 4 bytes at a time */ +3: ldr r0, [r4], #4 + ldr ip, [r1], #4 + eors r0, r0, ip + bne 2f + subs r2, r2, #4 + bhs 3b + + /* are we done? */ +4: adds r2, r2, #4 + moveq r0, #0 + beq 9f + + /* finish off the remaining bytes */ + b 8f + +2: /* the last 4 bytes are different, restart them */ + sub r4, r4, #4 + sub r1, r1, #4 + mov r2, #4 + + /* process the last few bytes */ +8: ldrb r0, [r4], #1 + ldrb ip, [r1], #1 + // stall + subs r0, r0, ip + bne 9f + subs r2, r2, #1 + bne 8b + +9: /* restore registers and return */ + ldmfd sp!, {r4, lr} + bx lr + + + + + +5: /*************** non-congruent case ***************/ + and r0, r1, #3 + cmp r0, #2 + bne 4f + + /* here, offset is 2 (16-bits aligned, special cased) */ + + /* make sure we have at least 16 bytes to process */ + subs r2, r2, #16 + addmi r2, r2, #16 + bmi 8b + + /* align the unaligned pointer */ + bic r1, r1, #3 + ldr lr, [r1], #4 + +6: PLD (r1, #64) + PLD (r4, #64) + mov ip, lr, lsr #16 + ldr lr, [r1], #4 + ldr r0, [r4], #4 + orr ip, ip, lr, lsl #16 + eors r0, r0, ip + moveq ip, lr, lsr #16 + ldreq lr, [r1], #4 + ldreq r0, [r4], #4 + orreq ip, ip, lr, lsl #16 + eoreqs r0, r0, ip + moveq ip, lr, lsr #16 + ldreq lr, [r1], #4 + ldreq r0, [r4], #4 + orreq ip, ip, lr, lsl #16 + eoreqs r0, r0, ip + moveq ip, lr, lsr #16 + ldreq lr, [r1], #4 + ldreq r0, [r4], #4 + orreq ip, ip, lr, lsl #16 + eoreqs r0, r0, ip + bne 7f + subs r2, r2, #16 + bhs 6b + sub r1, r1, #2 + /* are we done? */ + adds r2, r2, #16 + moveq r0, #0 + beq 9b + /* finish off the remaining bytes */ + b 8b + +7: /* fix up the 2 pointers and fallthrough... */ + sub r1, r1, #(4+2) + sub r4, r4, #4 + mov r2, #4 + b 8b + + +4: /*************** offset is 1 or 3 (less optimized) ***************/ + + stmfd sp!, {r5, r6, r7} + + // r5 = rhs + // r6 = lhs + // r7 = scratch + + mov r5, r0, lsl #3 /* r5 = right shift */ + rsb r6, r5, #32 /* r6 = left shift */ + + /* align the unaligned pointer */ + bic r1, r1, #3 + ldr r7, [r1], #4 + sub r2, r2, #8 + +6: mov ip, r7, lsr r5 + ldr r7, [r1], #4 + ldr r0, [r4], #4 + orr ip, ip, r7, lsl r6 + eors r0, r0, ip + moveq ip, r7, lsr r5 + ldreq r7, [r1], #4 + ldreq r0, [r4], #4 + orreq ip, ip, r7, lsl r6 + eoreqs r0, r0, ip + bne 7f + subs r2, r2, #8 + bhs 6b + + sub r1, r1, r6, lsr #3 + ldmfd sp!, {r5, r6, r7} + + /* are we done? */ + adds r2, r2, #8 + moveq r0, #0 + beq 9b + + /* finish off the remaining bytes */ + b 8b + +7: /* fix up the 2 pointers and fallthrough... */ + sub r1, r1, #4 + sub r1, r1, r6, lsr #3 + sub r4, r4, #4 + mov r2, #4 + ldmfd sp!, {r5, r6, r7} + b 8b diff --git a/libc/arch-arm/bionic/memcmp16.S b/libc/arch-arm/bionic/memcmp16.S new file mode 100644 index 0000000..38d8b62 --- /dev/null +++ b/libc/arch-arm/bionic/memcmp16.S @@ -0,0 +1,236 @@ +/* + * 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 <machine/cpu-features.h> + + .text + + .global __memcmp16 + .type __memcmp16, %function + .align 4 + +/* + * Optimized memcmp16() for ARM9. + * This would not be optimal on XScale or ARM11, where more prefetching + * and use of PLD will be needed. + * The 2 major optimzations here are + * (1) The main loop compares 16 bytes at a time + * (2) The loads are scheduled in a way they won't stall + */ + +__memcmp16: + PLD (r0, #0) + PLD (r1, #0) + + /* take of the case where length is nul or the buffers are the same */ + cmp r0, r1 + cmpne r2, #0 + moveq r0, #0 + bxeq lr + + /* since r0 hold the result, move the first source + * pointer somewhere else + */ + + mov r3, r0 + + /* make sure we have at least 12 words, this simplify things below + * and avoid some overhead for small blocks + */ + + cmp r2, #12 + bpl 0f + + /* small blocks (less then 12 words) */ + PLD (r0, #32) + PLD (r1, #32) + +1: ldrh r0, [r3], #2 + ldrh ip, [r1], #2 + subs r0, r0, ip + bxne lr + subs r2, r2, #1 + bne 1b + bx lr + + + /* save registers */ +0: stmfd sp!, {r4, lr} + + /* align first pointer to word boundary */ + tst r3, #2 + beq 0f + + ldrh r0, [r3], #2 + ldrh ip, [r1], #2 + sub r2, r2, #1 + subs r0, r0, ip + /* restore registers and return */ + ldmnefd sp!, {r4, lr} + bxne lr + + + +0: /* here the first pointer is aligned, and we have at least 3 words + * to process. + */ + + /* see if the pointers are congruent */ + eor r0, r3, r1 + ands r0, r0, #2 + bne 5f + + /* congruent case, 16 half-words per iteration + * We need to make sure there are at least 16+2 words left + * because we effectively read ahead one long word, and we could + * read past the buffer (and segfault) if we're not careful. + */ + + ldr ip, [r1] + subs r2, r2, #(16 + 2) + bmi 1f + +0: + PLD (r3, #64) + PLD (r1, #64) + ldr r0, [r3], #4 + ldr lr, [r1, #4]! + eors r0, r0, ip + ldreq r0, [r3], #4 + ldreq ip, [r1, #4]! + eoreqs r0, r0, lr + ldreq r0, [r3], #4 + ldreq lr, [r1, #4]! + eoreqs r0, r0, ip + ldreq r0, [r3], #4 + ldreq ip, [r1, #4]! + eoreqs r0, r0, lr + ldreq r0, [r3], #4 + ldreq lr, [r1, #4]! + eoreqs r0, r0, ip + ldreq r0, [r3], #4 + ldreq ip, [r1, #4]! + eoreqs r0, r0, lr + ldreq r0, [r3], #4 + ldreq lr, [r1, #4]! + eoreqs r0, r0, ip + ldreq r0, [r3], #4 + ldreq ip, [r1, #4]! + eoreqs r0, r0, lr + bne 2f + subs r2, r2, #16 + bhs 0b + + /* do we have at least 2 words left? */ +1: adds r2, r2, #(16 - 2 + 2) + bmi 4f + + /* finish off 2 words at a time */ +3: ldr r0, [r3], #4 + ldr ip, [r1], #4 + eors r0, r0, ip + bne 2f + subs r2, r2, #2 + bhs 3b + + /* are we done? */ +4: adds r2, r2, #2 + bne 8f + /* restore registers and return */ + mov r0, #0 + ldmfd sp!, {r4, lr} + bx lr + +2: /* the last 2 words are different, restart them */ + ldrh r0, [r3, #-4] + ldrh ip, [r1, #-4] + subs r0, r0, ip + ldreqh r0, [r3, #-2] + ldreqh ip, [r1, #-2] + subeqs r0, r0, ip + /* restore registers and return */ + ldmfd sp!, {r4, lr} + bx lr + + /* process the last few words */ +8: ldrh r0, [r3], #2 + ldrh ip, [r1], #2 + subs r0, r0, ip + bne 9f + subs r2, r2, #1 + bne 8b + +9: /* restore registers and return */ + ldmfd sp!, {r4, lr} + bx lr + + +5: /*************** non-congruent case ***************/ + + /* align the unaligned pointer */ + bic r1, r1, #3 + ldr lr, [r1], #4 + sub r2, r2, #8 + +6: + PLD (r3, #64) + PLD (r1, #64) + mov ip, lr, lsr #16 + ldr lr, [r1], #4 + ldr r0, [r3], #4 + orr ip, ip, lr, lsl #16 + eors r0, r0, ip + moveq ip, lr, lsr #16 + ldreq lr, [r1], #4 + ldreq r0, [r3], #4 + orreq ip, ip, lr, lsl #16 + eoreqs r0, r0, ip + moveq ip, lr, lsr #16 + ldreq lr, [r1], #4 + ldreq r0, [r3], #4 + orreq ip, ip, lr, lsl #16 + eoreqs r0, r0, ip + moveq ip, lr, lsr #16 + ldreq lr, [r1], #4 + ldreq r0, [r3], #4 + orreq ip, ip, lr, lsl #16 + eoreqs r0, r0, ip + bne 7f + subs r2, r2, #8 + bhs 6b + sub r1, r1, #2 + /* are we done? */ + adds r2, r2, #8 + moveq r0, #0 + beq 9b + /* finish off the remaining bytes */ + b 8b + +7: /* fix up the 2 pointers and fallthrough... */ + sub r1, r1, #2 + b 2b diff --git a/libc/arch-arm/bionic/memcpy.S b/libc/arch-arm/bionic/memcpy.S new file mode 100644 index 0000000..fcb58cd --- /dev/null +++ b/libc/arch-arm/bionic/memcpy.S @@ -0,0 +1,387 @@ +/* + * 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 <machine/cpu-features.h> + + .text + + .global memcpy + .type memcpy, %function + .align 4 + + /* + * Optimized memcpy() for ARM. + * + * note that memcpy() always returns the destination pointer, + * so we have to preserve R0. + */ + +memcpy: + /* The stack must always be 64-bits aligned to be compliant with the + * ARM ABI. Since we have to save R0, we might as well save R4 + * which we can use for better pipelining of the reads below + */ + .fnstart + .save {r0, r4, lr} + stmfd sp!, {r0, r4, lr} + /* Making room for r5-r11 which will be spilled later */ + .pad #28 + sub sp, sp, #28 + + // preload the destination because we'll align it to a cache line + // with small writes. Also start the source "pump". + PLD (r0, #0) + PLD (r1, #0) + PLD (r1, #32) + + /* it simplifies things to take care of len<4 early */ + cmp r2, #4 + blo copy_last_3_and_return + + /* compute the offset to align the source + * offset = (4-(src&3))&3 = -src & 3 + */ + rsb r3, r1, #0 + ands r3, r3, #3 + beq src_aligned + + /* align source to 32 bits. We need to insert 2 instructions between + * a ldr[b|h] and str[b|h] because byte and half-word instructions + * stall 2 cycles. + */ + movs r12, r3, lsl #31 + sub r2, r2, r3 /* we know that r3 <= r2 because r2 >= 4 */ + ldrmib r3, [r1], #1 + ldrcsb r4, [r1], #1 + ldrcsb r12,[r1], #1 + strmib r3, [r0], #1 + strcsb r4, [r0], #1 + strcsb r12,[r0], #1 + +src_aligned: + + /* see if src and dst are aligned together (congruent) */ + eor r12, r0, r1 + tst r12, #3 + bne non_congruent + + /* Use post-incriment mode for stm to spill r5-r11 to reserved stack + * frame. Don't update sp. + */ + stmea sp, {r5-r11} + + /* align the destination to a cache-line */ + rsb r3, r0, #0 + ands r3, r3, #0x1C + beq congruent_aligned32 + cmp r3, r2 + andhi r3, r2, #0x1C + + /* conditionnaly copies 0 to 7 words (length in r3) */ + movs r12, r3, lsl #28 + ldmcsia r1!, {r4, r5, r6, r7} /* 16 bytes */ + ldmmiia r1!, {r8, r9} /* 8 bytes */ + stmcsia r0!, {r4, r5, r6, r7} + stmmiia r0!, {r8, r9} + tst r3, #0x4 + ldrne r10,[r1], #4 /* 4 bytes */ + strne r10,[r0], #4 + sub r2, r2, r3 + +congruent_aligned32: + /* + * here source is aligned to 32 bytes. + */ + +cached_aligned32: + subs r2, r2, #32 + blo less_than_32_left + + /* + * We preload a cache-line up to 64 bytes ahead. On the 926, this will + * stall only until the requested world is fetched, but the linefill + * continues in the the background. + * While the linefill is going, we write our previous cache-line + * into the write-buffer (which should have some free space). + * When the linefill is done, the writebuffer will + * start dumping its content into memory + * + * While all this is going, we then load a full cache line into + * 8 registers, this cache line should be in the cache by now + * (or partly in the cache). + * + * This code should work well regardless of the source/dest alignment. + * + */ + + // Align the preload register to a cache-line because the cpu does + // "critical word first" (the first word requested is loaded first). + bic r12, r1, #0x1F + add r12, r12, #64 + +1: ldmia r1!, { r4-r11 } + PLD (r12, #64) + subs r2, r2, #32 + + // NOTE: if r12 is more than 64 ahead of r1, the following ldrhi + // for ARM9 preload will not be safely guarded by the preceding subs. + // When it is safely guarded the only possibility to have SIGSEGV here + // is because the caller overstates the length. + ldrhi r3, [r12], #32 /* cheap ARM9 preload */ + stmia r0!, { r4-r11 } + bhs 1b + + add r2, r2, #32 + + + + +less_than_32_left: + /* + * less than 32 bytes left at this point (length in r2) + */ + + /* skip all this if there is nothing to do, which should + * be a common case (if not executed the code below takes + * about 16 cycles) + */ + tst r2, #0x1F + beq 1f + + /* conditionnaly copies 0 to 31 bytes */ + movs r12, r2, lsl #28 + ldmcsia r1!, {r4, r5, r6, r7} /* 16 bytes */ + ldmmiia r1!, {r8, r9} /* 8 bytes */ + stmcsia r0!, {r4, r5, r6, r7} + stmmiia r0!, {r8, r9} + movs r12, r2, lsl #30 + ldrcs r3, [r1], #4 /* 4 bytes */ + ldrmih r4, [r1], #2 /* 2 bytes */ + strcs r3, [r0], #4 + strmih r4, [r0], #2 + tst r2, #0x1 + ldrneb r3, [r1] /* last byte */ + strneb r3, [r0] + + /* we're done! restore everything and return */ +1: ldmfd sp!, {r5-r11} + ldmfd sp!, {r0, r4, lr} + bx lr + + /********************************************************************/ + +non_congruent: + /* + * here source is aligned to 4 bytes + * but destination is not. + * + * in the code below r2 is the number of bytes read + * (the number of bytes written is always smaller, because we have + * partial words in the shift queue) + */ + cmp r2, #4 + blo copy_last_3_and_return + + /* Use post-incriment mode for stm to spill r5-r11 to reserved stack + * frame. Don't update sp. + */ + stmea sp, {r5-r11} + + /* compute shifts needed to align src to dest */ + rsb r5, r0, #0 + and r5, r5, #3 /* r5 = # bytes in partial words */ + mov r12, r5, lsl #3 /* r12 = right */ + rsb lr, r12, #32 /* lr = left */ + + /* read the first word */ + ldr r3, [r1], #4 + sub r2, r2, #4 + + /* write a partial word (0 to 3 bytes), such that destination + * becomes aligned to 32 bits (r5 = nb of words to copy for alignment) + */ + movs r5, r5, lsl #31 + strmib r3, [r0], #1 + movmi r3, r3, lsr #8 + strcsb r3, [r0], #1 + movcs r3, r3, lsr #8 + strcsb r3, [r0], #1 + movcs r3, r3, lsr #8 + + cmp r2, #4 + blo partial_word_tail + + /* Align destination to 32 bytes (cache line boundary) */ +1: tst r0, #0x1c + beq 2f + ldr r5, [r1], #4 + sub r2, r2, #4 + orr r4, r3, r5, lsl lr + mov r3, r5, lsr r12 + str r4, [r0], #4 + cmp r2, #4 + bhs 1b + blo partial_word_tail + + /* copy 32 bytes at a time */ +2: subs r2, r2, #32 + blo less_than_thirtytwo + + /* Use immediate mode for the shifts, because there is an extra cycle + * for register shifts, which could account for up to 50% of + * performance hit. + */ + + cmp r12, #24 + beq loop24 + cmp r12, #8 + beq loop8 + +loop16: + ldr r12, [r1], #4 +1: mov r4, r12 + ldmia r1!, { r5,r6,r7, r8,r9,r10,r11} + PLD (r1, #64) + subs r2, r2, #32 + ldrhs r12, [r1], #4 + orr r3, r3, r4, lsl #16 + mov r4, r4, lsr #16 + orr r4, r4, r5, lsl #16 + mov r5, r5, lsr #16 + orr r5, r5, r6, lsl #16 + mov r6, r6, lsr #16 + orr r6, r6, r7, lsl #16 + mov r7, r7, lsr #16 + orr r7, r7, r8, lsl #16 + mov r8, r8, lsr #16 + orr r8, r8, r9, lsl #16 + mov r9, r9, lsr #16 + orr r9, r9, r10, lsl #16 + mov r10, r10, lsr #16 + orr r10, r10, r11, lsl #16 + stmia r0!, {r3,r4,r5,r6, r7,r8,r9,r10} + mov r3, r11, lsr #16 + bhs 1b + b less_than_thirtytwo + +loop8: + ldr r12, [r1], #4 +1: mov r4, r12 + ldmia r1!, { r5,r6,r7, r8,r9,r10,r11} + PLD (r1, #64) + subs r2, r2, #32 + ldrhs r12, [r1], #4 + orr r3, r3, r4, lsl #24 + mov r4, r4, lsr #8 + orr r4, r4, r5, lsl #24 + mov r5, r5, lsr #8 + orr r5, r5, r6, lsl #24 + mov r6, r6, lsr #8 + orr r6, r6, r7, lsl #24 + mov r7, r7, lsr #8 + orr r7, r7, r8, lsl #24 + mov r8, r8, lsr #8 + orr r8, r8, r9, lsl #24 + mov r9, r9, lsr #8 + orr r9, r9, r10, lsl #24 + mov r10, r10, lsr #8 + orr r10, r10, r11, lsl #24 + stmia r0!, {r3,r4,r5,r6, r7,r8,r9,r10} + mov r3, r11, lsr #8 + bhs 1b + b less_than_thirtytwo + +loop24: + ldr r12, [r1], #4 +1: mov r4, r12 + ldmia r1!, { r5,r6,r7, r8,r9,r10,r11} + PLD (r1, #64) + subs r2, r2, #32 + ldrhs r12, [r1], #4 + orr r3, r3, r4, lsl #8 + mov r4, r4, lsr #24 + orr r4, r4, r5, lsl #8 + mov r5, r5, lsr #24 + orr r5, r5, r6, lsl #8 + mov r6, r6, lsr #24 + orr r6, r6, r7, lsl #8 + mov r7, r7, lsr #24 + orr r7, r7, r8, lsl #8 + mov r8, r8, lsr #24 + orr r8, r8, r9, lsl #8 + mov r9, r9, lsr #24 + orr r9, r9, r10, lsl #8 + mov r10, r10, lsr #24 + orr r10, r10, r11, lsl #8 + stmia r0!, {r3,r4,r5,r6, r7,r8,r9,r10} + mov r3, r11, lsr #24 + bhs 1b + + +less_than_thirtytwo: + /* copy the last 0 to 31 bytes of the source */ + rsb r12, lr, #32 /* we corrupted r12, recompute it */ + add r2, r2, #32 + cmp r2, #4 + blo partial_word_tail + +1: ldr r5, [r1], #4 + sub r2, r2, #4 + orr r4, r3, r5, lsl lr + mov r3, r5, lsr r12 + str r4, [r0], #4 + cmp r2, #4 + bhs 1b + +partial_word_tail: + /* we have a partial word in the input buffer */ + movs r5, lr, lsl #(31-3) + strmib r3, [r0], #1 + movmi r3, r3, lsr #8 + strcsb r3, [r0], #1 + movcs r3, r3, lsr #8 + strcsb r3, [r0], #1 + + /* Refill spilled registers from the stack. Don't update sp. */ + ldmfd sp, {r5-r11} + +copy_last_3_and_return: + movs r2, r2, lsl #31 /* copy remaining 0, 1, 2 or 3 bytes */ + ldrmib r2, [r1], #1 + ldrcsb r3, [r1], #1 + ldrcsb r12,[r1] + strmib r2, [r0], #1 + strcsb r3, [r0], #1 + strcsb r12,[r0] + + /* we're done! restore sp and spilled registers and return */ + add sp, sp, #28 + ldmfd sp!, {r0, r4, lr} + bx lr + .fnend + diff --git a/libc/arch-arm/bionic/memset.S b/libc/arch-arm/bionic/memset.S new file mode 100644 index 0000000..d52d622 --- /dev/null +++ b/libc/arch-arm/bionic/memset.S @@ -0,0 +1,117 @@ +/* + * 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 + + .global memset + .type memset, %function + + .global bzero + .type bzero, %function + + .align + + /* + * Optimized memset() for ARM. + * + * memset() returns its first argument. + */ + +bzero: + mov r2, r1 + mov r1, #0 + +memset: + /* compute the offset to align the destination + * offset = (4-(src&3))&3 = -src & 3 + */ + .fnstart + .save {r0, r4-r7, lr} + stmfd sp!, {r0, r4-r7, lr} + rsb r3, r0, #0 + ands r3, r3, #3 + cmp r3, r2 + movhi r3, r2 + + /* splat r1 */ + mov r1, r1, lsl #24 + orr r1, r1, r1, lsr #8 + orr r1, r1, r1, lsr #16 + + movs r12, r3, lsl #31 + strcsb r1, [r0], #1 /* can't use strh (alignment unknown) */ + strcsb r1, [r0], #1 + strmib r1, [r0], #1 + subs r2, r2, r3 + ldmlsfd sp!, {r0, r4-r7, lr} /* return */ + bxls lr + + /* align the destination to a cache-line */ + mov r12, r1 + mov lr, r1 + mov r4, r1 + mov r5, r1 + mov r6, r1 + mov r7, r1 + + rsb r3, r0, #0 + ands r3, r3, #0x1C + beq aligned32 + cmp r3, r2 + andhi r3, r2, #0x1C + sub r2, r2, r3 + + /* conditionnaly writes 0 to 7 words (length in r3) */ + movs r3, r3, lsl #28 + stmcsia r0!, {r1, lr} + stmcsia r0!, {r1, lr} + stmmiia r0!, {r1, lr} + movs r3, r3, lsl #2 + strcs r1, [r0], #4 + +aligned32: + subs r2, r2, #32 + mov r3, r1 + bmi 2f +1: subs r2, r2, #32 + stmia r0!, {r1,r3,r4,r5,r6,r7,r12,lr} + bhs 1b +2: add r2, r2, #32 + + /* conditionnaly stores 0 to 31 bytes */ + movs r2, r2, lsl #28 + stmcsia r0!, {r1,r3,r12,lr} + stmmiia r0!, {r1, lr} + movs r2, r2, lsl #2 + strcs r1, [r0], #4 + strmih r1, [r0], #2 + movs r2, r2, lsl #2 + strcsb r1, [r0] + ldmfd sp!, {r0, r4-r7, lr} + bx lr + .fnend + diff --git a/libc/arch-arm/bionic/setjmp.S b/libc/arch-arm/bionic/setjmp.S new file mode 100644 index 0000000..a9f6ea4 --- /dev/null +++ b/libc/arch-arm/bionic/setjmp.S @@ -0,0 +1,136 @@ +/* $OpenBSD: setjmp.S,v 1.2 2004/02/01 05:40:52 drahn Exp $ */ +/* $NetBSD: setjmp.S,v 1.5 2003/04/05 23:08:51 bjh21 Exp $ */ + +/* + * Copyright (c) 1997 Mark Brinicombe + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Mark Brinicombe + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include <machine/asm.h> +#include <machine/setjmp.h> + +/* + * C library -- setjmp, longjmp + * + * longjmp(a,v) + * will generate a "return(v)" from the last call to + * setjmp(a) + * by restoring registers from the stack. + * The previous signal state is restored. + */ + +ENTRY(setjmp) + /* Block all signals and retrieve the old signal mask */ + stmfd sp!, {r0, r14} + mov r0, #0x00000000 + + bl PIC_SYM(_C_LABEL(sigblock), PLT) + mov r1, r0 + + ldmfd sp!, {r0, r14} + + /* Store signal mask */ + str r1, [r0, #(25 * 4)] + + ldr r1, .Lsetjmp_magic + str r1, [r0], #4 + +#ifdef SOFTFLOAT + add r0, r0, #52 +#else + /* Store fp registers */ + sfm f4, 4, [r0], #48 + /* Store fpsr */ + rfs r1 + str r1, [r0], #0x0004 +#endif /*SOFTFLOAT*/ + /* Store integer registers */ + stmia r0, {r4-r14} + mov r0, #0x00000000 + bx lr + +.Lsetjmp_magic: + .word _JB_MAGIC_SETJMP + + +ENTRY(longjmp) + ldr r2, .Lsetjmp_magic + ldr r3, [r0] + teq r2, r3 + bne botch + + /* Fetch signal mask */ + ldr r2, [r0, #(25 * 4)] + + /* Set signal mask */ + stmfd sp!, {r0, r1, r14} + sub sp, sp, #4 /* align the stack */ + + mov r0, r2 + bl PIC_SYM(_C_LABEL(sigsetmask), PLT) + + add sp, sp, #4 /* unalign the stack */ + ldmfd sp!, {r0, r1, r14} + + add r0, r0, #4 +#ifdef SOFTFLOAT + add r0, r0, #52 +#else + /* Restore fp registers */ + lfm f4, 4, [r0], #48 + /* Restore FPSR */ + ldr r4, [r0], #0x0004 + wfs r4 +#endif /* SOFTFLOAT */ + /* Restore integer registers */ + ldmia r0, {r4-r14} + + /* Validate sp and r14 */ + teq sp, #0 + teqne r14, #0 + beq botch + + /* Set return value */ + + mov r0, r1 + teq r0, #0x00000000 + moveq r0, #0x00000001 + bx lr +#ifdef __ARM_26__ + mov r15, r14 +#else + mov r15, r14 +#endif + + /* validation failed, die die die. */ +botch: + bl PIC_SYM(_C_LABEL(longjmperror), PLT) + bl PIC_SYM(_C_LABEL(abort), PLT) + b . - 8 /* Cannot get here */ diff --git a/libc/arch-arm/bionic/sigsetjmp.S b/libc/arch-arm/bionic/sigsetjmp.S new file mode 100644 index 0000000..50e6429 --- /dev/null +++ b/libc/arch-arm/bionic/sigsetjmp.S @@ -0,0 +1,62 @@ +/* $OpenBSD: sigsetjmp.S,v 1.2 2004/02/01 05:40:52 drahn Exp $ */ +/* $NetBSD: sigsetjmp.S,v 1.3 2002/08/17 19:54:30 thorpej Exp $ */ + +/* + * Copyright (c) 1997 Mark Brinicombe + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Mark Brinicombe + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include <machine/asm.h> +#include <machine/setjmp.h> + +/* + * C library -- sigsetjmp, siglongjmp + * + * longjmp(a,v) + * will generate a "return(v)" from the last call to + * setjmp(a, m) + * by restoring registers from the stack. + * The previous signal state is restored. + */ + +ENTRY(sigsetjmp) + teq r1, #0 + beq PIC_SYM(_C_LABEL(_setjmp), PLT) + b PIC_SYM(_C_LABEL(setjmp), PLT) + +.L_setjmp_magic: + .word _JB_MAGIC__SETJMP + +ENTRY(siglongjmp) + ldr r2, .L_setjmp_magic + ldr r3, [r0] + teq r2, r3 + beq PIC_SYM(_C_LABEL(_longjmp), PLT) + b PIC_SYM(_C_LABEL(longjmp), PLT) diff --git a/libc/arch-arm/bionic/strlen.c b/libc/arch-arm/bionic/strlen.c new file mode 100644 index 0000000..01632e3 --- /dev/null +++ b/libc/arch-arm/bionic/strlen.c @@ -0,0 +1,129 @@ +/* + * 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 <string.h> +#include <stdint.h> +#include <machine/cpu-features.h> + +size_t strlen(const char *s) +{ + __builtin_prefetch(s); + __builtin_prefetch(s+32); + + union { + const char *b; + const uint32_t *w; + uintptr_t i; + } u; + + // these are some scratch variables for the asm code below + uint32_t v, t; + + // initialize the string length to zero + size_t l = 0; + + // align the pointer to a 32-bit word boundary + u.b = s; + while (u.i & 0x3) { + if (__builtin_expect(*u.b++ == 0, 0)) { + goto done; + } + l++; + } + + // loop for each word, testing if it contains a zero byte + // if so, exit the loop and update the length. + // We need to process 32 bytes per loop to schedule PLD properly + // and achieve the maximum bus speed. + asm( + "ldr %[v], [ %[s] ], #4 \n" + "sub %[l], %[l], %[s] \n" + "0: \n" +#if __ARM_HAVE_PLD + "pld [ %[s], #64 ] \n" +#endif + "sub %[t], %[v], %[mask], lsr #7\n" + "and %[t], %[t], %[mask] \n" + "bics %[t], %[t], %[v] \n" + "ldreq %[v], [ %[s] ], #4 \n" +#if !defined(__OPTIMIZE_SIZE__) + "bne 1f \n" + "sub %[t], %[v], %[mask], lsr #7\n" + "and %[t], %[t], %[mask] \n" + "bics %[t], %[t], %[v] \n" + "ldreq %[v], [ %[s] ], #4 \n" + "bne 1f \n" + "sub %[t], %[v], %[mask], lsr #7\n" + "and %[t], %[t], %[mask] \n" + "bics %[t], %[t], %[v] \n" + "ldreq %[v], [ %[s] ], #4 \n" + "bne 1f \n" + "sub %[t], %[v], %[mask], lsr #7\n" + "and %[t], %[t], %[mask] \n" + "bics %[t], %[t], %[v] \n" + "ldreq %[v], [ %[s] ], #4 \n" + "bne 1f \n" + "sub %[t], %[v], %[mask], lsr #7\n" + "and %[t], %[t], %[mask] \n" + "bics %[t], %[t], %[v] \n" + "ldreq %[v], [ %[s] ], #4 \n" + "bne 1f \n" + "sub %[t], %[v], %[mask], lsr #7\n" + "and %[t], %[t], %[mask] \n" + "bics %[t], %[t], %[v] \n" + "ldreq %[v], [ %[s] ], #4 \n" + "bne 1f \n" + "sub %[t], %[v], %[mask], lsr #7\n" + "and %[t], %[t], %[mask] \n" + "bics %[t], %[t], %[v] \n" + "ldreq %[v], [ %[s] ], #4 \n" + "bne 1f \n" + "sub %[t], %[v], %[mask], lsr #7\n" + "and %[t], %[t], %[mask] \n" + "bics %[t], %[t], %[v] \n" + "ldreq %[v], [ %[s] ], #4 \n" +#endif + "beq 0b \n" + "1: \n" + "add %[l], %[l], %[s] \n" + "tst %[v], #0xFF \n" + "beq 2f \n" + "add %[l], %[l], #1 \n" + "tst %[v], #0xFF00 \n" + "beq 2f \n" + "add %[l], %[l], #1 \n" + "tst %[v], #0xFF0000 \n" + "addne %[l], %[l], #1 \n" + "2: \n" + : [l]"=&r"(l), [v]"=&r"(v), [t]"=&r"(t), [s]"=&r"(u.b) + : "%[l]"(l), "%[s]"(u.b), [mask]"r"(0x80808080UL) + : "cc" + ); + +done: + return l; +} diff --git a/libc/arch-arm/bionic/syscall.S b/libc/arch-arm/bionic/syscall.S new file mode 100644 index 0000000..ada12a6 --- /dev/null +++ b/libc/arch-arm/bionic/syscall.S @@ -0,0 +1,71 @@ +/* + * 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/linux-syscalls.h> + + + .text + .align 4 + .type syscall,#function + .globl syscall + + .text + .align + +#if __ARM_EABI__ + +syscall: + mov ip, sp + stmfd sp!, {r4, r5, r6, r7} + mov r7, r0 + mov r0, r1 + mov r1, r2 + mov r2, r3 + ldmfd ip, {r3, r4, r5, r6} + swi #0 + ldmfd sp!, {r4, r5, r6, r7} + movs r0, r0 + bxpl lr + b __set_syscall_errno + +#else + +#ifndef __NR_syscall +#define __NR_syscall 113 +#endif + +syscall: + stmfd sp!, {r4, r5, lr} + ldr r4, [sp, #12] + ldr r5, [sp, #16] + swi __NR_syscall + ldmfd sp!, {r4, r5, lr} + movs r0, r0 + bxpl lr + b __set_syscall_errno + +#endif diff --git a/libc/arch-arm/bionic/tkill.S b/libc/arch-arm/bionic/tkill.S new file mode 100644 index 0000000..7b3301a --- /dev/null +++ b/libc/arch-arm/bionic/tkill.S @@ -0,0 +1,53 @@ +/* + * 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. + */ +/* unlike our auto-generated syscall stubs, this code saves lr + on the stack, as well as a few other registers. this makes + our stack unwinder happy, when we generate debug stack + traces after the C library or other parts of the system + abort due to a fatal runtime error (e.g. detection + of a corrupted malloc heap). +*/ +#include <sys/linux-syscalls.h> + +#ifndef __NR_tkill +#define __NR_tkill 238 +#endif + + .text + .type tkill, #function + .globl tkill + .align 4 + +tkill: + stmfd sp!, {r4-r7, ip, lr} + ldr r7, =__NR_tkill + swi #0 + ldmfd sp!, {r4-r7, ip, lr} + movs r0, r0 + bxpl lr + b __set_syscall_errno |