diff options
Diffstat (limited to 'libc')
-rw-r--r-- | libc/string/powerpc/string.c | 72 | ||||
-rw-r--r-- | libc/sysdeps/linux/alpha/crt1.S | 80 | ||||
-rw-r--r-- | libc/sysdeps/linux/arm/__syscall_error.c | 29 | ||||
-rw-r--r-- | libc/sysdeps/linux/arm/crt1.S | 143 | ||||
-rw-r--r-- | libc/sysdeps/linux/i386/__syscall_error.c | 29 | ||||
-rw-r--r-- | libc/sysdeps/linux/i386/crt1.S | 140 | ||||
-rw-r--r-- | libc/sysdeps/linux/sparc/__syscall_error.c | 29 | ||||
-rw-r--r-- | libc/sysdeps/linux/sparc/crt1.S | 134 | ||||
-rw-r--r-- | libc/sysdeps/linux/x86_64/__syscall_error.c | 29 | ||||
-rw-r--r-- | libc/sysdeps/linux/x86_64/crt1.S | 140 | ||||
-rw-r--r-- | libc/sysdeps/linux/x86_64/mmap.c | 17 |
11 files changed, 812 insertions, 30 deletions
diff --git a/libc/string/powerpc/string.c b/libc/string/powerpc/string.c index 1835e6aa7..acd5d0144 100644 --- a/libc/string/powerpc/string.c +++ b/libc/string/powerpc/string.c @@ -32,15 +32,16 @@ #include <locale.h> /* for __LOCALE_C_ONLY */ #ifdef L_memcpy -void *memcpy(void *to, const void *from, size_t n) +void attribute_hidden *__memcpy(void *to, const void *from, size_t n) /* PPC can do pre increment and load/store, but not post increment and load/store. Therefore use *++ptr instead of *ptr++. */ { unsigned long rem, chunks, tmp1, tmp2; - void *tmp_to; + unsigned char *tmp_to; + unsigned char *tmp_from = (unsigned char *)from; chunks = n / 8; - from -= 4; + tmp_from -= 4; tmp_to = to - 4; if (!chunks) goto lessthan8; @@ -50,9 +51,9 @@ void *memcpy(void *to, const void *from, size_t n) copy_chunks: do { /* make gcc to load all data, then store it */ - tmp1 = *(unsigned long *)(from+4); - from += 8; - tmp2 = *(unsigned long *)from; + tmp1 = *(unsigned long *)(tmp_from+4); + tmp_from += 8; + tmp2 = *(unsigned long *)tmp_from; *(unsigned long *)(tmp_to+4) = tmp1; tmp_to += 8; *(unsigned long *)tmp_to = tmp2; @@ -60,23 +61,25 @@ void *memcpy(void *to, const void *from, size_t n) lessthan8: n = n % 8; if (n >= 4) { - *++(unsigned long *)tmp_to = *++(unsigned long *)from; + *(unsigned long *)(tmp_to+4) = *(unsigned long *)(tmp_from+4); + tmp_from += 4; + tmp_to += 4; n = n-4; } if (!n ) return to; - from += 3; + tmp_from += 3; tmp_to += 3; do { - *++(unsigned char *)tmp_to = *++(unsigned char *)from; + *++tmp_to = *++tmp_from; } while (--n); return to; align: rem = 4 - rem; - n = n-rem; + n = n - rem; do { - *(unsigned char *)(tmp_to+4) = *(unsigned char *)(from+4); - ++from; + *(tmp_to+4) = *(tmp_from+4); + ++tmp_from; ++tmp_to; } while (--rem); chunks = n / 8; @@ -84,18 +87,20 @@ void *memcpy(void *to, const void *from, size_t n) goto copy_chunks; goto lessthan8; } +strong_alias(__memcpy, memcpy); #endif #ifdef L_memmove -void *memmove(void *to, const void *from, size_t n) +void attribute_hidden *__memmove(void *to, const void *from, size_t n) { unsigned long rem, chunks, tmp1, tmp2; - void *tmp_to; + unsigned char *tmp_to; + unsigned char *tmp_from = (unsigned char *)from; - if (from >= to) + if (tmp_from >= (unsigned char *)to) return memcpy(to, from, n); chunks = n / 8; - from += n; + tmp_from += n; tmp_to = to + n; if (!chunks) goto lessthan8; @@ -105,9 +110,9 @@ void *memmove(void *to, const void *from, size_t n) copy_chunks: do { /* make gcc to load all data, then store it */ - tmp1 = *(unsigned long *)(from-4); - from -= 8; - tmp2 = *(unsigned long *)from; + tmp1 = *(unsigned long *)(tmp_from-4); + tmp_from -= 8; + tmp2 = *(unsigned long *)tmp_from; *(unsigned long *)(tmp_to-4) = tmp1; tmp_to -= 8; *(unsigned long *)tmp_to = tmp2; @@ -115,26 +120,29 @@ void *memmove(void *to, const void *from, size_t n) lessthan8: n = n % 8; if (n >= 4) { - *--(unsigned long *)tmp_to = *--(unsigned long *)from; + *(unsigned long *)(tmp_to-4) = *(unsigned long *)(tmp_from-4); + tmp_from -= 4; + tmp_to -= 4; n = n-4; } if (!n ) return to; do { - *--(unsigned char *)tmp_to = *--(unsigned char *)from; + *--tmp_to = *--tmp_from; } while (--n); return to; align: rem = 4 - rem; - n = n-rem; + n = n - rem; do { - *--(unsigned char *)tmp_to = *--(unsigned char *)from; + *--tmp_to = *--tmp_from; } while (--rem); chunks = n / 8; if (chunks) goto copy_chunks; goto lessthan8; } +strong_alias(__memmove, memmove); #endif #ifdef L_memset @@ -148,10 +156,10 @@ static inline int expand_byte_word(int c){ : "=r" (c) : "0" (c)); return c; } -void *memset(void *to, int c, size_t n) +void attribute_hidden *__memset(void *to, int c, size_t n) { unsigned long rem, chunks; - void *tmp_to; + unsigned char *tmp_to; chunks = n / 8; tmp_to = to - 4; @@ -163,19 +171,22 @@ void *memset(void *to, int c, size_t n) goto align; copy_chunks: do { - *++(unsigned long *)tmp_to = c; - *++(unsigned long *)tmp_to = c; + *(unsigned long *)(tmp_to+4) = c; + tmp_to += 4; + *(unsigned long *)(tmp_to+4) = c; + tmp_to += 4; } while (--chunks); lessthan8: n = n % 8; if (n >= 4) { - *++(unsigned long *)tmp_to = c; + *(unsigned long *)(tmp_to+4) = c; + tmp_to += 4; n = n-4; } if (!n ) return to; tmp_to += 3; do { - *++(unsigned char *)tmp_to = c; + *++tmp_to = c; } while (--n); return to; @@ -183,7 +194,7 @@ void *memset(void *to, int c, size_t n) rem = 4 - rem; n = n-rem; do { - *(unsigned char *)(tmp_to+4) = c; + *(tmp_to+4) = c; ++tmp_to; } while (--rem); chunks = n / 8; @@ -191,6 +202,7 @@ void *memset(void *to, int c, size_t n) goto copy_chunks; goto lessthan8; } +strong_alias(__memset, memset); #endif #ifdef L_bzero diff --git a/libc/sysdeps/linux/alpha/crt1.S b/libc/sysdeps/linux/alpha/crt1.S new file mode 100644 index 000000000..0831ecf6f --- /dev/null +++ b/libc/sysdeps/linux/alpha/crt1.S @@ -0,0 +1,80 @@ +/* Startup code for Alpha/ELF. + Copyright (C) 1993,1995,1996,1997,1998,2000,2001 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Richard Henderson <rth@tamu.edu> + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include <features.h> +#include <asm/regdef.h> + +.text +.global _start +.ent _start,0 +.type _start,%function +#if defined(__UCLIBC_CTOR_DTOR__) +.type _init,%function +.type _fini,%function +#else +.weak _init +.weak _fini +#endif +.type __uClibc_main,%function +/* Stick in a dummy reference to main(), so that if an application + * is linking when the main() function is in a static library (.a) + * we can be sure that main() actually gets linked in */ +.type main,%function + +_start: + .frame $15, 0, $15 + br gp, 1f +1: ldgp gp, 0(gp) + subq sp, 16, sp + mov 0, $15 + .prologue 0 + + /* Load address of the user's main function. */ + lda a0, main + + ldl a1, 16(sp) /* get argc */ + lda a2, 24(sp) /* get argv */ + + /* Load address of our own entry points to .fini and .init. */ + lda a3, _init + lda a4, _fini + + /* Store address of the shared library termination function. */ + mov v0, a5 + + /* Provide the highest stack address to the user code. */ + stq sp, 0(sp) + + /* Call the user's main function, and exit with its value. + * But let the libc call main. */ + jsr ra, __uClibc_main + + /* Die very horribly if exit returns. Call_pal hlt is callable from + * kernel mode only; this will result in an illegal instruction trap. */ + call_pal 0 + .end _start + +/* Define a symbol for the first piece of initialized data. */ +.data +.global __data_start +__data_start: +.long 0 +.weak data_start + data_start = __data_start diff --git a/libc/sysdeps/linux/arm/__syscall_error.c b/libc/sysdeps/linux/arm/__syscall_error.c new file mode 100644 index 000000000..de65a1f39 --- /dev/null +++ b/libc/sysdeps/linux/arm/__syscall_error.c @@ -0,0 +1,29 @@ +/* Wrapper for setting errno. + Copyright (C) 1997, 1998, 1999, 2000 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include <errno.h> +#include <features.h> + +/* This routine is jumped to by all the syscall handlers, to stash + * an error number into errno. */ +int attribute_hidden __syscall_error(int err_no) +{ + __set_errno(err_no); + return -1; +} diff --git a/libc/sysdeps/linux/arm/crt1.S b/libc/sysdeps/linux/arm/crt1.S new file mode 100644 index 000000000..01e1f61d3 --- /dev/null +++ b/libc/sysdeps/linux/arm/crt1.S @@ -0,0 +1,143 @@ +/* Startup code for ARM & ELF + Copyright (C) 1995, 1996, 1997, 1998, 2001, 2002 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +/* This is the canonical entry point, usually the first thing in the text + segment. + + Note that the code in the .init section has already been run. + This includes _init and _libc_init + + + At this entry point, most registers' values are unspecified, except: + + a1 Contains a function pointer to be registered with `atexit'. + This is how the dynamic linker arranges to have DT_FINI + functions called for shared libraries that have been loaded + before this code runs. + + sp The stack contains the arguments and environment: + 0(sp) argc + 4(sp) argv[0] + ... + (4*argc)(sp) NULL + (4*(argc+1))(sp) envp[0] + ... + NULL +*/ +/* + For uClinux it looks like this: + + argc argument counter (integer) + argv char *argv[] + envp char *envp[] + argv[0] program name (pointer) + argv[1...N] program args (pointers) + argv[argc-1] end of args (integer) + NULL + env[0...N] environment variables (pointers) + NULL + +ARM register quick reference: + + Name Number ARM Procedure Calling Standard Role + + a1 r0 argument 1 / integer result / scratch register / argc + a2 r1 argument 2 / scratch register / argv + a3 r2 argument 3 / scratch register / envp + a4 r3 argument 4 / scratch register + v1 r4 register variable + v2 r5 register variable + v3 r6 register variable + v4 r7 register variable + v5 r8 register variable + sb/v6 r9 static base / register variable + sl/v7 r10 stack limit / stack chunk handle / reg. variable + fp r11 frame pointer + ip r12 scratch register / new-sb in inter-link-unit calls + sp r13 lower end of current stack frame + lr r14 link address / scratch register + pc r15 program counter +*/ + + .text + .globl _start + .type _start,#function +_start: + /* Clear the frame pointer and link register since this is the outermost frame. */ + mov fp, #0 + mov lr, #0 + + /* Pop argc off the stack and save a pointer to argv */ + ldr a2, [sp], #4 + mov a3, sp + + /* Push stack limit */ + str a3, [sp, #-4]! + + /* Push rtld_fini */ + str a1, [sp, #-4]! + +#ifdef __PIC__ + ldr sl, .L_GOT +.L_GOT_OFF: + add sl, pc, sl + + ldr ip, .L_GOT+4 /* _fini */ + ldr a1, [sl, ip] + str a1, [sp, #-4]! /* Push _fini */ + + ldr ip, .L_GOT+8 /* _init */ + ldr a4, [sl, ip] + + ldr ip, .L_GOT+12 /* main */ + ldr a1, [sl, ip] + + /* __uClibc_main (main, argc, argv, init, fini, rtld_fini, stack_end) */ + /* Let the libc call main and exit with its return code. */ + b __uClibc_main(PLT) +#else + /* Fetch address of fini */ + ldr ip, =_fini + /* Push fini */ + str ip, [sp, #-4]! + + /* Set up the other arguments in registers */ + ldr a1, =main + ldr a4, =_init + + /* __uClibc_main (main, argc, argv, init, fini, rtld_fini, stack_end) */ + /* Let the libc call main and exit with its return code. */ + b __uClibc_main +#endif + +#ifdef __PIC__ +.L_GOT: + .word _GLOBAL_OFFSET_TABLE_-(.L_GOT_OFF+8) + .word _fini(GOT) + .word _init(GOT) + .word main(GOT) +#endif + +/* Define a symbol for the first piece of initialized data. */ + .data + .globl __data_start +__data_start: + .long 0 + .weak data_start + data_start = __data_start diff --git a/libc/sysdeps/linux/i386/__syscall_error.c b/libc/sysdeps/linux/i386/__syscall_error.c new file mode 100644 index 000000000..de65a1f39 --- /dev/null +++ b/libc/sysdeps/linux/i386/__syscall_error.c @@ -0,0 +1,29 @@ +/* Wrapper for setting errno. + Copyright (C) 1997, 1998, 1999, 2000 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include <errno.h> +#include <features.h> + +/* This routine is jumped to by all the syscall handlers, to stash + * an error number into errno. */ +int attribute_hidden __syscall_error(int err_no) +{ + __set_errno(err_no); + return -1; +} diff --git a/libc/sysdeps/linux/i386/crt1.S b/libc/sysdeps/linux/i386/crt1.S new file mode 100644 index 000000000..a133cb9e0 --- /dev/null +++ b/libc/sysdeps/linux/i386/crt1.S @@ -0,0 +1,140 @@ +/* Startup code compliant to the ELF i386 ABI. + Copyright (C) 1995, 1996, 1997, 1998, 2000, 2001, 2002, 2003, 2004 + Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + In addition to the permissions in the GNU Lesser General Public + License, the Free Software Foundation gives you unlimited + permission to link the compiled version of this file with other + programs, and to distribute those programs without any restriction + coming from the use of this file. (The GNU Lesser General Public + License restrictions do apply in other respects; for example, they + cover modification of the file, and distribution when not linked + into another program.) + + Note that people who make modified versions of this file are not + obligated to grant this special exception for their modified + versions; it is their choice whether to do so. The GNU Lesser + General Public License gives permission to release a modified + version without this exception; this exception also makes it + possible to release a modified version which carries forward this + exception. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +/* This is the canonical entry point, usually the first thing in the text + segment. The SVR4/i386 ABI (pages 3-31, 3-32) says that when the entry + point runs, most registers' values are unspecified, except for: + + %edx Contains a function pointer to be registered with `atexit'. + This is how the dynamic linker arranges to have DT_FINI + functions called for shared libraries that have been loaded + before this code runs. + + %esp The stack contains the arguments and environment: + 0(%esp) argc + 4(%esp) argv[0] + ... + (4*argc)(%esp) NULL + (4*(argc+1))(%esp) envp[0] + ... + NULL +*/ + +#include <features.h> + +.text +.global _start +.type _start,%function +#if defined(__UCLIBC_CTOR_DTOR__) +.type _init,%function +.type _fini,%function +#else +.weak _init +.weak _fini +#endif +.type main,%function +.type __uClibc_main,%function +_start: + /* Clear the frame pointer. The ABI suggests this be done, to mark + the outermost frame obviously. */ + xorl %ebp, %ebp + + /* Extract the arguments as encoded on the stack and set up + the arguments for `main': argc, argv. envp will be determined + later in __libc_start_main. */ + popl %esi /* Pop the argument count. */ + movl %esp, %ecx /* argv starts just at the current stack top.*/ + + /* Before pushing the arguments align the stack to a 16-byte + (SSE needs 16-byte alignment) boundary to avoid penalties from + misaligned accesses. Thanks to Edward Seidl <seidl@janed.com> + for pointing this out. */ + andl $0xfffffff0, %esp + pushl %eax /* Push garbage because we allocate + 28 more bytes. */ + + /* Provide the highest stack address to the user code (for stacks + which grow downwards). */ + pushl %esp + + pushl %edx /* Push address of the shared library + termination function. */ + +#ifdef __PIC__ + /* Load PIC register. */ + call .L0 +.L0: + pop %ebx + addl $_GLOBAL_OFFSET_TABLE_+[.-.L0],%ebx + + /* Push address of our own entry points to .fini and .init. */ + pushl _fini@GOT(%ebx) + pushl _init@GOT(%ebx) + + pushl %ecx /* Push second argument: argv. */ + pushl %esi /* Push first argument: argc. */ + + pushl main@GOT(%ebx) + + /* Call the user's main function, and exit with its value. + But let the libc call main. */ + call __uClibc_main@PLT +#else + /* Push address of our own entry points to .fini and .init. */ + pushl $_fini + pushl $_init + + pushl %ecx /* Push second argument: argv. */ + pushl %esi /* Push first argument: argc. */ + + pushl $main + + /* Call the user's main function, and exit with its value. + But let the libc call main. */ + call __uClibc_main +#endif + + hlt /* Crash if somehow `exit' does return. */ +.size _start,.-_start + +/* Define a symbol for the first piece of initialized data. */ +.data +.global __data_start +__data_start: +.long 0 +.weak data_start + data_start = __data_start diff --git a/libc/sysdeps/linux/sparc/__syscall_error.c b/libc/sysdeps/linux/sparc/__syscall_error.c new file mode 100644 index 000000000..de65a1f39 --- /dev/null +++ b/libc/sysdeps/linux/sparc/__syscall_error.c @@ -0,0 +1,29 @@ +/* Wrapper for setting errno. + Copyright (C) 1997, 1998, 1999, 2000 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include <errno.h> +#include <features.h> + +/* This routine is jumped to by all the syscall handlers, to stash + * an error number into errno. */ +int attribute_hidden __syscall_error(int err_no) +{ + __set_errno(err_no); + return -1; +} diff --git a/libc/sysdeps/linux/sparc/crt1.S b/libc/sysdeps/linux/sparc/crt1.S new file mode 100644 index 000000000..f33a714ef --- /dev/null +++ b/libc/sysdeps/linux/sparc/crt1.S @@ -0,0 +1,134 @@ +/* Startup code for elf{32,64}-sparc + Copyright (C) 1997, 1998, 2002, 2004 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Richard Henderson <richard@gnu.ai.mit.edu>, 1997. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + In addition to the permissions in the GNU Lesser General Public + License, the Free Software Foundation gives you unlimited + permission to link the compiled version of this file with other + programs, and to distribute those programs without any restriction + coming from the use of this file. (The GNU Lesser General Public + License restrictions do apply in other respects; for example, they + cover modification of the file, and distribution when not linked + into another program.) + + Note that people who make modified versions of this file are not + obligated to grant this special exception for their modified + versions; it is their choice whether to do so. The GNU Lesser + General Public License gives permission to release a modified + version without this exception; this exception also makes it + possible to release a modified version which carries forward this + exception. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +/* Originally based on glibc's sysdeps/sparc/sparc{32,64}/elf/start.S */ + +#include <features.h> +#include <bits/wordsize.h> + +/* macro out the 32 / 64 bit differences */ +#if __WORDSIZE == 32 +# define STACK_BIAS 0 +# define ELE_SIZE 4 +# define LD ld +#else +# define STACK_BIAS 2047 /* see glibc/sysdeps/unix/sysv/linux/sparc/sparc64/sysdep.h */ +# define ELE_SIZE 8 +# define LD ldx +#endif + +.text +.align 4 +.global _start +.type _start,%function +#if defined(__UCLIBC_CTOR_DTOR__) +.type _init,%function +.type _fini,%function +#else +.weak _init +.weak _fini +#endif +.type __uClibc_main,%function +/* Stick in a dummy reference to main(), so that if an application + * is linking when the main() function is in a static library (.a) + * we can be sure that main() actually gets linked in */ +.global main +.type main,%function + +#ifdef __PIC__ +.LLGETPC0: + retl + add %o7, %l7, %l7 +#endif + +_start: +#ifdef __PIC__ + sethi %hi(_GLOBAL_OFFSET_TABLE_-4), %l7 + call .LLGETPC0 + add %l7, %lo(_GLOBAL_OFFSET_TABLE_+4), %l7 +#endif + + /* Terminate the stack frame, and reserve space for functions to + * drop their arguments. */ + mov %g0, %fp + sub %sp, 6*ELE_SIZE, %sp + + /* Extract the arguments and environment as encoded on the stack. The + * argument info starts after one register window (16 words) past the SP. */ + LD [%sp+STACK_BIAS+22*ELE_SIZE], %o1 /* %o1 = argc */ + add %sp, STACK_BIAS+23*ELE_SIZE, %o2 /* %o2 = argv */ + + /* Load the addresses of the user entry points. */ + sethi %hi(main), %o0 + sethi %hi(_init), %o3 + sethi %hi(_fini), %o4 + or %o0, %lo(main), %o0 + or %o3, %lo(_init), %o3 + or %o4, %lo(_fini), %o4 +#ifdef __PIC__ + /* Need a little more magic when building PIC to get addr of main */ + LD [%l7 + %o0], %o0 + LD [%l7 + %o3], %o3 + LD [%l7 + %o4], %o4 +#endif + + /* When starting a binary via the dynamic linker, %g1 contains the + * address of the shared library termination function, which will be + * registered with atexit(). If we are statically linked, this will + * be NULL. */ + mov %g1, %o5 + + /* Let libc do the rest of the initialization, and call main. */ + call __uClibc_main + nop + + /* Die very horribly if exit returns. */ +#if __WORDSIZE == 32 + unimp +#else + illtrap 0 +#endif + +.size _start,.-_start + +/* Define a symbol for the first piece of initialized data. */ +.data +.global __data_start +__data_start: +.long 0 +.weak data_start + data_start = __data_start diff --git a/libc/sysdeps/linux/x86_64/__syscall_error.c b/libc/sysdeps/linux/x86_64/__syscall_error.c new file mode 100644 index 000000000..de65a1f39 --- /dev/null +++ b/libc/sysdeps/linux/x86_64/__syscall_error.c @@ -0,0 +1,29 @@ +/* Wrapper for setting errno. + Copyright (C) 1997, 1998, 1999, 2000 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include <errno.h> +#include <features.h> + +/* This routine is jumped to by all the syscall handlers, to stash + * an error number into errno. */ +int attribute_hidden __syscall_error(int err_no) +{ + __set_errno(err_no); + return -1; +} diff --git a/libc/sysdeps/linux/x86_64/crt1.S b/libc/sysdeps/linux/x86_64/crt1.S new file mode 100644 index 000000000..f6c1eb1e7 --- /dev/null +++ b/libc/sysdeps/linux/x86_64/crt1.S @@ -0,0 +1,140 @@ +/* Startup code compliant to the ELF x86-64 ABI. + Copyright (C) 2001, 2002, 2003, 2005 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Andreas Jaeger <aj@suse.de>, 2001. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + In addition to the permissions in the GNU Lesser General Public + License, the Free Software Foundation gives you unlimited + permission to link the compiled version of this file with other + programs, and to distribute those programs without any restriction + coming from the use of this file. (The GNU Lesser General Public + License restrictions do apply in other respects; for example, they + cover modification of the file, and distribution when not linked + into another program.) + + Note that people who make modified versions of this file are not + obligated to grant this special exception for their modified + versions; it is their choice whether to do so. The GNU Lesser + General Public License gives permission to release a modified + version without this exception; this exception also makes it + possible to release a modified version which carries forward this + exception. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +/* Originally based on glibc's sysdeps/x86_64/elf/start.S */ + +/* This is the canonical entry point, usually the first thing in the text + segment. The SVR4/i386 ABI (pages 3-31, 3-32) says that when the entry + point runs, most registers' values are unspecified, except for: + + %rdx Contains a function pointer to be registered with `atexit'. + This is how the dynamic linker arranges to have DT_FINI + functions called for shared libraries that have been loaded + before this code runs. + + %rsp The stack contains the arguments and environment: + 0(%rsp) argc + 8(%rsp) argv[0] + ... + (8*argc)(%rsp) NULL + (8*(argc+1))(%rsp) envp[0] + ... + NULL +*/ + +#include <features.h> + +.text +.global _start +.type _start,%function +#if defined(__UCLIBC_CTOR_DTOR__) +.type _init,%function +.type _fini,%function +#else +.weak _init +.weak _fini +#endif +.type __uClibc_main,%function +/* Stick in a dummy reference to main(), so that if an application + * is linking when the main() function is in a static library (.a) + * we can be sure that main() actually gets linked in */ +.type main,%function + +_start: + /* Clear the frame pointer. The ABI suggests this be done, to mark + the outermost frame obviously. */ + xorl %ebp, %ebp + + /* Extract the arguments as encoded on the stack and set up + the arguments for __libc_start_main (int (*main) (int, char **, char **), + int argc, char *argv, + void (*init) (void), void (*fini) (void), + void (*rtld_fini) (void), void *stack_end). + The arguments are passed via registers and on the stack: + main: %rdi + argc: %rsi + argv: %rdx + init: %rcx + fini: %r8 + rtld_fini: %r9 + stack_end: stack. */ + + movq %rdx, %r9 /* Address of the shared library termination function. */ + popq %rsi /* Pop the argument count. */ + movq %rsp, %rdx /* argv starts just at the current stack top. */ + + /* Align the stack to a 16 byte boundary to follow the ABI. */ + andq $~15, %rsp + + pushq %rax /* Push garbage because we push 8 more bytes. */ + + /* Provide the highest stack address to the user code (for stacks + which grow downwards). */ + pushq %rsp + +#if defined(L_Scrt1) + /* Give address for main() */ + movq main@GOTPCREL(%rip), %rdi + + /* setup init/fini address */ + movq _init@GOTPCREL(%rip), %rcx + movq _fini@GOTPCREL(%rip), %r8 + + /* start the fun */ + call __uClibc_main@PLT +#else + /* Give address for main() */ + movq $main, %rdi + + /* setup init/fini address */ + movq $_init, %rcx + movq $_fini, %r8 + + /* start the fun */ + call __uClibc_main +#endif + + hlt /* Crash if somehow `exit' does return. */ +.size _start,.-_start + +/* Define a symbol for the first piece of initialized data. */ +.data +.global __data_start +__data_start: +.long 0 +.weak data_start + data_start = __data_start diff --git a/libc/sysdeps/linux/x86_64/mmap.c b/libc/sysdeps/linux/x86_64/mmap.c new file mode 100644 index 000000000..117d93ddc --- /dev/null +++ b/libc/sysdeps/linux/x86_64/mmap.c @@ -0,0 +1,17 @@ +/* vi: set sw=4 ts=4: */ +/* + * mmap() for uClibc/x86_64 + * + * Copyright (C) 2005 by Erik Andersen <andersen@codepoet.org> + * Copyright (C) 2005 by Mike Frysinger <vapier@gentoo.org> + * + * GNU Library General Public License (LGPL) version 2 or later. + */ + +#include <errno.h> +#include <unistd.h> +#include <sys/mman.h> +#include <sys/syscall.h> + +_syscall6(void *, mmap, void *, start, size_t, length, int, prot, + int, flags, int, fd, off_t, offset); |