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 | |
5 | |
6 | /* |
7 | * |
8 | * COM+99 EE to Debugger Interface Implementation |
9 | * |
10 | */ |
11 | #ifndef _eedbginterfaceimpl_h_ |
12 | #define _eedbginterfaceimpl_h_ |
13 | |
14 | #ifdef DEBUGGING_SUPPORTED |
15 | |
16 | #include "common.h" |
17 | #include "corpriv.h" |
18 | #include "hash.h" |
19 | #include "class.h" |
20 | #include "excep.h" |
21 | #include "field.h" |
22 | #include "eetwain.h" |
23 | #include "jitinterface.h" |
24 | #include "stubmgr.h" |
25 | |
26 | #include "eedbginterface.h" |
27 | #include "debugdebugger.h" |
28 | |
29 | #ifdef FEATURE_PREJIT |
30 | #include "corcompile.h" |
31 | #endif // FEATURE_PREJIT |
32 | |
33 | #include "eeconfig.h" |
34 | #include "pefile.h" |
35 | |
36 | class EEDbgInterfaceImpl : public EEDebugInterface |
37 | { |
38 | VPTR_VTABLE_CLASS_AND_CTOR(EEDbgInterfaceImpl, EEDebugInterface); |
39 | |
40 | public: |
41 | |
42 | virtual ~EEDbgInterfaceImpl() {} |
43 | |
44 | #ifndef DACCESS_COMPILE |
45 | |
46 | // |
47 | // Setup and global data used by this interface. |
48 | // |
49 | static FORCEINLINE void Init(void) |
50 | { |
51 | g_pEEDbgInterfaceImpl = new EEDbgInterfaceImpl(); // new throws on failure |
52 | } |
53 | |
54 | // |
55 | // Cleanup any global data used by this interface. |
56 | // |
57 | static void Terminate(void); |
58 | |
59 | #endif // #ifndef DACCESS_COMPILE |
60 | |
61 | Thread* GetThread(void); |
62 | |
63 | StackWalkAction StackWalkFramesEx(Thread* pThread, |
64 | PREGDISPLAY pRD, |
65 | PSTACKWALKFRAMESCALLBACK pCallback, |
66 | VOID* pData, |
67 | unsigned int flags); |
68 | |
69 | Frame *GetFrame(CrawlFrame *pCF); |
70 | |
71 | bool InitRegDisplay(Thread* pThread, |
72 | const PREGDISPLAY pRD, |
73 | const PT_CONTEXT pctx, |
74 | bool validContext); |
75 | |
76 | BOOL IsStringObject(Object* o); |
77 | |
78 | BOOL IsTypedReference(MethodTable* pMT); |
79 | |
80 | WCHAR* StringObjectGetBuffer(StringObject* so); |
81 | |
82 | DWORD StringObjectGetStringLength(StringObject* so); |
83 | |
84 | void* GetObjectFromHandle(OBJECTHANDLE handle); |
85 | |
86 | OBJECTHANDLE GetHandleFromObject(void *obj, |
87 | bool fStrongNewRef, |
88 | AppDomain *pAppDomain); |
89 | |
90 | void DbgDestroyHandle(OBJECTHANDLE oh, |
91 | bool fStrongNewRef); |
92 | |
93 | OBJECTHANDLE GetThreadException(Thread *pThread); |
94 | |
95 | bool IsThreadExceptionNull(Thread *pThread); |
96 | |
97 | void ClearThreadException(Thread *pThread); |
98 | |
99 | bool StartSuspendForDebug(AppDomain *pAppDomain, |
100 | BOOL fHoldingThreadStoreLock); |
101 | |
102 | bool SweepThreadsForDebug(bool forceSync); |
103 | |
104 | void ResumeFromDebug(AppDomain *pAppDomain); |
105 | |
106 | void MarkThreadForDebugSuspend(Thread* pRuntimeThread); |
107 | |
108 | void MarkThreadForDebugStepping(Thread* pRuntimeThread, |
109 | bool onOff); |
110 | |
111 | void SetThreadFilterContext(Thread *thread, |
112 | T_CONTEXT *context); |
113 | |
114 | T_CONTEXT *GetThreadFilterContext(Thread *thread); |
115 | |
116 | #ifdef FEATURE_INTEROP_DEBUGGING |
117 | VOID *GetThreadDebuggerWord(); |
118 | |
119 | VOID SetThreadDebuggerWord(VOID *dw); |
120 | #endif |
121 | |
122 | BOOL IsManagedNativeCode(const BYTE *address); |
123 | |
124 | PCODE GetNativeCodeStartAddress(PCODE address) DAC_UNEXPECTED(); |
125 | |
126 | MethodDesc *GetNativeCodeMethodDesc(const PCODE address) DAC_UNEXPECTED(); |
127 | |
128 | #ifndef USE_GC_INFO_DECODER |
129 | BOOL IsInPrologOrEpilog(const BYTE *address, |
130 | size_t* prologSize); |
131 | #endif |
132 | |
133 | void DetermineIfOffsetsInFilterOrHandler(const BYTE *functionAddress, |
134 | DebugOffsetToHandlerInfo *pOffsetToHandlerInfo, |
135 | unsigned offsetToHandlerInfoLength); |
136 | |
137 | void GetMethodRegionInfo(const PCODE pStart, |
138 | PCODE * pCold, |
139 | size_t *hotSize, |
140 | size_t *coldSize); |
141 | |
142 | #if defined(WIN64EXCEPTIONS) |
143 | DWORD GetFuncletStartOffsets(const BYTE *pStart, DWORD* pStartOffsets, DWORD dwLength); |
144 | StackFrame FindParentStackFrame(CrawlFrame* pCF); |
145 | #endif // WIN64EXCEPTIONS |
146 | |
147 | size_t GetFunctionSize(MethodDesc *pFD) DAC_UNEXPECTED(); |
148 | |
149 | PCODE GetFunctionAddress(MethodDesc *pFD); |
150 | |
151 | void DisablePreemptiveGC(void); |
152 | |
153 | void EnablePreemptiveGC(void); |
154 | |
155 | bool IsPreemptiveGCDisabled(void); |
156 | |
157 | DWORD MethodDescIsStatic(MethodDesc *pFD); |
158 | |
159 | Module *MethodDescGetModule(MethodDesc *pFD); |
160 | |
161 | COR_ILMETHOD* (MethodDesc *pFD); |
162 | |
163 | ULONG MethodDescGetRVA(MethodDesc *pFD); |
164 | |
165 | MethodDesc *FindLoadedMethodRefOrDef(Module* pModule, |
166 | mdToken memberRef); |
167 | |
168 | MethodDesc *LoadMethodDef(Module* pModule, |
169 | mdMethodDef methodDef, |
170 | DWORD numGenericArgs = 0, |
171 | TypeHandle *pGenericArgs = NULL, |
172 | TypeHandle *pOwnerTypeRes = NULL); |
173 | |
174 | TypeHandle FindLoadedClass(Module *pModule, |
175 | mdTypeDef classToken); |
176 | |
177 | TypeHandle FindLoadedInstantiation(Module *pModule, |
178 | mdTypeDef typeDef, |
179 | DWORD numGenericArgs, |
180 | TypeHandle *pGenericArgs); |
181 | |
182 | TypeHandle FindLoadedFnptrType(TypeHandle *inst, |
183 | DWORD ntypars); |
184 | |
185 | TypeHandle FindLoadedPointerOrByrefType(CorElementType et, |
186 | TypeHandle elemtype); |
187 | |
188 | TypeHandle FindLoadedArrayType(CorElementType et, |
189 | TypeHandle elemtype, |
190 | unsigned rank); |
191 | |
192 | TypeHandle FindLoadedElementType(CorElementType et); |
193 | |
194 | TypeHandle LoadClass(Module *pModule, |
195 | mdTypeDef classToken); |
196 | |
197 | TypeHandle LoadInstantiation(Module *pModule, |
198 | mdTypeDef typeDef, |
199 | DWORD numGenericArgs, |
200 | TypeHandle *pGenericArgs); |
201 | |
202 | TypeHandle LoadArrayType(CorElementType et, |
203 | TypeHandle elemtype, |
204 | unsigned rank); |
205 | |
206 | TypeHandle LoadPointerOrByrefType(CorElementType et, |
207 | TypeHandle elemtype); |
208 | |
209 | TypeHandle LoadFnptrType(TypeHandle *inst, |
210 | DWORD ntypars); |
211 | |
212 | TypeHandle LoadElementType(CorElementType et); |
213 | |
214 | __checkReturn |
215 | HRESULT GetMethodImplProps(Module *pModule, |
216 | mdToken tk, |
217 | DWORD *pRVA, |
218 | DWORD *pImplFlags); |
219 | |
220 | HRESULT GetParentToken(Module *pModule, |
221 | mdToken tk, |
222 | mdToken *pParentToken); |
223 | |
224 | void MarkDebuggerAttached(void); |
225 | |
226 | void MarkDebuggerUnattached(void); |
227 | |
228 | #ifdef EnC_SUPPORTED |
229 | |
230 | // Apply an EnC edit to the specified module |
231 | // This function should never return. |
232 | HRESULT EnCApplyChanges(EditAndContinueModule *pModule, |
233 | DWORD cbMetadata, |
234 | BYTE *pMetadata, |
235 | DWORD cbIL, |
236 | BYTE *pIL); |
237 | |
238 | // Remap execution to the latest version of an edited method |
239 | void ResumeInUpdatedFunction(EditAndContinueModule *pModule, |
240 | MethodDesc *pFD, |
241 | void *debuggerFuncHandle, |
242 | SIZE_T resumeIP, |
243 | T_CONTEXT *pContext); |
244 | #endif // EnC_SUPPORTED |
245 | |
246 | bool CrawlFrameIsGcSafe(CrawlFrame *pCF); |
247 | |
248 | bool IsStub(const BYTE *ip); |
249 | |
250 | bool DetectHandleILStubs(Thread *thread); |
251 | |
252 | bool TraceStub(const BYTE *ip, |
253 | TraceDestination *trace); |
254 | |
255 | bool FollowTrace(TraceDestination *trace); |
256 | |
257 | bool TraceFrame(Thread *thread, |
258 | Frame *frame, |
259 | BOOL fromPatch, |
260 | TraceDestination *trace, |
261 | REGDISPLAY *regs); |
262 | |
263 | bool TraceManager(Thread *thread, |
264 | StubManager *stubManager, |
265 | TraceDestination *trace, |
266 | T_CONTEXT *context, |
267 | BYTE **pRetAddr); |
268 | |
269 | void EnableTraceCall(Thread *thread); |
270 | |
271 | void DisableTraceCall(Thread *thread); |
272 | |
273 | void GetRuntimeOffsets(SIZE_T *pTLSIndex, |
274 | SIZE_T *pTLSIsSpecialIndex, |
275 | SIZE_T *pTLSCantStopIndex, |
276 | SIZE_T *pEEThreadStateOffset, |
277 | SIZE_T *pEEThreadStateNCOffset, |
278 | SIZE_T *pEEThreadPGCDisabledOffset, |
279 | DWORD *pEEThreadPGCDisabledValue, |
280 | SIZE_T *pEEThreadFrameOffset, |
281 | SIZE_T *pEEThreadMaxNeededSize, |
282 | DWORD *pEEThreadSteppingStateMask, |
283 | DWORD *pEEMaxFrameValue, |
284 | SIZE_T *pEEThreadDebuggerFilterContextOffset, |
285 | SIZE_T *pEEThreadCantStopOffset, |
286 | SIZE_T *pEEFrameNextOffset, |
287 | DWORD *pEEIsManagedExceptionStateMask); |
288 | |
289 | void DebuggerModifyingLogSwitch (int iNewLevel, |
290 | const WCHAR *pLogSwitchName); |
291 | |
292 | HRESULT SetIPFromSrcToDst(Thread *pThread, |
293 | SLOT addrStart, |
294 | DWORD offFrom, |
295 | DWORD offTo, |
296 | bool fCanSetIPOnly, |
297 | PREGDISPLAY pReg, |
298 | PT_CONTEXT pCtx, |
299 | void *pDji, |
300 | EHRangeTree *pEHRT); |
301 | |
302 | void SetDebugState(Thread *pThread, |
303 | CorDebugThreadState state); |
304 | |
305 | void SetAllDebugState(Thread *et, |
306 | CorDebugThreadState state); |
307 | |
308 | // This is pretty much copied from VM\COMSynchronizable's |
309 | // INT32 __stdcall ThreadNative::GetThreadState, so propogate changes |
310 | // to both functions |
311 | CorDebugUserState GetPartialUserState( Thread *pThread ); |
312 | |
313 | #ifdef FEATURE_PREJIT |
314 | #ifndef DACCESS_COMPILE |
315 | virtual void SetNGENDebugFlags(BOOL fAllowOpt) |
316 | { |
317 | LIMITED_METHOD_CONTRACT; |
318 | PEFile::SetNGENDebugFlags(fAllowOpt); |
319 | } |
320 | |
321 | virtual void GetNGENDebugFlags(BOOL *fAllowOpt) |
322 | { |
323 | LIMITED_METHOD_CONTRACT; |
324 | PEFile::GetNGENDebugFlags(fAllowOpt); |
325 | } |
326 | #endif |
327 | #endif // FEATURE_PREJIT |
328 | |
329 | #ifdef DACCESS_COMPILE |
330 | virtual void EnumMemoryRegions(CLRDataEnumMemoryFlags flags); |
331 | #endif |
332 | |
333 | virtual unsigned GetSizeForCorElementType(CorElementType etyp); |
334 | |
335 | #ifndef DACCESS_COMPILE |
336 | virtual BOOL ObjIsInstanceOf(Object *pElement, TypeHandle toTypeHnd); |
337 | #endif |
338 | |
339 | virtual void ClearAllDebugInterfaceReferences(void); |
340 | |
341 | #ifndef DACCESS_COMPILE |
342 | #ifdef _DEBUG |
343 | virtual void ObjectRefFlush(Thread *pThread); |
344 | #endif |
345 | #endif |
346 | |
347 | #ifndef DACCESS_COMPILE |
348 | virtual BOOL AdjustContextForWriteBarrierForDebugger(CONTEXT* context); |
349 | #endif |
350 | }; |
351 | |
352 | #endif // DEBUGGING_SUPPORTED |
353 | |
354 | #endif // _eedbginterfaceimpl_h_ |
355 | |