This commit was generated by cvs2svn to track changes on a CVS vendor
[unix-history] / sys / ddb / db_examine.c
CommitLineData
15637ed4
RG
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 Software.Distribution@CS.CMU.EDU
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
67char db_examine_format[TOK_STRING_SIZE] = "x";
68
69extern db_addr_t db_disasm(/* db_addr_t, boolean_t */);
70 /* instruction disassembler */
71
72/*
73 * Examine (print) data.
74 */
75/*ARGSUSED*/
76void
77db_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
92db_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 */
217char db_print_format = 'x';
218
219/*ARGSUSED*/
220void
221db_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
265db_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
273db_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 */
285void
286db_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
349db_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}