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"
3640eef4c20cc0b4500a0d8c8538872ed4b473d737Luca Barbieri#include "os/os_thread.h"
3764c4f9c56645768aa3cc4a9a60b266a20acca0c2Luca Barbieri#include "u_string.h"
38346e12773219b8a514b6cab7a670777c0fb554b6José Fonseca
39346e12773219b8a514b6cab7a670777c0fb554b6José Fonseca#include "u_debug.h"
40346e12773219b8a514b6cab7a670777c0fb554b6José Fonseca#include "u_debug_symbol.h"
4140eef4c20cc0b4500a0d8c8538872ed4b473d737Luca Barbieri#include "u_hash_table.h"
42346e12773219b8a514b6cab7a670777c0fb554b6José Fonseca
436c1fcf85838a4aa76bcb9f9ceb312f1772f1122eJosé Fonseca#if defined(PIPE_OS_WINDOWS) && defined(PIPE_ARCH_X86)
44346e12773219b8a514b6cab7a670777c0fb554b6José Fonseca
45346e12773219b8a514b6cab7a670777c0fb554b6José Fonseca#include <windows.h>
46346e12773219b8a514b6cab7a670777c0fb554b6José Fonseca#include <stddef.h>
47346e12773219b8a514b6cab7a670777c0fb554b6José Fonseca
486c1fcf85838a4aa76bcb9f9ceb312f1772f1122eJosé Fonseca#include "dbghelp.h"
496c1fcf85838a4aa76bcb9f9ceb312f1772f1122eJosé Fonseca
50346e12773219b8a514b6cab7a670777c0fb554b6José Fonseca
51346e12773219b8a514b6cab7a670777c0fb554b6José Fonsecastatic BOOL bSymInitialized = FALSE;
52346e12773219b8a514b6cab7a670777c0fb554b6José Fonseca
536c1fcf85838a4aa76bcb9f9ceb312f1772f1122eJosé Fonsecastatic HMODULE hModule_Dbghelp = NULL;
546c1fcf85838a4aa76bcb9f9ceb312f1772f1122eJosé Fonseca
556c1fcf85838a4aa76bcb9f9ceb312f1772f1122eJosé Fonseca
566c1fcf85838a4aa76bcb9f9ceb312f1772f1122eJosé Fonsecastatic
576c1fcf85838a4aa76bcb9f9ceb312f1772f1122eJosé FonsecaFARPROC WINAPI __GetProcAddress(LPCSTR lpProcName)
586c1fcf85838a4aa76bcb9f9ceb312f1772f1122eJosé Fonseca{
596c1fcf85838a4aa76bcb9f9ceb312f1772f1122eJosé Fonseca#ifdef PIPE_CC_GCC
606c1fcf85838a4aa76bcb9f9ceb312f1772f1122eJosé Fonseca   if (!hModule_Dbghelp) {
616c1fcf85838a4aa76bcb9f9ceb312f1772f1122eJosé Fonseca      /*
626c1fcf85838a4aa76bcb9f9ceb312f1772f1122eJosé Fonseca       * bfdhelp.dll is a dbghelp.dll look-alike replacement, which is able to
636c1fcf85838a4aa76bcb9f9ceb312f1772f1122eJosé Fonseca       * understand MinGW symbols using BFD library.  It is available from
646c1fcf85838a4aa76bcb9f9ceb312f1772f1122eJosé Fonseca       * http://people.freedesktop.org/~jrfonseca/bfdhelp/ for now.
656c1fcf85838a4aa76bcb9f9ceb312f1772f1122eJosé Fonseca       */
666c1fcf85838a4aa76bcb9f9ceb312f1772f1122eJosé Fonseca      hModule_Dbghelp = LoadLibraryA("bfdhelp.dll");
676c1fcf85838a4aa76bcb9f9ceb312f1772f1122eJosé Fonseca   }
686c1fcf85838a4aa76bcb9f9ceb312f1772f1122eJosé Fonseca#endif
696c1fcf85838a4aa76bcb9f9ceb312f1772f1122eJosé Fonseca
706c1fcf85838a4aa76bcb9f9ceb312f1772f1122eJosé Fonseca   if (!hModule_Dbghelp) {
716c1fcf85838a4aa76bcb9f9ceb312f1772f1122eJosé Fonseca      hModule_Dbghelp = LoadLibraryA("dbghelp.dll");
726c1fcf85838a4aa76bcb9f9ceb312f1772f1122eJosé Fonseca      if (!hModule_Dbghelp) {
736c1fcf85838a4aa76bcb9f9ceb312f1772f1122eJosé Fonseca         return NULL;
746c1fcf85838a4aa76bcb9f9ceb312f1772f1122eJosé Fonseca      }
756c1fcf85838a4aa76bcb9f9ceb312f1772f1122eJosé Fonseca   }
766c1fcf85838a4aa76bcb9f9ceb312f1772f1122eJosé Fonseca
776c1fcf85838a4aa76bcb9f9ceb312f1772f1122eJosé Fonseca   return GetProcAddress(hModule_Dbghelp, lpProcName);
786c1fcf85838a4aa76bcb9f9ceb312f1772f1122eJosé Fonseca}
796c1fcf85838a4aa76bcb9f9ceb312f1772f1122eJosé Fonseca
80346e12773219b8a514b6cab7a670777c0fb554b6José Fonseca
81346e12773219b8a514b6cab7a670777c0fb554b6José Fonsecatypedef BOOL (WINAPI *PFNSYMINITIALIZE)(HANDLE, LPSTR, BOOL);
82346e12773219b8a514b6cab7a670777c0fb554b6José Fonsecastatic PFNSYMINITIALIZE pfnSymInitialize = NULL;
83346e12773219b8a514b6cab7a670777c0fb554b6José Fonseca
84346e12773219b8a514b6cab7a670777c0fb554b6José Fonsecastatic
85346e12773219b8a514b6cab7a670777c0fb554b6José FonsecaBOOL WINAPI j_SymInitialize(HANDLE hProcess, PSTR UserSearchPath, BOOL fInvadeProcess)
86346e12773219b8a514b6cab7a670777c0fb554b6José Fonseca{
87346e12773219b8a514b6cab7a670777c0fb554b6José Fonseca   if(
886c1fcf85838a4aa76bcb9f9ceb312f1772f1122eJosé Fonseca      (pfnSymInitialize || (pfnSymInitialize = (PFNSYMINITIALIZE) __GetProcAddress("SymInitialize")))
89346e12773219b8a514b6cab7a670777c0fb554b6José Fonseca   )
90346e12773219b8a514b6cab7a670777c0fb554b6José Fonseca      return pfnSymInitialize(hProcess, UserSearchPath, fInvadeProcess);
91346e12773219b8a514b6cab7a670777c0fb554b6José Fonseca   else
92346e12773219b8a514b6cab7a670777c0fb554b6José Fonseca      return FALSE;
93346e12773219b8a514b6cab7a670777c0fb554b6José Fonseca}
94346e12773219b8a514b6cab7a670777c0fb554b6José Fonseca
95346e12773219b8a514b6cab7a670777c0fb554b6José Fonsecatypedef DWORD (WINAPI *PFNSYMSETOPTIONS)(DWORD);
96346e12773219b8a514b6cab7a670777c0fb554b6José Fonsecastatic PFNSYMSETOPTIONS pfnSymSetOptions = NULL;
97346e12773219b8a514b6cab7a670777c0fb554b6José Fonseca
98346e12773219b8a514b6cab7a670777c0fb554b6José Fonsecastatic
99346e12773219b8a514b6cab7a670777c0fb554b6José FonsecaDWORD WINAPI j_SymSetOptions(DWORD SymOptions)
100346e12773219b8a514b6cab7a670777c0fb554b6José Fonseca{
101346e12773219b8a514b6cab7a670777c0fb554b6José Fonseca   if(
1026c1fcf85838a4aa76bcb9f9ceb312f1772f1122eJosé Fonseca      (pfnSymSetOptions || (pfnSymSetOptions = (PFNSYMSETOPTIONS) __GetProcAddress("SymSetOptions")))
103346e12773219b8a514b6cab7a670777c0fb554b6José Fonseca   )
104346e12773219b8a514b6cab7a670777c0fb554b6José Fonseca      return pfnSymSetOptions(SymOptions);
105346e12773219b8a514b6cab7a670777c0fb554b6José Fonseca   else
106346e12773219b8a514b6cab7a670777c0fb554b6José Fonseca      return FALSE;
107346e12773219b8a514b6cab7a670777c0fb554b6José Fonseca}
108346e12773219b8a514b6cab7a670777c0fb554b6José Fonseca
1096c1fcf85838a4aa76bcb9f9ceb312f1772f1122eJosé Fonsecatypedef BOOL (WINAPI *PFNSYMGETSYMFROMADDR)(HANDLE, DWORD64, PDWORD64, PSYMBOL_INFO);
1106c1fcf85838a4aa76bcb9f9ceb312f1772f1122eJosé Fonsecastatic PFNSYMGETSYMFROMADDR pfnSymFromAddr = NULL;
111346e12773219b8a514b6cab7a670777c0fb554b6José Fonseca
112346e12773219b8a514b6cab7a670777c0fb554b6José Fonsecastatic
1136c1fcf85838a4aa76bcb9f9ceb312f1772f1122eJosé FonsecaBOOL WINAPI j_SymFromAddr(HANDLE hProcess, DWORD64 Address, PDWORD64 Displacement, PSYMBOL_INFO Symbol)
114346e12773219b8a514b6cab7a670777c0fb554b6José Fonseca{
115346e12773219b8a514b6cab7a670777c0fb554b6José Fonseca   if(
1166c1fcf85838a4aa76bcb9f9ceb312f1772f1122eJosé Fonseca      (pfnSymFromAddr || (pfnSymFromAddr = (PFNSYMGETSYMFROMADDR) __GetProcAddress("SymFromAddr")))
117346e12773219b8a514b6cab7a670777c0fb554b6José Fonseca   )
1186c1fcf85838a4aa76bcb9f9ceb312f1772f1122eJosé Fonseca      return pfnSymFromAddr(hProcess, Address, Displacement, Symbol);
119346e12773219b8a514b6cab7a670777c0fb554b6José Fonseca   else
120346e12773219b8a514b6cab7a670777c0fb554b6José Fonseca      return FALSE;
121346e12773219b8a514b6cab7a670777c0fb554b6José Fonseca}
122346e12773219b8a514b6cab7a670777c0fb554b6José Fonseca
123346e12773219b8a514b6cab7a670777c0fb554b6José Fonseca
12464c4f9c56645768aa3cc4a9a60b266a20acca0c2Luca Barbieristatic INLINE void
1256c1fcf85838a4aa76bcb9f9ceb312f1772f1122eJosé Fonsecadebug_symbol_name_dbghelp(const void *addr, char* buf, unsigned size)
126346e12773219b8a514b6cab7a670777c0fb554b6José Fonseca{
127346e12773219b8a514b6cab7a670777c0fb554b6José Fonseca   HANDLE hProcess;
128346e12773219b8a514b6cab7a670777c0fb554b6José Fonseca   BYTE symbolBuffer[1024];
1296c1fcf85838a4aa76bcb9f9ceb312f1772f1122eJosé Fonseca   PSYMBOL_INFO pSymbol = (PSYMBOL_INFO) symbolBuffer;
1306c1fcf85838a4aa76bcb9f9ceb312f1772f1122eJosé Fonseca   DWORD64 dwDisplacement = 0;  /* Displacement of the input address, relative to the start of the symbol */
131346e12773219b8a514b6cab7a670777c0fb554b6José Fonseca
132346e12773219b8a514b6cab7a670777c0fb554b6José Fonseca   hProcess = GetCurrentProcess();
133346e12773219b8a514b6cab7a670777c0fb554b6José Fonseca
1346c1fcf85838a4aa76bcb9f9ceb312f1772f1122eJosé Fonseca   memset(pSymbol, 0, sizeof *pSymbol);
135346e12773219b8a514b6cab7a670777c0fb554b6José Fonseca   pSymbol->SizeOfStruct = sizeof(symbolBuffer);
1366c1fcf85838a4aa76bcb9f9ceb312f1772f1122eJosé Fonseca   pSymbol->MaxNameLen = sizeof(symbolBuffer) - offsetof(SYMBOL_INFO, Name);
137346e12773219b8a514b6cab7a670777c0fb554b6José Fonseca
138346e12773219b8a514b6cab7a670777c0fb554b6José Fonseca   if(!bSymInitialized) {
139346e12773219b8a514b6cab7a670777c0fb554b6José Fonseca      j_SymSetOptions(/* SYMOPT_UNDNAME | */ SYMOPT_LOAD_LINES);
140346e12773219b8a514b6cab7a670777c0fb554b6José Fonseca      if(j_SymInitialize(hProcess, NULL, TRUE))
141346e12773219b8a514b6cab7a670777c0fb554b6José Fonseca         bSymInitialized = TRUE;
142346e12773219b8a514b6cab7a670777c0fb554b6José Fonseca   }
143346e12773219b8a514b6cab7a670777c0fb554b6José Fonseca
1446c1fcf85838a4aa76bcb9f9ceb312f1772f1122eJosé Fonseca   if(!j_SymFromAddr(hProcess, (DWORD64)(uintptr_t)addr, &dwDisplacement, pSymbol))
14564c4f9c56645768aa3cc4a9a60b266a20acca0c2Luca Barbieri      buf[0] = 0;
14664c4f9c56645768aa3cc4a9a60b266a20acca0c2Luca Barbieri   else
14764c4f9c56645768aa3cc4a9a60b266a20acca0c2Luca Barbieri   {
14864c4f9c56645768aa3cc4a9a60b266a20acca0c2Luca Barbieri      strncpy(buf, pSymbol->Name, size);
14964c4f9c56645768aa3cc4a9a60b266a20acca0c2Luca Barbieri      buf[size - 1] = 0;
15064c4f9c56645768aa3cc4a9a60b266a20acca0c2Luca Barbieri   }
151346e12773219b8a514b6cab7a670777c0fb554b6José Fonseca}
152346e12773219b8a514b6cab7a670777c0fb554b6José Fonseca#endif
153346e12773219b8a514b6cab7a670777c0fb554b6José Fonseca
154b3e57fc8685af44dcf35a7f429b7410e63a9a571Luca Barbieri#ifdef __GLIBC__
155f35e380dd240b418e17a179af73bbab74ceea784Anthony G. Basile#ifndef __UCLIBC__
156b3e57fc8685af44dcf35a7f429b7410e63a9a571Luca Barbieri#include <execinfo.h>
157f35e380dd240b418e17a179af73bbab74ceea784Anthony G. Basile#endif
158b3e57fc8685af44dcf35a7f429b7410e63a9a571Luca Barbieri
159b3e57fc8685af44dcf35a7f429b7410e63a9a571Luca Barbieri/* This can only provide dynamic symbols, or binary offsets into a file.
160b3e57fc8685af44dcf35a7f429b7410e63a9a571Luca Barbieri *
161b3e57fc8685af44dcf35a7f429b7410e63a9a571Luca Barbieri * To fix this, post-process the output with tools/addr2line.sh
162b3e57fc8685af44dcf35a7f429b7410e63a9a571Luca Barbieri */
163b3e57fc8685af44dcf35a7f429b7410e63a9a571Luca Barbieristatic INLINE void
164b3e57fc8685af44dcf35a7f429b7410e63a9a571Luca Barbieridebug_symbol_name_glibc(const void *addr, char* buf, unsigned size)
165b3e57fc8685af44dcf35a7f429b7410e63a9a571Luca Barbieri{
166b3e57fc8685af44dcf35a7f429b7410e63a9a571Luca Barbieri   char** syms = backtrace_symbols((void**)&addr, 1);
167b3e57fc8685af44dcf35a7f429b7410e63a9a571Luca Barbieri   strncpy(buf, syms[0], size);
168b3e57fc8685af44dcf35a7f429b7410e63a9a571Luca Barbieri   buf[size - 1] = 0;
169b3e57fc8685af44dcf35a7f429b7410e63a9a571Luca Barbieri   free(syms);
170b3e57fc8685af44dcf35a7f429b7410e63a9a571Luca Barbieri}
171b3e57fc8685af44dcf35a7f429b7410e63a9a571Luca Barbieri#endif
172b3e57fc8685af44dcf35a7f429b7410e63a9a571Luca Barbieri
173346e12773219b8a514b6cab7a670777c0fb554b6José Fonsecavoid
17464c4f9c56645768aa3cc4a9a60b266a20acca0c2Luca Barbieridebug_symbol_name(const void *addr, char* buf, unsigned size)
175346e12773219b8a514b6cab7a670777c0fb554b6José Fonseca{
1766c1fcf85838a4aa76bcb9f9ceb312f1772f1122eJosé Fonseca#if defined(PIPE_OS_WINDOWS) && defined(PIPE_ARCH_X86)
1776c1fcf85838a4aa76bcb9f9ceb312f1772f1122eJosé Fonseca   debug_symbol_name_dbghelp(addr, buf, size);
17864c4f9c56645768aa3cc4a9a60b266a20acca0c2Luca Barbieri   if(buf[0])
179346e12773219b8a514b6cab7a670777c0fb554b6José Fonseca      return;
180346e12773219b8a514b6cab7a670777c0fb554b6José Fonseca#endif
18164c4f9c56645768aa3cc4a9a60b266a20acca0c2Luca Barbieri
182b3e57fc8685af44dcf35a7f429b7410e63a9a571Luca Barbieri#ifdef __GLIBC__
183b3e57fc8685af44dcf35a7f429b7410e63a9a571Luca Barbieri   debug_symbol_name_glibc(addr, buf, size);
184b3e57fc8685af44dcf35a7f429b7410e63a9a571Luca Barbieri   if(buf[0])
185b3e57fc8685af44dcf35a7f429b7410e63a9a571Luca Barbieri      return;
186b3e57fc8685af44dcf35a7f429b7410e63a9a571Luca Barbieri#endif
187b3e57fc8685af44dcf35a7f429b7410e63a9a571Luca Barbieri
18864c4f9c56645768aa3cc4a9a60b266a20acca0c2Luca Barbieri   util_snprintf(buf, size, "%p", addr);
18964c4f9c56645768aa3cc4a9a60b266a20acca0c2Luca Barbieri   buf[size - 1] = 0;
19064c4f9c56645768aa3cc4a9a60b266a20acca0c2Luca Barbieri}
19164c4f9c56645768aa3cc4a9a60b266a20acca0c2Luca Barbieri
19264c4f9c56645768aa3cc4a9a60b266a20acca0c2Luca Barbierivoid
19364c4f9c56645768aa3cc4a9a60b266a20acca0c2Luca Barbieridebug_symbol_print(const void *addr)
19464c4f9c56645768aa3cc4a9a60b266a20acca0c2Luca Barbieri{
19564c4f9c56645768aa3cc4a9a60b266a20acca0c2Luca Barbieri   char buf[1024];
19664c4f9c56645768aa3cc4a9a60b266a20acca0c2Luca Barbieri   debug_symbol_name(addr, buf, sizeof(buf));
19764c4f9c56645768aa3cc4a9a60b266a20acca0c2Luca Barbieri   debug_printf("\t%s\n", buf);
198346e12773219b8a514b6cab7a670777c0fb554b6José Fonseca}
19940eef4c20cc0b4500a0d8c8538872ed4b473d737Luca Barbieri
20040eef4c20cc0b4500a0d8c8538872ed4b473d737Luca Barbieristruct util_hash_table* symbols_hash;
20152ad45677dd3d8a50836edea9f5841aa12d70419Jakob Bornecrantzpipe_static_mutex(symbols_mutex);
20240eef4c20cc0b4500a0d8c8538872ed4b473d737Luca Barbieri
20340eef4c20cc0b4500a0d8c8538872ed4b473d737Luca Barbieristatic unsigned hash_ptr(void* p)
20440eef4c20cc0b4500a0d8c8538872ed4b473d737Luca Barbieri{
20540eef4c20cc0b4500a0d8c8538872ed4b473d737Luca Barbieri   return (unsigned)(uintptr_t)p;
20640eef4c20cc0b4500a0d8c8538872ed4b473d737Luca Barbieri}
20740eef4c20cc0b4500a0d8c8538872ed4b473d737Luca Barbieri
20840eef4c20cc0b4500a0d8c8538872ed4b473d737Luca Barbieristatic int compare_ptr(void* a, void* b)
20940eef4c20cc0b4500a0d8c8538872ed4b473d737Luca Barbieri{
21040eef4c20cc0b4500a0d8c8538872ed4b473d737Luca Barbieri   if(a == b)
21140eef4c20cc0b4500a0d8c8538872ed4b473d737Luca Barbieri      return 0;
21240eef4c20cc0b4500a0d8c8538872ed4b473d737Luca Barbieri   else if(a < b)
21340eef4c20cc0b4500a0d8c8538872ed4b473d737Luca Barbieri      return -1;
21440eef4c20cc0b4500a0d8c8538872ed4b473d737Luca Barbieri   else
21540eef4c20cc0b4500a0d8c8538872ed4b473d737Luca Barbieri      return 1;
21640eef4c20cc0b4500a0d8c8538872ed4b473d737Luca Barbieri}
21740eef4c20cc0b4500a0d8c8538872ed4b473d737Luca Barbieri
21840eef4c20cc0b4500a0d8c8538872ed4b473d737Luca Barbiericonst char*
21940eef4c20cc0b4500a0d8c8538872ed4b473d737Luca Barbieridebug_symbol_name_cached(const void *addr)
22040eef4c20cc0b4500a0d8c8538872ed4b473d737Luca Barbieri{
22140eef4c20cc0b4500a0d8c8538872ed4b473d737Luca Barbieri   const char* name;
22252ad45677dd3d8a50836edea9f5841aa12d70419Jakob Bornecrantz#ifdef PIPE_SUBSYSTEM_WINDOWS_USER
22352ad45677dd3d8a50836edea9f5841aa12d70419Jakob Bornecrantz   static boolean first = TRUE;
22452ad45677dd3d8a50836edea9f5841aa12d70419Jakob Bornecrantz
22552ad45677dd3d8a50836edea9f5841aa12d70419Jakob Bornecrantz   if (first) {
22652ad45677dd3d8a50836edea9f5841aa12d70419Jakob Bornecrantz      pipe_mutex_init(symbols_mutex);
22752ad45677dd3d8a50836edea9f5841aa12d70419Jakob Bornecrantz      first = FALSE;
22852ad45677dd3d8a50836edea9f5841aa12d70419Jakob Bornecrantz   }
22952ad45677dd3d8a50836edea9f5841aa12d70419Jakob Bornecrantz#endif
23052ad45677dd3d8a50836edea9f5841aa12d70419Jakob Bornecrantz
23140eef4c20cc0b4500a0d8c8538872ed4b473d737Luca Barbieri   pipe_mutex_lock(symbols_mutex);
23240eef4c20cc0b4500a0d8c8538872ed4b473d737Luca Barbieri   if(!symbols_hash)
23340eef4c20cc0b4500a0d8c8538872ed4b473d737Luca Barbieri      symbols_hash = util_hash_table_create(hash_ptr, compare_ptr);
23440eef4c20cc0b4500a0d8c8538872ed4b473d737Luca Barbieri   name = util_hash_table_get(symbols_hash, (void*)addr);
23540eef4c20cc0b4500a0d8c8538872ed4b473d737Luca Barbieri   if(!name)
23640eef4c20cc0b4500a0d8c8538872ed4b473d737Luca Barbieri   {
23740eef4c20cc0b4500a0d8c8538872ed4b473d737Luca Barbieri      char buf[1024];
23840eef4c20cc0b4500a0d8c8538872ed4b473d737Luca Barbieri      debug_symbol_name(addr, buf, sizeof(buf));
23940eef4c20cc0b4500a0d8c8538872ed4b473d737Luca Barbieri      name = strdup(buf);
24040eef4c20cc0b4500a0d8c8538872ed4b473d737Luca Barbieri
24140eef4c20cc0b4500a0d8c8538872ed4b473d737Luca Barbieri      util_hash_table_set(symbols_hash, (void*)addr, (void*)name);
24240eef4c20cc0b4500a0d8c8538872ed4b473d737Luca Barbieri   }
24340eef4c20cc0b4500a0d8c8538872ed4b473d737Luca Barbieri   pipe_mutex_unlock(symbols_mutex);
24440eef4c20cc0b4500a0d8c8538872ed4b473d737Luca Barbieri   return name;
24540eef4c20cc0b4500a0d8c8538872ed4b473d737Luca Barbieri}
246