xref: /csrg-svn/lib/csu/vax/crt0.c (revision 21414)
1*21414Sdist /*
2*21414Sdist  * Copyright (c) 1980 Regents of the University of California.
3*21414Sdist  * All rights reserved.  The Berkeley software License Agreement
4*21414Sdist  * specifies the terms and conditions for redistribution.
5*21414Sdist  */
65102Smckusick 
7*21414Sdist #ifndef lint
8*21414Sdist static char sccsid[] = "@(#)crt0.c	5.1 (Berkeley) 05/30/85";
9*21414Sdist #endif not lint
10*21414Sdist 
115102Smckusick /*
125102Smckusick  *	C start up routine.
135102Smckusick  *	Robert Henry, UCB, 20 Oct 81
145102Smckusick  *
155102Smckusick  *	We make the following (true) assumptions:
165102Smckusick  *	1) when the kernel calls start, it does a jump to location 2,
175102Smckusick  *	and thus avoids the register save mask.  We are NOT called
185102Smckusick  *	with a calls!  see sys1.c:setregs().
195102Smckusick  *	2) The only register variable that we can trust is sp,
205102Smckusick  *	which points to the base of the kernel calling frame.
215102Smckusick  *	Do NOT believe the documentation in exec(2) regarding the
225102Smckusick  *	values of fp and ap.
235102Smckusick  *	3) We can allocate as many register variables as we want,
245102Smckusick  *	and don't have to save them for anybody.
255102Smckusick  *	4) Because of the ways that asm's work, we can't have
265102Smckusick  *	any automatic variables allocated on the stack, because
275102Smckusick  *	we must catch the value of sp before any automatics are
285102Smckusick  *	allocated.
295102Smckusick  */
305102Smckusick 
319438Smckusick char **environ = (char **)0;
325102Smckusick 
335332Smckusic asm("#define _start start");
349438Smckusick asm("#define _eprol eprol");
359438Smckusick extern	unsigned char	etext;
369438Smckusick extern	unsigned char	eprol;
375102Smckusick start()
385102Smckusick {
395102Smckusick 	struct kframe {
405102Smckusick 		int	kargc;
415102Smckusick 		char	*kargv[1];	/* size depends on kargc */
425102Smckusick 		char	kargstr[1];	/* size varies */
435102Smckusick 		char	kenvstr[1];	/* size varies */
445102Smckusick 	};
455102Smckusick 	/*
465102Smckusick 	 *	ALL REGISTER VARIABLES!!!
475102Smckusick 	 */
486852Srrh 	register int r11;		/* needed for init */
496852Srrh 	register struct kframe *kfp;	/* r10 */
505102Smckusick 	register char **targv;
515102Smckusick 	register char **argv;
525102Smckusick 
535102Smckusick #ifdef lint
545102Smckusick 	kfp = 0;
559438Smckusick 	initcode = initcode = 0;
565102Smckusick #else not lint
576852Srrh 	asm("	movl	sp,r10");	/* catch it quick */
585102Smckusick #endif not lint
595102Smckusick 	for (argv = targv = &kfp->kargv[0]; *targv++; /* void */)
605102Smckusick 		/* void */ ;
615102Smckusick 	if (targv >= (char **)(*argv))
625102Smckusick 		--targv;
635102Smckusick 	environ = targv;
649438Smckusick asm("eprol:");
659438Smckusick #ifdef MCRT0
669438Smckusick 	monstartup(&eprol, &etext);
679438Smckusick #endif MCRT0
685102Smckusick 	exit(main(kfp->kargc, argv, environ));
695102Smckusick }
709438Smckusick asm("#undef _start");
719438Smckusick asm("#undef _eprol");
725102Smckusick 
739438Smckusick #ifdef MCRT0
749438Smckusick /*ARGSUSED*/
759438Smckusick exit(code)
769438Smckusick 	register int code;	/* r11 */
779438Smckusick {
789438Smckusick 	monitor(0);
799438Smckusick 	_cleanup();
809438Smckusick 	asm("	movl r11,r0");
819438Smckusick 	asm("	chmk $1");
829438Smckusick }
839438Smckusick #endif MCRT0
849438Smckusick 
859438Smckusick #ifdef CRT0
865102Smckusick /*
8711795Speter  * null mcount and moncontrol,
8811795Speter  * just in case some routine is compiled for profiling
895102Smckusick  */
9011795Speter moncontrol(val)
9111795Speter 	int val;
9211795Speter {
9311795Speter 
9411795Speter }
955397Smckusic asm("	.globl	mcount");
965332Smckusic asm("mcount:	rsb");
979438Smckusick #endif CRT0
98