boolean_t db_shift_expr(db_expr_t *valuep) { db_expr_t lhs, rhs; int t; if (!db_add_expr(&lhs)) return (FALSE); t = db_read_token(); while (t == tSHIFT_L || t == tSHIFT_R) { if (!db_add_expr(&rhs)) { db_error("Syntax error\n"); /*NOTREACHED*/ } if (rhs < 0) { db_error("Negative shift amount\n"); /*NOTREACHED*/ } if (t == tSHIFT_L) lhs <<= rhs; else { /* Shift right is unsigned */ lhs = (unsigned) lhs >> rhs; } t = db_read_token(); } db_unread_token(t); *valuep = lhs; return (TRUE); }
boolean_t db_unary(db_expr_t *valuep) { int t; t = db_read_token(); if (t == tMINUS) { if (!db_unary(valuep)) { db_error("Syntax error\n"); /*NOTREACHED*/ } *valuep = -*valuep; return (TRUE); } if (t == tSTAR) { /* indirection */ if (!db_unary(valuep)) { db_error("Syntax error\n"); /*NOTREACHED*/ } *valuep = db_get_value((db_addr_t)*valuep, sizeof(int), FALSE); return (TRUE); } db_unread_token(t); return (db_term(valuep)); }
void db_set_cmd(db_expr_t dummy1, bool dummy2, db_expr_t dummy3, char *dummy4) { struct db_variable *vp; db_expr_t value; int t; t = db_read_token(); if (t != tDOLLAR) { db_error("Unknown variable\n"); return; } if (!db_find_variable(&vp)) { db_error("Unknown variable\n"); return; } t = db_read_token(); if (t != tEQ) db_unread_token(t); if (!db_expression(&value)) { db_error("No value\n"); return; } if (db_read_token() != tEOL) db_error("?\n"); db_write_variable(vp, value); }
/*ARGSUSED*/ void db_set_cmd(db_expr_t addr, int have_addr, db_expr_t count, char *modif) { db_expr_t value; struct db_variable *vp; int t; t = db_read_token(); if (t != tDOLLAR) { db_error("Unknown variable\n"); /*NOTREACHED*/ } if (!db_find_variable(&vp)) { db_error("Unknown variable\n"); /*NOTREACHED*/ } t = db_read_token(); if (t != tEQ) db_unread_token(t); if (!db_expression(&value)) { db_error("No value\n"); /*NOTREACHED*/ } if (db_read_token() != tEOL) { db_error("?\n"); /*NOTREACHED*/ } db_write_variable(vp, &value); }
boolean_t db_add_expr(db_expr_t *valuep) { db_expr_t lhs, rhs; int t; if (!db_mult_expr(&lhs)) return (FALSE); t = db_read_token(); while (t == tPLUS || t == tMINUS) { if (!db_mult_expr(&rhs)) { db_error("Syntax error\n"); /*NOTREACHED*/ } if (t == tPLUS) lhs += rhs; else lhs -= rhs; t = db_read_token(); } db_unread_token(t); *valuep = lhs; return (TRUE); }
boolean_t db_mult_expr(db_expr_t *valuep) { db_expr_t lhs, rhs; int t; if (!db_unary(&lhs)) return (FALSE); t = db_read_token(); while (t == tSTAR || t == tSLASH || t == tPCT || t == tHASH) { if (!db_term(&rhs)) { db_error("Syntax error\n"); /*NOTREACHED*/ } if (t == tSTAR) lhs *= rhs; else { if (rhs == 0) { db_error("Divide by 0\n"); /*NOTREACHED*/ } if (t == tSLASH) lhs /= rhs; else if (t == tPCT) lhs %= rhs; else lhs = ((lhs+rhs-1)/rhs)*rhs; } t = db_read_token(); } db_unread_token(t); *valuep = lhs; return (TRUE); }
void db_kill_proc(db_expr_t addr, bool haddr, db_expr_t count, const char *modif) { #ifdef _KERNEL /* XXX CRASH(8) */ struct proc *p; ksiginfo_t ksi; db_expr_t pid, sig; int t; /* What pid? */ if (!db_expression(&pid)) { db_error("pid?\n"); /*NOTREACHED*/ } /* What sig? */ t = db_read_token(); if (t == tCOMMA) { if (!db_expression(&sig)) { db_error("sig?\n"); /*NOTREACHED*/ } } else { db_unread_token(t); sig = 15; } if (db_read_token() != tEOL) { db_error("?\n"); /*NOTREACHED*/ } /* We might stop when the mutex is held or when not */ t = mutex_tryenter(proc_lock); #ifdef DIAGNOSTIC if (!t) { db_error("could not acquire proc_lock mutex\n"); /*NOTREACHED*/ } #endif p = proc_find((pid_t)pid); if (p == NULL) { if (t) mutex_exit(proc_lock); db_error("no such proc\n"); /*NOTREACHED*/ } KSI_INIT(&ksi); ksi.ksi_signo = sig; ksi.ksi_code = SI_USER; ksi.ksi_pid = 0; ksi.ksi_uid = 0; mutex_enter(p->p_lock); kpsignal2(p, &ksi); mutex_exit(p->p_lock); if (t) mutex_exit(proc_lock); #else db_printf("This command is not currently supported.\n"); #endif }
/* * 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); }
static boolean_t db_term(db_expr_t *valuep) { int t; t = db_read_token(); if (t == tIDENT) { if (!db_value_of_name(db_tok_string, valuep) && !db_value_of_name_pcpu(db_tok_string, valuep) && !db_value_of_name_vnet(db_tok_string, valuep)) { db_error("Symbol not found\n"); /*NOTREACHED*/ } return (TRUE); } if (t == tNUMBER) { *valuep = (db_expr_t)db_tok_number; return (TRUE); } if (t == tDOT) { *valuep = (db_expr_t)db_dot; return (TRUE); } if (t == tDOTDOT) { *valuep = (db_expr_t)db_prev; return (TRUE); } if (t == tPLUS) { *valuep = (db_expr_t) db_next; return (TRUE); } if (t == tDITTO) { *valuep = (db_expr_t)db_last_addr; return (TRUE); } if (t == tDOLLAR) { if (!db_get_variable(valuep)) return (FALSE); return (TRUE); } if (t == tLPAREN) { if (!db_expression(valuep)) { db_error("Syntax error\n"); /*NOTREACHED*/ } t = db_read_token(); if (t != tRPAREN) { db_error("Syntax error\n"); /*NOTREACHED*/ } return (TRUE); } db_unread_token(t); return (FALSE); }
/*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)); }
boolean_t db_cond_check(db_thread_breakpoint_t bkpt) { register struct db_cond *cp; db_expr_t value; int t; jmp_buf_t db_jmpbuf; if (bkpt->tb_cond <= 0) { /* no condition */ if (--(bkpt->tb_count) > 0) return(FALSE); bkpt->tb_count = bkpt->tb_init_count; return(TRUE); } db_dot = PC_REGS(DDB_REGS); db_prev = db_dot; db_next = db_dot; if (_setjmp(db_recover = &db_jmpbuf)) { /* * in case of error, return true to enter interactive mode */ return(TRUE); } /* * switch input, and evalutate condition */ cp = &db_cond[bkpt->tb_cond - 1]; db_switch_input(cp->c_cond_cmd, cp->c_size); if (!db_expression(&value)) { db_printf("error: condition evaluation error\n"); return(TRUE); } if (value == 0 || --(bkpt->tb_count) > 0) return(FALSE); /* * execute a command list if exist */ bkpt->tb_count = bkpt->tb_init_count; if ((t = db_read_token()) != tEOL) { db_unread_token(t); return(db_exec_cmd_nest(0, 0)); } return(TRUE); }
void db_show_macro(void) { register struct db_user_macro *mp; int t; char *name = 0; if ((t = db_read_token()) == tIDENT) name = db_tok_string; else db_unread_token(t); for (mp = db_user_macro; mp < &db_user_macro[DB_NUSER_MACRO]; mp++) { if (mp->m_name[0] == 0) continue; if (name && strncmp(mp->m_name, name, TOK_STRING_SIZE)) continue; db_printf("%s: %s", mp->m_name, mp->m_lbuf); } }
static bool db_term(db_expr_t *valuep) { int t; t = db_read_token(); if (t == tIDENT) { if (!db_value_of_name(db_tok_string, valuep)) { db_expr_t v = 0; int i, c, byte; /* See if we can make a number out of all of it */ for (i = 0; (c = db_tok_string[i]) != '\0'; i++) { byte = 0; if (c >= '0' && c <= '9') byte = c - '0'; else if (db_radix == 16 && c >= 'a' && c <= 'f') byte = c - 'a' + 10; else if (db_radix == 16 && c >= 'A' && c <= 'F') byte = c - 'A' + 10; else db_error("Symbol not found\n"); /*NOTREACHED*/ v = v * db_radix + byte; } *valuep = (db_expr_t)v; } return (true); } if (t == tNUMBER) { *valuep = (db_expr_t)db_tok_number; return (true); } if (t == tDOT) { *valuep = (db_expr_t)db_dot; return (true); } if (t == tDOTDOT) { *valuep = (db_expr_t)db_prev; return (true); } if (t == tPLUS) { *valuep = (db_expr_t) db_next; return (true); } if (t == tDITTO) { *valuep = (db_expr_t)db_last_addr; return (true); } if (t == tDOLLAR) { if (!db_get_variable(valuep)) return (false); return (true); } if (t == tLPAREN) { if (!db_expression(valuep)) { db_error("Syntax error\n"); /*NOTREACHED*/ } t = db_read_token(); if (t != tRPAREN) { db_error("Syntax error\n"); /*NOTREACHED*/ } return (true); } db_unread_token(t); return (false); }
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; } } }
void db_print_cmd(void) { db_expr_t value; int t; task_t task = TASK_NULL; if ((t = db_read_token()) == tSLASH) { if (db_read_token() != tIDENT) { db_printf("Bad modifier \"/%s\"\n", db_tok_string); db_error(0); /* NOTREACHED */ } if (db_tok_string[0]) db_print_format = db_tok_string[0]; if (db_option(db_tok_string, 't')) { if (db_default_act) task = db_default_act->task; if (db_print_format == 't') db_print_format = db_tok_string[1]; } } else db_unread_token(t); for ( ; ; ) { t = db_read_token(); if (t == tSTRING) { db_printf("%s", db_tok_string); continue; } db_unread_token(t); if (!db_expression(&value)) break; switch (db_print_format) { case 'a': case 'A': db_task_printsym((db_addr_t)value, (db_print_format == 'a') ? DB_STGY_ANY: DB_STGY_PROC, task); break; case 'r': db_printf("%11r", value); break; case 'x': db_printf("%08x", value); break; case 'z': db_printf("%8z", value); break; case 'd': db_printf("%11d", value); break; case 'u': db_printf("%11u", value); break; case 'o': db_printf("%16o", value); break; case 'c': value = value & 0xFF; if (value >= ' ' && value <= '~') db_printf("%c", value); else db_printf("\\%03o", value); break; default: db_printf("Unknown format %c\n", db_print_format); db_print_format = 'x'; db_error(0); } } }
/*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); }
/* * 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)); }
/* Delete breakpoint */ void db_delete_cmd(void) { register int n; thread_act_t thr_act; vm_offset_t task_thd; boolean_t user_global = FALSE; boolean_t task_bpt = FALSE; boolean_t user_space = FALSE; boolean_t thd_bpt = FALSE; db_expr_t addr; int t; t = db_read_token(); if (t == tSLASH) { t = db_read_token(); if (t != tIDENT) { db_printf("Bad modifier \"%s\"\n", db_tok_string); db_error(0); } user_global = db_option(db_tok_string, 'U'); user_space = (user_global)? TRUE: db_option(db_tok_string, 'u'); task_bpt = db_option(db_tok_string, 'T'); thd_bpt = db_option(db_tok_string, 't'); if (task_bpt && user_global) db_error("Cannot specify both 'T' and 'U' option\n"); t = db_read_token(); } if ( t == tSTAR ) { db_printf("Delete ALL breakpoints\n"); db_delete_all_breakpoints( (task_t)task_bpt ); return; } if (t == tHASH) { db_thread_breakpoint_t tbp; db_breakpoint_t bkpt; if (db_read_token() != tNUMBER) { db_printf("Bad break point number #%s\n", db_tok_string); db_error(0); } if ((tbp = db_find_breakpoint_number(db_tok_number, &bkpt)) == 0) { db_printf("No such break point #%d\n", db_tok_number); db_error(0); } db_delete_breakpoint(bkpt->task, bkpt->address, tbp->tb_task_thd); return; } db_unread_token(t); if (!db_expression(&addr)) { /* * We attempt to pick up the user_space indication from db_dot, * so that a plain "d" always works. */ addr = (db_expr_t)db_dot; if (!user_space && !DB_VALID_ADDRESS(addr, FALSE)) user_space = TRUE; } if (!DB_VALID_ADDRESS(addr, user_space)) { db_printf("Address %#X is not in %s space\n", addr, (user_space)? "user": "******"); db_error(0); } if (thd_bpt || task_bpt) { for (n = 0; db_get_next_act(&thr_act, n); n++) { if (thr_act == THR_ACT_NULL) db_error("No active thr_act\n"); if (task_bpt) { if (thr_act->task == TASK_NULL) db_error("No task\n"); task_thd = (vm_offset_t) (thr_act->task); } else task_thd = (user_global)? 0: (vm_offset_t) thr_act; db_delete_breakpoint(db_target_space(thr_act, user_space), (db_addr_t)addr, task_thd); } } else { db_delete_breakpoint(db_target_space(THR_ACT_NULL, user_space), (db_addr_t)addr, 0); } }
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); }