|
|
1.1 ! root 1: #ifndef lint ! 2: static char *rcsid = "$Header: /na/franz/franz/RCS/fex3.c,v 1.12 83/08/22 19:28:06 sklower Exp $"; ! 3: #endif ! 4: /* -[Sat Apr 9 17:03:02 1983 by layer]- ! 5: * fex3.c $Locker: $ ! 6: * nlambda functions ! 7: * ! 8: * (c) copyright 1982, Regents of the University of California ! 9: */ ! 10: ! 11: ! 12: #include "global.h" ! 13: extern char *gstab(); ! 14: static int pagsiz, pagrnd; ! 15: ! 16: ! 17: /* ! 18: *Ndumplisp -- create executable version of current state of this lisp. ! 19: */ ! 20: #ifndef os_vms ! 21: #include "aout.h" ! 22: ! 23: lispval ! 24: Ndumplisp() ! 25: { ! 26: register struct exec *workp; ! 27: register lispval argptr, temp; ! 28: register char *fname; ! 29: extern int reborn; ! 30: struct exec work, old; ! 31: extern int dmpmode,usehole; ! 32: extern char etext[], *curhbeg; ! 33: int descrip, des2, ax,mode; ! 34: extern int holesize; ! 35: char tbuf[BUFSIZ]; ! 36: long count, lseek(); ! 37: ! 38: ! 39: pageseql(); ! 40: pagsiz = Igtpgsz(); ! 41: pagrnd = pagsiz - 1; ! 42: ! 43: /* dump mode is kept in decimal (which looks like octal in dmpmode) ! 44: and is changeable via (sstatus dumpmode n) where n is 413 or 410 ! 45: base 10 ! 46: */ ! 47: if(dmpmode == 413) mode = 0413; ! 48: else mode = 0410; ! 49: ! 50: workp = &work; ! 51: workp->a_magic = mode; ! 52: if(holesize) { /* was ifdef HOLE */ ! 53: curhbeg = (char *) (1 + (pagrnd | ((int)curhbeg)-1)); ! 54: workp->a_text = (unsigned long)curhbeg - (unsigned long)OFFSET; ! 55: workp->a_data = (unsigned) sbrk(0) - workp->a_text - OFFSET; ! 56: } else { ! 57: workp->a_text = 1 + ((((int)etext)-1-OFFSET) | pagrnd); ! 58: workp->a_data = (int) sbrk(0) - ((int)curhbeg); ! 59: } ! 60: workp->a_bss = 0; ! 61: workp->a_syms = 0; ! 62: workp->a_entry = (unsigned) gstart(); ! 63: workp->a_trsize = 0; ! 64: workp->a_drsize = 0; ! 65: ! 66: fname = "savedlisp"; /*set defaults*/ ! 67: reborn = (int) CNIL; ! 68: argptr = lbot->val; ! 69: if (argptr != nil) { ! 70: temp = argptr->d.car; ! 71: if((TYPE(temp))==ATOM) ! 72: fname = temp->a.pname; ! 73: } ! 74: des2 = open(gstab(),0); ! 75: if(des2 >= 0) { ! 76: if(read(des2,(char *)&old,sizeof(old))>=0) ! 77: work.a_syms = old.a_syms; ! 78: } ! 79: descrip=creat(fname,0777); /*doit!*/ ! 80: if(-1==write(descrip,(char *)workp,sizeof(work))) ! 81: { ! 82: close(descrip); ! 83: error("Dumplisp header failed",FALSE); ! 84: } ! 85: if(mode == 0413) lseek(descrip,(long)pagsiz,0); ! 86: if( -1==write(descrip,(char *)nil,(int)workp->a_text) ) ! 87: { ! 88: close(descrip); ! 89: error("Dumplisp text failed",FALSE); ! 90: } ! 91: if( -1==write(descrip,(char *)curhbeg,(int)workp->a_data) ) ! 92: { ! 93: close(descrip); ! 94: error("Dumplisp data failed",FALSE); ! 95: } ! 96: if(des2>0 && work.a_syms) { ! 97: count = old.a_text + old.a_data + (old.a_magic == 0413 ? pagsiz ! 98: : sizeof(old)); ! 99: if(-1==lseek(des2,count,0)) ! 100: error("Could not seek to stab",FALSE); ! 101: for(count = old.a_syms;count > 0; count -=BUFSIZ) { ! 102: ax = read(des2,tbuf,(int)(count < BUFSIZ ? count : BUFSIZ)); ! 103: if(ax==0) { ! 104: printf("Unexpected end of syms",count); ! 105: fflush(stdout); ! 106: break; ! 107: } else if(ax > 0) ! 108: write(descrip,tbuf,ax); ! 109: else ! 110: error("Failure to write dumplisp stab",FALSE); ! 111: } ! 112: #if ! (os_unix_ts | os_unisoft) ! 113: if(-1 == lseek(des2,(long) ! 114: ((old.a_magic == 0413 ? pagsiz : sizeof(old)) ! 115: + old.a_text + old.a_data ! 116: + old.a_trsize + old.a_drsize + old.a_syms), ! 117: 0)) ! 118: error(" Could not seek to string table ",FALSE); ! 119: for( ax = 1 ; ax > 0;) { ! 120: ax = read(des2,tbuf,BUFSIZ); ! 121: if(ax > 0) ! 122: write(descrip,tbuf,ax); ! 123: else if (ax < 0) ! 124: error("Error in string table read ",FALSE); ! 125: } ! 126: #endif ! 127: } ! 128: close(descrip); ! 129: if(des2>0) close(des2); ! 130: reborn = 0; ! 131: ! 132: pagenorm(); ! 133: ! 134: return(nil); ! 135: } ! 136: ! 137: ! 138: /*** VMS version of Ndumplisp ***/ ! 139: #else ! 140: #include "aout.h" ! 141: #undef protect ! 142: #include <vms/vmsexe.h> ! 143: ! 144: lispval ! 145: Ndumplisp() ! 146: { ! 147: register struct exec *workp; ! 148: register lispval argptr, temp; ! 149: char *fname; ! 150: register ISD *Isd; ! 151: register int i; ! 152: extern lispval reborn; ! 153: struct exec work,old; ! 154: extern etext; ! 155: extern int dmpmode,holend,curhbeg,usehole,holesize; ! 156: int extra_cref_page = 0; ! 157: char *start_of_data; ! 158: int descrip, des2, count, ax,mode; ! 159: char buf[5000],stabname[100],tbuf[BUFSIZ]; ! 160: int fp,fp1; ! 161: union { ! 162: char Buffer[512]; ! 163: struct { ! 164: IHD Ihd; ! 165: IHA Iha; ! 166: IHS Ihs; ! 167: IHI Ihi; ! 168: } Header; ! 169: } Buffer; /* VMS Header */ ! 170: ! 171: /* ! 172: * Dumpmode is always 413!! ! 173: */ ! 174: mode = 0413; ! 175: pagsiz = Igtpgsz(); ! 176: pagrnd = pagsiz - 1; ! 177: ! 178: workp = &work; ! 179: workp->a_magic = mode; ! 180: if (holesize) { ! 181: workp->a_text = ! 182: ((unsigned)curhbeg) & (~pagrnd); ! 183: if (((unsigned)curhbeg) & pagrnd) extra_cref_page = 1; ! 184: start_of_data = (char *) ! 185: (((((unsigned) (&holend)) -1) & (~pagrnd)) + pagsiz); ! 186: } else { ! 187: workp->a_text = ! 188: ((((unsigned) (&etext)) -1) & (~pagrnd)) + pagsiz; ! 189: start_of_data = (char *)workp->a_text; ! 190: } ! 191: workp->a_data = ! 192: (unsigned) sbrk(0) - (unsigned)start_of_data; ! 193: workp->a_bss = 0; ! 194: workp->a_syms = 0; ! 195: workp->a_entry = (unsigned) gstart(); ! 196: workp->a_trsize = 0; ! 197: workp->a_drsize = 0; ! 198: ! 199: fname = "savedlisp"; /* set defaults */ ! 200: reborn = CNIL; ! 201: argptr = lbot->val; ! 202: if (argptr != nil) { ! 203: temp = argptr->d.car; ! 204: if((TYPE(temp))==ATOM) ! 205: fname = temp->a.pname; ! 206: } ! 207: /* ! 208: * Open the new executable file ! 209: */ ! 210: strcpy(buf,fname); ! 211: if (index(buf,'.') == 0) strcat(buf,".exe"); ! 212: if ((descrip = creat(buf,0777)) < 0) error("Dumplisp failed",FALSE); ! 213: /* ! 214: * Create the VMS header ! 215: */ ! 216: for(i = 0; i < 512; i++) Buffer.Buffer[i] = 0; /* Clear Header */ ! 217: Buffer.Header.Ihd.size = sizeof(Buffer.Header); ! 218: Buffer.Header.Ihd.activoff = sizeof(IHD); ! 219: Buffer.Header.Ihd.symdbgoff = sizeof(IHD) + sizeof(IHA); ! 220: Buffer.Header.Ihd.imgidoff = sizeof(IHD) + sizeof(IHA) + sizeof(IHS); ! 221: Buffer.Header.Ihd.majorid[0] = '0'; ! 222: Buffer.Header.Ihd.majorid[1] = '2'; ! 223: Buffer.Header.Ihd.minorid[0] = '0'; ! 224: Buffer.Header.Ihd.minorid[1] = '2'; ! 225: Buffer.Header.Ihd.imgtype = IHD_EXECUTABLE; ! 226: Buffer.Header.Ihd.privreqs[0] = -1; ! 227: Buffer.Header.Ihd.privreqs[1] = -1; ! 228: Buffer.Header.Ihd.lnkflags.nopobufs = 1; ! 229: Buffer.Header.Ihd.imgiocnt = 250; ! 230: ! 231: Buffer.Header.Iha.tfradr1 = SYS$IMGSTA; ! 232: Buffer.Header.Iha.tfradr2 = workp->a_entry; ! 233: ! 234: strcpy(Buffer.Header.Ihi.imgnam+1,"SAVEDLISP"); ! 235: Buffer.Header.Ihi.imgnam[0] = 9; ! 236: Buffer.Header.Ihi.imgid[0] = 0; ! 237: Buffer.Header.Ihi.imgid[1] = '0'; ! 238: sys$gettim(Buffer.Header.Ihi.linktime); ! 239: strcpy(Buffer.Header.Ihi.linkid+1," Opus 38"); ! 240: Buffer.Header.Ihi.linkid[0] = 8; ! 241: ! 242: Isd = (ISD *)&Buffer.Buffer[sizeof(Buffer.Header)]; ! 243: /* Text ISD */ ! 244: Isd->size = ISDSIZE_TEXT; ! 245: Isd->pagcnt = workp->a_text >> 9; ! 246: Isd->vpnpfc.vpn = 0; ! 247: Isd->flags.type = ISD_NORMAL; ! 248: Isd->vbn = 3; ! 249: Isd = (ISD *)((char *)Isd + Isd->size); ! 250: /* Hole ISDs (if necessary) */ ! 251: if (usehole) { ! 252: /* Copy on Ref ISD for possible extra text page */ ! 253: if(extra_cref_page) { ! 254: Isd->size = ISDSIZE_TEXT; ! 255: Isd->pagcnt = 1; ! 256: Isd->vpnpfc.vpn = (((unsigned)curhbeg) & (~pagrnd)) >> 9; ! 257: Isd->flags.type = ISD_NORMAL; ! 258: Isd->flags.crf = 1; ! 259: Isd->flags.wrt = 1; ! 260: Isd->vbn = (workp->a_text >> 9) + 3; ! 261: Isd = (ISD *)((char *)Isd + Isd->size); ! 262: } ! 263: /* Demand Zero ISD for rest of Hole */ ! 264: Isd->size = ISDSIZE_DZRO; ! 265: Isd->pagcnt = ! 266: ((((unsigned)&holend) ! 267: - (unsigned)curhbeg) & (~pagrnd)) >> 9; ! 268: Isd->vpnpfc.vpn = ! 269: ((((unsigned)curhbeg) & (~pagrnd)) >> 9) + extra_cref_page; ! 270: Isd->flags.type = ISD_NORMAL; ! 271: Isd->flags.dzro = 1; ! 272: Isd->flags.wrt = 1; ! 273: Isd = (ISD *)((char *)Isd + Isd->size); ! 274: } ! 275: /* Data ISD */ ! 276: Isd->size = ISDSIZE_TEXT; ! 277: Isd->pagcnt = workp->a_data >> 9; ! 278: Isd->vpnpfc.vpn = ((unsigned)start_of_data) >> 9; ! 279: Isd->flags.type = ISD_NORMAL; ! 280: Isd->flags.crf = 1; ! 281: Isd->flags.wrt = 1; ! 282: Isd->vbn = (workp->a_text >> 9) + 3; ! 283: if (holesize) { ! 284: /* ! 285: * Correct the Data ISD ! 286: */ ! 287: Isd->vbn += extra_cref_page; ! 288: } ! 289: Isd = (ISD *)((char *)Isd + Isd->size); ! 290: /* Stack ISD */ ! 291: Isd->size = ISDSIZE_DZRO; ! 292: Isd->pagcnt = ISDSTACK_SIZE; ! 293: Isd->vpnpfc.vpn = ISDSTACK_BASE; ! 294: Isd->flags.type = ISD_USERSTACK; ! 295: Isd->flags.dzro = 1; ! 296: Isd->flags.wrt = 1; ! 297: Isd = (ISD *)((char *)Isd + Isd->size); ! 298: /* End of ISD List */ ! 299: Isd->size = 0; ! 300: Isd = (ISD *)((char *)Isd + 2); ! 301: /* ! 302: * Make the rest of the header -1s ! 303: */ ! 304: for (i = ((char *)Isd - Buffer.Buffer); i < 512; i++) ! 305: Buffer.Buffer[i] = -1; ! 306: /* ! 307: * Write the VMS Header ! 308: */ ! 309: if (write(descrip,Buffer.Buffer,512) == -1) ! 310: error("Dumplisp failed",FALSE); ! 311: #if EUNICE_UNIX_OBJECT_FILE_CFASL ! 312: /* ! 313: * Get the UNIX symbol table file header ! 314: */ ! 315: des2 = open(gstab(),0); ! 316: if (des2 >= 0) { ! 317: old.a_magic = 0; ! 318: if (read(des2,(char *)&old,sizeof(old)) >= 0) { ! 319: if (N_BADMAG(old)) { ! 320: lseek(des2,512,0); /* Try block #1 */ ! 321: read(des2,(char *)&old,sizeof(old)); ! 322: } ! 323: if (!N_BADMAG(old)) work.a_syms = old.a_syms; ! 324: } ! 325: } ! 326: #endif EUNICE_UNIX_OBJECT_FILE_CFASL ! 327: /* ! 328: * Update the UNIX header so that the extra cref page is ! 329: * considered part of data space. ! 330: */ ! 331: if (extra_cref_page) work.a_data += 512; ! 332: /* ! 333: * Write the UNIX header ! 334: */ ! 335: if (write(descrip,&work,sizeof(work)) == -1) ! 336: error("Dumplisp failed",FALSE); ! 337: /* ! 338: * seek to 1024 (end of headers) ! 339: */ ! 340: if (lseek(descrip,1024,0) == -1) ! 341: error("Dumplisp failed",FALSE); ! 342: /* ! 343: * write the world ! 344: */ ! 345: if (write(descrip,0,workp->a_text) == -1) ! 346: error("Dumplisp failed",FALSE); ! 347: if (extra_cref_page) ! 348: if (write(descrip,(((unsigned)curhbeg) & pagrnd), pagsiz) == -1) ! 349: error("Dumplisp failed",FALSE); ! 350: if (write(descrip,start_of_data,workp->a_data) == -1) ! 351: error("Dumplisp failed",FALSE); ! 352: ! 353: #if !EUNICE_UNIX_OBJECT_FILE_CFASL ! 354: /* ! 355: * VMS OBJECT files: We are done with the executable file ! 356: */ ! 357: close(descrip); ! 358: /* ! 359: * Now try to write the symbol table file! ! 360: */ ! 361: strcpy(buf,gstab()); ! 362: ! 363: strcpy(stabname,fname); ! 364: if (index(stabname,'.') == 0) strcat(stabname,".stb"); ! 365: else strcpy(index(stabname,'.'), ".stb"); ! 366: ! 367: /* Use Link/Unlink to rename the symbol table */ ! 368: if (!strcmpn(gstab(),"tmp:",4)) ! 369: if (link(buf,stabname) >= 0) ! 370: if (unlink(buf) >= 0) return(nil); ! 371: ! 372: /* Copy the symbol table */ ! 373: if ((fp = open(buf,0)) < 0) ! 374: error("Symbol table file not there\n",FALSE); ! 375: fp1 = creat(stabname,0666,"var"); ! 376: while((i = read(fp,buf,5000)) > 0) ! 377: if (write(fp1,buf,i) == -1) { ! 378: close(fp); close(fp1); ! 379: error("Error writing symbol table\n",FALSE); ! 380: } ! 381: close(fp); close(fp1); ! 382: if (i < 0) error("Error reading symbol table\n",FALSE); ! 383: if (!strcmpn(gstab(),"tmp:",4)) unlink(gstab); ! 384: /* ! 385: * Done ! 386: */ ! 387: reborn = 0; ! 388: return(nil); ! 389: #else EUNICE_UNIX_OBJECT_FILE_CFASL ! 390: /* ! 391: * UNIX OBJECT files: append the new symbol table ! 392: */ ! 393: if(des2>0 && work.a_syms) { ! 394: count = old.a_text + old.a_data + (old.a_magic == 0413 ? 1024 ! 395: : sizeof(old)); ! 396: if(-1==lseek(des2,count,0)) ! 397: error("Could not seek to stab",FALSE); ! 398: for(count = old.a_syms;count > 0; count -=BUFSIZ) { ! 399: ax = read(des2,tbuf,(int)(count < BUFSIZ ? count : BUFSIZ)); ! 400: if(ax==0) { ! 401: printf("Unexpected end of syms",count); ! 402: fflush(stdout); ! 403: break; ! 404: } else if(ax > 0) ! 405: write(descrip,tbuf,ax); ! 406: else ! 407: error("Failure to write dumplisp stab",FALSE); ! 408: } ! 409: if(-1 == lseek(des2,(long) ! 410: ((old.a_magic == 0413 ? 1024 : sizeof(old)) ! 411: + old.a_text + old.a_data ! 412: + old.a_trsize + old.a_drsize + old.a_syms), ! 413: 0)) ! 414: error(" Could not seek to string table ",FALSE); ! 415: for( ax = 1 ; ax > 0;) { ! 416: ax = read(des2,tbuf,BUFSIZ); ! 417: if(ax > 0) ! 418: write(descrip,tbuf,ax); ! 419: else if (ax < 0) ! 420: error("Error in string table read ",FALSE); ! 421: } ! 422: } ! 423: close(descrip); ! 424: if(des2>0) close(des2); ! 425: reborn = 0; ! 426: ! 427: return(nil); ! 428: #endif EUNICE_UNIX_OBJECT_FILE_CFASL ! 429: } ! 430: #endif ! 431: #if (os_4_1 | os_4_1a | os_4_1c | os_4_2) ! 432: ! 433: #ifdef os_4_2 ! 434: #include <sys/vadvise.h> ! 435: #else ! 436: #include <vadvise.h> ! 437: #endif ! 438: ! 439: pagerand() { vadvise(VA_ANOM); } ! 440: pageseql() { vadvise(VA_SEQL); } ! 441: pagenorm() { vadvise(VA_NORM); } ! 442: #endif ! 443: #if (os_unisoft | os_vms) ! 444: pagerand() { } ! 445: pageseql() { } ! 446: pagenorm() { } ! 447: #endif ! 448: ! 449: /* getaddress -- ! 450: * ! 451: * (getaddress '|_entry1| 'fncname1 '|_entry2| 'fncname2 ...) ! 452: * ! 453: * binds value of symbol |_entry1| to function defition of atom fncname1, etc. ! 454: * ! 455: * returns fnc-binding of fncname1. ! 456: * ! 457: */ ! 458: #if os_unisoft || os_unix_ts ! 459: #define N_name n_name ! 460: #define STASSGN(p,q) strncpy(NTABLE[(p)].n_name,(q),8) ! 461: #else ! 462: #define N_name n_un.n_name ! 463: #define STASSGN(p,q) (NTABLE[p].N_name = (q)) ! 464: #endif ! 465: ! 466: lispval ! 467: Lgetaddress(){ ! 468: register struct argent *mlbot = lbot; ! 469: register lispval work; ! 470: register int numberofargs, i; ! 471: char ostabf[128]; ! 472: struct nlist NTABLE[100]; ! 473: lispval dispget(); ! 474: ! 475: Savestack(4); ! 476: ! 477: if(np-lbot == 2) protect(nil); /* allow 2 args */ ! 478: numberofargs = (np - lbot)/3; ! 479: if(numberofargs * 3 != np-lbot) ! 480: error("getaddress: arguments must come in triples ",FALSE); ! 481: ! 482: for ( i=0; i<numberofargs; i++,mlbot += 3) { ! 483: NTABLE[i].n_value = 0; ! 484: mlbot[0].val = verify(mlbot[0].val,"Incorrect entry specification for binding"); ! 485: STASSGN(i,(char *) mlbot[0].val); ! 486: while(TYPE(mlbot[1].val) != ATOM) ! 487: mlbot[1].val = errorh1(Vermisc, ! 488: "Bad associated atom name for binding", ! 489: nil,TRUE,0,mlbot[1].val); ! 490: mlbot[2].val = dispget(mlbot[2].val,"getaddress: Incorrect discipline specification ",(lispval)Vsubrou->a.pname); ! 491: } ! 492: STASSGN(numberofargs,""); ! 493: strcpyn(ostabf,gstab(),128); ! 494: if ( nlist(ostabf,NTABLE) == -1 ) { ! 495: errorh1(Vermisc,"Getaddress: Bad file",nil,FALSE,0,inewstr(ostabf)); ! 496: } else ! 497: for (i=0,mlbot=lbot+1; i<numberofargs; i++,mlbot+=3) { ! 498: if ( NTABLE[i].n_value == 0 ) ! 499: fprintf(stderr,"Undefined symbol: %s\n", ! 500: NTABLE[i].N_name); ! 501: else { ! 502: work= newfunct(); ! 503: work->bcd.start = (lispval (*) ())NTABLE[i].n_value; ! 504: work->bcd.discipline = mlbot[1].val; ! 505: mlbot->val->a.fnbnd = work; ! 506: } ! 507: }; ! 508: Restorestack(); ! 509: return(lbot[1].val->a.fnbnd); ! 510: }; ! 511: ! 512: Igtpgsz() ! 513: { ! 514: #if os_4_1c | os_4_2 ! 515: return(getpagesize()); ! 516: #else ! 517: #if vax_eunice_vms | os_unisoft ! 518: return(512); ! 519: #else ! 520: return(1024); ! 521: #endif ! 522: #endif ! 523: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.