| File: | ddb/db_command.c |
| Warning: | line 292, column 3 1st function call argument is an uninitialized value |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
| 1 | /* $OpenBSD: db_command.c,v 1.100 2023/09/19 11:35:30 claudio Exp $ */ | |||
| 2 | /* $NetBSD: db_command.c,v 1.20 1996/03/30 22:30:05 christos Exp $ */ | |||
| 3 | ||||
| 4 | /* | |||
| 5 | * Mach Operating System | |||
| 6 | * Copyright (c) 1993,1992,1991,1990 Carnegie Mellon University | |||
| 7 | * All Rights Reserved. | |||
| 8 | * | |||
| 9 | * Permission to use, copy, modify and distribute this software and its | |||
| 10 | * documentation is hereby granted, provided that both the copyright | |||
| 11 | * notice and this permission notice appear in all copies of the | |||
| 12 | * software, derivative works or modified versions, and any portions | |||
| 13 | * thereof, and that both notices appear in supporting documentation. | |||
| 14 | * | |||
| 15 | * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" | |||
| 16 | * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR | |||
| 17 | * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. | |||
| 18 | * | |||
| 19 | * Carnegie Mellon requests users of this software to return to | |||
| 20 | * | |||
| 21 | * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU | |||
| 22 | * School of Computer Science | |||
| 23 | * Carnegie Mellon University | |||
| 24 | * Pittsburgh PA 15213-3890 | |||
| 25 | * | |||
| 26 | * any improvements or extensions that they make and grant Carnegie Mellon | |||
| 27 | * the rights to redistribute these changes. | |||
| 28 | */ | |||
| 29 | ||||
| 30 | /* | |||
| 31 | * Command dispatcher. | |||
| 32 | */ | |||
| 33 | #include <sys/param.h> | |||
| 34 | #include <sys/systm.h> | |||
| 35 | #include <sys/proc.h> | |||
| 36 | #include <sys/reboot.h> | |||
| 37 | #include <sys/extent.h> | |||
| 38 | #include <sys/pool.h> | |||
| 39 | #include <sys/msgbuf.h> | |||
| 40 | #include <sys/malloc.h> | |||
| 41 | #include <sys/mount.h> | |||
| 42 | ||||
| 43 | #include <uvm/uvm_extern.h> | |||
| 44 | #include <machine/db_machdep.h> /* type definitions */ | |||
| 45 | ||||
| 46 | #include <ddb/db_access.h> | |||
| 47 | #include <ddb/db_lex.h> | |||
| 48 | #include <ddb/db_output.h> | |||
| 49 | #include <ddb/db_command.h> | |||
| 50 | #include <ddb/db_break.h> | |||
| 51 | #include <ddb/db_watch.h> | |||
| 52 | #include <ddb/db_run.h> | |||
| 53 | #include <ddb/db_sym.h> | |||
| 54 | #include <ddb/db_var.h> | |||
| 55 | #include <ddb/db_variables.h> | |||
| 56 | #include <ddb/db_interface.h> | |||
| 57 | #include <ddb/db_extern.h> | |||
| 58 | ||||
| 59 | #include <netinet/ip_ipsp.h> | |||
| 60 | #include <uvm/uvm_ddb.h> | |||
| 61 | ||||
| 62 | /* | |||
| 63 | * Exported global variables | |||
| 64 | */ | |||
| 65 | int db_cmd_loop_done; | |||
| 66 | label_t *db_recover; | |||
| 67 | ||||
| 68 | /* | |||
| 69 | * if 'ed' style: 'dot' is set at start of last item printed, | |||
| 70 | * and '+' points to next line. | |||
| 71 | * Otherwise: 'dot' points to next item, '..' points to last. | |||
| 72 | */ | |||
| 73 | int db_ed_style = 1; | |||
| 74 | ||||
| 75 | vaddr_t db_dot; /* current location */ | |||
| 76 | vaddr_t db_last_addr; /* last explicit address typed */ | |||
| 77 | vaddr_t db_prev; /* last address examined | |||
| 78 | or written */ | |||
| 79 | vaddr_t db_next; /* next address to be examined | |||
| 80 | or written */ | |||
| 81 | ||||
| 82 | int db_cmd_search(char *, const struct db_command *, | |||
| 83 | const struct db_command **); | |||
| 84 | void db_cmd_list(const struct db_command *); | |||
| 85 | void db_ctf_pprint_cmd(db_expr_t, int, db_expr_t,char *); | |||
| 86 | void db_map_print_cmd(db_expr_t, int, db_expr_t, char *); | |||
| 87 | void db_buf_print_cmd(db_expr_t, int, db_expr_t, char *); | |||
| 88 | void db_malloc_print_cmd(db_expr_t, int, db_expr_t, char *); | |||
| 89 | void db_mbuf_print_cmd(db_expr_t, int, db_expr_t, char *); | |||
| 90 | void db_mount_print_cmd(db_expr_t, int, db_expr_t, char *); | |||
| 91 | void db_show_all_mounts(db_expr_t, int, db_expr_t, char *); | |||
| 92 | void db_show_all_vnodes(db_expr_t, int, db_expr_t, char *); | |||
| 93 | void db_show_all_bufs(db_expr_t, int, db_expr_t, char *); | |||
| 94 | void db_show_all_tdbs(db_expr_t, int, db_expr_t, char *); | |||
| 95 | void db_object_print_cmd(db_expr_t, int, db_expr_t, char *); | |||
| 96 | void db_page_print_cmd(db_expr_t, int, db_expr_t, char *); | |||
| 97 | void db_extent_print_cmd(db_expr_t, int, db_expr_t, char *); | |||
| 98 | void db_pool_print_cmd(db_expr_t, int, db_expr_t, char *); | |||
| 99 | void db_proc_print_cmd(db_expr_t, int, db_expr_t, char *); | |||
| 100 | void db_uvmexp_print_cmd(db_expr_t, int, db_expr_t, char *); | |||
| 101 | void db_tdb_print_cmd(db_expr_t, int, db_expr_t, char *); | |||
| 102 | void db_vnode_print_cmd(db_expr_t, int, db_expr_t, char *); | |||
| 103 | void db_nfsreq_print_cmd(db_expr_t, int, db_expr_t, char *); | |||
| 104 | void db_nfsnode_print_cmd(db_expr_t, int, db_expr_t, char *); | |||
| 105 | void db_swap_print_cmd(db_expr_t, int, db_expr_t, char *); | |||
| 106 | void db_help_cmd(db_expr_t, int, db_expr_t, char *); | |||
| 107 | void db_fncall(db_expr_t, int, db_expr_t, char *); | |||
| 108 | void db_boot_sync_cmd(db_expr_t, int, db_expr_t, char *); | |||
| 109 | void db_boot_crash_cmd(db_expr_t, int, db_expr_t, char *); | |||
| 110 | void db_boot_dump_cmd(db_expr_t, int, db_expr_t, char *); | |||
| 111 | void db_boot_halt_cmd(db_expr_t, int, db_expr_t, char *); | |||
| 112 | void db_boot_reboot_cmd(db_expr_t, int, db_expr_t, char *); | |||
| 113 | void db_boot_poweroff_cmd(db_expr_t, int, db_expr_t, char *); | |||
| 114 | void db_stack_trace_cmd(db_expr_t, int, db_expr_t, char *); | |||
| 115 | void db_dmesg_cmd(db_expr_t, int, db_expr_t, char *); | |||
| 116 | void db_show_panic_cmd(db_expr_t, int, db_expr_t, char *); | |||
| 117 | void db_bcstats_print_cmd(db_expr_t, int, db_expr_t, char *); | |||
| 118 | void db_struct_offset_cmd(db_expr_t, int, db_expr_t, char *); | |||
| 119 | void db_ctf_show_struct(db_expr_t, int, db_expr_t, char *); | |||
| 120 | void db_show_regs(db_expr_t, int, db_expr_t, char *); | |||
| 121 | void db_write_cmd(db_expr_t, int, db_expr_t, char *); | |||
| 122 | void db_witness_display(db_expr_t, int, db_expr_t, char *); | |||
| 123 | void db_witness_list(db_expr_t, int, db_expr_t, char *); | |||
| 124 | void db_witness_list_all(db_expr_t, int, db_expr_t, char *); | |||
| 125 | ||||
| 126 | ||||
| 127 | /* | |||
| 128 | * Utility routine - discard tokens through end-of-line. | |||
| 129 | */ | |||
| 130 | void | |||
| 131 | db_skip_to_eol(void) | |||
| 132 | { | |||
| 133 | int t; | |||
| 134 | do { | |||
| 135 | t = db_read_token(); | |||
| 136 | } while (t != tEOL1); | |||
| 137 | } | |||
| 138 | ||||
| 139 | /* | |||
| 140 | * Results of command search. | |||
| 141 | */ | |||
| 142 | #define CMD_UNIQUE0 0 | |||
| 143 | #define CMD_FOUND1 1 | |||
| 144 | #define CMD_NONE2 2 | |||
| 145 | #define CMD_AMBIGUOUS3 3 | |||
| 146 | ||||
| 147 | /* | |||
| 148 | * Search for command prefix. | |||
| 149 | */ | |||
| 150 | int | |||
| 151 | db_cmd_search(char *name, const struct db_command *table, | |||
| 152 | const struct db_command **cmdp) | |||
| 153 | { | |||
| 154 | const struct db_command *cmd; | |||
| 155 | int result = CMD_NONE2; | |||
| 156 | ||||
| 157 | for (cmd = table; cmd->name != 0; cmd++) { | |||
| 158 | char *lp = name, *rp = cmd->name; | |||
| 159 | int c; | |||
| 160 | ||||
| 161 | while ((c = *lp) == *rp) { | |||
| 162 | if (c == 0) { | |||
| 163 | /* complete match */ | |||
| 164 | *cmdp = cmd; | |||
| 165 | return (CMD_UNIQUE0); | |||
| 166 | } | |||
| 167 | lp++; | |||
| 168 | rp++; | |||
| 169 | } | |||
| 170 | if (c == 0) { | |||
| 171 | /* end of name, not end of command - partial match */ | |||
| 172 | if (result == CMD_FOUND1) { | |||
| 173 | result = CMD_AMBIGUOUS3; | |||
| 174 | /* but keep looking for a full match - | |||
| 175 | this lets us match single letters */ | |||
| 176 | } else { | |||
| 177 | *cmdp = cmd; | |||
| 178 | result = CMD_FOUND1; | |||
| 179 | } | |||
| 180 | } | |||
| 181 | } | |||
| 182 | return (result); | |||
| 183 | } | |||
| 184 | ||||
| 185 | void | |||
| 186 | db_cmd_list(const struct db_command *table) | |||
| 187 | { | |||
| 188 | const struct db_command *cmd; | |||
| 189 | ||||
| 190 | for (cmd = table; cmd->name != 0; cmd++) { | |||
| 191 | db_printf("%-12s", cmd->name); | |||
| 192 | db_end_line(12); | |||
| 193 | } | |||
| 194 | } | |||
| 195 | ||||
| 196 | void | |||
| 197 | db_command(const struct db_command **last_cmdp, | |||
| 198 | const struct db_command *cmd_table) | |||
| 199 | { | |||
| 200 | const struct db_command *cmd; | |||
| 201 | char modif[TOK_STRING_SIZE120]; | |||
| 202 | db_expr_t addr, count; | |||
| 203 | int t, result, have_addr = 0; | |||
| 204 | ||||
| 205 | t = db_read_token(); | |||
| 206 | if (t == tEOL1) { | |||
| 207 | /* empty line repeats last command, at 'next' */ | |||
| 208 | cmd = *last_cmdp; | |||
| 209 | addr = (db_expr_t)db_next; | |||
| 210 | have_addr = 0; | |||
| 211 | count = 1; | |||
| 212 | modif[0] = '\0'; | |||
| 213 | } else if (t == tEXCL17) { | |||
| 214 | db_fncall(0, 0, 0, NULL((void *)0)); | |||
| 215 | return; | |||
| 216 | } else if (t != tIDENT3) { | |||
| 217 | db_printf("?\n"); | |||
| 218 | db_flush_lex(); | |||
| 219 | return; | |||
| 220 | } else { | |||
| 221 | /* Search for command */ | |||
| 222 | while (cmd_table) { | |||
| 223 | result = db_cmd_search(db_tok_string, | |||
| 224 | cmd_table, &cmd); | |||
| 225 | switch (result) { | |||
| 226 | case CMD_NONE2: | |||
| 227 | db_printf("No such command\n"); | |||
| 228 | db_flush_lex(); | |||
| 229 | return; | |||
| 230 | case CMD_AMBIGUOUS3: | |||
| 231 | db_printf("Ambiguous\n"); | |||
| 232 | db_flush_lex(); | |||
| 233 | return; | |||
| 234 | default: | |||
| 235 | break; | |||
| 236 | } | |||
| 237 | if ((cmd_table = cmd->more) != 0) { | |||
| 238 | t = db_read_token(); | |||
| 239 | if (t != tIDENT3) { | |||
| 240 | db_cmd_list(cmd_table); | |||
| 241 | db_flush_lex(); | |||
| 242 | return; | |||
| 243 | } | |||
| 244 | } | |||
| 245 | } | |||
| 246 | ||||
| 247 | if ((cmd->flag & CS_OWN0x1) == 0) { | |||
| 248 | /* | |||
| 249 | * Standard syntax: | |||
| 250 | * command [/modifier] [addr] [,count] | |||
| 251 | */ | |||
| 252 | t = db_read_token(); | |||
| 253 | if (t == tSLASH8) { | |||
| 254 | t = db_read_token(); | |||
| 255 | if (t != tIDENT3) { | |||
| 256 | db_printf("Bad modifier\n"); | |||
| 257 | db_flush_lex(); | |||
| 258 | return; | |||
| 259 | } | |||
| 260 | db_strlcpy(modif, db_tok_string, sizeof(modif)); | |||
| 261 | } else { | |||
| 262 | db_unread_token(t); | |||
| 263 | modif[0] = '\0'; | |||
| 264 | } | |||
| 265 | ||||
| 266 | if (db_expression(&addr)) { | |||
| 267 | db_dot = (vaddr_t) addr; | |||
| 268 | db_last_addr = db_dot; | |||
| 269 | have_addr = 1; | |||
| 270 | } else { | |||
| 271 | addr = (db_expr_t) db_dot; | |||
| 272 | have_addr = 0; | |||
| 273 | } | |||
| 274 | t = db_read_token(); | |||
| 275 | if (t == tCOMMA14) { | |||
| 276 | if (!db_expression(&count)) { | |||
| 277 | db_printf("Count missing\n"); | |||
| 278 | db_flush_lex(); | |||
| 279 | return; | |||
| 280 | } | |||
| 281 | } else { | |||
| 282 | db_unread_token(t); | |||
| 283 | count = -1; | |||
| 284 | } | |||
| 285 | if ((cmd->flag & CS_MORE0x2) == 0) | |||
| 286 | db_skip_to_eol(); | |||
| 287 | } | |||
| 288 | } | |||
| 289 | *last_cmdp = cmd; | |||
| 290 | if (cmd
| |||
| 291 | /* Execute the command. */ | |||
| 292 | (*cmd->fcn)(addr, have_addr, count, modif); | |||
| ||||
| 293 | ||||
| 294 | if (cmd->flag & CS_SET_DOT0x100) { | |||
| 295 | /* | |||
| 296 | * If command changes dot, set dot to | |||
| 297 | * previous address displayed (if 'ed' style). | |||
| 298 | */ | |||
| 299 | if (db_ed_style) | |||
| 300 | db_dot = db_prev; | |||
| 301 | else | |||
| 302 | db_dot = db_next; | |||
| 303 | } | |||
| 304 | } else { | |||
| 305 | /* | |||
| 306 | * If command does not change dot, | |||
| 307 | * set 'next' location to be the same. | |||
| 308 | */ | |||
| 309 | db_next = db_dot; | |||
| 310 | } | |||
| 311 | } | |||
| 312 | ||||
| 313 | void | |||
| 314 | db_buf_print_cmd(db_expr_t addr, int have_addr, db_expr_t count, char *modif) | |||
| 315 | { | |||
| 316 | int full = 0; | |||
| 317 | ||||
| 318 | if (modif[0] == 'f') | |||
| 319 | full = 1; | |||
| 320 | ||||
| 321 | vfs_buf_print((void *) addr, full, db_printf); | |||
| 322 | } | |||
| 323 | ||||
| 324 | void | |||
| 325 | db_map_print_cmd(db_expr_t addr, int have_addr, db_expr_t count, char *modif) | |||
| 326 | { | |||
| 327 | int full = 0; | |||
| 328 | ||||
| 329 | if (modif[0] == 'f') | |||
| 330 | full = 1; | |||
| 331 | ||||
| 332 | uvm_map_printit((struct vm_map *) addr, full, db_printf); | |||
| 333 | } | |||
| 334 | ||||
| 335 | void | |||
| 336 | db_malloc_print_cmd(db_expr_t addr, int have_addr, db_expr_t count, char *modif) | |||
| 337 | { | |||
| 338 | malloc_printit(db_printf); | |||
| 339 | } | |||
| 340 | ||||
| 341 | void | |||
| 342 | db_mbuf_print_cmd(db_expr_t addr, int have_addr, db_expr_t count, char *modif) | |||
| 343 | { | |||
| 344 | m_print((void *)addr, db_printf); | |||
| 345 | } | |||
| 346 | ||||
| 347 | void | |||
| 348 | db_socket_print_cmd(db_expr_t addr, int have_addr, db_expr_t count, char *modif) | |||
| 349 | { | |||
| 350 | so_print((void *)addr, db_printf); | |||
| 351 | } | |||
| 352 | ||||
| 353 | void | |||
| 354 | db_mount_print_cmd(db_expr_t addr, int have_addr, db_expr_t count, char *modif) | |||
| 355 | { | |||
| 356 | int full = 0; | |||
| 357 | ||||
| 358 | if (modif[0] == 'f') | |||
| 359 | full = 1; | |||
| 360 | ||||
| 361 | vfs_mount_print((struct mount *) addr, full, db_printf); | |||
| 362 | } | |||
| 363 | ||||
| 364 | void | |||
| 365 | db_show_all_mounts(db_expr_t addr, int have_addr, db_expr_t count, char *modif) | |||
| 366 | { | |||
| 367 | int full = 0; | |||
| 368 | struct mount *mp; | |||
| 369 | ||||
| 370 | if (modif[0] == 'f') | |||
| 371 | full = 1; | |||
| 372 | ||||
| 373 | TAILQ_FOREACH(mp, &mountlist, mnt_list)for((mp) = ((&mountlist)->tqh_first); (mp) != ((void * )0); (mp) = ((mp)->mnt_list.tqe_next)) { | |||
| 374 | db_printf("mountpoint %p\n", mp); | |||
| 375 | vfs_mount_print(mp, full, db_printf); | |||
| 376 | } | |||
| 377 | } | |||
| 378 | ||||
| 379 | extern struct pool vnode_pool; | |||
| 380 | void | |||
| 381 | db_show_all_vnodes(db_expr_t addr, int have_addr, db_expr_t count, char *modif) | |||
| 382 | { | |||
| 383 | int full = 0; | |||
| 384 | ||||
| 385 | if (modif[0] == 'f') | |||
| 386 | full = 1; | |||
| 387 | ||||
| 388 | pool_walk(&vnode_pool, full, db_printf, vfs_vnode_print); | |||
| 389 | } | |||
| 390 | ||||
| 391 | extern struct pool bufpool; | |||
| 392 | void | |||
| 393 | db_show_all_bufs(db_expr_t addr, int have_addr, db_expr_t count, char *modif) | |||
| 394 | { | |||
| 395 | int full = 0; | |||
| 396 | ||||
| 397 | if (modif[0] == 'f') | |||
| 398 | full = 1; | |||
| 399 | ||||
| 400 | pool_walk(&bufpool, full, db_printf, vfs_buf_print); | |||
| 401 | } | |||
| 402 | ||||
| 403 | #ifdef IPSEC1 | |||
| 404 | void | |||
| 405 | db_show_all_tdbs(db_expr_t addr, int have_addr, db_expr_t count, char *modif) | |||
| 406 | { | |||
| 407 | int full = 0; | |||
| 408 | ||||
| 409 | if (modif[0] == 'f') | |||
| 410 | full = 1; | |||
| 411 | ||||
| 412 | pool_walk(&tdb_pool, full, db_printf, tdb_printit); | |||
| 413 | } | |||
| 414 | #endif | |||
| 415 | ||||
| 416 | void | |||
| 417 | db_show_all_routes(db_expr_t addr, int have_addr, db_expr_t count, char *modif) | |||
| 418 | { | |||
| 419 | u_int rtableid = 0; | |||
| 420 | ||||
| 421 | if (have_addr) | |||
| 422 | rtableid = addr; | |||
| 423 | if (count == -1) | |||
| 424 | count = 1; | |||
| 425 | ||||
| 426 | while (count--) { | |||
| 427 | if (modif[0] != 'I') | |||
| 428 | db_show_rtable(AF_INET2, rtableid); | |||
| 429 | if (modif[0] != 'i') | |||
| 430 | db_show_rtable(AF_INET624, rtableid); | |||
| 431 | rtableid++; | |||
| 432 | } | |||
| 433 | } | |||
| 434 | ||||
| 435 | void | |||
| 436 | db_show_route(db_expr_t addr, int have_addr, db_expr_t count, char *modif) | |||
| 437 | { | |||
| 438 | db_show_rtentry((void *)addr, NULL((void *)0), -1); | |||
| 439 | } | |||
| 440 | ||||
| 441 | void | |||
| 442 | db_object_print_cmd(db_expr_t addr, int have_addr, db_expr_t count, char *modif) | |||
| 443 | { | |||
| 444 | int full = 0; | |||
| 445 | ||||
| 446 | if (modif[0] == 'f') | |||
| 447 | full = 1; | |||
| 448 | ||||
| 449 | uvm_object_printit((struct uvm_object *) addr, full, db_printf); | |||
| 450 | } | |||
| 451 | ||||
| 452 | void | |||
| 453 | db_page_print_cmd(db_expr_t addr, int have_addr, db_expr_t count, char *modif) | |||
| 454 | { | |||
| 455 | int full = 0; | |||
| 456 | ||||
| 457 | if (modif[0] == 'f') | |||
| 458 | full = 1; | |||
| 459 | ||||
| 460 | uvm_page_printit((struct vm_page *) addr, full, db_printf); | |||
| 461 | } | |||
| 462 | ||||
| 463 | void | |||
| 464 | db_vnode_print_cmd(db_expr_t addr, int have_addr, db_expr_t count, char *modif) | |||
| 465 | { | |||
| 466 | int full = 0; | |||
| 467 | ||||
| 468 | if (modif[0] == 'f') | |||
| 469 | full = 1; | |||
| 470 | ||||
| 471 | vfs_vnode_print((void *)addr, full, db_printf); | |||
| 472 | } | |||
| 473 | ||||
| 474 | #ifdef NFSCLIENT1 | |||
| 475 | void | |||
| 476 | db_nfsreq_print_cmd(db_expr_t addr, int have_addr, db_expr_t count, | |||
| 477 | char *modif) | |||
| 478 | { | |||
| 479 | int full = 0; | |||
| 480 | ||||
| 481 | if (modif[0] == 'f') | |||
| 482 | full = 1; | |||
| 483 | ||||
| 484 | nfs_request_print((void *)addr, full, db_printf); | |||
| 485 | } | |||
| 486 | ||||
| 487 | void | |||
| 488 | db_nfsnode_print_cmd(db_expr_t addr, int have_addr, db_expr_t count, | |||
| 489 | char *modif) | |||
| 490 | { | |||
| 491 | int full = 0; | |||
| 492 | ||||
| 493 | if (modif[0] == 'f') | |||
| 494 | full = 1; | |||
| 495 | ||||
| 496 | nfs_node_print((void *)addr, full, db_printf); | |||
| 497 | } | |||
| 498 | #endif | |||
| 499 | ||||
| 500 | void | |||
| 501 | db_swap_print_cmd(db_expr_t addr, int have_addr, db_expr_t count, | |||
| 502 | char *modif) | |||
| 503 | { | |||
| 504 | swap_print_all(db_printf); | |||
| 505 | } | |||
| 506 | ||||
| 507 | void | |||
| 508 | db_show_panic_cmd(db_expr_t addr, int have_addr, db_expr_t count, char *modif) | |||
| 509 | { | |||
| 510 | struct cpu_info *ci; | |||
| 511 | char *prefix; | |||
| 512 | CPU_INFO_ITERATORint cii; | |||
| 513 | int panicked = 0; | |||
| 514 | ||||
| 515 | CPU_INFO_FOREACH(cii, ci)for (cii = 0, ci = cpu_info_list; ci != ((void *)0); ci = ci-> ci_next) { | |||
| 516 | if (ci->ci_panicbuf[0] != '\0') { | |||
| 517 | prefix = (panicstr == ci->ci_panicbuf) ? "*" : " "; | |||
| 518 | db_printf("%scpu%d: %s\n", | |||
| 519 | prefix, CPU_INFO_UNIT(ci)((ci)->ci_dev ? (ci)->ci_dev->dv_unit : 0), ci->ci_panicbuf); | |||
| 520 | panicked = 1; | |||
| 521 | } | |||
| 522 | } | |||
| 523 | if (!panicked) | |||
| 524 | db_printf("the kernel did not panic\n"); /* yet */ | |||
| 525 | } | |||
| 526 | ||||
| 527 | void | |||
| 528 | db_extent_print_cmd(db_expr_t addr, int have_addr, db_expr_t count, char *modif) | |||
| 529 | { | |||
| 530 | extent_print_all(); | |||
| 531 | } | |||
| 532 | ||||
| 533 | void | |||
| 534 | db_pool_print_cmd(db_expr_t addr, int have_addr, db_expr_t count, char *modif) | |||
| 535 | { | |||
| 536 | pool_printit((struct pool *)addr, modif, db_printf); | |||
| 537 | } | |||
| 538 | ||||
| 539 | void | |||
| 540 | db_proc_print_cmd(db_expr_t addr, int have_addr, db_expr_t count, char *modif) | |||
| 541 | { | |||
| 542 | if (!have_addr) | |||
| 543 | addr = (db_expr_t)curproc({struct cpu_info *__ci; asm volatile("movq %%gs:%P1,%0" : "=r" (__ci) :"n" (__builtin_offsetof(struct cpu_info, ci_self))); __ci;})->ci_curproc; | |||
| 544 | if (modif[0] == 't') { | |||
| 545 | addr = (db_expr_t)tfind((pid_t)addr); | |||
| 546 | if (addr == 0) { | |||
| 547 | db_printf("not found\n"); | |||
| 548 | return; | |||
| 549 | } | |||
| 550 | } | |||
| 551 | ||||
| 552 | proc_printit((struct proc *)addr, modif, db_printf); | |||
| 553 | } | |||
| 554 | ||||
| 555 | #ifdef IPSEC1 | |||
| 556 | void | |||
| 557 | db_tdb_print_cmd(db_expr_t addr, int have_addr, db_expr_t count, char *modif) | |||
| 558 | { | |||
| 559 | int full = 0; | |||
| 560 | ||||
| 561 | if (modif[0] == 'f') | |||
| 562 | full = 1; | |||
| 563 | ||||
| 564 | tdb_printit((void *)addr, full, db_printf); | |||
| 565 | } | |||
| 566 | #endif | |||
| 567 | ||||
| 568 | void | |||
| 569 | db_uvmexp_print_cmd(db_expr_t addr, int have_addr, db_expr_t count, char *modif) | |||
| 570 | { | |||
| 571 | uvmexp_print(db_printf); | |||
| 572 | } | |||
| 573 | ||||
| 574 | void bcstats_print(int (*)(const char *, ...)); | |||
| 575 | ||||
| 576 | void | |||
| 577 | db_bcstats_print_cmd(db_expr_t addr, int have_addr, db_expr_t count, char *modif) | |||
| 578 | { | |||
| 579 | bcstats_print(db_printf); | |||
| 580 | } | |||
| 581 | ||||
| 582 | /* | |||
| 583 | * 'show' commands | |||
| 584 | */ | |||
| 585 | ||||
| 586 | const struct db_command db_show_all_cmds[] = { | |||
| 587 | { "procs", db_show_all_procs, 0, NULL((void *)0) }, | |||
| 588 | { "callout", db_show_callout, 0, NULL((void *)0) }, | |||
| 589 | { "clockintr", db_show_all_clockintr, 0, NULL((void *)0) }, | |||
| 590 | { "pools", db_show_all_pools, 0, NULL((void *)0) }, | |||
| 591 | { "mounts", db_show_all_mounts, 0, NULL((void *)0) }, | |||
| 592 | { "vnodes", db_show_all_vnodes, 0, NULL((void *)0) }, | |||
| 593 | { "bufs", db_show_all_bufs, 0, NULL((void *)0) }, | |||
| 594 | { "routes", db_show_all_routes, 0, NULL((void *)0) }, | |||
| 595 | #ifdef NFSCLIENT1 | |||
| 596 | { "nfsreqs", db_show_all_nfsreqs, 0, NULL((void *)0) }, | |||
| 597 | { "nfsnodes", db_show_all_nfsnodes, 0, NULL((void *)0) }, | |||
| 598 | #endif | |||
| 599 | #ifdef IPSEC1 | |||
| 600 | { "tdbs", db_show_all_tdbs, 0, NULL((void *)0) }, | |||
| 601 | #endif | |||
| 602 | #ifdef WITNESS | |||
| 603 | { "locks", db_witness_list_all, 0, NULL((void *)0) }, | |||
| 604 | #endif | |||
| 605 | { NULL((void *)0), NULL((void *)0), 0, NULL((void *)0) } | |||
| 606 | }; | |||
| 607 | ||||
| 608 | const struct db_command db_show_cmds[] = { | |||
| 609 | { "all", NULL((void *)0), 0, db_show_all_cmds }, | |||
| 610 | { "bcstats", db_bcstats_print_cmd, 0, NULL((void *)0) }, | |||
| 611 | { "breaks", db_listbreak_cmd, 0, NULL((void *)0) }, | |||
| 612 | { "buf", db_buf_print_cmd, 0, NULL((void *)0) }, | |||
| 613 | { "extents", db_extent_print_cmd, 0, NULL((void *)0) }, | |||
| 614 | #ifdef WITNESS | |||
| 615 | { "locks", db_witness_list, 0, NULL((void *)0) }, | |||
| 616 | #endif | |||
| 617 | { "malloc", db_malloc_print_cmd, 0, NULL((void *)0) }, | |||
| 618 | { "map", db_map_print_cmd, 0, NULL((void *)0) }, | |||
| 619 | { "mbuf", db_mbuf_print_cmd, 0, NULL((void *)0) }, | |||
| 620 | { "mount", db_mount_print_cmd, 0, NULL((void *)0) }, | |||
| 621 | #ifdef NFSCLIENT1 | |||
| 622 | { "nfsreq", db_nfsreq_print_cmd, 0, NULL((void *)0) }, | |||
| 623 | { "nfsnode", db_nfsnode_print_cmd, 0, NULL((void *)0) }, | |||
| 624 | #endif | |||
| 625 | { "object", db_object_print_cmd, 0, NULL((void *)0) }, | |||
| 626 | { "page", db_page_print_cmd, 0, NULL((void *)0) }, | |||
| 627 | { "panic", db_show_panic_cmd, 0, NULL((void *)0) }, | |||
| 628 | { "pool", db_pool_print_cmd, 0, NULL((void *)0) }, | |||
| 629 | { "proc", db_proc_print_cmd, 0, NULL((void *)0) }, | |||
| 630 | { "registers", db_show_regs, 0, NULL((void *)0) }, | |||
| 631 | { "route", db_show_route, 0, NULL((void *)0) }, | |||
| 632 | { "socket", db_socket_print_cmd, 0, NULL((void *)0) }, | |||
| 633 | { "struct", db_ctf_show_struct, CS_OWN0x1, NULL((void *)0) }, | |||
| 634 | { "swap", db_swap_print_cmd, 0, NULL((void *)0) }, | |||
| 635 | #ifdef IPSEC1 | |||
| 636 | { "tdb", db_tdb_print_cmd, 0, NULL((void *)0) }, | |||
| 637 | #endif | |||
| 638 | { "uvmexp", db_uvmexp_print_cmd, 0, NULL((void *)0) }, | |||
| 639 | { "vnode", db_vnode_print_cmd, 0, NULL((void *)0) }, | |||
| 640 | { "watches", db_listwatch_cmd, 0, NULL((void *)0) }, | |||
| 641 | #ifdef WITNESS | |||
| 642 | { "witness", db_witness_display, 0, NULL((void *)0) }, | |||
| 643 | #endif | |||
| 644 | { NULL((void *)0), NULL((void *)0), 0, NULL((void *)0) } | |||
| 645 | }; | |||
| 646 | ||||
| 647 | const struct db_command db_boot_cmds[] = { | |||
| 648 | { "sync", db_boot_sync_cmd, 0, 0 }, | |||
| 649 | { "crash", db_boot_crash_cmd, 0, 0 }, | |||
| 650 | { "dump", db_boot_dump_cmd, 0, 0 }, | |||
| 651 | { "halt", db_boot_halt_cmd, 0, 0 }, | |||
| 652 | { "reboot", db_boot_reboot_cmd, 0, 0 }, | |||
| 653 | { "poweroff", db_boot_poweroff_cmd, 0, 0 }, | |||
| 654 | { NULL((void *)0), } | |||
| 655 | }; | |||
| 656 | ||||
| 657 | const struct db_command db_command_table[] = { | |||
| 658 | #ifdef DB_MACHINE_COMMANDS | |||
| 659 | /* this must be the first entry, if it exists */ | |||
| 660 | { "machine", NULL((void *)0), 0, db_machine_command_table }, | |||
| 661 | #endif | |||
| 662 | { "kill", db_kill_cmd, 0, NULL((void *)0) }, | |||
| 663 | { "print", db_print_cmd, 0, NULL((void *)0) }, | |||
| 664 | { "p", db_print_cmd, 0, NULL((void *)0) }, | |||
| 665 | { "pprint", db_ctf_pprint_cmd, CS_OWN0x1, NULL((void *)0) }, | |||
| 666 | { "examine", db_examine_cmd, CS_SET_DOT0x100, NULL((void *)0) }, | |||
| 667 | { "x", db_examine_cmd, CS_SET_DOT0x100, NULL((void *)0) }, | |||
| 668 | { "search", db_search_cmd, CS_OWN0x1|CS_SET_DOT0x100, NULL((void *)0) }, | |||
| 669 | { "set", db_set_cmd, CS_OWN0x1, NULL((void *)0) }, | |||
| 670 | { "write", db_write_cmd, CS_MORE0x2|CS_SET_DOT0x100, NULL((void *)0) }, | |||
| 671 | { "w", db_write_cmd, CS_MORE0x2|CS_SET_DOT0x100, NULL((void *)0) }, | |||
| 672 | { "delete", db_delete_cmd, 0, NULL((void *)0) }, | |||
| 673 | { "d", db_delete_cmd, 0, NULL((void *)0) }, | |||
| 674 | { "break", db_breakpoint_cmd, 0, NULL((void *)0) }, | |||
| 675 | { "dwatch", db_deletewatch_cmd, 0, NULL((void *)0) }, | |||
| 676 | { "watch", db_watchpoint_cmd, CS_MORE0x2, NULL((void *)0) }, | |||
| 677 | { "step", db_single_step_cmd, 0, NULL((void *)0) }, | |||
| 678 | { "s", db_single_step_cmd, 0, NULL((void *)0) }, | |||
| 679 | { "continue", db_continue_cmd, 0, NULL((void *)0) }, | |||
| 680 | { "c", db_continue_cmd, 0, NULL((void *)0) }, | |||
| 681 | { "until", db_trace_until_call_cmd,0, NULL((void *)0) }, | |||
| 682 | { "next", db_trace_until_matching_cmd,0, NULL((void *)0) }, | |||
| 683 | { "match", db_trace_until_matching_cmd,0, NULL((void *)0) }, | |||
| 684 | { "trace", db_stack_trace_cmd, 0, NULL((void *)0) }, | |||
| 685 | { "bt", db_stack_trace_cmd, 0, NULL((void *)0) }, | |||
| 686 | { "call", db_fncall, CS_OWN0x1, NULL((void *)0) }, | |||
| 687 | { "ps", db_show_all_procs, 0, NULL((void *)0) }, | |||
| 688 | { "callout", db_show_callout, 0, NULL((void *)0) }, | |||
| 689 | { "reboot", db_boot_reboot_cmd, 0, NULL((void *)0) }, | |||
| 690 | { "show", NULL((void *)0), 0, db_show_cmds }, | |||
| 691 | { "boot", NULL((void *)0), 0, db_boot_cmds }, | |||
| 692 | { "help", db_help_cmd, 0, NULL((void *)0) }, | |||
| 693 | { "hangman", db_hangman, 0, NULL((void *)0) }, | |||
| 694 | { "dmesg", db_dmesg_cmd, 0, NULL((void *)0) }, | |||
| 695 | { NULL((void *)0), NULL((void *)0), 0, NULL((void *)0) } | |||
| 696 | }; | |||
| 697 | ||||
| 698 | const struct db_command *db_last_command = NULL((void *)0); | |||
| 699 | ||||
| 700 | void | |||
| 701 | db_help_cmd(db_expr_t addr, int haddr, db_expr_t count, char *modif) | |||
| 702 | { | |||
| 703 | db_cmd_list(db_command_table); | |||
| 704 | } | |||
| 705 | ||||
| 706 | void | |||
| 707 | db_command_loop(void) | |||
| 708 | { | |||
| 709 | label_t db_jmpbuf; | |||
| 710 | label_t *savejmp; | |||
| 711 | extern int db_output_line; | |||
| 712 | ||||
| 713 | /* | |||
| 714 | * Initialize 'prev' and 'next' to dot. | |||
| 715 | */ | |||
| 716 | db_prev = db_dot; | |||
| 717 | db_next = db_dot; | |||
| 718 | ||||
| 719 | db_cmd_loop_done = 0; | |||
| 720 | ||||
| 721 | savejmp = db_recover; | |||
| 722 | db_recover = &db_jmpbuf; | |||
| 723 | (void) setjmp(&db_jmpbuf); | |||
| 724 | ||||
| 725 | while (!db_cmd_loop_done) { | |||
| ||||
| 726 | ||||
| 727 | if (db_print_position() != 0) | |||
| 728 | db_printf("\n"); | |||
| 729 | db_output_line = 0; | |||
| 730 | ||||
| 731 | #ifdef MULTIPROCESSOR1 | |||
| 732 | db_printf("ddb{%d}> ", CPU_INFO_UNIT(curcpu())((({struct cpu_info *__ci; asm volatile("movq %%gs:%P1,%0" : "=r" (__ci) :"n" (__builtin_offsetof(struct cpu_info, ci_self))); __ci;}))->ci_dev ? (({struct cpu_info *__ci; asm volatile ("movq %%gs:%P1,%0" : "=r" (__ci) :"n" (__builtin_offsetof(struct cpu_info, ci_self))); __ci;}))->ci_dev->dv_unit : 0)); | |||
| 733 | #else | |||
| 734 | db_printf("ddb> "); | |||
| 735 | #endif | |||
| 736 | (void) db_read_line(); | |||
| 737 | ||||
| 738 | db_command(&db_last_command, db_command_table); | |||
| 739 | } | |||
| 740 | ||||
| 741 | db_recover = savejmp; | |||
| 742 | } | |||
| 743 | ||||
| 744 | void | |||
| 745 | db_error(char *s) | |||
| 746 | { | |||
| 747 | if (s) | |||
| 748 | db_printf("%s", s); | |||
| 749 | db_flush_lex(); | |||
| 750 | if (db_recover != NULL((void *)0)) | |||
| 751 | longjmp(db_recover); | |||
| 752 | } | |||
| 753 | ||||
| 754 | ||||
| 755 | /* | |||
| 756 | * Call random function: | |||
| 757 | * !expr(arg,arg,arg) | |||
| 758 | */ | |||
| 759 | void | |||
| 760 | db_fncall(db_expr_t addr, int have_addr, db_expr_t count, char *modif) | |||
| 761 | { | |||
| 762 | db_expr_t fn_addr; | |||
| 763 | #define MAXARGS11 11 | |||
| 764 | db_expr_t args[MAXARGS11]; | |||
| 765 | int nargs = 0; | |||
| 766 | db_expr_t retval; | |||
| 767 | db_expr_t (*func)(db_expr_t, ...); | |||
| 768 | int t; | |||
| 769 | char tmpfmt[28]; | |||
| 770 | ||||
| 771 | if (!db_expression(&fn_addr)) { | |||
| 772 | db_printf("Bad function\n"); | |||
| 773 | db_flush_lex(); | |||
| 774 | return; | |||
| 775 | } | |||
| 776 | func = (db_expr_t (*)(db_expr_t, ...)) fn_addr; | |||
| 777 | ||||
| 778 | t = db_read_token(); | |||
| 779 | if (t == tLPAREN10) { | |||
| 780 | if (db_expression(&args[0])) { | |||
| 781 | nargs++; | |||
| 782 | while ((t = db_read_token()) == tCOMMA14) { | |||
| 783 | if (nargs == MAXARGS11) { | |||
| 784 | db_printf("Too many arguments\n"); | |||
| 785 | db_flush_lex(); | |||
| 786 | return; | |||
| 787 | } | |||
| 788 | if (!db_expression(&args[nargs])) { | |||
| 789 | db_printf("Argument missing\n"); | |||
| 790 | db_flush_lex(); | |||
| 791 | return; | |||
| 792 | } | |||
| 793 | nargs++; | |||
| 794 | } | |||
| 795 | db_unread_token(t); | |||
| 796 | } | |||
| 797 | if (db_read_token() != tRPAREN11) { | |||
| 798 | db_printf("?\n"); | |||
| 799 | db_flush_lex(); | |||
| 800 | return; | |||
| 801 | } | |||
| 802 | } | |||
| 803 | db_skip_to_eol(); | |||
| 804 | ||||
| 805 | while (nargs < MAXARGS11) | |||
| 806 | args[nargs++] = 0; | |||
| 807 | ||||
| 808 | retval = (*func)(args[0], args[1], args[2], args[3], args[4], | |||
| 809 | args[5], args[6], args[7], args[8], args[9]); | |||
| 810 | db_printf("%s\n", db_format(tmpfmt, sizeof tmpfmt, retval, | |||
| 811 | DB_FORMAT_N3, 1, 0)); | |||
| 812 | } | |||
| 813 | ||||
| 814 | void | |||
| 815 | db_reboot(int howto) | |||
| 816 | { | |||
| 817 | spl0()spllower(0x0); | |||
| 818 | if (!curproc({struct cpu_info *__ci; asm volatile("movq %%gs:%P1,%0" : "=r" (__ci) :"n" (__builtin_offsetof(struct cpu_info, ci_self))); __ci;})->ci_curproc) | |||
| 819 | curproc({struct cpu_info *__ci; asm volatile("movq %%gs:%P1,%0" : "=r" (__ci) :"n" (__builtin_offsetof(struct cpu_info, ci_self))); __ci;})->ci_curproc = &proc0; | |||
| 820 | reboot(howto); | |||
| 821 | } | |||
| 822 | ||||
| 823 | void | |||
| 824 | db_boot_sync_cmd(db_expr_t addr, int haddr, db_expr_t count, char *modif) | |||
| 825 | { | |||
| 826 | db_reboot(RB_AUTOBOOT0 | RB_TIMEBAD0x00800 | RB_USERREQ0x04000); | |||
| 827 | } | |||
| 828 | ||||
| 829 | void | |||
| 830 | db_boot_crash_cmd(db_expr_t addr, int haddr, db_expr_t count, char *modif) | |||
| 831 | { | |||
| 832 | db_reboot(RB_NOSYNC0x00004 | RB_DUMP0x00100 | RB_TIMEBAD0x00800 | RB_USERREQ0x04000); | |||
| 833 | } | |||
| 834 | ||||
| 835 | void | |||
| 836 | db_boot_dump_cmd(db_expr_t addr, int haddr, db_expr_t count, char *modif) | |||
| 837 | { | |||
| 838 | db_reboot(RB_DUMP0x00100 | RB_TIMEBAD0x00800 | RB_USERREQ0x04000); | |||
| 839 | } | |||
| 840 | ||||
| 841 | void | |||
| 842 | db_boot_halt_cmd(db_expr_t addr, int haddr, db_expr_t count, char *modif) | |||
| 843 | { | |||
| 844 | db_reboot(RB_NOSYNC0x00004 | RB_HALT0x00008 | RB_TIMEBAD0x00800 | RB_USERREQ0x04000); | |||
| 845 | } | |||
| 846 | ||||
| 847 | void | |||
| 848 | db_boot_reboot_cmd(db_expr_t addr, int haddr, db_expr_t count, char *modif) | |||
| 849 | { | |||
| 850 | boot(RB_RESET0x08000 | RB_AUTOBOOT0 | RB_NOSYNC0x00004 | RB_TIMEBAD0x00800 | RB_USERREQ0x04000); | |||
| 851 | } | |||
| 852 | ||||
| 853 | void | |||
| 854 | db_boot_poweroff_cmd(db_expr_t addr, int haddr, db_expr_t count, char *modif) | |||
| 855 | { | |||
| 856 | db_reboot(RB_NOSYNC0x00004 | RB_HALT0x00008 | RB_POWERDOWN0x01000 | RB_TIMEBAD0x00800 | RB_USERREQ0x04000); | |||
| 857 | } | |||
| 858 | ||||
| 859 | void | |||
| 860 | db_dmesg_cmd(db_expr_t addr, int haddr, db_expr_t count, char *modif) | |||
| 861 | { | |||
| 862 | int i, off; | |||
| 863 | char *p; | |||
| 864 | ||||
| 865 | if (!msgbufp || msgbufp->msg_magic != MSG_MAGIC0x063061) | |||
| 866 | return; | |||
| 867 | off = msgbufp->msg_bufx; | |||
| 868 | if (off > msgbufp->msg_bufs) | |||
| 869 | off = 0; | |||
| 870 | for (i = 0, p = msgbufp->msg_bufc + off; | |||
| 871 | i < msgbufp->msg_bufs; i++, p++) { | |||
| 872 | if (p >= msgbufp->msg_bufc + msgbufp->msg_bufs) | |||
| 873 | p = msgbufp->msg_bufc; | |||
| 874 | if (*p != '\0') | |||
| 875 | db_putchar(*p); | |||
| 876 | } | |||
| 877 | db_putchar('\n'); | |||
| 878 | } | |||
| 879 | ||||
| 880 | void | |||
| 881 | db_stack_trace_cmd(db_expr_t addr, int have_addr, db_expr_t count, char *modif) | |||
| 882 | { | |||
| 883 | db_stack_trace_print(addr, have_addr, count, modif, db_printf); | |||
| 884 | } | |||
| 885 | ||||
| 886 | void | |||
| 887 | db_show_regs(db_expr_t addr, int have_addr, db_expr_t count, char *modif) | |||
| 888 | { | |||
| 889 | struct db_variable *regp; | |||
| 890 | db_expr_t value, offset; | |||
| 891 | char * name; | |||
| 892 | char tmpfmt[28]; | |||
| 893 | ||||
| 894 | for (regp = db_regs; regp < db_eregs; regp++) { | |||
| 895 | db_read_variable(regp, &value); | |||
| 896 | db_printf("%-12s%s", regp->name, | |||
| 897 | db_format(tmpfmt, sizeof tmpfmt, | |||
| 898 | (long)value, DB_FORMAT_N3, 1, sizeof(long) * 3)); | |||
| 899 | db_find_xtrn_sym_and_offset((vaddr_t)value, &name, &offset)db_symbol_values(db_search_symbol((vaddr_t)value,1,&offset ),&name,((void *)0)); | |||
| 900 | if (name != 0 && offset <= db_maxoff && offset != value) { | |||
| 901 | db_printf("\t%s", name); | |||
| 902 | if (offset != 0) | |||
| 903 | db_printf("+%s", | |||
| 904 | db_format(tmpfmt, sizeof tmpfmt, | |||
| 905 | (long)offset, DB_FORMAT_R2, 1, 0)); | |||
| 906 | } | |||
| 907 | db_printf("\n"); | |||
| 908 | } | |||
| 909 | db_print_loc_and_inst(PC_REGS(&ddb_regs)((vaddr_t)(&ddb_regs)->tf_rip)); | |||
| 910 | } | |||
| 911 | ||||
| 912 | /* | |||
| 913 | * Write to file. | |||
| 914 | */ | |||
| 915 | void | |||
| 916 | db_write_cmd(db_expr_t address, int have_addr, db_expr_t count, char *modif) | |||
| 917 | { | |||
| 918 | vaddr_t addr; | |||
| 919 | db_expr_t old_value; | |||
| 920 | db_expr_t new_value; | |||
| 921 | int size, wrote_one = 0; | |||
| 922 | char tmpfmt[28]; | |||
| 923 | ||||
| 924 | addr = (vaddr_t) address; | |||
| 925 | ||||
| 926 | switch (modif[0]) { | |||
| 927 | case 'b': | |||
| 928 | size = 1; | |||
| 929 | break; | |||
| 930 | case 'h': | |||
| 931 | size = 2; | |||
| 932 | break; | |||
| 933 | case 'l': | |||
| 934 | case '\0': | |||
| 935 | size = 4; | |||
| 936 | break; | |||
| 937 | #ifdef __LP64__1 | |||
| 938 | case 'q': | |||
| 939 | size = 8; | |||
| 940 | break; | |||
| 941 | #endif | |||
| 942 | default: | |||
| 943 | size = -1; | |||
| 944 | db_error("Unknown size\n"); | |||
| 945 | /*NOTREACHED*/ | |||
| 946 | } | |||
| 947 | ||||
| 948 | while (db_expression(&new_value)) { | |||
| 949 | old_value = db_get_value(addr, size, 0); | |||
| 950 | db_printsym(addr, DB_STGY_ANY0, db_printf); | |||
| 951 | db_printf("\t\t%s\t", db_format(tmpfmt, sizeof tmpfmt, | |||
| 952 | old_value, DB_FORMAT_N3, 0, 8)); | |||
| 953 | db_printf("=\t%s\n", db_format(tmpfmt, sizeof tmpfmt, | |||
| 954 | new_value, DB_FORMAT_N3, 0, 8)); | |||
| 955 | db_put_value(addr, size, new_value); | |||
| 956 | addr += size; | |||
| 957 | ||||
| 958 | wrote_one = 1; | |||
| 959 | } | |||
| 960 | ||||
| 961 | if (!wrote_one) { | |||
| 962 | db_error("Nothing written.\n"); | |||
| 963 | /*NOTREACHED*/ | |||
| 964 | } | |||
| 965 | ||||
| 966 | db_next = addr; | |||
| 967 | db_prev = addr - size; | |||
| 968 | ||||
| 969 | db_skip_to_eol(); | |||
| 970 | } |