diff options
Diffstat (limited to 'libc/arch-x86/bionic')
-rw-r--r-- | libc/arch-x86/bionic/__get_sp.S | 35 | ||||
-rwxr-xr-x | libc/arch-x86/bionic/__get_tls.c | 37 | ||||
-rwxr-xr-x | libc/arch-x86/bionic/__set_tls.c | 95 | ||||
-rw-r--r-- | libc/arch-x86/bionic/_exit_with_stack_teardown.S | 34 | ||||
-rw-r--r-- | libc/arch-x86/bionic/_setjmp.S | 71 | ||||
-rw-r--r-- | libc/arch-x86/bionic/atomics_x86.S | 140 | ||||
-rw-r--r-- | libc/arch-x86/bionic/atomics_x86.c | 104 | ||||
-rw-r--r-- | libc/arch-x86/bionic/clone.S | 50 | ||||
-rw-r--r-- | libc/arch-x86/bionic/crtbegin_dynamic.S | 96 | ||||
-rw-r--r-- | libc/arch-x86/bionic/crtbegin_so.S | 29 | ||||
-rw-r--r-- | libc/arch-x86/bionic/crtbegin_static.S | 95 | ||||
-rw-r--r-- | libc/arch-x86/bionic/crtend.S | 13 | ||||
-rw-r--r-- | libc/arch-x86/bionic/crtend_so.S | 47 | ||||
-rw-r--r-- | libc/arch-x86/bionic/dl_iterate_phdr_static.c | 74 | ||||
-rw-r--r-- | libc/arch-x86/bionic/setjmp.S | 93 | ||||
-rw-r--r-- | libc/arch-x86/bionic/vfork.S | 30 |
16 files changed, 1043 insertions, 0 deletions
diff --git a/libc/arch-x86/bionic/__get_sp.S b/libc/arch-x86/bionic/__get_sp.S new file mode 100644 index 0000000..aeaaa66 --- /dev/null +++ b/libc/arch-x86/bionic/__get_sp.S @@ -0,0 +1,35 @@ +/* + * 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 + .type __get_sp, @function + .global __get_sp + .align 4 + +__get_sp: + mov %esp, %eax + ret diff --git a/libc/arch-x86/bionic/__get_tls.c b/libc/arch-x86/bionic/__get_tls.c new file mode 100755 index 0000000..5ac6e44 --- /dev/null +++ b/libc/arch-x86/bionic/__get_tls.c @@ -0,0 +1,37 @@ +/* + * 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. + */ +/* see the implementation of __set_tls and pthread.c to understand this + * code. Basically, the content of gs:[0] always is a pointer to the base + * address of the tls region + */ +void* __get_tls(void) +{ + void* tls; + asm ( " movl %%gs:0, %0" : "=r"(tls) ); + return tls; +} diff --git a/libc/arch-x86/bionic/__set_tls.c b/libc/arch-x86/bionic/__set_tls.c new file mode 100755 index 0000000..48b55f0 --- /dev/null +++ b/libc/arch-x86/bionic/__set_tls.c @@ -0,0 +1,95 @@ +/* + * 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 <pthread.h> + + +struct user_desc { + unsigned int entry_number; + unsigned long base_addr; + unsigned int limit; + unsigned int seg_32bit:1; + unsigned int contents:2; + unsigned int read_exec_only:1; + unsigned int limit_in_pages:1; + unsigned int seg_not_present:1; + unsigned int useable:1; + unsigned int empty:25; +}; + +extern int __set_thread_area(struct user_desc *u_info); + +/* the following can't be const, since the first call will + * update the 'entry_number' field + */ +static struct user_desc _tls_desc = +{ + -1, + 0, + 0x1000, + 1, + 0, + 0, + 1, + 0, + 1, + 0 +}; + +struct _thread_area_head { + void *self; +}; + +/* we implement thread local storage through the gs: segment descriptor + * we create a segment descriptor for the tls + */ +int __set_tls(void *ptr) +{ + int rc, segment; + + _tls_desc.base_addr = (unsigned long)ptr; + + /* We also need to write the location of the tls to ptr[0] */ + ((struct _thread_area_head *)ptr)->self = ptr; + + rc = __set_thread_area( &_tls_desc ); + if (rc != 0) + { + /* could not set thread local area */ + return -1; + } + + /* this weird computation comes from GLibc */ + segment = _tls_desc.entry_number*8 + 3; + asm __volatile__ ( + " movw %w0, %%gs" :: "q"(segment) + ); + return 0; +} + + + diff --git a/libc/arch-x86/bionic/_exit_with_stack_teardown.S b/libc/arch-x86/bionic/_exit_with_stack_teardown.S new file mode 100644 index 0000000..83a504d --- /dev/null +++ b/libc/arch-x86/bionic/_exit_with_stack_teardown.S @@ -0,0 +1,34 @@ +#include <sys/linux-syscalls.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: + /* we can trash %ebx here since this call should never return. */ + /* We can also take advantage of the fact that the linux syscall trap + * handler saves all the registers, so we don't need a stack to keep + * the retCode argument for exit while doing the munmap */ + + /* TODO(dmtriyz): No one expects this code to return, so even if + * munmap fails, we have to exit. This should probably be fixed, but + * since ARM side does the same thing, leave it as is. + */ + mov 4(%esp), %ebx /* stackBase */ + mov 8(%esp), %ecx /* stackSize */ + mov 12(%esp), %edx /* retCode, not used for munmap */ + mov $__NR_munmap, %eax + int $0x80 + mov %edx, %ebx /* retrieve the retCode */ + movl $__NR_exit, %eax + int $0x80 + /* exit does not return */ + /* can't have a ret here since we no longer have a usable stack. Seems + * that presently, 'hlt' will cause the program to segfault.. but this + * should never happen :) */ + hlt diff --git a/libc/arch-x86/bionic/_setjmp.S b/libc/arch-x86/bionic/_setjmp.S new file mode 100644 index 0000000..ac62635 --- /dev/null +++ b/libc/arch-x86/bionic/_setjmp.S @@ -0,0 +1,71 @@ +/* $OpenBSD: _setjmp.S,v 1.5 2005/08/07 11:30:38 espie Exp $ */ +/*- + * Copyright (c) 1990 The Regents of the University of California. + * All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * William Jolitz. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include <machine/asm.h> + +/* + * 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. + */ + +ENTRY(_setjmp) + movl 4(%esp),%eax + movl 0(%esp),%edx + movl %edx, 0(%eax) /* rta */ + movl %ebx, 4(%eax) + movl %esp, 8(%eax) + movl %ebp,12(%eax) + movl %esi,16(%eax) + movl %edi,20(%eax) + xorl %eax,%eax + ret + +ENTRY(_longjmp) + movl 4(%esp),%edx + movl 8(%esp),%eax + movl 0(%edx),%ecx + movl 4(%edx),%ebx + movl 8(%edx),%esp + movl 12(%edx),%ebp + movl 16(%edx),%esi + movl 20(%edx),%edi + testl %eax,%eax + jnz 1f + incl %eax +1: movl %ecx,0(%esp) + ret diff --git a/libc/arch-x86/bionic/atomics_x86.S b/libc/arch-x86/bionic/atomics_x86.S new file mode 100644 index 0000000..2370f23 --- /dev/null +++ b/libc/arch-x86/bionic/atomics_x86.S @@ -0,0 +1,140 @@ +#include <sys/linux-syscalls.h> + +#define FUTEX_WAIT 0 +#define FUTEX_WAKE 1 + + +/* + * int __futex_wait(volatile void *ftx, int val, const struct timespec *timeout) + */ +.text +.globl __futex_wait +.type __futex_wait, @function +.align 4 +__futex_wait: + pushl %ebx + pushl %esi + mov 12(%esp), %ebx /* ftx */ + movl $FUTEX_WAIT, %ecx + mov 16(%esp), %edx /* val */ + mov 20(%esp), %esi /* timeout */ + movl $__NR_futex, %eax + int $0x80 + popl %esi + popl %ebx + ret + + +/* int __futex_wake(volatile void *ftx, int count) */ + +.text +.globl __futex_wake +.type __futex_wake, @function +.align 4 +__futex_wake: + pushl %ebx + mov 8(%esp), %ebx /* ftx */ + movl $FUTEX_WAKE, %ecx + mov 12(%esp), %edx /* count */ + movl $__NR_futex, %eax + int $0x80 + 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 + diff --git a/libc/arch-x86/bionic/atomics_x86.c b/libc/arch-x86/bionic/atomics_x86.c new file mode 100644 index 0000000..b7b20e6 --- /dev/null +++ b/libc/arch-x86/bionic/atomics_x86.c @@ -0,0 +1,104 @@ +/* + * 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/atomics.h> + +#define FUTEX_SYSCALL 240 +#define FUTEX_WAIT 0 +#define FUTEX_WAKE 1 + +int __futex_wait(volatile void *ftx, int val) +{ + int ret; + asm volatile ( + "int $0x80;" + : "=a" (ret) + : "0" (FUTEX_SYSCALL), + "b" (ftx), + "c" (FUTEX_WAIT), + "d" (val), + "S" (0) + ); + return ret; +} + +int __futex_wake(volatile void *ftx, int count) +{ + int ret; + asm volatile ( + "int $0x80;" + : "=a" (ret) + : "0" (FUTEX_SYSCALL), + "b" (ftx), + "c" (FUTEX_WAKE), + "d" (count) + ); + return ret; +} + +int __atomic_cmpxchg(int old, int new, volatile int* addr) { + int xchg; + asm volatile ( + "lock;" + "cmpxchg %%ecx, (%%edx);" + "setne %%al;" + : "=a" (xchg) + : "a" (old), + "c" (new), + "d" (addr) + ); + return xchg; +} + +int __atomic_swap(int new, volatile int* addr) { + int old; + asm volatile ( + "lock;" + "xchg %%ecx, (%%edx);" + : "=c" (old) + : "c" (new), + "d" (addr) + ); + return old; +} + +int __atomic_dec(volatile int* addr) { + int old; + do { + old = *addr; + } while (atomic_cmpxchg(old, old-1, addr)); + return old; +} + +int __atomic_inc(volatile int* addr) { + int old; + do { + old = *addr; + } while (atomic_cmpxchg(old, old+1, addr)); + return old; +} + diff --git a/libc/arch-x86/bionic/clone.S b/libc/arch-x86/bionic/clone.S new file mode 100644 index 0000000..361808d --- /dev/null +++ b/libc/arch-x86/bionic/clone.S @@ -0,0 +1,50 @@ +#include <sys/linux-syscalls.h> + +.text + +/* + * int __pthread_clone(int (*fn)(void*), void *tls, int flags, + * void *arg); + */ +.globl __pthread_clone +.type __pthread_clone, @function +.align 4 +__pthread_clone: + pushl %ebx + pushl %ecx + movl 16(%esp), %ecx + movl 20(%esp), %ebx + + # insert arguments onto the child stack + movl 12(%esp), %eax + movl %eax, -12(%ecx) + movl 24(%esp), %eax + movl %eax, -8(%ecx) + lea (%ecx), %eax + movl %eax, -4(%ecx) + + movl $__NR_clone, %eax + int $0x80 + test %eax, %eax + jns 1f + + # an error occured, set errno and return -1 + negl %eax + call __set_errno + orl $-1, %eax + jmp 2f + +1: + jnz 2f + + # we're in the child thread now, call __thread_entry + # with the appropriate arguments on the child stack + # we already placed most of them + subl $16, %esp + jmp __thread_entry + hlt + +2: + popl %ecx + popl %ebx + ret diff --git a/libc/arch-x86/bionic/crtbegin_dynamic.S b/libc/arch-x86/bionic/crtbegin_dynamic.S new file mode 100644 index 0000000..3b47b18 --- /dev/null +++ b/libc/arch-x86/bionic/crtbegin_dynamic.S @@ -0,0 +1,96 @@ +# bionic/arch-x86/bionic/crtbegin_dynamic.S +# +# Copyright 2006, The Android Open Source Project +# +# 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 Google Inc. nor the names of its contributors may +# be used to endorse or promote products derived from this software +# without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY Google Inc. ``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 Google Inc. 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 %esp, %eax + mov $1f, %edx + pushl %edx + mov $0f, %edx + pushl %edx + mov $0, %edx + pushl %edx + pushl %eax + call __libc_init + +0: + jmp 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-x86/bionic/crtbegin_so.S b/libc/arch-x86/bionic/crtbegin_so.S new file mode 100644 index 0000000..d49e9df --- /dev/null +++ b/libc/arch-x86/bionic/crtbegin_so.S @@ -0,0 +1,29 @@ +/* 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: + +.section .init_array, "aw" +.align 4 +.type __INIT_ARRAY__, @object +.globl __INIT_ARRAY__ +__INIT_ARRAY__: + .long -1 + +.section .fini_array, "aw" +.align 4 +.type __FINI_ARRAY__, @object +.globl __FINI_ARRAY__ +__FINI_ARRAY__: + .long -1 + +.section .ctors, "aw" +.align 4 +.type __CTOR_LIST__, @object +.globl __CTOR_LIST__ +__CTOR_LIST__: + .long -1 diff --git a/libc/arch-x86/bionic/crtbegin_static.S b/libc/arch-x86/bionic/crtbegin_static.S new file mode 100644 index 0000000..eb4acee --- /dev/null +++ b/libc/arch-x86/bionic/crtbegin_static.S @@ -0,0 +1,95 @@ +# bionic/arch-x86/bionic/crtbegin_static.S +# +# Copyright 2006, The Android Open Source Project +# +# 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 Google Inc. nor the names of its contributors may +# be used to endorse or promote products derived from this software +# without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY Google Inc. ``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 Google Inc. 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 %esp, %eax + mov $1f, %edx + pushl %edx + mov $0f, %edx + pushl %edx + mov $0, %edx + pushl %edx + pushl %eax + call __libc_init + +0: jmp 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-x86/bionic/crtend.S b/libc/arch-x86/bionic/crtend.S new file mode 100644 index 0000000..7f5fb66 --- /dev/null +++ b/libc/arch-x86/bionic/crtend.S @@ -0,0 +1,13 @@ + + .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-x86/bionic/crtend_so.S b/libc/arch-x86/bionic/crtend_so.S new file mode 100644 index 0000000..7fb2280 --- /dev/null +++ b/libc/arch-x86/bionic/crtend_so.S @@ -0,0 +1,47 @@ +.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 diff --git a/libc/arch-x86/bionic/dl_iterate_phdr_static.c b/libc/arch-x86/bionic/dl_iterate_phdr_static.c new file mode 100644 index 0000000..fd12106 --- /dev/null +++ b/libc/arch-x86/bionic/dl_iterate_phdr_static.c @@ -0,0 +1,74 @@ +/* bionic/arch-x86/bionic/dl_iterate_phdr_static.c +** +** Copyright 2006, The Android Open Source Project +** +** 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 Google Inc. nor the names of its contributors may +** be used to endorse or promote products derived from this software +** without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY Google Inc. ``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 Google Inc. 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 <linux/elf.h> + +/* TODO: Move this into a header that linker.h can also pull it in. + * Silly to have same struct in 2 places. This is temporary. */ +struct dl_phdr_info +{ + Elf32_Addr dlpi_addr; + const char *dlpi_name; + const Elf32_Phdr *dlpi_phdr; + Elf32_Half dlpi_phnum; +}; + +/* Dynamic binaries get this from the dynamic linker (system/linker), which + * we don't pull in for static bins. We also don't have a list of so's to + * iterate over, since there's really only a single monolithic blob of + * code/data. + * + * All we need to do is to find where the executable is in memory, and grab the + * phdr and phnum from there. + */ + +/* ld provides this to us in the default link script */ +extern void *__executable_start; + +int +dl_iterate_phdr(int (*cb)(struct dl_phdr_info *info, size_t size, void *data), + void *data) +{ + struct dl_phdr_info dl_info; + Elf32_Ehdr *ehdr = (Elf32_Ehdr *) &__executable_start; + Elf32_Phdr *phdr = (Elf32_Phdr *)((unsigned long)ehdr + ehdr->e_phoff); + + /* TODO: again, copied from linker.c. Find a better home for this + * later. */ + if (ehdr->e_ident[EI_MAG0] != ELFMAG0) return -1; + if (ehdr->e_ident[EI_MAG1] != ELFMAG1) return -1; + if (ehdr->e_ident[EI_MAG2] != ELFMAG2) return -1; + if (ehdr->e_ident[EI_MAG3] != ELFMAG3) return -1; + + dl_info.dlpi_addr = 0; + dl_info.dlpi_name = NULL; + dl_info.dlpi_phdr = phdr; + dl_info.dlpi_phnum = ehdr->e_phnum; + return cb(&dl_info, sizeof (struct dl_phdr_info), data); +} + diff --git a/libc/arch-x86/bionic/setjmp.S b/libc/arch-x86/bionic/setjmp.S new file mode 100644 index 0000000..bcb5f9d --- /dev/null +++ b/libc/arch-x86/bionic/setjmp.S @@ -0,0 +1,93 @@ +/* $OpenBSD: setjmp.S,v 1.8 2005/08/07 11:30:38 espie Exp $ */ +/*- + * Copyright (c) 1990 The Regents of the University of California. + * All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * William Jolitz. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include <machine/asm.h> + +/* + * 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) + PIC_PROLOGUE + pushl $0 +#ifdef PIC + call PIC_PLT(_C_LABEL(sigblock)) +#else + call _C_LABEL(sigblock) +#endif + addl $4,%esp + PIC_EPILOGUE + + movl 4(%esp),%ecx + movl 0(%esp),%edx + movl %edx, 0(%ecx) + movl %ebx, 4(%ecx) + movl %esp, 8(%ecx) + movl %ebp,12(%ecx) + movl %esi,16(%ecx) + movl %edi,20(%ecx) + movl %eax,24(%ecx) + xorl %eax,%eax + ret + +ENTRY(longjmp) + movl 4(%esp),%edx + PIC_PROLOGUE + pushl 24(%edx) +#ifdef PIC + call PIC_PLT(_C_LABEL(sigsetmask)) +#else + call _C_LABEL(sigsetmask) +#endif + addl $4,%esp + PIC_EPILOGUE + + movl 4(%esp),%edx + movl 8(%esp),%eax + movl 0(%edx),%ecx + movl 4(%edx),%ebx + movl 8(%edx),%esp + movl 12(%edx),%ebp + movl 16(%edx),%esi + movl 20(%edx),%edi + testl %eax,%eax + jnz 1f + incl %eax +1: movl %ecx,0(%esp) + ret diff --git a/libc/arch-x86/bionic/vfork.S b/libc/arch-x86/bionic/vfork.S new file mode 100644 index 0000000..53910ab --- /dev/null +++ b/libc/arch-x86/bionic/vfork.S @@ -0,0 +1,30 @@ +#include <sys/linux-syscalls.h> + +#ifndef __NR_vfork +#define __NR_vfork 190 +#endif + + + .text + .type vfork, @function + .globl vfork + .align 4 + +/* Get rid of the stack modifications (popl/ret) after vfork() success. + * vfork is VERY sneaky. One has to be very careful about what can be done + * between a successful vfork and a a subsequent execve() + */ + +vfork: + /* grab the return address */ + popl %ecx + movl $__NR_vfork, %eax + int $0x80 + cmpl $-129, %eax + jb 1f + negl %eax + pushl %eax + call __set_errno + orl $-1, %eax +1: + jmp *%ecx |