|
|
1.1 ! root 1: /* ! 2: * A debugger. ! 3: * Miscellaneous routines. ! 4: */ ! 5: #include <stdio.h> ! 6: #include <ctype.h> ! 7: #include <canon.h> ! 8: #include "trace.h" ! 9: #if NOUT ! 10: #include <n.out.h> ! 11: #else ! 12: #include <l.out.h> ! 13: #endif ! 14: ! 15: /* ! 16: * Save the rest of the input line in `miscbuf'. If line is ! 17: * not given, save the default, `cp'. ! 18: */ ! 19: getline(cp) ! 20: register char *cp; ! 21: { ! 22: register int c; ! 23: register char *bp; ! 24: ! 25: bp = miscbuf; ! 26: if ((c=getn()) != '\n') { ! 27: while (c != '\n') { ! 28: if (c == '\\') ! 29: if ((c=getn())!='\n' && c!='\\') ! 30: *bp++ = '\\'; ! 31: *bp++ = c; ! 32: c = getn(); ! 33: } ! 34: } else { ! 35: while (*cp != '\0') ! 36: *bp++ = *cp++; ! 37: } ! 38: *bp++ = '\n'; ! 39: *bp = '\0'; ! 40: } ! 41: ! 42: /* ! 43: * Add a string onto the input stream. ! 44: */ ! 45: addstrp(cp) ! 46: char *cp; ! 47: { ! 48: register INP *ip; ! 49: ! 50: ip = nalloc(sizeof (INP)); ! 51: ip->i_next = inpp; ! 52: ip->i_type = ICORE; ! 53: ip->i_strp = cp; ! 54: inpp = ip; ! 55: } ! 56: ! 57: /* ! 58: * Add a file pointer onto the input stack. ! 59: */ ! 60: addfilp(fp) ! 61: FILE *fp; ! 62: { ! 63: register INP *ip; ! 64: ! 65: ip = nalloc(sizeof (INP)); ! 66: ip->i_next = inpp; ! 67: ip->i_type = IFILE; ! 68: ip->i_filp = fp; ! 69: inpp = ip; ! 70: } ! 71: ! 72: /* ! 73: * Get the next character from the input stream. ! 74: */ ! 75: getn() ! 76: { ! 77: register INP *ip; ! 78: register int c; ! 79: ! 80: if (lastc != '\0') { ! 81: c = lastc; ! 82: lastc = '\0'; ! 83: return (c); ! 84: } ! 85: while ((ip=inpp) != NULL) { ! 86: switch (ip->i_type) { ! 87: case ICORE: ! 88: if ((c=*ip->i_strp++) != '\0') ! 89: return (c); ! 90: break; ! 91: case IFILE: ! 92: if ((c=getc(ip->i_filp)) != EOF) ! 93: return (c); ! 94: if (ip->i_filp == stdin) { ! 95: if (testint()) ! 96: continue; ! 97: leave(); ! 98: } ! 99: fclose(ip->i_filp); ! 100: break; ! 101: } ! 102: inpp = inpp->i_next; ! 103: nfree(ip); ! 104: } ! 105: return (EOF); ! 106: } ! 107: ! 108: /* ! 109: * Put back a character onto the current input stream. ! 110: */ ! 111: ungetn(c) ! 112: { ! 113: lastc = c; ! 114: } ! 115: ! 116: /* ! 117: * Put out an address. `t' is the tolerance allowed. ! 118: */ ! 119: putaddr(s, l, t) ! 120: long l; ! 121: { ! 122: register char *sp; ! 123: ! 124: sp = conaddr(miscbuf, s, l, t); ! 125: *sp = '\0'; ! 126: printx("%s", miscbuf); ! 127: } ! 128: ! 129: /* ! 130: * Read `n' bytes from the current position in segment `seg' ! 131: * and store it in the buffer `bp'. ! 132: */ ! 133: getb(segn, bp, n) ! 134: char *bp; ! 135: unsigned n; ! 136: { ! 137: if (getputb(segn, bp, n, 0) == 0) ! 138: return (0); ! 139: canon(bp, n); ! 140: return (1); ! 141: } ! 142: ! 143: /* ! 144: * Put `n' bytes from the buffer `bp' into segment `seg'. ! 145: */ ! 146: putb(segn, bp, n) ! 147: char *bp; ! 148: unsigned n; ! 149: { ! 150: canon(bp, n); ! 151: return (getputb(segn, bp, n, 1)); ! 152: } ! 153: ! 154: /* ! 155: * Canonize the buffer `bp' of length `n' according to `cantype'. ! 156: */ ! 157: canon(bp, n) ! 158: register char *bp; ! 159: unsigned n; ! 160: { ! 161: register int i; ! 162: register int t; ! 163: ! 164: if (cantype == 1) { ! 165: if ((n&1) != 0) ! 166: return; ! 167: for (i=0; i<n; i+=2) { ! 168: t = bp[i]; ! 169: bp[i] = bp[i+1]; ! 170: bp[i+1] = t; ! 171: } ! 172: } ! 173: } ! 174: ! 175: /* ! 176: * Move `n' bytes between the buffer `bp' and the segment `segn'. ! 177: * The flag `d' controls the direction. ! 178: */ ! 179: getputb(segn, bp, n, d) ! 180: char *bp; ! 181: unsigned n; ! 182: { ! 183: register MAP *mp; ! 184: register unsigned l; ! 185: register unsigned s; ! 186: register int (*f)(); ! 187: fsize_t a; ! 188: ! 189: s = n; ! 190: a = add; ! 191: while (s) { ! 192: if ((mp=mapaddr(segn, a)) == NULL) ! 193: return (0); ! 194: l = s; ! 195: if (a+l > mp->m_bend) ! 196: l = mp->m_bend-a+1; ! 197: f = d ? mp->m_putf : mp->m_getf; ! 198: if( (*f)( mp->m_segi, mp->m_offt+ ! 199: ( fflag ? a - mp->m_base : size( a - mp->m_base)) ! 200: , bp, l) == 0) ! 201: return (0); ! 202: bp += l; ! 203: a += l; ! 204: s -= l; ! 205: } ! 206: add += n; ! 207: return (1); ! 208: } ! 209: ! 210: /* ! 211: * Given a segment number and an address, return the segment map ! 212: * in which the address falls. ! 213: */ ! 214: MAP * ! 215: mapaddr(n, a) ! 216: fsize_t a; ! 217: { ! 218: register MAP *mp; ! 219: ! 220: for (mp=segmapl[n]; mp != NULL; mp=mp->m_next) ! 221: if (mp->m_base<=a && a<mp->m_bend) ! 222: break; ! 223: return (mp); ! 224: } ! 225: ! 226: /* ! 227: * Read a symbol and return it's value in the given `VAL' structure. ! 228: */ ! 229: getsval(vp) ! 230: VAL *vp; ! 231: { ! 232: register int n; ! 233: register int c; ! 234: struct ldsym lds; ! 235: ! 236: n = 0; ! 237: c = getn(); ! 238: while (isascii(c) && (isalnum(c)||c=='_')) { ! 239: if (n < NCPLN) ! 240: lds.ls_id[n++] = c; ! 241: c = getn(); ! 242: } ! 243: ungetn(c); ! 244: while (n < NCPLN) ! 245: lds.ls_id[n++] = '\0'; ! 246: if (specsym(&lds)==0 && regaddr(&lds)==0 && nameval(&lds)==0) { ! 247: printe("Symbol not found"); ! 248: return (0); ! 249: } ! 250: switch (lds.ls_type&LR_SEG) { ! 251: case L_SHRI: ! 252: case L_PRVI: ! 253: case L_BSSI: ! 254: vp->v_segn = 1; ! 255: vp->v_flag = VLVAL; ! 256: break; ! 257: case L_SHRD: ! 258: case L_PRVD: ! 259: case L_BSSD: ! 260: case L_ABS: ! 261: vp->v_segn = 0; ! 262: vp->v_flag = VLVAL; ! 263: break; ! 264: ! 265: case L_REF: ! 266: printe("Symbol not defined"); ! 267: return (0); ! 268: case L_REG: ! 269: vp->v_segn = 2; ! 270: vp->v_flag = VLVAL; ! 271: break; ! 272: } ! 273: vp->v_nval = lds.ls_addr; ! 274: return (1); ! 275: } ! 276: ! 277: /* ! 278: * See if the given symbol is a special symbol. ! 279: */ ! 280: specsym(ldp) ! 281: register struct ldsym *ldp; ! 282: { ! 283: if (ldp->ls_id[1] != '\0') ! 284: return (0); ! 285: switch (ldp->ls_id[0]) { ! 286: case 'd': ! 287: ldp->ls_type = L_SHRD; ! 288: break; ! 289: case 'i': ! 290: ldp->ls_type = L_SHRI; ! 291: break; ! 292: case 'u': ! 293: ldp->ls_type = L_REG; ! 294: break; ! 295: default: ! 296: return (0); ! 297: } ! 298: ldp->ls_addr = 0; ! 299: return (1); ! 300: } ! 301: ! 302: /* ! 303: * Convert a value to an address. `t' is the tolerance ! 304: * allowed. ! 305: */ ! 306: char * ! 307: conaddr(sp, s, l, t) ! 308: register char *sp; ! 309: unsigned long l; ! 310: { ! 311: /* Bug in PDP11 compiler ! 312: register unsigned d; ! 313: */ ! 314: unsigned d; ! 315: struct ldsym ldsym; ! 316: ! 317: /* Bug in 8086 compiler ! 318: if (t<0 || valname(s, (tvaddr)l, &ldsym)==0 || (d=l-ldsym.ls_addr)>t) ! 319: */ ! 320: if (t<0 || valname(s, (tvaddr)l, &ldsym)==0 || ! 321: (d=(unsigned)l-ldsym.ls_addr)>t) ! 322: #if FORZ8001 ! 323: conaddnum( sp, l); ! 324: #else ! 325: concons(sp, l); ! 326: #endif ! 327: else { ! 328: sprintf(sp, "%.*s", NCPLN, ldsym.ls_id); ! 329: while (*sp) ! 330: sp++; ! 331: if (d != 0) { ! 332: *sp++ = '+'; ! 333: concons( sp, (long)d); ! 334: } ! 335: } ! 336: while (*sp) ! 337: sp++; ! 338: return (sp); ! 339: } ! 340: ! 341: /* ! 342: * Find the value of a symbol. ! 343: */ ! 344: nameval(ldp) ! 345: struct ldsym *ldp; ! 346: { ! 347: register int u; ! 348: register fsize_t n; ! 349: register SYM *sp; ! 350: register int r; ! 351: register int h; ! 352: register fsize_t b; ! 353: struct ldsym lds; ! 354: struct ldsym ldu; ! 355: ! 356: u = 0; ! 357: h = hash(ldp); ! 358: for (n=snsym, sp=ssymp, b=sbase; n--; sp++, b+=sizeof(lds)) { ! 359: if (ssymp!=NULL && sp->s_hash!=h) ! 360: continue; ! 361: fseek(sfp, (long)b, 0); ! 362: if (fread(&lds, sizeof(lds), 1, sfp) != 1) ! 363: return (0); ! 364: #if NOUT ! 365: canshort( lds.ls_type); ! 366: canlong( lds.ls_addr); ! 367: #else ! 368: canint(lds.ls_type); ! 369: canvaddr(lds.ls_addr); ! 370: #endif ! 371: if ((r=namecmp(ldp, &lds)) > 0) { ! 372: *ldp = lds; ! 373: return (1); ! 374: } ! 375: if (r < 0) { ! 376: ldu = lds; ! 377: u = 1; ! 378: } ! 379: } ! 380: if (u) { ! 381: *ldp = ldu; ! 382: return (1); ! 383: } ! 384: return (0); ! 385: } ! 386: ! 387: /* ! 388: * Compare the names of two symbol table entries. If the compare ! 389: * fails and the name of the first entry doesn't already end with ! 390: * an '_', the compare is effectively tried again after appending ! 391: * an '_', to the end of the first symbol name. ! 392: */ ! 393: namecmp(ldp1, ldp2) ! 394: struct ldsym *ldp1; ! 395: struct ldsym *ldp2; ! 396: { ! 397: register char *cp1; ! 398: register char *cp2; ! 399: register int n; ! 400: ! 401: n = CCSSIZE; ! 402: cp1 = ldp1->ls_id; ! 403: cp2 = ldp2->ls_id; ! 404: do { ! 405: if (*cp1 != *cp2++) { ! 406: if (*cp2!='\0' || *--cp2!='_') ! 407: return (0); ! 408: if (*cp1!='\0' || *--cp1=='_') ! 409: return (0); ! 410: return (-1); ! 411: } ! 412: if (*cp1++ == '\0') ! 413: return (1); ! 414: } while (--n); ! 415: return (1); ! 416: } ! 417: ! 418: /* ! 419: * Given a value, find the closest symbol below. ! 420: * Searches in segment s; if s = -1 looks in all segments. ! 421: */ ! 422: valname(s, m, ldp) ! 423: tvaddr m; ! 424: struct ldsym *ldp; ! 425: { ! 426: register int n; ! 427: register tvaddr a; ! 428: register SYM *sp; ! 429: register int t; ! 430: register int n1; ! 431: register tvaddr a1; ! 432: struct ldsym lds; ! 433: ! 434: strncpy(ldp->ls_id, "", NCPLN); ! 435: if (sfp == NULL) ! 436: return (0); ! 437: a1 = 0; ! 438: n1 = -1; ! 439: if (ssymp == NULL) ! 440: fseek(sfp, (long)sbase, 0); ! 441: for (n=0, sp=ssymp; n<snsym; n++, sp++) { ! 442: if (ssymp != NULL) { ! 443: a = sp->s_sval; ! 444: t = sp->s_type; ! 445: } else { ! 446: if (fread(&lds, sizeof(lds), 1, sfp) != 1) ! 447: return (0); ! 448: #if NOUT ! 449: canshort( lds.ls_type); ! 450: canlong( lds.ls_addr); ! 451: #else ! 452: canint(lds.ls_type); ! 453: canvaddr(lds.ls_addr); ! 454: #endif ! 455: a = lds.ls_addr; ! 456: t = lds.ls_type; ! 457: } ! 458: switch (t&LR_SEG) { ! 459: case L_SHRI: ! 460: case L_PRVI: ! 461: case L_BSSI: ! 462: if (s == 0) ! 463: continue; ! 464: break; ! 465: case L_SHRD: ! 466: case L_PRVD: ! 467: case L_BSSD: ! 468: if (s == 1) ! 469: continue; ! 470: break; ! 471: default: ! 472: continue; ! 473: } ! 474: if (a <= m) { ! 475: if (a1==0 || a>a1) { ! 476: a1 = a; ! 477: n1 = n; ! 478: } ! 479: } ! 480: } ! 481: if (n1 >= 0) { ! 482: fseek(sfp, (long)sbase + n1*sizeof(struct ldsym), 0); ! 483: if (fread(ldp, sizeof(*ldp), 1, sfp) != 1) ! 484: return (0); ! 485: #if NOUT ! 486: canshort( lds.ls_type); ! 487: canlong( lds.ls_addr); ! 488: #else ! 489: canint(ldp->ls_type); ! 490: canvaddr(ldp->ls_addr); ! 491: #endif ! 492: return (1); ! 493: } ! 494: return (0); ! 495: } ! 496: ! 497: /* ! 498: * Read `n' bytes from the file specified by `f' starting at ! 499: * address `seek'. ! 500: */ ! 501: getf(f, seek, bp, n) ! 502: long seek; ! 503: char *bp; ! 504: { ! 505: register FILE *fp; ! 506: ! 507: fp = f ? cfp : lfp; ! 508: fseek(fp, (long)seek, 0); ! 509: return (fread(bp, n, 1, fp)); ! 510: } ! 511: ! 512: /* ! 513: * Write `n' bytes into the files specified by `f' starting at ! 514: * address `seek'. ! 515: */ ! 516: putf(f, seek, bp, n) ! 517: long seek; ! 518: char *bp; ! 519: { ! 520: register FILE *fp; ! 521: ! 522: fp = f ? cfp : lfp; ! 523: fseek(fp, (long)seek, 0); ! 524: return (fwrite(bp, n, 1, fp) && fflush(fp)!=EOF); ! 525: } ! 526: ! 527: /* ! 528: * Allocate `n' bytes. ! 529: */ ! 530: char * ! 531: nalloc(n) ! 532: { ! 533: register char *cp; ! 534: ! 535: if ((cp=malloc(n)) == NULL) ! 536: panic("No memory"); ! 537: return (cp); ! 538: } ! 539: ! 540: /* ! 541: * Print out an error message and exit. ! 542: */ ! 543: panic(a1) ! 544: char *a1; ! 545: { ! 546: fprintf(stderr, "%r", &a1); ! 547: putc('\n', stderr); ! 548: exit(1); ! 549: } ! 550: ! 551: /* ! 552: * Print out a breakpoint error message. ! 553: */ ! 554: printb(a) ! 555: vaddr_t a; ! 556: { ! 557: fprintf(stderr, "Breakpoint error at "); ! 558: fprintf(stderr, DAFMT, (long)a); ! 559: putc('\n', stderr); ! 560: } ! 561: ! 562: /* ! 563: * Print out a fatal error message. ! 564: */ ! 565: printr(a1) ! 566: char *a1; ! 567: { ! 568: fprintf(stderr, "%r", &a1); ! 569: putc('\n', stderr); ! 570: } ! 571: ! 572: /* ! 573: * Print out an error message. ! 574: */ ! 575: printe(sp) ! 576: char *sp; ! 577: { ! 578: errrstr = sp; ! 579: fprintf(stderr, "?\n"); ! 580: } ! 581: ! 582: /* ! 583: * Print formatted. ! 584: */ ! 585: printx(a1) ! 586: char *a1; ! 587: { ! 588: printf("%r", &a1); ! 589: } ! 590: ! 591: putaddnum( a) ! 592: long a; ! 593: { ! 594: char buf[40]; ! 595: ! 596: conaddnum( buf, a); ! 597: printx( "%s", buf); ! 598: } ! 599: ! 600: putnum( a) ! 601: long( a); ! 602: { ! 603: char buf[20]; ! 604: ! 605: concons( buf, a); ! 606: printx( "%s", buf); ! 607: } ! 608: ! 609: char * ! 610: concons( sp, a) ! 611: char *sp; ! 612: long a; ! 613: { ! 614: register char *cp = sp; ! 615: ! 616: switch( dbase) { ! 617: case 8: sprintf( cp, "%lo", a); break; ! 618: case 10: sprintf( cp, "%ld", a); break; ! 619: case 16: sprintf( cp, "%lx", a); break; ! 620: } ! 621: while( *++cp) ; ! 622: return( cp); ! 623: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.