Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

310 lines
6.2 KiB

  1. /*++
  2. Copyright (c) 1996-2000 Microsoft Corporation
  3. Module Name:
  4. symbols.c
  5. Abstract:
  6. Quick and not-so-dirty user-mode dh for heap.
  7. This module contains the functions to map addresses to
  8. symbol names.
  9. Author(s):
  10. Pat Kenny (PKenny) 09-Aug-2000
  11. Silviu Calinoiu (SilviuC) 07-Feb-00
  12. Revision History:
  13. PKenny 09-Aug-2000 Hash optimization code for dh symbol lookup
  14. SilviuC 06-Feb-00 Initial version and steal Pat's code from dh
  15. --*/
  16. #include <ctype.h>
  17. #include <stdlib.h>
  18. #include <stdio.h>
  19. #include <nt.h>
  20. #include <ntrtl.h>
  21. #include <nturtl.h>
  22. #include <ntos.h>
  23. #define NOWINBASEINTERLOCK
  24. #include <windows.h>
  25. #include <lmcons.h>
  26. // #include <imagehlp.h>
  27. #include <dbghelp.h>
  28. #include <heap.h>
  29. #include <heappagi.h>
  30. #include <stktrace.h>
  31. #include "types.h"
  32. #include "symbols.h"
  33. #include "miscellaneous.h"
  34. #include "database.h"
  35. #define MAXDWORD 0xffffffff //this is the max value for a DWORD
  36. //
  37. // the amount of memory to increase the size
  38. // of the buffer for NtQuerySystemInformation at each step
  39. //
  40. #define BUFFER_SIZE_STEP 65536
  41. #define NUM_BUCKETS 4096
  42. struct SymMapNode
  43. {
  44. struct SymMapNode* Next;
  45. DWORD_PTR Address;
  46. PBYTE Symbol;
  47. };
  48. struct SymMapNode* SymMapBuckets[NUM_BUCKETS];
  49. PBYTE FindSymbol( DWORD_PTR Address )
  50. {
  51. DWORD_PTR Bucket = (Address >> 2) % NUM_BUCKETS;
  52. struct SymMapNode* pNode = SymMapBuckets[Bucket];
  53. while( pNode != NULL )
  54. {
  55. if ( pNode->Address == Address )
  56. {
  57. return pNode->Symbol;
  58. }
  59. pNode = pNode->Next;
  60. }
  61. return NULL;
  62. }
  63. void InsertSymbol( PCHAR Symbol, DWORD_PTR Address )
  64. {
  65. DWORD_PTR Bucket = (Address >> 2) % NUM_BUCKETS;
  66. struct SymMapNode* pNew = (struct SymMapNode*) SymbolsHeapAllocate (sizeof (struct SymMapNode));
  67. pNew->Symbol = Symbol;
  68. pNew->Address = Address;
  69. pNew->Next = SymMapBuckets[Bucket];
  70. SymMapBuckets[Bucket] = pNew;
  71. }
  72. PCHAR
  73. GetSymbolicNameForAddress(
  74. IN HANDLE UniqueProcess,
  75. IN ULONG_PTR Address
  76. )
  77. {
  78. IMAGEHLP_MODULE ModuleInfo;
  79. CHAR SymbolBuffer[512];
  80. PIMAGEHLP_SYMBOL Symbol;
  81. ULONG_PTR Offset;
  82. LPSTR Name;
  83. SIZE_T TotalSize;
  84. BOOL Result;
  85. if (Address == (ULONG_PTR)-1) {
  86. return "<< FUZZY STACK TRACE >>";
  87. }
  88. //
  89. // Lookup in map first ..
  90. //
  91. Name = FindSymbol( Address );
  92. if ( Name != NULL ) {
  93. return Name;
  94. }
  95. TotalSize = 0;
  96. ModuleInfo.SizeOfStruct = sizeof(IMAGEHLP_MODULE);
  97. if (SymGetModuleInfo( UniqueProcess, Address, &ModuleInfo )) {
  98. TotalSize += strlen( ModuleInfo.ModuleName );
  99. }
  100. else {
  101. if (Globals.ComplainAboutUnresolvedSymbols) {
  102. Debug (NULL, 0,
  103. "Symbols: cannot identify module for address %p",
  104. Address);
  105. }
  106. return NULL;
  107. }
  108. Symbol = (PIMAGEHLP_SYMBOL)SymbolBuffer;
  109. Symbol->MaxNameLength = 512 - sizeof(IMAGEHLP_SYMBOL) - 1;
  110. if (SymGetSymFromAddr( UniqueProcess, Address, &Offset, Symbol )) {
  111. TotalSize += strlen (Symbol->Name) + 16 + 3;
  112. Name = (LPSTR) SymbolsHeapAllocate (TotalSize);
  113. if (Name == NULL) {
  114. return "<out of memory>";
  115. }
  116. sprintf (Name, "%s!%s+%08X", ModuleInfo.ModuleName, Symbol->Name, Offset);
  117. InsertSymbol( Name, Address );
  118. return Name;
  119. }
  120. else {
  121. if (Globals.ComplainAboutUnresolvedSymbols) {
  122. Debug (NULL, 0,
  123. "Symbols: incorrect symbols for module %s (address %p)",
  124. ModuleInfo.ModuleName,
  125. Address);
  126. }
  127. TotalSize += strlen ("???") + 16 + 5;
  128. Name = (LPSTR) SymbolsHeapAllocate (TotalSize);
  129. if (Name == NULL) {
  130. return "<out of memory>";
  131. }
  132. sprintf (Name, "%s!%s @ %p", ModuleInfo.ModuleName, "???", Address);
  133. InsertSymbol( Name, Address );
  134. return Name;
  135. }
  136. }
  137. BOOL
  138. SymbolsHeapInitialize (
  139. )
  140. {
  141. Globals.SymbolsHeapBase = (PCHAR) VirtualAlloc (NULL,
  142. 0x800000,
  143. MEM_RESERVE | MEM_COMMIT,
  144. PAGE_READWRITE);
  145. if (Globals.SymbolsHeapBase == NULL) {
  146. return FALSE;
  147. }
  148. Globals.SymbolsHeapFree = Globals.SymbolsHeapBase;
  149. Globals.SymbolsHeapLimit = Globals.SymbolsHeapBase + 0x800000;
  150. return TRUE;
  151. }
  152. PVOID
  153. SymbolsHeapAllocate (
  154. SIZE_T Size
  155. )
  156. {
  157. //
  158. // Aligning size is a must on IA64 since otherwise we will get
  159. // alignment exceptions. On x86 it is just a matter of better speed.
  160. //
  161. Size = ((Size + sizeof(ULONG_PTR) - 1) & ~(sizeof(ULONG_PTR) - 1));
  162. if (Globals.SymbolsHeapBase
  163. && (Globals.SymbolsHeapFree + Size < Globals.SymbolsHeapLimit)) {
  164. PVOID Result = (PVOID)(Globals.SymbolsHeapFree);
  165. Globals.SymbolsHeapFree += Size;
  166. return Result;
  167. }
  168. else {
  169. return XALLOC (Size);
  170. }
  171. }
  172. PVOID
  173. SymbolAddress (
  174. IN PCHAR Name
  175. )
  176. /*++
  177. Routine Description:
  178. SymbolAddress
  179. Arguments:
  180. Name - name we wsih to resolve into an address.
  181. Return Value:
  182. Address associated with the name or NULL if an error occurs.
  183. --*/
  184. {
  185. PVOID Address = NULL;
  186. BYTE Buffer [SYMBOL_BUFFER_LEN];
  187. PIMAGEHLP_SYMBOL Symbol;
  188. BOOL Result;
  189. Symbol = (PIMAGEHLP_SYMBOL)(&(Buffer[0]));
  190. Symbol->SizeOfStruct = sizeof (IMAGEHLP_SYMBOL);
  191. Symbol->MaxNameLength = SYMBOL_BUFFER_LEN - sizeof (IMAGEHLP_SYMBOL);
  192. Result = SymGetSymFromName(Globals.Target, Name, Symbol);
  193. if (Result == FALSE) {
  194. Comment ( "SymGetSymFromName (%p, %s, xxx) failed with error %u",
  195. Globals.Target, Name, GetLastError());
  196. Comment (
  197. "Please make sure you have correct symbols for ntdll.dll library");
  198. Address = NULL;
  199. } else {
  200. Address = (PVOID)(Symbol->Address);
  201. }
  202. return Address;
  203. }
  204. BOOL CALLBACK
  205. SymbolDbgHelpCallback (
  206. HANDLE Process,
  207. ULONG ActionCode,
  208. PVOID CallbackData,
  209. PVOID USerContext
  210. )
  211. {
  212. // Comment ("callback call: %p %x ", Process, ActionCode);
  213. if (ActionCode == CBA_DEBUG_INFO) {
  214. Debug (NULL, 0, "%s", CallbackData);
  215. }
  216. return TRUE;
  217. }