comparison src/ecrt0.c @ 0:376386a54a3c r19-14

Import from CVS: tag r19-14
author cvs
date Mon, 13 Aug 2007 08:45:50 +0200
parents
children ac2d302a0011
comparison
equal deleted inserted replaced
-1:000000000000 0:376386a54a3c
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 `envron' 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_fpa, 4");
525
526 #endif /* new hp assembler */
527 #endif /* hp9000s300 */
528
529 #ifdef GOULD
530
531 /* startup code has to be in near text rather
532 than fartext as allocated by the C compiler. */
533 asm(" .text");
534 asm(" .align 2");
535 asm(" .globl __start");
536 asm(" .text");
537 asm("__start:");
538 /* setup base register b1 (function base). */
539 asm(" .using b1,.");
540 asm(" tpcbr b1");
541 /* setup base registers b3 through b7 (data references). */
542 asm(" file basevals,b3");
543 /* setup base register b2 (stack pointer); it should be
544 aligned on a 8-word boundary; but because it is pointing
545 to argc, its value should be remembered (in r5). */
546 asm(" movw b2,r4");
547 asm(" movw b2,r5");
548 asm(" andw #~0x1f,r4");
549 asm(" movw r4,b2");
550 /* allocate stack frame to do some work. */
551 asm(" subea 16w,b2");
552 /* initialize signal catching for UTX/32 1.2; this is
553 necessary to make restart from saved image work. */
554 asm(" movea sigcatch,r1");
555 asm(" movw r1,8w[b2]");
556 asm(" svc #1,#150");
557 /* setup address of argc for start1. */
558 asm(" movw r5,8w[b2]");
559 asm(" func #1,_start1");
560 asm(" halt");
561 /* space for ld to store base register initial values. */
562 asm(" .align 5");
563 asm("basevals:");
564 asm(" .word __base3,__base4,__base5,__base6,__base7");
565
566 static
567 start1 (xargc)
568 int *xargc;
569 {
570 int argc;
571 char **argv;
572
573 argc = *xargc;
574 argv = (char **)(xargc) + 1;
575 environ = argv + argc + 1;
576
577 if (environ == argv)
578 environ--;
579 exit (main (argc, argv, environ));
580
581 }
582
583 #endif /* GOULD */
584
585 #ifdef elxsi
586 #include <elxsi/argvcache.h>
587
588 extern char **environ;
589 extern int errno;
590 extern void _init_doscan(), _init_iob();
591 extern char end[];
592 char *_init_brk = end;
593
594 _start()
595 {
596 environ = exec_cache.ac_envp;
597 brk (_init_brk);
598 errno = 0;
599 _init_doscan ();
600 _init_iob ();
601 _exit (exit (main (exec_cache.ac_argc,
602 exec_cache.ac_argv,
603 exec_cache.ac_envp)));
604 }
605 #endif /* elxsi */
606
607
608 #ifdef sparc
609 #ifdef no_toplevel_asm
610 static no_toplevel_asm_wrapper() {
611 #ifdef USG5_4
612 asm (".pushsection \".text\"");
613 #endif /* USG5_4 */
614 #endif /* no_toplevel_asm */
615 #ifdef USG5_4
616 asm (".global _start");
617 asm (".text");
618 asm ("_start:");
619 asm (" mov 0, %fp");
620 asm (" ld [%sp + 64], %o0");
621 asm (" add %sp, 68, %o1");
622 asm (" sll %o0, 2, %o2");
623 asm (" add %o2, 4, %o2");
624 asm (" add %o1, %o2, %o2");
625 asm (" sethi %hi(_environ), %o3");
626 asm (" st %o2, [%o3+%lo(_environ)]");
627 asm (" andn %sp, 7, %sp");
628 asm (" call main");
629 asm (" sub %sp, 24, %sp");
630 asm (" call _exit");
631 asm (" nop");
632 #else
633 asm (".global __start");
634 asm (".text");
635 asm ("__start:");
636 asm (" mov 0, %fp");
637 asm (" ld [%sp + 64], %o0");
638 asm (" add %sp, 68, %o1");
639 asm (" sll %o0, 2, %o2");
640 asm (" add %o2, 4, %o2");
641 asm (" add %o1, %o2, %o2");
642 asm (" sethi %hi(_environ), %o3");
643 asm (" st %o2, [%o3+%lo(_environ)]");
644 asm (" andn %sp, 7, %sp");
645 asm (" call _main");
646 asm (" sub %sp, 24, %sp");
647 asm (" call __exit");
648 asm (" nop");
649 #endif /* USG5_4 */
650 #ifdef no_toplevel_asm
651 #ifdef USG5_4
652 asm (".popsection");
653 #endif /* USG5_4 */
654 } /* no_toplevel_asm_wrapper() */
655 #endif /* no_toplevel_asm */
656 #endif /* sparc */
657
658 #if __FreeBSD__ == 2
659 char *__progname;
660 #endif
661 #ifdef __bsdi__
662 #include <sys/param.h> /* for version number */
663 #if defined(_BSDI_VERSION) && (_BSDI_VERSION >= 199501)
664 char *__progname;
665 #endif
666 #endif /* __bsdi__ */