428
+ − 1 /* C code startup routine.
+ − 2 Copyright (C) 1985, 1986, 1992, 1993 Free Software Foundation, Inc.
+ − 3
+ − 4 This file is part of XEmacs.
+ − 5
+ − 6 XEmacs is free software; you can redistribute it and/or modify it
+ − 7 under the terms of the GNU General Public License as published by the
+ − 8 Free Software Foundation; either version 2, or (at your option) any
+ − 9 later version.
+ − 10
+ − 11 XEmacs is distributed in the hope that it will be useful, but WITHOUT
+ − 12 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ − 13 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ − 14 for more details.
+ − 15
+ − 16 You should have received a copy of the GNU General Public License
+ − 17 along with XEmacs; 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 /* Synched up with: FSF 19.30. */
+ − 22
+ − 23
771
+ − 24 /* [[The standard Vax 4.2 Unix crt0.c cannot be used for Emacs
428
+ − 25 because it makes `environ' an initialized variable.
+ − 26 It is easiest to have a special crt0.c on all machines
771
+ − 27 though I don't know whether other machines actually need it.]]
+ − 28 This is insane! We DO NOT want to be doing this crap. */
428
+ − 29
+ − 30 /* On the vax and 68000, in BSD4.2 and USG5.2,
+ − 31 this is the data format on startup:
+ − 32 (vax) ap and fp are unpredictable as far as I know; don't use them.
+ − 33 sp -> word containing argc
+ − 34 word pointing to first arg string
+ − 35 [word pointing to next arg string]... 0 or more times
+ − 36 0
+ − 37 Optionally:
+ − 38 [word pointing to environment variable]... 1 or more times
+ − 39 ...
+ − 40 0
+ − 41 And always:
+ − 42 first arg string
+ − 43 [next arg string]... 0 or more times
+ − 44 */
+ − 45
+ − 46 /* On the 16000, at least in the one 4.2 system I know about,
+ − 47 the initial data format is
+ − 48 sp -> word containing argc
+ − 49 word containing argp
+ − 50 word pointing to first arg string, and so on as above
+ − 51 */
+ − 52
+ − 53 #ifdef emacs
+ − 54 #include <config.h>
+ − 55 #endif
+ − 56
+ − 57 #ifdef __GNUC__
+ − 58 #define asm __asm
+ − 59 #endif
+ − 60
+ − 61 /* Workaround for Sun cc 3.0, which doesn't handle asm's outside a fn. */
+ − 62 #if __SUNPRO_C >= 0x300
+ − 63 #define no_toplevel_asm
+ − 64 #endif
+ − 65
+ − 66 /* ******** WARNING ********
+ − 67 Do not insert any data definitions before data_start!
+ − 68 Since this is the first file linked, the address of the following
+ − 69 variable should correspond to the start of initialized data space.
+ − 70 On some systems this is a constant that is independent of the text
+ − 71 size for shared executables. On others, it is a function of the
+ − 72 text size. In short, this seems to be the most portable way to
+ − 73 discover the start of initialized data space dynamically at runtime,
+ − 74 for either shared or unshared executables, on either swapping or
+ − 75 virtual systems. It only requires that the linker allocate objects
+ − 76 in the order encountered, a reasonable model for most Unix systems.
+ − 77 Similarly, note that the address of _start() should be the start
+ − 78 of text space. Fred Fish, UniSoft Systems Inc. */
+ − 79
+ − 80 int data_start = 0;
+ − 81
+ − 82 #ifdef NEED_ERRNO
+ − 83 int errno;
+ − 84 #endif
+ − 85
+ − 86 char **environ;
+ − 87
+ − 88 #ifndef static
+ − 89 /* On systems where the static storage class is usable, this function
+ − 90 should be declared as static. Otherwise, the static keyword has
+ − 91 been defined to be something else, and code for those systems must
+ − 92 take care of this declaration appropriately. */
+ − 93 static start1 ();
+ − 94 #endif
+ − 95
+ − 96 #ifdef CRT0_DUMMIES
+ − 97
+ − 98 /* Define symbol "start": here; some systems want that symbol. */
+ − 99 #ifdef DOT_GLOBAL_START
+ − 100 asm(" .text ");
+ − 101 asm(" .globl start ");
+ − 102 asm(" start: ");
+ − 103 #endif /* DOT_GLOBAL_START */
+ − 104
+ − 105 #ifdef NODOT_GLOBAL_START
+ − 106 asm(" text ");
+ − 107 asm(" global start ");
+ − 108 asm(" start: ");
+ − 109 #endif /* NODOT_GLOBAL_START */
+ − 110
+ − 111 #ifdef m68000
+ − 112
+ − 113 /* GCC 2.1, when optimization is turned off, seems to want to push a
+ − 114 word of garbage on the stack, which screws up the CRT0_DUMMIES
+ − 115 hack. So we hand-code _start in assembly language. */
+ − 116 asm(".text ");
+ − 117 #ifndef sony_news
+ − 118 asm(" .even ");
+ − 119 #else /* sony_news (not gas) */
+ − 120 + asm(" .align 2 ");
+ − 121 #endif /* sony_news (not gas) */
+ − 122 asm(".globl __start ");
+ − 123 asm("__start: ");
+ − 124 asm(" link a6,#0 ");
+ − 125 asm(" jbsr _start1 ");
+ − 126 asm(" unlk a6 ");
+ − 127 asm(" rts ");
+ − 128
+ − 129 #else /* not m68000 */
+ − 130
+ − 131 int
+ − 132 _start ()
+ − 133 {
+ − 134 start1 ();
+ − 135 }
+ − 136
+ − 137 #endif /* possibly m68000 */
+ − 138
+ − 139 #ifdef __bsdi__ /* for version number */
+ − 140 #include <sys/param.h>
+ − 141 #endif
+ − 142 #if defined(_BSDI_VERSION) && (_BSDI_VERSION >= 199501)
+ − 143 char *__progname;
+ − 144 #endif
+ − 145 static int
+ − 146 start1 (CRT0_DUMMIES int argc, char *xargv)
+ − 147 {
+ − 148 char **argv = &xargv;
+ − 149 environ = argv + argc + 1;
+ − 150 #if defined(_BSDI_VERSION) && (_BSDI_VERSION >= 199501)
+ − 151 __progname = argv[0];
+ − 152 #endif
+ − 153
+ − 154 if ((char *)environ == xargv)
+ − 155 environ--;
+ − 156 exit (main (argc, argv, environ));
+ − 157
+ − 158 /* Refer to `start1' so GCC will not think it is never called
+ − 159 and optimize it out. */
+ − 160 (void) &start1;
+ − 161 }
+ − 162 #else /* not CRT0_DUMMIES */
+ − 163
+ − 164 /* "m68k" and "m68000" both stand for m68000 processors,
+ − 165 but with different program-entry conventions.
+ − 166 This is a kludge. Now that the CRT0_DUMMIES mechanism above exists,
+ − 167 most of these machines could use the vax code above
+ − 168 with some suitable definition of CRT0_DUMMIES.
+ − 169 Then the symbol m68k could be flushed.
+ − 170 But I don't want to risk breaking these machines
+ − 171 in a version 17 patch release, so that change is being put off. */
+ − 172
+ − 173 #ifdef m68k /* Can't do it all from C */
+ − 174 asm (" global _start");
+ − 175 asm (" text");
+ − 176 asm ("_start:");
+ − 177 #ifndef NU
+ − 178 #ifdef STRIDE
+ − 179 asm (" comm havefpu%,2");
+ − 180 #else /* m68k, not STRIDE */
+ − 181 asm (" comm splimit%,4");
+ − 182 #endif /* STRIDE */
+ − 183 asm (" global exit");
+ − 184 asm (" text");
+ − 185 #ifdef STRIDE
+ − 186 asm (" trap &3");
+ − 187 asm (" mov.w %d0,havefpu%");
+ − 188 #else /* m68k, not STRIDE */
+ − 189 asm (" mov.l %d0,splimit%");
+ − 190 #endif /* STRIDE */
+ − 191 #endif /* not NU */
+ − 192 asm (" jsr start1");
+ − 193 asm (" mov.l %d0,(%sp)");
+ − 194 asm (" jsr exit");
+ − 195 asm (" mov.l &1,%d0"); /* d0 = 1 => exit */
+ − 196 asm (" trap &0");
+ − 197 #else /* m68000, not m68k */
+ − 198
+ − 199 #ifdef m68000
+ − 200 _start ()
+ − 201 {
+ − 202 #ifdef sun
+ − 203 finitfp_();
+ − 204 #endif
+ − 205 /* On 68000, _start pushes a6 onto stack */
+ − 206 start1 ();
+ − 207 }
+ − 208 #endif /* m68000 */
+ − 209 #endif /* m68k */
+ − 210
+ − 211 #if defined(m68k) || defined(m68000)
+ − 212 /* ignore takes care of skipping the a6 value pushed in start. */
+ − 213 static
+ − 214 #if defined(m68k)
+ − 215 start1 (argc, xargv)
+ − 216 #else
+ − 217 start1 (ignore, argc, xargv)
+ − 218 #endif
+ − 219 int argc;
+ − 220 char *xargv;
+ − 221 {
+ − 222 char **argv = &xargv;
+ − 223 environ = argv + argc + 1;
+ − 224
+ − 225 if ((char *)environ == xargv)
+ − 226 environ--;
+ − 227 #ifdef sun_68881
+ − 228 asm(" jsr f68881_used");
+ − 229 #endif
+ − 230 #ifdef sun_fpa
+ − 231 asm(" jsr ffpa_used");
+ − 232 #endif
+ − 233 #ifdef sun_soft
+ − 234 asm(" jsr start_float");
+ − 235 #endif
+ − 236 exit (main (argc, argv, environ));
+ − 237 }
+ − 238
+ − 239 #endif /* m68k or m68000 */
+ − 240
+ − 241 #endif /* not CRT0_DUMMIES */
+ − 242
+ − 243 #ifdef sparc
+ − 244 #ifdef no_toplevel_asm
+ − 245 static no_toplevel_asm_wrapper() {
+ − 246 #ifdef USG5_4
+ − 247 asm (".pushsection \".text\"");
+ − 248 #endif /* USG5_4 */
+ − 249 #endif /* no_toplevel_asm */
+ − 250 #ifdef USG5_4
+ − 251 asm (".global _start");
+ − 252 asm (".text");
+ − 253 asm ("_start:");
+ − 254 asm (" mov 0, %fp");
+ − 255 asm (" ld [%sp + 64], %o0");
+ − 256 asm (" add %sp, 68, %o1");
+ − 257 asm (" sll %o0, 2, %o2");
+ − 258 asm (" add %o2, 4, %o2");
+ − 259 asm (" add %o1, %o2, %o2");
+ − 260 asm (" sethi %hi(_environ), %o3");
+ − 261 asm (" st %o2, [%o3+%lo(_environ)]");
+ − 262 asm (" andn %sp, 7, %sp");
+ − 263 asm (" call main");
+ − 264 asm (" sub %sp, 24, %sp");
+ − 265 asm (" call _exit");
+ − 266 asm (" nop");
+ − 267 #else
+ − 268 asm (".global __start");
+ − 269 asm (".text");
+ − 270 asm ("__start:");
+ − 271 asm (" mov 0, %fp");
+ − 272 asm (" ld [%sp + 64], %o0");
+ − 273 asm (" add %sp, 68, %o1");
+ − 274 asm (" sll %o0, 2, %o2");
+ − 275 asm (" add %o2, 4, %o2");
+ − 276 asm (" add %o1, %o2, %o2");
+ − 277 asm (" sethi %hi(_environ), %o3");
+ − 278 asm (" st %o2, [%o3+%lo(_environ)]");
+ − 279 asm (" andn %sp, 7, %sp");
+ − 280 asm (" call _main");
+ − 281 asm (" sub %sp, 24, %sp");
+ − 282 asm (" call __exit");
+ − 283 asm (" nop");
+ − 284 #endif /* USG5_4 */
+ − 285 #ifdef no_toplevel_asm
+ − 286 #ifdef USG5_4
+ − 287 asm (".popsection");
+ − 288 #endif /* USG5_4 */
+ − 289 } /* no_toplevel_asm_wrapper() */
+ − 290 #endif /* no_toplevel_asm */
+ − 291 #endif /* sparc */
+ − 292
+ − 293 #if __FreeBSD__ == 2
+ − 294 char *__progname;
+ − 295 #endif
+ − 296 #ifdef __bsdi__
+ − 297 #include <sys/param.h> /* for version number */
+ − 298 #if defined(_BSDI_VERSION) && (_BSDI_VERSION >= 199501)
+ − 299 char *__progname;
+ − 300 #endif
+ − 301 #endif /* __bsdi__ */