dbghelp: Allow each CPU backend to save CPU specific memory ranges in minidump.

Used this feature to add x86_64 unwind information.
This commit is contained in:
Eric Pouech 2012-01-23 21:37:16 +01:00 committed by Alexandre Julliard
parent 1c5450f91f
commit a672a51cbf
7 changed files with 81 additions and 2 deletions

View File

@ -228,6 +228,12 @@ static BOOL arm_fetch_minidump_thread(struct dump_context* dc, unsigned index, u
return FALSE;
}
static BOOL arm_fetch_minidump_module(struct dump_context* dc, unsigned index, unsigned flags)
{
FIXME("NIY\n");
return FALSE;
}
DECLSPEC_HIDDEN struct cpu cpu_arm = {
IMAGE_FILE_MACHINE_ARMV7,
4,
@ -239,4 +245,5 @@ DECLSPEC_HIDDEN struct cpu cpu_arm = {
arm_fetch_context_reg,
arm_fetch_regname,
arm_fetch_minidump_thread,
arm_fetch_minidump_module,
};

View File

@ -673,6 +673,14 @@ static BOOL i386_fetch_minidump_thread(struct dump_context* dc, unsigned index,
return TRUE;
}
static BOOL i386_fetch_minidump_module(struct dump_context* dc, unsigned index, unsigned flags)
{
/* FIXME: actually, we should probably take care of FPO data, unless it's stored in
* function table minidump stream
*/
return FALSE;
}
DECLSPEC_HIDDEN struct cpu cpu_i386 = {
IMAGE_FILE_MACHINE_I386,
4,
@ -684,4 +692,5 @@ DECLSPEC_HIDDEN struct cpu cpu_i386 = {
i386_fetch_context_reg,
i386_fetch_regname,
i386_fetch_minidump_thread,
i386_fetch_minidump_module,
};

View File

@ -78,6 +78,12 @@ static BOOL ppc_fetch_minidump_thread(struct dump_context* dc, unsigned index, u
return FALSE;
}
static BOOL ppc_fetch_minidump_module(struct dump_context* dc, unsigned index, unsigned flags)
{
FIXME("NIY\n");
return FALSE;
}
DECLSPEC_HIDDEN struct cpu cpu_ppc = {
IMAGE_FILE_MACHINE_POWERPC,
4,
@ -89,4 +95,5 @@ DECLSPEC_HIDDEN struct cpu cpu_ppc = {
ppc_fetch_context_reg,
ppc_fetch_regname,
ppc_fetch_minidump_thread,
ppc_fetch_minidump_module,
};

View File

@ -85,6 +85,12 @@ static BOOL sparc_fetch_minidump_thread(struct dump_context* dc, unsigned index,
return FALSE;
}
static BOOL sparc_fetch_minidump_module(struct dump_context* dc, unsigned index, unsigned flags)
{
FIXME("NIY\n");
return FALSE;
}
DECLSPEC_HIDDEN struct cpu cpu_sparc = {
IMAGE_FILE_MACHINE_SPARC,
4,
@ -96,4 +102,5 @@ DECLSPEC_HIDDEN struct cpu cpu_sparc = {
sparc_fetch_context_reg,
sparc_fetch_regname,
sparc_fetch_minidump_thread,
sparc_fetch_minidump_module,
};

View File

@ -145,7 +145,7 @@ static void dump_unwind_info(struct cpu_stack_walk* csw, ULONG64 base, RUNTIME_F
{
if (!sw_read_mem(csw, base + function->UnwindData, &snext, sizeof(snext)))
{
TRACE("Couldn't unwind RUNTIME_INFO\n");
TRACE("Couldn't unwind RUNTIME_INFO at %lx\n", base + function->UnwindData);
return;
}
TRACE("unwind info for function %p-%p chained to function %p-%p\n",
@ -159,7 +159,7 @@ static void dump_unwind_info(struct cpu_stack_walk* csw, ULONG64 base, RUNTIME_F
!sw_read_mem(csw, addr + FIELD_OFFSET(UNWIND_INFO, UnwindCode),
info->UnwindCode, info->CountOfCodes * sizeof(UNWIND_CODE)))
{
FIXME("couldn't read memory for UNWIND_INFO\n");
FIXME("couldn't read memory for UNWIND_INFO at %lx\n", addr);
return;
}
TRACE("unwind info at %p flags %x prolog 0x%x bytes function %p-%p\n",
@ -904,6 +904,50 @@ static BOOL x86_64_fetch_minidump_thread(struct dump_context* dc, unsigned index
return TRUE;
}
static BOOL x86_64_fetch_minidump_module(struct dump_context* dc, unsigned index, unsigned flags)
{
/* FIXME: not sure about the flags... */
if (1)
{
/* FIXME: crop values across module boundaries, */
#ifdef __x86_64__
struct process* pcs;
struct module* module;
const RUNTIME_FUNCTION* rtf;
ULONG size;
if (!(pcs = process_find_by_handle(dc->hProcess)) ||
!(module = module_find_by_addr(pcs, dc->modules[index].base, DMT_UNKNOWN)))
return FALSE;
rtf = (const RUNTIME_FUNCTION*)pe_map_directory(module, IMAGE_DIRECTORY_ENTRY_EXCEPTION, &size);
if (rtf)
{
const RUNTIME_FUNCTION* end = (const RUNTIME_FUNCTION*)((const char*)rtf + size);
UNWIND_INFO ui;
while (rtf + 1 < end)
{
while (rtf->UnwindData & 1) /* follow chained entry */
{
FIXME("RunTime_Function outside IMAGE_DIRECTORY_ENTRY_EXCEPTION unimplemented yet!\n");
return FALSE;
/* we need to read into the other process */
/* rtf = (RUNTIME_FUNCTION*)(module->module.BaseOfImage + (rtf->UnwindData & ~1)); */
}
if (ReadProcessMemory(dc->hProcess,
(void*)(dc->modules[index].base + rtf->UnwindData),
&ui, sizeof(ui), NULL))
minidump_add_memory_block(dc, dc->modules[index].base + rtf->UnwindData,
FIELD_OFFSET(UNWIND_INFO, UnwindCode) + ui.CountOfCodes * sizeof(UNWIND_CODE), 0);
rtf++;
}
}
#endif
}
return TRUE;
}
DECLSPEC_HIDDEN struct cpu cpu_x86_64 = {
IMAGE_FILE_MACHINE_AMD64,
8,
@ -915,4 +959,5 @@ DECLSPEC_HIDDEN struct cpu cpu_x86_64 = {
x86_64_fetch_context_reg,
x86_64_fetch_regname,
x86_64_fetch_minidump_thread,
x86_64_fetch_minidump_module,
};

View File

@ -538,6 +538,7 @@ struct cpu
/* minidump per CPU extension */
BOOL (*fetch_minidump_thread)(struct dump_context* dc, unsigned index, unsigned flags, const CONTEXT* ctx);
BOOL (*fetch_minidump_module)(struct dump_context* dc, unsigned index, unsigned flags);
};
extern struct cpu* dbghelp_current_cpu DECLSPEC_HIDDEN;

View File

@ -513,6 +513,9 @@ static unsigned dump_modules(struct dump_context* dc, BOOL dump_elf)
}
if (flags_out & ModuleWriteModule)
{
/* fetch CPU dependant module info (like UNWIND_INFO) */
dbghelp_current_cpu->fetch_minidump_module(dc, i, flags_out);
mdModule.BaseOfImage = dc->modules[i].base;
mdModule.SizeOfImage = dc->modules[i].size;
mdModule.CheckSum = dc->modules[i].checksum;