home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Source Code 1993 July / THE_SOURCE_CODE_CD_ROM.iso / gnu / lucid / lemacs-19.6 / src / crt0.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-06-29  |  13.0 KB  |  535 lines

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