comparison src/ecrt0.c @ 428:3ecd8885ac67 r21-2-22

Import from CVS: tag r21-2-22
author cvs
date Mon, 13 Aug 2007 11:28:15 +0200
parents
children 943eaba38521
comparison
equal deleted inserted replaced
427:0a0253eac470 428:3ecd8885ac67
1 /* C code startup routine.
2 Copyright (C) 1985, 1986, 1992, 1993 Free Software Foundation, Inc.
3
4 This file is part of XEmacs.
5
6 XEmacs is free software; you can redistribute it and/or modify it
7 under the terms of the GNU General Public License as published by the
8 Free Software Foundation; either version 2, or (at your option) any
9 later version.
10
11 XEmacs is distributed in the hope that it will be useful, but WITHOUT
12 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with XEmacs; see the file COPYING. If not, write to
18 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19 Boston, MA 02111-1307, USA. */
20
21 /* Synched up with: FSF 19.30. */
22
23
24 /* The standard Vax 4.2 Unix crt0.c cannot be used for Emacs
25 because it makes `environ' an initialized variable.
26 It is easiest to have a special crt0.c on all machines
27 though I don't know whether other machines actually need it. */
28
29 /* On the vax and 68000, in BSD4.2 and USG5.2,
30 this is the data format on startup:
31 (vax) ap and fp are unpredictable as far as I know; don't use them.
32 sp -> word containing argc
33 word pointing to first arg string
34 [word pointing to next arg string]... 0 or more times
35 0
36 Optionally:
37 [word pointing to environment variable]... 1 or more times
38 ...
39 0
40 And always:
41 first arg string
42 [next arg string]... 0 or more times
43 */
44
45 /* On the 16000, at least in the one 4.2 system I know about,
46 the initial data format is
47 sp -> word containing argc
48 word containing argp
49 word pointing to first arg string, and so on as above
50 */
51
52 #ifdef emacs
53 #include <config.h>
54 #endif
55
56 #ifdef __GNUC__
57 #define asm __asm
58 #endif
59
60 /* Workaround for Sun cc 3.0, which doesn't handle asm's outside a fn. */
61 #if __SUNPRO_C >= 0x300
62 #define no_toplevel_asm
63 #endif
64
65 /* ******** WARNING ********
66 Do not insert any data definitions before data_start!
67 Since this is the first file linked, the address of the following
68 variable should correspond to the start of initialized data space.
69 On some systems this is a constant that is independent of the text
70 size for shared executables. On others, it is a function of the
71 text size. In short, this seems to be the most portable way to
72 discover the start of initialized data space dynamically at runtime,
73 for either shared or unshared executables, on either swapping or
74 virtual systems. It only requires that the linker allocate objects
75 in the order encountered, a reasonable model for most Unix systems.
76 Similarly, note that the address of _start() should be the start
77 of text space. Fred Fish, UniSoft Systems Inc. */
78
79 int data_start = 0;
80
81 #ifdef NEED_ERRNO
82 int errno;
83 #endif
84
85 #ifndef DONT_NEED_ENVIRON
86 char **environ;
87 #endif
88
89 #ifndef static
90 /* On systems where the static storage class is usable, this function
91 should be declared as static. Otherwise, the static keyword has
92 been defined to be something else, and code for those systems must
93 take care of this declaration appropriately. */
94 static start1 ();
95 #endif
96
97 #ifdef APOLLO
98 extern char *malloc(), *realloc(), *(*_libc_malloc) (), *(*_libc_realloc)();
99 extern void free(), (*_libc_free) (); extern int main();
100 std_$call void unix_$main();
101
102 _start()
103 {
104 _libc_malloc = malloc;
105 _libc_realloc = realloc;
106 _libc_free = free;
107 unix_$main(main); /* no return */
108 }
109 #endif /* APOLLO */
110
111 #if defined(orion) || defined(pyramid) || defined(celerity) || defined(ALLIANT) || defined(clipper) || defined(sps7)
112
113 #if defined(sps7) && defined(V3x)
114 asm(" section 10");
115 asm(" ds.b 0xb0");
116 #endif
117
118 #ifdef ALLIANT
119 /* _start must initialize _curbrk and _minbrk on the first startup;
120 when starting up after dumping, it must initialize them to what they were
121 before the dumping, since they are in the shared library and
122 are not dumped. See ADJUST_EXEC_HEADER in m-alliant.h. */
123 extern unsigned char *_curbrk, *_minbrk;
124 extern unsigned char end;
125 unsigned char *_setbrk = &end;
126 #ifdef ALLIANT_2800
127 unsigned char *_end = &end;
128 #endif
129 #endif
130
131 #ifndef DUMMIES
132 #define DUMMIES
133 #endif
134
135 _start (DUMMIES argc, argv, envp)
136 int argc;
137 char **argv, **envp;
138 {
139 #ifdef ALLIANT
140 #ifdef ALLIANT_2800
141 _curbrk = _end;
142 _minbrk = _end;
143 #else
144 _curbrk = _setbrk;
145 _minbrk = _setbrk;
146 #endif
147 #endif
148
149 environ = envp;
150
151 exit (main (argc, argv, envp));
152 }
153
154 #endif /* orion or pyramid or celerity or alliant or clipper */
155
156 #if defined (ns16000) && !defined (sequent) && !defined (UMAX) && !defined (CRT0_DUMMIES)
157
158 _start ()
159 {
160 /* On 16000, _start pushes fp onto stack */
161 start1 ();
162 }
163
164 /* ignore takes care of skipping the fp value pushed in start. */
165 static
166 start1 (ignore, argc, argv)
167 int ignore;
168 int argc;
169 char **argv;
170 {
171 environ = argv + argc + 1;
172
173 if (environ == *argv)
174 environ--;
175 exit (main (argc, argv, environ));
176 }
177 #endif /* ns16000, not sequent and not UMAX, and not the CRT0_DUMMIES method */
178
179 #ifdef UMAX
180 _start()
181 {
182 asm(" exit [] # undo enter");
183 asm(" .set exitsc,1");
184 asm(" .set sigcatchall,0x400");
185
186 asm(" .globl _exit");
187 asm(" .globl start");
188 asm(" .globl __start");
189 asm(" .globl _main");
190 asm(" .globl _environ");
191 asm(" .globl _sigvec");
192 asm(" .globl sigentry");
193
194 asm("start:");
195 asm(" br .xstart");
196 asm(" .org 0x20");
197 asm(" .double p_glbl,0,0xf00000,0");
198 asm(" .org 0x30");
199 asm(".xstart:");
200 asm(" adjspb $8");
201 asm(" movd 8(sp),0(sp) # argc");
202 asm(" addr 12(sp),r0");
203 asm(" movd r0,4(sp) # argv");
204 asm("L1:");
205 asm(" movd r0,r1");
206 asm(" addqd $4,r0");
207 asm(" cmpqd $0,0(r1) # null args term ?");
208 asm(" bne L1");
209 asm(" cmpd r0,0(4(sp)) # end of 'env' or 'argv' ?");
210 asm(" blt L2");
211 asm(" addqd $-4,r0 # envp's are in list");
212 asm("L2:");
213 asm(" movd r0,8(sp) # env");
214 asm(" movd r0,@_environ # indir is 0 if no env ; not 0 if env");
215 asm(" movqd $0,tos # setup intermediate signal handler");
216 asm(" addr @sv,tos");
217 asm(" movzwd $sigcatchall,tos");
218 asm(" jsr @_sigvec");
219 asm(" adjspb $-12");
220 asm(" jsr @_main");
221 asm(" adjspb $-12");
222 asm(" movd r0,tos");
223 asm(" jsr @_exit");
224 asm(" adjspb $-4");
225 asm(" addr @exitsc,r0");
226 asm(" svc");
227 asm(" .align 4 # sigvec arg");
228 asm("sv:");
229 asm(" .double sigentry");
230 asm(" .double 0");
231 asm(" .double 0");
232
233 asm(" .comm p_glbl,1");
234 }
235 #endif /* UMAX */
236
237 #ifdef CRT0_DUMMIES
238
239 /* Define symbol "start": here; some systems want that symbol. */
240 #ifdef DOT_GLOBAL_START
241 asm(" .text ");
242 asm(" .globl start ");
243 asm(" start: ");
244 #endif /* DOT_GLOBAL_START */
245
246 #ifdef NODOT_GLOBAL_START
247 asm(" text ");
248 asm(" global start ");
249 asm(" start: ");
250 #endif /* NODOT_GLOBAL_START */
251
252 #ifdef m68000
253
254 /* GCC 2.1, when optimization is turned off, seems to want to push a
255 word of garbage on the stack, which screws up the CRT0_DUMMIES
256 hack. So we hand-code _start in assembly language. */
257 asm(".text ");
258 #ifndef sony_news
259 asm(" .even ");
260 #else /* sony_news (not gas) */
261 + asm(" .align 2 ");
262 #endif /* sony_news (not gas) */
263 asm(".globl __start ");
264 asm("__start: ");
265 asm(" link a6,#0 ");
266 asm(" jbsr _start1 ");
267 asm(" unlk a6 ");
268 asm(" rts ");
269
270 #else /* not m68000 */
271
272 int
273 _start ()
274 {
275 /* On vax, nothing is pushed here */
276 /* On sequent, bogus fp is pushed here */
277 start1 ();
278 }
279
280 #endif /* possibly m68000 */
281
282 #ifdef __bsdi__ /* for version number */
283 #include <sys/param.h>
284 #endif
285 #if defined(_BSDI_VERSION) && (_BSDI_VERSION >= 199501)
286 char *__progname;
287 #endif
288 static int
289 start1 (CRT0_DUMMIES int argc, char *xargv)
290 {
291 char **argv = &xargv;
292 environ = argv + argc + 1;
293 #if defined(_BSDI_VERSION) && (_BSDI_VERSION >= 199501)
294 __progname = argv[0];
295 #endif
296
297 if ((char *)environ == xargv)
298 environ--;
299 exit (main (argc, argv, environ));
300
301 /* Refer to `start1' so GCC will not think it is never called
302 and optimize it out. */
303 (void) &start1;
304 }
305 #else /* not CRT0_DUMMIES */
306
307 /* "m68k" and "m68000" both stand for m68000 processors,
308 but with different program-entry conventions.
309 This is a kludge. Now that the CRT0_DUMMIES mechanism above exists,
310 most of these machines could use the vax code above
311 with some suitable definition of CRT0_DUMMIES.
312 Then the symbol m68k could be flushed.
313 But I don't want to risk breaking these machines
314 in a version 17 patch release, so that change is being put off. */
315
316 #ifdef m68k /* Can't do it all from C */
317 asm (" global _start");
318 asm (" text");
319 asm ("_start:");
320 #ifndef NU
321 #ifdef STRIDE
322 asm (" comm havefpu%,2");
323 #else /* m68k, not STRIDE */
324 asm (" comm splimit%,4");
325 #endif /* STRIDE */
326 asm (" global exit");
327 asm (" text");
328 #ifdef STRIDE
329 asm (" trap &3");
330 asm (" mov.w %d0,havefpu%");
331 #else /* m68k, not STRIDE */
332 asm (" mov.l %d0,splimit%");
333 #endif /* STRIDE */
334 #endif /* not NU */
335 asm (" jsr start1");
336 asm (" mov.l %d0,(%sp)");
337 asm (" jsr exit");
338 asm (" mov.l &1,%d0"); /* d0 = 1 => exit */
339 asm (" trap &0");
340 #else /* m68000, not m68k */
341
342 #ifdef m68000
343
344 #ifdef ISI68K
345 /* Added by ESM Sun May 24 12:44:02 1987 to get new ISI library to work */
346 /* Edited by Ray Mon May 15 15:59:56 EST 1989 so we can compile with gcc */
347 #if defined(BSD4_3) && !defined(__GNUC__)
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 a6,#0");
362 asm (" jbsr _start1");
363 asm (" unlk a6");
364 asm (" rts");
365 #if defined(BSD4_3) && !defined(__GNUC__)
366 }
367 #endif
368 #else /* not ISI68K */
369
370 _start ()
371 {
372 #ifdef sun
373 #ifdef LISP_FLOAT_TYPE
374 finitfp_();
375 #endif
376 #endif
377 /* On 68000, _start pushes a6 onto stack */
378 start1 ();
379 }
380 #endif /* not ISI68k */
381 #endif /* m68000 */
382 #endif /* m68k */
383
384 #if defined(m68k) || defined(m68000)
385 /* ignore takes care of skipping the a6 value pushed in start. */
386 static
387 #if defined(m68k)
388 start1 (argc, xargv)
389 #else
390 start1 (ignore, argc, xargv)
391 #endif
392 int argc;
393 char *xargv;
394 {
395 char **argv = &xargv;
396 environ = argv + argc + 1;
397
398 if ((char *)environ == xargv)
399 environ--;
400 #ifdef sun_68881
401 asm(" jsr f68881_used");
402 #endif
403 #ifdef sun_fpa
404 asm(" jsr ffpa_used");
405 #endif
406 #ifdef sun_soft
407 asm(" jsr start_float");
408 #endif
409 exit (main (argc, argv, environ));
410 }
411
412 #endif /* m68k or m68000 */
413
414 #endif /* not CRT0_DUMMIES */
415
416 #ifdef hp9000s300
417 int argc_value;
418 char **argv_value;
419 #ifdef OLD_HP_ASSEMBLER
420 asm(" text");
421 asm(" globl __start");
422 asm(" globl _exit");
423 asm(" globl _main");
424 asm("__start");
425 asm(" dc.l 0");
426 asm(" subq.w #0x1,d0");
427 asm(" move.w d0,float_soft");
428 asm(" move.l 0x4(a7),d0");
429 asm(" beq.s skip_1");
430 asm(" move.l d0,a0");
431 asm(" clr.l -0x4(a0)");
432 asm("skip_1");
433 asm(" move.l a7,a0");
434 asm(" subq.l #0x8,a7");
435 asm(" move.l (a0),(a7)");
436 asm(" move.l (a0),_argc_value");
437 asm(" addq.l #0x4,a0");
438 asm(" move.l a0,0x4(a7)");
439 asm(" move.l a0,_argv_value");
440 asm("incr_loop");
441 asm(" tst.l (a0)+");
442 asm(" bne.s incr_loop");
443 asm(" move.l 0x4(a7),a1");
444 asm(" cmp.l (a1),a0");
445 asm(" blt.s skip_2");
446 asm(" subq.l #0x4,a0");
447 asm("skip_2");
448 asm(" move.l a0,0x8(a7)");
449 asm(" move.l a0,_environ");
450 asm(" jsr _main");
451 asm(" addq.l #0x8,a7");
452 asm(" move.l d0,-(a7)");
453 asm(" jsr _exit");
454 asm(" move.w #0x1,d0");
455 asm(" trap #0x0");
456 asm(" comm float_soft,4");
457 /* float_soft is allocated in this way because C would
458 put an underscore character in its name otherwise. */
459
460 #else /* new hp assembler */
461
462 asm(" text");
463 asm(" global float_loc");
464 asm(" set float_loc,0xFFFFB000");
465 asm(" global fpa_loc");
466 asm(" set fpa_loc,0xfff08000");
467 asm(" global __start");
468 asm(" global _exit");
469 asm(" global _main");
470 asm("__start:");
471 asm(" byte 0,0,0,0");
472 asm(" subq.w &1,%d0");
473 asm(" mov.w %d0,float_soft");
474 asm(" mov.w %d1,flag_68881");
475 #ifndef HPUX_68010
476 asm(" beq.b skip_float");
477 asm(" fmov.l &0x7400,%fpcr");
478 /* asm(" fmov.l &0x7480,%fpcr"); */
479 #endif /* HPUX_68010 */
480 asm("skip_float:");
481 asm(" mov.l %a0,%d0");
482 asm(" add.l %d0,%d0");
483 asm(" subx.w %d1,%d1");
484 asm(" mov.w %d1,flag_68010");
485 asm(" add.l %d0,%d0");
486 asm(" subx.w %d1,%d1");
487 asm(" mov.w %d1,flag_fpa");
488 asm(" tst.l %d2");
489 asm(" ble.b skip_3");
490 asm(" lsl flag_68881");
491 asm(" lsl flag_fpa");
492 asm("skip_3:");
493 asm(" mov.l 4(%a7),%d0");
494 asm(" beq.b skip_1");
495 asm(" mov.l %d0,%a0");
496 asm(" clr.l -4(%a0)");
497 asm("skip_1:");
498 asm(" mov.l %a7,%a0");
499 asm(" subq.l &8,%a7");
500 asm(" mov.l (%a0),(%a7)");
501 asm(" mov.l (%a0),_argc_value");
502 asm(" addq.l &4,%a0");
503 asm(" mov.l %a0,4(%a7)");
504 asm(" mov.l %a0,_argv_value");
505 asm("incr_loop:");
506 asm(" tst.l (%a0)+");
507 asm(" bne.b incr_loop");
508 asm(" mov.l 4(%a7),%a1");
509 asm(" cmp.l %a0,(%a1)");
510 asm(" blt.b skip_2");
511 asm(" subq.l &4,%a0");
512 asm("skip_2:");
513 asm(" mov.l %a0,8(%a7)");
514 asm(" mov.l %a0,_environ");
515 asm(" jsr _main");
516 asm(" addq.l &8,%a7");
517 asm(" mov.l %d0,-(%a7)");
518 asm(" jsr _exit");
519 asm(" mov.w &1,%d0");
520 asm(" trap &0");
521 asm(" comm float_soft, 4");
522 asm(" comm flag_68881, 4");
523 asm(" comm flag_68010, 4");
524 asm(" comm flag_68040, 4");
525 asm(" comm flag_fpa, 4");
526
527 #endif /* new hp assembler */
528 #endif /* hp9000s300 */
529
530 #ifdef GOULD
531
532 /* startup code has to be in near text rather
533 than fartext as allocated by the C compiler. */
534 asm(" .text");
535 asm(" .align 2");
536 asm(" .globl __start");
537 asm(" .text");
538 asm("__start:");
539 /* setup base register b1 (function base). */
540 asm(" .using b1,.");
541 asm(" tpcbr b1");
542 /* setup base registers b3 through b7 (data references). */
543 asm(" file basevals,b3");
544 /* setup base register b2 (stack pointer); it should be
545 aligned on a 8-word boundary; but because it is pointing
546 to argc, its value should be remembered (in r5). */
547 asm(" movw b2,r4");
548 asm(" movw b2,r5");
549 asm(" andw #~0x1f,r4");
550 asm(" movw r4,b2");
551 /* allocate stack frame to do some work. */
552 asm(" subea 16w,b2");
553 /* initialize signal catching for UTX/32 1.2; this is
554 necessary to make restart from saved image work. */
555 asm(" movea sigcatch,r1");
556 asm(" movw r1,8w[b2]");
557 asm(" svc #1,#150");
558 /* setup address of argc for start1. */
559 asm(" movw r5,8w[b2]");
560 asm(" func #1,_start1");
561 asm(" halt");
562 /* space for ld to store base register initial values. */
563 asm(" .align 5");
564 asm("basevals:");
565 asm(" .word __base3,__base4,__base5,__base6,__base7");
566
567 static
568 start1 (xargc)
569 int *xargc;
570 {
571 int argc;
572 char **argv;
573
574 argc = *xargc;
575 argv = (char **)(xargc) + 1;
576 environ = argv + argc + 1;
577
578 if (environ == argv)
579 environ--;
580 exit (main (argc, argv, environ));
581
582 }
583
584 #endif /* GOULD */
585
586 #ifdef elxsi
587 #include <elxsi/argvcache.h>
588
589 extern char **environ;
590 extern int errno;
591 extern void _init_doscan(), _init_iob();
592 extern char end[];
593 char *_init_brk = end;
594
595 _start()
596 {
597 environ = exec_cache.ac_envp;
598 brk (_init_brk);
599 errno = 0;
600 _init_doscan ();
601 _init_iob ();
602 _exit (exit (main (exec_cache.ac_argc,
603 exec_cache.ac_argv,
604 exec_cache.ac_envp)));
605 }
606 #endif /* elxsi */
607
608
609 #ifdef sparc
610 #ifdef no_toplevel_asm
611 static no_toplevel_asm_wrapper() {
612 #ifdef USG5_4
613 asm (".pushsection \".text\"");
614 #endif /* USG5_4 */
615 #endif /* no_toplevel_asm */
616 #ifdef USG5_4
617 asm (".global _start");
618 asm (".text");
619 asm ("_start:");
620 asm (" mov 0, %fp");
621 asm (" ld [%sp + 64], %o0");
622 asm (" add %sp, 68, %o1");
623 asm (" sll %o0, 2, %o2");
624 asm (" add %o2, 4, %o2");
625 asm (" add %o1, %o2, %o2");
626 asm (" sethi %hi(_environ), %o3");
627 asm (" st %o2, [%o3+%lo(_environ)]");
628 asm (" andn %sp, 7, %sp");
629 asm (" call main");
630 asm (" sub %sp, 24, %sp");
631 asm (" call _exit");
632 asm (" nop");
633 #else
634 asm (".global __start");
635 asm (".text");
636 asm ("__start:");
637 asm (" mov 0, %fp");
638 asm (" ld [%sp + 64], %o0");
639 asm (" add %sp, 68, %o1");
640 asm (" sll %o0, 2, %o2");
641 asm (" add %o2, 4, %o2");
642 asm (" add %o1, %o2, %o2");
643 asm (" sethi %hi(_environ), %o3");
644 asm (" st %o2, [%o3+%lo(_environ)]");
645 asm (" andn %sp, 7, %sp");
646 asm (" call _main");
647 asm (" sub %sp, 24, %sp");
648 asm (" call __exit");
649 asm (" nop");
650 #endif /* USG5_4 */
651 #ifdef no_toplevel_asm
652 #ifdef USG5_4
653 asm (".popsection");
654 #endif /* USG5_4 */
655 } /* no_toplevel_asm_wrapper() */
656 #endif /* no_toplevel_asm */
657 #endif /* sparc */
658
659 #if __FreeBSD__ == 2
660 char *__progname;
661 #endif
662 #ifdef __bsdi__
663 #include <sys/param.h> /* for version number */
664 #if defined(_BSDI_VERSION) && (_BSDI_VERSION >= 199501)
665 char *__progname;
666 #endif
667 #endif /* __bsdi__ */