| 49 | #include <ddb/db_sym.h> |
| 50 | |
| 51 | void |
| 52 | db_show_regs(db_expr_t _1, bool _2, db_expr_t _3, char *modif) |
| 53 | { |
| 54 | struct trapframe *oldtf; |
| 55 | struct db_variable *regp; |
| 56 | db_expr_t value, offset; |
| 57 | const char *name; |
| 58 | |
| 59 | /* |
| 60 | * The 'u' modifier instructs us to print the previous trapframe, most |
| 61 | * often containing state from userspace. This is done by temporarily |
| 62 | * switching out kdb_frame. |
| 63 | * |
| 64 | * NB: curthread is used instead of kdb_thread, so that behaviour is |
| 65 | * consistent with regular `show registers`, which always prints |
| 66 | * curthread's trapframe. |
| 67 | */ |
| 68 | oldtf = kdb_frame; |
| 69 | if (modif[0] == 'u') { |
| 70 | if (curthread->td_frame == NULL || |
| 71 | curthread->td_frame == oldtf) { |
| 72 | db_printf("previous trapframe unavailable"); |
| 73 | return; |
| 74 | } |
| 75 | kdb_frame = curthread->td_frame; |
| 76 | } |
| 77 | |
| 78 | for (regp = db_regs; regp < db_eregs; regp++) { |
| 79 | if (!db_read_variable(regp, &value)) |
| 80 | continue; |
| 81 | db_printf("%-12s%#*lr", regp->name, |
| 82 | (int)(sizeof(unsigned long) * 2 + 2), (unsigned long)value); |
| 83 | db_find_xtrn_sym_and_offset((db_addr_t)value, &name, &offset); |
| 84 | if (name != NULL && offset <= (unsigned long)db_maxoff && |
| 85 | offset != value) { |
| 86 | db_printf("\t%s", name); |
| 87 | if (offset != 0) |
| 88 | db_printf("+%+#lr", (long)offset); |
| 89 | } |
| 90 | db_printf("\n"); |
| 91 | } |
| 92 | db_print_loc_and_inst(PC_REGS()); |
| 93 | |
| 94 | kdb_frame = oldtf; |
| 95 | } |
nothing calls this directly
no test coverage detected