ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

stack.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 doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.