diff options
author | Miod Vallat <miod@cvs.openbsd.org> | 2003-12-25 23:26:10 +0000 |
---|---|---|
committer | Miod Vallat <miod@cvs.openbsd.org> | 2003-12-25 23:26:10 +0000 |
commit | f04218fe5a82a954c5622650dbecf584f0f794f6 (patch) | |
tree | 780e73b796ae3e5276795b6060960167c07fea8d /lib/csu/m88k/crt0.c | |
parent | b82f317239ca4196a37d1f0479e64c5618f840c4 (diff) |
A much simpler and more readable start() routine...
Diffstat (limited to 'lib/csu/m88k/crt0.c')
-rw-r--r-- | lib/csu/m88k/crt0.c | 89 |
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" |