Eric Pouech : dbghelp: StackWalk (32 and 64 bit version).

Alexandre Julliard julliard at wine.codeweavers.com
Thu Jan 5 10:53:54 CST 2006


Module: wine
Branch: refs/heads/master
Commit: 558130a696a1e6c11a84f3d1f12515c74b9ef17f
URL:    http://source.winehq.org/git/?p=wine.git;a=commit;h=558130a696a1e6c11a84f3d1f12515c74b9ef17f

Author: Eric Pouech <eric.pouech at wanadoo.fr>
Date:   Thu Jan  5 13:41:25 2006 +0100

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 SymFunctionTableAccess64

---

 dlls/dbghelp/dbghelp.spec |    4 ++-
 dlls/dbghelp/module.c     |   11 ++++++++-
 dlls/dbghelp/stack.c      |   56 ++++++++++++++++++++++++++++++++++++++-------
 dlls/dbghelp/symbol.c     |   14 +++++++++--
 include/dbghelp.h         |    2 ++
 5 files changed, 72 insertions(+), 15 deletions(-)

diff --git a/dlls/dbghelp/dbghelp.spec b/dlls/dbghelp/dbghelp.spec
index 92ccd49..7318bce 100644
--- a/dlls/dbghelp/dbghelp.spec
+++ b/dlls/dbghelp/dbghelp.spec
@@ -43,7 +43,7 @@
 @ stdcall SymFromAddr(ptr double ptr ptr)
 @ stdcall SymFromName(long str ptr)
 @ stub SymFromToken
-@ stub SymFunctionTableAccess64
+@ stdcall SymFunctionTableAccess64(long double)
 @ stdcall SymFunctionTableAccess(long long)
 @ stub SymGetFileLineOffsets64
 @ stub SymGetHomeDirectory
@@ -55,7 +55,7 @@
 @ stdcall SymGetLineNext(long ptr)
 @ stdcall SymGetLinePrev64(long ptr)
 @ stdcall SymGetLinePrev(long ptr)
-@ stub SymGetModuleBase64
+@ stdcall SymGetModuleBase64(long double)
 @ stdcall SymGetModuleBase(long long)
 @ stdcall SymGetModuleInfo64(long double ptr)
 @ stdcall SymGetModuleInfo(long long ptr)
diff --git a/dlls/dbghelp/module.c b/dlls/dbghelp/module.c
index 2b0de8c..3c0c5d4 100644
--- a/dlls/dbghelp/module.c
+++ b/dlls/dbghelp/module.c
@@ -642,7 +642,7 @@ BOOL  WINAPI SymGetModuleInfo64(HANDLE h
 }
 
 /***********************************************************************
- *		SymGetModuleBase (IMAGEHLP.@)
+ *		SymGetModuleBase (DBGHELP.@)
  */
 DWORD WINAPI SymGetModuleBase(HANDLE hProcess, DWORD dwAddr)
 {
@@ -655,6 +655,15 @@ DWORD WINAPI SymGetModuleBase(HANDLE hPr
     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
  * Removes any debug information linked to a given module.
diff --git a/dlls/dbghelp/stack.c b/dlls/dbghelp/stack.c
index 69e9c1f..e4827a6 100644
--- a/dlls/dbghelp/stack.c
+++ b/dlls/dbghelp/stack.c
@@ -89,11 +89,15 @@ struct stack_walk_callback
         {
             PREAD_PROCESS_MEMORY_ROUTINE        f_read_mem;
             PTRANSLATE_ADDRESS_ROUTINE          f_xlat_adr;
+            PFUNCTION_TABLE_ACCESS_ROUTINE      f_tabl_acs;
+            PGET_MODULE_BASE_ROUTINE            f_modl_bas;
         } s32;
         struct
         {
             PREAD_PROCESS_MEMORY_ROUTINE64      f_read_mem;
             PTRANSLATE_ADDRESS_ROUTINE64        f_xlat_adr;
+            PFUNCTION_TABLE_ACCESS_ROUTINE64    f_tabl_acs;
+            PGET_MODULE_BASE_ROUTINE64          f_modl_bas;
         } s64;
     } u;
 };
