|
|
1.1 ! root 1: /* ! 2: * A debugger. ! 3: * Initialisation, command line parsing. ! 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: #include <sys/proc.h> ! 15: #include <signal.h> ! 16: #include <sys/uproc.h> ! 17: ! 18: main(argc, argv) ! 19: char **argv; ! 20: { ! 21: initialise(); ! 22: setup(argc, argv); ! 23: signal(SIGINT, &armsint); ! 24: signal(SIGQUIT, SIG_IGN); ! 25: process(); ! 26: } ! 27: ! 28: /* ! 29: * Leave. ! 30: */ ! 31: leave() ! 32: { ! 33: killc(); ! 34: exit(0); ! 35: } ! 36: ! 37: /* ! 38: * Initialise. ! 39: */ ! 40: initialise() ! 41: { ! 42: register int i; ! 43: ! 44: for (i=0; i<NSEGM; i++) ! 45: strcpy(&segform[i][0], "aw"); ! 46: strcpy(&segform[1][0], "ai"); ! 47: bptinit(); ! 48: } ! 49: ! 50: /* ! 51: * Setup arguments. ! 52: */ ! 53: setup(argc, argv) ! 54: char **argv; ! 55: { ! 56: register char *cp; ! 57: register int c; ! 58: register int t; ! 59: register int u; ! 60: register int tflag; ! 61: ! 62: t = '\0'; ! 63: tflag = 0; ! 64: for (; argc>1; argc--, argv++) { ! 65: cp = argv[1]; ! 66: if (*cp++ != '-') ! 67: break; ! 68: while ((c=*cp++) != '\0') { ! 69: switch (c) { ! 70: case 'c': ! 71: case 'd': ! 72: case 'e': ! 73: case 'f': ! 74: case 'k': ! 75: case 'o': ! 76: if (t != '\0') ! 77: usage(); ! 78: t = c; ! 79: continue; ! 80: case 'h': ! 81: hflag = 1; ! 82: continue; ! 83: case 'r': ! 84: rflag = 1; ! 85: continue; ! 86: case 's': ! 87: sflag = 1; ! 88: continue; ! 89: case 't': ! 90: tflag = 1; ! 91: continue; ! 92: default: ! 93: usage(); ! 94: } ! 95: } ! 96: } ! 97: switch (t) { ! 98: case '\0': ! 99: switch (argc) { ! 100: case 1: ! 101: setlout("l.out", 3); ! 102: setcore("core"); ! 103: break; ! 104: case 2: ! 105: setlout(argv[1], 3); ! 106: break; ! 107: case 3: ! 108: setlout(argv[1], 3); ! 109: setcore(argv[2]); ! 110: break; ! 111: default: ! 112: usage(); ! 113: } ! 114: break; ! 115: case 'c': ! 116: switch (argc) { ! 117: case 1: ! 118: setlout("l.out", 3); ! 119: setcore("core"); ! 120: break; ! 121: case 2: ! 122: setcore(argv[1]); ! 123: break; ! 124: case 3: ! 125: setlout(argv[1], 3); ! 126: setcore(argv[2]); ! 127: break; ! 128: default: ! 129: usage(); ! 130: } ! 131: break; ! 132: case 'd': ! 133: switch (argc) { ! 134: case 1: ! 135: setlout("/coherent", 3); ! 136: setdump("/dev/dump"); ! 137: break; ! 138: case 3: ! 139: setlout(argv[1], 3); ! 140: setdump(argv[2]); ! 141: break; ! 142: default: ! 143: usage(); ! 144: } ! 145: break; ! 146: case 'e': ! 147: if (argc < 2) ! 148: usage(); ! 149: setlout(argv[1], 3); ! 150: if (startup(&argv[1], NULL, NULL, 0)==0 || shiftup()==0) ! 151: leave(); ! 152: break; ! 153: case 'f': ! 154: fflag = 1; ! 155: switch (argc) { ! 156: case 2: ! 157: setfile(argv[1]); ! 158: break; ! 159: case 3: ! 160: setlout(argv[1], 1); ! 161: setfile(argv[2]); ! 162: break; ! 163: default: ! 164: usage(); ! 165: } ! 166: break; ! 167: case 'k': ! 168: switch (argc) { ! 169: case 1: ! 170: setlout("/coherent", 1); ! 171: setkmem("/dev/mem"); ! 172: break; ! 173: case 2: ! 174: setkmem(argv[1]); ! 175: break; ! 176: case 3: ! 177: setlout(argv[1], 1); ! 178: setkmem(argv[2]); ! 179: break; ! 180: default: ! 181: usage(); ! 182: } ! 183: break; ! 184: case 'o': ! 185: switch (argc) { ! 186: case 1: ! 187: setlout("l.out", 3); ! 188: break; ! 189: case 2: ! 190: setlout(argv[1], 3); ! 191: break; ! 192: case 3: ! 193: setlout(argv[1], 1); ! 194: setlout(argv[2], 2); ! 195: break; ! 196: default: ! 197: usage(); ! 198: } ! 199: } ! 200: if (tflag) { ! 201: if ((u=open("/dev/tty", 2)) < 0) ! 202: panic("Cannot open /dev/tty"); ! 203: dup2(u, 0); ! 204: dup2(u, 1); ! 205: dup2(u, 2); ! 206: } ! 207: } ! 208: ! 209: /* ! 210: * Generate a usage message. ! 211: */ ! 212: usage() ! 213: { ! 214: panic("Usage: db [-cdefort] [object file] [auxiliary file]"); ! 215: } ! 216: ! 217: /* ! 218: * Catch and flag interrupts. ! 219: */ ! 220: armsint() ! 221: { ! 222: signal(SIGINT, &armsint); ! 223: intflag++; ! 224: } ! 225: ! 226: /* ! 227: * Check for interrupts and clear flag. ! 228: */ ! 229: testint() ! 230: { ! 231: register int n; ! 232: ! 233: if ((n=intflag) != 0) ! 234: printe("Interrupt"); ! 235: intflag = 0; ! 236: return (n); ! 237: } ! 238: ! 239: /* ! 240: * Assume the file, `np', is the name of an l.out. If the bottom bit ! 241: * of the flag is set, set up the symbol table. If the next bit is set, ! 242: * set up segmentation for the l.out. ! 243: */ ! 244: setlout(np, f) ! 245: char *np; ! 246: { ! 247: struct ldheader ldh; ! 248: ! 249: lfp = openfil(np, (f&2) ? rflag : 1); ! 250: if (fread(&ldh, sizeof(ldh), 1, lfp) != 1) ! 251: panic("Cannot read object file"); ! 252: canlout(&ldh); ! 253: if (ldh.l_magic != L_MAGIC) ! 254: panic("Bad object file"); ! 255: objflag = 1; ! 256: if ((f&1) != 0) { ! 257: #if NOUT ! 258: sbase = ldh.l_tbase; ! 259: #else ! 260: sbase = sizeof(ldh); ! 261: #endif ! 262: sbase += ldh.l_ssize[L_SHRI] + ldh.l_ssize[L_PRVI]; ! 263: sbase += ldh.l_ssize[L_SHRD] + ldh.l_ssize[L_PRVD]; ! 264: snsym = ldh.l_ssize[L_SYM] / sizeof(struct ldsym); ! 265: if (snsym != 0) { ! 266: sfp = lfp; ! 267: if (sflag == 0) ! 268: readsym(sfp); ! 269: } ! 270: } ! 271: if ((f&2) != 0) { ! 272: lfn = np; ! 273: setaseg(&ldh); ! 274: } ! 275: } ! 276: ! 277: /* ! 278: * Canonize an l.out header. ! 279: */ ! 280: canlout(ldp) ! 281: struct ldheader *ldp; ! 282: { ! 283: register int i; ! 284: ! 285: #if NOUT ! 286: canshort( ldp->l_magic); ! 287: canshort( ldp->l_flag); ! 288: canshort( ldp->l_machine); ! 289: canshort( ldp->l_tbase); ! 290: canlong( ldp->l_entry); ! 291: #else ! 292: canint( ldp->l_magic); ! 293: canint( ldp->l_flag); ! 294: canint( ldp->l_machine); ! 295: canvaddr( ldp->l_entry); ! 296: #endif ! 297: for (i=0; i<NLSEG; i++) ! 298: #if NOUT ! 299: canlong( ldp->l_ssize[i]); ! 300: #else ! 301: cansize( ldp->l_ssize[i]); ! 302: #endif ! 303: } ! 304: ! 305: /* ! 306: * Read all global symbols into memory. ! 307: */ ! 308: readsym(fp) ! 309: FILE *fp; ! 310: { ! 311: register int n; ! 312: register SYM *sp; ! 313: struct ldsym lds; ! 314: ! 315: if ((ssymp=nalloc((int)snsym * sizeof(SYM))) == NULL) ! 316: return; ! 317: fseek(fp, (long)sbase, 0); ! 318: for (n=snsym, sp=ssymp; n--; sp++) { ! 319: if (fread(&lds, sizeof(lds), 1, fp) != 1) { ! 320: nfree(ssymp); ! 321: ssymp = NULL; ! 322: return; ! 323: } ! 324: #if NOUT ! 325: canshort( lds.ls_type); ! 326: canlong( lds.ls_addr); ! 327: #else ! 328: canint( lds.ls_type); ! 329: canvaddr( lds.ls_addr); ! 330: #endif ! 331: sp->s_hash = hash(&lds); ! 332: sp->s_type = lds.ls_type; ! 333: sp->s_sval = lds.ls_addr; ! 334: } ! 335: } ! 336: ! 337: /* ! 338: * Hash a symbol name. ! 339: */ ! 340: hash(ldp) ! 341: struct ldsym *ldp; ! 342: { ! 343: register int h, n; ! 344: register char *cp; ! 345: ! 346: h = 0; ! 347: n = CCSSIZE; ! 348: cp = ldp->ls_id; ! 349: do { ! 350: if (*cp != '_') ! 351: h += *cp; ! 352: if (*cp++ == '\0') ! 353: break; ! 354: } while (--n); ! 355: return (h&0377); ! 356: } ! 357: ! 358: /* ! 359: * Set up segmentation for a core dump. The registers are also read. ! 360: */ ! 361: ! 362: MAP * ! 363: smapc( next, start, length, foffs) ! 364: MAP *next; ! 365: register tvaddr start; ! 366: fsize_t length, foffs; ! 367: { ! 368: return( setsmap( next, start, addr( size( start) + length) - start, ! 369: foffs, getf, putf, 1)); ! 370: } ! 371: setcore(np) ! 372: char *np; ! 373: { ! 374: register unsigned i; ! 375: register MAP *mp; ! 376: register char *cp; ! 377: register char *lcp; ! 378: register fsize_t siz; ! 379: register fsize_t offt; ! 380: char ucomm[10]; ! 381: SR usegs[NUSEG]; ! 382: ! 383: cfp = openfil(np, rflag); ! 384: fseek(cfp, (long)offset(uproc, u_comm[0]), 0); ! 385: if ((cp=lfn)!=NULL && fread(ucomm, sizeof(ucomm), 1, cfp)==1) { ! 386: lcp = cp; ! 387: while (*cp) { ! 388: if (*cp++ == '/') ! 389: lcp = cp; ! 390: } ! 391: if (strncmp(lcp, ucomm, sizeof(ucomm)) != 0) ! 392: printr("Core different from object"); ! 393: } ! 394: fseek(cfp, (long)offset(uproc, u_segl[0]), 0); ! 395: if (fread(usegs, sizeof(usegs), 1, cfp) != 1) ! 396: panic("Bad core file"); ! 397: USPACE = setsmap(NULL, (fsize_t)0, (fsize_t)UPASIZE, (fsize_t)0, ! 398: getf, putf, 1); ! 399: mp = clrsmap(DSPACE, endpure); ! 400: offt = usegs[0].sr_size; ! 401: for (i=1; i<NUSEG; i++) { ! 402: if (usegs[i].sr_segp == NULL) ! 403: continue; ! 404: if ((~usegs[i].sr_flag) & (SRFDUMP|SRFPMAP)) ! 405: continue; ! 406: siz = usegs[i].sr_size; ! 407: mp = smapc(mp, usegs[i].sr_base, siz, offt); ! 408: offt += siz; ! 409: } ! 410: if (ISPACE == DSPACE) ! 411: ISPACE = mp; ! 412: DSPACE = mp; ! 413: settrap(); ! 414: setregs(); ! 415: } ! 416: ! 417: /* ! 418: * Find out fault type. ! 419: */ ! 420: settrap() ! 421: { ! 422: int f; ! 423: ! 424: trapstr = "???"; ! 425: #if PDP11 ! 426: add = 0724; /* old pdp11 cohos differs from src */ ! 427: #else ! 428: add = offset(uproc, u_signo); ! 429: #endif ! 430: if (getb(2, (char *)&f, sizeof(f)) == 0) { ! 431: printr("Cannot read fault type"); ! 432: return (0); ! 433: } ! 434: if (f<=0 || f>NSIG) { ! 435: printr("Bad fault type"); ! 436: return (0); ! 437: } ! 438: trapstr = signame[f-1]; ! 439: return (f); ! 440: } ! 441: ! 442: /* ! 443: * Set up segmentation for an ordinary file. ! 444: * This is really easy. ! 445: */ ! 446: setfile(np) ! 447: char *np; ! 448: { ! 449: lfp = openfil(np, rflag); ! 450: DSPACE = setsmap(NULL, (fsize_t)0, (fsize_t)LI, (fsize_t)0, ! 451: getf, putf, 0); ! 452: ISPACE = DSPACE; ! 453: } ! 454: ! 455: /* ! 456: * Open the given file. If `rflag' is set, the file is opened for ! 457: * read only. ! 458: */ ! 459: FILE * ! 460: openfil(np, rflag) ! 461: char *np; ! 462: { ! 463: register FILE *fp; ! 464: ! 465: if (rflag) { ! 466: if ((fp=fopen(np, "r")) != NULL) ! 467: return (fp); ! 468: } else { ! 469: if ((fp=fopen(np, "r+w")) != NULL) ! 470: return (fp); ! 471: if ((fp=fopen(np, "r")) != NULL) { ! 472: printr("%s: opened read only", np); ! 473: return (fp); ! 474: } ! 475: } ! 476: panic("Cannot open %s", np); ! 477: } ! 478: ! 479: /* ! 480: * Initialise an element of a segment map. ! 481: */ ! 482: MAP * ! 483: setsmap(next, base, siz, offt, getf, putf, segi) ! 484: MAP *next; ! 485: fsize_t base; ! 486: fsize_t siz; ! 487: fsize_t offt; ! 488: int (*getf)(); ! 489: int (*putf)(); ! 490: { ! 491: register MAP *mp; ! 492: ! 493: mp = (MAP *)nalloc(sizeof(MAP)); ! 494: mp->m_next = next; ! 495: mp->m_base = base; ! 496: mp->m_bend = base+siz; ! 497: mp->m_offt = offt; ! 498: mp->m_getf = getf; ! 499: mp->m_putf = putf; ! 500: mp->m_segi = segi; ! 501: return (mp); ! 502: } ! 503: ! 504: /* ! 505: * Clear a section of a segment map. ! 506: */ ! 507: MAP * ! 508: clrsmap(mp, np) ! 509: register MAP *mp; ! 510: register MAP *np; ! 511: { ! 512: while (mp != np) { ! 513: nfree(mp); ! 514: mp = mp->m_next; ! 515: } ! 516: return (mp); ! 517: } ! 518: ! 519: /* ! 520: * Clear all maps. ! 521: */ ! 522: clramap() ! 523: { ! 524: register int n; ! 525: ! 526: n = 0; ! 527: if (segmapl[0] == segmapl[1]) ! 528: segmapl[n++] = NULL; ! 529: while (n < NSEGM) { ! 530: segmapl[n] = clrsmap(segmapl[n], NULL); ! 531: n++; ! 532: } ! 533: } ! 534:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.