| 1 | // Licensed to the .NET Foundation under one or more agreements. |
| 2 | // The .NET Foundation licenses this file to you under the MIT license. |
| 3 | // See the LICENSE file in the project root for more information. |
| 4 | // DebugInfoStore |
| 5 | |
| 6 | |
| 7 | |
| 8 | |
| 9 | #ifndef __DebugInfoStore_H_ |
| 10 | #define __DebugInfoStore_H_ |
| 11 | |
| 12 | // Debugging information is described in CorInfo.h |
| 13 | #include "corinfo.h" |
| 14 | |
| 15 | #include "nibblestream.h" |
| 16 | |
| 17 | //----------------------------------------------------------------------------- |
| 18 | // Information to request Debug info. |
| 19 | //----------------------------------------------------------------------------- |
| 20 | class DebugInfoRequest |
| 21 | { |
| 22 | public: |
| 23 | #ifdef _DEBUG |
| 24 | // Must initialize via an Init*() function, not just a ctor. |
| 25 | // In debug, ctor sets fields to values that will cause asserts if not initialized. |
| 26 | DebugInfoRequest() |
| 27 | { |
| 28 | SUPPORTS_DAC; |
| 29 | m_pMD = NULL; |
| 30 | m_addrStart = NULL; |
| 31 | } |
| 32 | #endif |
| 33 | // Eventually we may have many ways to initialize a request. |
| 34 | |
| 35 | // Init given a method desc and starting address for a native code blob. |
| 36 | void InitFromStartingAddr(MethodDesc * pDesc, PCODE addrCode); |
| 37 | |
| 38 | |
| 39 | MethodDesc * GetMD() const { LIMITED_METHOD_DAC_CONTRACT; return m_pMD; } |
| 40 | PCODE GetStartAddress() const { LIMITED_METHOD_DAC_CONTRACT; return m_addrStart; } |
| 41 | |
| 42 | protected: |
| 43 | MethodDesc * m_pMD; |
| 44 | PCODE m_addrStart; |
| 45 | |
| 46 | }; |
| 47 | |
| 48 | //----------------------------------------------------------------------------- |
| 49 | // A Debug-Info Store abstracts the storage of debugging information |
| 50 | //----------------------------------------------------------------------------- |
| 51 | |
| 52 | |
| 53 | // We pass the IDS an allocator which it uses to hand the data back. |
| 54 | // pData is data the allocator may use for 'new'. |
| 55 | // Eg, perhaps we have multiple heaps (eg, loader-heaps per appdomain). |
| 56 | typedef BYTE* (*FP_IDS_NEW)(void * pData, size_t cBytes); |
| 57 | |
| 58 | |
| 59 | //----------------------------------------------------------------------------- |
| 60 | // Utility routines used for compression |
| 61 | // Note that the compression is just an implementation detail of the stores, |
| 62 | // and so these are just utility routines exposed to the stores. |
| 63 | //----------------------------------------------------------------------------- |
| 64 | class CompressDebugInfo |
| 65 | { |
| 66 | public: |
| 67 | // Compress incoming data and write it to the provided NibbleWriter. |
| 68 | static void CompressBoundaries( |
| 69 | IN ULONG32 cMap, |
| 70 | IN ICorDebugInfo::OffsetMapping *pMap, |
| 71 | IN OUT NibbleWriter * pWriter |
| 72 | ); |
| 73 | |
| 74 | static void CompressVars( |
| 75 | IN ULONG32 cVars, |
| 76 | IN ICorDebugInfo::NativeVarInfo *vars, |
| 77 | IN OUT NibbleWriter * pBuffer |
| 78 | ); |
| 79 | |
| 80 | // Stores the result into SBuffer (used by NGen), or in LoaderHeap (used by JIT) |
| 81 | static PTR_BYTE CompressBoundariesAndVars( |
| 82 | IN ICorDebugInfo::OffsetMapping * pOffsetMapping, |
| 83 | IN ULONG iOffsetMapping, |
| 84 | IN ICorDebugInfo::NativeVarInfo * pNativeVarInfo, |
| 85 | IN ULONG iNativeVarInfo, |
| 86 | IN OUT SBuffer * pDebugInfoBuffer, |
| 87 | IN LoaderHeap * pLoaderHeap |
| 88 | ); |
| 89 | |
| 90 | public: |
| 91 | // Uncompress data supplied by Compress functions. |
| 92 | static void RestoreBoundariesAndVars( |
| 93 | IN FP_IDS_NEW fpNew, IN void * pNewData, |
| 94 | IN PTR_BYTE pDebugInfo, |
| 95 | OUT ULONG32 * pcMap, // number of entries in ppMap |
| 96 | OUT ICorDebugInfo::OffsetMapping **ppMap, // pointer to newly allocated array |
| 97 | OUT ULONG32 *pcVars, |
| 98 | OUT ICorDebugInfo::NativeVarInfo **ppVars |
| 99 | ); |
| 100 | |
| 101 | #ifdef DACCESS_COMPILE |
| 102 | static void EnumMemoryRegions(CLRDataEnumMemoryFlags flags, PTR_BYTE pDebugInfo); |
| 103 | #endif |
| 104 | }; |
| 105 | |
| 106 | //----------------------------------------------------------------------------- |
| 107 | // Debug-Info-manager. This is like a process-wide store. |
| 108 | // There should be only 1 instance of this and it's process-wide. |
| 109 | // It will delegate to sub-stores as needed |
| 110 | //----------------------------------------------------------------------------- |
| 111 | class DebugInfoManager |
| 112 | { |
| 113 | public: |
| 114 | static BOOL GetBoundariesAndVars( |
| 115 | const DebugInfoRequest & request, |
| 116 | IN FP_IDS_NEW fpNew, IN void * pNewData, |
| 117 | OUT ULONG32 * pcMap, |
| 118 | OUT ICorDebugInfo::OffsetMapping ** ppMap, |
| 119 | OUT ULONG32 * pcVars, |
| 120 | OUT ICorDebugInfo::NativeVarInfo ** ppVars); |
| 121 | |
| 122 | #ifdef DACCESS_COMPILE |
| 123 | static void EnumMemoryRegionsForMethodDebugInfo(CLRDataEnumMemoryFlags flags, MethodDesc * pMD); |
| 124 | #endif |
| 125 | }; |
| 126 | |
| 127 | |
| 128 | |
| 129 | #endif // __DebugInfoStore_H_ |
| 130 | |