winedbg: Added some black magic to still handle register values on non
current frame for some of the registers we know of (frame pointer, stack pointer).
This commit is contained in:
parent
4c634078b3
commit
d6d8682d71
|
@ -29,6 +29,12 @@ static unsigned be_alpha_get_addr(HANDLE hThread, const CONTEXT* ctx,
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static unsigned be_alpha_get_register_info(int regno, enum be_cpu_addr* kind)
|
||||||
|
{
|
||||||
|
dbg_printf("not done\n");
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
static void be_alpha_single_step(CONTEXT* ctx, unsigned enable)
|
static void be_alpha_single_step(CONTEXT* ctx, unsigned enable)
|
||||||
{
|
{
|
||||||
dbg_printf("not done\n");
|
dbg_printf("not done\n");
|
||||||
|
@ -148,6 +154,7 @@ struct backend_cpu be_alpha =
|
||||||
be_cpu_linearize,
|
be_cpu_linearize,
|
||||||
be_cpu_build_addr,
|
be_cpu_build_addr,
|
||||||
be_alpha_get_addr,
|
be_alpha_get_addr,
|
||||||
|
be_alpha_get_register_info,
|
||||||
be_alpha_single_step,
|
be_alpha_single_step,
|
||||||
be_alpha_print_context,
|
be_alpha_print_context,
|
||||||
be_alpha_print_segment_info,
|
be_alpha_print_segment_info,
|
||||||
|
|
|
@ -43,6 +43,10 @@ struct backend_cpu
|
||||||
*/
|
*/
|
||||||
unsigned (*get_addr)(HANDLE hThread, const CONTEXT* ctx,
|
unsigned (*get_addr)(HANDLE hThread, const CONTEXT* ctx,
|
||||||
enum be_cpu_addr, ADDRESS64* addr);
|
enum be_cpu_addr, ADDRESS64* addr);
|
||||||
|
|
||||||
|
/* returns which kind of information a given register number refers to */
|
||||||
|
unsigned (*get_register_info)(int regno, enum be_cpu_addr* kind);
|
||||||
|
|
||||||
/* -------------------------------------------------------------------------------
|
/* -------------------------------------------------------------------------------
|
||||||
* context manipulation
|
* context manipulation
|
||||||
* ------------------------------------------------------------------------------- */
|
* ------------------------------------------------------------------------------- */
|
||||||
|
|
|
@ -111,6 +111,17 @@ static unsigned be_i386_get_addr(HANDLE hThread, const CONTEXT* ctx,
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static unsigned be_i386_get_register_info(int regno, enum be_cpu_addr* kind)
|
||||||
|
{
|
||||||
|
switch (regno)
|
||||||
|
{
|
||||||
|
case CV_REG_EIP: *kind = be_cpu_addr_pc; return TRUE;
|
||||||
|
case CV_REG_EBP: *kind = be_cpu_addr_frame; return TRUE;
|
||||||
|
case CV_REG_ESP: *kind = be_cpu_addr_stack; return TRUE;
|
||||||
|
}
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
static void be_i386_single_step(CONTEXT* ctx, unsigned enable)
|
static void be_i386_single_step(CONTEXT* ctx, unsigned enable)
|
||||||
{
|
{
|
||||||
if (enable) ctx->EFlags |= STEP_FLAG;
|
if (enable) ctx->EFlags |= STEP_FLAG;
|
||||||
|
@ -739,6 +750,7 @@ struct backend_cpu be_i386 =
|
||||||
be_i386_linearize,
|
be_i386_linearize,
|
||||||
be_i386_build_addr,
|
be_i386_build_addr,
|
||||||
be_i386_get_addr,
|
be_i386_get_addr,
|
||||||
|
be_i386_get_register_info,
|
||||||
be_i386_single_step,
|
be_i386_single_step,
|
||||||
be_i386_print_context,
|
be_i386_print_context,
|
||||||
be_i386_print_segment_info,
|
be_i386_print_segment_info,
|
||||||
|
|
|
@ -38,6 +38,12 @@ static unsigned be_ppc_get_addr(HANDLE hThread, const CONTEXT* ctx,
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static unsigned be_ppc_get_register_info(int regno, enum be_cpu_addr* kind)
|
||||||
|
{
|
||||||
|
dbg_printf("not done\n");
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
static void be_ppc_single_step(CONTEXT* ctx, unsigned enable)
|
static void be_ppc_single_step(CONTEXT* ctx, unsigned enable)
|
||||||
{
|
{
|
||||||
#ifndef MSR_SE
|
#ifndef MSR_SE
|
||||||
|
@ -172,6 +178,7 @@ struct backend_cpu be_ppc =
|
||||||
be_cpu_linearize,
|
be_cpu_linearize,
|
||||||
be_cpu_build_addr,
|
be_cpu_build_addr,
|
||||||
be_ppc_get_addr,
|
be_ppc_get_addr,
|
||||||
|
be_ppc_get_register_info,
|
||||||
be_ppc_single_step,
|
be_ppc_single_step,
|
||||||
be_ppc_print_context,
|
be_ppc_print_context,
|
||||||
be_ppc_print_segment_info,
|
be_ppc_print_segment_info,
|
||||||
|
|
|
@ -46,6 +46,18 @@ static unsigned be_x86_64_get_addr(HANDLE hThread, const CONTEXT* ctx,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static unsigned be_x86_64_get_register_info(int regno, enum be_cpu_addr* kind)
|
||||||
|
{
|
||||||
|
/* this is true when running in 32bit mode... and wrong in 64 :-/ */
|
||||||
|
switch (regno)
|
||||||
|
{
|
||||||
|
case CV_AMD64_EIP: *kind = be_cpu_addr_pc; return TRUE;
|
||||||
|
case CV_AMD64_EBP: *kind = be_cpu_addr_frame; return TRUE;
|
||||||
|
case CV_AMD64_ESP: *kind = be_cpu_addr_stack; return TRUE;
|
||||||
|
}
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
static void be_x86_64_single_step(CONTEXT* ctx, unsigned enable)
|
static void be_x86_64_single_step(CONTEXT* ctx, unsigned enable)
|
||||||
{
|
{
|
||||||
dbg_printf("not done single_step\n");
|
dbg_printf("not done single_step\n");
|
||||||
|
@ -210,6 +222,7 @@ struct backend_cpu be_x86_64 =
|
||||||
be_cpu_linearize,
|
be_cpu_linearize,
|
||||||
be_cpu_build_addr,
|
be_cpu_build_addr,
|
||||||
be_x86_64_get_addr,
|
be_x86_64_get_addr,
|
||||||
|
be_x86_64_get_register_info,
|
||||||
be_x86_64_single_step,
|
be_x86_64_single_step,
|
||||||
be_x86_64_print_context,
|
be_x86_64_print_context,
|
||||||
be_x86_64_print_segment_info,
|
be_x86_64_print_segment_info,
|
||||||
|
|
|
@ -176,6 +176,10 @@ struct dbg_thread
|
||||||
{
|
{
|
||||||
ADDRESS64 addr_pc;
|
ADDRESS64 addr_pc;
|
||||||
ADDRESS64 addr_frame;
|
ADDRESS64 addr_frame;
|
||||||
|
ADDRESS64 addr_stack;
|
||||||
|
DWORD linear_pc;
|
||||||
|
DWORD linear_frame;
|
||||||
|
DWORD linear_stack;
|
||||||
}* frames;
|
}* frames;
|
||||||
int num_frames;
|
int num_frames;
|
||||||
int curr_frame;
|
int curr_frame;
|
||||||
|
@ -361,6 +365,7 @@ extern void stack_info(void);
|
||||||
extern void stack_backtrace(DWORD threadID);
|
extern void stack_backtrace(DWORD threadID);
|
||||||
extern BOOL stack_set_frame(int newframe);
|
extern BOOL stack_set_frame(int newframe);
|
||||||
extern BOOL stack_get_current_frame(IMAGEHLP_STACK_FRAME* ihsf);
|
extern BOOL stack_get_current_frame(IMAGEHLP_STACK_FRAME* ihsf);
|
||||||
|
extern BOOL stack_get_register_current_frame(unsigned regno, DWORD** pval);
|
||||||
extern unsigned stack_fetch_frames(void);
|
extern unsigned stack_fetch_frames(void);
|
||||||
extern BOOL stack_get_current_symbol(SYMBOL_INFO* sym);
|
extern BOOL stack_get_current_symbol(SYMBOL_INFO* sym);
|
||||||
|
|
||||||
|
|
|
@ -636,16 +636,22 @@ BOOL memory_get_register(DWORD regno, DWORD** value, char* buffer, int len)
|
||||||
if (buffer) snprintf(buffer, len, "<couldn't read memory>");
|
if (buffer) snprintf(buffer, len, "<couldn't read memory>");
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
if (dbg_curr_thread->curr_frame != 0)
|
|
||||||
{
|
|
||||||
if (buffer) snprintf(buffer, len, "<register not in topmost frame>");
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
for (div = dbg_context_vars; div->name; div++)
|
for (div = dbg_context_vars; div->name; div++)
|
||||||
{
|
{
|
||||||
if (div->val == regno)
|
if (div->val == regno)
|
||||||
{
|
{
|
||||||
*value = div->pval;
|
if (dbg_curr_thread->curr_frame != 0)
|
||||||
|
{
|
||||||
|
if (!stack_get_register_current_frame(regno, value))
|
||||||
|
{
|
||||||
|
if (buffer) snprintf(buffer, len, "<register %s not in topmost frame>", div->name);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
*value = div->pval;
|
||||||
|
|
||||||
snprintf(buffer, len, div->name);
|
snprintf(buffer, len, div->name);
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
|
@ -82,8 +82,8 @@ static BOOL stack_set_frame_internal(int newframe)
|
||||||
static BOOL stack_get_frame(int nf, IMAGEHLP_STACK_FRAME* ihsf)
|
static BOOL stack_get_frame(int nf, IMAGEHLP_STACK_FRAME* ihsf)
|
||||||
{
|
{
|
||||||
memset(ihsf, 0, sizeof(*ihsf));
|
memset(ihsf, 0, sizeof(*ihsf));
|
||||||
ihsf->InstructionOffset = (unsigned long)memory_to_linear_addr(&dbg_curr_thread->frames[nf].addr_pc);
|
ihsf->InstructionOffset = dbg_curr_thread->frames[nf].linear_pc;
|
||||||
ihsf->FrameOffset = (unsigned long)memory_to_linear_addr(&dbg_curr_thread->frames[nf].addr_frame);
|
ihsf->FrameOffset = dbg_curr_thread->frames[nf].linear_frame;
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -96,6 +96,29 @@ BOOL stack_get_current_frame(IMAGEHLP_STACK_FRAME* ihsf)
|
||||||
return stack_get_frame(dbg_curr_thread->curr_frame, ihsf);
|
return stack_get_frame(dbg_curr_thread->curr_frame, ihsf);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BOOL stack_get_register_current_frame(unsigned regno, DWORD** pval)
|
||||||
|
{
|
||||||
|
enum be_cpu_addr kind;
|
||||||
|
|
||||||
|
if (dbg_curr_thread->frames == NULL) return FALSE;
|
||||||
|
|
||||||
|
if (!be_cpu->get_register_info(regno, &kind)) return FALSE;
|
||||||
|
|
||||||
|
switch (kind)
|
||||||
|
{
|
||||||
|
case be_cpu_addr_pc:
|
||||||
|
*pval = &dbg_curr_thread->frames[dbg_curr_thread->curr_frame].linear_pc;
|
||||||
|
break;
|
||||||
|
case be_cpu_addr_stack:
|
||||||
|
*pval = &dbg_curr_thread->frames[dbg_curr_thread->curr_frame].linear_stack;
|
||||||
|
break;
|
||||||
|
case be_cpu_addr_frame:
|
||||||
|
*pval = &dbg_curr_thread->frames[dbg_curr_thread->curr_frame].linear_frame;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
BOOL stack_set_frame(int newframe)
|
BOOL stack_set_frame(int newframe)
|
||||||
{
|
{
|
||||||
ADDRESS64 addr;
|
ADDRESS64 addr;
|
||||||
|
@ -170,8 +193,12 @@ unsigned stack_fetch_frames(void)
|
||||||
dbg_curr_thread->frames = dbg_heap_realloc(dbg_curr_thread->frames,
|
dbg_curr_thread->frames = dbg_heap_realloc(dbg_curr_thread->frames,
|
||||||
(nf + 1) * sizeof(dbg_curr_thread->frames[0]));
|
(nf + 1) * sizeof(dbg_curr_thread->frames[0]));
|
||||||
|
|
||||||
dbg_curr_thread->frames[nf].addr_pc = sf.AddrPC;
|
dbg_curr_thread->frames[nf].addr_pc = sf.AddrPC;
|
||||||
dbg_curr_thread->frames[nf].addr_frame = sf.AddrFrame;
|
dbg_curr_thread->frames[nf].linear_pc = (DWORD)memory_to_linear_addr(&sf.AddrPC);
|
||||||
|
dbg_curr_thread->frames[nf].addr_frame = sf.AddrFrame;
|
||||||
|
dbg_curr_thread->frames[nf].linear_frame = (DWORD)memory_to_linear_addr(&sf.AddrFrame);
|
||||||
|
dbg_curr_thread->frames[nf].addr_stack = sf.AddrStack;
|
||||||
|
dbg_curr_thread->frames[nf].linear_stack = (DWORD)memory_to_linear_addr(&sf.AddrStack);
|
||||||
nf++;
|
nf++;
|
||||||
/* we've probably gotten ourselves into an infinite loop so bail */
|
/* we've probably gotten ourselves into an infinite loop so bail */
|
||||||
if (nf > 200) break;
|
if (nf > 200) break;
|
||||||
|
|
Loading…
Reference in New Issue