MFC 285783:
Various changes to the registers displayed in DDB for x86. - Fix segment registers to only display the low 16 bits. - Remove unused handlers and entries for the debug registers. - Display xcr0 (if valid) in 'show sysregs'. - Add '0x' prefix to MSR values to match other values in 'show sysregs'. - MFamd64: Display various MSRs in 'show sysregs'. - Add a 'show dbregs' to display the value of debug registers. - Dynamically size the column width for register values to properly align columns on 64-bit platforms. - Display %gs for i386 in 'show registers'.
This commit is contained in:
parent
2285630285
commit
d10f133720
@ -52,15 +52,8 @@ __FBSDID("$FreeBSD$");
|
||||
#include <ddb/db_sym.h>
|
||||
#include <ddb/db_variables.h>
|
||||
|
||||
static db_varfcn_t db_dr0;
|
||||
static db_varfcn_t db_dr1;
|
||||
static db_varfcn_t db_dr2;
|
||||
static db_varfcn_t db_dr3;
|
||||
static db_varfcn_t db_dr4;
|
||||
static db_varfcn_t db_dr5;
|
||||
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;
|
||||
|
||||
CTASSERT(sizeof(struct dbreg) == sizeof(((struct pcpu *)NULL)->pc_dbreg));
|
||||
|
||||
@ -69,12 +62,12 @@ CTASSERT(sizeof(struct dbreg) == sizeof(((struct pcpu *)NULL)->pc_dbreg));
|
||||
*/
|
||||
#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 },
|
||||
{ "ss", DB_OFFSET(tf_ss), 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", DB_OFFSET(tf_ss), db_frame_seg },
|
||||
{ "rax", DB_OFFSET(tf_rax), db_frame },
|
||||
{ "rcx", DB_OFFSET(tf_rcx), db_frame },
|
||||
{ "rdx", DB_OFFSET(tf_rdx), db_frame },
|
||||
@ -93,41 +86,25 @@ struct db_variable db_regs[] = {
|
||||
{ "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. */
|
||||
{ "dr0", NULL, db_dr0 },
|
||||
{ "dr1", NULL, db_dr1 },
|
||||
{ "dr2", NULL, db_dr2 },
|
||||
{ "dr3", NULL, db_dr3 },
|
||||
{ "dr4", NULL, db_dr4 },
|
||||
{ "dr5", NULL, db_dr5 },
|
||||
{ "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) \
|
||||
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 (); \
|
||||
else \
|
||||
load_ ## reg (*valuep); \
|
||||
return (1); \
|
||||
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);
|
||||
}
|
||||
|
||||
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)
|
||||
|
||||
static int
|
||||
db_frame(struct db_variable *vp, db_expr_t *valuep, int op)
|
||||
{
|
||||
|
@ -1238,11 +1238,26 @@ DB_SHOW_COMMAND(sysregs, db_show_sysregs)
|
||||
db_printf("cr2\t0x%016lx\n", rcr2());
|
||||
db_printf("cr3\t0x%016lx\n", rcr3());
|
||||
db_printf("cr4\t0x%016lx\n", rcr4());
|
||||
db_printf("EFER\t%016lx\n", rdmsr(MSR_EFER));
|
||||
db_printf("FEATURES_CTL\t%016lx\n", rdmsr(MSR_IA32_FEATURE_CONTROL));
|
||||
db_printf("DEBUG_CTL\t%016lx\n", rdmsr(MSR_DEBUGCTLMSR));
|
||||
db_printf("PAT\t%016lx\n", rdmsr(MSR_PAT));
|
||||
db_printf("GSBASE\t%016lx\n", rdmsr(MSR_GSBASE));
|
||||
if (rcr4() & CR4_XSAVE)
|
||||
db_printf("xcr0\t0x%016lx\n", rxcr(0));
|
||||
db_printf("EFER\t0x%016lx\n", rdmsr(MSR_EFER));
|
||||
if (cpu_feature2 & (CPUID2_VMX | CPUID2_SMX))
|
||||
db_printf("FEATURES_CTL\t%016lx\n",
|
||||
rdmsr(MSR_IA32_FEATURE_CONTROL));
|
||||
db_printf("DEBUG_CTL\t0x%016lx\n", rdmsr(MSR_DEBUGCTLMSR));
|
||||
db_printf("PAT\t0x%016lx\n", rdmsr(MSR_PAT));
|
||||
db_printf("GSBASE\t0x%016lx\n", rdmsr(MSR_GSBASE));
|
||||
}
|
||||
|
||||
DB_SHOW_COMMAND(dbregs, db_show_dbregs)
|
||||
{
|
||||
|
||||
db_printf("dr0\t0x%016lx\n", rdr0());
|
||||
db_printf("dr1\t0x%016lx\n", rdr1());
|
||||
db_printf("dr2\t0x%016lx\n", rdr2());
|
||||
db_printf("dr3\t0x%016lx\n", rdr3());
|
||||
db_printf("dr6\t0x%016lx\n", rdr6());
|
||||
db_printf("dr7\t0x%016lx\n", rdr7());
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -56,7 +56,8 @@ db_show_regs(db_expr_t _1, boolean_t _2, db_expr_t _3, char *_4)
|
||||
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) {
|
||||
|
@ -48,16 +48,10 @@ __FBSDID("$FreeBSD$");
|
||||
#include <ddb/db_sym.h>
|
||||
#include <ddb/db_variables.h>
|
||||
|
||||
static db_varfcn_t db_dr0;
|
||||
static db_varfcn_t db_dr1;
|
||||
static db_varfcn_t db_dr2;
|
||||
static db_varfcn_t db_dr3;
|
||||
static db_varfcn_t db_dr4;
|
||||
static db_varfcn_t db_dr5;
|
||||
static db_varfcn_t db_dr6;
|
||||
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;
|
||||
|
||||
/*
|
||||
@ -65,10 +59,11 @@ static db_varfcn_t db_ss;
|
||||
*/
|
||||
#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,40 +75,8 @@ struct db_variable db_regs[] = {
|
||||
{ "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. */
|
||||
{ "dr0", NULL, db_dr0 },
|
||||
{ "dr1", NULL, db_dr1 },
|
||||
{ "dr2", NULL, db_dr2 },
|
||||
{ "dr3", NULL, db_dr3 },
|
||||
{ "dr4", NULL, db_dr4 },
|
||||
{ "dr5", NULL, db_dr5 },
|
||||
{ "dr6", NULL, db_dr6 },
|
||||
{ "dr7", NULL, db_dr7 },
|
||||
};
|
||||
struct db_variable *db_eregs = db_regs + DB_N_SHOW_REGS;
|
||||
|
||||
#define DB_DRX_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 (); \
|
||||
else \
|
||||
load_ ## reg (*valuep); \
|
||||
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)
|
||||
struct db_variable *db_eregs = db_regs + nitems(db_regs);
|
||||
|
||||
static __inline int
|
||||
get_esp(struct trapframe *tf)
|
||||
@ -138,6 +101,22 @@ db_frame(struct db_variable *vp, db_expr_t *valuep, int op)
|
||||
return (1);
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
@ -152,6 +131,17 @@ db_esp(struct db_variable *vp, db_expr_t *valuep, int op)
|
||||
return (1);
|
||||
}
|
||||
|
||||
static int
|
||||
db_gs(struct db_variable *vp, db_expr_t *valuep, int op)
|
||||
{
|
||||
|
||||
if (op == DB_VAR_GET)
|
||||
*valuep = rgs();
|
||||
else
|
||||
load_gs(*valuep);
|
||||
return (1);
|
||||
}
|
||||
|
||||
static int
|
||||
db_ss(struct db_variable *vp, db_expr_t *valuep, int op)
|
||||
{
|
||||
|
@ -2043,6 +2043,29 @@ DB_SHOW_COMMAND(sysregs, db_show_sysregs)
|
||||
db_printf("cr2\t0x%08x\n", rcr2());
|
||||
db_printf("cr3\t0x%08x\n", rcr3());
|
||||
db_printf("cr4\t0x%08x\n", rcr4());
|
||||
if (rcr4() & CR4_XSAVE)
|
||||
db_printf("xcr0\t0x%016llx\n", rxcr(0));
|
||||
if (amd_feature & (AMDID_NX | AMDID_LM))
|
||||
db_printf("EFER\t0x%016llx\n", rdmsr(MSR_EFER));
|
||||
if (cpu_feature2 & (CPUID2_VMX | CPUID2_SMX))
|
||||
db_printf("FEATURES_CTL\t0x%016llx\n",
|
||||
rdmsr(MSR_IA32_FEATURE_CONTROL));
|
||||
if ((cpu_vendor_id == CPU_VENDOR_INTEL ||
|
||||
cpu_vendor_id == CPU_VENDOR_AMD) && CPUID_TO_FAMILY(cpu_id) >= 6)
|
||||
db_printf("DEBUG_CTL\t0x%016llx\n", rdmsr(MSR_DEBUGCTLMSR));
|
||||
if (cpu_feature & CPUID_PAT)
|
||||
db_printf("PAT\t0x%016llx\n", rdmsr(MSR_PAT));
|
||||
}
|
||||
|
||||
DB_SHOW_COMMAND(dbregs, db_show_dbregs)
|
||||
{
|
||||
|
||||
db_printf("dr0\t0x%08x\n", rdr0());
|
||||
db_printf("dr1\t0x%08x\n", rdr1());
|
||||
db_printf("dr2\t0x%08x\n", rdr2());
|
||||
db_printf("dr3\t0x%08x\n", rdr3());
|
||||
db_printf("dr6\t0x%08x\n", rdr6());
|
||||
db_printf("dr7\t0x%08x\n", rdr7());
|
||||
}
|
||||
#endif
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user