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