|
|
1.1 root 1: /* C code startup routine.
2: Copyright (C) 1985, 1986 Free Software Foundation, Inc.
3:
4: NO WARRANTY
5:
6: BECAUSE THIS PROGRAM IS LICENSED FREE OF CHARGE, WE PROVIDE ABSOLUTELY
7: NO WARRANTY, TO THE EXTENT PERMITTED BY APPLICABLE STATE LAW. EXCEPT
8: WHEN OTHERWISE STATED IN WRITING, FREE SOFTWARE FOUNDATION, INC,
9: RICHARD M. STALLMAN AND/OR OTHER PARTIES PROVIDE THIS PROGRAM "AS IS"
10: WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
11: BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
12: FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY
13: AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE
14: DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR
15: CORRECTION.
16:
17: IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW WILL RICHARD M.
18: STALLMAN, THE FREE SOFTWARE FOUNDATION, INC., AND/OR ANY OTHER PARTY
19: WHO MAY MODIFY AND REDISTRIBUTE THIS PROGRAM AS PERMITTED BELOW, BE
20: LIABLE TO YOU FOR DAMAGES, INCLUDING ANY LOST PROFITS, LOST MONIES, OR
21: OTHER SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
22: USE OR INABILITY TO USE (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR
23: DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY THIRD PARTIES OR
24: A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS) THIS
25: PROGRAM, EVEN IF YOU HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH
26: DAMAGES, OR FOR ANY CLAIM BY ANY OTHER PARTY.
27:
28: GENERAL PUBLIC LICENSE TO COPY
29:
30: 1. You may copy and distribute verbatim copies of this source file
31: as you receive it, in any medium, provided that you conspicuously and
32: appropriately publish on each copy a valid copyright notice "Copyright
33: (C) 1986 Free Software Foundation, Inc."; and include following the
34: copyright notice a verbatim copy of the above disclaimer of warranty
35: and of this License.
36:
37: 2. You may modify your copy or copies of this source file or
38: any portion of it, and copy and distribute such modifications under
39: the terms of Paragraph 1 above, provided that you also do the following:
40:
41: a) cause the modified files to carry prominent notices stating
42: that you changed the files and the date of any change; and
43:
44: b) cause the whole of any work that you distribute or publish,
45: that in whole or in part contains or is a derivative of this
46: program or any part thereof, to be licensed at no charge to all
47: third parties on terms identical to those contained in this
48: License Agreement (except that you may choose to grant more extensive
49: warranty protection to some or all third parties, at your option).
50:
51: c) You may charge a distribution fee for the physical act of
52: transferring a copy, and you may at your option offer warranty
53: protection in exchange for a fee.
54:
55: Mere aggregation of another unrelated program with this program (or its
56: derivative) on a volume of a storage or distribution medium does not bring
57: the other program under the scope of these terms.
58:
59: 3. You may copy and distribute this program (or a portion or derivative
60: of it, under Paragraph 2) in object code or executable form under the terms
61: of Paragraphs 1 and 2 above provided that you also do one of the following:
62:
63: a) accompany it with the complete corresponding machine-readable
64: source code, which must be distributed under the terms of
65: Paragraphs 1 and 2 above; or,
66:
67: b) accompany it with a written offer, valid for at least three
68: years, to give any third party free (except for a nominal
69: shipping charge) a complete machine-readable copy of the
70: corresponding source code, to be distributed under the terms of
71: Paragraphs 1 and 2 above; or,
72:
73: c) accompany it with the information you received as to where the
74: corresponding source code may be obtained. (This alternative is
75: allowed only for noncommercial distribution and only if you
76: received the program in object code or executable form alone.)
77:
78: For an executable file, complete source code means all the source code for
79: all modules it contains; but, as a special exception, it need not include
80: source code for modules which are standard libraries that accompany the
81: operating system on which the executable file runs.
82:
83: 4. You may not copy, sublicense, distribute or transfer this program
84: except as expressly provided under this License Agreement. Any attempt
85: otherwise to copy, sublicense, distribute or transfer this program is void and
86: your rights to use the program under this License agreement shall be
87: automatically terminated. However, parties who have received computer
88: software programs from you with this License Agreement will not have
89: their licenses terminated so long as such parties remain in full compliance.
90:
91: 5. If you wish to incorporate parts of this program into other free
92: programs whose distribution conditions are different, write to the Free
93: Software Foundation at 675 Mass Ave, Cambridge, MA 02139. We have not yet
94: worked out a simple rule that can be stated here, but we will often permit
95: this. We will be guided by the two goals of preserving the free status of
96: all derivatives of our free software and of promoting the sharing and reuse of
97: software.
98:
99:
100: In other words, you are welcome to use, share and improve this program.
101: You are forbidden to forbid anyone else to use, share and improve
102: what you give them. Help stamp out software-hoarding! */
103:
104:
105: /* The standard Vax 4.2 Unix crt0.c cannot be used for Emacs
106: because it makes `envron' an initialized variable.
107: It is easiest to have a special crt0.c on all machines
108: though I don't know whether other machines actually need it. */
109:
110: /* On the vax and 68000, in BSD4.2 and USG5.2,
111: this is the data format on startup:
112: (vax) ap and fp are unpredictable as far as I know; don't use them.
113: sp -> word containing argc
114: word pointing to first arg string
115: [word pointing to next arg string]... 0 or more times
116: 0
117: Optionally:
118: [word pointing to environment variable]... 1 or more times
119: ...
120: 0
121: And always:
122: first arg string
123: [next arg string]... 0 or more times
124: */
125:
126: /* On the 16000, at least in the one 4.2 system I know about,
127: the initial data format is
128: sp -> word containing argc
129: word containing argp
130: word pointing to first arg string, and so on as above
131: */
132:
133: #include "config.h"
134:
135: /* ******** WARNING ********
136: Do not insert any data definitions before data_start!
137: Since this is the first file linked, the address of the following
138: variable should correspond to the start of initialized data space.
139: On some systems this is a constant that is independent of the text
140: size for shared executables. On others, it is a function of the
141: text size. In short, this seems to be the most portable way to
142: discover the start of initialized data space dynamically at runtime,
143: for either shared or unshared executables, on either swapping or
144: virtual systems. It only requires that the linker allocate objects
145: in the order encountered, a reasonable model for most Unix systems.
146: Similarly, note that the address of _start() should be the start
147: of text space. Fred Fish, UniSoft Systems Inc. */
148:
149: int data_start = 0;
150:
151: #ifdef NEED_ERRNO
152: int errno;
153: #endif
154:
155: #ifndef DONT_NEED_ENVIRON
156: char **environ;
157: #endif
158:
159: #if defined(orion) || defined(pyramid) || defined(celerity) || defined(ALLIANT) || defined(clipper)
160:
161: #ifdef ALLIANT
162: /* _start must initialize _curbrk and _minbrk on the first startup;
163: when starting up after dumping, it must initialize them to what they were
164: before the dumping, since they are in the shared library and
165: are not dumped. See ADJUST_EXEC_HEADER in m-alliant.h. */
166: extern unsigned char *_curbrk, *_minbrk;
167: extern unsigned char end;
168: unsigned char *_setbrk = &end;
169: #endif
170:
171: #ifndef DUMMIES
172: #define DUMMIES
173: #endif
174:
175: _start (DUMMIES argc, argv, envp)
176: int argc;
177: char **argv, **envp;
178: {
179: #ifdef ALLIANT
180: _curbrk = _setbrk;
181: _minbrk = _setbrk;
182: #endif
183:
184: environ = envp;
185:
186: exit (main (argc, argv, envp));
187: }
188:
189: #endif /* orion or pyramid or celerity or alliant or clipper */
190:
191: #if defined (ns16000) && !defined (sequent) && !defined (UMAX)
192:
193: _start ()
194: {
195: /* On 16000, _start pushes fp onto stack */
196: start1 ();
197: }
198:
199: /* ignore takes care of skipping the fp value pushed in start. */
200: static
201: start1 (ignore, argc, argv)
202: int ignore;
203: int argc;
204: register char **argv;
205: {
206: environ = argv + argc + 1;
207:
208: if (environ == *argv)
209: environ--;
210: exit (main (argc, argv, environ));
211: }
212: #endif /* ns16000, not sequent and not UMAX */
213:
214: #ifdef UMAX
215: _start()
216: {
217: asm(" exit [] # undo enter");
218: asm(" .set exitsc,1");
219: asm(" .set sigcatchall,0x400");
220:
221: asm(" .globl _exit");
222: asm(" .globl start");
223: asm(" .globl __start");
224: asm(" .globl _main");
225: asm(" .globl _environ");
226: asm(" .globl _sigvec");
227: asm(" .globl sigentry");
228:
229: asm("start:");
230: asm(" br .xstart");
231: asm(" .org 0x20");
232: asm(" .double p_glbl,0,0xf00000,0");
233: asm(" .org 0x30");
234: asm(".xstart:");
235: asm(" adjspb $8");
236: asm(" movd 8(sp),0(sp) # argc");
237: asm(" addr 12(sp),r0");
238: asm(" movd r0,4(sp) # argv");
239: asm("L1:");
240: asm(" movd r0,r1");
241: asm(" addqd $4,r0");
242: asm(" cmpqd $0,0(r1) # null args term ?");
243: asm(" bne L1");
244: asm(" cmpd r0,0(4(sp)) # end of 'env' or 'argv' ?");
245: asm(" blt L2");
246: asm(" addqd $-4,r0 # envp's are in list");
247: asm("L2:");
248: asm(" movd r0,8(sp) # env");
249: asm(" movd r0,@_environ # indir is 0 if no env ; not 0 if env");
250: asm(" movqd $0,tos # setup intermediate signal handler");
251: asm(" addr @sv,tos");
252: asm(" movzwd $sigcatchall,tos");
253: asm(" jsr @_sigvec");
254: asm(" adjspb $-12");
255: asm(" jsr @_main");
256: asm(" adjspb $-12");
257: asm(" movd r0,tos");
258: asm(" jsr @_exit");
259: asm(" adjspb $-4");
260: asm(" addr @exitsc,r0");
261: asm(" svc");
262: asm(" .align 4 # sigvec arg");
263: asm("sv:");
264: asm(" .double sigentry");
265: asm(" .double 0");
266: asm(" .double 0");
267:
268: asm(" .comm p_glbl,1");
269: }
270: #endif /* UMAX */
271:
272: #ifdef CRT0_DUMMIES
273:
274: /* Define symbol "start": here; some systems want that symbol. */
275: #ifdef DOT_GLOBAL_START
276: asm(" .text ");
277: asm(" .globl start ");
278: asm(" start: ");
279: #endif /* DOT_GLOBAL_START */
280:
281: #ifdef NODOT_GLOBAL_START
282: asm(" text ");
283: asm(" global start ");
284: asm(" start: ");
285: #endif /* NODOT_GLOBAL_START */
286:
287: _start ()
288: {
289: /* On vax, nothing is pushed here */
290: /* On sequent, bogus fp is pushed here */
291: start1 ();
292: }
293:
294: static
295: start1 (CRT0_DUMMIES argc, xargv)
296: int argc;
297: char *xargv;
298: {
299: register char **argv = &xargv;
300: environ = argv + argc + 1;
301:
302: if ((char *)environ == xargv)
303: environ--;
304: exit (main (argc, argv, environ));
305: }
306: #else /* not CRT0_DUMMIES */
307:
308: /* "m68k" and "m68000" both stand for m68000 processors,
309: but with different program-entry conventions.
310: This is a kludge. Now that the CRT0_DUMMIES mechanism above exists,
311: most of these machines could use the vax code above
312: with some suitable definition of CRT0_DUMMIES.
313: Then the symbol m68k could be flushed.
314: But I don't want to risk breaking these machines
315: in a version 17 patch release, so that change is being put off. */
316:
317: #ifdef m68k /* Can't do it all from C */
318: asm (" global _start");
319: asm (" text");
320: asm ("_start:");
321: #ifndef NU
322: #ifdef STRIDE
323: asm (" comm havefpu%,2");
324: #else /* m68k, not STRIDE */
325: asm (" comm splimit%,4");
326: #endif /* STRIDE */
327: asm (" global exit");
328: asm (" text");
329: #ifdef STRIDE
330: asm (" trap &3");
331: asm (" mov.w %d0,havefpu%");
332: #else /* m68k, not STRIDE */
333: asm (" mov.l %d0,splimit%");
334: #endif /* STRIDE */
335: #endif /* not NU */
336: asm (" jsr start1");
337: asm (" mov.l %d0,(%sp)");
338: asm (" jsr exit");
339: asm (" mov.l &1,%d0"); /* d0 = 1 => exit */
340: asm (" trap &0");
341: #else /* m68000, not m68k */
342:
343: #ifdef m68000
344:
345: #ifdef ISI68K
346: /* Added by ESM Sun May 24 12:44:02 1987 to get new ISI library to work */
347: #ifdef BSD4_3
348: static foo () {
349: #endif
350: asm (" .globl is68020");
351: asm ("is68020:");
352: #ifndef BSD4_3
353: asm (" .long 0x00000000");
354: asm (" .long 0xffffffff");
355: /* End of stuff added by ESM */
356: #endif
357: asm (" .text");
358: asm (" .globl __start");
359: asm ("__start:");
360: asm (" .word 0");
361: asm (" link fp,#0");
362: asm (" jbsr _start1");
363: asm (" unlk fp");
364: asm (" rts");
365: #ifdef BSD4_3
366: }
367: #endif
368: #else /* not ISI68K */
369:
370: _start ()
371: {
372: /* On 68000, _start pushes a6 onto stack */
373: start1 ();
374: }
375: #endif /* not ISI68k */
376: #endif /* m68000 */
377: #endif /* m68k */
378:
379: #if defined(m68k) || defined(m68000)
380: /* ignore takes care of skipping the a6 value pushed in start. */
381: static
382: #if defined(m68k)
383: start1 (argc, xargv)
384: #else
385: start1 (ignore, argc, xargv)
386: #endif
387: int argc;
388: char *xargv;
389: {
390: register char **argv = &xargv;
391: environ = argv + argc + 1;
392:
393: if ((char *)environ == xargv)
394: environ--;
395: exit (main (argc, argv, environ));
396: }
397:
398: #endif /* m68k or m68000 */
399:
400: #endif /* not CRT0_DUMMIES */
401:
402: #ifdef hp9000s300
403: int argc_value;
404: char **argv_value;
405: #ifdef OLD_HP_ASSEMBLER
406: asm(" text");
407: asm(" globl __start");
408: asm(" globl _exit");
409: asm(" globl _main");
410: asm("__start");
411: asm(" dc.l 0");
412: asm(" subq.w #0x1,d0");
413: asm(" move.w d0,float_soft");
414: asm(" move.l 0x4(a7),d0");
415: asm(" beq.s skip_1");
416: asm(" move.l d0,a0");
417: asm(" clr.l -0x4(a0)");
418: asm("skip_1");
419: asm(" move.l a7,a0");
420: asm(" subq.l #0x8,a7");
421: asm(" move.l (a0),(a7)");
422: asm(" move.l (a0),_argc_value");
423: asm(" addq.l #0x4,a0");
424: asm(" move.l a0,0x4(a7)");
425: asm(" move.l a0,_argv_value");
426: asm("incr_loop");
427: asm(" tst.l (a0)+");
428: asm(" bne.s incr_loop");
429: asm(" move.l 0x4(a7),a1");
430: asm(" cmp.l (a1),a0");
431: asm(" blt.s skip_2");
432: asm(" subq.l #0x4,a0");
433: asm("skip_2");
434: asm(" move.l a0,0x8(a7)");
435: asm(" move.l a0,_environ");
436: asm(" jsr _main");
437: asm(" addq.l #0x8,a7");
438: asm(" move.l d0,-(a7)");
439: asm(" jsr _exit");
440: asm(" move.w #0x1,d0");
441: asm(" trap #0x0");
442: asm(" comm float_soft,4");
443: /* float_soft is allocated in this way because C would
444: put an underscore character in its name otherwise. */
445:
446: #else /* new hp assembler */
447:
448: asm(" text");
449: asm(" global float_loc");
450: asm(" set float_loc,0xFFFFB000");
451: asm(" global fpa_loc");
452: asm(" set fpa_loc,0xfff08000");
453: asm(" global __start");
454: asm(" global _exit");
455: asm(" global _main");
456: asm("__start:");
457: asm(" byte 0,0,0,0");
458: asm(" subq.w &1,%d0");
459: asm(" mov.w %d0,float_soft");
460: asm(" mov.w %d1,flag_68881");
461: #ifndef HPUX_68010
462: asm(" beq.b skip_float");
463: asm(" fmov.l &0x7400,%fpcr");
464: /* asm(" fmov.l &0x7480,%fpcr"); */
465: #endif /* HPUX_68010 */
466: asm("skip_float:");
467: asm(" mov.l %a0,%d0");
468: asm(" add.l %d0,%d0");
469: asm(" subx.w %d1,%d1");
470: asm(" mov.w %d1,flag_68010");
471: asm(" add.l %d0,%d0");
472: asm(" subx.w %d1,%d1");
473: asm(" mov.w %d1,flag_fpa");
474: asm(" mov.l 4(%a7),%d0");
475: asm(" beq.b skip_1");
476: asm(" mov.l %d0,%a0");
477: asm(" clr.l -4(%a0)");
478: asm("skip_1:");
479: asm(" mov.l %a7,%a0");
480: asm(" subq.l &8,%a7");
481: asm(" mov.l (%a0),(%a7)");
482: asm(" mov.l (%a0),_argc_value");
483: asm(" addq.l &4,%a0");
484: asm(" mov.l %a0,4(%a7)");
485: asm(" mov.l %a0,_argv_value");
486: asm("incr_loop:");
487: asm(" tst.l (%a0)+");
488: asm(" bne.b incr_loop");
489: asm(" mov.l 4(%a7),%a1");
490: asm(" cmp.l %a0,(%a1)");
491: asm(" blt.b skip_2");
492: asm(" subq.l &4,%a0");
493: asm("skip_2:");
494: asm(" mov.l %a0,8(%a7)");
495: asm(" mov.l %a0,_environ");
496: asm(" jsr _main");
497: asm(" addq.l &8,%a7");
498: asm(" mov.l %d0,-(%a7)");
499: asm(" jsr _exit");
500: asm(" mov.w &1,%d0");
501: asm(" trap &0");
502: asm(" comm float_soft, 4");
503: asm(" comm flag_68881, 4");
504: asm(" comm flag_68010, 4");
505: asm(" comm flag_fpa, 4");
506:
507: #endif /* new hp assembler */
508: #endif /* hp9000s300 */
509:
510: #ifdef GOULD
511:
512: /* startup code has to be in near text rather
513: than fartext as allocated by the C compiler. */
514: asm(" .text");
515: asm(" .align 2");
516: asm(" .globl __start");
517: asm(" .text");
518: asm("__start:");
519: /* setup base register b1 (function base). */
520: asm(" .using b1,.");
521: asm(" tpcbr b1");
522: /* setup base registers b3 through b7 (data references). */
523: asm(" file basevals,b3");
524: /* setup base register b2 (stack pointer); it should be
525: aligned on a 8-word boundary; but because it is pointing
526: to argc, its value should be remembered (in r5). */
527: asm(" movw b2,r4");
528: asm(" movw b2,r5");
529: asm(" andw #~0x1f,r4");
530: asm(" movw r4,b2");
531: /* allocate stack frame to do some work. */
532: asm(" subea 16w,b2");
533: /* initialize signal catching for UTX/32 1.2; this is
534: necessary to make restart from saved image work. */
535: asm(" movea sigcatch,r1");
536: asm(" movw r1,8w[b2]");
537: asm(" svc #1,#150");
538: /* setup address of argc for start1. */
539: asm(" movw r5,8w[b2]");
540: asm(" func #1,_start1");
541: asm(" halt");
542: /* space for ld to store base register initial values. */
543: asm(" .align 5");
544: asm("basevals:");
545: asm(" .word __base3,__base4,__base5,__base6,__base7");
546:
547: static
548: start1 (xargc)
549: int *xargc;
550: {
551: register int argc;
552: register char **argv;
553:
554: argc = *xargc;
555: argv = (char **)(xargc) + 1;
556: environ = argv + argc + 1;
557:
558: if (environ == argv)
559: environ--;
560: exit (main (argc, argv, environ));
561:
562: }
563:
564: #endif /* GOULD */
565:
566: #ifdef elxsi
567: extern int errno;
568: extern char **environ;
569:
570: _start()
571: {
572: register int r;
573:
574: errno = 0;
575: environ = *(&environ + 8);
576: _stdinit();
577: r = main(*(&environ + 6), *(&environ + 7), environ);
578: exit(r);
579: _exit(r);
580: }
581: #endif /* elxsi */
582:
583:
584: #ifdef sparc
585: asm (".global __start");
586: asm (".text");
587: asm ("__start:");
588: asm (" mov 0, %fp");
589: asm (" ld [%sp + 64], %o0");
590: asm (" add %sp, 68, %o1");
591: asm (" sll %o0, 2, %o2");
592: asm (" add %o2, 4, %o2");
593: asm (" add %o1, %o2, %o2");
594: asm (" sethi %hi(_environ), %o3");
595: asm (" st %o2, [%o3+%lo(_environ)]");
596: asm (" andn %sp, 7, %sp");
597: asm (" call _main");
598: asm (" sub %sp, 24, %sp");
599: asm (" call __exit");
600: asm (" nop");
601:
602: #endif /* sparc */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.