void db_bus_write_cmd(db_expr_t addr, bool have_addr, db_expr_t count, const char *modif) { db_expr_t datum; bus_space_tag_t iot = &iobus_bs_tag; /* XXX */ bus_space_handle_t ioh; if (!have_addr) db_error("target address must be specified"); bus_space_map(iot, addr, 1, 0, &ioh); while (db_expression(&datum)) { switch (*modif) { case 'b': bus_space_write_1(iot, ioh, 0, datum); break; case '\0': case 'h': bus_space_write_2(iot, ioh, 0, datum); break; default: db_error("bad modifier"); } } bus_space_unmap(iot, ioh, 1); db_skip_to_eol(); }
/*ARGSUSED*/ void db_write_cmd(db_expr_t address, boolean_t have_addr, db_expr_t count, char *modif) { db_addr_t addr; db_expr_t old_value; db_expr_t new_value; int size; boolean_t wrote_one = FALSE; char tmpfmt[28]; addr = (db_addr_t) address; switch (modif[0]) { case 'b': size = 1; break; case 'h': size = 2; break; case 'l': case '\0': size = 4; break; #ifdef __LP64__ case 'q': size = 8; break; #endif default: size = -1; db_error("Unknown size\n"); /*NOTREACHED*/ } while (db_expression(&new_value)) { old_value = db_get_value(addr, size, FALSE); db_printsym(addr, DB_STGY_ANY, db_printf); db_printf("\t\t%s\t", db_format(tmpfmt, sizeof tmpfmt, old_value, DB_FORMAT_N, 0, 8)); db_printf("=\t%s\n", db_format(tmpfmt, sizeof tmpfmt, new_value, DB_FORMAT_N, 0, 8)); db_put_value(addr, size, new_value); addr += size; wrote_one = TRUE; } if (!wrote_one) { db_error("Nothing written.\n"); /*NOTREACHED*/ } db_next = addr; db_prev = addr - size; db_skip_to_eol(); }
/* * Call random function: * !expr(arg,arg,arg) */ static void db_fncall(db_expr_t dummy1, boolean_t dummy2, db_expr_t dummy3, char *dummy4) { db_expr_t fn_addr; #define MAXARGS 11 /* XXX only 10 are passed */ db_expr_t args[MAXARGS]; int nargs = 0; db_expr_t retval; typedef db_expr_t fcn_10args_t (db_expr_t, db_expr_t, db_expr_t, db_expr_t, db_expr_t, db_expr_t, db_expr_t, db_expr_t, db_expr_t, db_expr_t); fcn_10args_t *func; int t; if (!db_expression(&fn_addr)) { db_printf("Bad function\n"); db_flush_lex(); return; } func = (fcn_10args_t *)fn_addr; /* XXX */ t = db_read_token(); if (t == tLPAREN) { if (db_expression(&args[0])) { nargs++; while ((t = db_read_token()) == tCOMMA) { if (nargs == MAXARGS) { db_printf("Too many arguments\n"); db_flush_lex(); return; } if (!db_expression(&args[nargs])) { db_printf("Argument missing\n"); db_flush_lex(); return; } nargs++; } db_unread_token(t); } if (db_read_token() != tRPAREN) { db_printf("?\n"); db_flush_lex(); return; } } db_skip_to_eol(); while (nargs < MAXARGS) { args[nargs++] = 0; } retval = (*func)(args[0], args[1], args[2], args[3], args[4], args[5], args[6], args[7], args[8], args[9] ); db_printf("%#lr\n", (long)retval); }
/*ARGSUSED*/ void db_write_cmd(db_expr_t address, bool have_addr, db_expr_t count, const char *modif) { db_addr_t addr; db_expr_t old_value; db_expr_t new_value; int size; bool wrote_one; bool show_old_val; addr = (db_addr_t) address; wrote_one = false; show_old_val = islower((unsigned char)modif[0]); switch (tolower((unsigned char)modif[0])) { case 'b': size = 1; break; case 'h': size = 2; break; case 'l': case '\0': size = 4; break; default: size = -1; db_error("Unknown size\n"); /*NOTREACHED*/ } while (db_expression(&new_value)) { db_printsym(addr, DB_STGY_ANY, db_printf); if (show_old_val) { old_value = db_get_value(addr, size, false); db_printf("\t\t%s = ", db_num_to_str(old_value)); db_printf("%s\n", db_num_to_str(new_value)); } else db_printf("\t\t= %s\n", db_num_to_str(new_value)); db_put_value(addr, size, new_value); addr += size; wrote_one = true; } if (!wrote_one) { db_error("Nothing written.\n"); /*NOTREACHED*/ } db_next = addr; db_prev = addr - size; db_skip_to_eol(); }
/*ARGSUSED*/ void db_fncall(db_expr_t addr, int have_addr, db_expr_t count, char *modif) { db_expr_t fn_addr; #define MAXARGS 11 db_expr_t args[MAXARGS]; int nargs = 0; db_expr_t retval; db_expr_t (*func)(db_expr_t, ...); int t; char tmpfmt[28]; if (!db_expression(&fn_addr)) { db_printf("Bad function\n"); db_flush_lex(); return; } func = (db_expr_t (*)(db_expr_t, ...)) fn_addr; t = db_read_token(); if (t == tLPAREN) { if (db_expression(&args[0])) { nargs++; while ((t = db_read_token()) == tCOMMA) { if (nargs == MAXARGS) { db_printf("Too many arguments\n"); db_flush_lex(); return; } if (!db_expression(&args[nargs])) { db_printf("Argument missing\n"); db_flush_lex(); return; } nargs++; } db_unread_token(t); } if (db_read_token() != tRPAREN) { db_printf("?\n"); db_flush_lex(); return; } } db_skip_to_eol(); while (nargs < MAXARGS) { args[nargs++] = 0; } retval = (*func)(args[0], args[1], args[2], args[3], args[4], args[5], args[6], args[7], args[8], args[9]); db_printf("%s\n", db_format(tmpfmt, sizeof tmpfmt, retval, DB_FORMAT_N, 1, 0)); }
/* * Print or set a named script, with the set portion broken out into its own * function. We must directly access the remainder of the DDB line input as * we do not wish to use db_lex's token processing. */ void db_script_cmd(db_expr_t addr, boolean_t have_addr, db_expr_t count, char *modif) { char *buf, scriptname[DB_MAXSCRIPTNAME]; struct ddb_script *dsp; int error, t; t = db_read_token(); if (t != tIDENT) { db_printf("usage: script scriptname=script\n"); db_skip_to_eol(); return; } if (strlcpy(scriptname, db_tok_string, sizeof(scriptname)) >= sizeof(scriptname)) { db_printf("scriptname too long\n"); db_skip_to_eol(); return; } t = db_read_token(); if (t == tEOL) { dsp = db_script_lookup(scriptname); if (dsp == NULL) { db_printf("script '%s' not found\n", scriptname); db_skip_to_eol(); return; } db_printf("%s=%s\n", scriptname, dsp->ds_script); } else if (t == tEQ) { buf = db_get_line(); if (buf[strlen(buf)-1] == '\n') buf[strlen(buf)-1] = '\0'; error = db_script_set(scriptname, buf); if (error != 0) db_printf("Error: %d\n", error); } else db_printf("?\n"); db_skip_to_eol(); }
/* * Remove a named script. */ void db_unscript_cmd(db_expr_t addr, boolean_t have_addr, db_expr_t count, char *modif) { int error, t; t = db_read_token(); if (t != tIDENT) { db_printf("?\n"); db_skip_to_eol(); return; } error = db_script_unset(db_tok_string); if (error == ENOENT) { db_printf("script '%s' not found\n", db_tok_string); db_skip_to_eol(); return; } db_skip_to_eol(); }
/*ARGSUSED*/ void db_watchpoint_cmd(db_expr_t addr, int have_addr, db_expr_t count, char *modif) { vsize_t size; db_expr_t value; if (db_expression(&value)) size = (vsize_t) value; else size = 4; db_skip_to_eol(); db_set_watchpoint(addr, size); }
/*ARGSUSED*/ void db_write_cmd(db_expr_t address, boolean_t have_addr, db_expr_t count, char *modif) { db_addr_t addr; db_expr_t old_value; db_expr_t new_value; int size; boolean_t wrote_one = FALSE; addr = (db_addr_t) address; switch (modif[0]) { case 'b': size = 1; break; case 'h': size = 2; break; case 'l': case '\0': size = 4; break; default: db_error("Unknown size\n"); return; } while (db_expression(&new_value)) { old_value = db_get_value(addr, size, FALSE); db_printsym(addr, DB_STGY_ANY); db_printf("\t\t%s = ", db_num_to_str(old_value)); db_printf("%s\n", db_num_to_str(new_value)); db_put_value(addr, size, new_value); addr += size; wrote_one = TRUE; } if (!wrote_one) db_error("Nothing written.\n"); db_next = addr; db_prev = addr - size; db_skip_to_eol(); }
void db_command(struct db_command **last_cmdp, struct db_command *cmd_table) { struct db_command *cmd; int t; char modif[TOK_STRING_SIZE]; db_expr_t addr, count; boolean_t have_addr = FALSE; int result; t = db_read_token(); if (t == tEOL) { /* empty line repeats last command, at 'next' */ cmd = *last_cmdp; addr = (db_expr_t)db_next; have_addr = FALSE; count = 1; modif[0] = '\0'; } else if (t == tEXCL) { db_fncall(0, 0, 0, NULL); return; } else if (t != tIDENT) { db_printf("?\n"); db_flush_lex(); return; } else { /* * Search for command */ while (cmd_table) { result = db_cmd_search(db_tok_string, cmd_table, &cmd); switch (result) { case CMD_NONE: db_printf("No such command\n"); db_flush_lex(); return; case CMD_AMBIGUOUS: db_printf("Ambiguous\n"); db_flush_lex(); return; default: break; } if ((cmd_table = cmd->more) != 0) { t = db_read_token(); if (t != tIDENT) { db_cmd_list(cmd_table); db_flush_lex(); return; } } } if ((cmd->flag & CS_OWN) == 0) { /* * Standard syntax: * command [/modifier] [addr] [,count] */ t = db_read_token(); if (t == tSLASH) { t = db_read_token(); if (t != tIDENT) { db_printf("Bad modifier\n"); db_flush_lex(); return; } db_strlcpy(modif, db_tok_string, sizeof(modif)); } else { db_unread_token(t); modif[0] = '\0'; } if (db_expression(&addr)) { db_dot = (db_addr_t) addr; db_last_addr = db_dot; have_addr = TRUE; } else { addr = (db_expr_t) db_dot; have_addr = FALSE; } t = db_read_token(); if (t == tCOMMA) { if (!db_expression(&count)) { db_printf("Count missing\n"); db_flush_lex(); return; } } else { db_unread_token(t); count = -1; } if ((cmd->flag & CS_MORE) == 0) { db_skip_to_eol(); } } } *last_cmdp = cmd; if (cmd != 0) { /* * Execute the command. */ (*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 (db_ed_style) { db_dot = db_prev; } else { db_dot = db_next; } } else { /* * If command does not change dot, * set 'next' location to be the same. */ db_next = db_dot; } } }
/*ARGSUSED*/ void db_search_cmd(db_expr_t daddr, int have_addr, db_expr_t dcount, char *modif) { int t; db_addr_t addr; int size; db_expr_t value; db_expr_t mask; db_expr_t count; t = db_read_token(); if (t == tSLASH) { t = db_read_token(); if (t != tIDENT) { bad_modifier: db_printf("Bad modifier\n"); db_flush_lex(); return; } if (!strcmp(db_tok_string, "b")) size = 1; else if (!strcmp(db_tok_string, "h")) size = 2; else if (!strcmp(db_tok_string, "l")) size = 4; else goto bad_modifier; } else { db_unread_token(t); size = 4; } if (!db_expression(&value)) { db_printf("Address missing\n"); db_flush_lex(); return; } addr = (db_addr_t) value; if (!db_expression(&value)) { db_printf("Value missing\n"); db_flush_lex(); return; } if (!db_expression(&mask)) mask = (int) ~0; t = db_read_token(); if (t == tCOMMA) { if (!db_expression(&count)) { db_printf("Count missing\n"); db_flush_lex(); return; } } else { db_unread_token(t); count = -1; /* forever */ } db_skip_to_eol(); db_search(addr, size, value, mask, count); }