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