|
|
1.1 ! root 1: /* ! 2: * Copyright (c) 1980 Regents of the University of California. ! 3: * All rights reserved. The Berkeley software License Agreement ! 4: * specifies the terms and conditions for redistribution. ! 5: */ ! 6: ! 7: #if defined(LIBC_SCCS) && !defined(lint) ! 8: static char sccsid[] = "@(#)crt0.c 5.4 (Berkeley) 1/18/88"; ! 9: #endif LIBC_SCCS and not lint ! 10: ! 11: /* ! 12: * C start up routine. ! 13: * Robert Henry, UCB, 20 Oct 81 ! 14: * ! 15: * We make the following (true) assumptions: ! 16: * 1) when the kernel calls start, it does a jump to location 2, ! 17: * and thus avoids the register save mask. We are NOT called ! 18: * with a calls! see sys1.c:setregs(). ! 19: * 2) The only register variable that we can trust is sp, ! 20: * which points to the base of the kernel calling frame. ! 21: * Do NOT believe the documentation in exec(2) regarding the ! 22: * values of fp and ap. ! 23: * 3) We can allocate as many register variables as we want, ! 24: * and don't have to save them for anybody. ! 25: * 4) Because of the ways that asm's work, we can't have ! 26: * any automatic variables allocated on the stack, because ! 27: * we must catch the value of sp before any automatics are ! 28: * allocated. ! 29: */ ! 30: ! 31: char **environ = (char **)0; ! 32: static int fd; ! 33: ! 34: asm("#define _start start"); ! 35: asm("#define _eprol eprol"); ! 36: extern unsigned char etext; ! 37: extern unsigned char eprol; ! 38: start() ! 39: { ! 40: struct kframe { ! 41: int kargc; ! 42: char *kargv[1]; /* size depends on kargc */ ! 43: char kargstr[1]; /* size varies */ ! 44: char kenvstr[1]; /* size varies */ ! 45: }; ! 46: /* ! 47: * ALL REGISTER VARIABLES!!! ! 48: */ ! 49: register int r11; /* needed for init */ ! 50: register struct kframe *kfp; /* r10 */ ! 51: register char **targv; ! 52: register char **argv; ! 53: extern int errno; ! 54: ! 55: #ifdef lint ! 56: kfp = 0; ! 57: initcode = initcode = 0; ! 58: #else not lint ! 59: asm(" movl sp,r10"); /* catch it quick */ ! 60: #endif not lint ! 61: for (argv = targv = &kfp->kargv[0]; *targv++; /* void */) ! 62: /* void */ ; ! 63: if (targv >= (char **)(*argv)) ! 64: --targv; ! 65: environ = targv; ! 66: asm("eprol:"); ! 67: ! 68: #ifdef paranoid ! 69: /* ! 70: * The standard I/O library assumes that file descriptors 0, 1, and 2 ! 71: * are open. If one of these descriptors is closed prior to the start ! 72: * of the process, I/O gets very confused. To avoid this problem, we ! 73: * insure that the first three file descriptors are open before calling ! 74: * main(). Normally this is undefined, as it adds two unnecessary ! 75: * system calls. ! 76: */ ! 77: do { ! 78: fd = open("/dev/null", 2); ! 79: } while (fd >= 0 && fd < 3); ! 80: close(fd); ! 81: #endif paranoid ! 82: ! 83: #ifdef MCRT0 ! 84: monstartup(&eprol, &etext); ! 85: #endif MCRT0 ! 86: errno = 0; ! 87: exit(main(kfp->kargc, argv, environ)); ! 88: } ! 89: asm("#undef _start"); ! 90: asm("#undef _eprol"); ! 91: ! 92: #ifdef MCRT0 ! 93: /*ARGSUSED*/ ! 94: exit(code) ! 95: register int code; /* r11 */ ! 96: { ! 97: monitor(0); ! 98: _cleanup(); ! 99: _exit(code); ! 100: } ! 101: #endif MCRT0 ! 102: ! 103: #ifdef CRT0 ! 104: /* ! 105: * null mcount and moncontrol, ! 106: * just in case some routine is compiled for profiling ! 107: */ ! 108: moncontrol(val) ! 109: int val; ! 110: { ! 111: ! 112: } ! 113: asm(" .globl mcount"); ! 114: asm("mcount: rsb"); ! 115: #endif CRT0
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.