Annotation of GNUtools/emacs/src/crt0.c, revision 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.