@@ -122,17 +126,32 @@ static inline BOOL sw_read_mem(struct st
 
 static inline DWORD sw_xlat_addr(struct stack_walk_callback* cb, ADDRESS* 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 (addr->Mode == AddrModeFlat) return addr->Offset;
+    if (cb->is32) return cb->u.s32.f_xlat_adr(cb->hProcess, cb->hThread, addr);
+    if (cb->u.s64.f_xlat_adr)
     {
         ADDRESS64       addr64;
 
         addr_32to64(addr, &addr64);
         return cb->u.s64.f_xlat_adr(cb->hProcess, cb->hThread, &addr64);
     }
+    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 addr_to_linear(cb->hProcess, cb->hThread, addr);
+        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)
@@ -223,6 +242,7 @@ static BOOL stack_walk(struct stack_walk
         /* don't set up AddrStack on first call. Either the caller has set it up, or
          * we will get it in the next frame
          */
+        memset(&frame->AddrBStore, 0, sizeof(frame->AddrBStore));
     }
     else
     {
@@ -414,16 +434,21 @@ static BOOL stack_walk(struct stack_walk
                     frame->Params, sizeof(frame->Params));
     }
 
-    frame->Far = FALSE;
-    frame->Virtual = FALSE;
+    frame->Far = TRUE;
+    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->AddrFrame),
           wine_dbgstr_addr(&frame->AddrReturn),
           wine_dbgstr_addr(&frame->AddrStack), 
           curr_mode == stm_start ? "start" : (curr_mode == stm_16bit ? "16bit" : "32bit"),
-          curr_switch, next_switch);
+          curr_switch, next_switch, frame->FuncTableEntry);
 
     return TRUE;
 done_err:
@@ -460,6 +485,8 @@ BOOL WINAPI StackWalk(DWORD MachineType,
     /* 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_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);
 }
@@ -479,7 +506,7 @@ BOOL WINAPI StackWalk64(DWORD MachineTyp
     STACKFRAME                  frame32;
     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,
           f_read_mem, FunctionTableAccessRoutine,
           GetModuleBaseRoutine, f_xlat_adr);
@@ -509,6 +536,8 @@ BOOL WINAPI StackWalk64(DWORD MachineTyp
     /* 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_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);
 
@@ -529,6 +558,15 @@ BOOL WINAPI StackWalk64(DWORD MachineTyp
     frame64->Reserved[1] = (ULONG)frame32.Reserved[1];
     frame64->Reserved[2] = (ULONG)frame32.Reserved[2];
     /* 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;
 }
diff --git a/dlls/dbghelp/symbol.c b/dlls/dbghelp/symbol.c
index 8df2d5b..704c8e4 100644
--- a/dlls/dbghelp/symbol.c
+++ b/dlls/dbghelp/symbol.c
@@ -1253,9 +1253,17 @@ BOOL WINAPI SymGetLineNext64(HANDLE hPro
  */
 PVOID WINAPI SymFunctionTableAccess(HANDLE hProcess, DWORD AddrBase)
 {
-    FIXME("(%p, 0x%08lx): stub\n", hProcess, AddrBase);
-    SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
-    return FALSE;
+    WARN("(%p, 0x%08lx): stub\n", hProcess, AddrBase);
+    return NULL;
+}
+
+/***********************************************************************
+ *		SymFunctionTableAccess64 (DBGHELP.@)
+ */
+PVOID WINAPI SymFunctionTableAccess64(HANDLE hProcess, DWORD64 AddrBase)
+{
+    WARN("(%p, %s): stub\n", hProcess, wine_dbgstr_longlong(AddrBase));
+    return NULL;
 }
 
 /***********************************************************************
diff --git a/include/dbghelp.h b/include/dbghelp.h
index dd2aad8..c70ca15 100644
--- a/include/dbghelp.h
+++ b/include/dbghelp.h
@@ -691,6 +691,7 @@ BOOL    WINAPI SymGetModuleInfoW(HANDLE,
 BOOL    WINAPI SymGetModuleInfo64(HANDLE, DWORD64, PIMAGEHLP_MODULE64);
 BOOL    WINAPI SymGetModuleInfoW64(HANDLE, DWORD64, PIMAGEHLP_MODULEW64);
 DWORD   WINAPI SymGetModuleBase(HANDLE, DWORD);
+DWORD64 WINAPI SymGetModuleBase64(HANDLE, DWORD64);
 DWORD   WINAPI SymLoadModule(HANDLE, HANDLE, PSTR, PSTR, DWORD, DWORD);
 DWORD64 WINAPI SymLoadModule64(HANDLE, HANDLE, PSTR, PSTR, DWORD64, DWORD);
 DWORD64 WINAPI SymLoadModuleEx(HANDLE, HANDLE, PCSTR, PCSTR, DWORD64, DWORD,
@@ -973,6 +974,7 @@ BOOL WINAPI StackWalk64(DWORD, HANDLE, H
                         PTRANSLATE_ADDRESS_ROUTINE64);
 
 PVOID WINAPI SymFunctionTableAccess(HANDLE, DWORD);
+PVOID WINAPI SymFunctionTableAccess64(HANDLE, DWORD64);
 
 typedef PVOID (CALLBACK *PSYMBOL_FUNCENTRY_CALLBACK)(HANDLE, DWORD, PVOID);
 typedef PVOID (CALLBACK *PSYMBOL_FUNCENTRY_CALLBACK64)(HANDLE, ULONG64, ULONG64);




More information about the wine-cvs mailing list