1 /* C code startup routine.
2 Copyright (C) 1985, 1986, 1992, 2001, 2002, 2003, 2004,
3 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
5 This file is part of GNU Emacs.
7 GNU Emacs is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3, or (at your option)
12 GNU Emacs is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with GNU Emacs; see the file COPYING. If not, write to
19 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
20 Boston, MA 02110-1301, USA. */
23 /* The standard Vax 4.2 Unix crt0.c cannot be used for Emacs
24 because it makes `environ' an initialized variable.
25 It is easiest to have a special crt0.c on all machines
26 though I don't know whether other machines actually need it. */
28 /* On the vax and 68000, in BSD4.2 and USG5.2,
29 this is the data format on startup:
30 (vax) ap and fp are unpredictable as far as I know; don't use them.
31 sp -> word containing argc
32 word pointing to first arg string
33 [word pointing to next arg string]... 0 or more times
36 [word pointing to environment variable]... 1 or more times
41 [next arg string]... 0 or more times
44 /* On the 16000, at least in the one 4.2 system I know about,
45 the initial data format is
46 sp -> word containing argc
48 word pointing to first arg string, and so on as above
55 /* ******** WARNING ********
56 Do not insert any data definitions before data_start!
57 Since this is the first file linked, the address of the following
58 variable should correspond to the start of initialized data space.
59 On some systems this is a constant that is independent of the text
60 size for shared executables. On others, it is a function of the
61 text size. In short, this seems to be the most portable way to
62 discover the start of initialized data space dynamically at runtime,
63 for either shared or unshared executables, on either swapping or
64 virtual systems. It only requires that the linker allocate objects
65 in the order encountered, a reasonable model for most Unix systems.
66 Similarly, note that the address of _start() should be the start
67 of text space. Fred Fish, UniSoft Systems Inc. */
75 #ifndef DONT_NEED_ENVIRON
80 /* On systems where the static storage class is usable, this function
81 should be declared as static. Otherwise, the static keyword has
82 been defined to be something else, and code for those systems must
83 take care of this declaration appropriately. */
88 extern char *malloc(), *realloc(), *(*_libc_malloc
) (), *(*_libc_realloc
)();
89 extern void free(), (*_libc_free
) (); extern int main();
90 std_$call
void unix_$
main();
94 _libc_malloc
= malloc
;
95 _libc_realloc
= realloc
;
97 unix_$
main(main
); /* no return */
101 #if defined(orion) || defined(pyramid) || defined(celerity) || defined(ALLIANT) || defined(clipper) || defined(sps7)
103 #if defined(sps7) && defined(V3x)
109 /* _start must initialize _curbrk and _minbrk on the first startup;
110 when starting up after dumping, it must initialize them to what they were
111 before the dumping, since they are in the shared library and
112 are not dumped. See ADJUST_EXEC_HEADER in m-alliant.h. */
113 extern unsigned char *_curbrk
, *_minbrk
;
114 extern unsigned char end
;
115 unsigned char *_setbrk
= &end
;
117 unsigned char *_end
= &end
;
125 _start (DUMMIES argc
, argv
, envp
)
141 exit (main (argc
, argv
, envp
));
144 #endif /* orion or pyramid or celerity or alliant or clipper */
146 #if defined (ns16000) && !defined (sequent) && !defined (UMAX) && !defined (CRT0_DUMMIES)
150 /* On 16000, _start pushes fp onto stack */
154 /* ignore takes care of skipping the fp value pushed in start. */
156 start1 (ignore
, argc
, argv
)
159 register char **argv
;
161 environ
= argv
+ argc
+ 1;
163 if (environ
== *argv
)
165 exit (main (argc
, argv
, environ
));
167 #endif /* ns16000, not sequent and not UMAX, and not the CRT0_DUMMIES method */
172 asm(" exit [] # undo enter");
173 asm(" .set exitsc,1");
174 asm(" .set sigcatchall,0x400");
176 asm(" .globl _exit");
177 asm(" .globl start");
178 asm(" .globl __start");
179 asm(" .globl _main");
180 asm(" .globl _environ");
181 asm(" .globl _sigvec");
182 asm(" .globl sigentry");
187 asm(" .double p_glbl,0,0xf00000,0");
191 asm(" movd 8(sp),0(sp) # argc");
192 asm(" addr 12(sp),r0");
193 asm(" movd r0,4(sp) # argv");
197 asm(" cmpqd $0,0(r1) # null args term ?");
199 asm(" cmpd r0,0(4(sp)) # end of 'env' or 'argv' ?");
201 asm(" addqd $-4,r0 # envp's are in list");
203 asm(" movd r0,8(sp) # env");
204 asm(" movd r0,@_environ # indir is 0 if no env ; not 0 if env");
205 asm(" movqd $0,tos # setup intermediate signal handler");
206 asm(" addr @sv,tos");
207 asm(" movzwd $sigcatchall,tos");
208 asm(" jsr @_sigvec");
215 asm(" addr @exitsc,r0");
217 asm(" .align 4 # sigvec arg");
219 asm(" .double sigentry");
223 asm(" .comm p_glbl,1");
229 /* Define symbol "start": here; some systems want that symbol. */
230 #ifdef DOT_GLOBAL_START
232 asm(" .globl start ");
234 #endif /* DOT_GLOBAL_START */
236 #ifdef NODOT_GLOBAL_START
238 asm(" global start ");
240 #endif /* NODOT_GLOBAL_START */
244 /* GCC 2.1, when optimization is turned off, seems to want to push a
245 word of garbage on the stack, which screws up the CRT0_DUMMIES
246 hack. So we hand-code _start in assembly language. */
249 asm(".globl __start ");
252 asm(" jbsr _start1 ");
256 #else /* not m68000 */
260 /* On vax, nothing is pushed here */
261 /* On sequent, bogus fp is pushed here */
265 #endif /* possibly m68000 */
268 start1 (CRT0_DUMMIES argc
, xargv
)
272 register char **argv
= &xargv
;
273 environ
= argv
+ argc
+ 1;
275 if ((char *)environ
== xargv
)
277 exit (main (argc
, argv
, environ
));
279 /* Refer to `start1' so GCC will not think it is never called
280 and optimize it out. */
283 #else /* not CRT0_DUMMIES */
285 /* "m68k" and "m68000" both stand for m68000 processors,
286 but with different program-entry conventions.
287 This is a kludge. Now that the CRT0_DUMMIES mechanism above exists,
288 most of these machines could use the vax code above
289 with some suitable definition of CRT0_DUMMIES.
290 Then the symbol m68k could be flushed.
291 But I don't want to risk breaking these machines
292 in a version 17 patch release, so that change is being put off. */
294 #ifdef m68k /* Can't do it all from C */
295 asm (" global _start");
300 asm (" comm havefpu%,2");
301 #else /* m68k, not STRIDE */
302 asm (" comm splimit%,4");
304 asm (" global exit");
308 asm (" mov.w %d0,havefpu%");
309 #else /* m68k, not STRIDE */
310 asm (" mov.l %d0,splimit%");
314 asm (" mov.l %d0,(%sp)");
316 asm (" mov.l &1,%d0"); /* d0 = 1 => exit */
318 #else /* m68000, not m68k */
323 /* Added by ESM Sun May 24 12:44:02 1987 to get new ISI library to work */
324 /* Edited by Ray Mon May 15 15:59:56 EST 1989 so we can compile with gcc */
325 #if defined(BSD4_3) && !defined(__GNUC__)
328 asm (" .globl is68020");
331 asm (" .long 0x00000000");
332 asm (" .long 0xffffffff");
333 /* End of stuff added by ESM */
336 asm (" .globl __start");
340 asm (" jbsr _start1");
343 #if defined(BSD4_3) && !defined(__GNUC__)
346 #else /* not ISI68K */
353 /* On 68000, _start pushes a6 onto stack */
356 #endif /* not ISI68k */
360 #if defined(m68k) || defined(m68000)
361 /* ignore takes care of skipping the a6 value pushed in start. */
366 start1 (ignore
, argc
, xargv
)
371 register char **argv
= &xargv
;
372 environ
= argv
+ argc
+ 1;
374 if ((char *)environ
== xargv
)
377 asm(" jsr f68881_used");
380 asm(" jsr ffpa_used");
383 asm(" jsr start_float");
385 exit (main (argc
, argv
, environ
));
388 #endif /* m68k or m68000 */
390 #endif /* not CRT0_DUMMIES */
395 #ifdef OLD_HP_ASSEMBLER
397 asm(" globl __start");
402 asm(" subq.w #0x1,d0");
403 asm(" move.w d0,float_soft");
404 asm(" move.l 0x4(a7),d0");
405 asm(" beq.s skip_1");
406 asm(" move.l d0,a0");
407 asm(" clr.l -0x4(a0)");
409 asm(" move.l a7,a0");
410 asm(" subq.l #0x8,a7");
411 asm(" move.l (a0),(a7)");
412 asm(" move.l (a0),_argc_value");
413 asm(" addq.l #0x4,a0");
414 asm(" move.l a0,0x4(a7)");
415 asm(" move.l a0,_argv_value");
418 asm(" bne.s incr_loop");
419 asm(" move.l 0x4(a7),a1");
420 asm(" cmp.l (a1),a0");
421 asm(" blt.s skip_2");
422 asm(" subq.l #0x4,a0");
424 asm(" move.l a0,0x8(a7)");
425 asm(" move.l a0,_environ");
427 asm(" addq.l #0x8,a7");
428 asm(" move.l d0,-(a7)");
430 asm(" move.w #0x1,d0");
432 asm(" comm float_soft,4");
433 /* float_soft is allocated in this way because C would
434 put an underscore character in its name otherwise. */
436 #else /* new hp assembler */
439 asm(" global float_loc");
440 asm(" set float_loc,0xFFFFB000");
441 asm(" global fpa_loc");
442 asm(" set fpa_loc,0xfff08000");
443 asm(" global __start");
444 asm(" global _exit");
445 asm(" global _main");
447 asm(" byte 0,0,0,0");
448 asm(" subq.w &1,%d0");
449 asm(" mov.w %d0,float_soft");
450 asm(" mov.w %d1,flag_68881");
452 asm(" beq.b skip_float");
453 asm(" fmov.l &0x7400,%fpcr");
454 /* asm(" fmov.l &0x7480,%fpcr"); */
455 #endif /* HPUX_68010 */
457 asm(" mov.l %a0,%d0");
458 asm(" add.l %d0,%d0");
459 asm(" subx.w %d1,%d1");
460 asm(" mov.w %d1,flag_68010");
461 asm(" add.l %d0,%d0");
462 asm(" subx.w %d1,%d1");
463 asm(" mov.w %d1,flag_fpa");
465 asm(" ble.b skip_3");
466 asm(" lsl flag_68881");
467 asm(" lsl flag_fpa");
469 asm(" mov.l 4(%a7),%d0");
470 asm(" beq.b skip_1");
471 asm(" mov.l %d0,%a0");
472 asm(" clr.l -4(%a0)");
474 asm(" mov.l %a7,%a0");
475 asm(" subq.l &8,%a7");
476 asm(" mov.l (%a0),(%a7)");
477 asm(" mov.l (%a0),_argc_value");
478 asm(" addq.l &4,%a0");
479 asm(" mov.l %a0,4(%a7)");
480 asm(" mov.l %a0,_argv_value");
482 asm(" tst.l (%a0)+");
483 asm(" bne.b incr_loop");
484 asm(" mov.l 4(%a7),%a1");
485 asm(" cmp.l %a0,(%a1)");
486 asm(" blt.b skip_2");
487 asm(" subq.l &4,%a0");
489 asm(" mov.l %a0,8(%a7)");
490 asm(" mov.l %a0,_environ");
492 asm(" addq.l &8,%a7");
493 asm(" mov.l %d0,-(%a7)");
495 asm(" mov.w &1,%d0");
497 asm(" comm float_soft, 4");
498 asm(" comm flag_68881, 4");
499 asm(" comm flag_68010, 4");
500 asm(" comm flag_68040, 4");
501 asm(" comm flag_fpa, 4");
503 #endif /* new hp assembler */
504 #endif /* hp9000s300 */
508 /* startup code has to be in near text rather
509 than fartext as allocated by the C compiler. */
512 asm(" .globl __start");
515 /* setup base register b1 (function base). */
518 /* setup base registers b3 through b7 (data references). */
519 asm(" file basevals,b3");
520 /* setup base register b2 (stack pointer); it should be
521 aligned on a 8-word boundary; but because it is pointing
522 to argc, its value should be remembered (in r5). */
525 asm(" andw #~0x1f,r4");
527 /* allocate stack frame to do some work. */
528 asm(" subea 16w,b2");
529 /* initialize signal catching for UTX/32 1.2; this is
530 necessary to make restart from saved image work. */
531 asm(" movea sigcatch,r1");
532 asm(" movw r1,8w[b2]");
534 /* setup address of argc for start1. */
535 asm(" movw r5,8w[b2]");
536 asm(" func #1,_start1");
538 /* space for ld to store base register initial values. */
541 asm(" .word __base3,__base4,__base5,__base6,__base7");
548 register char **argv
;
551 argv
= (char **)(xargc
) + 1;
552 environ
= argv
+ argc
+ 1;
556 exit (main (argc
, argv
, environ
));
563 #include <elxsi/argvcache.h>
565 extern char **environ
;
567 extern void _init_doscan(), _init_iob();
569 char *_init_brk
= end
;
573 environ
= exec_cache
.ac_envp
;
578 _exit (exit (main (exec_cache
.ac_argc
,
580 exec_cache
.ac_envp
)));
586 asm (".global __start");
590 asm (" ld [%sp + 64], %o0");
591 asm (" add %sp, 68, %o1");
592 asm (" sll %o0, 2, %o2");
593 asm (" add %o2, 4, %o2");
594 asm (" add %o1, %o2, %o2");
595 asm (" sethi %hi(_environ), %o3");
596 asm (" st %o2, [%o3+%lo(_environ)]");
597 asm (" andn %sp, 7, %sp");
599 asm (" sub %sp, 24, %sp");
600 asm (" call __exit");
609 #include <sys/param.h> /* for version number */
610 #if defined(_BSDI_VERSION) && (_BSDI_VERSION >= 199501)
613 #endif /* __bsdi__ */
615 /* arch-tag: 4025c2fb-d6b1-4d29-b1b6-8100b6bd1e74
616 (do not change this comment) */