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