1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/tools/trace-malloc/lib/nsDebugHelpWin32.h Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,133 @@ 1.4 +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ 1.5 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.6 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.7 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.8 + 1.9 +/* Win32 x86/x64 code for stack walking, symbol resolution, and function hooking */ 1.10 + 1.11 +#ifndef __nsDebugHelpWin32_h__ 1.12 +#define __nsDebugHelpWin32_h__ 1.13 + 1.14 +#if defined(_WIN32) && (defined(_M_IX86) || defined(_M_X64)) 1.15 + #ifndef WIN32_LEAN_AND_MEAN 1.16 + #define WIN32_LEAN_AND_MEAN 1.17 + #endif 1.18 + #include <windows.h> 1.19 + #include <imagehlp.h> 1.20 + #include <crtdbg.h> 1.21 +#else 1.22 + #error "nsDebugHelpWin32.h should only be included in Win32 x86/x64 builds" 1.23 +#endif 1.24 + 1.25 +// XXX temporary hack... 1.26 +//#include "hacky_defines.h" 1.27 + 1.28 + 1.29 +/***************************************************************************/ 1.30 +// useful macros... 1.31 + 1.32 +#ifdef DHW_IMPLEMENT_GLOBALS 1.33 +#define DHW_DECLARE_FUN_GLOBAL(name_) decltype(name_)* dhw##name_ 1.34 +#else 1.35 +#define DHW_DECLARE_FUN_GLOBAL(name_) extern decltype(name_)* dhw##name_ 1.36 +#endif 1.37 + 1.38 + 1.39 +/**********************************************************/ 1.40 +// This is used to get 'original' function addresses from DHWImportHooker. 1.41 + 1.42 +#define DHW_ORIGINAL(name_, hooker_) \ 1.43 + ((decltype(name_)*) hooker_ . GetOriginalFunction()) 1.44 + 1.45 +/***************************************************************************/ 1.46 +// Global declarations of entry points into ImgHelp functions 1.47 + 1.48 +#ifndef _WIN64 1.49 +DHW_DECLARE_FUN_GLOBAL(EnumerateLoadedModules); 1.50 +#else 1.51 +DHW_DECLARE_FUN_GLOBAL(EnumerateLoadedModules64); 1.52 +#endif 1.53 + 1.54 +DHW_DECLARE_FUN_GLOBAL(ImageDirectoryEntryToData); 1.55 + 1.56 +/***************************************************************************/ 1.57 + 1.58 +extern bool 1.59 +dhwEnsureImageHlpInitialized(); 1.60 + 1.61 +/***************************************************************************/ 1.62 + 1.63 +class DHWImportHooker 1.64 +{ 1.65 +public: 1.66 + 1.67 + DHWImportHooker(const char* aModuleName, 1.68 + const char* aFunctionName, 1.69 + PROC aHook, 1.70 + bool aExcludeOurModule = false); 1.71 + 1.72 + ~DHWImportHooker(); 1.73 + 1.74 + PROC GetOriginalFunction() {return mOriginal;} 1.75 + 1.76 + bool PatchAllModules(); 1.77 + bool PatchOneModule(HMODULE aModule, const char* name); 1.78 + static bool ModuleLoaded(HMODULE aModule, DWORD flags); 1.79 + 1.80 + 1.81 + // I think that these should be made not static members, but allocated 1.82 + // things created in an explicit static 'init' method and cleaned up in 1.83 + // an explicit static 'finish' method. This would allow the application 1.84 + // to have proper lifetime control over all the hooks. 1.85 + 1.86 + static DHWImportHooker &getLoadLibraryWHooker(); 1.87 + static DHWImportHooker &getLoadLibraryExWHooker(); 1.88 + static DHWImportHooker &getLoadLibraryAHooker(); 1.89 + static DHWImportHooker &getLoadLibraryExAHooker(); 1.90 + static DHWImportHooker &getGetProcAddressHooker(); 1.91 + 1.92 + static HMODULE WINAPI LoadLibraryA(PCSTR path); 1.93 + 1.94 +private: 1.95 + DHWImportHooker* mNext; 1.96 + const char* mModuleName; 1.97 + const char* mFunctionName; 1.98 + PROC mOriginal; 1.99 + PROC mHook; 1.100 + HMODULE mIgnoreModule; 1.101 + bool mHooking; 1.102 + 1.103 +private: 1.104 + static PRLock* gLock; 1.105 + static DHWImportHooker* gHooks; 1.106 + static decltype(GetProcAddress)* gRealGetProcAddress; 1.107 + 1.108 + static HMODULE WINAPI LoadLibraryW(PCWSTR path); 1.109 + static HMODULE WINAPI LoadLibraryExW(PCWSTR path, HANDLE file, DWORD flags); 1.110 + static HMODULE WINAPI LoadLibraryExA(PCSTR path, HANDLE file, DWORD flags); 1.111 + 1.112 + static FARPROC WINAPI GetProcAddress(HMODULE aModule, PCSTR aFunctionName); 1.113 +}; 1.114 + 1.115 +/***************************************************************************/ 1.116 +// This supports the _CrtSetAllocHook based hooking. 1.117 +// This system sucks because you don't get to see the allocated pointer. I 1.118 +// don't think it appropriate for nsTraceMalloc, but is useful as a means to make 1.119 +// malloc fail for testing purposes. 1.120 +#if 0 //comment out this stuff. not necessary 1.121 + 1.122 +class DHWAllocationSizeDebugHook 1.123 +{ 1.124 +public: 1.125 + virtual bool AllocHook(size_t size) = 0; 1.126 + virtual bool ReallocHook(size_t size, size_t sizeOld) = 0; 1.127 + virtual bool FreeHook(size_t size) = 0; 1.128 +}; 1.129 + 1.130 +extern bool dhwSetAllocationSizeDebugHook(DHWAllocationSizeDebugHook* hook); 1.131 +extern bool dhwClearAllocationSizeDebugHook(); 1.132 + 1.133 +/***************************************************************************/ 1.134 +#endif //0 1.135 + 1.136 +#endif /* __nsDebugHelpWin32_h__ */