1*11795Speter static char *sccsid = "@(#)crt0.c 4.6 (Berkeley) 03/30/83"; 25102Smckusick 35102Smckusick /* 45102Smckusick * C start up routine. 55102Smckusick * Robert Henry, UCB, 20 Oct 81 65102Smckusick * 75102Smckusick * We make the following (true) assumptions: 85102Smckusick * 1) when the kernel calls start, it does a jump to location 2, 95102Smckusick * and thus avoids the register save mask. We are NOT called 105102Smckusick * with a calls! see sys1.c:setregs(). 115102Smckusick * 2) The only register variable that we can trust is sp, 125102Smckusick * which points to the base of the kernel calling frame. 135102Smckusick * Do NOT believe the documentation in exec(2) regarding the 145102Smckusick * values of fp and ap. 155102Smckusick * 3) We can allocate as many register variables as we want, 165102Smckusick * and don't have to save them for anybody. 175102Smckusick * 4) Because of the ways that asm's work, we can't have 185102Smckusick * any automatic variables allocated on the stack, because 195102Smckusick * we must catch the value of sp before any automatics are 205102Smckusick * allocated. 215102Smckusick */ 225102Smckusick 239438Smckusick char **environ = (char **)0; 245102Smckusick 255332Smckusic asm("#define _start start"); 269438Smckusick asm("#define _eprol eprol"); 279438Smckusick extern unsigned char etext; 289438Smckusick extern unsigned char eprol; 295102Smckusick start() 305102Smckusick { 315102Smckusick struct kframe { 325102Smckusick int kargc; 335102Smckusick char *kargv[1]; /* size depends on kargc */ 345102Smckusick char kargstr[1]; /* size varies */ 355102Smckusick char kenvstr[1]; /* size varies */ 365102Smckusick }; 375102Smckusick /* 385102Smckusick * ALL REGISTER VARIABLES!!! 395102Smckusick */ 406852Srrh register int r11; /* needed for init */ 416852Srrh register struct kframe *kfp; /* r10 */ 425102Smckusick register char **targv; 435102Smckusick register char **argv; 445102Smckusick 455102Smckusick #ifdef lint 465102Smckusick kfp = 0; 479438Smckusick initcode = initcode = 0; 485102Smckusick #else not lint 496852Srrh asm(" movl sp,r10"); /* catch it quick */ 505102Smckusick #endif not lint 515102Smckusick for (argv = targv = &kfp->kargv[0]; *targv++; /* void */) 525102Smckusick /* void */ ; 535102Smckusick if (targv >= (char **)(*argv)) 545102Smckusick --targv; 555102Smckusick environ = targv; 569438Smckusick asm("eprol:"); 579438Smckusick #ifdef MCRT0 589438Smckusick monstartup(&eprol, &etext); 599438Smckusick #endif MCRT0 605102Smckusick exit(main(kfp->kargc, argv, environ)); 615102Smckusick } 629438Smckusick asm("#undef _start"); 639438Smckusick asm("#undef _eprol"); 645102Smckusick 659438Smckusick #ifdef MCRT0 669438Smckusick /*ARGSUSED*/ 679438Smckusick exit(code) 689438Smckusick register int code; /* r11 */ 699438Smckusick { 709438Smckusick monitor(0); 719438Smckusick _cleanup(); 729438Smckusick asm(" movl r11,r0"); 739438Smckusick asm(" chmk $1"); 749438Smckusick } 759438Smckusick #endif MCRT0 769438Smckusick 779438Smckusick #ifdef CRT0 785102Smckusick /* 79*11795Speter * null mcount and moncontrol, 80*11795Speter * just in case some routine is compiled for profiling 815102Smckusick */ 82*11795Speter moncontrol(val) 83*11795Speter int val; 84*11795Speter { 85*11795Speter 86*11795Speter } 875397Smckusic asm(" .globl mcount"); 885332Smckusic asm("mcount: rsb"); 899438Smckusick #endif CRT0 90