* Copyright (c) 1991,1990 Carnegie Mellon University
* Permission to use, copy, modify and distribute this software and its
* documentation is hereby granted, provided that both the copyright
* notice and this permission notice appear in all copies of the
* software, derivative works or modified versions, and any portions
* thereof, and that both notices appear in supporting documentation.
* CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS
* CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
* ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
* Carnegie Mellon requests users of this software to return to
* Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
* School of Computer Science
* Carnegie Mellon University
* Pittsburgh PA 15213-3890
* any improvements or extensions that they make and grant Carnegie the
* rights to redistribute these changes.
* PATCHES MAGIC LEVEL PATCH THAT GOT US HERE
* -------------------- ----- ----------------------
* CURRENT PATCH LEVEL: 1 00081
* -------------------- ----- ----------------------
* 01 Feb 93 Julian Elischer move strcmp to a more general
* Revision 1.1 1992/03/25 21:45:02 pace
* Revision 2.6 91/02/05 17:06:10 mrt
* Changed to new Mach copyright
* [91/01/31 16:17:18 mrt]
* Revision 2.5 91/01/08 17:31:54 rpd
* Forward reference for db_fncall();
* [91/01/04 12:35:17 rvb]
* Add call as a synonym for ! and match for next
* [91/01/04 12:14:48 rvb]
* Revision 2.4 90/11/07 16:49:15 rpd
* Revision 2.3 90/10/25 14:43:45 rwd
* Changed db_fncall to print the result unsigned.
* Added CS_MORE to db_watchpoint_cmd.
* Added watchpoint commands: watch, dwatch, show watches.
* Revision 2.2 90/08/27 21:50:10 dbg
* Remove 'listbreaks' - use 'show breaks' instead. Change 'show
* threads' to 'show all threads' to avoid clash with 'show thread'.
* Set 'dot' here from db_prev or db_next, depending on 'db_ed_style'
* Author: David B. Golub, Carnegie Mellon University
#include <machine/db_machdep.h> /* type definitions */
#include <ddb/db_output.h>
* Exported global variables
boolean_t db_cmd_loop_done
;
* if 'ed' style: 'dot' is set at start of last item printed,
* and '+' points to next line.
* Otherwise: 'dot' points to next item, '..' points to last.
boolean_t db_ed_style
= TRUE
;
* Utility routine - discard tokens through end-of-line.
char * name
; /* command name */
void (*fcn
)(); /* function to call */
int flag
; /* extra info: */
#define CS_OWN 0x1 /* non-standard syntax */
#define CS_MORE 0x2 /* standard syntax, but may have other
#define CS_SET_DOT 0x100 /* set dot after command */
struct command
*more
; /* another level of command */
* Results of command search.
* Search for command prefix.
db_cmd_search(name
, table
, cmdp
)
struct command
**cmdp
; /* out */
for (cmd
= table
; cmd
->name
!= 0; cmd
++) {
while ((c
= *lp
) == *rp
) {
/* end of name, not end of command -
if (result
== CMD_FOUND
) {
/* but keep looking for a full match -
this lets us match single letters */
if (result
== CMD_NONE
) {
if (name
[0] == 'h' && name
[1] == 'e'
&& name
[2] == 'l' && name
[3] == 'p')
register struct command
*cmd
;
for (cmd
= table
; cmd
->name
!= 0; cmd
++) {
db_printf("%-12s", cmd
->name
);
db_command(last_cmdp
, cmd_table
)
struct command
**last_cmdp
; /* IN_OUT */
struct command
*cmd_table
;
char modif
[TOK_STRING_SIZE
];
/* empty line repeats last command, at 'next' */
addr
= (db_expr_t
)db_next
;
result
= db_cmd_search(db_tok_string
,
db_printf("No such command\n");
db_printf("Ambiguous\n");
if ((cmd_table
= cmd
->more
) != 0) {
if ((cmd
->flag
& CS_OWN
) == 0) {
* command [/modifier] [addr] [,count]
db_printf("Bad modifier\n");
db_strcpy(modif
, db_tok_string
);
if (db_expression(&addr
)) {
db_dot
= (db_addr_t
) addr
;
addr
= (db_expr_t
) db_dot
;
if (!db_expression(&count
)) {
db_printf("Count missing\n");
if ((cmd
->flag
& CS_MORE
) == 0) {
(*cmd
->fcn
)(addr
, have_addr
, count
, modif
);
if (cmd
->flag
& CS_SET_DOT
) {
* If command changes dot, set dot to
* previous address displayed (if 'ed' style).
* If command does not change dot,
* set 'next' location to be the same.
extern void db_listbreak_cmd();
extern void db_listwatch_cmd();
extern void db_show_regs(), db_show_one_thread(), db_show_all_threads();
extern void vm_map_print(), vm_object_print(), vm_page_print();
extern void ipc_port_print();
struct command db_show_all_cmds
[] = {
{ "threads", db_show_all_threads
,0, 0 },
struct command db_show_cmds
[] = {
{ "all", 0, 0, db_show_all_cmds
},
{ "registers", db_show_regs
, 0, 0 },
{ "breaks", db_listbreak_cmd
, 0, 0 },
{ "watches", db_listwatch_cmd
, 0, 0 },
{ "thread", db_show_one_thread
, 0, 0 },
{ "map", vm_map_print
, 0, 0 },
{ "object", vm_object_print
, 0, 0 },
{ "page", vm_page_print
, 0, 0 },
{ "port", ipc_port_print
, 0, 0 },
extern void db_print_cmd(), db_examine_cmd(), db_set_cmd();
extern void db_search_cmd();
extern void db_write_cmd();
extern void db_delete_cmd(), db_breakpoint_cmd();
extern void db_deletewatch_cmd(), db_watchpoint_cmd();
extern void db_single_step_cmd(), db_trace_until_call_cmd(),
db_trace_until_matching_cmd(), db_continue_cmd();
extern void db_stack_trace_cmd();
struct command db_command_table
[] = {
{ "print", db_print_cmd
, 0, 0 },
{ "examine", db_examine_cmd
, CS_SET_DOT
, 0 },
{ "x", db_examine_cmd
, CS_SET_DOT
, 0 },
{ "search", db_search_cmd
, CS_OWN
|CS_SET_DOT
, 0 },
{ "set", db_set_cmd
, CS_OWN
, 0 },
{ "write", db_write_cmd
, CS_MORE
|CS_SET_DOT
, 0 },
{ "w", db_write_cmd
, CS_MORE
|CS_SET_DOT
, 0 },
{ "delete", db_delete_cmd
, 0, 0 },
{ "d", db_delete_cmd
, 0, 0 },
{ "break", db_breakpoint_cmd
, 0, 0 },
{ "dwatch", db_deletewatch_cmd
, 0, 0 },
{ "watch", db_watchpoint_cmd
, CS_MORE
,0 },
{ "step", db_single_step_cmd
, 0, 0 },
{ "s", db_single_step_cmd
, 0, 0 },
{ "continue", db_continue_cmd
, 0, 0 },
{ "c", db_continue_cmd
, 0, 0 },
{ "until", db_trace_until_call_cmd
,0, 0 },
{ "next", db_trace_until_matching_cmd
,0, 0 },
{ "match", db_trace_until_matching_cmd
,0, 0 },
{ "trace", db_stack_trace_cmd
, 0, 0 },
{ "call", db_fncall
, CS_OWN
, 0 },
{ "show", 0, 0, db_show_cmds
},
struct command
*db_last_command
= 0;
struct command
*cmd
= db_command_table
;
db_printf("%-12s", cmd
->name
);
* Initialize 'prev' and 'next' to dot.
while (!db_cmd_loop_done
) {
(void) setjmp(db_jmpbuf
);
if (db_print_position() != 0)
db_command(&db_last_command
, db_command_table
);
if (!db_expression(&fn_addr
)) {
db_printf("Bad function\n");
func
= (db_expr_t (*) ()) fn_addr
;
if (db_expression(&args
[0])) {
while ((t
= db_read_token()) == tCOMMA
) {
db_printf("Too many arguments\n");
if (!db_expression(&args
[nargs
])) {
db_printf("Argument missing\n");
if (db_read_token() != tRPAREN
) {
while (nargs
< MAXARGS
) {
retval
= (*func
)(args
[0], args
[1], args
[2], args
[3], args
[4],
args
[5], args
[6], args
[7], args
[8], args
[9] );
db_printf("%#n\n", retval
);