home *** CD-ROM | disk | FTP | other *** search
/ OpenStep 4.2J (Developer) / os42jdev.iso / NextDeveloper / Source / GNU / emacs / src / crt0.c < prev    next >
C/C++ Source or Header  |  1992-01-28  |  13KB  |  536 lines

  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 */
  536.