|
|
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.