Index: sys/amd64/amd64/db_trace.c =================================================================== --- sys/amd64/amd64/db_trace.c +++ sys/amd64/amd64/db_trace.c @@ -52,6 +52,10 @@ #include #include +static db_varfcn_t db_cr0; +static db_varfcn_t db_cr2; +static db_varfcn_t db_cr3; +static db_varfcn_t db_cr4; static db_varfcn_t db_dr0; static db_varfcn_t db_dr1; static db_varfcn_t db_dr2; @@ -61,8 +65,10 @@ static db_varfcn_t db_dr6; static db_varfcn_t db_dr7; static db_varfcn_t db_frame; +static db_varfcn_t db_frame_seg; static db_varfcn_t db_rsp; static db_varfcn_t db_ss; +static db_varfcn_t db_xcr; CTASSERT(sizeof(struct dbreg) == sizeof(((struct pcpu *)NULL)->pc_dbreg)); @@ -71,11 +77,11 @@ */ #define DB_OFFSET(x) (db_expr_t *)offsetof(struct trapframe, x) struct db_variable db_regs[] = { - { "cs", DB_OFFSET(tf_cs), db_frame }, - { "ds", DB_OFFSET(tf_ds), db_frame }, - { "es", DB_OFFSET(tf_es), db_frame }, - { "fs", DB_OFFSET(tf_fs), db_frame }, - { "gs", DB_OFFSET(tf_gs), db_frame }, + { "cs", DB_OFFSET(tf_cs), db_frame_seg }, + { "ds", DB_OFFSET(tf_ds), db_frame_seg }, + { "es", DB_OFFSET(tf_es), db_frame_seg }, + { "fs", DB_OFFSET(tf_fs), db_frame_seg }, + { "gs", DB_OFFSET(tf_gs), db_frame_seg }, { "ss", NULL, db_ss }, { "rax", DB_OFFSET(tf_rax), db_frame }, { "rcx", DB_OFFSET(tf_rcx), db_frame }, @@ -95,7 +101,11 @@ { "r15", DB_OFFSET(tf_r15), db_frame }, { "rip", DB_OFFSET(tf_rip), db_frame }, { "rflags", DB_OFFSET(tf_rflags), db_frame }, -#define DB_N_SHOW_REGS 24 /* Don't show registers after here. */ + { "cr0", NULL, db_cr0 }, + { "cr2", NULL, db_cr2 }, + { "cr3", NULL, db_cr3 }, + { "cr4", NULL, db_cr4 }, + { "xcr0", 0, db_xcr }, { "dr0", NULL, db_dr0 }, { "dr1", NULL, db_dr1 }, { "dr2", NULL, db_dr2 }, @@ -105,9 +115,9 @@ { "dr6", NULL, db_dr6 }, { "dr7", NULL, db_dr7 }, }; -struct db_variable *db_eregs = db_regs + DB_N_SHOW_REGS; +struct db_variable *db_eregs = db_regs + nitems(db_regs); -#define DB_DRX_FUNC(reg) \ +#define DB_RW_REG_FUNC(reg) \ static int \ db_ ## reg (vp, valuep, op) \ struct db_variable *vp; \ @@ -121,14 +131,32 @@ return (1); \ } -DB_DRX_FUNC(dr0) -DB_DRX_FUNC(dr1) -DB_DRX_FUNC(dr2) -DB_DRX_FUNC(dr3) -DB_DRX_FUNC(dr4) -DB_DRX_FUNC(dr5) -DB_DRX_FUNC(dr6) -DB_DRX_FUNC(dr7) +#define DB_RO_REG_FUNC(reg) \ +static int \ +db_ ## reg (vp, valuep, op) \ + struct db_variable *vp; \ + db_expr_t * valuep; \ + int op; \ +{ \ + if (op == DB_VAR_GET) { \ + *valuep = r ## reg (); \ + return (1); \ + } \ + return (0); \ +} + +DB_RW_REG_FUNC(cr0) +DB_RO_REG_FUNC(cr2) +DB_RW_REG_FUNC(cr3) +DB_RW_REG_FUNC(cr4) +DB_RW_REG_FUNC(dr0) +DB_RW_REG_FUNC(dr1) +DB_RW_REG_FUNC(dr2) +DB_RW_REG_FUNC(dr3) +DB_RW_REG_FUNC(dr4) +DB_RW_REG_FUNC(dr5) +DB_RW_REG_FUNC(dr6) +DB_RW_REG_FUNC(dr7) static __inline long get_rsp(struct trapframe *tf) @@ -138,6 +166,22 @@ } static int +db_frame_seg(struct db_variable *vp, db_expr_t *valuep, int op) +{ + uint16_t *reg; + + if (kdb_frame == NULL) + return (0); + + reg = (uint16_t *)((uintptr_t)kdb_frame + (db_expr_t)vp->valuep); + if (op == DB_VAR_GET) + *valuep = *reg; + else + *reg = *valuep; + return (1); +} + +static int db_frame(struct db_variable *vp, db_expr_t *valuep, int op) { long *reg; @@ -181,6 +225,23 @@ return (1); } +static int +db_xcr(struct db_variable *vp, db_expr_t *valuep, int op) +{ + u_int reg; + + reg = (db_expr_t)vp->valuep; + if (reg != 0) + return (0); + if ((rcr4() & CR4_XSAVE) == 0) + return (0); + if (op == DB_VAR_GET) + *valuep = rxcr(reg); + else + load_xcr(reg, *valuep); + return (1); +} + #define NORMAL 0 #define TRAP 1 #define INTERRUPT 2 Index: sys/ddb/db_print.c =================================================================== --- sys/ddb/db_print.c +++ sys/ddb/db_print.c @@ -56,7 +56,8 @@ for (regp = db_regs; regp < db_eregs; regp++) { if (!db_read_variable(regp, &value)) continue; - db_printf("%-12s%#10lr", regp->name, (unsigned long)value); + db_printf("%-12s%#*lr", regp->name, + (int)(sizeof(unsigned long) * 2 + 2), (unsigned long)value); db_find_xtrn_sym_and_offset((db_addr_t)value, &name, &offset); if (name != NULL && offset <= (unsigned long)db_maxoff && offset != value) { Index: sys/i386/i386/db_trace.c =================================================================== --- sys/i386/i386/db_trace.c +++ sys/i386/i386/db_trace.c @@ -48,6 +48,10 @@ #include #include +static db_varfcn_t db_cr0; +static db_varfcn_t db_cr2; +static db_varfcn_t db_cr3; +static db_varfcn_t db_cr4; static db_varfcn_t db_dr0; static db_varfcn_t db_dr1; static db_varfcn_t db_dr2; @@ -58,17 +62,21 @@ static db_varfcn_t db_dr7; static db_varfcn_t db_esp; static db_varfcn_t db_frame; +static db_varfcn_t db_frame_seg; +static db_varfcn_t db_gs; static db_varfcn_t db_ss; +static db_varfcn_t db_xcr; /* * Machine register set. */ #define DB_OFFSET(x) (db_expr_t *)offsetof(struct trapframe, x) struct db_variable db_regs[] = { - { "cs", DB_OFFSET(tf_cs), db_frame }, - { "ds", DB_OFFSET(tf_ds), db_frame }, - { "es", DB_OFFSET(tf_es), db_frame }, - { "fs", DB_OFFSET(tf_fs), db_frame }, + { "cs", DB_OFFSET(tf_cs), db_frame_seg }, + { "ds", DB_OFFSET(tf_ds), db_frame_seg }, + { "es", DB_OFFSET(tf_es), db_frame_seg }, + { "fs", DB_OFFSET(tf_fs), db_frame_seg }, + { "gs", NULL, db_gs }, { "ss", NULL, db_ss }, { "eax", DB_OFFSET(tf_eax), db_frame }, { "ecx", DB_OFFSET(tf_ecx), db_frame }, @@ -80,7 +88,11 @@ { "edi", DB_OFFSET(tf_edi), db_frame }, { "eip", DB_OFFSET(tf_eip), db_frame }, { "efl", DB_OFFSET(tf_eflags), db_frame }, -#define DB_N_SHOW_REGS 15 /* Don't show registers after here. */ + { "cr0", NULL, db_cr0 }, + { "cr2", NULL, db_cr2 }, + { "cr3", NULL, db_cr3 }, + { "cr4", NULL, db_cr4 }, + { "xcr0", 0, db_xcr }, { "dr0", NULL, db_dr0 }, { "dr1", NULL, db_dr1 }, { "dr2", NULL, db_dr2 }, @@ -90,9 +102,9 @@ { "dr6", NULL, db_dr6 }, { "dr7", NULL, db_dr7 }, }; -struct db_variable *db_eregs = db_regs + DB_N_SHOW_REGS; +struct db_variable *db_eregs = db_regs + nitems(db_regs); -#define DB_DRX_FUNC(reg) \ +#define DB_RW_REG_FUNC(reg) \ static int \ db_ ## reg (vp, valuep, op) \ struct db_variable *vp; \ @@ -106,14 +118,33 @@ return (1); \ } -DB_DRX_FUNC(dr0) -DB_DRX_FUNC(dr1) -DB_DRX_FUNC(dr2) -DB_DRX_FUNC(dr3) -DB_DRX_FUNC(dr4) -DB_DRX_FUNC(dr5) -DB_DRX_FUNC(dr6) -DB_DRX_FUNC(dr7) +#define DB_RO_REG_FUNC(reg) \ +static int \ +db_ ## reg (vp, valuep, op) \ + struct db_variable *vp; \ + db_expr_t * valuep; \ + int op; \ +{ \ + if (op == DB_VAR_GET) { \ + *valuep = r ## reg (); \ + return (1); \ + } \ + return (0); \ +} + +DB_RW_REG_FUNC(cr0) +DB_RO_REG_FUNC(cr2) +DB_RW_REG_FUNC(cr3) +DB_RW_REG_FUNC(cr4) +DB_RW_REG_FUNC(dr0) +DB_RW_REG_FUNC(dr1) +DB_RW_REG_FUNC(dr2) +DB_RW_REG_FUNC(dr3) +DB_RW_REG_FUNC(dr4) +DB_RW_REG_FUNC(dr5) +DB_RW_REG_FUNC(dr6) +DB_RW_REG_FUNC(dr7) +DB_RW_REG_FUNC(gs) static __inline int get_esp(struct trapframe *tf) @@ -139,6 +170,22 @@ } static int +db_frame_seg(struct db_variable *vp, db_expr_t *valuep, int op) +{ + uint16_t *reg; + + if (kdb_frame == NULL) + return (0); + + reg = (uint16_t *)((uintptr_t)kdb_frame + (db_expr_t)vp->valuep); + if (op == DB_VAR_GET) + *valuep = *reg; + else + *reg = *valuep; + return (1); +} + +static int db_esp(struct db_variable *vp, db_expr_t *valuep, int op) { @@ -166,6 +213,23 @@ return (1); } +static int +db_xcr(struct db_variable *vp, db_expr_t *valuep, int op) +{ + u_int reg; + + reg = (db_expr_t)vp->valuep; + if (reg != 0) + return (0); + if ((rcr4() & CR4_XSAVE) == 0) + return (0); + if (op == DB_VAR_GET) + *valuep = rxcr(reg); + else + load_xcr(reg, *valuep); + return (1); +} + #define NORMAL 0 #define TRAP 1 #define INTERRUPT 2