diff options
Diffstat (limited to 'libc/sysdeps/linux/powerpc/crt0.S')
-rw-r--r-- | libc/sysdeps/linux/powerpc/crt0.S | 94 |
1 files changed, 58 insertions, 36 deletions
diff --git a/libc/sysdeps/linux/powerpc/crt0.S b/libc/sysdeps/linux/powerpc/crt0.S index 11738ad5b..ec3fbd4ae 100644 --- a/libc/sysdeps/linux/powerpc/crt0.S +++ b/libc/sysdeps/linux/powerpc/crt0.S @@ -1,9 +1,5 @@ /* - * uC-libc/sysdeps/linux/powerpc/crt0.S - * process init code for powerpc - * - * Copyright (C) 2001 by Lineo, Inc. - * Author: David A. Schleef <ds@schleef.org> + * Copyright (C) 2003 by Erik Andersen * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Library General Public License as published by @@ -18,46 +14,72 @@ * You should have received a copy of the GNU Library General Public License * along with this program; if not, write to the Free Software Foundation, * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ - -/* - _start is called with the following registers initialized: - - r1 null stack frame - r3 argc - r4 argv - r5 envp - r6 auxiliary vector. ignored. - r7 function pointer to jump to when main() exits. If - this is non-zero, it should be registered with atexit(). - Linux always (?) sets r7 to NULL, so it is not implemented - here. */ +/* Integer registers. */ +#define r0 0 +#define r1 1 +#define r2 2 +#define r3 3 +#define r4 4 +#define r5 5 +#define r6 6 +#define r7 7 +#define r8 8 +#define r9 9 +#define r13 13 +#define r31 31 -.text - .global _start - .global __uClibc_main +#include <features.h> - .type _start,%function + .section ".text" + .globl _start + .type main,%function +#if defined L_crt0 || ! defined __UCLIBC_CTOR_DTOR__ .type __uClibc_main,%function +#else + .weak _init + .weak _fini + .type __uClibc_start_main,%function +#endif +/* 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 _start,@function _start: - /* create 2 empty stack frames */ - stwu 1,-32(1) + /* Save the stack pointer, in case we're statically linked under Linux. */ + mr r9,r1 + /* Set up an initial stack frame, and clear the LR. */ + clrrwi r1,r1,4 + li r0,0 + stwu r1,-16(r1) + mtlr r0 + stw r0,0(r1) - lwz 3,32(1) - addi 4,1,36 - addi 5,1,40 - rlwinm 0,3,2,0,29 - add 5,5,0 + /* find argc from the stack pointer */ + lwz r3,0(r9) + /* find argv one word offset from the stack pointer */ + addi r4,r9,4 + /* find environment pointer (argv+argc+1) */ + lwz r5,0(r9) + addi r5,r5,1 + rlwinm r5,r5,2,0,29 + add r5,r5,r4 + /* Ok, now run uClibc's main() -- shouldn't return */ +#if defined L_crt0 || ! defined __UCLIBC_CTOR_DTOR__ bl __uClibc_main +#else + lis r6,_init@ha # load top 16 bits + addi r6,r6,_init@l # load bottom 16 bits + lis r7,_fini@ha # load top 16 bits of &msg + addi r7,r7,_fini@l # load bottom 16 bits + bl __uClibc_start_main +#endif +.size _start,.-_start -/* 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 */ -L_dummy_main_reference: - .long main + .section ".data" + .globl __data_start +__data_start: |