summaryrefslogtreecommitdiff
path: root/lib/csu/m88k/crt0.c
diff options
context:
space:
mode:
authorMiod Vallat <miod@cvs.openbsd.org>2003-12-25 23:26:10 +0000
committerMiod Vallat <miod@cvs.openbsd.org>2003-12-25 23:26:10 +0000
commitf04218fe5a82a954c5622650dbecf584f0f794f6 (patch)
tree780e73b796ae3e5276795b6060960167c07fea8d /lib/csu/m88k/crt0.c
parentb82f317239ca4196a37d1f0479e64c5618f840c4 (diff)
A much simpler and more readable start() routine...
Diffstat (limited to 'lib/csu/m88k/crt0.c')
-rw-r--r--lib/csu/m88k/crt0.c89
1 files changed, 24 insertions, 65 deletions
diff --git a/lib/csu/m88k/crt0.c b/lib/csu/m88k/crt0.c
index 903b05ff0a0..f87274a2692 100644
--- a/lib/csu/m88k/crt0.c
+++ b/lib/csu/m88k/crt0.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: crt0.c,v 1.3 2003/03/10 04:02:49 david Exp $ */
+/* $OpenBSD: crt0.c,v 1.4 2003/12/25 23:26:09 miod Exp $ */
/*
* Mach Operating System
@@ -28,80 +28,40 @@
*/
#if defined(LIBC_SCCS) && !defined(lint)
-static char rcsid[] = "$OpenBSD: crt0.c,v 1.3 2003/03/10 04:02:49 david Exp $";
+static char rcsid[] = "$OpenBSD: crt0.c,v 1.4 2003/12/25 23:26:09 miod Exp $";
#endif /* LIBC_SCCS and not lint */
-/*
- * Author : Jeffrey Friedl
- * Created: July 1992
- * Standalone crt0.
- */
-
-/*
- * GCCisms used:
- * A "volatile void fcn()" is one that never returns.
- * register var asm("r1"): variable VAR is raw access to named register.
- */
-
/*
- * When a program begins, r31 points to info passed from the kernel.
- *
- * The following shows the memory to which r31 points (think "int *r31;"),
- * and how we derive argc, argv, and envp from that:
+ * When a program starts, r31 points to a structure passed from the kernel.
*
- * +-------------------+ <-------------------------------------- r31
- * | ARGC | <- argc = r31[0];
- * +-------------------+ <- argv = &r31[1];
- * | &(argument #1) |
- * +-------------------+
- * | &(argument #2) |
- * - - - - - - - - -
- * | &(argument #ARGC) |
- * +-------------------+
- * | 0x00000000 | <- end-of-ARGV-list marker (redundant information).
- * +-------------------+ <- environ = envp = &argv[argc+1];
- * | &(env. var. #1) |
- * +-------------------+
- * | &(env. var. #2) |
- * - - - - - - - - -
- * | &(env. var. #N) |
- * +-------------------+
- * | 0x00000000 | <- end-of-ENVP-list marker (not redundant!).
- * +-------------------+
- *
- * We use 'start:' to grab r31 and call real_start(argc, argv, envp).
- * We must do this since the function prologue makes finding the initial
- * r31 difficult in C.
+ * This structure contains argc, the argv[] array, a NULL marker, then
+ * the envp[] array, and another NULL marker.
*/
#include <stdlib.h>
#include "common.h"
-asm(" text ");
-asm(" align 4 ");
-asm("start: global start ");
-asm(" ld r2, r31, 0 "); /* First arg to real_start: argc */
-asm(" addu r3, r31, 4 "); /* Second arg to real_start: argv */
-asm(" lda r4, r3 [r2]"); /* Third arg to real_start: envp, but.... */
-asm(" addu r4, r4, 4 "); /* ... don't forget to skip past marker */
-asm(" br.n ___crt0_real_start");
-asm(" subu r31, r31, 32 ");
-
-#ifdef DYNAMIC
-extern struct _dynamic _DYNAMIC;
-struct _dynamic *___pdynamic = &_DYNAMIC;
-#endif
+extern void start(void) __asm__("start");
-/* static */ void volatile
-__crt0_real_start(int argc, char *argv[], char *envp[])
+void
+start(void)
{
- register char *ap;
- volatile int a = 0;
- extern int end;
- char *s;
+ struct kframe {
+ int argc;
+ char *argv[0];
+ };
+
+ struct kframe *kfp;
+ char **argv, *ap, *s;
- environ = envp; /* environ is for the user that can't get at 'envp' */
+ /*
+ * Pick the arguments frame as early as possible
+ */
+ __asm__ __volatile__ ("or %0, r31, 0" : "=r" (kfp) :: "r31");
+
+ argv = &kfp->argv[0];
+ environ = argv + kfp->argc + 1;
if (ap = argv[0]) {
if ((__progname = _strrchr(ap, '/')) == NULL)
@@ -114,10 +74,9 @@ __crt0_real_start(int argc, char *argv[], char *envp[])
*s = '\0';
__progname = __progname_storage;
}
-asm ("__callmain:"); /* Defined for the benefit of debuggers */
- exit(main(argc, argv, environ));
- /*NOTREACHED*/
+asm ("__callmain:"); /* Defined for the benefit of debuggers */
+ exit(main(kfp->argc, argv, environ));
}
#include "common.c"