|
|
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.3 (Berkeley) 3/9/86"; ! 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: ! 37: #ifdef hp300 ! 38: asm("#define link .long 0; linkw"); /* Yuk!! */ ! 39: #endif ! 40: ! 41: extern unsigned char etext; ! 42: extern unsigned char eprol; ! 43: start() ! 44: { ! 45: struct kframe { ! 46: int kargc; ! 47: char *kargv[1]; /* size depends on kargc */ ! 48: char kargstr[1]; /* size varies */ ! 49: char kenvstr[1]; /* size varies */ ! 50: }; ! 51: /* ! 52: * ALL REGISTER VARIABLES!!! ! 53: */ ! 54: register int d7; /* needed for init (this will be ! 55: a problem with GCC) */ ! 56: register struct kframe *kfp; /* PCC a5 */ ! 57: register char **targv; ! 58: register char **argv; ! 59: extern int errno; ! 60: ! 61: #ifdef lint ! 62: kfp = 0; ! 63: initcode = initcode = 0; ! 64: #else not lint ! 65: #ifdef __GNUC__ ! 66: asm("lea a6@(4),%0" : "=r" (kfp)); /* catch it quick */ ! 67: #else ! 68: asm(" lea a6@(4),a5"); /* catch it quick */ ! 69: #endif ! 70: #endif not lint ! 71: for (argv = targv = &kfp->kargv[0]; *targv++; /* void */) ! 72: /* void */ ; ! 73: if (targv >= (char **)(*argv)) ! 74: --targv; ! 75: environ = targv; ! 76: asm("eprol:"); ! 77: ! 78: #ifdef paranoid ! 79: /* ! 80: * The standard I/O library assumes that file descriptors 0, 1, and 2 ! 81: * are open. If one of these descriptors is closed prior to the start ! 82: * of the process, I/O gets very confused. To avoid this problem, we ! 83: * insure that the first three file descriptors are open before calling ! 84: * main(). Normally this is undefined, as it adds two unnecessary ! 85: * system calls. ! 86: */ ! 87: do { ! 88: fd = open("/dev/null", 2); ! 89: } while (fd >= 0 && fd < 3); ! 90: close(fd); ! 91: #endif paranoid ! 92: ! 93: #ifdef MCRT0 ! 94: monstartup(&eprol, &etext); ! 95: #endif MCRT0 ! 96: errno = 0; ! 97: exit(main(kfp->kargc, argv, environ)); ! 98: } ! 99: asm("#undef link"); ! 100: asm("#undef _start"); ! 101: asm("#undef _eprol"); ! 102: ! 103: #ifdef MCRT0 ! 104: /*ARGSUSED*/ ! 105: exit(code) ! 106: register int code; /* PCC d7 */ ! 107: { ! 108: monitor(0); ! 109: _cleanup(); ! 110: #ifdef __GNUC__ ! 111: asm("movl %1,sp@-" : "=m" (*(char *)0) : "r" (code)); ! 112: #else ! 113: asm(" movl d7,sp@-"); ! 114: #endif ! 115: asm(" subql #4,sp"); ! 116: asm(" movl #1,d0"); ! 117: asm(" trap #0"); ! 118: } ! 119: #endif MCRT0 ! 120: ! 121: #ifdef CRT0 ! 122: /* ! 123: * null mcount and moncontrol, ! 124: * just in case some routine is compiled for profiling ! 125: */ ! 126: moncontrol(val) ! 127: int val; ! 128: { ! 129: ! 130: } ! 131: asm(" .globl mcount"); ! 132: asm("mcount: rts"); ! 133: #endif CRT0
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.