Annotation of GNUtools/emacs/src/crt0.c, revision 1.1.1.1

1.1       root        1: /* C code startup routine.
                      2:    Copyright (C) 1985, 1986 Free Software Foundation, Inc.
                      3: 
                      4:     This program is free software; you can redistribute it and/or modify
                      5:     it under the terms of the GNU General Public License as published by
                      6:     the Free Software Foundation; either version 1, or (at your option)
                      7:     any later version.
                      8: 
                      9:     This program is distributed in the hope that it will be useful,
                     10:     but WITHOUT ANY WARRANTY; without even the implied warranty of
                     11:     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
                     12:     GNU General Public License for more details.
                     13: 
                     14:     You should have received a copy of the GNU General Public License
                     15:     along with this program; if not, write to the Free Software
                     16:     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
                     17: 
                     18: In other words, you are welcome to use, share and improve this program.
                     19: You are forbidden to forbid anyone else to use, share and improve
                     20: what you give them.   Help stamp out software-hoarding!  */
                     21: 
                     22: 
                     23: /* The standard Vax 4.2 Unix crt0.c cannot be used for Emacs
                     24:    because it makes `envron' 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: #include "config.h"
                     52: 
                     53: /*             ********  WARNING ********
                     54:     Do not insert any data definitions before data_start!
                     55:     Since this is the first file linked, the address of the following
                     56:     variable should correspond to the start of initialized data space.
                     57:     On some systems this is a constant that is independent of the text
                     58:     size for shared executables.  On others, it is a function of the
                     59:     text size. In short, this seems to be the most portable way to
                     60:     discover the start of initialized data space dynamically at runtime,
                     61:     for either shared or unshared executables, on either swapping or
                     62:     virtual systems.  It only requires that the linker allocate objects
                     63:     in the order encountered, a reasonable model for most Unix systems.
                     64:     Similarly, note that the address of _start() should be the start
                     65:     of text space.   Fred Fish, UniSoft Systems Inc.  */
                     66: 
                     67: int data_start = 0;
                     68: 
                     69: #ifdef NEED_ERRNO
                     70: int errno;
                     71: #endif
                     72: 
                     73: #ifndef DONT_NEED_ENVIRON
                     74: char **environ;
                     75: #endif
                     76: 
                     77: #if defined(orion) || defined(pyramid) || defined(celerity) || defined(ALLIANT) || defined(clipper)
                     78: 
                     79: #ifdef ALLIANT
                     80: /* _start must initialize _curbrk and _minbrk on the first startup;
                     81:    when starting up after dumping, it must initialize them to what they were
                     82:    before the dumping, since they are in the shared library and
                     83:    are not dumped.  See ADJUST_EXEC_HEADER in m-alliant.h.  */
                     84: extern unsigned char *_curbrk, *_minbrk;
                     85: extern unsigned char end;
                     86: unsigned char *_setbrk = &end;
                     87: #ifdef ALLIANT_2800
                     88: unsigned char *_end = &end;
                     89: #endif
                     90: #endif
                     91: 
                     92: #ifndef DUMMIES
                     93: #define DUMMIES
                     94: #endif
                     95: 
                     96: _start (DUMMIES argc, argv, envp)
                     97:      int argc;
                     98:      char **argv, **envp;
                     99: {
                    100: #ifdef ALLIANT
                    101: #ifdef ALLIANT_2800
                    102:   _curbrk = _end;
                    103:   _minbrk = _end;
                    104: #else
                    105:   _curbrk = _setbrk;
                    106:   _minbrk = _setbrk;
                    107: #endif
                    108: #endif
                    109: 
                    110:   environ = envp;
                    111: 
                    112:   exit (main (argc, argv, envp));
                    113: }
                    114: 
                    115: #endif /* orion or pyramid or celerity or alliant or clipper */
                    116: 
                    117: #if defined (ns16000) && !defined (sequent) && !defined (UMAX)
                    118: 
                    119: _start ()
                    120: {
                    121: /* On 16000, _start pushes fp onto stack */
                    122:   start1 ();
                    123: }
                    124: 
                    125: /* ignore takes care of skipping the fp value pushed in start.  */
                    126: static
                    127: start1 (ignore, argc, argv)
                    128:      int ignore;
                    129:      int argc;
                    130:      register char **argv;
                    131: {
                    132:   environ = argv + argc + 1;
                    133: 
                    134:   if (environ == *argv)
                    135:     environ--;
                    136:   exit (main (argc, argv, environ));
                    137: }
                    138: #endif /* ns16000, not sequent and not UMAX */
                    139: 
                    140: #ifdef UMAX
                    141: _start()
                    142: {
                    143:        asm("   exit []                 # undo enter");
                    144:        asm("   .set    exitsc,1");
                    145:        asm("   .set    sigcatchall,0x400");
                    146: 
                    147:        asm("   .globl  _exit");
                    148:        asm("   .globl  start");
                    149:        asm("   .globl  __start");
                    150:        asm("   .globl  _main");
                    151:        asm("   .globl  _environ");
                    152:        asm("   .globl  _sigvec");
                    153:        asm("   .globl  sigentry");
                    154: 
                    155:        asm("start:");
                    156:        asm("   br      .xstart");
                    157:        asm("   .org    0x20");
                    158:        asm("   .double p_glbl,0,0xf00000,0");
                    159:        asm("   .org    0x30");
                    160:        asm(".xstart:");
                    161:        asm("   adjspb  $8");
                    162:        asm("   movd    8(sp),0(sp)     # argc");
                    163:        asm("   addr    12(sp),r0");
                    164:        asm("   movd    r0,4(sp)        # argv");
                    165:        asm("L1:");
                    166:        asm("   movd    r0,r1");
                    167:        asm("   addqd   $4,r0");
                    168:        asm("   cmpqd   $0,0(r1)        # null args term ?");
                    169:        asm("   bne     L1");
                    170:        asm("   cmpd    r0,0(4(sp))     # end of 'env' or 'argv' ?");
                    171:        asm("   blt     L2");
                    172:        asm("   addqd   $-4,r0          # envp's are in list");
                    173:        asm("L2:");
                    174:        asm("   movd    r0,8(sp)        # env");
                    175:        asm("   movd    r0,@_environ    # indir is 0 if no env ; not 0 if env");
                    176:        asm("   movqd   $0,tos          # setup intermediate signal handler");
                    177:        asm("   addr    @sv,tos");
                    178:        asm("   movzwd  $sigcatchall,tos");
                    179:        asm("   jsr     @_sigvec");
                    180:        asm("   adjspb  $-12");
                    181:        asm("   jsr     @_main");
                    182:        asm("   adjspb  $-12");
                    183:        asm("   movd    r0,tos");
                    184:        asm("   jsr     @_exit");
                    185:        asm("   adjspb  $-4");
                    186:        asm("   addr    @exitsc,r0");
                    187:        asm("   svc");
                    188:        asm("   .align  4               # sigvec arg");
                    189:        asm("sv:");
                    190:        asm("   .double sigentry");
                    191:        asm("   .double 0");
                    192:        asm("   .double 0");
                    193: 
                    194:        asm("   .comm   p_glbl,1");
                    195: }
                    196: #endif /* UMAX */
                    197: 
                    198: #ifdef CRT0_DUMMIES
                    199: 
                    200: /* Define symbol "start": here; some systems want that symbol.  */
                    201: #ifdef DOT_GLOBAL_START
                    202: asm("  .text           ");
                    203: asm("  .globl start    ");
                    204: asm("  start:          ");
                    205: #endif /* DOT_GLOBAL_START */
                    206: 
                    207: #ifdef NODOT_GLOBAL_START
                    208: asm("  text            ");
                    209: asm("  global start    ");
                    210: asm("  start:          ");
                    211: #endif /* NODOT_GLOBAL_START */
                    212: 
                    213: static start1 ();
                    214: 
                    215: _start ()
                    216: {
                    217: /* On vax, nothing is pushed here  */
                    218: /* On sequent, bogus fp is pushed here  */
                    219:   start1 ();
                    220: }
                    221: 
                    222: static
                    223: start1 (CRT0_DUMMIES argc, xargv)
                    224:      int argc;
                    225:      char *xargv;
                    226: {
                    227:   register char **argv = &xargv;
                    228:   environ = argv + argc + 1;
                    229: 
                    230:   if ((char *)environ == xargv)
                    231:     environ--;
                    232:   exit (main (argc, argv, environ));
                    233: }
                    234: #else /* not CRT0_DUMMIES */
                    235: 
                    236: /* "m68k" and "m68000" both stand for m68000 processors,
                    237:    but with different program-entry conventions.
                    238:    This is a kludge.  Now that the CRT0_DUMMIES mechanism above exists,
                    239:    most of these machines could use the vax code above
                    240:    with some suitable definition of CRT0_DUMMIES.
                    241:    Then the symbol m68k could be flushed.
                    242:    But I don't want to risk breaking these machines
                    243:    in a version 17 patch release, so that change is being put off.  */
                    244: 
                    245: #ifdef m68k                    /* Can't do it all from C */
                    246:        asm ("  global  _start");
                    247:        asm ("  text");
                    248:        asm ("_start:");
                    249: #ifndef NU
                    250: #ifdef STRIDE
                    251:        asm ("  comm    havefpu%,2");
                    252: #else /* m68k, not STRIDE */
                    253:        asm ("  comm    splimit%,4");
                    254: #endif /* STRIDE */
                    255:        asm ("  global  exit");
                    256:        asm ("  text");
                    257: #ifdef STRIDE
                    258:        asm ("  trap    &3");
                    259:        asm ("  mov.w   %d0,havefpu%");
                    260: #else /* m68k, not STRIDE */
                    261:        asm ("  mov.l   %d0,splimit%");
                    262: #endif /* STRIDE */
                    263: #endif /* not NU */
                    264:        asm ("  jsr     start1");
                    265:        asm ("  mov.l   %d0,(%sp)");
                    266:        asm ("  jsr     exit");
                    267:        asm ("  mov.l   &1,%d0");       /* d0 = 1 => exit */
                    268:        asm ("  trap    &0");
                    269: #else /* m68000, not m68k */
                    270: 
                    271: #ifdef m68000
                    272: 
                    273: #ifdef ISI68K
                    274: /* Added by ESM Sun May 24 12:44:02 1987 to get new ISI library to work */
                    275: #ifdef BSD4_3
                    276: static foo () {
                    277: #endif
                    278:        asm ("  .globl  is68020");
                    279:        asm ("is68020:");
                    280: #ifndef BSD4_3
                    281:        asm ("  .long   0x00000000");
                    282:        asm ("  .long   0xffffffff");
                    283: /* End of stuff added by ESM */
                    284: #endif
                    285:        asm ("  .text");
                    286:        asm ("  .globl  __start");
                    287:        asm ("__start:");
                    288:        asm ("  .word 0");
                    289:        asm ("  link    fp,#0");
                    290:        asm ("  jbsr    _start1");
                    291:        asm ("  unlk    fp");
                    292:        asm ("  rts");
                    293: #ifdef BSD4_3
                    294:       }
                    295: #endif
                    296: #else /* not ISI68K */
                    297: 
                    298: _start ()
                    299: {
                    300: /* On 68000, _start pushes a6 onto stack  */
                    301:   start1 ();
                    302: }
                    303: #endif /* not ISI68k */
                    304: #endif /* m68000 */
                    305: #endif /* m68k */
                    306: 
                    307: #if defined(m68k) || defined(m68000)
                    308: /* ignore takes care of skipping the a6 value pushed in start.  */
                    309: static
                    310: #if defined(m68k)
                    311: start1 (argc, xargv)
                    312: #else
                    313: start1 (ignore, argc, xargv)
                    314: #endif
                    315:      int argc;
                    316:      char *xargv;
                    317: {
                    318:   register char **argv = &xargv;
                    319:   environ = argv + argc + 1;
                    320: 
                    321:   if ((char *)environ == xargv)
                    322:     environ--;
                    323:   exit (main (argc, argv, environ));
                    324: }
                    325: 
                    326: #endif /* m68k or m68000 */
                    327: 
                    328: #endif /* not CRT0_DUMMIES */
                    329: 
                    330: #ifdef hp9000s300
                    331: int argc_value;
                    332: char **argv_value;
                    333: #ifdef OLD_HP_ASSEMBLER
                    334:        asm("   text");
                    335:        asm("   globl __start");
                    336:        asm("   globl _exit");
                    337:        asm("   globl _main");
                    338:        asm("__start");
                    339:        asm("   dc.l    0");
                    340:        asm("   subq.w  #0x1,d0");
                    341:        asm("   move.w  d0,float_soft");
                    342:        asm("   move.l  0x4(a7),d0");
                    343:        asm("   beq.s   skip_1");
                    344:        asm("   move.l  d0,a0");
                    345:        asm("   clr.l   -0x4(a0)");
                    346:        asm("skip_1");
                    347:        asm("   move.l  a7,a0");
                    348:        asm("   subq.l  #0x8,a7");
                    349:        asm("   move.l  (a0),(a7)");
                    350:        asm("   move.l  (a0),_argc_value");
                    351:        asm("   addq.l  #0x4,a0");
                    352:        asm("   move.l  a0,0x4(a7)");
                    353:        asm("   move.l  a0,_argv_value");
                    354:        asm("incr_loop");
                    355:        asm("   tst.l   (a0)+");
                    356:        asm("   bne.s   incr_loop");
                    357:        asm("   move.l  0x4(a7),a1");
                    358:        asm("   cmp.l   (a1),a0");
                    359:        asm("   blt.s   skip_2");
                    360:        asm("   subq.l  #0x4,a0");
                    361:        asm("skip_2");
                    362:        asm("   move.l  a0,0x8(a7)");
                    363:        asm("   move.l  a0,_environ");
                    364:        asm("   jsr     _main");
                    365:        asm("   addq.l  #0x8,a7");
                    366:        asm("   move.l  d0,-(a7)");
                    367:        asm("   jsr     _exit");
                    368:        asm("   move.w  #0x1,d0");
                    369:        asm("   trap    #0x0");
                    370:        asm("   comm    float_soft,4");
                    371: /* float_soft is allocated in this way because C would
                    372:    put an underscore character in its name otherwise. */
                    373: 
                    374: #else /* new hp assembler */
                    375: 
                    376:        asm("   text");
                    377:         asm("   global  float_loc");
                    378:         asm("   set     float_loc,0xFFFFB000");
                    379:        asm("   global  fpa_loc");
                    380:        asm("   set     fpa_loc,0xfff08000");
                    381:        asm("   global  __start");
                    382:        asm("   global  _exit");
                    383:        asm("   global  _main");
                    384:        asm("__start:");
                    385:        asm("   byte    0,0,0,0");
                    386:        asm("   subq.w  &1,%d0");
                    387:        asm("   mov.w   %d0,float_soft");
                    388:        asm("   mov.w   %d1,flag_68881");
                    389: #ifndef HPUX_68010
                    390:        asm("   beq.b   skip_float");
                    391:        asm("   fmov.l  &0x7400,%fpcr");
                    392: /*     asm("   fmov.l  &0x7480,%fpcr"); */
                    393: #endif /* HPUX_68010 */
                    394:        asm("skip_float:");
                    395:        asm("   mov.l   %a0,%d0");
                    396:        asm("   add.l   %d0,%d0");
                    397:        asm("   subx.w  %d1,%d1");
                    398:        asm("   mov.w   %d1,flag_68010");
                    399:        asm("   add.l   %d0,%d0");
                    400:        asm("   subx.w  %d1,%d1");
                    401:        asm("   mov.w   %d1,flag_fpa");
                    402:        asm("   tst.l   %d2");
                    403:        asm("   ble.b   skip_3");
                    404:        asm("   lsl     flag_68881");
                    405:        asm("   lsl     flag_fpa");
                    406:        asm("skip_3:");
                    407:        asm("   mov.l   4(%a7),%d0");
                    408:        asm("   beq.b   skip_1");
                    409:        asm("   mov.l   %d0,%a0");
                    410:        asm("   clr.l   -4(%a0)");
                    411:        asm("skip_1:");
                    412:        asm("   mov.l   %a7,%a0");
                    413:        asm("   subq.l  &8,%a7");
                    414:        asm("   mov.l   (%a0),(%a7)");
                    415:        asm("   mov.l   (%a0),_argc_value");
                    416:        asm("   addq.l  &4,%a0");
                    417:        asm("   mov.l   %a0,4(%a7)");
                    418:        asm("   mov.l   %a0,_argv_value");
                    419:        asm("incr_loop:");
                    420:        asm("   tst.l   (%a0)+");
                    421:        asm("   bne.b   incr_loop");
                    422:        asm("   mov.l   4(%a7),%a1");
                    423:        asm("   cmp.l   %a0,(%a1)");
                    424:        asm("   blt.b   skip_2");
                    425:        asm("   subq.l  &4,%a0");
                    426:        asm("skip_2:");
                    427:        asm("   mov.l   %a0,8(%a7)");
                    428:        asm("   mov.l   %a0,_environ");
                    429:        asm("   jsr     _main");
                    430:        asm("   addq.l  &8,%a7");
                    431:        asm("   mov.l   %d0,-(%a7)");
                    432:        asm("   jsr     _exit");
                    433:        asm("   mov.w   &1,%d0");
                    434:        asm("   trap    &0");
                    435:        asm("   comm    float_soft, 4");
                    436:        asm("   comm    flag_68881, 4");
                    437:        asm("   comm    flag_68010, 4");
                    438:        asm("   comm    flag_fpa, 4");
                    439: 
                    440: #endif /* new hp assembler */
                    441: #endif /* hp9000s300 */
                    442: 
                    443: #ifdef GOULD
                    444: 
                    445: /* startup code has to be in near text rather
                    446:    than fartext as allocated by the C compiler. */
                    447:        asm("   .text");
                    448:        asm("   .align  2");
                    449:        asm("   .globl  __start");
                    450:        asm("   .text");
                    451:        asm("__start:");
                    452: /* setup base register b1 (function base). */
                    453:        asm("   .using  b1,.");
                    454:        asm("   tpcbr   b1");
                    455: /* setup base registers b3 through b7 (data references). */
                    456:        asm("   file    basevals,b3");
                    457: /* setup base register b2 (stack pointer); it should be
                    458:    aligned on a 8-word boundary; but because it is pointing
                    459:    to argc, its value should be remembered (in r5). */
                    460:        asm("   movw    b2,r4");
                    461:        asm("   movw    b2,r5");
                    462:        asm("   andw    #~0x1f,r4");
                    463:        asm("   movw    r4,b2");
                    464: /* allocate stack frame to do some work. */
                    465:        asm("   subea   16w,b2");
                    466: /* initialize signal catching for UTX/32 1.2; this is
                    467:    necessary to make restart from saved image work. */
                    468:        asm("   movea   sigcatch,r1");
                    469:        asm("   movw    r1,8w[b2]");
                    470:        asm("   svc     #1,#150");
                    471: /* setup address of argc for start1. */
                    472:        asm("   movw    r5,8w[b2]");
                    473:        asm("   func    #1,_start1");
                    474:        asm("   halt");
                    475: /* space for ld to store base register initial values. */
                    476:        asm("   .align  5");
                    477:        asm("basevals:");
                    478:        asm("   .word   __base3,__base4,__base5,__base6,__base7");
                    479: 
                    480: static
                    481: start1 (xargc)
                    482:      int *xargc;
                    483: {
                    484:   register int argc;
                    485:   register char **argv;
                    486: 
                    487:   argc = *xargc;
                    488:   argv = (char **)(xargc) + 1;
                    489:   environ = argv + argc + 1;
                    490: 
                    491:   if (environ == argv)
                    492:     environ--;
                    493:   exit (main (argc, argv, environ));
                    494: 
                    495: }
                    496: 
                    497: #endif /* GOULD */
                    498: 
                    499: #ifdef elxsi
                    500: extern int errno;
                    501: extern char **environ;
                    502: 
                    503: _start()
                    504: {
                    505:   register int r;
                    506: 
                    507:   errno = 0;
                    508:   environ = *(&environ + 8);
                    509:   _stdinit();
                    510:   r = main(*(&environ + 6), *(&environ + 7), environ);
                    511:   exit(r);
                    512:   _exit(r);
                    513: }
                    514: #endif /* elxsi */
                    515: 
                    516: 
                    517: #ifdef sparc
                    518: asm (".global __start");
                    519: asm (".text");
                    520: asm ("__start:");
                    521: asm (" mov     0, %fp");
                    522: asm (" ld      [%sp + 64], %o0");
                    523: asm (" add     %sp, 68, %o1");
                    524: asm (" sll     %o0, 2, %o2");
                    525: asm (" add     %o2, 4, %o2");
                    526: asm (" add     %o1, %o2, %o2");
                    527: asm (" sethi   %hi(_environ), %o3");
                    528: asm (" st      %o2, [%o3+%lo(_environ)]");
                    529: asm (" andn    %sp, 7, %sp");
                    530: asm (" call    _main");
                    531: asm (" sub     %sp, 24, %sp");
                    532: asm (" call    __exit");
                    533: asm (" nop");
                    534: 
                    535: #endif /* sparc */

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.