1: /* C code startup routine. 2: Copyright (C) 1985 Richard M. Stallman 3: 4: This program is distributed in the hope that it will be useful, 5: but without any warranty. No author or distributor 6: accepts responsibility to anyone for the consequences of using it 7: or for whether it serves any particular purpose or works at all, 8: unless he says so in writing. 9: 10: Permission is granted to anyone to distribute verbatim copies 11: of this program's source code as received, in any medium, provided that 12: the copyright notice, the nonwarraty notice above 13: and this permission notice are preserved, 14: and that the distributor grants the recipient all rights 15: for further redistribution as permitted by this notice, 16: and informs him of these rights. 17: 18: Permission is granted to distribute modified versions of this 19: program's source code, or of portions of it, under the above 20: conditions, plus the conditions that all changed files carry 21: prominent notices stating who last changed them and that the 22: derived material, including anything packaged together with it and 23: conceptually functioning as a modification of it rather than an 24: application of it, is in its entirety subject to a permission 25: notice identical to this one. 26: 27: Permission is granted to distribute this program (verbatim or 28: as modified) in compiled or executable form, provided verbatim 29: redistribution is permitted as stated above for source code, and 30: A. it is accompanied by the corresponding machine-readable 31: source code, under the above conditions, or 32: B. it is accompanied by a written offer, with no time limit, 33: to distribute the corresponding machine-readable source code, 34: under the above conditions, to any one, in return for reimbursement 35: of the cost of distribution. Verbatim redistribution of the 36: written offer must be permitted. Or, 37: C. it is distributed by someone who received only the 38: compiled or executable form, and is accompanied by a copy of the 39: written offer of source code which he received along with it. 40: 41: Permission is granted to distribute this program (verbatim or as modified) 42: in executable form as part of a larger system provided that the source 43: code for this program, including any modifications used, 44: is also distributed or offered as stated in the preceding paragraph. 45: 46: In other words, you are welcome to use, share and improve this program. 47: You are forbidden to forbid anyone else to use, share and improve 48: what you give them. Help stamp out software-hoarding! */ 49: 50: 51: /* The standard Vax 4.2 Unix crt0.c cannot be used for Emacs 52: because it makes `envron' an initialized variable. 53: It is easiest to have a special crt0.c on all machines 54: though I don't know whether other machines actually need it. */ 55: 56: /* On the vax and 68000, in BSD4.2 and USG5.2, 57: this is the data format on startup: 58: (vax) ap and fp are unpredictable as far as I know; don't use them. 59: sp -> word containing argc 60: word pointing to first arg string 61: [word pointing to next arg string]... 0 or more times 62: 0 63: Optionally: 64: [word pointing to environment variable]... 1 or more times 65: ... 66: 0 67: And always: 68: first arg string 69: [next arg string]... 0 or more times 70: */ 71: 72: /* On the 16000, at least in the one 4.2 system I know about, 73: the initial data format is 74: sp -> word containing argc 75: word containing argp 76: word pointing to first arg string, and so on as above 77: */ 78: 79: #include "config.h" 80: 81: /* ******** WARNING ******** 82: Do not insert any data definitions before data_start! 83: Since this is the first file linked, the address of the following 84: variable should correspond to the start of initialized data space. 85: On some systems this is a constant that is independent of the text 86: size for shared executables. On others, it is a function of the 87: text size. In short, this seems to be the most portable way to 88: discover the start of initialized data space dynamically at runtime, 89: for either shared or unshared executables, on either swapping or 90: virtual systems. It only requires that the linker allocate objects 91: in the order encountered, a reasonable model for most Unix systems. 92: Similarly, note that the address of _start() should be the start 93: of text space. Fred Fish, UniSoft Systems Inc. */ 94: 95: int data_start = 0; 96: 97: #ifdef NEED_ERRNO 98: int errno = 0; 99: #endif 100: 101: char **environ; 102: 103: #if defined(orion) || defined(pyramid) || defined (celerity) 104: 105: _start (argc, argv, envp) 106: int argc; 107: char **argv, **envp; 108: { 109: environ = envp; 110: 111: exit (main (argc, argv, envp)); 112: } 113: 114: #endif /* orion or pyramid or celerity */ 115: 116: #if defined (ns16000) && !defined (sequent) && !defined (UMAX) 117: 118: _start () 119: { 120: /* On 16000, _start pushes fp onto stack */ 121: start1 (); 122: } 123: 124: /* ignore takes care of skipping the fp value pushed in start. */ 125: static 126: start1 (ignore, argc, argv) 127: int ignore; 128: int argc; 129: register char **argv; 130: { 131: environ = argv + argc + 1; 132: 133: if (environ == *argv) 134: environ--; 135: exit (main (argc, argv, environ)); 136: } 137: #endif /* ns16000, not sequent and not UMAX */ 138: 139: #ifdef UMAX 140: _start() 141: { 142: asm(" exit [] # undo enter"); 143: asm(" .set exitsc,1"); 144: asm(" .set sigcatchall,0x400"); 145: 146: asm(" .globl _exit"); 147: asm(" .globl start"); 148: asm(" .globl __start"); 149: asm(" .globl _main"); 150: asm(" .globl _environ"); 151: asm(" .globl _sigvec"); 152: asm(" .globl sigentry"); 153: 154: asm("start:"); 155: asm(" br .xstart"); 156: asm(" .org 0x20"); 157: asm(" .double p_glbl,0,0xf00000,0"); 158: asm(" .org 0x30"); 159: asm(".xstart:"); 160: asm(" adjspb $8"); 161: asm(" movd 8(sp),0(sp) # argc"); 162: asm(" addr 12(sp),r0"); 163: asm(" movd r0,4(sp) # argv"); 164: asm("L1:"); 165: asm(" movd r0,r1"); 166: asm(" addqd $4,r0"); 167: asm(" cmpqd $0,0(r1) # null args term ?"); 168: asm(" bne L1"); 169: asm(" cmpd r0,0(4(sp)) # end of 'env' or 'argv' ?"); 170: asm(" blt L2"); 171: asm(" addqd $-4,r0 # envp's are in list"); 172: asm("L2:"); 173: asm(" movd r0,8(sp) # env"); 174: asm(" movd r0,@_environ # indir is 0 if no env ; not 0 if env"); 175: asm(" movqd $0,tos # setup intermediate signal handler"); 176: asm(" addr @sv,tos"); 177: asm(" movzwd $sigcatchall,tos"); 178: asm(" jsr @_sigvec"); 179: asm(" adjspb $-12"); 180: asm(" jsr @_main"); 181: asm(" adjspb $-12"); 182: asm(" movd r0,tos"); 183: asm(" jsr @_exit"); 184: asm(" adjspb $-4"); 185: asm(" addr @exitsc,r0"); 186: asm(" svc"); 187: asm(" .align 4 # sigvec arg"); 188: asm("sv:"); 189: asm(" .double sigentry"); 190: asm(" .double 0"); 191: asm(" .double 0"); 192: 193: asm(" .comm p_glbl,1"); 194: } 195: #endif /* UMAX */ 196: 197: #if defined(vax) || defined(tahoe) || defined (sequent) || defined (BOGUS) 198: 199: #ifdef sequent 200: #define BOGUS bogus_fp, 201: #endif /* sequent */ 202: 203: #ifdef vax 204: #define BOGUS 205: #endif /* vax */ 206: 207: #ifdef tahoe 208: #define BOGUS 209: #endif /* tahoe */ 210: 211: /* Define symbol "start": here; some systems want that symbol. */ 212: #ifdef tower32 213: asm(" text "); 214: asm(" global start "); 215: #else 216: asm(" .text "); 217: asm(" .globl start "); 218: #endif 219: asm(" start: "); 220: 221: _start () 222: { 223: /* On vax, nothing is pushed here */ 224: /* On sequent, bogus fp is pushed here */ 225: start1 (); 226: } 227: 228: static 229: start1 (BOGUS argc, xargv) 230: int argc; 231: char *xargv; 232: { 233: register char **argv = &xargv; 234: environ = argv + argc + 1; 235: 236: if ((char *)environ == xargv) 237: environ--; 238: exit (main (argc, argv, environ)); 239: } 240: #else /* not vax or tahoe or sequent or BOGUS */ 241: 242: /* "m68k" and "m68000" both stand for m68000 processors, 243: but with different program-entry conventions. 244: This is a kludge. Now that the BOGUS mechanism above exists, 245: most of these machines could use the vax code above 246: with some suitable definition of BOGUS. 247: Then the symbol m68k could be flushed. 248: But I don't want to risk breaking these machines 249: in a version 17 patch release, so that change is being put off. */ 250: 251: #ifdef m68k /* Can't do it all from C */ 252: #ifdef STRIDE 253: asm (" comm havefpu%,2"); 254: #else /* m68k, not STRIDE */ 255: asm (" data"); 256: asm (" even"); 257: asm (" global splimit%"); 258: asm ("splimit%:"); 259: asm (" space 4"); 260: #endif /* STRIDE */ 261: asm (" global _start"); 262: asm (" global exit"); 263: asm (" text"); 264: asm ("_start:"); 265: #ifdef STRIDE 266: asm (" trap &3"); 267: asm (" mov.w %d0,havefpu%"); 268: #else /* m68k, not STRIDE */ 269: asm (" mov.l %d0,splimit%"); 270: #endif /* STRIDE */ 271: asm (" jsr start1"); 272: asm (" mov.l %d0,(%sp)"); 273: asm (" jsr exit"); 274: asm (" mov.l &1,%d0"); /* d0 = 1 => exit */ 275: asm (" trap &0"); 276: #else /* m68000, not m68k */ 277: 278: #ifdef m68000 279: 280: _start () 281: { 282: /* On 68000, _start pushes a6 onto stack */ 283: start1 (); 284: } 285: #endif /* m68000 */ 286: #endif /* m68k */ 287: 288: #if defined(m68k) || defined(m68000) 289: /* ignore takes care of skipping the a6 value pushed in start. */ 290: static 291: #ifdef m68k 292: start1 (argc, xargv) 293: #else 294: start1 (ignore, argc, xargv) 295: #endif 296: int argc; 297: char *xargv; 298: { 299: register char **argv = &xargv; 300: environ = argv + argc + 1; 301: 302: if ((char *)environ == xargv) 303: environ--; 304: #ifdef sun2 305: hack_sky(); 306: #endif /* sun2 */ 307: exit (main (argc, argv, environ)); 308: } 309: 310: #endif /* m68k or m68000 */ 311: 312: #endif /* not vax or tahoe or sequent or BOGUS */ 313: 314: #ifdef hp9000s200 315: int argc_value; 316: char **argv_value; 317: 318: asm(" text"); 319: asm(" globl __start"); 320: asm(" globl _exit"); 321: asm(" globl _main"); 322: asm("__start"); 323: asm(" dc.l 0"); 324: asm(" subq.w #0x1,d0"); 325: asm(" move.w d0,float_soft"); 326: asm(" move.l 0x4(a7),d0"); 327: asm(" beq.s skip_1"); 328: asm(" move.l d0,a0"); 329: asm(" clr.l -0x4(a0)"); 330: asm("skip_1"); 331: asm(" move.l a7,a0"); 332: asm(" subq.l #0x8,a7"); 333: asm(" move.l (a0),(a7)"); 334: asm(" move.l (a0),_argc_value"); 335: asm(" addq.l #0x4,a0"); 336: asm(" move.l a0,0x4(a7)"); 337: asm(" move.l a0,_argv_value"); 338: asm("incr_loop"); 339: asm(" tst.l (a0)+"); 340: asm(" bne.s incr_loop"); 341: asm(" move.l 0x4(a7),a1"); 342: asm(" cmp.l (a1),a0"); 343: asm(" blt.s skip_2"); 344: asm(" subq.l #0x4,a0"); 345: asm("skip_2"); 346: asm(" move.l a0,0x8(a7)"); 347: asm(" move.l a0,_environ"); 348: asm(" jsr _main"); 349: asm(" addq.l #0x8,a7"); 350: asm(" move.l d0,-(a7)"); 351: asm(" jsr _exit"); 352: asm(" move.w #0x1,d0"); 353: asm(" trap #0x0"); 354: asm(" comm float_soft,4"); 355: /* float_soft is allocated in this way because C would 356: put an underscore character in its name otherwise. */ 357: #endif /* hp9000s200 */