void db_cond_cmd(void) { register int c; register struct db_cond *cp; register char *p; db_expr_t value; db_thread_breakpoint_t bkpt; if (db_read_token() != tHASH || db_read_token() != tNUMBER) { db_printf("#<number> expected instead of \"%s\"\n", db_tok_string); db_error(0); return; } if ((bkpt = db_find_breakpoint_number(db_tok_number, 0)) == 0) { db_printf("No such break point #%d\n", db_tok_number); db_error(0); return; } /* * if the break point already has a condition, free it first */ if (bkpt->tb_cond > 0) { cp = &db_cond[bkpt->tb_cond - 1]; db_cond_free(bkpt); } else { if (db_ncond_free <= 0) { db_error("Too many conditions\n"); return; } for (cp = db_cond; cp < &db_cond[DB_MAX_COND]; cp++) if (cp->c_size == 0) break; if (cp >= &db_cond[DB_MAX_COND]) panic("bad db_cond_free"); } for (c = db_read_char(); c == ' ' || c == '\t'; c = db_read_char()); for (p = cp->c_cond_cmd; c >= 0; c = db_read_char()) *p++ = c; /* * switch to saved data and call db_expression to check the condition. * If no condition is supplied, db_expression will return false. * In this case, clear previous condition of the break point. * If condition is supplied, set the condition to the permanent area. * Note: db_expression will not return here, if the condition * expression is wrong. */ db_switch_input(cp->c_cond_cmd, p - cp->c_cond_cmd); if (!db_expression(&value)) { /* since condition is already freed, do nothing */ db_flush_lex(); return; } db_flush_lex(); db_ncond_free--; cp->c_size = p - cp->c_cond_cmd; bkpt->tb_cond = (cp - db_cond) + 1; }
/* * 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_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)); }
int db_parse_name(void) { int t, rv = 1; memset(scope, 0, sizeof scope); do { t = db_read_token(); if (t == tIDENT) { if (strlcat(scope, db_tok_string, sizeof scope) >= sizeof scope) { printf("Input too long\n"); goto error; } t = db_read_token(); if (t == tDOT) if (strlcat(scope, ".", sizeof scope) >= sizeof scope) { printf("Input too long 2\n"); goto error; } } } while (t != tEOL); if (!strlen(scope)) { db_printf("Invalid input\n"); goto error; } rv = 0; error: /* get rid of the rest of input */ db_flush_lex(); return (rv); }
void db_error(char *s) { if (s) db_printf("%s", s); db_flush_lex(); longjmp(db_jmpbuf, 1); }
void db_error(char *s) { if (s) db_printf("%s", s); db_flush_lex(); if (db_recover != NULL) longjmp(db_recover); }
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); }
static void bxe_ddb(db_expr_t blah1, boolean_t blah2, db_expr_t blah3, char *blah4) { char if_xname[IFNAMSIZ]; struct ifnet *ifp = NULL; struct bxe_softc *sc; db_expr_t next_arg; int index; int tok; int mod_phys_addr = FALSE; int mod_virt_addr = FALSE; db_addr_t addr; tok = db_read_token(); if (tok == tSLASH) { tok = db_read_token(); if (tok != tIDENT) { db_printf("ERROR: bad modifier\n"); bxe_ddb_usage(); goto bxe_ddb_done; } if (strcmp(db_tok_string, "h") == 0) { bxe_ddb_usage(); goto bxe_ddb_done; } else if (strcmp(db_tok_string, "p") == 0) { mod_phys_addr = TRUE; } else if (strcmp(db_tok_string, "v") == 0) { mod_virt_addr = TRUE; } } else { db_unread_token(tok); } if (!db_expression((db_expr_t *)&index)) { db_printf("ERROR: bxe index missing\n"); bxe_ddb_usage(); goto bxe_ddb_done; } snprintf(if_xname, sizeof(if_xname), "bxe%d", index); if ((ifp = ifunit_ref(if_xname)) == NULL) { db_printf("ERROR: Invalid interface %s\n", if_xname); goto bxe_ddb_done; } sc = (struct bxe_softc *)ifp->if_softc; db_printf("ifnet=%p (%s)\n", ifp, if_xname); db_printf("softc=%p\n", sc); db_printf(" dev=%p\n", sc->dev); db_printf(" BDF=%d:%d:%d\n", sc->pcie_bus, sc->pcie_device, sc->pcie_func); if (mod_phys_addr || mod_virt_addr) { if (!db_expression((db_addr_t *)&addr)) { db_printf("ERROR: Invalid address\n"); bxe_ddb_usage(); goto bxe_ddb_done; } db_printf("addr=%p", addr); } bxe_ddb_done: db_flush_lex(); if (ifp) if_rele(ifp); }
/* * Search for a value in memory. * Syntax: search [/bhl] addr value [mask] [,count] [thread] */ void db_search_cmd(void) { int t; db_addr_t addr; int size = 0; db_expr_t value; db_expr_t mask; db_addr_t count; thread_act_t thr_act; boolean_t thread_flag = FALSE; register char *p; t = db_read_token(); if (t == tSLASH) { t = db_read_token(); if (t != tIDENT) { bad_modifier: db_printf("Bad modifier \"/%s\"\n", db_tok_string); db_flush_lex(); return; } for (p = db_tok_string; *p; p++) { switch(*p) { case 'b': size = sizeof(char); break; case 'h': size = sizeof(short); break; case 'l': size = sizeof(long); break; case 't': thread_flag = TRUE; break; default: goto bad_modifier; } } } else { db_unread_token(t); size = sizeof(int); } if (!db_expression((db_expr_t *) &addr)) { db_printf("Address missing\n"); db_flush_lex(); return; } if (!db_expression(&value)) { db_printf("Value missing\n"); db_flush_lex(); return; } if (!db_expression(&mask)) mask = ~0; t = db_read_token(); if (t == tCOMMA) { if (!db_expression((db_expr_t *) &count)) { db_printf("Count missing\n"); db_flush_lex(); return; } } else { db_unread_token(t); count = -1; /* effectively forever */ } if (thread_flag) { if (!db_get_next_act(&thr_act, 0)) return; } else thr_act = THR_ACT_NULL; db_search(addr, size, value, mask, count, db_act_to_task(thr_act)); }
int db_lex(void) { int c; c = db_read_char(); while (c <= ' ' || c > '~') { if (c == '\n' || c == -1) return (tEOL); c = db_read_char(); } if (c >= '0' && c <= '9') { /* number */ int r, digit = 0; if (c > '0') r = db_radix; else { c = db_read_char(); if (c == 'O' || c == 'o') r = 8; else if (c == 'T' || c == 't') r = 10; else if (c == 'X' || c == 'x') r = 16; else { r = db_radix; db_unread_char(c); } c = db_read_char(); } db_tok_number = 0; for (;;) { if (c >= '0' && c <= ((r == 8) ? '7' : '9')) digit = c - '0'; else if (r == 16 && ((c >= 'A' && c <= 'F') || (c >= 'a' && c <= 'f'))) { if (c >= 'a') digit = c - 'a' + 10; else if (c >= 'A') digit = c - 'A' + 10; } else break; db_tok_number = db_tok_number * r + digit; c = db_read_char(); } if ((c >= '0' && c <= '9') || (c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z') || (c == '_')) { db_error("Bad character in number\n"); /*NOTREACHED*/ } db_unread_char(c); return (tNUMBER); } if ((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z') || c == '_' || c == '\\') { /* string */ char *cp; cp = db_tok_string; if (c == '\\') { c = db_read_char(); if (c == '\n' || c == -1) { db_error("Bad escape\n"); /*NOTREACHED*/ } } *cp++ = c; while (1) { c = db_read_char(); if ((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z') || (c >= '0' && c <= '9') || c == '_' || c == '\\' || c == ':') { if (c == '\\') { c = db_read_char(); if (c == '\n' || c == -1) { db_error("Bad escape\n"); /*NOTREACHED*/ } } *cp++ = c; if (cp == db_tok_string+sizeof(db_tok_string)) { db_error("String too long\n"); /*NOTREACHED*/ } continue; } else { *cp = '\0'; break; } } db_unread_char(c); return (tIDENT); } switch (c) { case '+': return (tPLUS); case '-': return (tMINUS); case '.': c = db_read_char(); if (c == '.') return (tDOTDOT); db_unread_char(c); return (tDOT); case '*': return (tSTAR); case '/': return (tSLASH); case '=': return (tEQ); case '%': return (tPCT); case '#': return (tHASH); case '(': return (tLPAREN); case ')': return (tRPAREN); case ',': return (tCOMMA); case '"': return (tDITTO); case '$': return (tDOLLAR); case '!': return (tEXCL); case '<': c = db_read_char(); if (c == '<') return (tSHIFT_L); db_unread_char(c); break; case '>': c = db_read_char(); if (c == '>') return (tSHIFT_R); db_unread_char(c); break; case -1: return (tEOF); } db_printf("Bad character\n"); db_flush_lex(); return (tEOF); }