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:
parent
1c5450f91f
commit
a672a51cbf
|
@ -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,
|
||||
};
|
||||
|
|
|
@ -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,
|
||||
};
|
||||
|
|
|
@ -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,
|
||||
};
|
||||
|
|
|
@ -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,
|
||||
};
|
||||
|
|
|
@ -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,
|
||||
};
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue