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