|
|
1.1 root 1: /*
2: * Mach Operating System
3: * Copyright (c) 1991,1990 Carnegie Mellon University
4: * All Rights Reserved.
5: *
6: * Permission to use, copy, modify and distribute this software and its
7: * documentation is hereby granted, provided that both the copyright
8: * notice and this permission notice appear in all copies of the
9: * software, derivative works or modified versions, and any portions
10: * thereof, and that both notices appear in supporting documentation.
11: *
12: * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS
13: * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
14: * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
15: *
16: * Carnegie Mellon requests users of this software to return to
17: *
18: * Software Distribution Coordinator or [email protected]
19: * School of Computer Science
20: * Carnegie Mellon University
21: * Pittsburgh PA 15213-3890
22: *
23: * any improvements or extensions that they make and grant Carnegie the
24: * rights to redistribute these changes.
25: */
26: /*
27: * HISTORY
28: * $Log: db_examine.c,v $
29: * Revision 1.1 1992/03/25 21:45:07 pace
30: * Initial revision
31: *
32: * Revision 2.4 91/02/05 17:06:20 mrt
33: * Changed to new Mach copyright
34: * [91/01/31 16:17:37 mrt]
35: *
36: * Revision 2.3 90/11/07 16:49:23 rpd
37: * Added db_search_cmd, db_search.
38: * [90/11/06 rpd]
39: *
40: * Revision 2.2 90/08/27 21:50:38 dbg
41: * Add 'r', 'z' to print and examine formats.
42: * Change calling sequence of db_disasm.
43: * db_examine sets db_prev and db_next instead of explicitly
44: * advancing dot.
45: * [90/08/20 dbg]
46: * Reflected changes in db_printsym()'s calling seq.
47: * [90/08/20 af]
48: * Reduce lint.
49: * [90/08/07 dbg]
50: * Created.
51: * [90/07/25 dbg]
52: *
53: */
54: /*
55: * Author: David B. Golub, Carnegie Mellon University
56: * Date: 7/90
57: */
58: #include "param.h"
59: #include "proc.h"
60: #include <machine/db_machdep.h> /* type definitions */
61:
62: #include <ddb/db_lex.h>
63: #include <ddb/db_output.h>
64: #include <ddb/db_command.h>
65: #include <ddb/db_sym.h>
66:
67: char db_examine_format[TOK_STRING_SIZE] = "x";
68:
69: extern db_addr_t db_disasm(/* db_addr_t, boolean_t */);
70: /* instruction disassembler */
71:
72: /*
73: * Examine (print) data.
74: */
75: /*ARGSUSED*/
76: void
77: db_examine_cmd(addr, have_addr, count, modif)
78: db_expr_t addr;
79: int have_addr;
80: db_expr_t count;
81: char * modif;
82: {
83: if (modif[0] != '\0')
84: db_strcpy(db_examine_format, modif);
85:
86: if (count == -1)
87: count = 1;
88:
89: db_examine((db_addr_t) addr, db_examine_format, count);
90: }
91:
92: db_examine(addr, fmt, count)
93: register
94: db_addr_t addr;
95: char * fmt; /* format string */
96: int count; /* repeat count */
97: {
98: int c;
99: db_expr_t value;
100: int size;
101: int width;
102: char * fp;
103:
104: while (--count >= 0) {
105: fp = fmt;
106: size = 4;
107: width = 16;
108: while ((c = *fp++) != 0) {
109: switch (c) {
110: case 'b':
111: size = 1;
112: width = 4;
113: break;
114: case 'h':
115: size = 2;
116: width = 8;
117: break;
118: case 'l':
119: size = 4;
120: width = 16;
121: break;
122: case 'a': /* address */
123: /* always forces a new line */
124: if (db_print_position() != 0)
125: db_printf("\n");
126: db_prev = addr;
127: db_printsym(addr, DB_STGY_ANY);
128: db_printf(":\t");
129: break;
130: default:
131: if (db_print_position() == 0) {
132: /* If we hit a new symbol, print it */
133: char * name;
134: db_expr_t off;
135:
136: db_find_sym_and_offset(addr, &name, &off);
137: if (off == 0)
138: db_printf("%s:\t", name);
139: else
140: db_printf("\t\t");
141:
142: db_prev = addr;
143: }
144:
145: switch (c) {
146: case 'r': /* signed, current radix */
147: value = db_get_value(addr, size, TRUE);
148: addr += size;
149: db_printf("%-*r", width, value);
150: break;
151: case 'x': /* unsigned hex */
152: value = db_get_value(addr, size, FALSE);
153: addr += size;
154: db_printf("%-*x", width, value);
155: break;
156: case 'z': /* signed hex */
157: value = db_get_value(addr, size, TRUE);
158: addr += size;
159: db_printf("%-*z", width, value);
160: break;
161: case 'd': /* signed decimal */
162: value = db_get_value(addr, size, TRUE);
163: addr += size;
164: db_printf("%-*d", width, value);
165: break;
166: case 'u': /* unsigned decimal */
167: value = db_get_value(addr, size, FALSE);
168: addr += size;
169: db_printf("%-*u", width, value);
170: break;
171: case 'o': /* unsigned octal */
172: value = db_get_value(addr, size, FALSE);
173: addr += size;
174: db_printf("%-*o", width, value);
175: break;
176: case 'c': /* character */
177: value = db_get_value(addr, 1, FALSE);
178: addr += 1;
179: if (value >= ' ' && value <= '~')
180: db_printf("%c", value);
181: else
182: db_printf("\\%03o", value);
183: break;
184: case 's': /* null-terminated string */
185: for (;;) {
186: value = db_get_value(addr, 1, FALSE);
187: addr += 1;
188: if (value == 0)
189: break;
190: if (value >= ' ' && value <= '~')
191: db_printf("%c", value);
192: else
193: db_printf("\\%03o", value);
194: }
195: break;
196: case 'i': /* instruction */
197: addr = db_disasm(addr, FALSE);
198: break;
199: case 'I': /* instruction, alternate form */
200: addr = db_disasm(addr, TRUE);
201: break;
202: default:
203: break;
204: }
205: if (db_print_position() != 0)
206: db_end_line();
207: break;
208: }
209: }
210: }
211: db_next = addr;
212: }
213:
214: /*
215: * Print value.
216: */
217: char db_print_format = 'x';
218:
219: /*ARGSUSED*/
220: void
221: db_print_cmd(addr, have_addr, count, modif)
222: db_expr_t addr;
223: int have_addr;
224: db_expr_t count;
225: char * modif;
226: {
227: db_expr_t value;
228:
229: if (modif[0] != '\0')
230: db_print_format = modif[0];
231:
232: switch (db_print_format) {
233: case 'a':
234: db_printsym((db_addr_t)addr, DB_STGY_ANY);
235: break;
236: case 'r':
237: db_printf("%11r", addr);
238: break;
239: case 'x':
240: db_printf("%8x", addr);
241: break;
242: case 'z':
243: db_printf("%8z", addr);
244: break;
245: case 'd':
246: db_printf("%11d", addr);
247: break;
248: case 'u':
249: db_printf("%11u", addr);
250: break;
251: case 'o':
252: db_printf("%16o", addr);
253: break;
254: case 'c':
255: value = addr & 0xFF;
256: if (value >= ' ' && value <= '~')
257: db_printf("%c", value);
258: else
259: db_printf("\\%03o", value);
260: break;
261: }
262: db_printf("\n");
263: }
264:
265: db_print_loc_and_inst(loc)
266: db_addr_t loc;
267: {
268: db_printsym(loc, DB_STGY_PROC);
269: db_printf(":\t");
270: (void) db_disasm(loc, TRUE);
271: }
272:
273: db_strcpy(dst, src)
274: register char *dst;
275: register char *src;
276: {
277: while (*dst++ = *src++)
278: ;
279: }
280:
281: /*
282: * Search for a value in memory.
283: * Syntax: search [/bhl] addr value [mask] [,count]
284: */
285: void
286: db_search_cmd()
287: {
288: int t;
289: db_addr_t addr;
290: int size;
291: db_expr_t value;
292: db_expr_t mask;
293: unsigned int count;
294:
295: t = db_read_token();
296: if (t == tSLASH) {
297: t = db_read_token();
298: if (t != tIDENT) {
299: bad_modifier:
300: db_printf("Bad modifier\n");
301: db_flush_lex();
302: return;
303: }
304:
305: if (!strcmp(db_tok_string, "b"))
306: size = 1;
307: else if (!strcmp(db_tok_string, "h"))
308: size = 2;
309: else if (!strcmp(db_tok_string, "l"))
310: size = 4;
311: else
312: goto bad_modifier;
313: } else {
314: db_unread_token(t);
315: size = 4;
316: }
317:
318: if (!db_expression(&addr)) {
319: db_printf("Address missing\n");
320: db_flush_lex();
321: return;
322: }
323:
324: if (!db_expression(&value)) {
325: db_printf("Value missing\n");
326: db_flush_lex();
327: return;
328: }
329:
330: if (!db_expression(&mask))
331: mask = 0xffffffff;
332:
333: t = db_read_token();
334: if (t == tCOMMA) {
335: if (!db_expression(&count)) {
336: db_printf("Count missing\n");
337: db_flush_lex();
338: return;
339: }
340: } else {
341: db_unread_token(t);
342: count = -1; /* effectively forever */
343: }
344: db_skip_to_eol();
345:
346: db_search(addr, size, value, mask, count);
347: }
348:
349: db_search(addr, size, value, mask, count)
350: register
351: db_addr_t addr;
352: int size;
353: db_expr_t value;
354: db_expr_t mask;
355: unsigned int count;
356: {
357: while (count-- != 0) {
358: db_prev = addr;
359: if ((db_get_value(addr, size, FALSE) & mask) == value)
360: break;
361: addr += size;
362: }
363: db_next = addr;
364: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.