forked from Mirrors/wine-wine
dbghelp: StackWalk (32 and 64 bit version).
- enhance implementation of StackWalk (32 and 64 bit version) by making use of module information and calling for FPO - FPO part is still non functional - implemented SymGetModuleBase64 - stubbed SymFunctionTableAccess64oldstable
parent
5070268711
commit
558130a696
|
@ -43,7 +43,7 @@
|
||||||
@ stdcall SymFromAddr(ptr double ptr ptr)
|
@ stdcall SymFromAddr(ptr double ptr ptr)
|
||||||
@ stdcall SymFromName(long str ptr)
|
@ stdcall SymFromName(long str ptr)
|
||||||
@ stub SymFromToken
|
@ stub SymFromToken
|
||||||
@ stub SymFunctionTableAccess64
|
@ stdcall SymFunctionTableAccess64(long double)
|
||||||
@ stdcall SymFunctionTableAccess(long long)
|
@ stdcall SymFunctionTableAccess(long long)
|
||||||
@ stub SymGetFileLineOffsets64
|
@ stub SymGetFileLineOffsets64
|
||||||
@ stub SymGetHomeDirectory
|
@ stub SymGetHomeDirectory
|
||||||
|
@ -55,7 +55,7 @@
|
||||||
@ stdcall SymGetLineNext(long ptr)
|
@ stdcall SymGetLineNext(long ptr)
|
||||||
@ stdcall SymGetLinePrev64(long ptr)
|
@ stdcall SymGetLinePrev64(long ptr)
|
||||||
@ stdcall SymGetLinePrev(long ptr)
|
@ stdcall SymGetLinePrev(long ptr)
|
||||||
@ stub SymGetModuleBase64
|
@ stdcall SymGetModuleBase64(long double)
|
||||||
@ stdcall SymGetModuleBase(long long)
|
@ stdcall SymGetModuleBase(long long)
|
||||||
@ stdcall SymGetModuleInfo64(long double ptr)
|
@ stdcall SymGetModuleInfo64(long double ptr)
|
||||||
@ stdcall SymGetModuleInfo(long long ptr)
|
@ stdcall SymGetModuleInfo(long long ptr)
|
||||||
|
|
|
@ -642,7 +642,7 @@ BOOL WINAPI SymGetModuleInfo64(HANDLE hProcess, DWORD64 dwAddr,
|
||||||
}
|
}
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
* SymGetModuleBase (IMAGEHLP.@)
|
* SymGetModuleBase (DBGHELP.@)
|
||||||
*/
|
*/
|
||||||
DWORD WINAPI SymGetModuleBase(HANDLE hProcess, DWORD dwAddr)
|
DWORD WINAPI SymGetModuleBase(HANDLE hProcess, DWORD dwAddr)
|
||||||
{
|
{
|
||||||
|
@ -655,6 +655,15 @@ DWORD WINAPI SymGetModuleBase(HANDLE hProcess, DWORD dwAddr)
|
||||||
return module->module.BaseOfImage;
|
return module->module.BaseOfImage;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/***********************************************************************
|
||||||
|
* SymGetModuleBase64 (DBGHELP.@)
|
||||||
|
*/
|
||||||
|
DWORD64 WINAPI SymGetModuleBase64(HANDLE hProcess, DWORD64 dwAddr)
|
||||||
|
{
|
||||||
|
if (!validate_addr64(dwAddr)) return 0;
|
||||||
|
return SymGetModuleBase(hProcess, (DWORD)dwAddr);
|
||||||
|
}
|
||||||
|
|
||||||
/******************************************************************
|
/******************************************************************
|
||||||
* module_reset_debug_info
|
* module_reset_debug_info
|
||||||
* Removes any debug information linked to a given module.
|
* Removes any debug information linked to a given module.
|
||||||
|
|
|
@ -89,11 +89,15 @@ struct stack_walk_callback
|
||||||
{
|
{
|
||||||
PREAD_PROCESS_MEMORY_ROUTINE f_read_mem;
|
PREAD_PROCESS_MEMORY_ROUTINE f_read_mem;
|
||||||
PTRANSLATE_ADDRESS_ROUTINE f_xlat_adr;
|
PTRANSLATE_ADDRESS_ROUTINE f_xlat_adr;
|
||||||
|
PFUNCTION_TABLE_ACCESS_ROUTINE f_tabl_acs;
|
||||||
|
PGET_MODULE_BASE_ROUTINE f_modl_bas;
|
||||||
} s32;
|
} s32;
|
||||||
struct
|
struct
|
||||||
{
|
{
|
||||||
PREAD_PROCESS_MEMORY_ROUTINE64 f_read_mem;
|
PREAD_PROCESS_MEMORY_ROUTINE64 f_read_mem;
|
||||||
PTRANSLATE_ADDRESS_ROUTINE64 f_xlat_adr;
|
PTRANSLATE_ADDRESS_ROUTINE64 f_xlat_adr;
|
||||||
|
PFUNCTION_TABLE_ACCESS_ROUTINE64 f_tabl_acs;
|
||||||
|
PGET_MODULE_BASE_ROUTINE64 f_modl_bas;
|
||||||
} s64;
|
} s64;
|
||||||
} u;
|
} u;
|
||||||
};
|
};
|
||||||
|
@ -122,19 +126,34 @@ static inline BOOL sw_read_mem(struct stack_walk_callback* cb, DWORD addr, void*
|
||||||
|
|
||||||
static inline DWORD sw_xlat_addr(struct stack_walk_callback* cb, ADDRESS* addr)
|
static inline DWORD sw_xlat_addr(struct stack_walk_callback* cb, ADDRESS* addr)
|
||||||
{
|
{
|
||||||
if (cb->is32)
|
if (addr->Mode == AddrModeFlat) return addr->Offset;
|
||||||
return cb->u.s32.f_xlat_adr(cb->hProcess, cb->hThread, addr);
|
if (cb->is32) return cb->u.s32.f_xlat_adr(cb->hProcess, cb->hThread, addr);
|
||||||
else if (cb->u.s64.f_xlat_adr)
|
if (cb->u.s64.f_xlat_adr)
|
||||||
{
|
{
|
||||||
ADDRESS64 addr64;
|
ADDRESS64 addr64;
|
||||||
|
|
||||||
addr_32to64(addr, &addr64);
|
addr_32to64(addr, &addr64);
|
||||||
return cb->u.s64.f_xlat_adr(cb->hProcess, cb->hThread, &addr64);
|
return cb->u.s64.f_xlat_adr(cb->hProcess, cb->hThread, &addr64);
|
||||||
}
|
}
|
||||||
else
|
|
||||||
return addr_to_linear(cb->hProcess, cb->hThread, addr);
|
return addr_to_linear(cb->hProcess, cb->hThread, addr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline void* sw_tabl_acs(struct stack_walk_callback* cb, DWORD addr)
|
||||||
|
{
|
||||||
|
if (cb->is32)
|
||||||
|
return cb->u.s32.f_tabl_acs(cb->hProcess, addr);
|
||||||
|
else
|
||||||
|
return cb->u.s64.f_tabl_acs(cb->hProcess, addr);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline DWORD sw_modl_bas(struct stack_walk_callback* cb, DWORD addr)
|
||||||
|
{
|
||||||
|
if (cb->is32)
|
||||||
|
return cb->u.s32.f_modl_bas(cb->hProcess, addr);
|
||||||
|
else
|
||||||
|
return cb->u.s64.f_modl_bas(cb->hProcess, addr);
|
||||||
|
}
|
||||||
|
|
||||||
static BOOL stack_walk(struct stack_walk_callback* cb, LPSTACKFRAME frame)
|
static BOOL stack_walk(struct stack_walk_callback* cb, LPSTACKFRAME frame)
|
||||||
{
|
{
|
||||||
STACK32FRAME frame32;
|
STACK32FRAME frame32;
|
||||||
|
@ -223,6 +242,7 @@ static BOOL stack_walk(struct stack_walk_callback* cb, LPSTACKFRAME frame)
|
||||||
/* don't set up AddrStack on first call. Either the caller has set it up, or
|
/* don't set up AddrStack on first call. Either the caller has set it up, or
|
||||||
* we will get it in the next frame
|
* we will get it in the next frame
|
||||||
*/
|
*/
|
||||||
|
memset(&frame->AddrBStore, 0, sizeof(frame->AddrBStore));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -414,16 +434,21 @@ static BOOL stack_walk(struct stack_walk_callback* cb, LPSTACKFRAME frame)
|
||||||
frame->Params, sizeof(frame->Params));
|
frame->Params, sizeof(frame->Params));
|
||||||
}
|
}
|
||||||
|
|
||||||
frame->Far = FALSE;
|
frame->Far = TRUE;
|
||||||
frame->Virtual = FALSE;
|
frame->Virtual = TRUE;
|
||||||
|
p = sw_xlat_addr(cb, &frame->AddrPC);
|
||||||
|
if (p && sw_modl_bas(cb, p))
|
||||||
|
frame->FuncTableEntry = sw_tabl_acs(cb, p);
|
||||||
|
else
|
||||||
|
frame->FuncTableEntry = NULL;
|
||||||
|
|
||||||
TRACE("Leave: PC=%s Frame=%s Return=%s Stack=%s Mode=%s cSwitch=%08lx nSwitch=%08lx\n",
|
TRACE("Leave: PC=%s Frame=%s Return=%s Stack=%s Mode=%s cSwitch=%08lx nSwitch=%08lx FuncTable=%p\n",
|
||||||
wine_dbgstr_addr(&frame->AddrPC),
|
wine_dbgstr_addr(&frame->AddrPC),
|
||||||
wine_dbgstr_addr(&frame->AddrFrame),
|
wine_dbgstr_addr(&frame->AddrFrame),
|
||||||
wine_dbgstr_addr(&frame->AddrReturn),
|
wine_dbgstr_addr(&frame->AddrReturn),
|
||||||
wine_dbgstr_addr(&frame->AddrStack),
|
wine_dbgstr_addr(&frame->AddrStack),
|
||||||
curr_mode == stm_start ? "start" : (curr_mode == stm_16bit ? "16bit" : "32bit"),
|
curr_mode == stm_start ? "start" : (curr_mode == stm_16bit ? "16bit" : "32bit"),
|
||||||
curr_switch, next_switch);
|
curr_switch, next_switch, frame->FuncTableEntry);
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
done_err:
|
done_err:
|
||||||
|
@ -460,6 +485,8 @@ BOOL WINAPI StackWalk(DWORD MachineType, HANDLE hProcess, HANDLE hThread,
|
||||||
/* sigh... MS isn't even consistent in the func prototypes */
|
/* sigh... MS isn't even consistent in the func prototypes */
|
||||||
swcb.u.s32.f_read_mem = (f_read_mem) ? f_read_mem : read_mem;
|
swcb.u.s32.f_read_mem = (f_read_mem) ? f_read_mem : read_mem;
|
||||||
swcb.u.s32.f_xlat_adr = (f_xlat_adr) ? f_xlat_adr : addr_to_linear;
|
swcb.u.s32.f_xlat_adr = (f_xlat_adr) ? f_xlat_adr : addr_to_linear;
|
||||||
|
swcb.u.s32.f_tabl_acs = (FunctionTableAccessRoutine) ? FunctionTableAccessRoutine : SymFunctionTableAccess;
|
||||||
|
swcb.u.s32.f_modl_bas = (GetModuleBaseRoutine) ? GetModuleBaseRoutine : SymGetModuleBase;
|
||||||
|
|
||||||
return stack_walk(&swcb, frame);
|
return stack_walk(&swcb, frame);
|
||||||
}
|
}
|
||||||
|
@ -479,7 +506,7 @@ BOOL WINAPI StackWalk64(DWORD MachineType, HANDLE hProcess, HANDLE hThread,
|
||||||
STACKFRAME frame32;
|
STACKFRAME frame32;
|
||||||
BOOL ret;
|
BOOL ret;
|
||||||
|
|
||||||
TRACE("(%ld, %p, %p, %p, %p, %p, %p, %p, %p) - stub!\n",
|
TRACE("(%ld, %p, %p, %p, %p, %p, %p, %p, %p)\n",
|
||||||
MachineType, hProcess, hThread, frame64, ctx,
|
MachineType, hProcess, hThread, frame64, ctx,
|
||||||
f_read_mem, FunctionTableAccessRoutine,
|
f_read_mem, FunctionTableAccessRoutine,
|
||||||
GetModuleBaseRoutine, f_xlat_adr);
|
GetModuleBaseRoutine, f_xlat_adr);
|
||||||
|
@ -509,6 +536,8 @@ BOOL WINAPI StackWalk64(DWORD MachineType, HANDLE hProcess, HANDLE hThread,
|
||||||
/* sigh... MS isn't even consistent in the func prototypes */
|
/* sigh... MS isn't even consistent in the func prototypes */
|
||||||
swcb.u.s64.f_read_mem = (f_read_mem) ? f_read_mem : read_mem64;
|
swcb.u.s64.f_read_mem = (f_read_mem) ? f_read_mem : read_mem64;
|
||||||
swcb.u.s64.f_xlat_adr = f_xlat_adr;
|
swcb.u.s64.f_xlat_adr = f_xlat_adr;
|
||||||
|
swcb.u.s64.f_tabl_acs = (FunctionTableAccessRoutine) ? FunctionTableAccessRoutine : SymFunctionTableAccess64;
|
||||||
|
swcb.u.s64.f_modl_bas = (GetModuleBaseRoutine) ? GetModuleBaseRoutine : SymGetModuleBase64;
|
||||||
|
|
||||||
ret = stack_walk(&swcb, &frame32);
|
ret = stack_walk(&swcb, &frame32);
|
||||||
|
|
||||||
|
@ -529,6 +558,15 @@ BOOL WINAPI StackWalk64(DWORD MachineType, HANDLE hProcess, HANDLE hThread,
|
||||||
frame64->Reserved[1] = (ULONG)frame32.Reserved[1];
|
frame64->Reserved[1] = (ULONG)frame32.Reserved[1];
|
||||||
frame64->Reserved[2] = (ULONG)frame32.Reserved[2];
|
frame64->Reserved[2] = (ULONG)frame32.Reserved[2];
|
||||||
/* we don't handle KdHelp */
|
/* we don't handle KdHelp */
|
||||||
|
frame64->KdHelp.Thread = 0xC000FADE;
|
||||||
|
frame64->KdHelp.ThCallbackStack = 0x10;
|
||||||
|
frame64->KdHelp.ThCallbackBStore = 0;
|
||||||
|
frame64->KdHelp.NextCallback = 0;
|
||||||
|
frame64->KdHelp.FramePointer = 0;
|
||||||
|
frame64->KdHelp.KiCallUserMode = 0xD000DAFE;
|
||||||
|
frame64->KdHelp.KeUserCallbackDispatcher = 0xE000F000;
|
||||||
|
frame64->KdHelp.SystemRangeStart = 0xC0000000;
|
||||||
|
frame64->KdHelp.Reserved[0] /* KiUserExceptionDispatcher */ = 0xE0005000;
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1253,9 +1253,17 @@ BOOL WINAPI SymGetLineNext64(HANDLE hProcess, PIMAGEHLP_LINE64 Line)
|
||||||
*/
|
*/
|
||||||
PVOID WINAPI SymFunctionTableAccess(HANDLE hProcess, DWORD AddrBase)
|
PVOID WINAPI SymFunctionTableAccess(HANDLE hProcess, DWORD AddrBase)
|
||||||
{
|
{
|
||||||
FIXME("(%p, 0x%08lx): stub\n", hProcess, AddrBase);
|
WARN("(%p, 0x%08lx): stub\n", hProcess, AddrBase);
|
||||||
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
|
return NULL;
|
||||||
return FALSE;
|
}
|
||||||
|
|
||||||
|
/***********************************************************************
|
||||||
|
* SymFunctionTableAccess64 (DBGHELP.@)
|
||||||
|
*/
|
||||||
|
PVOID WINAPI SymFunctionTableAccess64(HANDLE hProcess, DWORD64 AddrBase)
|
||||||
|
{
|
||||||
|
WARN("(%p, %s): stub\n", hProcess, wine_dbgstr_longlong(AddrBase));
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
|
|
|
@ -691,6 +691,7 @@ BOOL WINAPI SymGetModuleInfoW(HANDLE, DWORD, PIMAGEHLP_MODULEW);
|
||||||
BOOL WINAPI SymGetModuleInfo64(HANDLE, DWORD64, PIMAGEHLP_MODULE64);
|
BOOL WINAPI SymGetModuleInfo64(HANDLE, DWORD64, PIMAGEHLP_MODULE64);
|
||||||
BOOL WINAPI SymGetModuleInfoW64(HANDLE, DWORD64, PIMAGEHLP_MODULEW64);
|
BOOL WINAPI SymGetModuleInfoW64(HANDLE, DWORD64, PIMAGEHLP_MODULEW64);
|
||||||
DWORD WINAPI SymGetModuleBase(HANDLE, DWORD);
|
DWORD WINAPI SymGetModuleBase(HANDLE, DWORD);
|
||||||
|
DWORD64 WINAPI SymGetModuleBase64(HANDLE, DWORD64);
|
||||||
DWORD WINAPI SymLoadModule(HANDLE, HANDLE, PSTR, PSTR, DWORD, DWORD);
|
DWORD WINAPI SymLoadModule(HANDLE, HANDLE, PSTR, PSTR, DWORD, DWORD);
|
||||||
DWORD64 WINAPI SymLoadModule64(HANDLE, HANDLE, PSTR, PSTR, DWORD64, DWORD);
|
DWORD64 WINAPI SymLoadModule64(HANDLE, HANDLE, PSTR, PSTR, DWORD64, DWORD);
|
||||||
DWORD64 WINAPI SymLoadModuleEx(HANDLE, HANDLE, PCSTR, PCSTR, DWORD64, DWORD,
|
DWORD64 WINAPI SymLoadModuleEx(HANDLE, HANDLE, PCSTR, PCSTR, DWORD64, DWORD,
|
||||||
|
@ -973,6 +974,7 @@ BOOL WINAPI StackWalk64(DWORD, HANDLE, HANDLE, LPSTACKFRAME64, PVOID,
|
||||||
PTRANSLATE_ADDRESS_ROUTINE64);
|
PTRANSLATE_ADDRESS_ROUTINE64);
|
||||||
|
|
||||||
PVOID WINAPI SymFunctionTableAccess(HANDLE, DWORD);
|
PVOID WINAPI SymFunctionTableAccess(HANDLE, DWORD);
|
||||||
|
PVOID WINAPI SymFunctionTableAccess64(HANDLE, DWORD64);
|
||||||
|
|
||||||
typedef PVOID (CALLBACK *PSYMBOL_FUNCENTRY_CALLBACK)(HANDLE, DWORD, PVOID);
|
typedef PVOID (CALLBACK *PSYMBOL_FUNCENTRY_CALLBACK)(HANDLE, DWORD, PVOID);
|
||||||
typedef PVOID (CALLBACK *PSYMBOL_FUNCENTRY_CALLBACK64)(HANDLE, ULONG64, ULONG64);
|
typedef PVOID (CALLBACK *PSYMBOL_FUNCENTRY_CALLBACK64)(HANDLE, ULONG64, ULONG64);
|
||||||
|
|
Loading…
Reference in New Issue