|
|
1.1 ! root 1: /* ! 2: * db/db7.c ! 3: * A debugger. ! 4: * Miscellaneous routines. ! 5: */ ! 6: ! 7: #include "db.h" ! 8: #ifndef NOCANON ! 9: #include <canon.h> ! 10: #endif ! 11: ! 12: /* ! 13: * Add a string or a FILE * to the input stream. ! 14: */ ! 15: void ! 16: add_input(type, cp) int type; char *cp; ! 17: { ! 18: register INP *ip; ! 19: ! 20: ip = (INP *)nalloc(sizeof(INP), "input stack"); ! 21: ip->i_next = inpp; ! 22: inpp = ip; ! 23: ip->i_type = type; ! 24: if (type == ICORE) ! 25: ip->i_u.i_strp = cp; ! 26: else ! 27: ip->i_u.i_filp = (FILE *)cp; ! 28: } ! 29: ! 30: #ifndef NOCANON ! 31: /* ! 32: * Canonize the buffer 'bp' of length 'n' according to 'cantype'. ! 33: */ ! 34: void ! 35: canon(bp, n) register char *bp; unsigned int n; ! 36: { ! 37: register int i; ! 38: register int t; ! 39: ! 40: if ((n&1) != 0) ! 41: return; ! 42: for (i=0; i<n; i+=2) { ! 43: t = bp[i]; ! 44: bp[i] = bp[i+1]; ! 45: bp[i+1] = t; ! 46: } ! 47: } ! 48: #endif ! 49: ! 50: /* ! 51: * Convert value 'l' in segment 's' to an address. ! 52: * Store the result in 'buf' and return a pointer past the end. ! 53: * Conversion can produce a constant or a symbol with optional displacement. ! 54: */ ! 55: char * ! 56: cvt_addr(buf, s, addr) register char *buf; int s; register ADDR_T addr; ! 57: { ! 58: register SYM *sp; ! 59: register ADDR_T d; ! 60: ! 61: if ((sp = findsym(s, addr)) == (SYM *)NULL) /* name not found */ ! 62: print_const(buf, addr); /* so print as constant */ ! 63: else if ((d = addr - sp->s_addr) == 0) /* no displacement */ ! 64: sprintf(buf, "%s", sp->s_id); ! 65: else /* with displacement */ ! 66: sprintf(buf, "%s+%lu", sp->s_id, (long)d); ! 67: /* FIX_ME Watch out for buf overflow on id printf's above. */ ! 68: return strchr(buf, '\0'); ! 69: } ! 70: ! 71: #ifndef NOCANON /* If NOCANON, this is a macro in db.h. */ ! 72: /* ! 73: * Read 'n' bytes from the current position in segment 'segn' ! 74: * and store it in the buffer 'bp'. ! 75: */ ! 76: int ! 77: getb(segn, bp, n) int segn; char *bp; unsigned int n; ! 78: { ! 79: if (getputb(segn, bp, n, 0) == 0) ! 80: return 0; ! 81: #ifndef NOCANON ! 82: if (cantype != 0) ! 83: canon(bp, n); ! 84: #endif ! 85: #if 0 ! 86: { ! 87: register int i; ! 88: printf("getb(%d, ..., %d):\n", segn, n); ! 89: for (i = 0; i < n; i++) ! 90: printf("bp = %X\n", (unsigned char)bp[i]); ! 91: } ! 92: #endif ! 93: return 1; ! 94: } ! 95: #endif ! 96: ! 97: /* ! 98: * Read 'n' bytes to 'bp' from the file specified by 'fp'. ! 99: */ ! 100: int ! 101: getf(fp, bp, n) register FILE *fp; char *bp; int n; ! 102: { ! 103: return fread(bp, n, 1, fp); ! 104: } ! 105: ! 106: /* ! 107: * Save the rest of the input line in 'miscbuf'. ! 108: * If line is not given, save the default, 'cp'. ! 109: */ ! 110: void ! 111: getline(cp) register char *cp; ! 112: { ! 113: register int c; ! 114: register char *bp; ! 115: ! 116: bp = miscbuf; ! 117: if ((c = getn()) != '\n') { ! 118: while (c != '\n') { ! 119: if (c == '\\') ! 120: if ((c=getn())!='\n' && c!='\\') ! 121: *bp++ = '\\'; ! 122: *bp++ = c; ! 123: c = getn(); ! 124: } ! 125: } else { ! 126: while (*cp != '\0') ! 127: *bp++ = *cp++; ! 128: } ! 129: *bp++ = '\n'; ! 130: *bp = '\0'; ! 131: } ! 132: ! 133: /* ! 134: * Get the next character from the input stream. ! 135: */ ! 136: int ! 137: getn() ! 138: { ! 139: register INP *ip; ! 140: register int c; ! 141: ! 142: if (ungotc != '\0') { ! 143: c = ungotc; ! 144: ungotc = '\0'; ! 145: return c; ! 146: } ! 147: while ((ip = inpp) != (INP *)NULL) { ! 148: switch (ip->i_type) { ! 149: case ICORE: ! 150: if ((c = *ip->i_u.i_strp++) != '\0') ! 151: return c; ! 152: break; ! 153: case IFILE: ! 154: if ((c = getc(ip->i_u.i_filp)) != EOF) ! 155: return c; ! 156: if (ip->i_u.i_filp == stdin) { ! 157: if (testint()) ! 158: continue; ! 159: leave(); ! 160: } ! 161: fclose(ip->i_u.i_filp); ! 162: break; ! 163: } ! 164: inpp = inpp->i_next; ! 165: nfree(ip); ! 166: } ! 167: return EOF; ! 168: } ! 169: ! 170: /* ! 171: * Move 'n' bytes between the buffer 'bp' and the segment 'segn'. ! 172: * The flag 'd' controls the direction. ! 173: */ ! 174: int ! 175: getputb(segn, bp, n, d) int segn; char *bp; unsigned int n; int d; ! 176: { ! 177: register MAP *mp; ! 178: register FILE *fp; ! 179: register unsigned int l; ! 180: register unsigned int s; ! 181: register int (*f)(); ! 182: ADDR_T a; ! 183: ! 184: dbprintf(("getputb(s=%d bp=%X n=%d d=%s) add=%X\n", segn, bp, n,(d) ? "put" : "get", add)); ! 185: s = n; ! 186: a = add; ! 187: while (s) { ! 188: if ((mp = map_addr(segn, a)) == (MAP *)NULL) ! 189: return 0; ! 190: l = s; ! 191: if (a+l > mp->m_bend) ! 192: l = mp->m_bend-a+1; ! 193: if (mp->m_flag == MAP_CHILD) { ! 194: /* Map to child process. */ ! 195: f = (d) ? putp : getp; ! 196: if ((*f)(mp->m_segi, ((ADDR_T)mp->m_offt)+(a-mp->m_base), bp, l) == 0) ! 197: return 0; ! 198: } else { ! 199: /* Map to program or core file. */ ! 200: fp = mp->m_flag == MAP_PROG ? lfp : cfp; ! 201: f = (d) ? putf : getf; ! 202: if (fseek(fp, (long)(mp->m_offt+(a-mp->m_base)), SEEK_SET) == -1) ! 203: return 0; ! 204: if ((*f)(fp, bp, l) == 0) { ! 205: clearerr(fp); ! 206: return 0; ! 207: } ! 208: } ! 209: bp += l; ! 210: a += l; ! 211: s -= l; ! 212: } ! 213: add += n; ! 214: return 1; ! 215: } ! 216: ! 217: /* ! 218: * Allocate 'n' bytes. ! 219: */ ! 220: char * ! 221: nalloc(n, msg) int n; char *msg; ! 222: { ! 223: register char *cp; ! 224: ! 225: if ((cp = malloc(n)) == NULL) ! 226: panic("No memory for %s", msg); ! 227: return cp; ! 228: } ! 229: ! 230: #if 0 ! 231: /* ! 232: * Free storage allocated by nalloc(). ! 233: */ ! 234: void ! 235: nfree(cp) char *cp; ! 236: { ! 237: free(cp); ! 238: } ! 239: #endif ! 240: ! 241: /* ! 242: * Print a fatal error message and die. ! 243: */ ! 244: /* VARARGS */ ! 245: void ! 246: panic(arg1) ! 247: char *arg1; ! 248: { ! 249: fprintf(stderr, "%r\n", &arg1); ! 250: exit(1); ! 251: } ! 252: ! 253: /* ! 254: * Print a breakpoint error message. ! 255: */ ! 256: void ! 257: printb(addr) ADDR_T addr; ! 258: { ! 259: fprintf(stderr, "Breakpoint error at "); ! 260: fprintf(stderr, addr_fmt, addr); ! 261: fprintf(stderr, "\n"); ! 262: } ! 263: ! 264: /* ! 265: * Print an error message and set lasterr. ! 266: * Return a 0 for the convenience of the caller. ! 267: */ ! 268: int ! 269: printe(msg) register char *msg; ! 270: { ! 271: lasterr = msg; ! 272: fprintf(stderr, "%s\n", msg); ! 273: return 0; ! 274: } ! 275: ! 276: /* ! 277: * Print an error message. ! 278: * Return a 0 for the convenience of the caller. ! 279: */ ! 280: /* VARARGS */ ! 281: int ! 282: printr(arg1) char *arg1; ! 283: { ! 284: fprintf(stderr, "%r\n", &arg1); ! 285: return 0; ! 286: } ! 287: ! 288: #if 0 /* covered by macro in db.h */ ! 289: /* ! 290: * Formatted print. ! 291: */ ! 292: /* VARARGS */ ! 293: void ! 294: printx(arg1) char *arg1; ! 295: { ! 296: printf("%r", &arg1); ! 297: } ! 298: #endif ! 299: ! 300: /* ! 301: * Put out address 'addr' in segment 's'. ! 302: */ ! 303: void ! 304: putaddr(s, addr) int s; ADDR_T addr; ! 305: { ! 306: register char *sp; ! 307: ! 308: sp = cvt_addr(miscbuf, s, addr); ! 309: *sp = '\0'; ! 310: printx("%s", miscbuf); ! 311: } ! 312: ! 313: #ifndef NOCANON /* If NOCANON, this is a macro in db.h. */ ! 314: /* ! 315: * Put 'n' bytes from the buffer 'bp' into segment 'seg' ! 316: * at the current position. ! 317: */ ! 318: int ! 319: putb(segn, bp, n) int segn; char *bp; unsigned int n; ! 320: { ! 321: #ifndef NOCANON ! 322: if (cantype != 0) ! 323: canon(bp, n); ! 324: #endif ! 325: return getputb(segn, bp, n, 1); ! 326: } ! 327: #endif ! 328: ! 329: /* ! 330: * Write 'n' bytes from 'bp' to the file specified by 'fp'. ! 331: */ ! 332: int ! 333: putf(fp, bp, n) register FILE *fp; char *bp; int n; ! 334: { ! 335: return (fwrite(bp, n, 1, fp) == 1 && fflush(fp)!=EOF); ! 336: } ! 337: ! 338: #if 0 /* covered by macro in db.h */ ! 339: /* ! 340: * Put out a character. ! 341: */ ! 342: void ! 343: putx(c) int c; ! 344: { ! 345: putchar(c); ! 346: } ! 347: #endif ! 348: ! 349: #if 0 /* covered by macro in db.h */ ! 350: /* ! 351: * Put back a character onto the current input stream. ! 352: */ ! 353: void ! 354: ungetn(c) ! 355: { ! 356: ungotc = c; ! 357: } ! 358: #endif ! 359: ! 360: /* end of db/db7.c */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.