aboutsummaryrefslogtreecommitdiffstats
path: root/tools/xentrace
diff options
context:
space:
mode:
authorKeir Fraser <keir.fraser@citrix.com>2009-03-31 11:38:05 +0100
committerKeir Fraser <keir.fraser@citrix.com>2009-03-31 11:38:05 +0100
commit0a0346fc3f81744534ea79fce2401675e2278356 (patch)
treed2a32985983194a11b1dcd95afab6d333ab41602 /tools/xentrace
parent1ecaba192cef7fbdfb28504275d9396af7e4da36 (diff)
downloadxen-0a0346fc3f81744534ea79fce2401675e2278356.tar.gz
xen-0a0346fc3f81744534ea79fce2401675e2278356.tar.bz2
xen-0a0346fc3f81744534ea79fce2401675e2278356.zip
xenctx: Teach xenctx how to find the right addresses in real-mode.
Signed-off-by: George Dunlap <george.dunlap@eu.citrix.com>
Diffstat (limited to 'tools/xentrace')
-rw-r--r--tools/xentrace/xenctx.c38
1 files changed, 30 insertions, 8 deletions
diff --git a/tools/xentrace/xenctx.c b/tools/xentrace/xenctx.c
index 38edb3fb55..127379e671 100644
--- a/tools/xentrace/xenctx.c
+++ b/tools/xentrace/xenctx.c
@@ -42,6 +42,7 @@ typedef unsigned long long guest_word_t;
int guest_word_size = sizeof (unsigned long);
/* Word-length of the context record we get from xen */
int ctxt_word_size = sizeof (unsigned long);
+int guest_protected_mode = 1;
#elif defined (__ia64__)
/* On ia64, we can't translate virtual address to physical address. */
#define NO_TRANSLATION
@@ -206,6 +207,7 @@ static void read_symbol_table(const char *symtab)
}
#if defined(__i386__) || defined(__x86_64__)
+#define CR0_PE 0x1
char *flag_values[22][2] =
{/* clear, set, bit# */
{ NULL, "c" }, // 0 Carry
@@ -371,20 +373,38 @@ static void print_ctx(vcpu_guest_context_any_t *ctx)
print_ctx_64(&ctx->x64);
}
+#define NONPROT_MODE_SEGMENT_SHIFT 4
+
static guest_word_t instr_pointer(vcpu_guest_context_any_t *ctx)
{
- if (ctxt_word_size == 4)
- return ctx->x32.user_regs.eip;
+ guest_word_t r;
+ if (ctxt_word_size == 4)
+ {
+ r = ctx->x32.user_regs.eip;
+
+ if ( !guest_protected_mode )
+ r += ctx->x32.user_regs.cs << NONPROT_MODE_SEGMENT_SHIFT;
+ }
else
- return ctx->x64.user_regs.rip;
+ r = ctx->x64.user_regs.rip;
+
+ return r;
}
static guest_word_t stack_pointer(vcpu_guest_context_any_t *ctx)
{
- if (ctxt_word_size == 4)
- return ctx->x32.user_regs.esp;
+ guest_word_t r;
+ if (ctxt_word_size == 4)
+ {
+ r = ctx->x32.user_regs.esp;
+
+ if ( !guest_protected_mode )
+ r += ctx->x32.user_regs.ss << NONPROT_MODE_SEGMENT_SHIFT;
+ }
else
- return ctx->x64.user_regs.rsp;
+ r = ctx->x64.user_regs.rsp;
+
+ return r;
}
static guest_word_t frame_pointer(vcpu_guest_context_any_t *ctx)
@@ -688,8 +708,9 @@ static void print_code(vcpu_guest_context_any_t *ctx, int vcpu)
guest_word_t instr;
int i;
- printf("Code:\n");
- instr = instr_pointer(ctx) - 21;
+ instr = instr_pointer(ctx);
+ printf("Code (instr addr %08llx)\n", instr);
+ instr -= 21;
for(i=0; i<32; i++) {
unsigned char *c = map_page(ctx, vcpu, instr+i);
if (instr+i == instr_pointer(ctx))
@@ -835,6 +856,7 @@ static void dump_ctx(int vcpu)
exit(-1);
}
guest_word_size = (cpuctx.msr_efer & 0x400) ? 8 : 4;
+ guest_protected_mode = (cpuctx.cr0 & CR0_PE);
/* HVM guest context records are always host-sized */
if (xc_version(xc_handle, XENVER_capabilities, &xen_caps) != 0) {
perror("xc_version");