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.

295 lines
9.3 KiB

  1. //----------------------------------------------------------------------------
  2. //
  3. // Function entry cache.
  4. //
  5. // Copyright (C) Microsoft Corporation, 2000.
  6. //
  7. //----------------------------------------------------------------------------
  8. #ifndef __FECACHE_HPP__
  9. #define __FECACHE_HPP__
  10. union FeCacheData
  11. {
  12. // 32-bit Alpha entry is only temporary storage;
  13. // cache entries are always converted to 64-bit
  14. // to allow common code.
  15. IMAGE_ALPHA_RUNTIME_FUNCTION_ENTRY Axp32;
  16. IMAGE_ALPHA64_RUNTIME_FUNCTION_ENTRY Axp64;
  17. IMAGE_IA64_RUNTIME_FUNCTION_ENTRY Ia64;
  18. _IMAGE_RUNTIME_FUNCTION_ENTRY Amd64;
  19. UCHAR Data[1];
  20. };
  21. struct FeCacheEntry
  22. {
  23. FeCacheData Data;
  24. // Generic values translated from the raw data.
  25. ULONG RelBegin;
  26. ULONG RelEnd;
  27. ULONG64 Address;
  28. HANDLE Process;
  29. ULONG64 ModuleBase;
  30. #if DBG
  31. PSTR Description;
  32. #endif
  33. };
  34. #if DBG
  35. #define FE_DEBUG(x) if (tlsvar(DebugFunctionEntries)) dbPrint##x
  36. #define FE_ShowRuntimeFunctionIa64(x) ShowRuntimeFunctionIa64##x
  37. #define FE_ShowRuntimeFunctionAxp64(x) ShowRuntimeFunctionAxp64##x
  38. #define FE_SET_DESC(Ent, Desc) ((Ent)->Description = (Desc))
  39. void
  40. ShowRuntimeFunctionEntryIa64(
  41. FeCacheEntry* FunctionEntry,
  42. PSTR Label
  43. );
  44. void
  45. ShowRuntimeFunctionAxp64(
  46. FeCacheEntry* FunctionEntry,
  47. PSTR Label
  48. );
  49. #else
  50. #define FE_DEBUG(x)
  51. #define FE_ShowRuntimeFunctionIa64(x)
  52. #define FE_ShowRuntimeFunctionAxp64(x)
  53. #define FE_SET_DESC(Ent, Desc)
  54. #endif // #if DBG
  55. //----------------------------------------------------------------------------
  56. //
  57. // FunctionEntryCache.
  58. //
  59. //----------------------------------------------------------------------------
  60. class FunctionEntryCache
  61. {
  62. public:
  63. FunctionEntryCache(ULONG ImageDataSize, ULONG CacheDataSize,
  64. ULONG Machine);
  65. ~FunctionEntryCache(void);
  66. BOOL Initialize(ULONG MaxEntries, ULONG ReplaceAt);
  67. FeCacheEntry* Find(
  68. HANDLE Process,
  69. ULONG64 CodeOffset,
  70. PREAD_PROCESS_MEMORY_ROUTINE64 ReadMemory,
  71. PGET_MODULE_BASE_ROUTINE64 GetModuleBase,
  72. PFUNCTION_TABLE_ACCESS_ROUTINE64 GetFunctionEntry
  73. );
  74. FeCacheEntry* FindDirect(
  75. HANDLE Process,
  76. ULONG64 CodeOffset,
  77. PREAD_PROCESS_MEMORY_ROUTINE64 ReadMemory,
  78. PGET_MODULE_BASE_ROUTINE64 GetModuleBase,
  79. PFUNCTION_TABLE_ACCESS_ROUTINE64 GetFunctionEntry
  80. );
  81. FeCacheEntry* ReadImage(
  82. HANDLE Process,
  83. ULONG64 Address,
  84. PREAD_PROCESS_MEMORY_ROUTINE64 ReadMemory,
  85. PGET_MODULE_BASE_ROUTINE64 GetModuleBase
  86. );
  87. void InvalidateProcessOrModule(HANDLE Process, ULONG64 Base);
  88. protected:
  89. // Total number of entries to store.
  90. ULONG m_MaxEntries;
  91. // When the cache is full entries are overwritten starting
  92. // at the replacement point. Cache hits are moved up
  93. // prior to the replacement point so frequently used
  94. // entries stay unmodified in the front of the cache
  95. // and other entries are stored temporarily at the end.
  96. ULONG m_ReplaceAt;
  97. // Size of raw function entry data in the image.
  98. ULONG m_ImageDataSize;
  99. // Size of raw function entry data in the cache.
  100. // This may be different from the image data size if
  101. // the image data is translated into a different form,
  102. // such as Axp32 keeping cache entries in Axp64 form.
  103. ULONG m_CacheDataSize;
  104. // Machine type.
  105. ULONG m_Machine;
  106. FeCacheEntry* m_Entries;
  107. // Number of entries currently used.
  108. ULONG m_Used;
  109. // Index of next slot to fill.
  110. ULONG m_Next;
  111. // Temporary data area for callback-filled data.
  112. FeCacheEntry m_Temporary;
  113. FeCacheEntry* FillTemporary(HANDLE Process, PVOID RawEntry)
  114. {
  115. // No need to translate as this entry is not part of
  116. // the cache that will be searched.
  117. ZeroMemory(&m_Temporary, sizeof(m_Temporary));
  118. memcpy(&m_Temporary.Data, RawEntry, m_CacheDataSize);
  119. m_Temporary.Process = Process;
  120. return &m_Temporary;
  121. }
  122. virtual void TranslateRawData(FeCacheEntry* Entry) = 0;
  123. virtual void TranslateRvaDataToRawData(PIMGHLP_RVA_FUNCTION_DATA RvaData,
  124. ULONG64 ModuleBase,
  125. FeCacheData* Data) = 0;
  126. // Base implementation just returns the given entry.
  127. virtual FeCacheEntry* SearchForPrimaryEntry(
  128. FeCacheEntry* CacheEntry,
  129. HANDLE Process,
  130. PREAD_PROCESS_MEMORY_ROUTINE64 ReadMemory,
  131. PGET_MODULE_BASE_ROUTINE64 GetModuleBase,
  132. PFUNCTION_TABLE_ACCESS_ROUTINE64 GetFunctionEntry
  133. );
  134. FeCacheEntry* FindStatic(
  135. HANDLE Process,
  136. ULONG64 CodeOffset,
  137. PREAD_PROCESS_MEMORY_ROUTINE64 ReadMemory,
  138. PGET_MODULE_BASE_ROUTINE64 GetModuleBase,
  139. PFUNCTION_TABLE_ACCESS_ROUTINE64 GetFunctionEntry,
  140. PULONG64 ModuleBase
  141. );
  142. FeCacheEntry* Promote(FeCacheEntry* Entry);
  143. ULONG64 FunctionTableBase(
  144. HANDLE Process,
  145. PREAD_PROCESS_MEMORY_ROUTINE64 ReadMemory,
  146. ULONG64 Base,
  147. PULONG Size
  148. );
  149. };
  150. //----------------------------------------------------------------------------
  151. //
  152. // Ia64FunctionEntryCache.
  153. //
  154. //----------------------------------------------------------------------------
  155. class Ia64FunctionEntryCache : public FunctionEntryCache
  156. {
  157. public:
  158. Ia64FunctionEntryCache(void) :
  159. FunctionEntryCache(sizeof(IMAGE_IA64_RUNTIME_FUNCTION_ENTRY),
  160. sizeof(IMAGE_IA64_RUNTIME_FUNCTION_ENTRY),
  161. IMAGE_FILE_MACHINE_IA64)
  162. {
  163. }
  164. protected:
  165. virtual void TranslateRawData(FeCacheEntry* Entry);
  166. virtual void TranslateRvaDataToRawData(PIMGHLP_RVA_FUNCTION_DATA RvaData,
  167. ULONG64 ModuleBase,
  168. FeCacheData* Data);
  169. };
  170. //----------------------------------------------------------------------------
  171. //
  172. // Amd64FunctionEntryCache.
  173. //
  174. //----------------------------------------------------------------------------
  175. class Amd64FunctionEntryCache : public FunctionEntryCache
  176. {
  177. public:
  178. Amd64FunctionEntryCache(void) :
  179. FunctionEntryCache(sizeof(_IMAGE_RUNTIME_FUNCTION_ENTRY),
  180. sizeof(_IMAGE_RUNTIME_FUNCTION_ENTRY),
  181. IMAGE_FILE_MACHINE_AMD64)
  182. {
  183. }
  184. protected:
  185. virtual void TranslateRawData(FeCacheEntry* Entry);
  186. virtual void TranslateRvaDataToRawData(PIMGHLP_RVA_FUNCTION_DATA RvaData,
  187. ULONG64 ModuleBase,
  188. FeCacheData* Data);
  189. };
  190. //----------------------------------------------------------------------------
  191. //
  192. // AlphaFunctionEntryCache.
  193. //
  194. //----------------------------------------------------------------------------
  195. class AlphaFunctionEntryCache : public FunctionEntryCache
  196. {
  197. public:
  198. AlphaFunctionEntryCache(ULONG ImageDataSize, ULONG CacheDataSize,
  199. ULONG Machine) :
  200. FunctionEntryCache(ImageDataSize, CacheDataSize, Machine)
  201. {
  202. }
  203. protected:
  204. virtual void TranslateRvaDataToRawData(PIMGHLP_RVA_FUNCTION_DATA RvaData,
  205. ULONG64 ModuleBase,
  206. FeCacheData* Data);
  207. virtual FeCacheEntry* SearchForPrimaryEntry(
  208. FeCacheEntry* CacheEntry,
  209. HANDLE Process,
  210. PREAD_PROCESS_MEMORY_ROUTINE64 ReadMemory,
  211. PGET_MODULE_BASE_ROUTINE64 GetModuleBase,
  212. PFUNCTION_TABLE_ACCESS_ROUTINE64 GetFunctionEntry
  213. );
  214. };
  215. //----------------------------------------------------------------------------
  216. //
  217. // Axp32FunctionEntryCache.
  218. //
  219. //----------------------------------------------------------------------------
  220. class Axp32FunctionEntryCache : public AlphaFunctionEntryCache
  221. {
  222. public:
  223. Axp32FunctionEntryCache(void) :
  224. AlphaFunctionEntryCache(sizeof(IMAGE_ALPHA_RUNTIME_FUNCTION_ENTRY),
  225. sizeof(IMAGE_ALPHA64_RUNTIME_FUNCTION_ENTRY),
  226. IMAGE_FILE_MACHINE_ALPHA)
  227. {
  228. }
  229. protected:
  230. virtual void TranslateRawData(FeCacheEntry* Entry);
  231. };
  232. //----------------------------------------------------------------------------
  233. //
  234. // Axp64FunctionEntryCache.
  235. //
  236. //----------------------------------------------------------------------------
  237. class Axp64FunctionEntryCache : public AlphaFunctionEntryCache
  238. {
  239. public:
  240. Axp64FunctionEntryCache(void) :
  241. AlphaFunctionEntryCache(sizeof(IMAGE_ALPHA64_RUNTIME_FUNCTION_ENTRY),
  242. sizeof(IMAGE_ALPHA64_RUNTIME_FUNCTION_ENTRY),
  243. IMAGE_FILE_MACHINE_ALPHA64)
  244. {
  245. }
  246. protected:
  247. virtual void TranslateRawData(FeCacheEntry* Entry);
  248. };
  249. //----------------------------------------------------------------------------
  250. //
  251. // Functions.
  252. //
  253. //----------------------------------------------------------------------------
  254. FunctionEntryCache* GetFeCache(ULONG Machine, BOOL Create);
  255. void ClearFeCaches(void);
  256. #endif // #ifndef __FECACHE_HPP__