1 /*-
2 * Copyright (c) 1991, 1993
3 * The Regents of the University of California. All rights reserved.
4 *
5 * %sccs.include.redist.c%
6 */
7
8 #ifndef lint
9 static char sccsid[] = "@(#)crt0.c 8.1 (Berkeley) 06/01/93";
10 #endif /* not lint */
11
12 /*
13 * C start up routine.
14 * Robert Henry, UCB, 20 Oct 81
15 *
16 * We make the following (true) assumptions:
17 * 1) When the kernel calls start, it does a jump to location 2,
18 * and thus avoids the register save mask. We are NOT called
19 * with a calls!
20 * 2) The only register variable that we can trust is sp,
21 * which points to the base of the kernel calling frame.
22 */
23
24 #include <stddef.h>
25 #include <stdlib.h>
26 #include <string.h>
27
28 char **environ = (char **)0;
29 static char empty[1];
30 char *__progname = empty;
31 static int fd;
32
33 extern unsigned char etext;
34 extern unsigned char eprol asm ("eprol");
35 extern start() asm("start");
36
37 /*
38 * Some kluges: store sp at entry in environ, and
39 * install 16 bits of 0 at location 0 (a zero register save mask).
40 * These two hacks remove limits on the use of local
41 * and register variables in start().
42 * The reason for using 'moval (sp),...' is that 'movl sp,...' generates
43 * a privileged instruction trap (argh).
44 * XXX 'addl3 $start,$2,r0; jmp (r0)' should be replaced with
45 * XXX 'jbr start+2' when we convert over to gas.
46 */
47 asm(".text; .word 0; moval (sp),_environ; addl3 $start,$2,r0; jmp (r0)");
48
start()49 start()
50 {
51 struct kframe {
52 int kargc;
53 char *kargv[1]; /* size depends on kargc */
54 char kargstr[1]; /* size varies */
55 char kenvstr[1]; /* size varies */
56 };
57 register struct kframe *kfp;
58 register char **targv;
59 register char **argv;
60 extern int errno;
61
62 kfp = (struct kframe *) environ;
63 for (argv = targv = &kfp->kargv[0]; *targv++; /* void */)
64 /* void */ ;
65 if (targv >= (char **)(*argv))
66 --targv;
67 environ = targv;
68 asm("eprol:");
69
70 #ifdef MCRT0
71 monstartup(&eprol, &etext);
72 #endif
73 errno = 0;
74 if (argv[0])
75 if ((__progname = strrchr(argv[0], '/')) == NULL)
76 __progname = argv[0];
77 else
78 ++__progname;
79 exit(main(kfp->kargc, argv, environ));
80 }
81
82 #ifdef MCRT0
83 /*ARGSUSED*/
exit(code)84 exit(code)
85 register int code;
86 {
87 _mcleanup();
88 _cleanup();
89 _exit(code);
90 }
91 #endif
92
93 #ifdef CRT0
94 /*
95 * null moncontrol, just in case some routine is compiled for profiling
96 */
moncontrol(val)97 moncontrol(val)
98 int val;
99 {
100
101 }
102 #endif
103