Commit | Line | Data |
---|---|---|
984263bc MD |
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 | * $FreeBSD: src/sys/ddb/db_command.c,v 1.34.2.2 2001/07/29 22:48:36 kris Exp $ | |
27 | */ | |
28 | ||
29 | /* | |
30 | * Author: David B. Golub, Carnegie Mellon University | |
31 | * Date: 7/90 | |
32 | */ | |
33 | ||
34 | /* | |
35 | * Command dispatcher. | |
36 | */ | |
37 | #include <sys/param.h> | |
38 | #include <sys/linker_set.h> | |
39 | #include <sys/reboot.h> | |
40 | #include <sys/systm.h> | |
41 | #include <sys/cons.h> | |
42 | ||
43 | #include <ddb/ddb.h> | |
44 | #include <ddb/db_command.h> | |
45 | #include <ddb/db_lex.h> | |
46 | #include <ddb/db_output.h> | |
47 | ||
6bd9bbba | 48 | #include <machine/md_var.h> /* needed for db_reset() */ |
09c0e0d6 | 49 | #include <machine/setjmp.h> |
984263bc MD |
50 | |
51 | /* | |
52 | * Exported global variables | |
53 | */ | |
54 | boolean_t db_cmd_loop_done; | |
984263bc MD |
55 | db_addr_t db_dot; |
56 | jmp_buf db_jmpbuf; | |
57 | db_addr_t db_last_addr; | |
58 | db_addr_t db_prev; | |
59 | db_addr_t db_next; | |
dc62b251 MD |
60 | |
61 | SET_DECLARE(db_cmd_set, struct command); | |
62 | SET_DECLARE(db_show_cmd_set, struct command); | |
984263bc MD |
63 | |
64 | static db_cmdfcn_t db_fncall; | |
65 | static db_cmdfcn_t db_gdb; | |
6bd9bbba | 66 | static db_cmdfcn_t db_reset; |
984263bc | 67 | |
35efc471 SW |
68 | /* |
69 | * 'show' commands | |
70 | */ | |
71 | ||
72 | static struct command db_show_all_cmds[] = { | |
73 | #if 0 | |
60d79925 | 74 | { "threads", db_show_all_threads, 0, NULL }, |
35efc471 | 75 | #endif |
60d79925 | 76 | { "procs", db_ps, 0, NULL }, |
35efc471 SW |
77 | { NULL } |
78 | }; | |
79 | ||
80 | static struct command db_show_cmds[] = { | |
81 | { "all", 0, 0, db_show_all_cmds }, | |
60d79925 SW |
82 | { "registers", db_show_regs, 0, NULL }, |
83 | { "breaks", db_listbreak_cmd, 0, NULL }, | |
35efc471 | 84 | #if 0 |
60d79925 | 85 | { "thread", db_show_one_thread, 0, NULL }, |
35efc471 SW |
86 | #endif |
87 | #if 0 | |
60d79925 | 88 | { "port", ipc_port_print, 0, NULL }, |
35efc471 SW |
89 | #endif |
90 | { NULL, } | |
91 | }; | |
92 | ||
93 | static struct command db_command_table[] = { | |
60d79925 SW |
94 | { "print", db_print_cmd, 0, NULL }, |
95 | { "p", db_print_cmd, 0, NULL }, | |
96 | { "examine", db_examine_cmd, CS_SET_DOT, NULL }, | |
97 | { "x", db_examine_cmd, CS_SET_DOT, NULL }, | |
98 | { "search", db_search_cmd, CS_OWN|CS_SET_DOT, NULL }, | |
99 | { "set", db_set_cmd, CS_OWN, NULL }, | |
100 | { "write", db_write_cmd, CS_MORE|CS_SET_DOT, NULL }, | |
101 | { "w", db_write_cmd, CS_MORE|CS_SET_DOT, NULL }, | |
102 | { "delete", db_delete_cmd, 0, NULL }, | |
103 | { "d", db_delete_cmd, 0, NULL }, | |
104 | { "break", db_breakpoint_cmd, 0, NULL }, | |
105 | { "dwatch", db_deletewatch_cmd, 0, NULL }, | |
106 | { "watch", db_watchpoint_cmd, CS_MORE,NULL }, | |
107 | { "dhwatch", db_deletehwatch_cmd, 0, NULL }, | |
108 | { "hwatch", db_hwatchpoint_cmd, 0, NULL }, | |
109 | { "step", db_single_step_cmd, 0, NULL }, | |
110 | { "s", db_single_step_cmd, 0, NULL }, | |
111 | { "continue", db_continue_cmd, 0, NULL }, | |
112 | { "c", db_continue_cmd, 0, NULL }, | |
abfdbc2b | 113 | { "i", db_invltlb_cmd, 0, NULL }, |
60d79925 SW |
114 | { "until", db_trace_until_call_cmd,0, NULL }, |
115 | { "next", db_trace_until_matching_cmd,0, NULL }, | |
116 | { "match", db_trace_until_matching_cmd,0, NULL }, | |
117 | { "trace", db_stack_trace_cmd, 0, NULL }, | |
118 | { "where", db_stack_trace_cmd, 0, NULL }, | |
119 | { "call", db_fncall, CS_OWN, NULL }, | |
35efc471 | 120 | { "show", 0, 0, db_show_cmds }, |
60d79925 SW |
121 | { "ps", db_ps, 0, NULL }, |
122 | { "gdb", db_gdb, 0, NULL }, | |
123 | { "reset", db_reset, 0, NULL }, | |
35efc471 SW |
124 | { NULL, } |
125 | }; | |
126 | ||
4090d6ff | 127 | static struct command *db_last_command = NULL; |
984263bc MD |
128 | |
129 | /* | |
130 | * if 'ed' style: 'dot' is set at start of last item printed, | |
131 | * and '+' points to next line. | |
132 | * Otherwise: 'dot' points to next item, '..' points to last. | |
133 | */ | |
134 | static boolean_t db_ed_style = TRUE; | |
135 | ||
136 | /* | |
137 | * Utility routine - discard tokens through end-of-line. | |
138 | */ | |
139 | void | |
2c9702b2 | 140 | db_skip_to_eol(void) |
984263bc MD |
141 | { |
142 | int t; | |
143 | do { | |
144 | t = db_read_token(); | |
145 | } while (t != tEOL); | |
146 | } | |
147 | ||
148 | /* | |
149 | * Results of command search. | |
150 | */ | |
151 | #define CMD_UNIQUE 0 | |
152 | #define CMD_FOUND 1 | |
153 | #define CMD_NONE 2 | |
154 | #define CMD_AMBIGUOUS 3 | |
155 | #define CMD_HELP 4 | |
156 | ||
43c0ece6 | 157 | static void db_cmd_list (struct command *table, |
dc62b251 MD |
158 | struct command **aux_tablep, |
159 | struct command **aux_tablep_end); | |
43c0ece6 | 160 | static int db_cmd_search (char *name, struct command *table, |
984263bc | 161 | struct command **aux_tablep, |
dc62b251 | 162 | struct command **aux_tablep_end, |
43c0ece6 RG |
163 | struct command **cmdp); |
164 | static void db_command (struct command **last_cmdp, | |
984263bc | 165 | struct command *cmd_table, |
dc62b251 MD |
166 | struct command **aux_cmd_tablep, |
167 | struct command **aux_cmd_tablep_end); | |
984263bc MD |
168 | |
169 | /* | |
170 | * Search for command prefix. | |
2c9702b2 SW |
171 | * |
172 | * Parameters: | |
173 | * cmdp: out | |
984263bc MD |
174 | */ |
175 | static int | |
2c9702b2 SW |
176 | db_cmd_search(char *name, struct command *table, struct command **aux_tablep, |
177 | struct command **aux_tablep_end, struct command **cmdp) | |
984263bc MD |
178 | { |
179 | struct command *cmd; | |
180 | struct command **aux_cmdp; | |
181 | int result = CMD_NONE; | |
182 | ||
183 | for (cmd = table; cmd->name != 0; cmd++) { | |
ad0290bd RG |
184 | char *lp; |
185 | char *rp; | |
186 | int c; | |
984263bc MD |
187 | |
188 | lp = name; | |
189 | rp = cmd->name; | |
190 | while ((c = *lp) == *rp) { | |
191 | if (c == 0) { | |
192 | /* complete match */ | |
193 | *cmdp = cmd; | |
194 | return (CMD_UNIQUE); | |
195 | } | |
196 | lp++; | |
197 | rp++; | |
198 | } | |
199 | if (c == 0) { | |
200 | /* end of name, not end of command - | |
201 | partial match */ | |
202 | if (result == CMD_FOUND) { | |
203 | result = CMD_AMBIGUOUS; | |
204 | /* but keep looking for a full match - | |
205 | this lets us match single letters */ | |
206 | } | |
207 | else { | |
208 | *cmdp = cmd; | |
209 | result = CMD_FOUND; | |
210 | } | |
211 | } | |
212 | } | |
4090d6ff | 213 | if (result == CMD_NONE && aux_tablep != NULL) |
984263bc | 214 | /* XXX repeat too much code. */ |
dc62b251 | 215 | for (aux_cmdp = aux_tablep; aux_cmdp < aux_tablep_end; aux_cmdp++) { |
ad0290bd RG |
216 | char *lp; |
217 | char *rp; | |
218 | int c; | |
984263bc MD |
219 | |
220 | lp = name; | |
221 | rp = (*aux_cmdp)->name; | |
222 | while ((c = *lp) == *rp) { | |
223 | if (c == 0) { | |
224 | /* complete match */ | |
225 | *cmdp = *aux_cmdp; | |
226 | return (CMD_UNIQUE); | |
227 | } | |
228 | lp++; | |
229 | rp++; | |
230 | } | |
231 | if (c == 0) { | |
232 | /* end of name, not end of command - | |
233 | partial match */ | |
234 | if (result == CMD_FOUND) { | |
235 | result = CMD_AMBIGUOUS; | |
236 | /* but keep looking for a full match - | |
237 | this lets us match single letters */ | |
238 | } | |
239 | else { | |
240 | *cmdp = *aux_cmdp; | |
241 | result = CMD_FOUND; | |
242 | } | |
243 | } | |
244 | } | |
245 | if (result == CMD_NONE) { | |
246 | /* check for 'help' */ | |
247 | if (name[0] == 'h' && name[1] == 'e' | |
248 | && name[2] == 'l' && name[3] == 'p') | |
249 | result = CMD_HELP; | |
250 | } | |
251 | return (result); | |
252 | } | |
253 | ||
254 | static void | |
2c9702b2 SW |
255 | db_cmd_list(struct command *table, struct command **aux_tablep, |
256 | struct command **aux_tablep_end) | |
984263bc | 257 | { |
ad0290bd RG |
258 | struct command *cmd; |
259 | struct command **aux_cmdp; | |
984263bc MD |
260 | |
261 | for (cmd = table; cmd->name != 0; cmd++) { | |
262 | db_printf("%-12s", cmd->name); | |
3734708d | 263 | db_end_line(12); |
984263bc | 264 | } |
4090d6ff | 265 | if (aux_tablep == NULL) |
984263bc | 266 | return; |
dc62b251 | 267 | for (aux_cmdp = aux_tablep; aux_cmdp < aux_tablep_end; aux_cmdp++) { |
984263bc | 268 | db_printf("%-12s", (*aux_cmdp)->name); |
3734708d | 269 | db_end_line(12); |
984263bc MD |
270 | } |
271 | } | |
272 | ||
2c9702b2 SW |
273 | /* |
274 | * Parameters: | |
275 | * last_cmdp: IN_OUT | |
276 | */ | |
984263bc | 277 | static void |
2c9702b2 SW |
278 | db_command(struct command **last_cmdp, struct command *cmd_table, |
279 | struct command **aux_cmd_tablep, struct command **aux_cmd_tablep_end) | |
984263bc MD |
280 | { |
281 | struct command *cmd; | |
282 | int t; | |
283 | char modif[TOK_STRING_SIZE]; | |
284 | db_expr_t addr, count; | |
285 | boolean_t have_addr = FALSE; | |
286 | int result; | |
287 | ||
d557216f | 288 | cmd = NULL; |
984263bc MD |
289 | t = db_read_token(); |
290 | if (t == tEOL) { | |
291 | /* empty line repeats last command, at 'next' */ | |
292 | cmd = *last_cmdp; | |
293 | addr = (db_expr_t)db_next; | |
294 | have_addr = FALSE; | |
295 | count = 1; | |
296 | modif[0] = '\0'; | |
297 | } | |
298 | else if (t == tEXCL) { | |
60233e58 | 299 | db_fncall((db_expr_t)0, (boolean_t)0, (db_expr_t)0, NULL); |
984263bc MD |
300 | return; |
301 | } | |
302 | else if (t != tIDENT) { | |
303 | db_printf("?\n"); | |
304 | db_flush_lex(); | |
305 | return; | |
306 | } | |
307 | else { | |
308 | /* | |
309 | * Search for command | |
310 | */ | |
311 | while (cmd_table) { | |
312 | result = db_cmd_search(db_tok_string, | |
313 | cmd_table, | |
314 | aux_cmd_tablep, | |
dc62b251 | 315 | aux_cmd_tablep_end, |
984263bc MD |
316 | &cmd); |
317 | switch (result) { | |
318 | case CMD_NONE: | |
319 | db_printf("No such command\n"); | |
320 | db_flush_lex(); | |
321 | return; | |
322 | case CMD_AMBIGUOUS: | |
323 | db_printf("Ambiguous\n"); | |
324 | db_flush_lex(); | |
325 | return; | |
326 | case CMD_HELP: | |
dc62b251 | 327 | db_cmd_list(cmd_table, aux_cmd_tablep, aux_cmd_tablep_end); |
984263bc MD |
328 | db_flush_lex(); |
329 | return; | |
330 | default: | |
331 | break; | |
332 | } | |
4090d6ff | 333 | if ((cmd_table = cmd->more) != NULL) { |
984263bc | 334 | /* XXX usually no more aux's. */ |
4090d6ff | 335 | aux_cmd_tablep = NULL; |
dc62b251 MD |
336 | if (cmd_table == db_show_cmds) { |
337 | aux_cmd_tablep = SET_BEGIN(db_show_cmd_set); | |
338 | aux_cmd_tablep_end = SET_LIMIT(db_show_cmd_set); | |
339 | } | |
984263bc MD |
340 | |
341 | t = db_read_token(); | |
342 | if (t != tIDENT) { | |
dc62b251 | 343 | db_cmd_list(cmd_table, aux_cmd_tablep, aux_cmd_tablep_end); |
984263bc MD |
344 | db_flush_lex(); |
345 | return; | |
346 | } | |
347 | } | |
348 | } | |
349 | ||
350 | if ((cmd->flag & CS_OWN) == 0) { | |
351 | /* | |
352 | * Standard syntax: | |
353 | * command [/modifier] [addr] [,count] | |
354 | */ | |
355 | t = db_read_token(); | |
356 | if (t == tSLASH) { | |
357 | t = db_read_token(); | |
337d8b07 | 358 | if (t != tIDENT && t != tNUMBER) { |
984263bc MD |
359 | db_printf("Bad modifier\n"); |
360 | db_flush_lex(); | |
361 | return; | |
362 | } | |
363 | db_strcpy(modif, db_tok_string); | |
364 | } | |
365 | else { | |
366 | db_unread_token(t); | |
367 | modif[0] = '\0'; | |
368 | } | |
369 | ||
370 | if (db_expression(&addr)) { | |
371 | db_dot = (db_addr_t) addr; | |
372 | db_last_addr = db_dot; | |
373 | have_addr = TRUE; | |
374 | } | |
375 | else { | |
376 | addr = (db_expr_t) db_dot; | |
377 | have_addr = FALSE; | |
378 | } | |
379 | t = db_read_token(); | |
380 | if (t == tCOMMA) { | |
381 | if (!db_expression(&count)) { | |
382 | db_printf("Count missing\n"); | |
383 | db_flush_lex(); | |
384 | return; | |
385 | } | |
386 | } | |
387 | else { | |
388 | db_unread_token(t); | |
389 | count = -1; | |
390 | } | |
391 | if ((cmd->flag & CS_MORE) == 0) { | |
392 | db_skip_to_eol(); | |
393 | } | |
394 | } | |
395 | } | |
396 | *last_cmdp = cmd; | |
4090d6ff | 397 | if (cmd != NULL) { |
984263bc MD |
398 | /* |
399 | * Execute the command. | |
400 | */ | |
401 | (*cmd->fcn)(addr, have_addr, count, modif); | |
402 | ||
403 | if (cmd->flag & CS_SET_DOT) { | |
404 | /* | |
405 | * If command changes dot, set dot to | |
406 | * previous address displayed (if 'ed' style). | |
407 | */ | |
408 | if (db_ed_style) { | |
409 | db_dot = db_prev; | |
410 | } | |
411 | else { | |
412 | db_dot = db_next; | |
413 | } | |
414 | } | |
415 | else { | |
416 | /* | |
417 | * If command does not change dot, | |
418 | * set 'next' location to be the same. | |
419 | */ | |
420 | db_next = db_dot; | |
421 | } | |
422 | } | |
423 | } | |
424 | ||
984263bc MD |
425 | #if 0 |
426 | void | |
2c9702b2 | 427 | db_help_cmd(void) |
984263bc MD |
428 | { |
429 | struct command *cmd = db_command_table; | |
430 | ||
431 | while (cmd->name != 0) { | |
432 | db_printf("%-12s", cmd->name); | |
3734708d | 433 | db_end_line(12); |
984263bc MD |
434 | cmd++; |
435 | } | |
436 | } | |
437 | #endif | |
438 | ||
439 | /* | |
440 | * At least one non-optional command must be implemented using | |
441 | * DB_COMMAND() so that db_cmd_set gets created. Here is one. | |
442 | */ | |
443 | DB_COMMAND(panic, db_panic) | |
444 | { | |
445 | panic("from debugger"); | |
446 | } | |
447 | ||
448 | void | |
2c9702b2 | 449 | db_command_loop(void) |
984263bc MD |
450 | { |
451 | /* | |
452 | * Initialize 'prev' and 'next' to dot. | |
453 | */ | |
ce7866b8 | 454 | cnpoll(TRUE); |
984263bc MD |
455 | db_prev = db_dot; |
456 | db_next = db_dot; | |
457 | ||
6f25fdab | 458 | db_cmd_loop_done = FALSE; |
984263bc MD |
459 | while (!db_cmd_loop_done) { |
460 | ||
2c9702b2 | 461 | setjmp(db_jmpbuf); |
984263bc MD |
462 | if (db_print_position() != 0) |
463 | db_printf("\n"); | |
464 | ||
465 | db_printf("db> "); | |
2c9702b2 | 466 | db_read_line(); |
984263bc MD |
467 | |
468 | db_command(&db_last_command, db_command_table, | |
dc62b251 | 469 | SET_BEGIN(db_cmd_set), SET_LIMIT(db_cmd_set)); |
984263bc | 470 | } |
ce7866b8 | 471 | cnpoll(FALSE); |
984263bc MD |
472 | } |
473 | ||
474 | void | |
2c9702b2 | 475 | db_error(char *s) |
984263bc MD |
476 | { |
477 | if (s) | |
478 | db_printf("%s", s); | |
479 | db_flush_lex(); | |
480 | longjmp(db_jmpbuf, 1); | |
481 | } | |
482 | ||
483 | ||
484 | /* | |
485 | * Call random function: | |
486 | * !expr(arg,arg,arg) | |
487 | */ | |
adf0eb4f MD |
488 | typedef union { |
489 | db_expr_t (*a0)(void); | |
490 | db_expr_t (*a1)(db_expr_t); | |
491 | db_expr_t (*a2)(db_expr_t, db_expr_t); | |
492 | db_expr_t (*a3)(db_expr_t, db_expr_t, db_expr_t); | |
493 | db_expr_t (*a4)(db_expr_t, db_expr_t, db_expr_t, db_expr_t); | |
494 | db_expr_t (*a5)(db_expr_t, db_expr_t, db_expr_t, db_expr_t, db_expr_t); | |
495 | db_expr_t (*a6)(db_expr_t, db_expr_t, db_expr_t, db_expr_t, db_expr_t, | |
496 | db_expr_t); | |
497 | db_expr_t (*a7)(db_expr_t, db_expr_t, db_expr_t, db_expr_t, db_expr_t, | |
498 | db_expr_t, db_expr_t); | |
499 | db_expr_t (*a8)(db_expr_t, db_expr_t, db_expr_t, db_expr_t, db_expr_t, | |
500 | db_expr_t, db_expr_t, db_expr_t); | |
501 | db_expr_t (*a9)(db_expr_t, db_expr_t, db_expr_t, db_expr_t, db_expr_t, | |
502 | db_expr_t, db_expr_t, db_expr_t, db_expr_t); | |
503 | db_expr_t (*a10)(db_expr_t, db_expr_t, db_expr_t, db_expr_t, db_expr_t, | |
504 | db_expr_t, db_expr_t, db_expr_t, db_expr_t, db_expr_t); | |
505 | } fcn_multiargs_t; | |
506 | ||
507 | ||
984263bc | 508 | static void |
2c9702b2 | 509 | db_fncall(db_expr_t dummy1, boolean_t dummy2, db_expr_t dummy3, char *dummy4) |
984263bc MD |
510 | { |
511 | db_expr_t fn_addr; | |
512 | #define MAXARGS 11 /* XXX only 10 are passed */ | |
513 | db_expr_t args[MAXARGS]; | |
514 | int nargs = 0; | |
515 | db_expr_t retval; | |
adf0eb4f | 516 | fcn_multiargs_t func; |
984263bc MD |
517 | int t; |
518 | ||
519 | if (!db_expression(&fn_addr)) { | |
520 | db_printf("Bad function\n"); | |
521 | db_flush_lex(); | |
522 | return; | |
523 | } | |
adf0eb4f | 524 | func.a0 = (void *)fn_addr; |
984263bc MD |
525 | |
526 | t = db_read_token(); | |
527 | if (t == tLPAREN) { | |
528 | if (db_expression(&args[0])) { | |
529 | nargs++; | |
530 | while ((t = db_read_token()) == tCOMMA) { | |
531 | if (nargs == MAXARGS) { | |
532 | db_printf("Too many arguments\n"); | |
533 | db_flush_lex(); | |
534 | return; | |
535 | } | |
536 | if (!db_expression(&args[nargs])) { | |
537 | db_printf("Argument missing\n"); | |
538 | db_flush_lex(); | |
539 | return; | |
540 | } | |
541 | nargs++; | |
542 | } | |
543 | db_unread_token(t); | |
544 | } | |
545 | if (db_read_token() != tRPAREN) { | |
546 | db_printf("?\n"); | |
547 | db_flush_lex(); | |
548 | return; | |
549 | } | |
550 | } | |
551 | db_skip_to_eol(); | |
552 | ||
adf0eb4f MD |
553 | /* |
554 | * This is mainly so kgdb doesn't get confused if ddb> call is | |
555 | * in its backtrace. | |
556 | */ | |
557 | switch(nargs) { | |
558 | case 0: | |
559 | retval = (*func.a0)(); | |
560 | break; | |
561 | case 1: | |
562 | retval = (*func.a1)(args[0]); | |
563 | break; | |
564 | case 2: | |
565 | retval = (*func.a2)(args[0], args[1]); | |
566 | break; | |
567 | case 3: | |
568 | retval = (*func.a3)(args[0], args[1], args[2]); | |
569 | break; | |
570 | case 4: | |
571 | retval = (*func.a4)(args[0], args[1], args[2], args[3]); | |
572 | break; | |
573 | case 5: | |
574 | retval = (*func.a5)(args[0], args[1], args[2], args[3], args[4]); | |
575 | break; | |
576 | case 6: | |
577 | retval = (*func.a6)(args[0], args[1], args[2], args[3], args[4], | |
578 | args[5]); | |
579 | break; | |
580 | case 7: | |
581 | retval = (*func.a7)(args[0], args[1], args[2], args[3], args[4], | |
582 | args[5], args[6]); | |
583 | break; | |
584 | case 8: | |
585 | retval = (*func.a8)(args[0], args[1], args[2], args[3], args[4], | |
586 | args[5], args[6], args[7]); | |
587 | break; | |
588 | case 9: | |
589 | retval = (*func.a9)(args[0], args[1], args[2], args[3], args[4], | |
590 | args[5], args[6], args[7], args[8]); | |
591 | break; | |
592 | case 10: | |
593 | retval = (*func.a10)(args[0], args[1], args[2], args[3], args[4], | |
594 | args[5], args[6], args[7], args[8], args[9]); | |
595 | break; | |
596 | default: | |
597 | db_printf("too many arguments\n"); | |
598 | retval = 0; | |
599 | break; | |
984263bc | 600 | } |
8d0b962d | 601 | db_printf("%s\n", db_num_to_str(retval)); |
984263bc MD |
602 | } |
603 | ||
604 | /* Enter GDB remote protocol debugger on the next trap. */ | |
605 | ||
984263bc | 606 | static void |
2c9702b2 | 607 | db_gdb(db_expr_t dummy1, boolean_t dummy2, db_expr_t dummy3, char *dummy4) |
984263bc | 608 | { |
ce81f184 | 609 | if (gdb_tab == NULL) { |
984263bc MD |
610 | db_printf("No gdb port enabled. Set flag 0x80 on desired port\n"); |
611 | db_printf("in your configuration file (currently sio only).\n"); | |
612 | return; | |
613 | } | |
614 | boothowto ^= RB_GDB; | |
615 | ||
616 | db_printf("Next trap will enter %s\n", | |
617 | boothowto & RB_GDB ? "GDB remote protocol mode" | |
618 | : "DDB debugger"); | |
619 | } | |
6bd9bbba HP |
620 | |
621 | static void | |
2c9702b2 SW |
622 | db_reset(db_expr_t dummy1, boolean_t dummy2, db_expr_t dummy3, char * dummy4) |
623 | { | |
624 | cpu_reset(); | |
6bd9bbba | 625 | } |