old versions; put these to bed
[unix-history] / usr / src / lib / csu / vax / crt0.c
static char *sccsid = "@(#)crt0.c 4.4 (Berkeley) %G%";
/*
* C start up routine.
* Robert Henry, UCB, 20 Oct 81
*
* We make the following (true) assumptions:
* 1) when the kernel calls start, it does a jump to location 2,
* and thus avoids the register save mask. We are NOT called
* with a calls! see sys1.c:setregs().
* 2) The only register variable that we can trust is sp,
* which points to the base of the kernel calling frame.
* Do NOT believe the documentation in exec(2) regarding the
* values of fp and ap.
* 3) We can allocate as many register variables as we want,
* and don't have to save them for anybody.
* 4) Because of the ways that asm's work, we can't have
* any automatic variables allocated on the stack, because
* we must catch the value of sp before any automatics are
* allocated.
*/
char **environ;
asm("#define _start start");
start()
{
struct kframe {
int kargc;
char *kargv[1]; /* size depends on kargc */
char kargstr[1]; /* size varies */
char kenvstr[1]; /* size varies */
};
/*
* ALL REGISTER VARIABLES!!!
*/
register int r11; /* needed for init */
register struct kframe *kfp; /* r10 */
register char **targv;
register char **argv;
#ifdef lint
kfp = 0;
#else not lint
asm(" movl sp,r10"); /* catch it quick */
#endif not lint
for (argv = targv = &kfp->kargv[0]; *targv++; /* void */)
/* void */ ;
if (targv >= (char **)(*argv))
--targv;
environ = targv;
exit(main(kfp->kargc, argv, environ));
}
/*
* null mcount, just in case some routine is compiled for profiling
*/
asm(" .globl mcount");
asm("mcount: rsb");