xref: /csrg-svn/lib/csu/vax/crt0.c (revision 49278)
147884Sbostic /*-
247884Sbostic  * Copyright (c) 1982 The Regents of the University of California.
347884Sbostic  * All rights reserved.
447884Sbostic  *
5*49278Sbostic  * %sccs.include.redist.c%
621414Sdist  */
75102Smckusick 
8*49278Sbostic #ifndef lint
9*49278Sbostic static char sccsid[] = "@(#)crt0.c	5.8 (Berkeley) 05/06/91";
10*49278Sbostic #endif /* not lint */
1121414Sdist 
125102Smckusick /*
135102Smckusick  *	C start up routine.
145102Smckusick  *	Robert Henry, UCB, 20 Oct 81
155102Smckusick  *
165102Smckusick  *	We make the following (true) assumptions:
175102Smckusick  *	1) when the kernel calls start, it does a jump to location 2,
185102Smckusick  *	and thus avoids the register save mask.  We are NOT called
195102Smckusick  *	with a calls!  see sys1.c:setregs().
205102Smckusick  *	2) The only register variable that we can trust is sp,
215102Smckusick  *	which points to the base of the kernel calling frame.
225102Smckusick  *	Do NOT believe the documentation in exec(2) regarding the
235102Smckusick  *	values of fp and ap.
245102Smckusick  */
255102Smckusick 
269438Smckusick char **environ = (char **)0;
2725247Smckusick static int fd;
285102Smckusick 
299438Smckusick extern	unsigned char	etext;
3048971Sdonn extern	unsigned char	eprol asm ("eprol");
3148971Sdonn extern			start() asm("start");
3248971Sdonn 
3348971Sdonn /*
3448971Sdonn  * Two kluges: store sp at entry in environ, and
3548971Sdonn  * install 16 bits of 0 at location 0 (a zero register save mask).
3648971Sdonn  * These two hacks remove limits on the use of local
3748971Sdonn  * and register variables in start().
3848971Sdonn  */
3948971Sdonn asm(".text; .word 0; movl sp,_environ; jbr start+2");
4048971Sdonn 
415102Smckusick start()
425102Smckusick {
435102Smckusick 	struct kframe {
445102Smckusick 		int	kargc;
455102Smckusick 		char	*kargv[1];	/* size depends on kargc */
465102Smckusick 		char	kargstr[1];	/* size varies */
475102Smckusick 		char	kenvstr[1];	/* size varies */
485102Smckusick 	};
4948971Sdonn 	register struct kframe *kfp;
505102Smckusick 	register char **targv;
515102Smckusick 	register char **argv;
5225247Smckusick 	extern int errno;
535102Smckusick 
545102Smckusick #ifdef lint
555102Smckusick 	kfp = 0;
569438Smckusick 	initcode = initcode = 0;
575102Smckusick #else not lint
5848971Sdonn 	kfp = (struct kframe *) environ;
595102Smckusick #endif not lint
605102Smckusick 	for (argv = targv = &kfp->kargv[0]; *targv++; /* void */)
615102Smckusick 		/* void */ ;
625102Smckusick 	if (targv >= (char **)(*argv))
635102Smckusick 		--targv;
645102Smckusick 	environ = targv;
659438Smckusick asm("eprol:");
6625247Smckusick 
6725247Smckusick #ifdef paranoid
6825247Smckusick 	/*
6925247Smckusick 	 * The standard I/O library assumes that file descriptors 0, 1, and 2
7025247Smckusick 	 * are open. If one of these descriptors is closed prior to the start
7125247Smckusick 	 * of the process, I/O gets very confused. To avoid this problem, we
7225247Smckusick 	 * insure that the first three file descriptors are open before calling
7325247Smckusick 	 * main(). Normally this is undefined, as it adds two unnecessary
7425247Smckusick 	 * system calls.
7525247Smckusick 	 */
7625247Smckusick 	do	{
7725247Smckusick 		fd = open("/dev/null", 2);
7825247Smckusick 	} while (fd >= 0 && fd < 3);
7925247Smckusick 	close(fd);
8025247Smckusick #endif paranoid
8125247Smckusick 
829438Smckusick #ifdef MCRT0
839438Smckusick 	monstartup(&eprol, &etext);
849438Smckusick #endif MCRT0
8525247Smckusick 	errno = 0;
865102Smckusick 	exit(main(kfp->kargc, argv, environ));
875102Smckusick }
885102Smckusick 
899438Smckusick #ifdef MCRT0
909438Smckusick /*ARGSUSED*/
919438Smckusick exit(code)
9248971Sdonn 	register int code;
939438Smckusick {
949438Smckusick 	monitor(0);
959438Smckusick 	_cleanup();
9633363Smckusick 	_exit(code);
979438Smckusick }
989438Smckusick #endif MCRT0
999438Smckusick 
1009438Smckusick #ifdef CRT0
1015102Smckusick /*
10211795Speter  * null mcount and moncontrol,
10311795Speter  * just in case some routine is compiled for profiling
1045102Smckusick  */
10511795Speter moncontrol(val)
10611795Speter 	int val;
10711795Speter {
10811795Speter 
10911795Speter }
11048971Sdonn asm(".globl mcount");
11148971Sdonn asm("mcount: rsb");
1129438Smckusick #endif CRT0
113