xref: /original-bsd/lib/csu/tahoe/crt0.c (revision c3e32dec)
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 
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*/
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  */
97 moncontrol(val)
98 	int val;
99 {
100 
101 }
102 #endif
103