Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenstack.c
Go to the documentation of this file.
00001 /* 00002 * Stack walking 00003 * 00004 * Copyright 1995 Alexandre Julliard 00005 * Copyright 1996 Eric Youngdale 00006 * Copyright 1999 Ove Kåven 00007 * Copyright 2004 Eric Pouech 00008 * 00009 * This library is free software; you can redistribute it and/or 00010 * modify it under the terms of the GNU Lesser General Public 00011 * License as published by the Free Software Foundation; either 00012 * version 2.1 of the License, or (at your option) any later version. 00013 * 00014 * This library is distributed in the hope that it will be useful, 00015 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00016 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00017 * Lesser General Public License for more details. 00018 * 00019 * You should have received a copy of the GNU Lesser General Public 00020 * License along with this library; if not, write to the Free Software 00021 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA 00022 */ 00023 00024 #include "config.h" 00025 #include <stdlib.h> 00026 #include <stdio.h> 00027 #include <string.h> 00028 #include <assert.h> 00029 00030 #include "dbghelp_private.h" 00031 #include "wine/debug.h" 00032 00033 WINE_DEFAULT_DEBUG_CHANNEL(dbghelp); 00034 00035 static DWORD64 WINAPI addr_to_linear(HANDLE hProcess, HANDLE hThread, ADDRESS64* addr) 00036 { 00037 LDT_ENTRY le; 00038 00039 switch (addr->Mode) 00040 { 00041 case AddrMode1616: 00042 if (GetThreadSelectorEntry(hThread, addr->Segment, &le)) 00043 return (le.HighWord.Bits.BaseHi << 24) + 00044 (le.HighWord.Bits.BaseMid << 16) + le.BaseLow + LOWORD(addr->Offset); 00045 break; 00046 case AddrMode1632: 00047 if (GetThreadSelectorEntry(hThread, addr->Segment, &le)) 00048 return (le.HighWord.Bits.BaseHi << 24) + 00049 (le.HighWord.Bits.BaseMid << 16) + le.BaseLow + addr->Offset; 00050 break; 00051 case AddrModeReal: 00052 return (DWORD)(LOWORD(addr->Segment) << 4) + addr->Offset; 00053 case AddrModeFlat: 00054 return addr->Offset; 00055 default: 00056 FIXME("Unsupported (yet) mode (%x)\n", addr->Mode); 00057 return 0; 00058 } 00059 FIXME("Failed to linearize address %04x:%s (mode %x)\n", 00060 addr->Segment, wine_dbgstr_longlong(addr->Offset), addr->Mode); 00061 return 0; 00062 } 00063 00064 static BOOL CALLBACK read_mem(HANDLE hProcess, DWORD addr, void* buffer, 00065 DWORD size, LPDWORD nread) 00066 { 00067 SIZE_T r; 00068 if (!ReadProcessMemory(hProcess, (void*)(DWORD_PTR)addr, buffer, size, &r)) return FALSE; 00069 if (nread) *nread = r; 00070 return TRUE; 00071 } 00072 00073 static BOOL CALLBACK read_mem64(HANDLE hProcess, DWORD64 addr, void* buffer, 00074 DWORD size, LPDWORD nread) 00075 { 00076 SIZE_T r; 00077 if (!ReadProcessMemory(hProcess, (void*)(DWORD_PTR)addr, buffer, size, &r)) return FALSE; 00078 if (nread) *nread = r; 00079 return TRUE; 00080 } 00081 00082 static inline void addr_32to64(const ADDRESS* addr32, ADDRESS64* addr64) 00083 { 00084 addr64->Offset = (ULONG64)addr32->Offset; 00085 addr64->Segment = addr32->Segment; 00086 addr64->Mode = addr32->Mode; 00087 } 00088 00089 static inline void addr_64to32(const ADDRESS64* addr64, ADDRESS* addr32) 00090 { 00091 addr32->Offset = (ULONG)addr64->Offset; 00092 addr32->Segment = addr64->Segment; 00093 addr32->Mode = addr64->Mode; 00094 } 00095 00096 BOOL sw_read_mem(struct cpu_stack_walk* csw, DWORD64 addr, void* ptr, DWORD sz) 00097 { 00098 DWORD bytes_read = 0; 00099 if (csw->is32) 00100 return csw->u.s32.f_read_mem(csw->hProcess, addr, ptr, sz, &bytes_read); 00101 else 00102 return csw->u.s64.f_read_mem(csw->hProcess, addr, ptr, sz, &bytes_read); 00103 } 00104 00105 DWORD64 sw_xlat_addr(struct cpu_stack_walk* csw, ADDRESS64* addr) 00106 { 00107 if (addr->Mode == AddrModeFlat) return addr->Offset; 00108 if (csw->is32) 00109 { 00110 ADDRESS addr32; 00111 00112 addr_64to32(addr, &addr32); 00113 return csw->u.s32.f_xlat_adr(csw->hProcess, csw->hThread, &addr32); 00114 } 00115 else if (csw->u.s64.f_xlat_adr) 00116 return csw->u.s64.f_xlat_adr(csw->hProcess, csw->hThread, addr); 00117 return addr_to_linear(csw->hProcess, csw->hThread, addr); 00118 } 00119 00120 void* sw_table_access(struct cpu_stack_walk* csw, DWORD64 addr) 00121 { 00122 if (csw->is32) 00123 return csw->u.s32.f_tabl_acs(csw->hProcess, addr); 00124 else 00125 return csw->u.s64.f_tabl_acs(csw->hProcess, addr); 00126 } 00127 00128 DWORD64 sw_module_base(struct cpu_stack_walk* csw, DWORD64 addr) 00129 { 00130 if (csw->is32) 00131 return csw->u.s32.f_modl_bas(csw->hProcess, addr); 00132 else 00133 return csw->u.s64.f_modl_bas(csw->hProcess, addr); 00134 } 00135 00136 /*********************************************************************** 00137 * StackWalk (DBGHELP.@) 00138 */ 00139 BOOL WINAPI StackWalk(DWORD MachineType, HANDLE hProcess, HANDLE hThread, 00140 LPSTACKFRAME frame32, PVOID ctx, 00141 PREAD_PROCESS_MEMORY_ROUTINE f_read_mem, 00142 PFUNCTION_TABLE_ACCESS_ROUTINE FunctionTableAccessRoutine, 00143 PGET_MODULE_BASE_ROUTINE GetModuleBaseRoutine, 00144 PTRANSLATE_ADDRESS_ROUTINE f_xlat_adr) 00145 { 00146 struct cpu_stack_walk csw; 00147 STACKFRAME64 frame64; 00148 BOOL ret; 00149 struct cpu* cpu; 00150 00151 TRACE("(%d, %p, %p, %p, %p, %p, %p, %p, %p)\n", 00152 MachineType, hProcess, hThread, frame32, ctx, 00153 f_read_mem, FunctionTableAccessRoutine, 00154 GetModuleBaseRoutine, f_xlat_adr); 00155 00156 if (!(cpu = cpu_find(MachineType))) 00157 { 00158 SetLastError(ERROR_INVALID_PARAMETER); 00159 return FALSE; 00160 } 00161 00162 addr_32to64(&frame32->AddrPC, &frame64.AddrPC); 00163 addr_32to64(&frame32->AddrReturn, &frame64.AddrReturn); 00164 addr_32to64(&frame32->AddrFrame, &frame64.AddrFrame); 00165 addr_32to64(&frame32->AddrStack, &frame64.AddrStack); 00166 addr_32to64(&frame32->AddrBStore, &frame64.AddrBStore); 00167 frame64.FuncTableEntry = frame32->FuncTableEntry; /* FIXME */ 00168 frame64.Far = frame32->Far; 00169 frame64.Virtual = frame32->Virtual; 00170 frame64.Reserved[0] = frame32->Reserved[0]; 00171 frame64.Reserved[1] = frame32->Reserved[1]; 00172 frame64.Reserved[2] = frame32->Reserved[2]; 00173 /* we don't handle KdHelp */ 00174 00175 csw.hProcess = hProcess; 00176 csw.hThread = hThread; 00177 csw.is32 = TRUE; 00178 /* sigh... MS isn't even consistent in the func prototypes */ 00179 csw.u.s32.f_read_mem = (f_read_mem) ? f_read_mem : read_mem; 00180 csw.u.s32.f_xlat_adr = f_xlat_adr; 00181 csw.u.s32.f_tabl_acs = (FunctionTableAccessRoutine) ? FunctionTableAccessRoutine : SymFunctionTableAccess; 00182 csw.u.s32.f_modl_bas = (GetModuleBaseRoutine) ? GetModuleBaseRoutine : SymGetModuleBase; 00183 00184 if ((ret = cpu->stack_walk(&csw, &frame64, ctx))) 00185 { 00186 addr_64to32(&frame64.AddrPC, &frame32->AddrPC); 00187 addr_64to32(&frame64.AddrReturn, &frame32->AddrReturn); 00188 addr_64to32(&frame64.AddrFrame, &frame32->AddrFrame); 00189 addr_64to32(&frame64.AddrStack, &frame32->AddrStack); 00190 addr_64to32(&frame64.AddrBStore, &frame32->AddrBStore); 00191 frame32->FuncTableEntry = frame64.FuncTableEntry; /* FIXME */ 00192 frame32->Params[0] = frame64.Params[0]; 00193 frame32->Params[1] = frame64.Params[1]; 00194 frame32->Params[2] = frame64.Params[2]; 00195 frame32->Params[3] = frame64.Params[3]; 00196 frame32->Far = frame64.Far; 00197 frame32->Virtual = frame64.Virtual; 00198 frame32->Reserved[0] = frame64.Reserved[0]; 00199 frame32->Reserved[1] = frame64.Reserved[1]; 00200 frame32->Reserved[2] = frame64.Reserved[2]; 00201 } 00202 00203 return ret; 00204 } 00205 00206 00207 /*********************************************************************** 00208 * StackWalk64 (DBGHELP.@) 00209 */ 00210 BOOL WINAPI StackWalk64(DWORD MachineType, HANDLE hProcess, HANDLE hThread, 00211 LPSTACKFRAME64 frame, PVOID ctx, 00212 PREAD_PROCESS_MEMORY_ROUTINE64 f_read_mem, 00213 PFUNCTION_TABLE_ACCESS_ROUTINE64 FunctionTableAccessRoutine, 00214 PGET_MODULE_BASE_ROUTINE64 GetModuleBaseRoutine, 00215 PTRANSLATE_ADDRESS_ROUTINE64 f_xlat_adr) 00216 { 00217 struct cpu_stack_walk csw; 00218 struct cpu* cpu; 00219 00220 TRACE("(%d, %p, %p, %p, %p, %p, %p, %p, %p)\n", 00221 MachineType, hProcess, hThread, frame, ctx, 00222 f_read_mem, FunctionTableAccessRoutine, 00223 GetModuleBaseRoutine, f_xlat_adr); 00224 00225 if (!(cpu = cpu_find(MachineType))) 00226 { 00227 SetLastError(ERROR_INVALID_PARAMETER); 00228 return FALSE; 00229 } 00230 00231 csw.hProcess = hProcess; 00232 csw.hThread = hThread; 00233 csw.is32 = FALSE; 00234 /* sigh... MS isn't even consistent in the func prototypes */ 00235 csw.u.s64.f_read_mem = (f_read_mem) ? f_read_mem : read_mem64; 00236 csw.u.s64.f_xlat_adr = (f_xlat_adr) ? f_xlat_adr : addr_to_linear; 00237 csw.u.s64.f_tabl_acs = (FunctionTableAccessRoutine) ? FunctionTableAccessRoutine : SymFunctionTableAccess64; 00238 csw.u.s64.f_modl_bas = (GetModuleBaseRoutine) ? GetModuleBaseRoutine : SymGetModuleBase64; 00239 00240 if (!cpu->stack_walk(&csw, frame, ctx)) return FALSE; 00241 00242 /* we don't handle KdHelp */ 00243 frame->KdHelp.Thread = 0xC000FADE; 00244 frame->KdHelp.ThCallbackStack = 0x10; 00245 frame->KdHelp.ThCallbackBStore = 0; 00246 frame->KdHelp.NextCallback = 0; 00247 frame->KdHelp.FramePointer = 0; 00248 frame->KdHelp.KiCallUserMode = 0xD000DAFE; 00249 frame->KdHelp.KeUserCallbackDispatcher = 0xE000F000; 00250 frame->KdHelp.SystemRangeStart = 0xC0000000; 00251 frame->KdHelp.Reserved[0] /* KiUserExceptionDispatcher */ = 0xE0005000; 00252 00253 return TRUE; 00254 } 00255 00256 /****************************************************************** 00257 * SymRegisterFunctionEntryCallback (DBGHELP.@) 00258 * 00259 * 00260 */ 00261 BOOL WINAPI SymRegisterFunctionEntryCallback(HANDLE hProc, 00262 PSYMBOL_FUNCENTRY_CALLBACK cb, PVOID user) 00263 { 00264 FIXME("(%p %p %p): stub!\n", hProc, cb, user); 00265 SetLastError(ERROR_CALL_NOT_IMPLEMENTED); 00266 return FALSE; 00267 } 00268 00269 /****************************************************************** 00270 * SymRegisterFunctionEntryCallback64 (DBGHELP.@) 00271 * 00272 * 00273 */ 00274 BOOL WINAPI SymRegisterFunctionEntryCallback64(HANDLE hProc, 00275 PSYMBOL_FUNCENTRY_CALLBACK64 cb, 00276 ULONG64 user) 00277 { 00278 FIXME("(%p %p %s): stub!\n", hProc, cb, wine_dbgstr_longlong(user)); 00279 SetLastError(ERROR_CALL_NOT_IMPLEMENTED); 00280 return FALSE; 00281 } Generated on Sun May 27 2012 04:23:25 for ReactOS by
1.7.6.1
|