dbg_printf("not done\n");
}
-static void be_alpha_print_context(HANDLE hThread, const CONTEXT* ctx)
+static void be_alpha_print_context(HANDLE hThread, const CONTEXT* ctx, int all_regs)
{
dbg_printf("Context printing for Alpha not done yet\n");
}
/* Enables/disables CPU single step mode (depending on enable) */
void (*single_step)(CONTEXT* ctx, unsigned enable);
/* Dumps out the content of the context */
- void (*print_context)(HANDLE hThread, const CONTEXT* ctx);
+ void (*print_context)(HANDLE hThread, const CONTEXT* ctx, int all_regs);
/* Prints information about segments. Non segmented CPU should leave this
* function empty
*/
else ctx->EFlags &= ~STEP_FLAG;
}
-static void be_i386_print_context(HANDLE hThread, const CONTEXT* ctx)
+static void be_i386_all_print_context(HANDLE hThread, const CONTEXT* ctx)
+{
+ long double ST[8]; /* These are for floating regs */
+ int cnt;
+
+ /* Break out the FPU state and the floating point registers */
+ dbg_printf("Floating Point Unit status:\n");
+ dbg_printf(" FLCW:%04x ", LOWORD(ctx->FloatSave.ControlWord));
+ dbg_printf(" FLTW:%04x ", LOWORD(ctx->FloatSave.TagWord));
+ dbg_printf(" FLEO:%08x ", (unsigned int) ctx->FloatSave.ErrorOffset);
+ dbg_printf(" FLSW:%04x", LOWORD(ctx->FloatSave.StatusWord));
+
+ /* Isolate the condition code bits - note they are not contiguous */
+ dbg_printf("(CC:%ld%ld%ld%ld", (ctx->FloatSave.StatusWord & 0x00004000) >> 14,
+ (ctx->FloatSave.StatusWord & 0x00000400) >> 10,
+ (ctx->FloatSave.StatusWord & 0x00000200) >> 9,
+ (ctx->FloatSave.StatusWord & 0x00000100) >> 8);
+
+ /* Now pull out hte 3 bit of the TOP stack pointer */
+ dbg_printf(" TOP:%01x", (unsigned int) (ctx->FloatSave.StatusWord & 0x00003800) >> 11);
+
+ /* Lets analyse the error bits and indicate the status
+ * the Invalid Op flag has sub status which is tested as follows */
+ if (ctx->FloatSave.StatusWord & 0x00000001) { /* Invalid Fl OP */
+ if (ctx->FloatSave.StatusWord & 0x00000040) { /* Stack Fault */
+ if (ctx->FloatSave.StatusWord & 0x00000200) /* C1 says Overflow */
+ dbg_printf(" #IE(Stack Overflow)");
+ else
+ dbg_printf(" #IE(Stack Underflow)"); /* Underflow */
+ }
+ else dbg_printf(" #IE(Arthimetic error)"); /* Invalid Fl OP */
+ }
+
+ if (ctx->FloatSave.StatusWord & 0x00000002) dbg_printf(" #DE"); /* Denormalised OP */
+ if (ctx->FloatSave.StatusWord & 0x00000004) dbg_printf(" #ZE"); /* Zero Divide */
+ if (ctx->FloatSave.StatusWord & 0x00000008) dbg_printf(" #OE"); /* Overflow */
+ if (ctx->FloatSave.StatusWord & 0x00000010) dbg_printf(" #UE"); /* Underflow */
+ if (ctx->FloatSave.StatusWord & 0x00000020) dbg_printf(" #PE"); /* Precision error */
+ if (ctx->FloatSave.StatusWord & 0x00000040)
+ if (!(ctx->FloatSave.StatusWord & 0x00000001))
+ dbg_printf(" #SE"); /* Stack Fault (don't think this can occur) */
+ if (ctx->FloatSave.StatusWord & 0x00000080) dbg_printf(" #ES"); /* Error Summary */
+ if (ctx->FloatSave.StatusWord & 0x00008000) dbg_printf(" #FB"); /* FPU Busy */
+ dbg_printf(")\n");
+
+ /* Here are the rest of the registers */
+ dbg_printf(" FLES:%08x ", (unsigned int) ctx->FloatSave.ErrorSelector);
+ dbg_printf(" FLDO:%08x ", (unsigned int) ctx->FloatSave.DataOffset);
+ dbg_printf(" FLDS:%08x ", (unsigned int) ctx->FloatSave.DataSelector);
+ dbg_printf(" FLCNS:%08x \n", (unsigned int) ctx->FloatSave.Cr0NpxState);
+
+ /* Now for the floating point registers */
+ dbg_printf("Floating Point Registers:\n");
+ for (cnt = 0; cnt < 4; cnt++)
+ {
+ memcpy(&ST[cnt], &ctx->FloatSave.RegisterArea[cnt * 10], 10);
+ dbg_printf(" ST%d:%Lf ", cnt, ST[cnt]);
+ }
+ dbg_printf("\n");
+ for (cnt = 4; cnt < 8; cnt++)
+ {
+ memcpy(&ST[cnt], &ctx->FloatSave.RegisterArea[cnt * 10], 10);
+ dbg_printf(" ST%d:%Lf ", cnt, ST[cnt]);
+ }
+ dbg_printf("\n");
+}
+
+static void be_i386_print_context(HANDLE hThread, const CONTEXT* ctx, int all_regs)
{
char buf[33];
char* pt;
ctx->Esi, ctx->Edi);
break;
}
+
+ if (all_regs) be_i386_all_print_context(hThread, ctx); /* print floating regs */
+
}
static void be_i386_print_segment_info(HANDLE hThread, const CONTEXT* ctx)
else ctx->Msr &= ~MSR_SE;
}
-static void be_ppc_print_context(HANDLE hThread, const CONTEXT* ctx)
+static void be_ppc_print_context(HANDLE hThread, const CONTEXT* ctx, int all_regs)
{
dbg_printf("Context printing for PPC not done yet\n");
}
%token tCONT tPASS tSTEP tLIST tNEXT tQUIT tHELP tBACKTRACE tALL tINFO tUP tDOWN
%token tENABLE tDISABLE tBREAK tHBREAK tWATCH tDELETE tSET tMODE tPRINT tEXAM
%token tABORT tVM86 tECHO
-%token tCLASS tMAPS tSTACK tSEGMENTS tSYMBOL tREGS tWND tQUEUE tLOCAL tEXCEPTION
+%token tCLASS tMAPS tSTACK tSEGMENTS tSYMBOL tREGS tALLREGS tWND tQUEUE tLOCAL tEXCEPTION
%token tPROCESS tTHREAD tMODREF tEOL tEOF
%token tFRAME tSHARE tCOND tDISPLAY tUNDISPLAY tDISASSEMBLE
%token tSTEPI tNEXTI tFINISH tSHOW tDIR tWHATIS tSOURCE
tINFO tBREAK { break_info(); }
| tINFO tSHARE { info_win32_module(0); }
| tINFO tSHARE expr_rvalue { info_win32_module($3); }
- | tINFO tREGS { be_cpu->print_context(dbg_curr_thread->handle, &dbg_context); }
+ | tINFO tREGS { be_cpu->print_context(dbg_curr_thread->handle, &dbg_context, 0); }
+ | tINFO tALLREGS { be_cpu->print_context(dbg_curr_thread->handle, &dbg_context, 1); }
| tINFO tSEGMENTS expr_rvalue { info_win32_segments($3 >> 3, 1); }
| tINFO tSEGMENTS { info_win32_segments(0, -1); }
| tINFO tSTACK { stack_info(); }
<INFO_CMD>threads|thread|threa|thre|thr|th { return tTHREAD; }
<INFO_CMD>exception|except|exc|ex { return tEXCEPTION; }
<INFO_CMD>registers|regs|reg|re { return tREGS; }
+<INFO_CMD>allregs|allreg|allre { return tALLREGS; }
+<INFO_CMD>"all-registers"|"all-regs"|"all-reg"|"all-re" { return tALLREGS; }
<INFO_CMD>segments|segment|segm|seg|se { return tSEGMENTS; }
<INFO_CMD>stack|stac|sta|st { return tSTACK; }
<INFO_CMD>symbol|symbo|symb|sym { BEGIN(ASTRING_EXPECTED); return tSYMBOL; }
" info locals Displays values of all local vars for current frame",
" info maps <pid> Shows virtual mappings (in a given process)",
" info process Shows all running processes",
- " info reg Displays values in all registers at top of stack",
+ " info reg Displays values of the general registers at top of stack",
+ " info all-reg Displays the general and floating point registers",
" info segments <pid> Displays information about all known segments",
" info share Displays all loaded modules",
" info share <addr> Displays internal module state",
if (!is_debug)
{
/* This is a real crash, dump some info */
- be_cpu->print_context(dbg_curr_thread->handle, &dbg_context);
+ be_cpu->print_context(dbg_curr_thread->handle, &dbg_context, 0);
stack_info();
be_cpu->print_segment_info(dbg_curr_thread->handle, &dbg_context);
stack_backtrace(dbg_curr_tid);
min(sizeof(dbg_context), mes->ThreadContext.DataSize));
memory_get_current_pc(&addr);
stack_fetch_frames();
- be_cpu->print_context(dbg_curr_thread->handle, &dbg_context);
+ be_cpu->print_context(dbg_curr_thread->handle, &dbg_context, 0);
stack_info();
be_cpu->print_segment_info(dbg_curr_thread->handle, &dbg_context);
stack_backtrace(mes->ThreadId);
Prints information on module at address \fBN\fR
.IP \fBinfo\ regs\fR
Prints the value of the CPU registers
+.IP \fBinfo\ all-regs\fR
+Prints the value of the CPU and Floating Point registers
.IP \fBinfo\ segment\fR
Lists all allocated segments (i386 only)
.IP \fBinfo\ segment\ N\fR