added my responsibility for the `cpm' port
[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.
15637ed4 25 *
fde1aeb2 26 * $Id: db_examine.c,v 1.3 1993/11/25 01:30:05 wollman Exp $
15637ed4 27 */
cbeffc91 28
15637ed4
RG
29/*
30 * Author: David B. Golub, Carnegie Mellon University
31 * Date: 7/90
32 */
33#include "param.h"
4c45483e 34#include "systm.h"
15637ed4 35#include "proc.h"
4c45483e
GW
36
37#include "ddb/ddb.h"
15637ed4 38
fde1aeb2
GW
39#include "ddb/db_lex.h"
40#include "ddb/db_output.h"
41#include "ddb/db_command.h"
42#include "ddb/db_sym.h"
43#include "ddb/db_access.h"
15637ed4
RG
44
45char db_examine_format[TOK_STRING_SIZE] = "x";
46
47extern db_addr_t db_disasm(/* db_addr_t, boolean_t */);
48 /* instruction disassembler */
49
4c45483e
GW
50static void db_examine(db_addr_t, char *, int);
51static void db_search(db_addr_t, int, db_expr_t, db_expr_t, u_int);
52
15637ed4
RG
53/*
54 * Examine (print) data.
55 */
56/*ARGSUSED*/
57void
58db_examine_cmd(addr, have_addr, count, modif)
59 db_expr_t addr;
60 int have_addr;
61 db_expr_t count;
62 char * modif;
63{
64 if (modif[0] != '\0')
65 db_strcpy(db_examine_format, modif);
66
67 if (count == -1)
68 count = 1;
69
70 db_examine((db_addr_t) addr, db_examine_format, count);
71}
72
4c45483e 73static void
15637ed4
RG
74db_examine(addr, fmt, count)
75 register
76 db_addr_t addr;
77 char * fmt; /* format string */
78 int count; /* repeat count */
79{
80 int c;
81 db_expr_t value;
82 int size;
83 int width;
84 char * fp;
85
86 while (--count >= 0) {
87 fp = fmt;
88 size = 4;
89 width = 16;
90 while ((c = *fp++) != 0) {
91 switch (c) {
92 case 'b':
93 size = 1;
94 width = 4;
95 break;
96 case 'h':
97 size = 2;
98 width = 8;
99 break;
100 case 'l':
101 size = 4;
102 width = 16;
103 break;
104 case 'a': /* address */
105 /* always forces a new line */
106 if (db_print_position() != 0)
107 db_printf("\n");
108 db_prev = addr;
109 db_printsym(addr, DB_STGY_ANY);
110 db_printf(":\t");
111 break;
112 default:
113 if (db_print_position() == 0) {
114 /* If we hit a new symbol, print it */
115 char * name;
116 db_expr_t off;
117
118 db_find_sym_and_offset(addr, &name, &off);
119 if (off == 0)
120 db_printf("%s:\t", name);
121 else
122 db_printf("\t\t");
123
124 db_prev = addr;
125 }
126
127 switch (c) {
128 case 'r': /* signed, current radix */
129 value = db_get_value(addr, size, TRUE);
130 addr += size;
131 db_printf("%-*r", width, value);
132 break;
133 case 'x': /* unsigned hex */
134 value = db_get_value(addr, size, FALSE);
135 addr += size;
136 db_printf("%-*x", width, value);
137 break;
138 case 'z': /* signed hex */
139 value = db_get_value(addr, size, TRUE);
140 addr += size;
141 db_printf("%-*z", width, value);
142 break;
143 case 'd': /* signed decimal */
144 value = db_get_value(addr, size, TRUE);
145 addr += size;
146 db_printf("%-*d", width, value);
147 break;
148 case 'u': /* unsigned decimal */
149 value = db_get_value(addr, size, FALSE);
150 addr += size;
151 db_printf("%-*u", width, value);
152 break;
153 case 'o': /* unsigned octal */
154 value = db_get_value(addr, size, FALSE);
155 addr += size;
156 db_printf("%-*o", width, value);
157 break;
158 case 'c': /* character */
159 value = db_get_value(addr, 1, FALSE);
160 addr += 1;
161 if (value >= ' ' && value <= '~')
162 db_printf("%c", value);
163 else
164 db_printf("\\%03o", value);
165 break;
166 case 's': /* null-terminated string */
167 for (;;) {
168 value = db_get_value(addr, 1, FALSE);
169 addr += 1;
170 if (value == 0)
171 break;
172 if (value >= ' ' && value <= '~')
173 db_printf("%c", value);
174 else
175 db_printf("\\%03o", value);
176 }
177 break;
178 case 'i': /* instruction */
179 addr = db_disasm(addr, FALSE);
180 break;
181 case 'I': /* instruction, alternate form */
182 addr = db_disasm(addr, TRUE);
183 break;
184 default:
185 break;
186 }
187 if (db_print_position() != 0)
188 db_end_line();
189 break;
190 }
191 }
192 }
193 db_next = addr;
194}
195
196/*
197 * Print value.
198 */
199char db_print_format = 'x';
200
201/*ARGSUSED*/
202void
203db_print_cmd(addr, have_addr, count, modif)
204 db_expr_t addr;
205 int have_addr;
206 db_expr_t count;
207 char * modif;
208{
209 db_expr_t value;
210
211 if (modif[0] != '\0')
212 db_print_format = modif[0];
213
214 switch (db_print_format) {
215 case 'a':
216 db_printsym((db_addr_t)addr, DB_STGY_ANY);
217 break;
218 case 'r':
219 db_printf("%11r", addr);
220 break;
221 case 'x':
222 db_printf("%8x", addr);
223 break;
224 case 'z':
225 db_printf("%8z", addr);
226 break;
227 case 'd':
228 db_printf("%11d", addr);
229 break;
230 case 'u':
231 db_printf("%11u", addr);
232 break;
233 case 'o':
234 db_printf("%16o", addr);
235 break;
236 case 'c':
237 value = addr & 0xFF;
238 if (value >= ' ' && value <= '~')
239 db_printf("%c", value);
240 else
241 db_printf("\\%03o", value);
242 break;
243 }
244 db_printf("\n");
245}
246
4c45483e 247void
15637ed4
RG
248db_print_loc_and_inst(loc)
249 db_addr_t loc;
250{
251 db_printsym(loc, DB_STGY_PROC);
252 db_printf(":\t");
253 (void) db_disasm(loc, TRUE);
254}
255
15637ed4
RG
256/*
257 * Search for a value in memory.
258 * Syntax: search [/bhl] addr value [mask] [,count]
259 */
260void
4c45483e 261db_search_cmd(db_expr_t dummy1, int dummy2, db_expr_t dummy3, char *dummy4)
15637ed4
RG
262{
263 int t;
264 db_addr_t addr;
265 int size;
266 db_expr_t value;
267 db_expr_t mask;
268 unsigned int count;
269
270 t = db_read_token();
271 if (t == tSLASH) {
272 t = db_read_token();
273 if (t != tIDENT) {
274 bad_modifier:
275 db_printf("Bad modifier\n");
276 db_flush_lex();
277 return;
278 }
279
280 if (!strcmp(db_tok_string, "b"))
281 size = 1;
282 else if (!strcmp(db_tok_string, "h"))
283 size = 2;
284 else if (!strcmp(db_tok_string, "l"))
285 size = 4;
286 else
287 goto bad_modifier;
288 } else {
289 db_unread_token(t);
290 size = 4;
291 }
292
4c45483e 293 if (!db_expression((db_expr_t *)&addr)) {
15637ed4
RG
294 db_printf("Address missing\n");
295 db_flush_lex();
296 return;
297 }
298
299 if (!db_expression(&value)) {
300 db_printf("Value missing\n");
301 db_flush_lex();
302 return;
303 }
304
305 if (!db_expression(&mask))
fde1aeb2 306 mask = 0xffffffffUL;
15637ed4
RG
307
308 t = db_read_token();
309 if (t == tCOMMA) {
310 if (!db_expression(&count)) {
311 db_printf("Count missing\n");
312 db_flush_lex();
313 return;
314 }
315 } else {
316 db_unread_token(t);
317 count = -1; /* effectively forever */
318 }
319 db_skip_to_eol();
320
321 db_search(addr, size, value, mask, count);
322}
323
4c45483e 324static void
15637ed4
RG
325db_search(addr, size, value, mask, count)
326 register
327 db_addr_t addr;
328 int size;
329 db_expr_t value;
330 db_expr_t mask;
331 unsigned int count;
332{
333 while (count-- != 0) {
334 db_prev = addr;
335 if ((db_get_value(addr, size, FALSE) & mask) == value)
336 break;
337 addr += size;
338 }
339 db_next = addr;
340}