[x86/Linux] Fix SIGSEGV during evaluation abort routine.
[platform/upstream/coreclr.git] / src / debug / ee / debugger.inl
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 // File: debugger.inl
6 // 
7
8 //
9 // Inline definitions for the Left-Side of the CLR debugging services
10 // This is logically part of the header file. 
11 //
12 //*****************************************************************************
13
14 #ifndef DEBUGGER_INL_
15 #define DEBUGGER_INL_
16
17 //=============================================================================
18 // Inlined methods for Debugger.
19 //=============================================================================
20 inline bool Debugger::HasLazyData()
21 {
22     LIMITED_METHOD_CONTRACT;
23     return (m_pLazyData != NULL);
24 }
25 inline RCThreadLazyInit *Debugger::GetRCThreadLazyData()
26 {
27     LIMITED_METHOD_CONTRACT;
28     return &(GetLazyData()->m_RCThread);
29 }
30
31 inline DebuggerLazyInit *Debugger::GetLazyData() 
32
33     LIMITED_METHOD_DAC_CONTRACT;
34     _ASSERTE(m_pLazyData != NULL); 
35     return m_pLazyData; 
36 }
37
38 inline DebuggerModuleTable * Debugger::GetModuleTable() 
39
40     LIMITED_METHOD_CONTRACT;
41
42     return m_pModules; 
43 }
44
45
46 //=============================================================================
47 // Inlined methods for DebuggerModule.
48 //=============================================================================
49
50
51 //-----------------------------------------------------------------------------
52 // Constructor for a Debugger-Module.
53 // @dbgtodo inspection - get rid of this entire class as we move things out-of-proc. 
54 //-----------------------------------------------------------------------------
55 inline DebuggerModule::DebuggerModule(Module *      pRuntimeModule, 
56                                       DomainFile *  pDomainFile, 
57                                       AppDomain *   pAppDomain) :
58         m_enableClassLoadCallbacks(FALSE),
59         m_pPrimaryModule(NULL),
60         m_pRuntimeModule(pRuntimeModule),
61         m_pRuntimeDomainFile(pDomainFile),
62         m_pAppDomain(pAppDomain)
63 {
64     LOG((LF_CORDB,LL_INFO10000, "DM::DM this:0x%x Module:0x%x DF:0x%x AD:0x%x\n",
65         this, pRuntimeModule, pDomainFile, pAppDomain));
66
67     // Pick a primary module.
68     // Arguably, this could be in DebuggerModuleTable::AddModule
69     PickPrimaryModule();
70
71
72     // Do we have any optimized code?   
73     DWORD dwDebugBits = pRuntimeModule->GetDebuggerInfoBits();
74     m_fHasOptimizedCode = CORDebuggerAllowJITOpts(dwDebugBits);    
75
76     // Dynamic modules must receive ClassLoad callbacks in order to receive metadata updates as the module
77     // evolves. So we force this on here and refuse to change it for all dynamic modules.
78     if (pRuntimeModule->IsReflection())
79     {
80         EnableClassLoadCallbacks(TRUE);
81     }
82 }
83     
84 //-----------------------------------------------------------------------------
85 // Returns true if we have any optimized code in the module.
86 // 
87 // Notes:
88 //    JMC-probes aren't emitted in optimized code. 
89 //    <TODO> Life would be nice if the Jit tracked this. </TODO>
90 //-----------------------------------------------------------------------------
91 inline bool DebuggerModule::HasAnyOptimizedCode() 
92
93     LIMITED_METHOD_CONTRACT;
94     Module * pModule = this->GetPrimaryModule()->GetRuntimeModule();    
95     DWORD dwDebugBits = pModule->GetDebuggerInfoBits();
96     return CORDebuggerAllowJITOpts(dwDebugBits);    
97 }
98
99 //-----------------------------------------------------------------------------
100 // Return true if we've enabled class-load callbacks.
101 //-----------------------------------------------------------------------------
102 inline BOOL DebuggerModule::ClassLoadCallbacksEnabled(void) 
103
104     return m_enableClassLoadCallbacks; 
105 }
106
107 //-----------------------------------------------------------------------------
108 // Set whether we should enable class-load callbacks for this module.
109 //-----------------------------------------------------------------------------
110 inline void DebuggerModule::EnableClassLoadCallbacks(BOOL f) 
111
112     if (m_enableClassLoadCallbacks != f)
113     {
114         if (f)
115         {
116             _ASSERTE(g_pDebugger != NULL);
117             g_pDebugger->IncrementClassLoadCallbackCount();
118         }
119         else
120         {
121             _ASSERTE(g_pDebugger != NULL);
122             g_pDebugger->DecrementClassLoadCallbackCount();
123         }
124
125         m_enableClassLoadCallbacks = f;
126     }    
127 }
128
129 //-----------------------------------------------------------------------------
130 // Return the appdomain that this module exists in.
131 //-----------------------------------------------------------------------------
132 inline AppDomain* DebuggerModule::GetAppDomain() 
133 {
134     return m_pAppDomain;
135 }
136
137 //-----------------------------------------------------------------------------
138 // Return the EE module that this module corresponds to.
139 //-----------------------------------------------------------------------------
140 inline Module * DebuggerModule::GetRuntimeModule()
141 {
142     LIMITED_METHOD_DAC_CONTRACT;
143     return m_pRuntimeModule;
144 }
145
146 //-----------------------------------------------------------------------------
147 // <TODO> (8/12/2002)
148 // Currently we create a new DebuggerModules for each appdomain a shared
149 // module lives in. We then pretend there aren't any shared modules.
150 // This is bad. We need to move away from this.
151 // Once we stop lying, then every module will be it's own PrimaryModule. :)
152 //
153 // Currently, Module* is 1:n w/ DebuggerModule. 
154 // We add a notion of PrimaryModule so that:
155 // Module* is 1:1 w/ DebuggerModule::GetPrimaryModule(); 
156 // This should help transition towards exposing shared modules.
157 // If the Runtime module is shared, then this gives a common DM.
158 // If the runtime module is not shared, then this is an identity function.
159 // </TODO>
160 //-----------------------------------------------------------------------------
161 inline DebuggerModule * DebuggerModule::GetPrimaryModule() 
162 {
163     _ASSERTE(m_pPrimaryModule != NULL);
164     return m_pPrimaryModule; 
165 }
166
167 //-----------------------------------------------------------------------------
168 // This is called by DebuggerModuleTable to set our primary module.
169 //-----------------------------------------------------------------------------
170 inline void DebuggerModule::SetPrimaryModule(DebuggerModule * pPrimary)
171 {
172     _ASSERTE(pPrimary != NULL);
173     // Our primary module must by definition refer to the same runtime module as us 
174     _ASSERTE(pPrimary->GetRuntimeModule() == this->GetRuntimeModule());
175
176     LOG((LF_CORDB, LL_EVERYTHING, "DM::SetPrimaryModule - this=%p, pPrimary=%p\n", this, pPrimary));
177     m_pPrimaryModule = pPrimary;        
178 }
179
180 inline DebuggerEval * FuncEvalFrame::GetDebuggerEval()
181 {
182     LIMITED_METHOD_DAC_CONTRACT;
183     return m_pDebuggerEval;
184 }
185
186 inline unsigned FuncEvalFrame::GetFrameAttribs(void)
187 {
188     LIMITED_METHOD_DAC_CONTRACT;
189
190     if (GetDebuggerEval()->m_evalDuringException)
191     {
192         return FRAME_ATTR_NONE;
193     }
194     else
195     {
196         return FRAME_ATTR_RESUMABLE;    // Treat the next frame as the top frame.
197     }
198 }
199
200 inline TADDR FuncEvalFrame::GetReturnAddressPtr()
201 {
202     LIMITED_METHOD_DAC_CONTRACT;
203
204     if (GetDebuggerEval()->m_evalDuringException)
205     {
206         return NULL;
207     }
208     else
209     {
210         return PTR_HOST_MEMBER_TADDR(FuncEvalFrame, this, m_ReturnAddress);
211     }
212 }
213
214 //
215 // This updates the register display for a FuncEvalFrame.
216 //
217 inline void FuncEvalFrame::UpdateRegDisplay(const PREGDISPLAY pRD)
218 {
219     SUPPORTS_DAC;
220     DebuggerEval * pDE = GetDebuggerEval();
221
222     // No context to update if we're doing a func eval from within exception processing.
223     if (pDE->m_evalDuringException)
224     {
225         return;
226     }
227
228 #ifndef WIN64EXCEPTIONS
229     // Reset pContext; it's only valid for active (top-most) frame.
230     pRD->pContext = NULL;
231 #endif // !_WIN64
232
233
234 #ifdef _TARGET_X86_
235     // Update all registers in the reg display from the CONTEXT we stored when the thread was hijacked for this func
236     // eval. We have to update all registers, not just the callee saved registers, because we can hijack a thread at any
237     // point for a func eval, not just at a call site.
238     pRD->SetEdiLocation(&(pDE->m_context.Edi));
239     pRD->SetEsiLocation(&(pDE->m_context.Esi));
240     pRD->SetEbxLocation(&(pDE->m_context.Ebx));
241     pRD->SetEdxLocation(&(pDE->m_context.Edx));
242     pRD->SetEcxLocation(&(pDE->m_context.Ecx));
243     pRD->SetEaxLocation(&(pDE->m_context.Eax));
244     pRD->SetEbpLocation(&(pDE->m_context.Ebp));
245     pRD->PCTAddr = GetReturnAddressPtr();
246
247 #ifdef WIN64EXCEPTIONS
248
249     pRD->IsCallerContextValid = FALSE;
250     pRD->IsCallerSPValid      = FALSE;        // Don't add usage of this field.  This is only temporary.
251
252     pRD->pCurrentContext->Eip = *PTR_PCODE(pRD->PCTAddr);
253     pRD->pCurrentContext->Esp = (DWORD)GetSP(&pDE->m_context);
254
255     SyncRegDisplayToCurrentContext(pRD);
256
257 #else // WIN64EXCEPTIONS
258
259     pRD->ControlPC = *PTR_PCODE(pRD->PCTAddr);
260     pRD->SP = (DWORD)GetSP(&pDE->m_context);
261
262 #endif // WIN64EXCEPTIONS
263
264 #elif defined(_TARGET_AMD64_)
265     pRD->IsCallerContextValid = FALSE;
266     pRD->IsCallerSPValid      = FALSE;        // Don't add usage of this flag.  This is only temporary.
267
268     memcpy(pRD->pCurrentContext, &(pDE->m_context), sizeof(CONTEXT));
269
270     pRD->pCurrentContextPointers->Rax = &(pDE->m_context.Rax);
271     pRD->pCurrentContextPointers->Rcx = &(pDE->m_context.Rcx);
272     pRD->pCurrentContextPointers->Rdx = &(pDE->m_context.Rdx);
273     pRD->pCurrentContextPointers->R8  = &(pDE->m_context.R8);
274     pRD->pCurrentContextPointers->R9  = &(pDE->m_context.R9);
275     pRD->pCurrentContextPointers->R10 = &(pDE->m_context.R10);
276     pRD->pCurrentContextPointers->R11 = &(pDE->m_context.R11);
277
278     pRD->pCurrentContextPointers->Rbx = &(pDE->m_context.Rbx);
279     pRD->pCurrentContextPointers->Rsi = &(pDE->m_context.Rsi);
280     pRD->pCurrentContextPointers->Rdi = &(pDE->m_context.Rdi);
281     pRD->pCurrentContextPointers->Rbp = &(pDE->m_context.Rbp);
282     pRD->pCurrentContextPointers->R12 = &(pDE->m_context.R12);
283     pRD->pCurrentContextPointers->R13 = &(pDE->m_context.R13);
284     pRD->pCurrentContextPointers->R14 = &(pDE->m_context.R14);
285     pRD->pCurrentContextPointers->R15 = &(pDE->m_context.R15);
286
287     // SyncRegDisplayToCurrentContext() sets the pRD->SP and pRD->ControlPC on AMD64.
288     SyncRegDisplayToCurrentContext(pRD);
289
290 #elif defined(_TARGET_ARM_)
291     pRD->IsCallerContextValid = FALSE;
292     pRD->IsCallerSPValid      = FALSE;        // Don't add usage of this flag.  This is only temporary.
293
294     memcpy(pRD->pCurrentContext, &(pDE->m_context), sizeof(T_CONTEXT));
295     
296     pRD->pCurrentContextPointers->R4 = &(pDE->m_context.R4);
297     pRD->pCurrentContextPointers->R5 = &(pDE->m_context.R5);
298     pRD->pCurrentContextPointers->R6 = &(pDE->m_context.R6);
299     pRD->pCurrentContextPointers->R7 = &(pDE->m_context.R7);
300     pRD->pCurrentContextPointers->R8 = &(pDE->m_context.R8);
301     pRD->pCurrentContextPointers->R9 = &(pDE->m_context.R9);
302     pRD->pCurrentContextPointers->R10 = &(pDE->m_context.R10);
303     pRD->pCurrentContextPointers->R11 = &(pDE->m_context.R11);
304     pRD->pCurrentContextPointers->Lr = &(pDE->m_context.Lr);
305
306     pRD->volatileCurrContextPointers.R0 = &(pDE->m_context.R0);
307     pRD->volatileCurrContextPointers.R1 = &(pDE->m_context.R1);
308     pRD->volatileCurrContextPointers.R2 = &(pDE->m_context.R2);
309     pRD->volatileCurrContextPointers.R3 = &(pDE->m_context.R3);
310     pRD->volatileCurrContextPointers.R12 = &(pDE->m_context.R12);
311
312     SyncRegDisplayToCurrentContext(pRD);
313
314 #elif defined(_TARGET_ARM64_)
315     pRD->IsCallerContextValid = FALSE;
316     pRD->IsCallerSPValid = FALSE;        // Don't add usage of this flag.  This is only temporary.
317
318     memcpy(pRD->pCurrentContext, &(pDE->m_context), sizeof(T_CONTEXT));
319
320     pRD->pCurrentContextPointers->X19 = &(pDE->m_context.X19);
321     pRD->pCurrentContextPointers->X20 = &(pDE->m_context.X20);
322     pRD->pCurrentContextPointers->X21 = &(pDE->m_context.X21);
323     pRD->pCurrentContextPointers->X22 = &(pDE->m_context.X22);
324     pRD->pCurrentContextPointers->X23 = &(pDE->m_context.X23);
325     pRD->pCurrentContextPointers->X24 = &(pDE->m_context.X24);
326     pRD->pCurrentContextPointers->X25 = &(pDE->m_context.X25);
327     pRD->pCurrentContextPointers->X26 = &(pDE->m_context.X26);
328     pRD->pCurrentContextPointers->X27 = &(pDE->m_context.X27);
329     pRD->pCurrentContextPointers->X28 = &(pDE->m_context.X28);
330     pRD->pCurrentContextPointers->Lr = &(pDE->m_context.Lr);
331     pRD->pCurrentContextPointers->Fp = &(pDE->m_context.Fp);
332
333     pRD->volatileCurrContextPointers.X0 = &(pDE->m_context.X0);
334     pRD->volatileCurrContextPointers.X1 = &(pDE->m_context.X1);
335     pRD->volatileCurrContextPointers.X2 = &(pDE->m_context.X2);
336     pRD->volatileCurrContextPointers.X3 = &(pDE->m_context.X3);
337     pRD->volatileCurrContextPointers.X4 = &(pDE->m_context.X4);
338     pRD->volatileCurrContextPointers.X5 = &(pDE->m_context.X5);
339     pRD->volatileCurrContextPointers.X6 = &(pDE->m_context.X6);
340     pRD->volatileCurrContextPointers.X7 = &(pDE->m_context.X7);
341     pRD->volatileCurrContextPointers.X8 = &(pDE->m_context.X8);
342     pRD->volatileCurrContextPointers.X9 = &(pDE->m_context.X9);
343     pRD->volatileCurrContextPointers.X10 = &(pDE->m_context.X10);
344     pRD->volatileCurrContextPointers.X11 = &(pDE->m_context.X11);
345     pRD->volatileCurrContextPointers.X12 = &(pDE->m_context.X12);
346     pRD->volatileCurrContextPointers.X13 = &(pDE->m_context.X13);
347     pRD->volatileCurrContextPointers.X14 = &(pDE->m_context.X14);
348     pRD->volatileCurrContextPointers.X15 = &(pDE->m_context.X15);
349     pRD->volatileCurrContextPointers.X16 = &(pDE->m_context.X16);
350     pRD->volatileCurrContextPointers.X17 = &(pDE->m_context.X17);
351
352     SyncRegDisplayToCurrentContext(pRD); 
353 #else
354     PORTABILITY_ASSERT("FuncEvalFrame::UpdateRegDisplay is not implemented on this platform.");
355 #endif
356 }
357
358 #endif  // DEBUGGER_INL_