xref: /csrg-svn/lib/csu/vax/crt0.c (revision 48971)
147884Sbostic /*-
247884Sbostic  * Copyright (c) 1982 The Regents of the University of California.
347884Sbostic  * All rights reserved.
447884Sbostic  *
547884Sbostic  * %sccs.include.proprietary.c%
621414Sdist  */
75102Smckusick 
826668Sdonn #if defined(LIBC_SCCS) && !defined(lint)
9*48971Sdonn static char sccsid[] = "@(#)crt0.c	5.6 (Berkeley) 05/03/91";
1047884Sbostic #endif /* LIBC_SCCS and 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  *	3) We can allocate as many register variables as we want,
255102Smckusick  *	and don't have to save them for anybody.
265102Smckusick  *	4) Because of the ways that asm's work, we can't have
275102Smckusick  *	any automatic variables allocated on the stack, because
285102Smckusick  *	we must catch the value of sp before any automatics are
295102Smckusick  *	allocated.
305102Smckusick  */
315102Smckusick 
329438Smckusick char **environ = (char **)0;
3325247Smckusick static int fd;
345102Smckusick 
359438Smckusick extern	unsigned char	etext;
36*48971Sdonn extern	unsigned char	eprol asm ("eprol");
37*48971Sdonn extern			start() asm("start");
38*48971Sdonn 
39*48971Sdonn /*
40*48971Sdonn  * Two kluges: store sp at entry in environ, and
41*48971Sdonn  * install 16 bits of 0 at location 0 (a zero register save mask).
42*48971Sdonn  * These two hacks remove limits on the use of local
43*48971Sdonn  * and register variables in start().
44*48971Sdonn  */
45*48971Sdonn asm(".text; .word 0; movl sp,_environ; jbr start+2");
46*48971Sdonn 
475102Smckusick start()
485102Smckusick {
495102Smckusick 	struct kframe {
505102Smckusick 		int	kargc;
515102Smckusick 		char	*kargv[1];	/* size depends on kargc */
525102Smckusick 		char	kargstr[1];	/* size varies */
535102Smckusick 		char	kenvstr[1];	/* size varies */
545102Smckusick 	};
55*48971Sdonn 	register struct kframe *kfp;
565102Smckusick 	register char **targv;
575102Smckusick 	register char **argv;
5825247Smckusick 	extern int errno;
595102Smckusick 
605102Smckusick #ifdef lint
615102Smckusick 	kfp = 0;
629438Smckusick 	initcode = initcode = 0;
635102Smckusick #else not lint
64*48971Sdonn 	kfp = (struct kframe *) environ;
655102Smckusick #endif not lint
665102Smckusick 	for (argv = targv = &kfp->kargv[0]; *targv++; /* void */)
675102Smckusick 		/* void */ ;
685102Smckusick 	if (targv >= (char **)(*argv))
695102Smckusick 		--targv;
705102Smckusick 	environ = targv;
719438Smckusick asm("eprol:");
7225247Smckusick 
7325247Smckusick #ifdef paranoid
7425247Smckusick 	/*
7525247Smckusick 	 * The standard I/O library assumes that file descriptors 0, 1, and 2
7625247Smckusick 	 * are open. If one of these descriptors is closed prior to the start
7725247Smckusick 	 * of the process, I/O gets very confused. To avoid this problem, we
7825247Smckusick 	 * insure that the first three file descriptors are open before calling
7925247Smckusick 	 * main(). Normally this is undefined, as it adds two unnecessary
8025247Smckusick 	 * system calls.
8125247Smckusick 	 */
8225247Smckusick 	do	{
8325247Smckusick 		fd = open("/dev/null", 2);
8425247Smckusick 	} while (fd >= 0 && fd < 3);
8525247Smckusick 	close(fd);
8625247Smckusick #endif paranoid
8725247Smckusick 
889438Smckusick #ifdef MCRT0
899438Smckusick 	monstartup(&eprol, &etext);
909438Smckusick #endif MCRT0
9125247Smckusick 	errno = 0;
925102Smckusick 	exit(main(kfp->kargc, argv, environ));
935102Smckusick }
945102Smckusick 
959438Smckusick #ifdef MCRT0
969438Smckusick /*ARGSUSED*/
979438Smckusick exit(code)
98*48971Sdonn 	register int code;
999438Smckusick {
1009438Smckusick 	monitor(0);
1019438Smckusick 	_cleanup();
10233363Smckusick 	_exit(code);
1039438Smckusick }
1049438Smckusick #endif MCRT0
1059438Smckusick 
1069438Smckusick #ifdef CRT0
1075102Smckusick /*
10811795Speter  * null mcount and moncontrol,
10911795Speter  * just in case some routine is compiled for profiling
1105102Smckusick  */
11111795Speter moncontrol(val)
11211795Speter 	int val;
11311795Speter {
11411795Speter 
11511795Speter }
116*48971Sdonn asm(".globl mcount");
117*48971Sdonn asm("mcount: rsb");
1189438Smckusick #endif CRT0
119