diff options
author | "Steven J. Hill" <sjhill@realitydiluted.com> | 2006-02-28 00:54:52 +0000 |
---|---|---|
committer | "Steven J. Hill" <sjhill@realitydiluted.com> | 2006-02-28 00:54:52 +0000 |
commit | 2fb769718703b255e9f6e91daf27650dede80229 (patch) | |
tree | b190163e67cc1881b33a5ba9bb503216f4bae811 /libc/sysdeps/linux/vax/crt1.S | |
parent | 5eb1fae2a97ffc88d136502ace050662e57ef34a (diff) | |
download | uClibc-alpine-2fb769718703b255e9f6e91daf27650dede80229.tar.bz2 uClibc-alpine-2fb769718703b255e9f6e91daf27650dede80229.tar.xz |
Copy from trunk.
Diffstat (limited to 'libc/sysdeps/linux/vax/crt1.S')
-rw-r--r-- | libc/sysdeps/linux/vax/crt1.S | 73 |
1 files changed, 73 insertions, 0 deletions
diff --git a/libc/sysdeps/linux/vax/crt1.S b/libc/sysdeps/linux/vax/crt1.S new file mode 100644 index 000000000..70960988d --- /dev/null +++ b/libc/sysdeps/linux/vax/crt1.S @@ -0,0 +1,73 @@ +/* + * crt0 for VAX + */ + +/* + * Program stack looks like: + * sp-> argc argument counter (integer) + * 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 + */ + +#include <features.h> + +.text +.align 4 + +.global __start +__start: +.global _start +_start: + /* Kernel uses a_interp + 2, so __start isn't exactly CALLSed, */ + /* but we need to have two bytes here, so we use NOPs. This */ + /* won't hurt, though R0 would be invalid to push, but at */ + /* lease this looks like a real function. */ + .word 0x0101 + + movl $0, %fp /* FP = 0, since this is the */ + /* top-most stack frame */ + movl %sp, %r0 /* R0 = %sp */ + movl (%sp)+, %r4 /* R4 = argc */ + movl %sp, %r3 /* R3 = argv = &argv[0] */ + +#if (defined L_crt1 || defined L_gcrt1) && defined __UCLIBC_CTOR_DTOR__ + pushl %r0 /* stack_end */ + pushl $0 /* rtld_fini. This is probably needed for the */ + /* case where a dynamic linker is involved. So */ + /* this is an open FIXME that needs to be */ + /* addressed at some time... */ + pushl $_fini + pushl $_init + pushl %r3 /* Argument pointer */ + pushl %r4 /* And the argument count */ + pushl $main /* main() */ + + /* We need to call __uClibc_main which should not return. + * __uClibc_main (int (*main) (int, char **, char **), + * int argc, + * char **argv, + * void (*init) (void), + * void (*fini) (void), + * void (*rtld_fini) (void), + * void *stack_end); + */ + calls $7, __uClibc_main +#else /* FIXME: THIS IS BROKEN!!! */ + /* start to load the arguments from the stack */ + /* arguments are on ap stack */ + pushl %r2 + pushl %r3 + pushl %r4 + + calls $3, __uClibc_main +#endif + + /* The above __uClibc_start_main() shouldn't ever return. If it */ + /* does, we just crash. */ + halt +.align 2 + |