Mercurial > emacs
annotate src/ecrt0.c @ 82622:fde565f809da
Move refcards from etc/ to etc/refcards/
author | Glenn Morris <rgm@gnu.org> |
---|---|
date | Wed, 22 Aug 2007 07:17:48 +0000 |
parents | 922696f363b0 |
children | fc2bcd2a8aad f55f9811f5d7 |
rev | line source |
---|---|
25844 | 1 /* C code startup routine. |
75227
e90d04cd455a
Update copyright for years from Emacs 21 to present (mainly adding
Glenn Morris <rgm@gnu.org>
parents:
68651
diff
changeset
|
2 Copyright (C) 1985, 1986, 1992, 2001, 2002, 2003, 2004, |
75348 | 3 2005, 2006, 2007 Free Software Foundation, Inc. |
25844 | 4 |
5 This file is part of GNU Emacs. | |
6 | |
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 | |
78260
922696f363b0
Switch license to GPLv3 or later.
Glenn Morris <rgm@gnu.org>
parents:
75348
diff
changeset
|
9 the Free Software Foundation; either version 3, or (at your option) |
25844 | 10 any later version. |
11 | |
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. | |
16 | |
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 | |
64084 | 19 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, |
20 Boston, MA 02110-1301, USA. */ | |
25844 | 21 |
22 | |
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. */ | |
27 | |
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 | |
34 0 | |
35 Optionally: | |
36 [word pointing to environment variable]... 1 or more times | |
37 ... | |
38 0 | |
39 And always: | |
40 first arg string | |
41 [next arg string]... 0 or more times | |
42 */ | |
43 | |
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 | |
47 word containing argp | |
48 word pointing to first arg string, and so on as above | |
49 */ | |
50 | |
51 #ifdef emacs | |
52 #include <config.h> | |
53 #endif | |
54 | |
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. */ | |
68 | |
69 int data_start = 0; | |
70 | |
71 #ifdef NEED_ERRNO | |
72 int errno; | |
73 #endif | |
74 | |
75 #ifndef DONT_NEED_ENVIRON | |
76 char **environ; | |
77 #endif | |
78 | |
79 #ifndef static | |
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. */ | |
84 static start1 (); | |
85 #endif | |
86 | |
87 #ifdef APOLLO | |
88 extern char *malloc(), *realloc(), *(*_libc_malloc) (), *(*_libc_realloc)(); | |
89 extern void free(), (*_libc_free) (); extern int main(); | |
90 std_$call void unix_$main(); | |
91 | |
92 _start() | |
93 { | |
94 _libc_malloc = malloc; | |
95 _libc_realloc = realloc; | |
96 _libc_free = free; | |
97 unix_$main(main); /* no return */ | |
98 } | |
99 #endif /* APOLLO */ | |
100 | |
101 #if defined(orion) || defined(pyramid) || defined(celerity) || defined(ALLIANT) || defined(clipper) || defined(sps7) | |
102 | |
103 #if defined(sps7) && defined(V3x) | |
104 asm(" section 10"); | |
105 asm(" ds.b 0xb0"); | |
106 #endif | |
107 | |
108 #ifdef ALLIANT | |
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; | |
116 #ifdef ALLIANT_2800 | |
117 unsigned char *_end = &end; | |
118 #endif | |
119 #endif | |
120 | |
121 #ifndef DUMMIES | |
122 #define DUMMIES | |
123 #endif | |
124 | |
125 _start (DUMMIES argc, argv, envp) | |
126 int argc; | |
127 char **argv, **envp; | |
128 { | |
129 #ifdef ALLIANT | |
130 #ifdef ALLIANT_2800 | |
131 _curbrk = _end; | |
132 _minbrk = _end; | |
133 #else | |
134 _curbrk = _setbrk; | |
135 _minbrk = _setbrk; | |
136 #endif | |
137 #endif | |
138 | |
139 environ = envp; | |
140 | |
141 exit (main (argc, argv, envp)); | |
142 } | |
143 | |
144 #endif /* orion or pyramid or celerity or alliant or clipper */ | |
145 | |
146 #if defined (ns16000) && !defined (sequent) && !defined (UMAX) && !defined (CRT0_DUMMIES) | |
147 | |
148 _start () | |
149 { | |
150 /* On 16000, _start pushes fp onto stack */ | |
151 start1 (); | |
152 } | |
153 | |
154 /* ignore takes care of skipping the fp value pushed in start. */ | |
155 static | |
156 start1 (ignore, argc, argv) | |
157 int ignore; | |
158 int argc; | |
159 register char **argv; | |
160 { | |
161 environ = argv + argc + 1; | |
162 | |
163 if (environ == *argv) | |
164 environ--; | |
165 exit (main (argc, argv, environ)); | |
166 } | |
167 #endif /* ns16000, not sequent and not UMAX, and not the CRT0_DUMMIES method */ | |
168 | |
169 #ifdef UMAX | |
170 _start() | |
171 { | |
172 asm(" exit [] # undo enter"); | |
173 asm(" .set exitsc,1"); | |
174 asm(" .set sigcatchall,0x400"); | |
175 | |
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"); | |
183 | |
184 asm("start:"); | |
185 asm(" br .xstart"); | |
186 asm(" .org 0x20"); | |
187 asm(" .double p_glbl,0,0xf00000,0"); | |
188 asm(" .org 0x30"); | |
189 asm(".xstart:"); | |
190 asm(" adjspb $8"); | |
191 asm(" movd 8(sp),0(sp) # argc"); | |
192 asm(" addr 12(sp),r0"); | |
193 asm(" movd r0,4(sp) # argv"); | |
194 asm("L1:"); | |
195 asm(" movd r0,r1"); | |
196 asm(" addqd $4,r0"); | |
197 asm(" cmpqd $0,0(r1) # null args term ?"); | |
198 asm(" bne L1"); | |
199 asm(" cmpd r0,0(4(sp)) # end of 'env' or 'argv' ?"); | |
200 asm(" blt L2"); | |
201 asm(" addqd $-4,r0 # envp's are in list"); | |
202 asm("L2:"); | |
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"); | |
209 asm(" adjspb $-12"); | |
210 asm(" jsr @_main"); | |
211 asm(" adjspb $-12"); | |
212 asm(" movd r0,tos"); | |
213 asm(" jsr @_exit"); | |
214 asm(" adjspb $-4"); | |
215 asm(" addr @exitsc,r0"); | |
216 asm(" svc"); | |
217 asm(" .align 4 # sigvec arg"); | |
218 asm("sv:"); | |
219 asm(" .double sigentry"); | |
220 asm(" .double 0"); | |
221 asm(" .double 0"); | |
222 | |
223 asm(" .comm p_glbl,1"); | |
224 } | |
225 #endif /* UMAX */ | |
226 | |
227 #ifdef CRT0_DUMMIES | |
228 | |
229 /* Define symbol "start": here; some systems want that symbol. */ | |
230 #ifdef DOT_GLOBAL_START | |
231 asm(" .text "); | |
232 asm(" .globl start "); | |
233 asm(" start: "); | |
234 #endif /* DOT_GLOBAL_START */ | |
235 | |
236 #ifdef NODOT_GLOBAL_START | |
237 asm(" text "); | |
238 asm(" global start "); | |
239 asm(" start: "); | |
240 #endif /* NODOT_GLOBAL_START */ | |
241 | |
242 #ifdef m68000 | |
243 | |
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. */ | |
247 asm(".text "); | |
248 asm(" .even "); | |
249 asm(".globl __start "); | |
250 asm("__start: "); | |
251 asm(" link a6,#0 "); | |
252 asm(" jbsr _start1 "); | |
253 asm(" unlk a6 "); | |
254 asm(" rts "); | |
255 | |
256 #else /* not m68000 */ | |
257 | |
258 _start () | |
259 { | |
260 /* On vax, nothing is pushed here */ | |
261 /* On sequent, bogus fp is pushed here */ | |
262 start1 (); | |
263 } | |
264 | |
265 #endif /* possibly m68000 */ | |
266 | |
267 static | |
268 start1 (CRT0_DUMMIES argc, xargv) | |
269 int argc; | |
270 char *xargv; | |
271 { | |
272 register char **argv = &xargv; | |
273 environ = argv + argc + 1; | |
274 | |
275 if ((char *)environ == xargv) | |
276 environ--; | |
277 exit (main (argc, argv, environ)); | |
278 | |
279 /* Refer to `start1' so GCC will not think it is never called | |
280 and optimize it out. */ | |
281 (void) &start1; | |
282 } | |
283 #else /* not CRT0_DUMMIES */ | |
284 | |
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. */ | |
293 | |
294 #ifdef m68k /* Can't do it all from C */ | |
295 asm (" global _start"); | |
296 asm (" text"); | |
297 asm ("_start:"); | |
298 #ifndef NU | |
299 #ifdef STRIDE | |
300 asm (" comm havefpu%,2"); | |
301 #else /* m68k, not STRIDE */ | |
302 asm (" comm splimit%,4"); | |
303 #endif /* STRIDE */ | |
304 asm (" global exit"); | |
305 asm (" text"); | |
306 #ifdef STRIDE | |
307 asm (" trap &3"); | |
308 asm (" mov.w %d0,havefpu%"); | |
309 #else /* m68k, not STRIDE */ | |
310 asm (" mov.l %d0,splimit%"); | |
311 #endif /* STRIDE */ | |
312 #endif /* not NU */ | |
313 asm (" jsr start1"); | |
314 asm (" mov.l %d0,(%sp)"); | |
315 asm (" jsr exit"); | |
316 asm (" mov.l &1,%d0"); /* d0 = 1 => exit */ | |
317 asm (" trap &0"); | |
318 #else /* m68000, not m68k */ | |
319 | |
320 #ifdef m68000 | |
321 | |
322 #ifdef ISI68K | |
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__) | |
326 static foo () { | |
327 #endif | |
328 asm (" .globl is68020"); | |
329 asm ("is68020:"); | |
330 #ifndef BSD4_3 | |
331 asm (" .long 0x00000000"); | |
332 asm (" .long 0xffffffff"); | |
333 /* End of stuff added by ESM */ | |
334 #endif | |
335 asm (" .text"); | |
336 asm (" .globl __start"); | |
337 asm ("__start:"); | |
338 asm (" .word 0"); | |
339 asm (" link a6,#0"); | |
340 asm (" jbsr _start1"); | |
341 asm (" unlk a6"); | |
342 asm (" rts"); | |
343 #if defined(BSD4_3) && !defined(__GNUC__) | |
344 } | |
345 #endif | |
346 #else /* not ISI68K */ | |
347 | |
348 _start () | |
349 { | |
350 #ifdef sun | |
351 finitfp_(); | |
49600
23a1cea22d13
Trailing whitespace deleted.
Juanma Barranquero <lekktu@gmail.com>
parents:
27727
diff
changeset
|
352 #endif |
25844 | 353 /* On 68000, _start pushes a6 onto stack */ |
354 start1 (); | |
355 } | |
356 #endif /* not ISI68k */ | |
357 #endif /* m68000 */ | |
358 #endif /* m68k */ | |
359 | |
360 #if defined(m68k) || defined(m68000) | |
361 /* ignore takes care of skipping the a6 value pushed in start. */ | |
362 static | |
363 #if defined(m68k) | |
364 start1 (argc, xargv) | |
365 #else | |
366 start1 (ignore, argc, xargv) | |
367 #endif | |
368 int argc; | |
369 char *xargv; | |
370 { | |
371 register char **argv = &xargv; | |
372 environ = argv + argc + 1; | |
373 | |
374 if ((char *)environ == xargv) | |
375 environ--; | |
376 #ifdef sun_68881 | |
377 asm(" jsr f68881_used"); | |
378 #endif | |
379 #ifdef sun_fpa | |
380 asm(" jsr ffpa_used"); | |
381 #endif | |
382 #ifdef sun_soft | |
383 asm(" jsr start_float"); | |
384 #endif | |
385 exit (main (argc, argv, environ)); | |
386 } | |
387 | |
388 #endif /* m68k or m68000 */ | |
389 | |
390 #endif /* not CRT0_DUMMIES */ | |
391 | |
392 #ifdef hp9000s300 | |
393 int argc_value; | |
394 char **argv_value; | |
395 #ifdef OLD_HP_ASSEMBLER | |
396 asm(" text"); | |
397 asm(" globl __start"); | |
398 asm(" globl _exit"); | |
399 asm(" globl _main"); | |
400 asm("__start"); | |
401 asm(" dc.l 0"); | |
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)"); | |
408 asm("skip_1"); | |
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"); | |
416 asm("incr_loop"); | |
417 asm(" tst.l (a0)+"); | |
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"); | |
423 asm("skip_2"); | |
424 asm(" move.l a0,0x8(a7)"); | |
425 asm(" move.l a0,_environ"); | |
426 asm(" jsr _main"); | |
427 asm(" addq.l #0x8,a7"); | |
428 asm(" move.l d0,-(a7)"); | |
429 asm(" jsr _exit"); | |
430 asm(" move.w #0x1,d0"); | |
431 asm(" trap #0x0"); | |
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. */ | |
435 | |
436 #else /* new hp assembler */ | |
437 | |
438 asm(" text"); | |
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"); | |
446 asm("__start:"); | |
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"); | |
451 #ifndef HPUX_68010 | |
452 asm(" beq.b skip_float"); | |
453 asm(" fmov.l &0x7400,%fpcr"); | |
454 /* asm(" fmov.l &0x7480,%fpcr"); */ | |
455 #endif /* HPUX_68010 */ | |
456 asm("skip_float:"); | |
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"); | |
464 asm(" tst.l %d2"); | |
465 asm(" ble.b skip_3"); | |
466 asm(" lsl flag_68881"); | |
467 asm(" lsl flag_fpa"); | |
468 asm("skip_3:"); | |
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)"); | |
473 asm("skip_1:"); | |
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"); | |
481 asm("incr_loop:"); | |
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"); | |
488 asm("skip_2:"); | |
489 asm(" mov.l %a0,8(%a7)"); | |
490 asm(" mov.l %a0,_environ"); | |
491 asm(" jsr _main"); | |
492 asm(" addq.l &8,%a7"); | |
493 asm(" mov.l %d0,-(%a7)"); | |
494 asm(" jsr _exit"); | |
495 asm(" mov.w &1,%d0"); | |
496 asm(" trap &0"); | |
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"); | |
502 | |
503 #endif /* new hp assembler */ | |
504 #endif /* hp9000s300 */ | |
505 | |
506 #ifdef GOULD | |
507 | |
508 /* startup code has to be in near text rather | |
509 than fartext as allocated by the C compiler. */ | |
510 asm(" .text"); | |
511 asm(" .align 2"); | |
512 asm(" .globl __start"); | |
513 asm(" .text"); | |
514 asm("__start:"); | |
515 /* setup base register b1 (function base). */ | |
516 asm(" .using b1,."); | |
517 asm(" tpcbr b1"); | |
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). */ | |
523 asm(" movw b2,r4"); | |
524 asm(" movw b2,r5"); | |
525 asm(" andw #~0x1f,r4"); | |
526 asm(" movw r4,b2"); | |
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]"); | |
533 asm(" svc #1,#150"); | |
534 /* setup address of argc for start1. */ | |
535 asm(" movw r5,8w[b2]"); | |
536 asm(" func #1,_start1"); | |
537 asm(" halt"); | |
538 /* space for ld to store base register initial values. */ | |
539 asm(" .align 5"); | |
540 asm("basevals:"); | |
541 asm(" .word __base3,__base4,__base5,__base6,__base7"); | |
542 | |
543 static | |
544 start1 (xargc) | |
545 int *xargc; | |
546 { | |
547 register int argc; | |
548 register char **argv; | |
549 | |
550 argc = *xargc; | |
551 argv = (char **)(xargc) + 1; | |
552 environ = argv + argc + 1; | |
553 | |
554 if (environ == argv) | |
555 environ--; | |
556 exit (main (argc, argv, environ)); | |
557 | |
558 } | |
559 | |
560 #endif /* GOULD */ | |
561 | |
562 #ifdef elxsi | |
563 #include <elxsi/argvcache.h> | |
564 | |
565 extern char **environ; | |
566 extern int errno; | |
567 extern void _init_doscan(), _init_iob(); | |
568 extern char end[]; | |
569 char *_init_brk = end; | |
570 | |
571 _start() | |
572 { | |
573 environ = exec_cache.ac_envp; | |
574 brk (_init_brk); | |
575 errno = 0; | |
576 _init_doscan (); | |
577 _init_iob (); | |
578 _exit (exit (main (exec_cache.ac_argc, | |
579 exec_cache.ac_argv, | |
580 exec_cache.ac_envp))); | |
581 } | |
582 #endif /* elxsi */ | |
583 | |
584 | |
585 #ifdef sparc | |
586 asm (".global __start"); | |
587 asm (".text"); | |
588 asm ("__start:"); | |
589 asm (" mov 0, %fp"); | |
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"); | |
598 asm (" call _main"); | |
599 asm (" sub %sp, 24, %sp"); | |
600 asm (" call __exit"); | |
601 asm (" nop"); | |
602 | |
603 #endif /* sparc */ | |
604 | |
605 #if __FreeBSD__ == 2 | |
606 char *__progname; | |
607 #endif | |
608 #ifdef __bsdi__ | |
609 #include <sys/param.h> /* for version number */ | |
610 #if defined(_BSDI_VERSION) && (_BSDI_VERSION >= 199501) | |
611 char *__progname; | |
612 #endif | |
613 #endif /* __bsdi__ */ | |
52401 | 614 |
615 /* arch-tag: 4025c2fb-d6b1-4d29-b1b6-8100b6bd1e74 | |
616 (do not change this comment) */ |