home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 5 Edit / 05-Edit.zip / e20313sr.zip / emacs / 20.3.1 / src / ecrt0.c < prev    next >
C/C++ Source or Header  |  1999-07-31  |  16KB  |  615 lines

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