xref: /csrg-svn/lib/csu/vax/crt0.c (revision 47884)
1*47884Sbostic /*-
2*47884Sbostic  * Copyright (c) 1982 The Regents of the University of California.
3*47884Sbostic  * All rights reserved.
4*47884Sbostic  *
5*47884Sbostic  * %sccs.include.proprietary.c%
621414Sdist  */
75102Smckusick 
826668Sdonn #if defined(LIBC_SCCS) && !defined(lint)
9*47884Sbostic static char sccsid[] = "@(#)crt0.c	5.5 (Berkeley) 04/12/91";
10*47884Sbostic #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 
355332Smckusic asm("#define _start start");
369438Smckusick asm("#define _eprol eprol");
379438Smckusick extern	unsigned char	etext;
389438Smckusick extern	unsigned char	eprol;
395102Smckusick start()
405102Smckusick {
415102Smckusick 	struct kframe {
425102Smckusick 		int	kargc;
435102Smckusick 		char	*kargv[1];	/* size depends on kargc */
445102Smckusick 		char	kargstr[1];	/* size varies */
455102Smckusick 		char	kenvstr[1];	/* size varies */
465102Smckusick 	};
475102Smckusick 	/*
485102Smckusick 	 *	ALL REGISTER VARIABLES!!!
495102Smckusick 	 */
506852Srrh 	register int r11;		/* needed for init */
516852Srrh 	register struct kframe *kfp;	/* r10 */
525102Smckusick 	register char **targv;
535102Smckusick 	register char **argv;
5425247Smckusick 	extern int errno;
555102Smckusick 
565102Smckusick #ifdef lint
575102Smckusick 	kfp = 0;
589438Smckusick 	initcode = initcode = 0;
595102Smckusick #else not lint
606852Srrh 	asm("	movl	sp,r10");	/* catch it quick */
615102Smckusick #endif not lint
625102Smckusick 	for (argv = targv = &kfp->kargv[0]; *targv++; /* void */)
635102Smckusick 		/* void */ ;
645102Smckusick 	if (targv >= (char **)(*argv))
655102Smckusick 		--targv;
665102Smckusick 	environ = targv;
679438Smckusick asm("eprol:");
6825247Smckusick 
6925247Smckusick #ifdef paranoid
7025247Smckusick 	/*
7125247Smckusick 	 * The standard I/O library assumes that file descriptors 0, 1, and 2
7225247Smckusick 	 * are open. If one of these descriptors is closed prior to the start
7325247Smckusick 	 * of the process, I/O gets very confused. To avoid this problem, we
7425247Smckusick 	 * insure that the first three file descriptors are open before calling
7525247Smckusick 	 * main(). Normally this is undefined, as it adds two unnecessary
7625247Smckusick 	 * system calls.
7725247Smckusick 	 */
7825247Smckusick 	do	{
7925247Smckusick 		fd = open("/dev/null", 2);
8025247Smckusick 	} while (fd >= 0 && fd < 3);
8125247Smckusick 	close(fd);
8225247Smckusick #endif paranoid
8325247Smckusick 
849438Smckusick #ifdef MCRT0
859438Smckusick 	monstartup(&eprol, &etext);
869438Smckusick #endif MCRT0
8725247Smckusick 	errno = 0;
885102Smckusick 	exit(main(kfp->kargc, argv, environ));
895102Smckusick }
909438Smckusick asm("#undef _start");
919438Smckusick asm("#undef _eprol");
925102Smckusick 
939438Smckusick #ifdef MCRT0
949438Smckusick /*ARGSUSED*/
959438Smckusick exit(code)
969438Smckusick 	register int code;	/* r11 */
979438Smckusick {
989438Smckusick 	monitor(0);
999438Smckusick 	_cleanup();
10033363Smckusick 	_exit(code);
1019438Smckusick }
1029438Smckusick #endif MCRT0
1039438Smckusick 
1049438Smckusick #ifdef CRT0
1055102Smckusick /*
10611795Speter  * null mcount and moncontrol,
10711795Speter  * just in case some routine is compiled for profiling
1085102Smckusick  */
10911795Speter moncontrol(val)
11011795Speter 	int val;
11111795Speter {
11211795Speter 
11311795Speter }
1145397Smckusic asm("	.globl	mcount");
1155332Smckusic asm("mcount:	rsb");
1169438Smckusick #endif CRT0
117