summaryrefslogtreecommitdiff
path: root/libc/sysdeps/linux/vax/crt1.S
diff options
context:
space:
mode:
Diffstat (limited to 'libc/sysdeps/linux/vax/crt1.S')
-rw-r--r--libc/sysdeps/linux/vax/crt1.S73
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..ea9c105d6
--- /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
+