Commit 09941267 authored by Jeff Latimer's avatar Jeff Latimer Committed by Alexandre Julliard

winedbg: Add display for floating point status.

Added code to examine and display floating point unit status into be_i386.c as info all-regs command.
parent ef4440ad
......@@ -34,7 +34,7 @@ static void be_alpha_single_step(CONTEXT* ctx, unsigned enable)
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");
}
......
......@@ -49,7 +49,7 @@ struct backend_cpu
/* 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
*/
......
......@@ -116,7 +116,74 @@ static void be_i386_single_step(CONTEXT* ctx, unsigned enable)
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;
......@@ -173,6 +240,9 @@ static void be_i386_print_context(HANDLE hThread, const CONTEXT* ctx)
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)
......
......@@ -47,7 +47,7 @@ static void be_ppc_single_step(CONTEXT* ctx, unsigned enable)
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");
}
......
......@@ -52,7 +52,7 @@ int yyerror(const char*);
%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
......@@ -256,7 +256,8 @@ info_command:
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(); }
......
......@@ -189,6 +189,8 @@ STRING \"[^\n"]+\"
<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; }
......
......@@ -101,7 +101,8 @@ void info_help(void)
" 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",
......
......@@ -171,7 +171,7 @@ static unsigned dbg_exception_prolog(BOOL is_debug, const EXCEPTION_RECORD* rec)
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);
......
......@@ -348,7 +348,7 @@ static enum dbg_start minidump_do_reload(struct tgt_process_minidump_data* data)
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);
......
......@@ -348,6 +348,8 @@ Lists all the dynamic libraries loaded in the debugged program
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
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment