---
tools/xentrace/xenctx.c | 284 ++++++++++++++++++++++++++++++++++++++++++++++-
1 files changed, 282 insertions(+), 2 deletions(-)
diff --git a/tools/xentrace/xenctx.c b/tools/xentrace/xenctx.c
index 6ec9c74..d3cbb22 100644
--- a/tools/xentrace/xenctx.c
+++ b/tools/xentrace/xenctx.c
@@ -415,6 +415,247 @@ static void print_ctx(vcpu_guest_context_any_t *ctx)
print_ctx_64(&ctx->x64);
}
+#if defined(__i386__) || defined(__x86_64__)
+static void print_cpuctx_regs64(struct hvm_hw_cpu *ctx)
+{
+ printf("rip: %016"PRIx64, ctx->rip);
+ print_symbol(ctx->rip, KERNEL_TEXT_ADDR);
+ print_flags(ctx->rflags);
+ printf("rsp: %016"PRIx64"\n", ctx->rsp);
+
+ printf("rax: %016"PRIx64"\t", ctx->rax);
+ printf("rcx: %016"PRIx64"\t", ctx->rcx);
+ printf("rdx: %016"PRIx64"\n", ctx->rdx);
+
+ printf("rbx: %016"PRIx64"\t", ctx->rbx);
+ printf("rsi: %016"PRIx64"\t", ctx->rsi);
+ printf("rdi: %016"PRIx64"\n", ctx->rdi);
+
+ printf("rbp: %016"PRIx64"\t", ctx->rbp);
+ printf(" r8: %016"PRIx64"\t", ctx->r8);
+ printf(" r9: %016"PRIx64"\n", ctx->r9);
+
+ printf("r10: %016"PRIx64"\t", ctx->r10);
+ printf("r11: %016"PRIx64"\t", ctx->r11);
+ printf("r12: %016"PRIx64"\n", ctx->r12);
+
+ printf("r13: %016"PRIx64"\t", ctx->r13);
+ printf("r14: %016"PRIx64"\t", ctx->r14);
+ printf("r15: %016"PRIx64"\n", ctx->r15);
+
+ printf(" cs: %04x @ %016"PRIx64, ctx->cs_sel, ctx->cs_base);
+ if (ctx->cs_base)
+ print_symbol(ctx->cs_base, KERNEL_DATA_ADDR);
+ printf("\n /%08x(%x)\n", ctx->cs_limit, ctx->cs_arbytes);
+ printf(" ss: %04x @ %016"PRIx64, ctx->ss_sel, ctx->ss_base);
+ if (ctx->ss_base)
+ print_symbol(ctx->ss_base, KERNEL_DATA_ADDR);
+ printf("\n /%08x(%x)\n", ctx->ss_limit, ctx->ss_arbytes);
+ printf(" ds: %04x @ %016"PRIx64, ctx->ds_sel, ctx->ds_base);
+ if (ctx->ds_base)
+ print_symbol(ctx->ds_base, KERNEL_DATA_ADDR);
+ printf("\n /%08x(%x)\n", ctx->ds_limit, ctx->ds_arbytes);
+ printf(" es: %04x @ %016"PRIx64, ctx->es_sel, ctx->es_base);
+ if (ctx->es_base)
+ print_symbol(ctx->es_base, KERNEL_DATA_ADDR);
+ printf("\n /%08x(%x)\n", ctx->es_limit, ctx->es_arbytes);
+ printf(" fs: %04x @ %016"PRIx64, ctx->fs_sel, ctx->fs_base);
+ if (ctx->fs_base)
+ print_symbol(ctx->fs_base, KERNEL_DATA_ADDR);
+ printf("\n /%08x(%x)\n", ctx->fs_limit, ctx->fs_arbytes);
+ printf(" gs: %04x @ %016"PRIx64"\\%016"PRIx64, ctx->gs_sel,
+ ctx->gs_base, ctx->shadow_gs);
+ if (ctx->gs_base)
+ print_symbol(ctx->gs_base, KERNEL_DATA_ADDR);
+ printf("\\");
+ if (ctx->shadow_gs)
+ print_symbol(ctx->shadow_gs, KERNEL_DATA_ADDR);
+ printf("\n /%08x(%x)\n", ctx->gs_limit, ctx->gs_arbytes);
+
+ if (xenctx.disp_all) {
+ printf(" tr: %04x @ %016"PRIx64, ctx->tr_sel, ctx->tr_base);
+ if (ctx->tr_base)
+ print_symbol(ctx->tr_base, KERNEL_DATA_ADDR);
+ printf("\n /%08x(%x)\n", ctx->tr_limit, ctx->tr_arbytes);
+ printf(" ldt: %04x @ %016"PRIx64, ctx->ldtr_sel, ctx->ldtr_base);
+ if (ctx->ldtr_base)
+ print_symbol(ctx->ldtr_base, KERNEL_DATA_ADDR);
+ printf("\n /%08x(%x)\n", ctx->ldtr_limit, ctx->ldtr_arbytes);
+ printf("\n");
+ printf("cr0: %08"PRIx64"\n", ctx->cr0);
+ printf("cr2: %08"PRIx64, ctx->cr2);
+ print_symbol(ctx->cr2, KERNEL_DATA_ADDR);
+ printf("\n");
+ printf("cr3: %08"PRIx64"\n", ctx->cr3);
+ printf("cr4: %08"PRIx64"\n", ctx->cr4);
+ printf("\n");
+ printf("dr0: %08"PRIx64, ctx->dr0);
+ print_symbol(ctx->dr0, KERNEL_DATA_ADDR);
+ printf("\n");
+ printf("dr1: %08"PRIx64, ctx->dr1);
+ print_symbol(ctx->dr1, KERNEL_DATA_ADDR);
+ printf("\n");
+ printf("dr2: %08"PRIx64, ctx->dr2);
+ print_symbol(ctx->dr2, KERNEL_DATA_ADDR);
+ printf("\n");
+ printf("dr3: %08"PRIx64, ctx->dr3);
+ print_symbol(ctx->dr3, KERNEL_DATA_ADDR);
+ printf("\n");
+ printf("dr6: %08"PRIx64"\n", ctx->dr6);
+ printf("dr7: %08"PRIx64"\n", ctx->dr7);
+ printf("\n");
+ printf("gdt: %016"PRIx64"/%lx", ctx->gdtr_base,
(long)(ctx->gdtr_limit));
+ print_symbol(ctx->gdtr_base, KERNEL_DATA_ADDR);
+ printf("\n");
+ printf("idt: %016"PRIx64"/%lx", ctx->idtr_base,
(long)(ctx->idtr_limit));
+ print_symbol(ctx->idtr_base, KERNEL_DATA_ADDR);
+ printf("\n");
+ printf("\n");
+ printf(" EFER: %08"PRIx64" flags: %08"PRIx64"\n",
+ ctx->msr_efer, ctx->msr_flags);
+ printf("SYSENTER cs: %08"PRIx64" esp: %08"PRIx64" eip: %08"PRIx64,
+ ctx->sysenter_cs, ctx->sysenter_esp, ctx->sysenter_eip);
+ print_symbol(ctx->sysenter_eip, KERNEL_TEXT_ADDR);
+ printf("\n");
+ printf(" STAR: %08"PRIx64" SFMASK: %08"PRIx64"\n",
+ ctx->msr_star, ctx->msr_syscall_mask);
+ printf("LSTAR: %08"PRIx64, ctx->msr_lstar);
+ print_symbol(ctx->msr_lstar, KERNEL_TEXT_ADDR);
+ printf("\n");
+ printf("CSTAR: %08"PRIx64, ctx->msr_cstar);
+ print_symbol(ctx->msr_cstar, KERNEL_TEXT_ADDR);
+ printf("\n");
+ printf("\n");
+ printf("\n");
+ printf(" tsc: %016"PRIx64"\n", ctx->tsc);
+ printf("\n");
+ printf("\n");
+ printf("pending_event: %lx pending_vector: %lx\n",
+ (long)(ctx->pending_event), (long)(ctx->pending_vector));
+ printf("pending error_code: %lx\n\n", (long)(ctx->error_code));
+ }
+}
+
+static void print_cpuctx_regs32(struct hvm_hw_cpu *ctx)
+{
+ printf("cs:eip: %04x:%08x", ctx->cs_sel, (uint32_t)ctx->rip);
+ print_symbol((uint32_t)ctx->rip, KERNEL_TEXT_ADDR);
+ print_flags((uint32_t)ctx->rflags);
+ printf("ss:esp: %04x:%08x\n", ctx->ss_sel, (uint32_t)ctx->rsp);
+ printf("\n");
+
+ printf("eax: %08x\t", (uint32_t)ctx->rax);
+ printf("ebx: %08x\t", (uint32_t)ctx->rbx);
+ printf("ecx: %08x\t", (uint32_t)ctx->rcx);
+ printf("edx: %08x\n", (uint32_t)ctx->rdx);
+
+ printf("esi: %08x\t", (uint32_t)ctx->rsi);
+ printf("edi: %08x\t", (uint32_t)ctx->rdi);
+ printf("ebp: %08x\n", (uint32_t)ctx->rbp);
+ printf("\n");
+
+ printf(" cs: %04x @ %08"PRIx64, ctx->cs_sel, ctx->cs_base);
+ if (ctx->cs_base)
+ print_symbol(ctx->cs_base, KERNEL_DATA_ADDR);
+ printf("\n /%08x(%x)\n", ctx->cs_limit, ctx->cs_arbytes);
+ printf(" ss: %04x @ %08"PRIx64, ctx->ss_sel, ctx->ss_base);
+ if (ctx->ss_base)
+ print_symbol(ctx->ss_base, KERNEL_DATA_ADDR);
+ printf("\n /%08x(%x)\n", ctx->ss_limit, ctx->ss_arbytes);
+ printf(" ds: %04x @ %08"PRIx64, ctx->ds_sel, ctx->ds_base);
+ if (ctx->ds_base)
+ print_symbol(ctx->ds_base, KERNEL_DATA_ADDR);
+ printf("\n /%08x(%x)\n", ctx->ds_limit, ctx->ds_arbytes);
+ printf(" es: %04x @ %08"PRIx64, ctx->es_sel, ctx->es_base);
+ if (ctx->es_base)
+ print_symbol(ctx->es_base, KERNEL_DATA_ADDR);
+ printf("\n /%08x(%x)\n", ctx->es_limit, ctx->es_arbytes);
+ printf(" fs: %04x @ %08"PRIx64, ctx->fs_sel, ctx->fs_base);
+ if (ctx->fs_base)
+ print_symbol(ctx->fs_base, KERNEL_DATA_ADDR);
+ printf("\n /%08x(%x)\n", ctx->fs_limit, ctx->fs_arbytes);
+ printf(" gs: %04x @ %08"PRIx64"\\%08"PRIx64, ctx->gs_sel,
+ ctx->gs_base, ctx->shadow_gs);
+ if (ctx->gs_base)
+ print_symbol(ctx->gs_base, KERNEL_DATA_ADDR);
+ printf("\\");
+ if (ctx->shadow_gs)
+ print_symbol(ctx->shadow_gs, KERNEL_DATA_ADDR);
+ printf("\n /%08x(%x)\n", ctx->gs_limit, ctx->gs_arbytes);
+
+ if (xenctx.disp_all) {
+ printf(" tr: %04x @ %08"PRIx64, ctx->tr_sel, ctx->tr_base);
+ if (ctx->tr_base)
+ print_symbol(ctx->tr_base, KERNEL_DATA_ADDR);
+ printf("\n /%08x(%x)\n", ctx->tr_limit, ctx->tr_arbytes);
+ printf(" ldt: %04x @ %08"PRIx64, ctx->ldtr_sel, ctx->ldtr_base);
+ if (ctx->ldtr_base)
+ print_symbol(ctx->ldtr_base, KERNEL_DATA_ADDR);
+ printf("\n /%08x(%x)\n", ctx->ldtr_limit, ctx->ldtr_arbytes);
+ printf("\n");
+ printf("cr0: %08"PRIx64"\n", ctx->cr0);
+ printf("cr2: %08"PRIx64, ctx->cr2);
+ print_symbol(ctx->cr2, KERNEL_DATA_ADDR);
+ printf("\n");
+ printf("cr3: %08"PRIx64"\n", ctx->cr3);
+ printf("cr4: %08"PRIx64"\n", ctx->cr4);
+ printf("\n");
+ printf("dr0: %08"PRIx64, ctx->dr0);
+ print_symbol(ctx->dr0, KERNEL_DATA_ADDR);
+ printf("\n");
+ printf("dr1: %08"PRIx64, ctx->dr1);
+ print_symbol(ctx->dr1, KERNEL_DATA_ADDR);
+ printf("\n");
+ printf("dr2: %08"PRIx64, ctx->dr2);
+ print_symbol(ctx->dr2, KERNEL_DATA_ADDR);
+ printf("\n");
+ printf("dr3: %08"PRIx64, ctx->dr3);
+ print_symbol(ctx->dr3, KERNEL_DATA_ADDR);
+ printf("\n");
+ printf("dr6: %08"PRIx64"\n", ctx->dr6);
+ printf("dr7: %08"PRIx64"\n", ctx->dr7);
+ printf("\n");
+ printf("gdt: %08"PRIx64"/%lx", ctx->gdtr_base,
(long)(ctx->gdtr_limit));
+ print_symbol(ctx->gdtr_base, KERNEL_DATA_ADDR);
+ printf("\n");
+ printf("idt: %08"PRIx64"/%lx", ctx->idtr_base,
(long)(ctx->idtr_limit));
+ print_symbol(ctx->idtr_base, KERNEL_DATA_ADDR);
+ printf("\n");
+ printf("\n");
+ printf(" EFER: %08"PRIx64" flags: %08"PRIx64"\n",
+ ctx->msr_efer, ctx->msr_flags);
+ printf("SYSENTER cs: %08"PRIx64" esp: %08"PRIx64" eip: %08"PRIx64,
+ ctx->sysenter_cs, ctx->sysenter_esp, ctx->sysenter_eip);
+ print_symbol(ctx->sysenter_eip, KERNEL_TEXT_ADDR);
+ printf("\n");
+ printf(" STAR: %08"PRIx64" SFMASK: %08"PRIx64"\n",
+ ctx->msr_star, ctx->msr_syscall_mask);
+ printf("LSTAR: %08"PRIx64, ctx->msr_lstar);
+ print_symbol(ctx->msr_lstar, KERNEL_TEXT_ADDR);
+ printf("\n");
+ printf("CSTAR: %08"PRIx64, ctx->msr_cstar);
+ print_symbol(ctx->msr_cstar, KERNEL_TEXT_ADDR);
+ printf("\n");
+ printf("\n");
+ printf(" tsc: %016"PRIx64"\n", ctx->tsc);
+ printf("\n");
+ printf("\n");
+ printf("pending_event: %lx pending_vector: %lx\n",
+ (long)(ctx->pending_event), (long)(ctx->pending_vector));
+ printf("pending error_code: %lx\n\n", (long)(ctx->error_code));
+ }
+}
+
+static void print_cpuctx(struct hvm_hw_cpu *ctx)
+{
+ if (guest_word_size == 8)
+ print_cpuctx_regs64(ctx);
+ else
+ print_cpuctx_regs32(ctx);
+
+}
+#endif
+
#define NONPROT_MODE_SEGMENT_SHIFT 4
static guest_word_t instr_pointer(vcpu_guest_context_any_t *ctx)
@@ -887,6 +1128,9 @@ static int print_stack(vcpu_guest_context_any_t *ctx, int
vcpu, int width, guest
static void dump_ctx(int vcpu, guest_word_t mem_addr, guest_word_t stk_addr)
{
vcpu_guest_context_any_t ctx;
+#if defined(__i386__) || defined(__x86_64__)
+ struct hvm_hw_cpu cpuctx;
+#endif
if (xc_vcpu_getcontext(xenctx.xc_handle, xenctx.domid, vcpu, &ctx) < 0) {
perror("xc_vcpu_getcontext");
@@ -896,7 +1140,6 @@ static void dump_ctx(int vcpu, guest_word_t mem_addr,
guest_word_t stk_addr)
#if defined(__i386__) || defined(__x86_64__)
{
if (xenctx.dominfo.hvm) {
- struct hvm_hw_cpu cpuctx;
xen_capabilities_info_t xen_caps = "";
if (xc_domain_hvm_getcontext_partial(
xenctx.xc_handle, xenctx.domid, HVM_SAVE_CODE(CPU),
@@ -931,7 +1174,44 @@ static void dump_ctx(int vcpu, guest_word_t mem_addr,
guest_word_t stk_addr)
#endif
} else {
if (!stk_addr) {
- print_ctx(&ctx);
+#if defined(__i386__) || defined(__x86_64__)
+ if (xenctx.dominfo.hvm && ctxt_word_size == 8) {
+ if (guest_word_size == 4) {
+ if ((((uint32_t)ctx.x64.user_regs.eip) != cpuctx.rip) ||
+ (((uint32_t)ctx.x64.user_regs.esp) != cpuctx.rsp) ||
+ (((uint32_t)ctx.x64.ctrlreg[3]) != cpuctx.cr3)) {
+ fprintf(stderr, "Regs mismatch ip=%llx vs %llx sp=%llx vs
%llx cr3=%llx vs %llx\n",
+ (long long)((uint32_t)ctx.x64.user_regs.eip),
+ (long long)cpuctx.rip,
+ (long long)((uint32_t)ctx.x64.user_regs.esp),
+ (long long)cpuctx.rsp,
+ (long long)((uint32_t)ctx.x64.ctrlreg[3]),
+ (long long)cpuctx.cr3);
+ fprintf(stdout, "=============Regs mismatch
start=============\n");
+ print_ctx(&ctx);
+ fprintf(stdout, "=============Regs mismatch
end=============\n");
+ }
+ } else {
+ if ((ctx.x64.user_regs.eip != cpuctx.rip) ||
+ (ctx.x64.user_regs.esp != cpuctx.rsp) ||
+ (ctx.x64.ctrlreg[3] != cpuctx.cr3)) {
+ fprintf(stderr, "Regs mismatch ip=%llx vs %llx sp=%llx vs
%llx cr3=%llx vs %llx\n",
+ (long long)ctx.x64.user_regs.eip,
+ (long long)cpuctx.rip,
+ (long long)ctx.x64.user_regs.esp,
+ (long long)cpuctx.rsp,
+ (long long)ctx.x64.ctrlreg[3],
+ (long long)cpuctx.cr3);
+ fprintf(stdout, "=============Regs mismatch
start=============\n");
+ print_ctx(&ctx);
+ fprintf(stdout, "=============Regs mismatch
end=============\n");
+ }
+ }
+ print_cpuctx(&cpuctx);
+ }
+ else
+#endif
+ print_ctx(&ctx);
}
#ifndef NO_TRANSLATION
if (!stk_addr) {