|
|
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.