u_debug_symbol.c revision 64c4f9c56645768aa3cc4a9a60b266a20acca0c2
1346e12773219b8a514b6cab7a670777c0fb554b6José Fonseca/************************************************************************** 2346e12773219b8a514b6cab7a670777c0fb554b6José Fonseca * 3346e12773219b8a514b6cab7a670777c0fb554b6José Fonseca * Copyright 2009 VMware, Inc. 4346e12773219b8a514b6cab7a670777c0fb554b6José Fonseca * All Rights Reserved. 5346e12773219b8a514b6cab7a670777c0fb554b6José Fonseca * 6346e12773219b8a514b6cab7a670777c0fb554b6José Fonseca * Permission is hereby granted, free of charge, to any person obtaining a 7346e12773219b8a514b6cab7a670777c0fb554b6José Fonseca * copy of this software and associated documentation files (the 8346e12773219b8a514b6cab7a670777c0fb554b6José Fonseca * "Software"), to deal in the Software without restriction, including 9346e12773219b8a514b6cab7a670777c0fb554b6José Fonseca * without limitation the rights to use, copy, modify, merge, publish, 10346e12773219b8a514b6cab7a670777c0fb554b6José Fonseca * distribute, sub license, and/or sell copies of the Software, and to 11346e12773219b8a514b6cab7a670777c0fb554b6José Fonseca * permit persons to whom the Software is furnished to do so, subject to 12346e12773219b8a514b6cab7a670777c0fb554b6José Fonseca * the following conditions: 13346e12773219b8a514b6cab7a670777c0fb554b6José Fonseca * 14346e12773219b8a514b6cab7a670777c0fb554b6José Fonseca * The above copyright notice and this permission notice (including the 15346e12773219b8a514b6cab7a670777c0fb554b6José Fonseca * next paragraph) shall be included in all copies or substantial portions 16346e12773219b8a514b6cab7a670777c0fb554b6José Fonseca * of the Software. 17346e12773219b8a514b6cab7a670777c0fb554b6José Fonseca * 18346e12773219b8a514b6cab7a670777c0fb554b6José Fonseca * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 19346e12773219b8a514b6cab7a670777c0fb554b6José Fonseca * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 20346e12773219b8a514b6cab7a670777c0fb554b6José Fonseca * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. 21346e12773219b8a514b6cab7a670777c0fb554b6José Fonseca * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR 22346e12773219b8a514b6cab7a670777c0fb554b6José Fonseca * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 23346e12773219b8a514b6cab7a670777c0fb554b6José Fonseca * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 24346e12773219b8a514b6cab7a670777c0fb554b6José Fonseca * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 25346e12773219b8a514b6cab7a670777c0fb554b6José Fonseca * 26346e12773219b8a514b6cab7a670777c0fb554b6José Fonseca **************************************************************************/ 27346e12773219b8a514b6cab7a670777c0fb554b6José Fonseca 28346e12773219b8a514b6cab7a670777c0fb554b6José Fonseca/** 29346e12773219b8a514b6cab7a670777c0fb554b6José Fonseca * @file 30346e12773219b8a514b6cab7a670777c0fb554b6José Fonseca * Symbol lookup. 31346e12773219b8a514b6cab7a670777c0fb554b6José Fonseca * 32346e12773219b8a514b6cab7a670777c0fb554b6José Fonseca * @author Jose Fonseca <jfonseca@vmware.com> 33346e12773219b8a514b6cab7a670777c0fb554b6José Fonseca */ 34346e12773219b8a514b6cab7a670777c0fb554b6José Fonseca 35346e12773219b8a514b6cab7a670777c0fb554b6José Fonseca#include "pipe/p_compiler.h" 3664c4f9c56645768aa3cc4a9a60b266a20acca0c2Luca Barbieri#include "u_string.h" 37346e12773219b8a514b6cab7a670777c0fb554b6José Fonseca 38346e12773219b8a514b6cab7a670777c0fb554b6José Fonseca#include "u_debug.h" 39346e12773219b8a514b6cab7a670777c0fb554b6José Fonseca#include "u_debug_symbol.h" 40346e12773219b8a514b6cab7a670777c0fb554b6José Fonseca 41346e12773219b8a514b6cab7a670777c0fb554b6José Fonseca#if defined(PIPE_SUBSYSTEM_WINDOWS_USER) && defined(PIPE_ARCH_X86) 42346e12773219b8a514b6cab7a670777c0fb554b6José Fonseca 43346e12773219b8a514b6cab7a670777c0fb554b6José Fonseca#include <windows.h> 44346e12773219b8a514b6cab7a670777c0fb554b6José Fonseca#include <stddef.h> 45346e12773219b8a514b6cab7a670777c0fb554b6José Fonseca#include <imagehlp.h> 46346e12773219b8a514b6cab7a670777c0fb554b6José Fonseca 47346e12773219b8a514b6cab7a670777c0fb554b6José Fonseca/* 48346e12773219b8a514b6cab7a670777c0fb554b6José Fonseca * TODO: Cleanup code. 49346e12773219b8a514b6cab7a670777c0fb554b6José Fonseca * TODO: Support x86_64 50346e12773219b8a514b6cab7a670777c0fb554b6José Fonseca */ 51346e12773219b8a514b6cab7a670777c0fb554b6José Fonseca 52346e12773219b8a514b6cab7a670777c0fb554b6José Fonsecastatic BOOL bSymInitialized = FALSE; 53346e12773219b8a514b6cab7a670777c0fb554b6José Fonseca 54346e12773219b8a514b6cab7a670777c0fb554b6José Fonsecastatic HMODULE hModule_Imagehlp = NULL; 55346e12773219b8a514b6cab7a670777c0fb554b6José Fonseca 56346e12773219b8a514b6cab7a670777c0fb554b6José Fonsecatypedef BOOL (WINAPI *PFNSYMINITIALIZE)(HANDLE, LPSTR, BOOL); 57346e12773219b8a514b6cab7a670777c0fb554b6José Fonsecastatic PFNSYMINITIALIZE pfnSymInitialize = NULL; 58346e12773219b8a514b6cab7a670777c0fb554b6José Fonseca 59346e12773219b8a514b6cab7a670777c0fb554b6José Fonsecastatic 60346e12773219b8a514b6cab7a670777c0fb554b6José FonsecaBOOL WINAPI j_SymInitialize(HANDLE hProcess, PSTR UserSearchPath, BOOL fInvadeProcess) 61346e12773219b8a514b6cab7a670777c0fb554b6José Fonseca{ 62346e12773219b8a514b6cab7a670777c0fb554b6José Fonseca if( 63346e12773219b8a514b6cab7a670777c0fb554b6José Fonseca (hModule_Imagehlp || (hModule_Imagehlp = LoadLibraryA("IMAGEHLP.DLL"))) && 64346e12773219b8a514b6cab7a670777c0fb554b6José Fonseca (pfnSymInitialize || (pfnSymInitialize = (PFNSYMINITIALIZE) GetProcAddress(hModule_Imagehlp, "SymInitialize"))) 65346e12773219b8a514b6cab7a670777c0fb554b6José Fonseca ) 66346e12773219b8a514b6cab7a670777c0fb554b6José Fonseca return pfnSymInitialize(hProcess, UserSearchPath, fInvadeProcess); 67346e12773219b8a514b6cab7a670777c0fb554b6José Fonseca else 68346e12773219b8a514b6cab7a670777c0fb554b6José Fonseca return FALSE; 69346e12773219b8a514b6cab7a670777c0fb554b6José Fonseca} 70346e12773219b8a514b6cab7a670777c0fb554b6José Fonseca 71346e12773219b8a514b6cab7a670777c0fb554b6José Fonsecatypedef DWORD (WINAPI *PFNSYMSETOPTIONS)(DWORD); 72346e12773219b8a514b6cab7a670777c0fb554b6José Fonsecastatic PFNSYMSETOPTIONS pfnSymSetOptions = NULL; 73346e12773219b8a514b6cab7a670777c0fb554b6José Fonseca 74346e12773219b8a514b6cab7a670777c0fb554b6José Fonsecastatic 75346e12773219b8a514b6cab7a670777c0fb554b6José FonsecaDWORD WINAPI j_SymSetOptions(DWORD SymOptions) 76346e12773219b8a514b6cab7a670777c0fb554b6José Fonseca{ 77346e12773219b8a514b6cab7a670777c0fb554b6José Fonseca if( 78346e12773219b8a514b6cab7a670777c0fb554b6José Fonseca (hModule_Imagehlp || (hModule_Imagehlp = LoadLibraryA("IMAGEHLP.DLL"))) && 79346e12773219b8a514b6cab7a670777c0fb554b6José Fonseca (pfnSymSetOptions || (pfnSymSetOptions = (PFNSYMSETOPTIONS) GetProcAddress(hModule_Imagehlp, "SymSetOptions"))) 80346e12773219b8a514b6cab7a670777c0fb554b6José Fonseca ) 81346e12773219b8a514b6cab7a670777c0fb554b6José Fonseca return pfnSymSetOptions(SymOptions); 82346e12773219b8a514b6cab7a670777c0fb554b6José Fonseca else 83346e12773219b8a514b6cab7a670777c0fb554b6José Fonseca return FALSE; 84346e12773219b8a514b6cab7a670777c0fb554b6José Fonseca} 85346e12773219b8a514b6cab7a670777c0fb554b6José Fonseca 86346e12773219b8a514b6cab7a670777c0fb554b6José Fonsecatypedef PGET_MODULE_BASE_ROUTINE PFNSYMGETMODULEBASE; 87346e12773219b8a514b6cab7a670777c0fb554b6José Fonsecastatic PFNSYMGETMODULEBASE pfnSymGetModuleBase = NULL; 88346e12773219b8a514b6cab7a670777c0fb554b6José Fonseca 89346e12773219b8a514b6cab7a670777c0fb554b6José Fonsecastatic 90346e12773219b8a514b6cab7a670777c0fb554b6José FonsecaDWORD WINAPI j_SymGetModuleBase(HANDLE hProcess, DWORD dwAddr) 91346e12773219b8a514b6cab7a670777c0fb554b6José Fonseca{ 92346e12773219b8a514b6cab7a670777c0fb554b6José Fonseca if( 93346e12773219b8a514b6cab7a670777c0fb554b6José Fonseca (hModule_Imagehlp || (hModule_Imagehlp = LoadLibraryA("IMAGEHLP.DLL"))) && 94346e12773219b8a514b6cab7a670777c0fb554b6José Fonseca (pfnSymGetModuleBase || (pfnSymGetModuleBase = (PFNSYMGETMODULEBASE) GetProcAddress(hModule_Imagehlp, "SymGetModuleBase"))) 95346e12773219b8a514b6cab7a670777c0fb554b6José Fonseca ) 96346e12773219b8a514b6cab7a670777c0fb554b6José Fonseca return pfnSymGetModuleBase(hProcess, dwAddr); 97346e12773219b8a514b6cab7a670777c0fb554b6José Fonseca else 98346e12773219b8a514b6cab7a670777c0fb554b6José Fonseca return 0; 99346e12773219b8a514b6cab7a670777c0fb554b6José Fonseca} 100346e12773219b8a514b6cab7a670777c0fb554b6José Fonseca 101346e12773219b8a514b6cab7a670777c0fb554b6José Fonsecatypedef BOOL (WINAPI *PFNSYMGETSYMFROMADDR)(HANDLE, DWORD, LPDWORD, PIMAGEHLP_SYMBOL); 102346e12773219b8a514b6cab7a670777c0fb554b6José Fonsecastatic PFNSYMGETSYMFROMADDR pfnSymGetSymFromAddr = NULL; 103346e12773219b8a514b6cab7a670777c0fb554b6José Fonseca 104346e12773219b8a514b6cab7a670777c0fb554b6José Fonsecastatic 105346e12773219b8a514b6cab7a670777c0fb554b6José FonsecaBOOL WINAPI j_SymGetSymFromAddr(HANDLE hProcess, DWORD Address, PDWORD Displacement, PIMAGEHLP_SYMBOL Symbol) 106346e12773219b8a514b6cab7a670777c0fb554b6José Fonseca{ 107346e12773219b8a514b6cab7a670777c0fb554b6José Fonseca if( 108346e12773219b8a514b6cab7a670777c0fb554b6José Fonseca (hModule_Imagehlp || (hModule_Imagehlp = LoadLibraryA("IMAGEHLP.DLL"))) && 109346e12773219b8a514b6cab7a670777c0fb554b6José Fonseca (pfnSymGetSymFromAddr || (pfnSymGetSymFromAddr = (PFNSYMGETSYMFROMADDR) GetProcAddress(hModule_Imagehlp, "SymGetSymFromAddr"))) 110346e12773219b8a514b6cab7a670777c0fb554b6José Fonseca ) 111346e12773219b8a514b6cab7a670777c0fb554b6José Fonseca return pfnSymGetSymFromAddr(hProcess, Address, Displacement, Symbol); 112346e12773219b8a514b6cab7a670777c0fb554b6José Fonseca else 113346e12773219b8a514b6cab7a670777c0fb554b6José Fonseca return FALSE; 114346e12773219b8a514b6cab7a670777c0fb554b6José Fonseca} 115346e12773219b8a514b6cab7a670777c0fb554b6José Fonseca 116346e12773219b8a514b6cab7a670777c0fb554b6José Fonseca 11764c4f9c56645768aa3cc4a9a60b266a20acca0c2Luca Barbieristatic INLINE void 11864c4f9c56645768aa3cc4a9a60b266a20acca0c2Luca Barbieridebug_symbol_name_imagehlp(const void *addr, char* buf, unsigned size) 119346e12773219b8a514b6cab7a670777c0fb554b6José Fonseca{ 120346e12773219b8a514b6cab7a670777c0fb554b6José Fonseca HANDLE hProcess; 121346e12773219b8a514b6cab7a670777c0fb554b6José Fonseca BYTE symbolBuffer[1024]; 122346e12773219b8a514b6cab7a670777c0fb554b6José Fonseca PIMAGEHLP_SYMBOL pSymbol = (PIMAGEHLP_SYMBOL) symbolBuffer; 123389021220d27c376b81a6221a31d0ee33c24e67fBrian Paul DWORD dwDisplacement = 0; /* Displacement of the input address, relative to the start of the symbol */ 124346e12773219b8a514b6cab7a670777c0fb554b6José Fonseca 125346e12773219b8a514b6cab7a670777c0fb554b6José Fonseca hProcess = GetCurrentProcess(); 126346e12773219b8a514b6cab7a670777c0fb554b6José Fonseca 127346e12773219b8a514b6cab7a670777c0fb554b6José Fonseca pSymbol->SizeOfStruct = sizeof(symbolBuffer); 128346e12773219b8a514b6cab7a670777c0fb554b6José Fonseca pSymbol->MaxNameLength = sizeof(symbolBuffer) - offsetof(IMAGEHLP_SYMBOL, Name); 129346e12773219b8a514b6cab7a670777c0fb554b6José Fonseca 130346e12773219b8a514b6cab7a670777c0fb554b6José Fonseca if(!bSymInitialized) { 131346e12773219b8a514b6cab7a670777c0fb554b6José Fonseca j_SymSetOptions(/* SYMOPT_UNDNAME | */ SYMOPT_LOAD_LINES); 132346e12773219b8a514b6cab7a670777c0fb554b6José Fonseca if(j_SymInitialize(hProcess, NULL, TRUE)) 133346e12773219b8a514b6cab7a670777c0fb554b6José Fonseca bSymInitialized = TRUE; 134346e12773219b8a514b6cab7a670777c0fb554b6José Fonseca } 135346e12773219b8a514b6cab7a670777c0fb554b6José Fonseca 13664c4f9c56645768aa3cc4a9a60b266a20acca0c2Luca Barbieri if(!j_SymGetSymFromAddr(hProcess, (DWORD)addr, &dwDisplacement, pSymbol)) 13764c4f9c56645768aa3cc4a9a60b266a20acca0c2Luca Barbieri buf[0] = 0; 13864c4f9c56645768aa3cc4a9a60b266a20acca0c2Luca Barbieri else 13964c4f9c56645768aa3cc4a9a60b266a20acca0c2Luca Barbieri { 14064c4f9c56645768aa3cc4a9a60b266a20acca0c2Luca Barbieri strncpy(buf, pSymbol->Name, size); 14164c4f9c56645768aa3cc4a9a60b266a20acca0c2Luca Barbieri buf[size - 1] = 0; 14264c4f9c56645768aa3cc4a9a60b266a20acca0c2Luca Barbieri } 143346e12773219b8a514b6cab7a670777c0fb554b6José Fonseca} 144346e12773219b8a514b6cab7a670777c0fb554b6José Fonseca#endif 145346e12773219b8a514b6cab7a670777c0fb554b6José Fonseca 146346e12773219b8a514b6cab7a670777c0fb554b6José Fonsecavoid 14764c4f9c56645768aa3cc4a9a60b266a20acca0c2Luca Barbieridebug_symbol_name(const void *addr, char* buf, unsigned size) 148346e12773219b8a514b6cab7a670777c0fb554b6José Fonseca{ 1498d72caea3f10a26e4b11a522f4f973ce61f95127José Fonseca#if defined(PIPE_SUBSYSTEM_WINDOWS_USER) && defined(PIPE_ARCH_X86) 15064c4f9c56645768aa3cc4a9a60b266a20acca0c2Luca Barbieri debug_symbol_name_imagehlp(addr, buf, size); 15164c4f9c56645768aa3cc4a9a60b266a20acca0c2Luca Barbieri if(buf[0]) 152346e12773219b8a514b6cab7a670777c0fb554b6José Fonseca return; 153346e12773219b8a514b6cab7a670777c0fb554b6José Fonseca#endif 15464c4f9c56645768aa3cc4a9a60b266a20acca0c2Luca Barbieri 15564c4f9c56645768aa3cc4a9a60b266a20acca0c2Luca Barbieri util_snprintf(buf, size, "%p", addr); 15664c4f9c56645768aa3cc4a9a60b266a20acca0c2Luca Barbieri buf[size - 1] = 0; 15764c4f9c56645768aa3cc4a9a60b266a20acca0c2Luca Barbieri} 15864c4f9c56645768aa3cc4a9a60b266a20acca0c2Luca Barbieri 15964c4f9c56645768aa3cc4a9a60b266a20acca0c2Luca Barbierivoid 16064c4f9c56645768aa3cc4a9a60b266a20acca0c2Luca Barbieridebug_symbol_print(const void *addr) 16164c4f9c56645768aa3cc4a9a60b266a20acca0c2Luca Barbieri{ 16264c4f9c56645768aa3cc4a9a60b266a20acca0c2Luca Barbieri char buf[1024]; 16364c4f9c56645768aa3cc4a9a60b266a20acca0c2Luca Barbieri debug_symbol_name(addr, buf, sizeof(buf)); 16464c4f9c56645768aa3cc4a9a60b266a20acca0c2Luca Barbieri debug_printf("\t%s\n", buf); 165346e12773219b8a514b6cab7a670777c0fb554b6José Fonseca} 166