(linenum→info "unix/slp.c:2238")

emacs/22.1/src/ecrt0.c

    1: /* C code startup routine.
    2:    Copyright (C) 1985, 1986, 1992, 2001, 2002, 2003, 2004,
    3:                  2005, 2006, 2007 Free Software Foundation, Inc.
    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
    9: the Free Software Foundation; either version 2, or (at your option)
   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
   19: the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
   20: Boston, MA 02110-1301, USA.  */
   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_();
  352: #endif
  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