xref: /csrg-svn/lib/csu/vax/crt0.c (revision 60985)
147884Sbostic /*-
2*60985Sbostic  * Copyright (c) 1982, 1993
3*60985Sbostic  *	The Regents of the University of California.  All rights reserved.
447884Sbostic  *
549278Sbostic  * %sccs.include.redist.c%
621414Sdist  */
75102Smckusick 
849278Sbostic #ifndef lint
9*60985Sbostic static char sccsid[] = "@(#)crt0.c	8.1 (Berkeley) 06/01/93";
1049278Sbostic #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 
2657962Sbostic #include <stddef.h>
2757962Sbostic #include <stdlib.h>
2857962Sbostic #include <string.h>
2957962Sbostic 
309438Smckusick char **environ = (char **)0;
3157962Sbostic static char empty[1];
3257962Sbostic char *__progname = empty;
3325247Smckusick static int fd;
345102Smckusick 
359438Smckusick extern	unsigned char	etext;
3648971Sdonn extern	unsigned char	eprol asm ("eprol");
3748971Sdonn extern			start() asm("start");
3848971Sdonn 
3948971Sdonn /*
4048971Sdonn  * Two kluges: store sp at entry in environ, and
4148971Sdonn  * install 16 bits of 0 at location 0 (a zero register save mask).
4248971Sdonn  * These two hacks remove limits on the use of local
4348971Sdonn  * and register variables in start().
4448971Sdonn  */
4548971Sdonn asm(".text; .word 0; movl sp,_environ; jbr start+2");
4648971Sdonn 
start()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 	};
5548971Sdonn 	register struct kframe *kfp;
565102Smckusick 	register char **targv;
575102Smckusick 	register char **argv;
5825247Smckusick 	extern int errno;
5950405Smckusick 	extern void _mcleanup();
605102Smckusick 
615102Smckusick #ifdef lint
625102Smckusick 	kfp = 0;
639438Smckusick 	initcode = initcode = 0;
6457962Sbostic #else
6548971Sdonn 	kfp = (struct kframe *) environ;
6657962Sbostic #endif
675102Smckusick 	for (argv = targv = &kfp->kargv[0]; *targv++; /* void */)
685102Smckusick 		/* void */ ;
695102Smckusick 	if (targv >= (char **)(*argv))
705102Smckusick 		--targv;
715102Smckusick 	environ = targv;
729438Smckusick asm("eprol:");
7325247Smckusick 
7425247Smckusick #ifdef paranoid
7525247Smckusick 	/*
7625247Smckusick 	 * The standard I/O library assumes that file descriptors 0, 1, and 2
7725247Smckusick 	 * are open. If one of these descriptors is closed prior to the start
7825247Smckusick 	 * of the process, I/O gets very confused. To avoid this problem, we
7925247Smckusick 	 * insure that the first three file descriptors are open before calling
8025247Smckusick 	 * main(). Normally this is undefined, as it adds two unnecessary
8125247Smckusick 	 * system calls.
8225247Smckusick 	 */
8325247Smckusick 	do	{
8425247Smckusick 		fd = open("/dev/null", 2);
8525247Smckusick 	} while (fd >= 0 && fd < 3);
8625247Smckusick 	close(fd);
8757962Sbostic #endif
8825247Smckusick 
899438Smckusick #ifdef MCRT0
9050405Smckusick 	atexit(_mcleanup);
919438Smckusick 	monstartup(&eprol, &etext);
9257962Sbostic #endif
9325247Smckusick 	errno = 0;
9457962Sbostic 	if (argv[0])
9557962Sbostic 		if ((__progname = strrchr(argv[0], '/')) == NULL)
9657962Sbostic 			__progname = argv[0];
9757962Sbostic 		else
9857962Sbostic 			++__progname;
995102Smckusick 	exit(main(kfp->kargc, argv, environ));
1005102Smckusick }
1015102Smckusick 
1029438Smckusick #ifdef CRT0
1035102Smckusick /*
10455307Smckusick  * null moncontrol, just in case some routine is compiled for profiling
1055102Smckusick  */
moncontrol(val)10611795Speter moncontrol(val)
10711795Speter 	int val;
10811795Speter {
10911795Speter 
11011795Speter }
11157962Sbostic #endif
112