Commit 7c2a5e18 authored by Eric Pouech's avatar Eric Pouech Committed by Alexandre Julliard

dbghelp: In x86-64 support code, fix RUNTIME_FUNCTION dumping.

parent 2ed88d7a
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* File cpu_x86_64.c * File cpu_x86_64.c
* *
* Copyright (C) 1999, 2005 Alexandre Julliard * Copyright (C) 1999, 2005 Alexandre Julliard
* Copyright (C) 2009 Eric Pouech. * Copyright (C) 2009, 2011 Eric Pouech.
* *
* This library is free software; you can redistribute it and/or * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public * modify it under the terms of the GNU Lesser General Public
...@@ -125,39 +125,45 @@ union handler_data ...@@ -125,39 +125,45 @@ union handler_data
ULONG handler; ULONG handler;
}; };
static void dump_unwind_info(HANDLE hProcess, ULONG64 base, RUNTIME_FUNCTION *function) static void dump_unwind_info(struct cpu_stack_walk* csw, ULONG64 base, RUNTIME_FUNCTION *function)
{ {
static const char * const reg_names[16] = static const char * const reg_names[16] =
{ "rax", "rcx", "rdx", "rbx", "rsp", "rbp", "rsi", "rdi", { "rax", "rcx", "rdx", "rbx", "rsp", "rbp", "rsi", "rdi",
"r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15" }; "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15" };
union handler_data *handler_data; union handler_data handler_data;
char buffer[sizeof(UNWIND_INFO) + 256 * sizeof(UNWIND_CODE)]; char buffer[sizeof(UNWIND_INFO) + 256 * sizeof(UNWIND_CODE)];
UNWIND_INFO* info = (UNWIND_INFO*)buffer; UNWIND_INFO* info = (UNWIND_INFO*)buffer;
unsigned int i, count; unsigned int i, count;
SIZE_T r; RUNTIME_FUNCTION snext;
ULONG64 addr;
TRACE("**** func %x-%x\n", function->BeginAddress, function->EndAddress); TRACE("**** func %x-%x\n", function->BeginAddress, function->EndAddress);
for (;;) for (;;)
{ {
if (function->UnwindData & 1) if (function->UnwindData & 1)
{ {
#if 0 if (!sw_read_mem(csw, base + function->UnwindData, &snext, sizeof(snext)))
RUNTIME_FUNCTION *next = (RUNTIME_FUNCTION*)((char*)base + (function->UnwindData & ~1)); {
TRACE("Couldn't unwind RUNTIME_INFO\n");
return;
}
TRACE("unwind info for function %p-%p chained to function %p-%p\n", TRACE("unwind info for function %p-%p chained to function %p-%p\n",
(char*)base + function->BeginAddress, (char*)base + function->EndAddress, (char*)base + function->BeginAddress, (char*)base + function->EndAddress,
(char*)base + next->BeginAddress, (char*)base + next->EndAddress); (char*)base + snext.BeginAddress, (char*)base + snext.EndAddress);
function = next; function = &snext;
continue; continue;
#else
FIXME("NOT SUPPORTED\n");
#endif
} }
ReadProcessMemory(hProcess, (char*)base + function->UnwindData, info, sizeof(*info), &r); addr = base + function->UnwindData;
ReadProcessMemory(hProcess, (char*)base + function->UnwindData + FIELD_OFFSET(UNWIND_INFO, UnwindCode), if (!sw_read_mem(csw, addr, info, FIELD_OFFSET(UNWIND_INFO, UnwindCode)) ||
info->UnwindCode, 256 * sizeof(UNWIND_CODE), &r); !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");
return;
}
TRACE("unwind info at %p flags %x prolog 0x%x bytes function %p-%p\n", TRACE("unwind info at %p flags %x prolog 0x%x bytes function %p-%p\n",
info, info->Flags, info->SizeOfProlog, (char*)addr, info->Flags, info->SizeOfProlog,
(char*)base + function->BeginAddress, (char*)base + function->EndAddress); (char*)base + function->BeginAddress, (char*)base + function->EndAddress);
if (info->FrameRegister) if (info->FrameRegister)
...@@ -222,18 +228,31 @@ static void dump_unwind_info(HANDLE hProcess, ULONG64 base, RUNTIME_FUNCTION *fu ...@@ -222,18 +228,31 @@ static void dump_unwind_info(HANDLE hProcess, ULONG64 base, RUNTIME_FUNCTION *fu
} }
} }
handler_data = (union handler_data*)&info->UnwindCode[(info->CountOfCodes + 1) & ~1]; addr += FIELD_OFFSET(UNWIND_INFO, UnwindCode) +
((info->CountOfCodes + 1) & ~1) * sizeof(UNWIND_CODE);
if (info->Flags & UNW_FLAG_CHAININFO) if (info->Flags & UNW_FLAG_CHAININFO)
{ {
if (!sw_read_mem(csw, addr, &handler_data, sizeof(handler_data.chain)))
{
FIXME("couldn't read memory for handler_data.chain\n");
return;
}
TRACE(" chained to function %p-%p\n", TRACE(" chained to function %p-%p\n",
(char*)base + handler_data->chain.BeginAddress, (char*)base + handler_data.chain.BeginAddress,
(char*)base + handler_data->chain.EndAddress); (char*)base + handler_data.chain.EndAddress);
function = &handler_data->chain; function = &handler_data.chain;
continue; continue;
} }
if (info->Flags & (UNW_FLAG_EHANDLER | UNW_FLAG_UHANDLER)) if (info->Flags & (UNW_FLAG_EHANDLER | UNW_FLAG_UHANDLER))
{
if (!sw_read_mem(csw, addr, &handler_data, sizeof(handler_data.handler)))
{
FIXME("couldn't read memory for handler_data.handler\n");
return;
}
TRACE(" handler %p data at %p\n", TRACE(" handler %p data at %p\n",
(char*)base + handler_data->handler, &handler_data->handler + 1); (char*)base + handler_data.handler, (char*)addr + sizeof(handler_data.handler));
}
break; break;
} }
} }
...@@ -448,7 +467,7 @@ static BOOL interpret_function_table_entry(struct cpu_stack_walk* csw, ...@@ -448,7 +467,7 @@ static BOOL interpret_function_table_entry(struct cpu_stack_walk* csw,
/* FIXME: we have some assumptions here */ /* FIXME: we have some assumptions here */
assert(context); assert(context);
dump_unwind_info(csw->hProcess, sw_module_base(csw, context->Rip), function); dump_unwind_info(csw, sw_module_base(csw, context->Rip), function);
newframe = context->Rsp; newframe = context->Rsp;
for (;;) for (;;)
{ {
......
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