Enable build with clang 4.0 (#11226)
[platform/upstream/coreclr.git] / src / debug / di / module.cpp
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 // File: module.cpp
7 // 
8
9 //
10 //*****************************************************************************
11 #include "stdafx.h"
12 #include "winbase.h"
13
14 #include "metadataexports.h"
15
16 #include "winbase.h"
17 #include "corpriv.h"
18 #include "corsym.h"
19 #include "ildbsymlib.h"
20
21 #include "pedecoder.h"
22
23 //---------------------------------------------------------------------------------------
24 // Update an existing metadata importer with a buffer
25 //
26 // Arguments:
27 //     pUnk - IUnknoown of importer to update.
28 //     pData - local buffer containing new metadata
29 //     cbData - size of buffer in bytes.
30 //     dwReOpenFlags - metadata flags to pass for reopening.
31 //
32 // Returns:
33 //     S_OK on success. Else failure.
34 //
35 // Notes:
36 //    This will call code:MDReOpenMetaDataWithMemoryEx from the metadata engine.
37 STDAPI ReOpenMetaDataWithMemoryEx(
38     void        *pUnk,
39     LPCVOID     pData,
40     ULONG       cbData,
41     DWORD       dwReOpenFlags)
42 {
43     HRESULT hr = MDReOpenMetaDataWithMemoryEx(pUnk,pData, cbData, dwReOpenFlags);
44     return hr;
45 }
46
47 //---------------------------------------------------------------------------------------
48 // Initialize a new CordbModule around a Module in the target.
49 // 
50 // Arguments:
51 //    pProcess - process that this module lives in
52 //    vmDomainFile - CLR cookie for module.
53 CordbModule::CordbModule(
54     CordbProcess *     pProcess,
55     VMPTR_Module        vmModule,
56     VMPTR_DomainFile    vmDomainFile)
57 : CordbBase(pProcess, vmDomainFile.IsNull() ? VmPtrToCookie(vmModule) : VmPtrToCookie(vmDomainFile), enumCordbModule), 
58     m_pAssembly(0),
59     m_pAppDomain(0),
60     m_classes(11),
61     m_functions(101),
62     m_vmDomainFile(vmDomainFile),
63     m_vmModule(vmModule),
64     m_EnCCount(0),
65     m_isIlWinMD(Uninitialized),
66     m_fForceMetaDataSerialize(FALSE),
67     m_nativeCodeTable(101)
68 {
69     _ASSERTE(pProcess->GetProcessLock()->HasLock());
70
71     _ASSERTE(!vmModule.IsNull());
72
73     m_nLoadEventContinueCounter = 0;
74 #ifdef _DEBUG
75     m_classes.DebugSetRSLock(pProcess->GetProcessLock());
76     m_functions.DebugSetRSLock(pProcess->GetProcessLock());
77 #endif
78
79     // Fill out properties via DAC.
80     ModuleInfo modInfo;
81     pProcess->GetDAC()->GetModuleData(vmModule, &modInfo); // throws
82
83     m_PEBuffer.Init(modInfo.pPEBaseAddress, modInfo.nPESize);
84
85     m_fDynamic  = modInfo.fIsDynamic;
86     m_fInMemory = modInfo.fInMemory;
87     m_vmPEFile = modInfo.vmPEFile;
88
89     if (!vmDomainFile.IsNull())
90     {
91         DomainFileInfo dfInfo;
92         
93         pProcess->GetDAC()->GetDomainFileData(vmDomainFile, &dfInfo); // throws
94         
95         m_pAppDomain = pProcess->LookupOrCreateAppDomain(dfInfo.vmAppDomain);
96         m_pAssembly  = m_pAppDomain->LookupOrCreateAssembly(dfInfo.vmDomainAssembly);
97     }
98     else
99     {
100         // Not yet implemented
101         m_pAppDomain = pProcess->GetSharedAppDomain();
102         m_pAssembly = m_pAppDomain->LookupOrCreateAssembly(modInfo.vmAssembly);
103     }
104 #ifdef _DEBUG
105     m_nativeCodeTable.DebugSetRSLock(GetProcess()->GetProcessLock());
106 #endif
107
108     // MetaData is initialized lazily (via code:CordbModule::GetMetaDataImporter).
109     // Getting the metadata may be very expensive (especially if we go through the metadata locator, which
110     // invokes back to the data-target), so don't do it until asked.
111     // m_pIMImport, m_pInternalMetaDataImport are smart pointers that already initialize to NULL.
112 }
113
114
115 #ifdef _DEBUG
116 //---------------------------------------------------------------------------------------
117 // Callback helper for code:CordbModule::DbgAssertModuleDeleted
118 // 
119 // Arguments
120 //    vmDomainFile - domain file in the enumeration
121 //    pUserData - pointer to the CordbModule that we just got an exit event for.
122 //    
123 void DbgAssertModuleDeletedCallback(VMPTR_DomainFile vmDomainFile, void * pUserData)
124 {
125     CordbModule * pThis = reinterpret_cast<CordbModule *>(pUserData);
126     INTERNAL_DAC_CALLBACK(pThis->GetProcess());
127
128     if (!pThis->m_vmDomainFile.IsNull())
129     {
130         VMPTR_DomainFile vmDomainFileDeleted = pThis->m_vmDomainFile;
131         
132         CONSISTENCY_CHECK_MSGF((vmDomainFileDeleted != vmDomainFile), 
133             ("A Module Unload event was sent for a module, but it still shows up in the enumeration.\n vmDomainFileDeleted=%p\n", 
134             VmPtrToCookie(vmDomainFileDeleted)));
135     }
136 }
137
138 //---------------------------------------------------------------------------------------
139 // Assert that a module is no longer discoverable via enumeration.
140 //
141 // Notes:
142 //   See code:IDacDbiInterface#Enumeration for rules that we're asserting.
143 //   This is a debug only method. It's conceptually similar to 
144 //   code:CordbProcess::DbgAssertAppDomainDeleted. 
145 //
146 void CordbModule::DbgAssertModuleDeleted()
147 {
148     GetProcess()->GetDAC()->EnumerateModulesInAssembly(
149         m_pAssembly->GetDomainAssemblyPtr(),
150         DbgAssertModuleDeletedCallback,
151         this);
152 }
153 #endif // _DEBUG
154
155 CordbModule::~CordbModule()
156 {
157     // We should have been explicitly neutered before our internal ref went to 0.
158     _ASSERTE(IsNeutered());
159
160     _ASSERTE(m_pIMImport == NULL);
161 }
162
163 // Neutered by CordbAppDomain
164 void CordbModule::Neuter()
165 {
166     // m_pAppDomain, m_pAssembly assigned w/o AddRef()
167     m_classes.NeuterAndClear(GetProcess()->GetProcessLock());
168     m_functions.NeuterAndClear(GetProcess()->GetProcessLock());
169
170     m_nativeCodeTable.NeuterAndClear(GetProcess()->GetProcessLock());
171     m_pClass.Clear();
172
173     // This is very important because it also releases the metadata's potential file locks.
174     m_pInternalMetaDataImport.Clear();
175     m_pIMImport.Clear();
176
177     CordbBase::Neuter();
178 }
179
180 //
181 // Creates an IStream based off the memory described by the TargetBuffer.
182 // 
183 // Arguments:
184 //   pProcess - process that buffer is valid in.
185 //   buffer - memory range in target
186 //   ppStream - out parameter to receive the new stream. *ppStream == NULL on input.
187 //      caller owns the new object and must call Release.
188 //   
189 // Returns:
190 //    Throws on error. 
191 //    Common errors include if memory is missing in the target.
192 //    
193 // Notes:
194 //   This will copy the memory over from the TargetBuffer, and then create a new IStream 
195 //   object around it. 
196 //   
197 void GetStreamFromTargetBuffer(CordbProcess * pProcess, TargetBuffer buffer, IStream ** ppStream)
198 {
199     CONTRACTL
200     {
201         THROWS;
202     }
203     CONTRACTL_END;
204
205     _ASSERTE(ppStream != NULL);
206     _ASSERTE(*ppStream == NULL);
207     
208     int cbSize = buffer.cbSize;
209     NewArrayHolder<BYTE> localBuffer(new BYTE[cbSize]);
210     
211     pProcess->SafeReadBuffer(buffer, localBuffer);
212
213     HRESULT hr = E_FAIL;
214     hr = CInMemoryStream::CreateStreamOnMemoryCopy(localBuffer, cbSize, ppStream);
215     IfFailThrow(hr);
216     _ASSERTE(*ppStream != NULL);
217 }
218
219 //
220 // Helper API to get in-memory symbols from the target into a host stream object.
221 // 
222 // Arguments:
223 //   ppStream - out parameter to receive the new stream. *ppStream == NULL on input.
224 //      caller owns the new object and must call Release.
225 //      
226 // Returns:
227 //   kSymbolFormatNone if no PDB stream is present. This is a common case for 
228 //     file-based modules, and also for dynamic modules that just aren't tracking 
229 //     debug information. 
230 //   The format of the symbols stored into ppStream. This is common:
231 //      - Ref.Emit modules if the debuggee generated debug symbols,
232 //      - in-memory modules (such as Load(Byte[], Byte[])
233 //      - hosted modules.
234 //   Throws on error
235 // 
236 IDacDbiInterface::SymbolFormat CordbModule::GetInMemorySymbolStream(IStream ** ppStream)
237 {
238     // @dbgtodo : add a PUBLIC_REENTRANT_API_ENTRY_FOR_SHIM contract
239     // This function is mainly called internally in dbi, and also by the shim to emulate the
240     // UpdateModuleSymbols callback on attach.
241
242     CONTRACTL
243     {
244         THROWS;
245     }
246     CONTRACTL_END;
247
248     _ASSERTE(ppStream != NULL);
249     _ASSERTE(*ppStream == NULL);
250     *ppStream = NULL;
251
252     TargetBuffer bufferPdb;
253     IDacDbiInterface::SymbolFormat symFormat;
254     GetProcess()->GetDAC()->GetSymbolsBuffer(m_vmModule, &bufferPdb, &symFormat);
255     if (bufferPdb.IsEmpty())
256     {
257         // No in-memory PDB. Common case.
258         _ASSERTE(symFormat == IDacDbiInterface::kSymbolFormatNone);
259         return IDacDbiInterface::kSymbolFormatNone;
260     }
261     else
262     {
263         _ASSERTE(symFormat != IDacDbiInterface::kSymbolFormatNone);
264         GetStreamFromTargetBuffer(GetProcess(), bufferPdb, ppStream);
265         return symFormat;
266     }
267 }
268
269 //---------------------------------------------------------------------------------------
270 // Accessor for PE file.
271 //
272 // Returns:
273 //    VMPTR_PEFile for this module. Should always be non-null
274 //
275 // Notes:
276 //    A main usage of this is to find the proper internal MetaData importer.
277 //    DACized code needs to map from PEFile --> IMDInternalImport.
278 //
279 VMPTR_PEFile CordbModule::GetPEFile()
280 {
281     return m_vmPEFile;
282 }
283
284 //---------------------------------------------------------------------------------------
285 //
286 // Top-level getter for the public metadata importer for this module
287 //
288 // Returns:
289 //     metadata importer. 
290 //     Never returns NULL. Will throw some hr (likely CORDBG_E_MISSING_METADATA) instead.
291 //
292 // Notes:
293 //     This will lazily create the metadata, possibly invoking back into the data-target.
294 IMetaDataImport * CordbModule::GetMetaDataImporter()
295 {
296     CONTRACTL
297     {
298         THROWS;
299     }
300     CONTRACTL_END;
301
302
303     // If we already have it, then we're done.
304     // This is critical to do at the top of this function to avoid potential recursion. 
305     if (m_pIMImport != NULL)
306     {
307         return m_pIMImport;
308     }
309
310     // Lazily initialize
311
312
313     // Fetch metadata from target
314     LOG((LF_CORDB,LL_INFO1000, "CM::GMI Lazy init refreshing metadata\n"));
315
316     ALLOW_DATATARGET_MISSING_MEMORY(
317         RefreshMetaData();
318     );
319
320     // If lookup failed from the Module & target memory, try the metadata locator interface
321     // from debugger, if we have one.
322     if (m_pIMImport == NULL)
323     {
324         bool isILMetaDataForNGENImage;  // Not currently used for anything.
325
326         // The process's LookupMetaData will ping the debugger's ICorDebugMetaDataLocator iface.
327         CordbProcess * pProcess = GetProcess();
328         RSLockHolder processLockHolder(pProcess->GetProcessLock());
329         m_pInternalMetaDataImport.Clear();
330
331         // Do not call code:CordbProcess::LookupMetaData from this function.  It will try to load
332         // through the CordbModule again which will end up back here, and on failure you'll fill the stack.
333         // Since we've already done everything possible from the Module anyhow, just call the
334         // stuff that talks to the debugger.
335         // Don't do anything with the ptr returned here, since it's really m_pInternalMetaDataImport.
336         pProcess->LookupMetaDataFromDebugger(m_vmPEFile, isILMetaDataForNGENImage, this);
337     }
338
339     // If we still can't get it, throw.
340     if (m_pIMImport == NULL)
341     {
342         ThrowHR(CORDBG_E_MISSING_METADATA);
343     }
344
345     return m_pIMImport;
346 }
347
348 // Refresh the metadata cache if a profiler added new rows.
349 //
350 // Arguments:
351 //    token - token that we want to ensure is in the metadata cache.
352 //
353 // Notes:
354 //    In profiler case, this may be referred to new rows and we may need to update the metadata
355 //    This only supports StandAloneSigs. 
356 //
357 void CordbModule::UpdateMetaDataCacheIfNeeded(mdToken token)
358 {
359     CONTRACTL
360     {
361         THROWS;
362     }
363     CONTRACTL_END;
364
365     LOG((LF_CORDB,LL_INFO10000, "CM::UMCIN token=0x%x\n", token));
366
367     // If we aren't trying to keep parity with our legacy profiler metadata update behavior
368     // then we should avoid this temporary update mechanism entirely
369     if(GetProcess()->GetWriteableMetadataUpdateMode() != LegacyCompatPolicy)
370     {
371         return; 
372     }
373
374     // the metadata in WinMD is currently static since there's no
375     // support for profilers or EnC so we can simply exit early.
376     if (IsWinMD())
377     {
378         LOG((LF_CORDB,LL_INFO10000, "CM::UMCIN token is in WinMD, exiting\n"));
379         return;
380     }
381
382     //
383     // 1) Check if in-range? Compare against tables, etc. 
384     // 
385     if(CheckIfTokenInMetaData(token))
386     {
387         LOG((LF_CORDB,LL_INFO10000, "CM::UMCIN token was present\n"));
388         return;
389     }
390
391     // 
392     // 2) Copy over new MetaData. From now on we assume that the profiler is
393     //    modifying module metadata and that we need to serialize in process
394     //    at each refresh
395     // 
396     LOG((LF_CORDB,LL_INFO10000, "CM::UMCIN token was not present, refreshing\n"));
397     m_fForceMetaDataSerialize = TRUE;
398     RefreshMetaData();
399     
400     // If we are dump debugging, we may still not have it. Nothing to be done.
401 }
402
403 // Returns TRUE if the token is present, FALSE if not.
404 BOOL CordbModule::CheckIfTokenInMetaData(mdToken token)
405 {
406     CONTRACTL
407     {
408         THROWS;
409     }
410     CONTRACTL_END;
411     LOG((LF_CORDB,LL_INFO10000, "CM::CITIM token=0x%x\n", token));
412     _ASSERTE(TypeFromToken(token) == mdtSignature);    
413     // we shouldn't be doing this on WinMD modules since they don't implement IID_IMetaDataTables
414     _ASSERTE(!IsWinMD());
415     RSExtSmartPtr<IMetaDataTables> pTable;
416
417     HRESULT hr = GetMetaDataImporter()->QueryInterface(IID_IMetaDataTables, (void**) &pTable);
418
419     _ASSERTE(SUCCEEDED(hr));
420     if (FAILED(hr))
421     {
422         ThrowHR(hr);
423     }
424
425     ULONG cbRowsAvailable; // number of rows in the table
426     
427     hr = pTable->GetTableInfo(    
428         mdtSignature >> 24,                      // [IN] Which table.
429         NULL,                    // [OUT] Size of a row, bytes.
430         &cbRowsAvailable,                    // [OUT] Number of rows.
431         NULL,                    // [OUT] Number of columns in each row.
432         NULL,                     // [OUT] Key column, or -1 if none.
433         NULL);          // [OUT] Name of the table.
434     
435     _ASSERTE(SUCCEEDED(hr));
436     if (FAILED(hr))
437     {
438         ThrowHR(hr);
439     }    
440
441
442     // Rows start counting with number 1.
443     ULONG rowRequested = RidFromToken(token);
444     LOG((LF_CORDB,LL_INFO10000, "CM::UMCIN requested=0x%x available=0x%x\n", rowRequested, cbRowsAvailable));
445     return (rowRequested <= cbRowsAvailable);
446 }
447
448 // This helper class ensures the remote serailzied buffer gets deleted in the RefreshMetaData
449 // function below
450 class CleanupRemoteBuffer
451 {
452 public:
453     CordbProcess* pProcess;
454     CordbModule* pModule;
455     TargetBuffer bufferMetaData;
456     BOOL fDoCleanup;
457
458     CleanupRemoteBuffer() : 
459     fDoCleanup(FALSE) { }
460
461     ~CleanupRemoteBuffer()
462     {
463         if(fDoCleanup)
464         {
465             //
466             // Send 2nd event to free buffer.
467             //
468             DebuggerIPCEvent event;
469             pProcess->InitIPCEvent(&event,
470                 DB_IPCE_RESOLVE_UPDATE_METADATA_2,
471                 true,
472                 pModule->GetAppDomain()->GetADToken());
473
474             event.MetadataUpdateRequest.pMetadataStart = CORDB_ADDRESS_TO_PTR(bufferMetaData.pAddress);
475
476             // Note: two-way event here...
477             IfFailThrow(pProcess->SendIPCEvent(&event, sizeof(DebuggerIPCEvent)));
478             _ASSERTE(event.type == DB_IPCE_RESOLVE_UPDATE_METADATA_2_RESULT);
479         }
480     }
481
482 };
483
484 // Called to refetch metadata. This occurs when a dynamic module grows or the profiler
485 // has edited the metadata
486 void CordbModule::RefreshMetaData()
487 {
488     CONTRACTL
489     {
490         THROWS;
491     }
492     CONTRACTL_END;
493
494     LOG((LF_CORDB,LL_INFO1000, "CM::RM\n"));
495
496     // There are several different ways we can get the metadata
497     // 1) [Most common] Module is loaded into VM and never changed. The importer
498     //    will be constructed refering to the file on disk. This is a significant
499     //    working set win because the VM and debugger share the image. If there is
500     //    an error reading by file we can fall back to case #2 for these modules
501     // 2) Most modules have a buffer in target memory that represents their
502     //    metadata. We copy that data over the RS and construct an in-memory
503     //    importer on top of it. 
504     // 3) The only modules that don't have a suitable buffer (case #2) are those
505     //    modified in memory via the profiling API (or ENC). A message can be sent from
506     //    the debugger to the debuggee instructing it to allocate a buffer and
507     //    serialize the metadata into it. Then we copy that data to the RS and
508     //    construct an in-memory importer on top of it.
509     //    We don't need to send this message in the ENC case because the debugger
510     //    has the same changes applied as the debuggee.
511     // 4) Case #3 won't work when dump debugging because we can't send IPC events.
512     //    Instead we can locate chunks of the metadata pointed to in the implementation
513     //    details of a remote MDInternalRW object, marshal that memory over to the
514     //    debugger process, and then put a metadata reader on top of it.
515     //    In time this DAC'ized metadata could be used in almost any scenario,
516     //    although its probably worth keeping the file mapping technique in case
517     //    #1 around for its performance wins.
518
519     CordbProcess * pProcess = GetProcess();
520     TargetBuffer bufferMetaData;
521     CleanupRemoteBuffer cleanup; // this local has a destructor to do some finally work
522
523
524     // check for scenarios we might want to handle with case #4
525     if (GetProcess()->GetShim() == NULL &&
526         GetProcess()->GetWriteableMetadataUpdateMode() == AlwaysShowUpdates &&
527         !m_fDynamic)
528     {
529         //None of the above requirements are particularly hard to change in the future as needed...
530         // a) dump-debugging mode - If we do this on a process that can move forward we need a mechanism to determine
531         //                          when to refetch the metadata.
532         // b) AlwaysShowUpdates - this is purely a risk mitigation choice, there aren't any known back-compat issues
533         //                        using DAC'ized metadata. If you want back-compat with the in-proc debugging behavior
534         //                        you need to figure out how to ReOpen the same public MD interface with new data.
535         // c) !m_fDynamic       - A risk mitigation choice. Initial testing suggests it would work fine.
536
537
538         // So far we've only got a reader for in-memory-writable metadata (MDInternalRW implementation)
539         // We could make a reader for MDInternalRO, but no need yet. This also ensures we don't encroach into common
540         // scenario where we can map a file on disk.
541         TADDR remoteMDInternalRWAddr = NULL;
542         GetProcess()->GetDAC()->GetPEFileMDInternalRW(m_vmPEFile, &remoteMDInternalRWAddr);
543         if (remoteMDInternalRWAddr != NULL)
544         {
545             // we should only be doing this once to initialize, we don't support reopen with this technique
546             _ASSERTE(m_pIMImport == NULL); 
547             ULONG32 mdStructuresVersion;
548             HRESULT hr = GetProcess()->GetDAC()->GetMDStructuresVersion(&mdStructuresVersion);
549             IfFailThrow(hr);
550             ULONG32 mdStructuresDefines;
551             hr = GetProcess()->GetDAC()->GetDefinesBitField(&mdStructuresDefines);
552             IfFailThrow(hr);
553             IMetaDataDispenserCustom* pDispCustom = NULL;
554             hr = GetProcess()->GetDispenser()->QueryInterface(IID_IMetaDataDispenserCustom, (void**)&pDispCustom);
555             IfFailThrow(hr);
556             IMDCustomDataSource* pDataSource = NULL;
557             hr = CreateRemoteMDInternalRWSource(remoteMDInternalRWAddr, GetProcess()->GetDataTarget(), mdStructuresDefines, mdStructuresVersion, &pDataSource);
558             IfFailThrow(hr);
559             IMetaDataImport* pImport = NULL;
560             hr = pDispCustom->OpenScopeOnCustomDataSource(pDataSource, 0, IID_IMetaDataImport, (IUnknown**)&m_pIMImport);
561             IfFailThrow(hr);
562             UpdateInternalMetaData();
563             return;
564         }
565     }
566
567     if(!m_fForceMetaDataSerialize) // case 1 and 2
568     {
569         LOG((LF_CORDB,LL_INFO10000, "CM::RM !m_fForceMetaDataSerialize case\n"));
570         GetProcess()->GetDAC()->GetMetadata(m_vmModule, &bufferMetaData); // throws 
571     }
572     else if (GetProcess()->GetShim() == NULL) // case 3 won't work on a dump so don't try
573     {
574         return;
575     }
576     else // case 3 on a live process
577     {
578         LOG((LF_CORDB,LL_INFO10000, "CM::RM m_fForceMetaDataSerialize case\n"));
579         //
580         // Send 1 event to get metadata. This allocates a buffer
581         //
582         DebuggerIPCEvent event;
583         pProcess->InitIPCEvent(&event,
584             DB_IPCE_RESOLVE_UPDATE_METADATA_1,
585             true,
586             GetAppDomain()->GetADToken());
587
588         event.MetadataUpdateRequest.vmModule = m_vmModule;
589
590         // Note: two-way event here...
591         IfFailThrow(pProcess->SendIPCEvent(&event, sizeof(DebuggerIPCEvent)));
592
593         _ASSERTE(event.type == DB_IPCE_RESOLVE_UPDATE_METADATA_1_RESULT);
594
595         //
596         // Update it on the RS
597         //
598         bufferMetaData.Init(PTR_TO_CORDB_ADDRESS(event.MetadataUpdateRequest.pMetadataStart), (ULONG) event.MetadataUpdateRequest.nMetadataSize);
599
600         // init the cleanup object to ensure the buffer gets destroyed later
601         cleanup.bufferMetaData = bufferMetaData;
602         cleanup.pProcess = pProcess;
603         cleanup.pModule = this;
604         cleanup.fDoCleanup = TRUE;
605     }
606
607     InitMetaData(bufferMetaData, IsFileMetaDataValid()); // throws 
608 }
609
610 // Determines whether the on-disk metadata for this module is usable as the
611 // current metadata
612 BOOL CordbModule::IsFileMetaDataValid()
613 {
614     bool fOpenFromFile = true;
615
616     // Dynamic, In-memory, modules must be OpenScopeOnMemory.
617     // For modules that require the metadata to be serialized in memory, we must also OpenScopeOnMemory
618     // For Enc, we'll can use OpenScope(onFile) and it will get converted to Memory when we get an emitter.
619     // We're called from before the ModuleLoad callback, so EnC status hasn't been set yet, so
620     // EnC will be false.
621     if (m_fDynamic || m_fInMemory || m_fForceMetaDataSerialize)
622     {
623         LOG((LF_CORDB,LL_INFO10000, "CM::IFMV: m_fDynamic=0x%x m_fInMemory=0x%x m_fForceMetaDataSerialize=0x%x\n",
624             m_fDynamic, m_fInMemory, m_fForceMetaDataSerialize));
625         fOpenFromFile = false;
626     }
627
628 #ifdef _DEBUG
629     // Reg key override to force us to use Open-by-memory. This can let us run perf tests to
630     // compare the Open-by-mem vs. Open-by-file.
631     static DWORD openFromFile = 99;
632     if (openFromFile == 99)
633         openFromFile = CLRConfig::GetConfigValue(CLRConfig::INTERNAL_DbgNoOpenMDByFile);
634
635     if (openFromFile)
636     {
637         LOG((LF_CORDB,LL_INFO10000, "CM::IFMV: INTERNAL_DbgNoOpenMDByFile is set\n"));
638         fOpenFromFile = false;
639     }
640 #endif
641
642     LOG((LF_CORDB,LL_INFO10000, "CM::IFMV: returns 0x%x\n", fOpenFromFile));
643     return fOpenFromFile;
644 }
645
646 //---------------------------------------------------------------------------------------
647 // Accessor for Internal MetaData importer. This is lazily initialized.
648 // 
649 // Returns:
650 //     Internal MetaDataImporter, which can be handed off to DAC. Not AddRef().
651 //     Should be non-null. Throws on error.
652 //
653 // Notes:
654 //     An internal metadata importer is used extensively by DAC-ized code (And Edit-and-continue).
655 //     This should not be handed out through ICorDebug. 
656 IMDInternalImport * CordbModule::GetInternalMD()
657 {   
658     if (m_pInternalMetaDataImport == NULL)
659     {
660         UpdateInternalMetaData(); // throws
661     }
662     return m_pInternalMetaDataImport;
663 }
664
665 //---------------------------------------------------------------------------------------
666 // The one-stop top-level initialization function the metadata (both public and private) for this module. 
667 //
668 // Arguments:
669 //    buffer - valid buffer into target containing the metadata.
670 //    useFileMappingOptimization - if true this allows us to attempt just opening the importer
671 //                                 by using the metadata in the module on disk. if false or
672 //                                 if the attempt fails we open the metadata import on memory in
673 //                                 target buffer
674 //
675 // Notes:
676 //    This will initialize both the internal and public metadata from the buffer in the target.
677 //    Only called as a helper from RefreshMetaData()
678 // 
679 //    This may throw (eg, target buffer is missing).
680 //
681 void CordbModule::InitMetaData(TargetBuffer buffer, BOOL allowFileMappingOptimization)
682 {
683     CONTRACTL
684     {
685         THROWS;
686     }
687     CONTRACTL_END;
688     
689     LOG((LF_CORDB,LL_INFO100000, "CM::IM: initing with remote buffer 0x%p length 0x%x\n", 
690         CORDB_ADDRESS_TO_PTR(buffer.pAddress), buffer.cbSize));
691
692     // clear all the metadata
693     m_pInternalMetaDataImport.Clear();
694
695     if (m_pIMImport == NULL)
696     {
697         // The optimization we're going for here is that the OS will use the same physical memory to
698         // back multiple ReadOnly opens of the same file.  Thus since we expect the target process in
699         // live debugging, or the debugger in dump debugging, has already opened the file we would
700         // like to not create a local buffer and spend time copying in metadata from the target when
701         // the OS will happily do address lookup magic against the same physical memory for everyone.
702
703
704         // Try getting the data from the file if allowed, and fall back to using the buffer
705         // if required
706         HRESULT hr = S_OK;
707         if (allowFileMappingOptimization)
708         {
709             hr = InitPublicMetaDataFromFile();
710             if(FAILED(hr))
711             {
712                 LOG((LF_CORDB,LL_INFO1000000, "CM::IPM: File mapping failed with hr=0x%x\n", hr));
713             }
714         }
715
716         if(!allowFileMappingOptimization || FAILED(hr))
717         {
718             // This is where the expensive copy of all metadata content from target memory 
719             // that we would like to try and avoid happens.
720             InitPublicMetaData(buffer);
721         }
722     }
723     else
724     {
725         // We've already handed out an Import object, and so we can't create a new pointer instance.
726         // Instead, we update the existing instance with new data.
727         UpdatePublicMetaDataFromRemote(buffer);
728     }
729
730     // if we haven't set it by this point UpdateInternalMetaData below is going to get us
731     // in an infinite loop of refreshing public metadata
732     _ASSERTE(m_pIMImport != NULL);
733
734     // Now that public metadata has changed, force internal metadata to update too.
735     // Public and internal metadata expose different access interfaces to the same underlying storage.
736     UpdateInternalMetaData();
737 }
738
739 //---------------------------------------------------------------------------------------
740 // Updates the Internal MetaData object from the public importer. Lazily fetch public importer if needed.
741 //
742 // Assumptions:
743 //     Caller has cleared Internal metadata before even updating public metadata.
744 //     This way, if the caller fails halfway through updating the public metadata, we don't have 
745 //     stale internal MetaData.
746 void CordbModule::UpdateInternalMetaData()
747 {
748     CONTRACTL
749     {
750         THROWS;
751     }
752     CONTRACTL_END;
753
754     // Caller should have already cleared it.
755     _ASSERTE(m_pInternalMetaDataImport == NULL);
756
757     // Get the importer. If it's currently null, this will go fetch it.
758     IMetaDataImport * pImport = GetMetaDataImporter(); // throws
759
760     // If both the public and the private interfaces are NULL on entry to this function, the call above will
761     // recursively call this function.  This can happen if the caller calls GetInternalMD() directly 
762     // instead of InitMetaData().  In this case, the above function call will have initialized the internal
763     // interface as well, so we need to check for it here.
764
765     if (m_pInternalMetaDataImport == NULL)
766     {
767         HRESULT hr = GetMDInternalInterfaceFromPublic(
768             pImport, 
769             IID_IMDInternalImport, 
770             reinterpret_cast<void**> (&m_pInternalMetaDataImport));
771
772         if (m_pInternalMetaDataImport == NULL)
773         {
774             ThrowHR(hr);
775         }
776     }
777
778     _ASSERTE(m_pInternalMetaDataImport != NULL);
779 }
780
781 // Initialize the public metadata.
782 //
783 // The debuggee already has a copy of the metadata in its process.
784 // If we OpenScope on file as read-only, the OS file-system will share our metadata with the
785 // copy in the debuggee. This can be a major perf win. FX metadata can be over 8 MB+.
786 // OpenScopeOnMemory can't be shared b/c we allocate a buffer.
787 HRESULT CordbModule::InitPublicMetaDataFromFile()
788 {
789     INTERNAL_API_ENTRY(this->GetProcess());
790
791     // @dbgtodo  metadata - In v3, we can't assume we have the same path namespace as the target (i.e. it could be
792     // a dump or remote), so we can't just try and open the file.  Instead we have to rely on interfaces
793     // on the datatarget to map the metadata here.  Note that this must also work for minidumps where the
794     // metadata isn't necessarily in the dump image.
795
796     // Get filename. There are 2 filenames to choose from:
797     // - ngen (if applicable).
798     // - non-ngen (aka "normal").
799     // By loading metadata out of the same OS file as loaded into the debuggee space, the OS can share those pages.
800     const WCHAR * szFullPathName = NULL;
801     bool fDebuggerLoadingNgen = false;
802     bool fDebuggeeLoadedNgen = false;
803     szFullPathName = GetNGenImagePath();
804
805     if(szFullPathName != NULL)
806     {
807         fDebuggeeLoadedNgen = true;
808         fDebuggerLoadingNgen = true;
809
810 #ifndef FEATURE_PAL
811         // NGEN images are large and we shouldn't load them if they won't be shared, therefore fail the NGEN mapping and
812         // fallback to IL image if the debugger doesn't have the image loaded already.
813         // Its possible that the debugger would still load the NGEN image sometime in the future and we will miss a sharing
814         // opportunity. Its an acceptable loss from an imperfect heuristic.
815         if (NULL == WszGetModuleHandle(szFullPathName))
816 #endif            
817         {
818             szFullPathName = NULL;
819             fDebuggerLoadingNgen = false;
820         }
821
822     }
823
824     // If we don't have or decided not to load the NGEN image, check to see if IL image is available
825     if (!fDebuggerLoadingNgen)
826     {
827         szFullPathName = GetModulePath();
828     }
829
830     // If we are doing live debugging we shouldn't use metadata from an IL image because it doesn't match closely enough.
831     // In particular the RVAs for IL code headers are different between the two images which will cause all IL code and
832     // local var signature lookups to fail. With further work we could compensate for the RVAs by computing
833     // the image layout differences and adjusting the returned RVAs, but there may be other differences that need to be accounted
834     // for as well. If we did go that route we should do a binary diff across a variety of NGEN/IL image metadata blobs to
835     // get a concrete understanding of the format differences.
836     //
837     // This check should really be 'Are we OK with only getting the functionality level of mini-dump debugging?' but since we
838     // don't know the debugger's intent we guess whether or not we are doing dump debugging by checking if we are shimmed. Once
839     // the shim supports live debugging we should probably just stop automatically falling back to IL image and let the debugger
840     // decide via the ICorDebugMetadataLocator interface.
841     if(fDebuggeeLoadedNgen && !fDebuggerLoadingNgen && GetProcess()->GetShim()!=NULL)
842     {
843         // The IL image might be there, but we shouldn't use it for live debugging
844         return CORDBG_E_MISSING_METADATA;
845     }
846
847
848     // @dbgtodo  metadata  - This is really a CreateFile() call which we can't do. We must offload this to 
849     // the data target for the dump-debugging scenarios.
850     //
851     // We're opening it as "read". If we QI for an IEmit interface (which we need for EnC),
852     // then the metadata engine will convert it to a "write" underneath us.
853     // We want "read" so that we can let the OS share the pages.
854     DWORD dwOpenFlags = 0;
855
856     // If we know we're never going to need to write (i.e. never do EnC), then we should indicate
857     // that to metadata by telling it this interface will always be read-only.  By passing read-only,
858     // the metadata library will then also share the VM space for the image when the same image is
859     // opened multiple times for multiple AppDomains.  
860     // We don't currently have a way to tell absolutely whether this module will support EnC, but we
861     // know that NGen modules NEVER support EnC, and NGen is the common case that eats up a lot of VM.
862     // So we'll use the heuristic of opening the metadata for all ngen images as read-only.  Ideally
863     // we'd go even further here (perhaps even changing metadata to map only the region of the file it
864     // needs).
865     if (fDebuggerLoadingNgen)
866     {
867         dwOpenFlags = ofReadOnly | ofTrustedImage;
868     }
869
870     // This is the only place we ever validate that the file matches, because we're potentially
871     // loading the file from disk ourselves.  We're doing this without giving the debugger a chance
872     // to do anything.  We should never load a file that isn't an exact match.
873     return InitPublicMetaDataFromFile(szFullPathName, dwOpenFlags, true);
874 }
875
876 // We should only ever validate we have the correct file if it's a file we found ourselves.
877 // We allow the debugger to choose their own policy with regard to using metadata from the IL image
878 // when debugging an NI, or even intentionally using mismatched metadata if they like.
879 HRESULT CordbModule::InitPublicMetaDataFromFile(const WCHAR * pszFullPathName,
880                                                 DWORD dwOpenFlags,
881                                                 bool validateFileInfo)
882 {
883 #ifdef FEATURE_PAL    
884     // UNIXTODO: Some intricate details of file mapping don't work on Linux as on Windows.
885     // We have to revisit this and try to fix it for POSIX system. 
886     return E_FAIL;
887 #else    
888     if (validateFileInfo)
889     {
890         // Check that we've got the right file to target.
891         // There's nothing to prevent some other file being copied in for live, and with
892         // dump debugging there's nothing to say that we're not on another machine where a different
893         // file is at the same path.
894         // If we can't validate we have a hold of the correct file, we should not open it.
895         // We will fall back on asking the debugger to get us the correct file, or copying
896         // target memory back to the debugger.
897         DWORD dwImageTimeStamp = 0;
898         DWORD dwImageSize = 0;
899         bool isNGEN = false; // unused
900         StringCopyHolder filePath;
901
902         
903         _ASSERTE(!m_vmPEFile.IsNull());
904         // MetaData lookup favors the NGEN image, which is what we want here.
905         if (!this->GetProcess()->GetDAC()->GetMetaDataFileInfoFromPEFile(m_vmPEFile,
906                                                                          dwImageTimeStamp,
907                                                                          dwImageSize,
908                                                                          isNGEN,
909                                                                          &filePath))
910         {
911             LOG((LF_CORDB,LL_WARNING, "CM::IM: Couldn't get metadata info for file \"%s\"\n", pszFullPathName));
912             return CORDBG_E_MISSING_METADATA;
913         }
914
915         // If the timestamp and size don't match, then this is the wrong file!
916         // Map the file and check them.
917         HandleHolder hMDFile = WszCreateFile(pszFullPathName, 
918                                               GENERIC_READ, 
919                                               FILE_SHARE_READ, 
920                                               NULL,                 // default security descriptor
921                                               OPEN_EXISTING, 
922                                               FILE_ATTRIBUTE_NORMAL, 
923                                               NULL);
924
925         if (hMDFile == INVALID_HANDLE_VALUE)
926         {
927             LOG((LF_CORDB,LL_WARNING, "CM::IM: Couldn't open file \"%s\" (GLE=%x)\n", pszFullPathName, GetLastError()));
928             return CORDBG_E_MISSING_METADATA;
929         }
930
931         DWORD dwFileHigh = 0;
932         DWORD dwFileLow = GetFileSize(hMDFile, &dwFileHigh);
933         if (dwFileLow == INVALID_FILE_SIZE)
934         {
935             LOG((LF_CORDB,LL_WARNING, "CM::IM: File \"%s\" had invalid size.\n", pszFullPathName));
936             return CORDBG_E_MISSING_METADATA;
937         }
938
939         _ASSERTE(dwFileHigh == 0);
940
941         HandleHolder hMap = WszCreateFileMapping(hMDFile, NULL, PAGE_READONLY, dwFileHigh, dwFileLow, NULL);
942         if (hMap == NULL)
943         {
944             LOG((LF_CORDB,LL_WARNING, "CM::IM: Couldn't create mapping of file \"%s\" (GLE=%x)\n", pszFullPathName, GetLastError()));
945             return CORDBG_E_MISSING_METADATA;
946         }
947
948         MapViewHolder hMapView = MapViewOfFile(hMap, FILE_MAP_READ, 0, 0, 0);
949         if (hMapView == NULL)
950         {
951             LOG((LF_CORDB,LL_WARNING, "CM::IM: Couldn't map view of file \"%s\" (GLE=%x)\n", pszFullPathName, GetLastError()));
952             return CORDBG_E_MISSING_METADATA;
953         }
954
955         // Mapped as flat file, have PEDecoder go find what we want.
956         PEDecoder pedecoder(hMapView, (COUNT_T)dwFileLow);
957
958         if (!pedecoder.HasNTHeaders())
959         {
960             LOG((LF_CORDB,LL_WARNING, "CM::IM: \"%s\" did not have PE headers!\n", pszFullPathName));
961             return CORDBG_E_MISSING_METADATA;
962         }
963
964         if ((dwImageSize != pedecoder.GetVirtualSize()) ||
965             (dwImageTimeStamp != pedecoder.GetTimeDateStamp()))
966         {
967             LOG((LF_CORDB,LL_WARNING, "CM::IM: Validation of \"%s\" failed.  "
968                 "Expected size=%x, Expected timestamp=%x, Actual size=%x, Actual timestamp=%x\n", 
969                 pszFullPathName,
970                 pedecoder.GetVirtualSize(),
971                 pedecoder.GetTimeDateStamp(),
972                 dwImageSize,
973                 dwImageTimeStamp));
974             return CORDBG_E_MISSING_METADATA;
975         }
976
977         // All checks passed, go ahead and load this file for real.
978     }
979
980     // Get metadata Dispenser.
981     IMetaDataDispenserEx * pDisp = GetProcess()->GetDispenser();
982
983     HRESULT hr = pDisp->OpenScope(pszFullPathName, dwOpenFlags, IID_IMetaDataImport, (IUnknown**)&m_pIMImport);
984     _ASSERTE(SUCCEEDED(hr) == (m_pIMImport != NULL));
985
986     if (FAILED(hr))
987     {
988         // This should never happen in normal scenarios.  It could happen if someone has renamed
989         // the assembly after it was opened by the debugee process, but this should be rare enough
990         // that we don't mind taking the perf. hit and loading from memory.
991         // @dbgtodo  metadata  - would this happen in the shadow-copy scenario? 
992         LOG((LF_CORDB,LL_WARNING, "CM::IM: Couldn't open metadata in file \"%s\" (hr=%x)\n", pszFullPathName, hr));
993     }
994
995     return hr;
996 #endif // FEATURE_PAL     
997 }
998
999 //---------------------------------------------------------------------------------------
1000 // Initialize the public metadata.
1001 //
1002 // Arguments:
1003 //    buffer - valid buffer into target containing the metadata.
1004 //
1005 // Assumptions:
1006 //    This is an internal function which should only be called once to initialize the 
1007 //    metadata. Future attempts to re-initialize (in dynamic cases) should call code:CordbModule::UpdatePublicMetaDataFromRemote
1008 //    After the public metadata is initialized, initialize private metadata via code:CordbModule::UpdateInternalMetaData
1009 //
1010 void CordbModule::InitPublicMetaData(TargetBuffer buffer)
1011 {
1012     CONTRACTL
1013     {
1014         THROWS;
1015     }
1016     CONTRACTL_END;
1017
1018     INTERNAL_API_ENTRY(this->GetProcess());
1019     LOG((LF_CORDB,LL_INFO100000, "CM::IPM: initing with remote buffer 0x%p length 0x%x\n", 
1020         CORDB_ADDRESS_TO_PTR(buffer.pAddress), buffer.cbSize));
1021     ULONG nMetaDataSize = buffer.cbSize;
1022
1023     if (nMetaDataSize == 0)
1024     {
1025         // We should always have metadata, and if we don't, we want to know. 
1026         // @dbgtodo  metadata - we know metadata from dynamic modules doesn't work in V3 
1027         // (non-shim) cases yet.
1028         // But our caller should already have handled that case.
1029         SIMPLIFYING_ASSUMPTION(!"Error: missing the metadata");
1030         return;
1031     }
1032
1033     HRESULT hr = S_OK;
1034
1035     // Get metadata Dispenser.
1036     IMetaDataDispenserEx * pDisp = GetProcess()->GetDispenser();
1037
1038     // copy it over from the remote process
1039
1040     CoTaskMemHolder<VOID> pMetaDataCopy;
1041     CopyRemoteMetaData(buffer, pMetaDataCopy.GetAddr());
1042     
1043     
1044     //
1045     // Setup our metadata import object, m_pIMImport
1046     //
1047
1048     // Save the old mode for restoration
1049     VARIANT valueOld;
1050     hr = pDisp->GetOption(MetaDataSetUpdate, &valueOld);
1051     SIMPLIFYING_ASSUMPTION(!FAILED(hr));
1052
1053     // Set R/W mode so that we can update the metadata when
1054     // we do EnC operations.
1055     VARIANT valueRW;
1056     V_VT(&valueRW) = VT_UI4;
1057     V_I4(&valueRW) = MDUpdateFull;
1058     hr = pDisp->SetOption(MetaDataSetUpdate, &valueRW);
1059     SIMPLIFYING_ASSUMPTION(!FAILED(hr));
1060
1061     hr = pDisp->OpenScopeOnMemory(pMetaDataCopy,
1062                                   nMetaDataSize,
1063                                   ofTakeOwnership,
1064                                   IID_IMetaDataImport,
1065                                   reinterpret_cast<IUnknown**>( &m_pIMImport ));
1066
1067     // MetaData has taken ownership -don't free the memory
1068     pMetaDataCopy.SuppressRelease();
1069
1070     // Immediately restore the old setting. 
1071     HRESULT hrRestore = pDisp->SetOption(MetaDataSetUpdate, &valueOld);
1072     SIMPLIFYING_ASSUMPTION(!FAILED(hrRestore));
1073
1074     // Throw on errors.
1075     IfFailThrow(hr);    
1076     IfFailThrow(hrRestore);
1077
1078     // Done!
1079 }
1080
1081 //---------------------------------------------------------------------------------------
1082 // Update public MetaData by copying it from the target and updating our IMetaDataImport object.
1083 //
1084 // Arguments:
1085 //    buffer - buffer into target space containing metadata blob
1086 //
1087 // Notes:
1088 //     Useful for additional class-loads into a dynamic module. A new class means new metadata
1089 //     and so we need to update the RS metadata to stay in sync with the left-side.
1090 //
1091 //     This will call code:CordbModule::CopyRemoteMetaData to copy the remote buffer locally, and then
1092 //     it can OpenScopeOnMemory().
1093 //
1094 void CordbModule::UpdatePublicMetaDataFromRemote(TargetBuffer bufferRemoteMetaData)
1095 {    
1096     CONTRACTL
1097     {
1098         // @dbgtodo  metadata  - think about the error semantics here. These fails during dispatching an event; so 
1099         // address this during event pipeline. 
1100         THROWS;
1101     }
1102     CONTRACTL_END;
1103
1104     if (bufferRemoteMetaData.IsEmpty())
1105     {
1106         ThrowHR(E_INVALIDARG);
1107     }
1108     
1109     INTERNAL_API_ENTRY(this->GetProcess()); //
1110     LOG((LF_CORDB,LL_INFO100000, "CM::UPMFR: updating with remote buffer 0x%p length 0x%x\n", 
1111         CORDB_ADDRESS_TO_PTR(bufferRemoteMetaData.pAddress), bufferRemoteMetaData.cbSize));
1112     // We're re-initializing existing metadata.
1113     _ASSERTE(m_pIMImport != NULL);
1114
1115
1116     HRESULT hr = S_OK;
1117
1118     ULONG dwMetaDataSize = bufferRemoteMetaData.cbSize;
1119
1120     // First copy it from the remote process
1121     CoTaskMemHolder<VOID> pLocalMetaDataPtr;
1122     CopyRemoteMetaData(bufferRemoteMetaData, pLocalMetaDataPtr.GetAddr());
1123
1124     IMetaDataDispenserEx *  pDisp = GetProcess()->GetDispenser();    
1125     _ASSERTE(pDisp != NULL); // throws on error.
1126
1127     LOG((LF_CORDB,LL_INFO100000, "CM::RI: converting to new metadata\n"));
1128
1129     // now verify that the metadata is valid by opening a temporary scope on the memory
1130     {
1131         ReleaseHolder<IMetaDataImport> pIMImport;
1132         hr = pDisp->OpenScopeOnMemory(pLocalMetaDataPtr,
1133                                   dwMetaDataSize,
1134                                   0,
1135                                   IID_IMetaDataImport,
1136                                   (IUnknown**)&pIMImport);
1137         IfFailThrow(hr);
1138     }
1139
1140     // We reopen on an existing instance, not create a new instance.
1141     _ASSERTE(m_pIMImport != NULL); //
1142
1143     // Now tell our current IMetaDataImport object to re-initialize by swapping in the new memory block.
1144     // This allows us to keep manipulating metadata objects on other threads without crashing.
1145     // This will also invalidate an existing associated Internal MetaData.
1146     hr = ReOpenMetaDataWithMemoryEx(m_pIMImport, pLocalMetaDataPtr, dwMetaDataSize, ofTakeOwnership );
1147     IfFailThrow(hr);
1148
1149     // Success.  MetaData now owns the metadata memory
1150     pLocalMetaDataPtr.SuppressRelease();   
1151 }
1152
1153 //---------------------------------------------------------------------------------------
1154 // Copy metadata memory from the remote process into a newly allocated local buffer.
1155 //
1156 // Arguments:
1157 //    pRemoteMetaDataPtr - pointer to remote buffer
1158 //    dwMetaDataSize - size of buffer.
1159 //    pLocalBuffer - holder to get local buffer. 
1160 //
1161 // Returns:
1162 //    pLocalBuffer may be allocated.
1163 //    Throws on error (pLocalBuffer may contain garbage). 
1164 //    Else if successful, pLocalBuffer contains local copy of metadata.
1165 //
1166 // Notes:
1167 //    This can copy metadata out for the dynamic case or the normal case.
1168 //    Uses an allocator (CoTaskMemHolder) that lets us hand off the memory to the metadata.
1169 void CordbModule::CopyRemoteMetaData(
1170     TargetBuffer buffer,
1171     CoTaskMemHolder<VOID> * pLocalBuffer)
1172 {
1173     CONTRACTL
1174     {
1175         THROWS;
1176     }
1177     CONTRACTL_END;
1178
1179     _ASSERTE(pLocalBuffer != NULL);
1180     _ASSERTE(!buffer.IsEmpty());
1181
1182     // Allocate space for the local copy of the metadata
1183     // No need to zero out the memory since we'll fill it all here.
1184     LPVOID pRawBuffer = CoTaskMemAlloc(buffer.cbSize);
1185     if (pRawBuffer == NULL)
1186     {
1187         ThrowOutOfMemory();
1188     }
1189
1190     pLocalBuffer->Assign(pRawBuffer);
1191     
1192
1193
1194     // Copy the metadata from the left side
1195     GetProcess()->SafeReadBuffer(buffer, (BYTE *)pRawBuffer);
1196
1197     return;
1198 }
1199
1200 HRESULT CordbModule::QueryInterface(REFIID id, void **pInterface)
1201 {
1202     if (id == IID_ICorDebugModule)
1203     {
1204         *pInterface = static_cast<ICorDebugModule*>(this);
1205     }
1206     else if (id == IID_ICorDebugModule2)
1207     {
1208         *pInterface = static_cast<ICorDebugModule2*>(this);
1209     }
1210     else if (id == IID_ICorDebugModule3)
1211     {
1212         *pInterface = static_cast<ICorDebugModule3*>(this);
1213     }
1214     else if (id == IID_IUnknown)
1215     {
1216         *pInterface = static_cast<IUnknown*>(static_cast<ICorDebugModule*>(this));
1217     }
1218     else
1219     {
1220         *pInterface = NULL;
1221         return E_NOINTERFACE;
1222     }
1223
1224     ExternalAddRef();
1225     return S_OK;
1226 }
1227
1228 HRESULT CordbModule::GetProcess(ICorDebugProcess **ppProcess)
1229 {
1230     PUBLIC_API_ENTRY(this);
1231     FAIL_IF_NEUTERED(this);
1232     VALIDATE_POINTER_TO_OBJECT(ppProcess, ICorDebugProcess **);
1233
1234     *ppProcess = static_cast<ICorDebugProcess*> (GetProcess());
1235     GetProcess()->ExternalAddRef();
1236
1237     return S_OK;
1238 }
1239
1240 HRESULT CordbModule::GetBaseAddress(CORDB_ADDRESS *pAddress)
1241 {
1242     PUBLIC_API_ENTRY(this);
1243     FAIL_IF_NEUTERED(this);
1244     VALIDATE_POINTER_TO_OBJECT(pAddress, CORDB_ADDRESS *);
1245
1246     *pAddress = m_PEBuffer.pAddress;
1247     return S_OK;
1248 }
1249
1250 HRESULT CordbModule::GetAssembly(ICorDebugAssembly **ppAssembly)
1251 {
1252     PUBLIC_API_ENTRY(this);
1253     FAIL_IF_NEUTERED(this);
1254     VALIDATE_POINTER_TO_OBJECT(ppAssembly, ICorDebugAssembly **);
1255
1256     *ppAssembly = static_cast<ICorDebugAssembly *> (m_pAssembly);
1257     if (m_pAssembly != NULL)
1258     {
1259         m_pAssembly->ExternalAddRef();
1260     }
1261
1262     return S_OK;
1263 }
1264
1265 // Public implementation of ICorDebugModule::GetName,
1266 // wrapper around code:GetNameWorker (which throws).
1267 HRESULT CordbModule::GetName(ULONG32 cchName, ULONG32 *pcchName, __out_ecount_part_opt(cchName, *pcchName) WCHAR szName[])
1268 {
1269     HRESULT hr = S_OK;
1270     PUBLIC_API_BEGIN(this)
1271     {
1272         EX_TRY
1273         {
1274             hr = GetNameWorker(cchName, pcchName, szName);
1275         }
1276         EX_CATCH_HRESULT(hr);
1277
1278         // GetNameWorker can use metadata.  If it fails due to missing metadata, or if we fail to find expected
1279         // target memory (dump debugging) then we should fall back to getting the file name without metadata.
1280         if ((hr == CORDBG_E_MISSING_METADATA) ||
1281             (hr == CORDBG_E_READVIRTUAL_FAILURE) ||
1282             (hr == HRESULT_FROM_WIN32(ERROR_PARTIAL_COPY)))
1283         {
1284             DWORD dwImageTimeStamp = 0; // unused
1285             DWORD dwImageSize = 0;      // unused
1286             bool isNGEN = false;
1287             StringCopyHolder filePath;
1288
1289             _ASSERTE(!m_vmPEFile.IsNull());
1290             if (this->GetProcess()->GetDAC()->GetMetaDataFileInfoFromPEFile(m_vmPEFile,
1291                                                                              dwImageTimeStamp,
1292                                                                              dwImageSize,
1293                                                                              isNGEN,
1294                                                                              &filePath))
1295             {
1296                 _ASSERTE(filePath.IsSet());
1297
1298                 // Unfortunately, metadata lookup preferentially takes the ngen image - so in this case,
1299                 //  we need to go back and get the IL image's name instead.
1300                 if ((isNGEN) &&
1301                     (this->GetProcess()->GetDAC()->GetILImageInfoFromNgenPEFile(m_vmPEFile,
1302                                                                                 dwImageTimeStamp,
1303                                                                                 dwImageSize,
1304                                                                                 &filePath)))
1305                 {
1306                     _ASSERTE(filePath.IsSet());
1307                 }
1308
1309                 hr = CopyOutString(filePath, cchName, pcchName, szName);
1310             }
1311         }
1312     }
1313     PUBLIC_API_END(hr);
1314
1315     return hr;
1316 }
1317
1318 //---------------------------------------------------------------------------------------
1319 // Gets the module pretty name (may be filename or faked up name)
1320 // 
1321 // Arguments:
1322 //   cchName - count of characters in the szName buffer on input.
1323 //   *pcchName - Optional Out parameter, which gets set to the fully requested size
1324 //          (not just how many characters are written).
1325 //   szName - buffer to get name.
1326 //
1327 // Returns:
1328 //   S_OK on success.
1329 //   S_FALSE if we fabricate the name.
1330 //   Return failing HR (on common errors) or Throw on exceptional errors.
1331 // 
1332 // Note:
1333 //    Filename isn't necessarily the same as the module name in the metadata.
1334 //
1335 HRESULT CordbModule::GetNameWorker(ULONG32 cchName, ULONG32 *pcchName, __out_ecount_part_opt(cchName, *pcchName) WCHAR szName[])
1336 {
1337     CONTRACTL
1338     {
1339         THROWS;
1340     }
1341     CONTRACTL_END;
1342     HRESULT hr = S_OK;
1343     const WCHAR * szTempName = NULL;
1344
1345     ALLOW_DATATARGET_MISSING_MEMORY(
1346         szTempName = GetModulePath();
1347     );
1348
1349 #if defined(FEATURE_DBGIPC_TRANSPORT_DI)
1350     // To support VS when debugging remotely we act like the Compact Framework and return the assembly name
1351     // when asked for the name of an in-memory module.
1352     if (szTempName == NULL)
1353     {
1354         IMetaDataAssemblyImport *pAssemblyImport = NULL;
1355         if (SUCCEEDED(hr = GetMetaDataImporter()->QueryInterface(IID_IMetaDataAssemblyImport, (void**)&pAssemblyImport)))
1356         {
1357             mdAssembly mda = TokenFromRid(1, mdtAssembly);
1358             hr = pAssemblyImport->GetAssemblyProps(mda,          // [IN] The Assembly for which to get the properties.
1359                                                    NULL,         // [OUT] Pointer to the Originator blob.
1360                                                    NULL,         // [OUT] Count of bytes in the Originator Blob.
1361                                                    NULL,         // [OUT] Hash Algorithm.
1362                                                    szName,       // [OUT] Buffer to fill with name.
1363                                                    cchName,      // [IN] Size of buffer in wide chars.
1364                                                    (ULONG*)pcchName, // [OUT] Actual # of wide chars in name.
1365                                                    NULL,         // [OUT] Assembly MetaData.
1366                                                    NULL);        // [OUT] Flags.
1367
1368             pAssemblyImport->Release();
1369
1370             return hr;
1371         }
1372
1373         // reset hr
1374         hr = S_OK;
1375     }
1376
1377
1378 #endif // FEATURE_DBGIPC_TRANSPORT_DI
1379
1380
1381     EX_TRY_ALLOW_DATATARGET_MISSING_MEMORY
1382     {
1383         StringCopyHolder buffer;
1384         // If the module has no file name, then we'll fabricate a fake name
1385         if (!szTempName)
1386         {
1387             // On MiniDumpNormal, if the debugger can't find the module then there's no way we will
1388             // find metadata.
1389             hr = HRESULT_FROM_WIN32(ERROR_PARTIAL_COPY);
1390
1391             // Tempting to use the metadata-scope name, but that's a regression from Whidbey. For manifest modules,
1392             // the metadata scope name is not initialized with the string the user supplied to create the 
1393             // dynamic assembly. So we call into the runtime to use CLR heuristics to get a more accurate name.
1394             m_pProcess->GetDAC()->GetModuleSimpleName(m_vmModule, &buffer);
1395             _ASSERTE(buffer.IsSet());
1396             szTempName = buffer;
1397             // Note that we considered returning S_FALSE for fabricated names like this, but that's a breaking
1398             // change from Whidbey that is known to trigger bugs in vS.  If a debugger wants to differentiate
1399             // real path names from fake simple names, we'll just have to add a new API with the right semantics.
1400         }
1401
1402         hr = CopyOutString(szTempName, cchName, pcchName, szName);
1403     }
1404     EX_END_CATCH_ALLOW_DATATARGET_MISSING_MEMORY
1405
1406     return hr;
1407 }
1408
1409 //---------------------------------------------------------------------------------------
1410 // Gets actual name of loaded module. (no faked names)
1411 //
1412 // Returns: 
1413 //    string for full path to module name. This is a file that can be opened.
1414 //    NULL if name is not available (such as in some dynamic module cases)
1415 //    Throws if failed accessing target
1416 //
1417 // Notes:
1418 //    We avoid using the method name "GetModuleFileName" because winbase.h #defines that
1419 //    token (along with many others) to have an A or W suffix. 
1420 const WCHAR * CordbModule::GetModulePath()
1421 {
1422     // Lazily initialize.  Module filenames cannot change, and so once 
1423     // we've retrieved this successfully, it's stored for good.
1424     if (!m_strModulePath.IsSet())
1425     {
1426         IDacDbiInterface * pDac = m_pProcess->GetDAC(); // throws 
1427         pDac->GetModulePath(m_vmModule, &m_strModulePath); // throws
1428         _ASSERTE(m_strModulePath.IsSet());
1429     }
1430
1431     if (m_strModulePath.IsEmpty())
1432     {
1433         return NULL;    // module has no filename
1434     }
1435     return m_strModulePath;
1436 }
1437
1438 //---------------------------------------------------------------------------------------
1439 // Get and caches ngen image path.
1440 // 
1441 // Returns:
1442 //    Null-terminated string to ngen image path. 
1443 //    NULL if there is no ngen filename (eg, file is not ngenned).
1444 //    Throws on error (such as inability to read the path from the target).
1445 //
1446 // Notes:
1447 //    This can be used to get the path to find metadata. For ngenned images, 
1448 //    the IL (and associated metadata) may not be loaded, so we may want to get the 
1449 //    metadata out of the ngen image.
1450 const WCHAR * CordbModule::GetNGenImagePath()
1451 {
1452     HRESULT hr = S_OK;
1453     EX_TRY
1454     {
1455         // Lazily initialize.  Module filenames cannot change, and so once 
1456         // we've retrieved this successfully, it's stored for good.
1457         if (!m_strNGenImagePath.IsSet())
1458         {
1459             IDacDbiInterface * pDac = m_pProcess->GetDAC(); // throws 
1460             BOOL fNonEmpty = pDac->GetModuleNGenPath(m_vmModule, &m_strNGenImagePath); // throws
1461             (void)fNonEmpty; //prevent "unused variable" error from GCC
1462             _ASSERTE(m_strNGenImagePath.IsSet() && (m_strNGenImagePath.IsEmpty() == !fNonEmpty));
1463         }
1464     }
1465     EX_CATCH_HRESULT(hr);
1466
1467     if (FAILED(hr) || 
1468         m_strNGenImagePath == NULL ||
1469         m_strNGenImagePath.IsEmpty())
1470     {
1471         return NULL;    // module has no ngen filename
1472     }
1473     return m_strNGenImagePath;
1474 }
1475
1476 // Implementation of ICorDebugModule::EnableJITDebugging
1477 // See also code:CordbModule::SetJITCompilerFlags
1478 HRESULT CordbModule::EnableJITDebugging(BOOL bTrackJITInfo, BOOL bAllowJitOpts)
1479 {
1480     // Leftside will enforce that this is a valid time to change jit flags.
1481     // V1.0 behavior allowed setting these in the middle of a module's lifetime, which meant
1482     // that different methods throughout the module may have been jitted differently.
1483     // Since V2, this has to be set when the module is first loaded, before anything is jitted.
1484
1485     PUBLIC_API_ENTRY(this);
1486     FAIL_IF_NEUTERED(this);
1487
1488     DWORD dwFlags = CORDEBUG_JIT_DEFAULT;
1489
1490     // Since V2, bTrackJITInfo is the default and cannot be turned off.
1491     if (!bAllowJitOpts)
1492     {
1493         dwFlags |= CORDEBUG_JIT_DISABLE_OPTIMIZATION;
1494     }
1495     return SetJITCompilerFlags(dwFlags);
1496 }
1497
1498 HRESULT CordbModule::EnableClassLoadCallbacks(BOOL bClassLoadCallbacks)
1499 {
1500     PUBLIC_API_ENTRY(this);
1501     FAIL_IF_NEUTERED(this);
1502     ATT_ALLOW_LIVE_DO_STOPGO(GetProcess());
1503
1504     // You must receive ClassLoad callbacks for dynamic modules so that we can keep the metadata up-to-date on the Right
1505     // Side. Therefore, we refuse to turn them off for all dynamic modules (they were forced on when the module was
1506     // loaded on the Left Side.)
1507     if (m_fDynamic && !bClassLoadCallbacks)
1508         return E_INVALIDARG;
1509         
1510     if (m_vmDomainFile.IsNull())
1511         return E_UNEXPECTED;
1512
1513     // Send a Set Class Load Flag event to the left side. There is no need to wait for a response, and this can be
1514     // called whether or not the process is synchronized.
1515     CordbProcess *pProcess = GetProcess();
1516
1517     DebuggerIPCEvent event;
1518     pProcess->InitIPCEvent(&event,
1519                            DB_IPCE_SET_CLASS_LOAD_FLAG,
1520                            false,
1521                            (GetAppDomain()->GetADToken()));
1522     event.SetClassLoad.vmDomainFile = this->m_vmDomainFile;
1523     event.SetClassLoad.flag = (bClassLoadCallbacks == TRUE);
1524
1525     HRESULT hr = pProcess->m_cordb->SendIPCEvent(pProcess, &event,
1526                                                  sizeof(DebuggerIPCEvent));
1527     hr = WORST_HR(hr, event.hr);
1528     return hr;
1529 }
1530
1531 //-----------------------------------------------------------------------------
1532 // Public implementation of ICorDebugModule::GetFunctionFromToken
1533 // Get the CordbFunction matches this token / module pair.
1534 // Each time a function is Enc-ed, it gets its own CordbFunction object.
1535 // This will return the latest EnC version of the function for this Module,Token pair.
1536 HRESULT CordbModule::GetFunctionFromToken(mdMethodDef token,
1537                                           ICorDebugFunction **ppFunction)
1538 {
1539     // This is not reentrant. DBI should call code:CordbModule::LookupOrCreateFunctionLatestVersion instead.
1540     PUBLIC_API_ENTRY(this); 
1541     ATT_ALLOW_LIVE_DO_STOPGO(GetProcess()); // @todo - can this be RequiredStop?
1542
1543
1544     FAIL_IF_NEUTERED(this);
1545     VALIDATE_POINTER_TO_OBJECT(ppFunction, ICorDebugFunction **);
1546
1547     HRESULT hr = S_OK;
1548     EX_TRY
1549     {
1550         RSLockHolder lockHolder(GetProcess()->GetProcessLock());
1551
1552         // Check token is valid.
1553         if ((token == mdMethodDefNil) || 
1554             (!GetMetaDataImporter()->IsValidToken(token)))
1555         {
1556             ThrowHR(E_INVALIDARG);
1557         }
1558
1559         CordbFunction * pFunction = LookupOrCreateFunctionLatestVersion(token);
1560
1561         *ppFunction = static_cast<ICorDebugFunction*> (pFunction);
1562         pFunction->ExternalAddRef();
1563
1564     }
1565     EX_CATCH_HRESULT(hr);
1566     return hr;
1567 }
1568
1569 HRESULT CordbModule::GetFunctionFromRVA(CORDB_ADDRESS rva,
1570                                         ICorDebugFunction **ppFunction)
1571 {
1572     PUBLIC_API_ENTRY(this);
1573     FAIL_IF_NEUTERED(this);
1574     VALIDATE_POINTER_TO_OBJECT(ppFunction, ICorDebugFunction **);
1575
1576     return E_NOTIMPL;
1577 }
1578
1579 HRESULT CordbModule::LookupClassByToken(mdTypeDef token,
1580                                         CordbClass **ppClass)
1581 {
1582     INTERNAL_API_ENTRY(this->GetProcess()); //
1583     FAIL_IF_NEUTERED(this);
1584
1585     HRESULT hr = S_OK;
1586     EX_TRY // @dbgtodo  exceptions - push this up
1587     {
1588         *ppClass = NULL;
1589
1590         if ((token == mdTypeDefNil) || (TypeFromToken(token) != mdtTypeDef))
1591         {
1592             ThrowHR(E_INVALIDARG);
1593         }
1594
1595         RSLockHolder lockHolder(GetProcess()->GetProcessLock()); // @dbgtodo  synchronization - Push this up
1596
1597         CordbClass *pClass = m_classes.GetBase(token);
1598         if (pClass == NULL)
1599         {
1600             // Validate the token.
1601             if (!GetMetaDataImporter()->IsValidToken(token))
1602             {
1603                 ThrowHR(E_INVALIDARG);
1604             }
1605
1606             RSInitHolder<CordbClass> pClassInit(new CordbClass(this, token));
1607             pClass = pClassInit.TransferOwnershipToHash(&m_classes);
1608         }
1609
1610         *ppClass = pClass;
1611
1612     }
1613     EX_CATCH_HRESULT(hr);
1614     return hr;
1615 }
1616
1617 HRESULT CordbModule::GetClassFromToken(mdTypeDef token,
1618                                        ICorDebugClass **ppClass)
1619 {
1620     PUBLIC_API_ENTRY(this);
1621     FAIL_IF_NEUTERED(this);
1622     ATT_ALLOW_LIVE_DO_STOPGO(this->GetProcess()); // @todo - could this be RequiredStopped?
1623     VALIDATE_POINTER_TO_OBJECT(ppClass, ICorDebugClass **);
1624
1625     HRESULT hr = S_OK;
1626     EX_TRY
1627     {
1628         CordbClass *pClass = NULL;
1629         *ppClass = NULL;
1630
1631         // Validate the token.
1632         if (!GetMetaDataImporter()->IsValidToken(token))
1633         {
1634             ThrowHR(E_INVALIDARG);
1635         }
1636
1637         hr = LookupClassByToken(token, &pClass);
1638         IfFailThrow(hr);
1639
1640         *ppClass = static_cast<ICorDebugClass*> (pClass);
1641         pClass->ExternalAddRef();        
1642     } 
1643     EX_CATCH_HRESULT(hr);
1644     return hr;
1645 }
1646
1647 HRESULT CordbModule::CreateBreakpoint(ICorDebugModuleBreakpoint **ppBreakpoint)
1648 {
1649     PUBLIC_API_ENTRY(this);
1650     FAIL_IF_NEUTERED(this);
1651     VALIDATE_POINTER_TO_OBJECT(ppBreakpoint, ICorDebugModuleBreakpoint **);
1652
1653     return E_NOTIMPL;
1654 }
1655
1656 //
1657 // Return the token for the Module table entry for this object.  The token
1658 // may then be passed to the meta data import api's.
1659 //
1660 HRESULT CordbModule::GetToken(mdModule *pToken)
1661 {
1662     PUBLIC_API_ENTRY(this);
1663     FAIL_IF_NEUTERED(this);
1664     VALIDATE_POINTER_TO_OBJECT(pToken, mdModule *);
1665
1666     HRESULT hr = S_OK;
1667     EX_TRY
1668     {
1669         hr = GetMetaDataImporter()->GetModuleFromScope(pToken);
1670         IfFailThrow(hr);
1671     }
1672     EX_CATCH_HRESULT(hr);
1673     return hr;
1674 }
1675
1676
1677 // public implementation for ICorDebugModule::GetMetaDataInterface
1678 // Return a meta data interface pointer that can be used to examine the
1679 // meta data for this module.
1680 HRESULT CordbModule::GetMetaDataInterface(REFIID riid, IUnknown **ppObj)
1681 {
1682     PUBLIC_API_ENTRY(this);
1683     FAIL_IF_NEUTERED(this);
1684     VALIDATE_POINTER_TO_OBJECT(ppObj, IUnknown **);
1685
1686     HRESULT hr = S_OK;
1687     EX_TRY
1688     {
1689     // QI the importer that we already have and return the result.
1690         hr = GetMetaDataImporter()->QueryInterface(riid, (void**)ppObj);
1691         IfFailThrow(hr);
1692     }
1693     EX_CATCH_HRESULT(hr);
1694
1695     return hr;
1696 }
1697
1698 //-----------------------------------------------------------------------------
1699 // LookupFunctionLatestVersion finds the latest cached version of an existing CordbFunction 
1700 // in the given module. If the function doesn't exist, it returns NULL.
1701 //
1702 // Arguments:
1703 //     funcMetaDataToken - methoddef token for function to lookup
1704 //
1705 // 
1706 // Notes:
1707 //     If no CordbFunction instance was cached, then this returns NULL.
1708 //     use code:CordbModule::LookupOrCreateFunctionLatestVersion to do a lookup that will
1709 //     populate the cache if needed.
1710 CordbFunction* CordbModule::LookupFunctionLatestVersion(mdMethodDef funcMetaDataToken)
1711 {
1712     INTERNAL_API_ENTRY(this);
1713     return m_functions.GetBase(funcMetaDataToken);
1714 }
1715
1716
1717 //-----------------------------------------------------------------------------
1718 // Lookup (or create) the CordbFunction for the latest EnC version. 
1719 //
1720 // Arguments:
1721 //     funcMetaDataToken - methoddef token for function to lookup
1722 //
1723 // Returns:
1724 //     CordbFunction instance for that token. This will create an instance if needed, and so never returns null. 
1725 //     Throws on critical error.
1726 //
1727 // Notes:
1728 //     This creates the latest EnC version. Use code:CordbModule::LookupOrCreateFunction to do an
1729 //     enc-version aware function lookup.
1730 //
1731 CordbFunction* CordbModule::LookupOrCreateFunctionLatestVersion(mdMethodDef funcMetaDataToken)
1732 {
1733     INTERNAL_API_ENTRY(this);
1734     CordbFunction * pFunction = m_functions.GetBase(funcMetaDataToken);
1735     if (pFunction != NULL)
1736     {
1737         return pFunction;
1738     }
1739
1740     // EnC adds each version to the hash. So if the hash lookup fails, then it must not be an EnC case,
1741     // and so we can use the default version number.
1742     return CreateFunction(funcMetaDataToken, CorDB_DEFAULT_ENC_FUNCTION_VERSION);
1743 }
1744
1745 //-----------------------------------------------------------------------------
1746 // LookupOrCreateFunction finds an existing version of CordbFunction in the given module.
1747 // If the function doesn't exist, it creates it.
1748 //
1749 // The outgoing function is not yet fully inititalized. For eg, the Class field is not set. 
1750 // However, ICorDebugFunction::GetClass() will check that and lazily initialize the field.
1751 //
1752 // Throws on error.
1753 //
1754 CordbFunction * CordbModule::LookupOrCreateFunction(mdMethodDef funcMetaDataToken, SIZE_T enCVersion)
1755 {
1756     INTERNAL_API_ENTRY(this);
1757
1758     _ASSERTE(GetProcess()->ThreadHoldsProcessLock());
1759
1760     CordbFunction * pFunction = m_functions.GetBase(funcMetaDataToken);
1761
1762     // special case non-existance as need to add to the hash table too
1763     if (pFunction == NULL)
1764     {
1765         // EnC adds each version to the hash. So if the hash lookup fails, 
1766         // then it must not be an EnC case.
1767         return CreateFunction(funcMetaDataToken, enCVersion);
1768     }
1769
1770     // linked list sorted with most recent version at front. Version numbers correspond
1771     // to actual edit count against the module, so version numbers not necessarily contiguous.
1772     // Any valid EnC version must already exist as we would have created it on the ApplyChanges
1773     for (CordbFunction *pf=pFunction; pf != NULL; pf = pf->GetPrevVersion())
1774     {
1775         if (pf->GetEnCVersionNumber() == enCVersion)
1776         {
1777             return pf;
1778         }
1779     }
1780
1781     _ASSERTE(!"Couldn't find EnC version of function\n");
1782     ThrowHR(E_FAIL);
1783 }
1784
1785 HRESULT CordbModule::IsDynamic(BOOL *pDynamic)
1786 {
1787     PUBLIC_API_ENTRY(this);
1788     FAIL_IF_NEUTERED(this);
1789     VALIDATE_POINTER_TO_OBJECT(pDynamic, BOOL *);
1790
1791     (*pDynamic) = m_fDynamic;
1792
1793     return S_OK;
1794 }
1795
1796 BOOL CordbModule::IsDynamic()
1797 {
1798     return m_fDynamic;
1799 }
1800
1801
1802 HRESULT CordbModule::IsInMemory(BOOL *pInMemory)
1803 {
1804     PUBLIC_API_ENTRY(this);
1805     FAIL_IF_NEUTERED(this);
1806     VALIDATE_POINTER_TO_OBJECT(pInMemory, BOOL *);
1807
1808     (*pInMemory) = m_fInMemory;
1809
1810     return S_OK;
1811 }
1812
1813 HRESULT CordbModule::GetGlobalVariableValue(mdFieldDef fieldDef,
1814                                             ICorDebugValue **ppValue)
1815 {
1816     PUBLIC_API_ENTRY(this);
1817     FAIL_IF_NEUTERED(this);
1818     VALIDATE_POINTER_TO_OBJECT(ppValue, ICorDebugValue **);
1819     ATT_REQUIRE_STOPPED_MAY_FAIL(this->GetProcess());
1820
1821     HRESULT hr = S_OK;
1822     EX_TRY
1823     {
1824
1825         if (m_pClass == NULL)
1826         {
1827             CordbClass * pGlobalClass = NULL;
1828             hr = LookupClassByToken(COR_GLOBAL_PARENT_TOKEN, &pGlobalClass);
1829             IfFailThrow(hr);
1830
1831             m_pClass.Assign(pGlobalClass);
1832             _ASSERTE(m_pClass != NULL);
1833         }
1834
1835         hr = m_pClass->GetStaticFieldValue(fieldDef, NULL, ppValue);
1836         IfFailThrow(hr);
1837     }
1838     EX_CATCH_HRESULT(hr);
1839     return hr;
1840 }
1841
1842
1843
1844 //
1845 // CreateFunction creates a new function from the given information and
1846 // adds it to the module.
1847 //
1848 CordbFunction * CordbModule::CreateFunction(mdMethodDef funcMetaDataToken, SIZE_T enCVersion)
1849 {
1850     INTERNAL_API_ENTRY(this);
1851
1852     // In EnC cases, the token may not yet be valid. We may be caching the CordbFunction
1853     // for a token for an added method before the metadata is updated on the RS. 
1854     // We rely that our caller has done token validation.
1855
1856     // Create a new CordbFunction object or throw.
1857     RSInitHolder<CordbFunction> pFunction(new CordbFunction(this, funcMetaDataToken, enCVersion)); // throws
1858     CordbFunction * pCopy = pFunction.TransferOwnershipToHash(&m_functions);
1859     return pCopy;
1860 }
1861
1862 #ifdef EnC_SUPPORTED
1863 //---------------------------------------------------------------------------------------
1864 //
1865 // Creates a new CordbFunction object to represent this new version of a function and
1866 // updates the module's function collection to mark this as the latest version.
1867 //
1868 // Arguments:
1869 //    funcMetaDataToken - the functions methodDef token in this module
1870 //    enCVerison        - The new version number of this function
1871 //    ppFunction        - Output param for the new instance - optional
1872 //
1873 // Assumptions:
1874 //    Assumes the specified version of this function doesn't already exist (i.e. enCVersion
1875 //    is newer than all existing versions).
1876 //
1877 HRESULT CordbModule::UpdateFunction(mdMethodDef funcMetaDataToken,
1878                                     SIZE_T enCVersion,
1879                                     CordbFunction** ppFunction)
1880 {
1881     INTERNAL_API_ENTRY(this);
1882     if (ppFunction)
1883         *ppFunction = NULL;
1884
1885     _ASSERTE(funcMetaDataToken);
1886
1887     RSLockHolder lockHolder(GetProcess()->GetProcessLock());
1888
1889     // pOldVersion is the 2nd newest version
1890     CordbFunction* pOldVersion = LookupFunctionLatestVersion(funcMetaDataToken);
1891
1892     // if don't have an old version, then create a default versioned one as will most likely
1893     // go looking for it later and easier to put it in now than have code to insert it later.
1894     if (!pOldVersion)
1895     {
1896         LOG((LF_ENC, LL_INFO10000, "CM::UF: adding %8.8x with version %d\n", funcMetaDataToken, enCVersion));
1897         HRESULT hr = S_OK;
1898         EX_TRY
1899         {
1900             pOldVersion = CreateFunction(funcMetaDataToken, CorDB_DEFAULT_ENC_FUNCTION_VERSION);
1901         }
1902         EX_CATCH_HRESULT(hr);
1903         if (FAILED(hr))
1904         {
1905             return hr;
1906         }
1907     }
1908
1909     // This method should not be called for versions that already exist
1910     _ASSERTE( enCVersion > pOldVersion->GetEnCVersionNumber());
1911
1912     LOG((LF_ENC, LL_INFO10000, "CM::UF: updating %8.8x with version %d\n", funcMetaDataToken, enCVersion));
1913     // Create a new function object.
1914     CordbFunction * pNewVersion = new (nothrow) CordbFunction(this, funcMetaDataToken, enCVersion);
1915
1916     if (pNewVersion == NULL)
1917         return E_OUTOFMEMORY;
1918
1919     // Chain the 2nd most recent version onto this instance (this will internal addref).
1920     pNewVersion->SetPrevVersion(pOldVersion); 
1921
1922     // Add the function to the Module's hash of all functions.
1923     HRESULT hr = m_functions.SwapBase(pOldVersion, pNewVersion);
1924
1925     if (FAILED(hr))
1926     {
1927         delete pNewVersion;
1928         return hr;
1929     }
1930
1931     // Do cleanup for function which is no longer the latest version
1932     pNewVersion->GetPrevVersion()->MakeOld();
1933
1934     if (ppFunction)
1935         *ppFunction = pNewVersion;
1936
1937     return hr;
1938 }
1939 #endif // EnC_SUPPORTED
1940
1941
1942 HRESULT CordbModule::LookupOrCreateClass(mdTypeDef classMetaDataToken,CordbClass** ppClass)
1943 {
1944     INTERNAL_API_ENTRY(this);
1945     FAIL_IF_NEUTERED(this);
1946
1947     RSLockHolder lockHolder(GetProcess()->GetProcessLock()); // @dbgtodo  exceptions synchronization- 
1948                                                                // Push this lock up, convert to exceptions.
1949
1950     HRESULT hr = S_OK;
1951     *ppClass = LookupClass(classMetaDataToken);
1952     if (*ppClass == NULL)
1953     {
1954         hr = CreateClass(classMetaDataToken,ppClass);
1955         if (!SUCCEEDED(hr))
1956         {
1957             return hr;
1958         }
1959         _ASSERTE(*ppClass != NULL);
1960     }
1961     return hr;
1962 }
1963
1964 //
1965 // LookupClass finds an existing CordbClass in the given module.
1966 // If the class doesn't exist, it returns NULL.
1967 //
1968 CordbClass* CordbModule::LookupClass(mdTypeDef classMetaDataToken)
1969 {
1970     INTERNAL_API_ENTRY(this);
1971     _ASSERTE(GetProcess()->ThreadHoldsProcessLock());
1972     return m_classes.GetBase(classMetaDataToken);
1973 }
1974
1975 //
1976 // CreateClass creates a new class from the given information and
1977 // adds it to the module.
1978 //
1979 HRESULT CordbModule::CreateClass(mdTypeDef classMetaDataToken,
1980                                  CordbClass** ppClass)
1981 {
1982     INTERNAL_API_ENTRY(this);
1983     FAIL_IF_NEUTERED(this);
1984
1985     _ASSERTE(GetProcess()->ThreadHoldsProcessLock());
1986     
1987     CordbClass* pClass = new (nothrow) CordbClass(this, classMetaDataToken);
1988
1989     if (pClass == NULL)
1990         return E_OUTOFMEMORY;
1991
1992     HRESULT hr = m_classes.AddBase(pClass);
1993
1994     if (SUCCEEDED(hr))
1995         *ppClass = pClass;
1996     else
1997         delete pClass;
1998
1999     if (classMetaDataToken == COR_GLOBAL_PARENT_TOKEN)
2000     {
2001         _ASSERTE( m_pClass == NULL ); //redundant create
2002         m_pClass.Assign(pClass);
2003     }
2004
2005     return hr;
2006 }
2007
2008
2009 // Resolve a type-ref from this module to a CordbClass
2010 // 
2011 // Arguments:
2012 //    token - a Type Ref in this module's scope.
2013 //    ppClass - out parameter to get the class we resolve to.
2014 //    
2015 // Returns:
2016 //    S_OK on success.
2017 //    CORDBG_E_CLASS_NOT_LOADED is the TypeRef is not yet resolved because the type it will refer
2018 //    to is not yet loaded.
2019 //    
2020 // Notes:
2021 //    In general, a TypeRef refers to a type in another module. (Although as a corner case, it could
2022 //    refer to this module too). This resolves a TypeRef within the current module's scope to a 
2023 //    (TypeDef, metadata scope), which is in turn encapsulated as a CordbClass.
2024 //    
2025 //    A TypeRef has a resolution scope (ModuleRef or AssemblyRef) and string name for the type
2026 //    within that scope. Resolving means:
2027 //    1. Determining the actual metadata scope loaded for the resolution scope. 
2028 //        See also code:CordbModule::ResolveAssemblyInternal 
2029 //        If the resolved module hasn't been loaded yet, the resolution will fail.
2030 //    2. Doing a string lookup of the TypeRef's name within that resolved scope to find the TypeDef.
2031 //    3. Returning the (resolved scope, TypeDef) pair. 
2032 //    
2033 HRESULT CordbModule::ResolveTypeRef(mdTypeRef token, CordbClass **ppClass)
2034 {
2035     FAIL_IF_NEUTERED(this);
2036     INTERNAL_SYNC_API_ENTRY(GetProcess()); //
2037
2038     CordbProcess * pProcess = GetProcess();
2039
2040     _ASSERTE((pProcess->GetShim() == NULL) || pProcess->GetSynchronized());
2041
2042
2043     if ((token == mdTypeRefNil) || (TypeFromToken(token) != mdtTypeRef))
2044     {
2045         return E_INVALIDARG;
2046     }
2047     
2048     if (m_vmDomainFile.IsNull() || m_pAppDomain == NULL)
2049     {
2050         return E_UNEXPECTED;
2051     }
2052
2053     HRESULT         hr = S_OK;
2054     *ppClass = NULL;
2055     EX_TRY
2056     {
2057         TypeRefData inData = {m_vmDomainFile, token};
2058         TypeRefData outData;
2059
2060         {
2061             RSLockHolder lockHolder(pProcess->GetProcessLock());
2062             pProcess->GetDAC()->ResolveTypeReference(&inData, &outData);
2063         }
2064
2065         CordbModule * pModule = m_pAppDomain->LookupOrCreateModule(outData.vmDomainFile);
2066         IfFailThrow(pModule->LookupClassByToken(outData.typeToken, ppClass));
2067     }
2068     EX_CATCH_HRESULT(hr);
2069     
2070     return hr;
2071     
2072 } // CordbModule::ResolveTypeRef
2073
2074 // Resolve a type ref or def to a CordbClass
2075 // 
2076 // Arguments:
2077 //    token - a mdTypeDef or mdTypeRef in this module's scope to be resolved
2078 //    ppClass - out parameter to get the CordbClass for this type
2079 //     
2080 // Notes:
2081 //    See code:CordbModule::ResolveTypeRef for more details.
2082 HRESULT CordbModule::ResolveTypeRefOrDef(mdToken token, CordbClass **ppClass)
2083 {
2084     FAIL_IF_NEUTERED(this);
2085     INTERNAL_SYNC_API_ENTRY(this->GetProcess()); //
2086
2087     if ((token == mdTypeRefNil) ||
2088         (TypeFromToken(token) != mdtTypeRef && TypeFromToken(token) != mdtTypeDef))
2089         return E_INVALIDARG;
2090
2091     if (TypeFromToken(token)==mdtTypeRef)
2092     {
2093         // It's a type-ref. That means the type is defined in another module.
2094         // That other module is determined at runtime by Fusion / Loader policy. So we need to
2095         // ultimately ask the runtime which module was actually loaded.
2096         return ( ResolveTypeRef(token, ppClass) );
2097     }
2098     else
2099     {
2100         // It's a type-def. This is the easy case because the type is defined in this same module.
2101         return ( LookupClassByToken(token, ppClass) );
2102     }
2103
2104 }
2105
2106 //
2107 // GetSize returns the size of the module.
2108 //
2109 HRESULT CordbModule::GetSize(ULONG32 *pcBytes)
2110 {
2111     PUBLIC_API_ENTRY(this);
2112     FAIL_IF_NEUTERED(this);
2113     VALIDATE_POINTER_TO_OBJECT(pcBytes, ULONG32 *);
2114
2115     *pcBytes = m_PEBuffer.cbSize;
2116
2117     return S_OK;
2118 }
2119
2120 CordbAssembly *CordbModule::GetCordbAssembly()
2121 {
2122     INTERNAL_API_ENTRY(this);
2123     return m_pAssembly;
2124 }
2125
2126
2127 // This is legacy from the aborted V1 EnC attempt - not used in V2 EnC support
2128 HRESULT CordbModule::GetEditAndContinueSnapshot(
2129     ICorDebugEditAndContinueSnapshot **ppEditAndContinueSnapshot)
2130 {
2131     return E_NOTIMPL;
2132 }
2133
2134
2135 //---------------------------------------------------------------------------------------
2136 //
2137 // Requests that an edit be applied to the module for edit and continue and updates
2138 // the right-side state and metadata.
2139 //
2140 // Arguments:
2141 //    cbMetaData - number of bytes in pbMetaData
2142 //    pbMetaData - a delta metadata blob describing the metadata edits to be made
2143 //    cbIL       - number of bytes in pbIL
2144 //    pbIL       - a new method body stream containing all of the method body information
2145 //                 (IL, EH info, etc) for edited and added methods.
2146 //
2147 // Return Value:
2148 //    S_OK on success, various errors on failure
2149 //
2150 // Notes:
2151 //    
2152 //   
2153 //    This applies the same changes to the RS's copy of the metadata that the left-side will apply to
2154 //    it's copy of the metadata. see code:EditAndContinueModule::ApplyEditAndContinue
2155 //
2156 HRESULT CordbModule::ApplyChanges(ULONG  cbMetaData,
2157                                   BYTE   pbMetaData[], 
2158                                   ULONG  cbIL, 
2159                                   BYTE   pbIL[])
2160 {
2161     PUBLIC_API_ENTRY(this);
2162     FAIL_IF_NEUTERED(this);
2163     ATT_REQUIRE_STOPPED_MAY_FAIL(GetProcess());
2164
2165 #ifdef EnC_SUPPORTED
2166     // We enable EnC back in code:CordbModule::SetJITCompilerFlags.
2167     // If EnC isn't enabled, then we'll fail in the LS when we try to ApplyChanges. 
2168     // We'd expect a well-behaved debugger to never actually land here.
2169
2170
2171     LOG((LF_CORDB,LL_INFO10000, "CP::AC: applying changes"));
2172
2173     VALIDATE_POINTER_TO_OBJECT_ARRAY(pbMetaData,
2174                                    BYTE,
2175                                    cbMetaData,
2176                                    true,
2177                                    true);
2178     VALIDATE_POINTER_TO_OBJECT_ARRAY(pbIL,
2179                                    BYTE,
2180                                    cbIL,
2181                                    true,
2182                                    true);
2183
2184     HRESULT hr;
2185     RSExtSmartPtr<IUnknown> pUnk;
2186     RSExtSmartPtr<IMDInternalImport> pMDImport;
2187     RSExtSmartPtr<IMDInternalImport> pMDImport2;
2188
2189     //
2190     // Edit was successful - update the right-side state to reflect the edit
2191     //
2192
2193     ++m_EnCCount;
2194
2195     // apply the changes to our copy of the metadata
2196
2197     _ASSERTE(m_pIMImport != NULL); // must have metadata at this point in EnC
2198     IfFailGo(m_pIMImport->QueryInterface(IID_IUnknown, (void**)&pUnk));
2199
2200     IfFailGo(GetMDInternalInterfaceFromPublic(pUnk, IID_IMDInternalImport,
2201                                                     (void **)&pMDImport));
2202
2203     // The left-side will call this same method on its copy of the metadata.
2204     hr = pMDImport->ApplyEditAndContinue(pbMetaData, cbMetaData, &pMDImport2);
2205     if (pMDImport2 != NULL) 
2206     {
2207         // ApplyEditAndContinue() expects IMDInternalImport**, but we give it RSExtSmartPtr<IMDInternalImport>
2208         // Silent cast of RSExtSmartPtr to IMDInternalImport* leads to assignment of a raw pointer
2209         // without calling AddRef(), thus we need to do it manually.
2210
2211         // @todo -  ApplyEditAndContinue should probably AddRef the out parameter.
2212         pMDImport2->AddRef(); 
2213     }
2214     IfFailGo(hr);
2215
2216    
2217     // We're about to get a new importer object, so release the old one.
2218     m_pIMImport.Clear();
2219     IfFailGo(GetMDPublicInterfaceFromInternal(pMDImport2, IID_IMetaDataImport, (void **)&m_pIMImport));
2220     // set the new RVA value
2221     
2222     // Send the delta over to the debugee and request that it apply the edit
2223     IfFailGo( ApplyChangesInternal(cbMetaData, pbMetaData, cbIL, pbIL) );
2224
2225     EX_TRY
2226     {
2227
2228         m_pInternalMetaDataImport.Clear();
2229         UpdateInternalMetaData();
2230     }
2231     EX_CATCH_HRESULT(hr);    
2232     _ASSERTE(SUCCEEDED(hr));
2233
2234 ErrExit:
2235     // MetaData interface pointers will be automatically released via SmartPtr dtors.
2236
2237     // @todo : prevent further execution of program
2238     return hr;
2239 #else
2240     return E_NOTIMPL;
2241 #endif
2242 }
2243
2244
2245
2246
2247 //---------------------------------------------------------------------------------------
2248 //
2249 // Requests that an edit be applied to the module for edit and continue and updates
2250 // some right-side state, but does not update our copy of the metadata.
2251 //
2252 // Arguments:
2253 //    cbMetaData - number of bytes in pbMetaData
2254 //    pbMetaData - a delta metadata blob describing the metadata edits to be made
2255 //    cbIL       - number of bytes in pbIL
2256 //    pbIL       - a new method body stream containing all of the method body information
2257 //                 (IL, EH info, etc) for edited and added methods.
2258 //
2259 // Return Value:
2260 //    S_OK on success, various errors on failure
2261 //
2262 HRESULT CordbModule::ApplyChangesInternal(ULONG  cbMetaData, 
2263                                           BYTE   pbMetaData[], 
2264                                           ULONG  cbIL, 
2265                                           BYTE   pbIL[])
2266 {
2267     CONTRACTL
2268     {
2269         NOTHROW;
2270     }
2271     CONTRACTL_END;
2272
2273     LOG((LF_ENC,LL_INFO100, "CordbProcess::ApplyChangesInternal\n"));
2274
2275     FAIL_IF_NEUTERED(this);
2276     INTERNAL_SYNC_API_ENTRY(this->GetProcess()); //
2277     
2278     if (m_vmDomainFile.IsNull())
2279         return E_UNEXPECTED;
2280
2281 #ifdef EnC_SUPPORTED
2282     HRESULT hr;
2283
2284     void * pRemoteBuf = NULL;
2285
2286     EX_TRY
2287     {
2288
2289         // Create and initialize the event as synchronous
2290         // We'll be sending a NULL appdomain pointer since the individual modules
2291         // will contains pointers to their respective A.D.s
2292         DebuggerIPCEvent event;
2293         GetProcess()->InitIPCEvent(&event, DB_IPCE_APPLY_CHANGES, false, VMPTR_AppDomain::NullPtr());
2294
2295         event.ApplyChanges.vmDomainFile = this->m_vmDomainFile;
2296
2297         // Have the left-side create a buffer for us to store the delta into
2298         ULONG cbSize = cbMetaData+cbIL;
2299         TargetBuffer tbFull = GetProcess()->GetRemoteBuffer(cbSize);
2300         pRemoteBuf = CORDB_ADDRESS_TO_PTR(tbFull.pAddress);
2301
2302         TargetBuffer tbMetaData = tbFull.SubBuffer(0, cbMetaData); // 1st half
2303         TargetBuffer tbIL = tbFull.SubBuffer(cbMetaData); // 2nd half
2304
2305         // Copy the delta metadata over to the debugee
2306
2307         GetProcess()->SafeWriteBuffer(tbMetaData, pbMetaData); // throws
2308         GetProcess()->SafeWriteBuffer(tbIL, pbIL); // throws
2309             
2310         // Send a synchronous event requesting the debugee apply the edit
2311         event.ApplyChanges.pDeltaMetadata = tbMetaData.pAddress;
2312         event.ApplyChanges.cbDeltaMetadata = tbMetaData.cbSize;
2313         event.ApplyChanges.pDeltaIL = tbIL.pAddress;
2314         event.ApplyChanges.cbDeltaIL = tbIL.cbSize;
2315
2316         LOG((LF_ENC,LL_INFO100, "CordbProcess::ApplyChangesInternal sending event\n"));
2317         hr = GetProcess()->SendIPCEvent(&event, sizeof(event));
2318         hr = WORST_HR(hr, event.hr);
2319         IfFailThrow(hr);
2320
2321         // Allocate space for the return event.
2322         // We always copy over the whole buffer size which is bigger than sizeof(DebuggerIPCEvent)
2323         // This seems ugly, in this case we know the exact size of the event we want to read
2324         // why copy over all the extra data?
2325         DebuggerIPCEvent *retEvent = (DebuggerIPCEvent *) _alloca(CorDBIPC_BUFFER_SIZE);
2326
2327         {
2328             //
2329             // Wait for events to return from the RC. We expect zero or more add field,
2330             // add function or update function events and one completion event.
2331             //
2332             while (TRUE)
2333             {
2334                 hr = GetProcess()->m_cordb->WaitForIPCEventFromProcess(GetProcess(),
2335                                                                        GetAppDomain(),
2336                                                                        retEvent);
2337                 IfFailThrow(hr);
2338
2339                 if (retEvent->type == DB_IPCE_APPLY_CHANGES_RESULT)
2340                 {
2341                     // Done receiving update events
2342                     hr = retEvent->ApplyChangesResult.hr;
2343                     LOG((LF_CORDB, LL_INFO1000, "[%x] RCET::DRCE: EnC apply changes result %8.8x.\n", hr));
2344                     break;
2345                 }
2346
2347                 _ASSERTE(retEvent->type == DB_IPCE_ENC_UPDATE_FUNCTION ||
2348                                   retEvent->type == DB_IPCE_ENC_ADD_FUNCTION ||
2349                                   retEvent->type == DB_IPCE_ENC_ADD_FIELD);
2350                 LOG((LF_CORDB, LL_INFO1000, "[%x] RCET::DRCE: EnC %s %8.8x to version %d.\n",
2351                         GetCurrentThreadId(),
2352                         retEvent->type == DB_IPCE_ENC_UPDATE_FUNCTION ? "Update function" :
2353                         retEvent->type == DB_IPCE_ENC_ADD_FUNCTION ? "Add function" : "Add field",
2354                         retEvent->EnCUpdate.memberMetadataToken, retEvent->EnCUpdate.newVersionNumber));
2355
2356                 CordbAppDomain *pAppDomain = GetAppDomain();
2357                 _ASSERTE(NULL != pAppDomain);
2358                 CordbModule* pModule = NULL;
2359
2360                 
2361                 pModule = pAppDomain->LookupOrCreateModule(retEvent->EnCUpdate.vmDomainFile); // throws            
2362                 _ASSERTE(pModule != NULL);
2363
2364                 // update to the newest version
2365
2366                 if (retEvent->type == DB_IPCE_ENC_UPDATE_FUNCTION ||
2367                      retEvent->type == DB_IPCE_ENC_ADD_FUNCTION)
2368                 {
2369                     // Update the function collection to reflect this edit
2370                     hr = pModule->UpdateFunction(retEvent->EnCUpdate.memberMetadataToken, retEvent->EnCUpdate.newVersionNumber, NULL);
2371                         
2372                 }
2373                 // mark the class and relevant type as old so we update it next time we try to query it
2374                 if (retEvent->type == DB_IPCE_ENC_ADD_FUNCTION ||
2375                      retEvent->type == DB_IPCE_ENC_ADD_FIELD)
2376                 {
2377                     RSLockHolder lockHolder(GetProcess()->GetProcessLock()); // @dbgtodo  synchronization -  push this up 
2378                     CordbClass* pClass = pModule->LookupClass(retEvent->EnCUpdate.classMetadataToken);
2379                     // if don't find class, that is fine because it hasn't been loaded yet so doesn't
2380                     // need to be updated
2381                     if (pClass)
2382                     {
2383                         pClass->MakeOld();
2384                     }
2385                 }
2386             }
2387         }
2388
2389         LOG((LF_ENC,LL_INFO100, "CordbProcess::ApplyChangesInternal complete.\n"));
2390     } 
2391     EX_CATCH_HRESULT(hr);
2392     
2393     // process may have gone away by the time we get here so don't assume is there.
2394     CordbProcess *pProcess = GetProcess();
2395     if (pProcess)
2396     {        
2397         HRESULT hr2 = pProcess->ReleaseRemoteBuffer(&pRemoteBuf);
2398         TESTANDRETURNHR(hr2);
2399     }
2400     return hr;
2401 #else // EnC_SUPPORTED
2402     return E_NOTIMPL;
2403 #endif // EnC_SUPPORTED
2404
2405 }
2406
2407 // Set the JMC status for the entire module.
2408 // All methods specified in others[] will have jmc status !fIsUserCode
2409 // All other methods will have jmc status fIsUserCode.
2410 HRESULT CordbModule::SetJMCStatus(
2411         BOOL fIsUserCode,
2412         ULONG32 cOthers,
2413         mdToken others[])
2414 {
2415     PUBLIC_API_ENTRY(this);
2416     FAIL_IF_NEUTERED(this);
2417     ATT_REQUIRE_STOPPED_MAY_FAIL(GetProcess());
2418     
2419     if (m_vmDomainFile.IsNull())
2420         return E_UNEXPECTED;
2421
2422     // @todo -allow the other parameters. These are functions that have default status
2423     // opposite of fIsUserCode.
2424     if (cOthers != 0)
2425     {
2426         _ASSERTE(!"not yet impl for cOthers != 0");
2427         return E_NOTIMPL;
2428     }
2429
2430     // Send event to the LS.
2431     CordbProcess* pProcess = this->GetProcess();
2432     _ASSERTE(pProcess != NULL);
2433
2434
2435     // Tell the LS that this module is/is not user code
2436     DebuggerIPCEvent event;
2437     pProcess->InitIPCEvent(&event, DB_IPCE_SET_MODULE_JMC_STATUS, true, this->GetAppDomain()->GetADToken());
2438     event.SetJMCFunctionStatus.vmDomainFile = m_vmDomainFile;
2439     event.SetJMCFunctionStatus.dwStatus = fIsUserCode;
2440
2441
2442     // Note: two-way event here...
2443     HRESULT hr = pProcess->m_cordb->SendIPCEvent(pProcess, &event, sizeof(DebuggerIPCEvent));
2444
2445     // Stop now if we can't even send the event.
2446     if (!SUCCEEDED(hr))
2447     {
2448         LOG((LF_CORDB, LL_INFO10, "CordbModule::SetJMCStatus failed  0x%08x...\n", hr));
2449
2450         return hr;
2451     }
2452
2453     _ASSERTE(event.type == DB_IPCE_SET_MODULE_JMC_STATUS_RESULT);
2454
2455     LOG((LF_CORDB, LL_INFO10, "returning from CordbModule::SetJMCStatus 0x%08x...\n", hr));
2456
2457     return event.hr;
2458 }
2459
2460
2461 //
2462 // Resolve an assembly given an AssemblyRef token. Note that
2463 // this will not trigger the loading of assembly. If assembly is not yet loaded,
2464 // this will return an CORDBG_E_CANNOT_RESOLVE_ASSEMBLY error
2465 //
2466 HRESULT CordbModule::ResolveAssembly(mdToken tkAssemblyRef,
2467                                     ICorDebugAssembly **ppAssembly)
2468 {
2469     PUBLIC_API_ENTRY(this);
2470     FAIL_IF_NEUTERED(this);
2471     ATT_REQUIRE_STOPPED_MAY_FAIL(this->GetProcess());
2472
2473     if(ppAssembly)
2474     {
2475         *ppAssembly = NULL;
2476     }
2477
2478     HRESULT hr = S_OK;
2479     EX_TRY
2480     {
2481         CordbAssembly *pCordbAsm = ResolveAssemblyInternal(tkAssemblyRef);
2482         if (pCordbAsm == NULL)
2483         {
2484             // Don't throw here. It's a common-case failure path and not exceptional.
2485             hr = CORDBG_E_CANNOT_RESOLVE_ASSEMBLY;
2486         }
2487         else if(ppAssembly)
2488         {
2489             _ASSERTE(pCordbAsm != NULL);
2490             *ppAssembly = pCordbAsm;
2491             pCordbAsm->ExternalAddRef();
2492         }
2493     }
2494     EX_CATCH_HRESULT(hr);
2495     return hr;
2496 }
2497
2498 //---------------------------------------------------------------------------------------
2499 // Worker to resolve an assembly ref.
2500 // 
2501 // Arguments:
2502 //     tkAssemblyRef - token of assembly ref to resolve
2503 //
2504 // Returns:
2505 //     Assembly that this token resolves to.
2506 //     NULL if it's a valid token but the assembly has not yet been resolved. 
2507 //      (This is a non-exceptional error case).
2508 //
2509 // Notes:
2510 //     MetaData has tokens to represent a reference to another assembly.
2511 //     But Loader/Fusion policy ultimately decides which specific assembly is actually loaded
2512 //     for that token. 
2513 //     This does the lookup of actual assembly and reports back to the debugger.
2514
2515 CordbAssembly * CordbModule::ResolveAssemblyInternal(mdToken tkAssemblyRef)
2516 {
2517     INTERNAL_SYNC_API_ENTRY(GetProcess()); //
2518     
2519     if (TypeFromToken(tkAssemblyRef) != mdtAssemblyRef || tkAssemblyRef == mdAssemblyRefNil)
2520     {
2521         // Not a valid token
2522         ThrowHR(E_INVALIDARG);
2523     }
2524
2525     CordbAssembly *    pAssembly = NULL;
2526
2527     if (!m_vmDomainFile.IsNull())
2528     {
2529         // Get DAC to do the real work to resolve the assembly
2530         VMPTR_DomainAssembly vmDomainAssembly = GetProcess()->GetDAC()->ResolveAssembly(m_vmDomainFile, tkAssemblyRef);
2531             
2532         // now find the ICorDebugAssembly corresponding to it
2533         if (!vmDomainAssembly.IsNull() && m_pAppDomain != NULL)
2534         {
2535             RSLockHolder lockHolder(GetProcess()->GetProcessLock());
2536             // Don't throw here because if the lookup fails, we want to throw CORDBG_E_CANNOT_RESOLVE_ASSEMBLY.
2537             pAssembly = m_pAppDomain->LookupOrCreateAssembly(vmDomainAssembly);
2538         }
2539     }
2540     
2541     return pAssembly;
2542 }
2543
2544 //
2545 // CreateReaderForInMemorySymbols - create an ISymUnmanagedReader object for symbols
2546 // which are loaded into memory in the CLR.  See interface definition in cordebug.idl for 
2547 // details.
2548 // 
2549 HRESULT CordbModule::CreateReaderForInMemorySymbols(REFIID riid, void** ppObj)
2550 {
2551     PUBLIC_API_ENTRY(this);
2552     FAIL_IF_NEUTERED(this);
2553
2554     CordbProcess *pProcess = GetProcess();
2555     ATT_REQUIRE_STOPPED_MAY_FAIL(pProcess);
2556
2557     HRESULT hr = S_OK;
2558     EX_TRY
2559     {
2560         // Get the symbol memory in a stream to give to the reader.
2561         ReleaseHolder<IStream> pStream;
2562         IDacDbiInterface::SymbolFormat symFormat = GetInMemorySymbolStream(&pStream);
2563
2564         // First create the symbol binder corresponding to the format of the stream
2565         ReleaseHolder<ISymUnmanagedBinder> pBinder;
2566         if (symFormat == IDacDbiInterface::kSymbolFormatPDB)
2567         {
2568 #ifndef FEATURE_PAL
2569             // PDB format - use diasymreader.dll with COM activation
2570             InlineSString<_MAX_PATH> ssBuf;
2571             IfFailThrow(GetHModuleDirectory(GetModuleInst(), ssBuf));
2572             IfFailThrow(FakeCoCreateInstanceEx(CLSID_CorSymBinder_SxS,
2573                                                ssBuf.GetUnicode(),
2574                                                IID_ISymUnmanagedBinder,
2575                                                (void**)&pBinder,
2576                                                NULL));
2577 #else
2578             IfFailThrow(FakeCoCreateInstance(CLSID_CorSymBinder_SxS,
2579                                              IID_ISymUnmanagedBinder,
2580                                              (void**)&pBinder));
2581 #endif
2582         }
2583         else if (symFormat == IDacDbiInterface::kSymbolFormatILDB)
2584         {
2585             // ILDB format - use statically linked-in ildbsymlib
2586             IfFailThrow(IldbSymbolsCreateInstance(CLSID_CorSymBinder_SxS,
2587                                                 IID_ISymUnmanagedBinder,
2588                                                 (void**)&pBinder));
2589         }
2590         else
2591         {
2592             // No in-memory symbols, return the appropriate error
2593             _ASSERTE(symFormat == IDacDbiInterface::kSymbolFormatNone);
2594             if (m_fDynamic || m_fInMemory)
2595             {
2596                 // This is indeed an in-memory or dynamic module, we just don't have any symbols for it.
2597                 // This means the application didn't supply any, or they are not yet available.  Symbols
2598                 // first become available at LoadClass time for dynamic modules and UpdateModuleSymbols
2599                 // time for non-dynamic in-memory modules.
2600                 ThrowHR(CORDBG_E_SYMBOLS_NOT_AVAILABLE);
2601             }
2602
2603             // This module is on disk - the debugger should use it's normal symbol-loading logic.
2604             ThrowHR(CORDBG_E_MODULE_LOADED_FROM_DISK);
2605         }
2606
2607         // In the attach or dump case, if we attach or take the dump after we have defined a dynamic module, we may
2608         // have already set the symbol format to "PDB" by the time we call CreateReaderForInMemorySymbols during initialization 
2609         // for loaded modules. (In the launch case, we do this initialization when the module is actually loaded, and before we 
2610         // set the symbol format.) When we call CreateReaderForInMemorySymbols, we can't assume the initialization was already 
2611         // performed or specifically, that we already have m_pIMImport initialized. We can't call into diasymreader with a NULL 
2612         // pointer as the value for m_pIMImport, so we need to check that here.
2613         if (m_pIMImport == NULL)
2614         {
2615             ThrowHR(CORDBG_E_SYMBOLS_NOT_AVAILABLE);
2616         }
2617
2618         // Now create the symbol reader from the data 
2619         ReleaseHolder<ISymUnmanagedReader> pReader;
2620         IfFailThrow(pBinder->GetReaderFromStream(m_pIMImport, pStream, &pReader));
2621
2622         // Attempt to return the interface requested
2623         // Note that this does an AddRef for our return value ppObj, so we don't suppress the release
2624         // of the pReader holder.
2625         IfFailThrow(pReader->QueryInterface(riid, ppObj));
2626     }
2627     EX_CATCH_HRESULT(hr);
2628     return hr; 
2629 }
2630
2631 /* ------------------------------------------------------------------------- *
2632  * Class class
2633  * ------------------------------------------------------------------------- */
2634
2635 //---------------------------------------------------------------------------------------
2636 // Set the continue counter that marks when the module is in its Load event
2637 //    
2638 // Notes:
2639 //    Jit flags can only be changed in the real module Load event. We may
2640 //    have multiple module load events on different threads coming at the
2641 //    same time. So each module load tracks its continue counter.  
2642 //    
2643 //    This can be used by code:CordbModule::EnsureModuleIsInLoadCallback to
2644 //    properly return CORDBG_E_MUST_BE_IN_LOAD_MODULE
2645 void CordbModule::SetLoadEventContinueMarker()
2646 {
2647     // Well behaved targets should only set this once.
2648     GetProcess()->TargetConsistencyCheck(m_nLoadEventContinueCounter == 0);
2649
2650     m_nLoadEventContinueCounter = GetProcess()->m_continueCounter;
2651 }
2652
2653 //---------------------------------------------------------------------------------------
2654 // Return CORDBG_E_MUST_BE_IN_LOAD_MODULE if the module is not in the load module callback. 
2655 // 
2656 // Notes:
2657 //   The comparison is done via continue counters. The counter of the load
2658 //   event is cached via code:CordbModule::SetLoadEventContinueMarker. 
2659 //   
2660 //   This state is currently stored on the RS. Alternatively, it could likely be retreived from the LS state as
2661 //   well. One disadvantage of the current model is that if we detach during the load-module callback and
2662 //   then reattach, the RS state is flushed and we lose the fact that we can toggle the jit flags.
2663 HRESULT CordbModule::EnsureModuleIsInLoadCallback()
2664 {    
2665     if (this->m_nLoadEventContinueCounter < GetProcess()->m_continueCounter)
2666     {
2667         return CORDBG_E_MUST_BE_IN_LOAD_MODULE;
2668     }
2669     else
2670     {
2671         return S_OK;
2672     }
2673 }
2674
2675 // Implementation of ICorDebugModule2::SetJITCompilerFlags
2676 // See also code:CordbModule::EnableJITDebugging
2677 HRESULT CordbModule::SetJITCompilerFlags(DWORD dwFlags)
2678 {
2679     PUBLIC_REENTRANT_API_ENTRY(this);    
2680     FAIL_IF_NEUTERED(this);
2681
2682     CordbProcess *pProcess = GetProcess();
2683
2684     ATT_REQUIRE_STOPPED_MAY_FAIL(pProcess);
2685     HRESULT hr = S_OK;
2686
2687     EX_TRY
2688     {
2689         // can't have a subset of these, eg 0x101, so make sure we have an exact match
2690         if ((dwFlags != CORDEBUG_JIT_DEFAULT) &&
2691             (dwFlags != CORDEBUG_JIT_DISABLE_OPTIMIZATION) &&
2692             (dwFlags != CORDEBUG_JIT_ENABLE_ENC))
2693         {
2694             hr = E_INVALIDARG;
2695         }
2696         else
2697         {
2698             BOOL fAllowJitOpts = ((dwFlags & CORDEBUG_JIT_DISABLE_OPTIMIZATION) != CORDEBUG_JIT_DISABLE_OPTIMIZATION);
2699             BOOL fEnableEnC = ((dwFlags & CORDEBUG_JIT_ENABLE_ENC) == CORDEBUG_JIT_ENABLE_ENC);
2700
2701             // Can only change jit flags when module is first loaded and before there's any jitted code.
2702             // This ensures all code in the module is jitted the same way. 
2703             hr = EnsureModuleIsInLoadCallback();
2704
2705             if (SUCCEEDED(hr))
2706             {
2707                 // DD interface will check if it's a valid time to change the flags.
2708                 hr = pProcess->GetDAC()->SetCompilerFlags(GetRuntimeDomainFile(), fAllowJitOpts, fEnableEnC);
2709             }
2710         }
2711     }
2712     EX_CATCH_HRESULT(hr);
2713
2714     // emulate v2 hresults
2715     if (GetProcess()->GetShim() != NULL)
2716     {
2717         // Emulate Whidbey error hresults
2718         hr = GetProcess()->GetShim()->FilterSetJitFlagsHresult(hr);
2719     }
2720     return hr;
2721     
2722 }
2723
2724 // Implementation of ICorDebugModule2::GetJitCompilerFlags
2725 HRESULT CordbModule::GetJITCompilerFlags(DWORD *pdwFlags )
2726 {
2727     PUBLIC_REENTRANT_API_ENTRY(this);
2728     FAIL_IF_NEUTERED(this);
2729     VALIDATE_POINTER_TO_OBJECT(pdwFlags, DWORD*);
2730     *pdwFlags = CORDEBUG_JIT_DEFAULT;;
2731
2732     CordbProcess *pProcess = GetProcess();
2733
2734
2735     ATT_REQUIRE_STOPPED_MAY_FAIL(pProcess);
2736     HRESULT hr = S_OK;
2737     
2738     EX_TRY
2739     {
2740         BOOL fAllowJitOpts;
2741         BOOL fEnableEnC;
2742
2743         pProcess->GetDAC()->GetCompilerFlags (
2744             GetRuntimeDomainFile(), 
2745             &fAllowJitOpts, 
2746             &fEnableEnC);
2747
2748         if (fEnableEnC)
2749         {
2750             *pdwFlags = CORDEBUG_JIT_ENABLE_ENC;
2751         }
2752         else if (! fAllowJitOpts)
2753         {
2754             *pdwFlags = CORDEBUG_JIT_DISABLE_OPTIMIZATION;
2755         }
2756
2757     }
2758     EX_CATCH_HRESULT(hr);
2759     return hr;
2760 }
2761
2762 BOOL CordbModule::IsWinMD()
2763 {
2764     CONTRACTL
2765     {
2766         THROWS;
2767     }
2768     CONTRACTL_END;
2769
2770     if (m_isIlWinMD == Uninitialized)
2771     {
2772         BOOL isWinRT;
2773         HRESULT hr = E_FAIL;
2774         
2775         {
2776             RSLockHolder processLockHolder(GetProcess()->GetProcessLock());
2777             hr = GetProcess()->GetDAC()->IsWinRTModule(m_vmModule, isWinRT);
2778         }
2779
2780         _ASSERTE(SUCCEEDED(hr));
2781         if (FAILED(hr))
2782             ThrowHR(hr);
2783
2784         if (isWinRT)
2785             m_isIlWinMD = True;
2786         else
2787             m_isIlWinMD = False;
2788     }
2789
2790     return m_isIlWinMD == True;
2791 }
2792
2793 /* ------------------------------------------------------------------------- *
2794  * CordbCode class
2795  * ------------------------------------------------------------------------- */
2796 //-----------------------------------------------------------------------------
2797 // CordbCode constructor
2798 // Arguments:
2799 //    Input:
2800 //        pFunction  - CordbFunction instance for this function
2801 //        encVersion - Edit and Continue version number for this code chunk
2802 //        fIsIL      - indicates whether the instance is a CordbILCode (as
2803 //                     opposed to a CordbNativeCode)
2804 //        id         - This is the hashtable key for CordbCode objects
2805 //                   - for native code, the code start address
2806 //                   - for IL code, 0
2807 //                   - for ReJit IL code, the remote pointer to the ReJitSharedInfo
2808 //    Output:
2809 //        fields of the CordbCode instance have been initialized
2810 //-----------------------------------------------------------------------------
2811
2812 CordbCode::CordbCode(CordbFunction * pFunction, UINT_PTR id, SIZE_T encVersion, BOOL fIsIL)
2813   : CordbBase(pFunction->GetProcess(), id, enumCordbCode),
2814     m_fIsIL(fIsIL),
2815     m_nVersion(encVersion),
2816     m_rgbCode(NULL),
2817     m_continueCounterLastSync(0),
2818     m_pFunction(pFunction)
2819 {
2820     _ASSERTE(pFunction != NULL);
2821     _ASSERTE(m_nVersion >= CorDB_DEFAULT_ENC_FUNCTION_VERSION);
2822 } // CordbCode::CordbCode
2823
2824 //-----------------------------------------------------------------------------
2825 // Destructor for CordbCode object
2826 //-----------------------------------------------------------------------------
2827 CordbCode::~CordbCode()
2828 {
2829     _ASSERTE(IsNeutered());
2830 }
2831
2832 //-----------------------------------------------------------------------------
2833 // Neutered by CordbFunction
2834 // See CordbBase::Neuter for neuter semantics.
2835 //-----------------------------------------------------------------------------
2836 void CordbCode::Neuter()
2837 {
2838     m_pFunction = NULL;
2839
2840     delete [] m_rgbCode;
2841     m_rgbCode = NULL;
2842
2843     CordbBase::Neuter();
2844 }
2845
2846 //-----------------------------------------------------------------------------
2847 // Public method for IUnknown::QueryInterface.
2848 // Has standard QI semantics.
2849 //-----------------------------------------------------------------------------
2850 HRESULT CordbCode::QueryInterface(REFIID id, void ** pInterface)
2851 {
2852     if (id == IID_ICorDebugCode)
2853     {
2854         *pInterface = static_cast<ICorDebugCode*>(this);
2855     }
2856     else if (id == IID_IUnknown)
2857     {
2858         *pInterface = static_cast<IUnknown *>(static_cast<ICorDebugCode *>(this));
2859     }
2860     else
2861     {
2862         *pInterface = NULL;
2863         return E_NOINTERFACE;
2864     }
2865
2866     ExternalAddRef();
2867     return S_OK;
2868 }
2869
2870 //-----------------------------------------------------------------------------
2871 // NOT IMPLEMENTED. Remap sequence points are entirely private to the LS,
2872 // and ICorDebug will dispatch a RemapOpportunity callback to notify the
2873 // debugger instead of letting the debugger query for the points.
2874 //
2875 // Returns: E_NOTIMPL
2876 //-----------------------------------------------------------------------------
2877 HRESULT CordbCode::GetEnCRemapSequencePoints(ULONG32 cMap, ULONG32 * pcMap, ULONG32 offsets[])
2878 {
2879     FAIL_IF_NEUTERED(this);
2880     VALIDATE_POINTER_TO_OBJECT_OR_NULL(pcMap, ULONG32*);
2881     VALIDATE_POINTER_TO_OBJECT_ARRAY_OR_NULL(offsets, ULONG32*, cMap, true, true);
2882
2883     //
2884     // Old EnC interface - deprecated
2885     //
2886     return E_NOTIMPL;
2887 } // CordbCode::GetEnCRemapSequencePoints
2888
2889
2890 //-----------------------------------------------------------------------------
2891 // CordbCode::IsIL
2892 // Public method to determine if this Code object represents IL or native code.
2893 // 
2894 // Parameters:
2895 //    pbIL - OUT: on return, set to True if IL code, else False.
2896 //
2897 // Returns:
2898 //    S_OK on success.
2899 //-----------------------------------------------------------------------------
2900 HRESULT CordbCode::IsIL(BOOL *pbIL)
2901 {
2902     PUBLIC_API_ENTRY(this);
2903     FAIL_IF_NEUTERED(this);
2904     VALIDATE_POINTER_TO_OBJECT(pbIL, BOOL *);
2905
2906     *pbIL = IsIL();
2907
2908     return S_OK;
2909 }
2910
2911 //-----------------------------------------------------------------------------
2912 // CordbCode::GetFunction
2913 // Public method to get the Function object associated with this Code object.
2914 // Function:Code = 1:1 for IL, and 1:n for Native. So there is always a single
2915 // unique Function object to return.
2916 // 
2917 // Parameters:
2918 //   ppFunction - OUT: returns the Function object for this Code.
2919 //
2920 // Returns:
2921 //   S_OK - on success.
2922 //-----------------------------------------------------------------------------
2923 HRESULT CordbCode::GetFunction(ICorDebugFunction **ppFunction)
2924 {
2925     PUBLIC_API_ENTRY(this);
2926     FAIL_IF_NEUTERED(this);
2927     VALIDATE_POINTER_TO_OBJECT(ppFunction, ICorDebugFunction **);
2928
2929     *ppFunction = static_cast<ICorDebugFunction*> (m_pFunction);
2930     m_pFunction->ExternalAddRef();
2931
2932     return S_OK;
2933 }
2934
2935 //-----------------------------------------------------------------------------
2936 // CordbCode::GetSize
2937 // Get the size of the code in bytes. If this is IL code, it will be bytes of IL.
2938 // If this is native code, it will be bytes of native code.
2939 //
2940 // Parameters:
2941 //   pcBytes - OUT: on return, set to the size of the code in bytes.
2942 //
2943 // Returns:
2944 //   S_OK on success.
2945 //-----------------------------------------------------------------------------
2946 HRESULT CordbCode::GetSize(ULONG32 *pcBytes)
2947 {
2948     PUBLIC_REENTRANT_API_ENTRY(this);
2949     FAIL_IF_NEUTERED(this);
2950     VALIDATE_POINTER_TO_OBJECT(pcBytes, ULONG32 *);
2951
2952     *pcBytes = GetSize();
2953     return S_OK;
2954 }
2955
2956 //-----------------------------------------------------------------------------
2957 // CordbCode::CreateBreakpoint
2958 // public method to create a breakpoint in the code. 
2959 // 
2960 // Parameters:
2961 //   offset - offset in bytes to set the breakpoint at. If this is a Native
2962 //      code object (IsIl == false), then units are bytes of native code. If
2963 //      this is an IL code object, then units are bytes of IL code.
2964 //   ppBreakpoint- out-parameter to hold newly created breakpoint object.
2965 //
2966 // Return value:
2967 //   S_OK iff *ppBreakpoint is set. Else some error.
2968 //-----------------------------------------------------------------------------
2969 HRESULT CordbCode::CreateBreakpoint(ULONG32 offset,
2970                                     ICorDebugFunctionBreakpoint **ppBreakpoint)
2971 {
2972     PUBLIC_REENTRANT_API_ENTRY(this);
2973     FAIL_IF_NEUTERED(this);
2974     VALIDATE_POINTER_TO_OBJECT(ppBreakpoint, ICorDebugFunctionBreakpoint **);
2975
2976     HRESULT hr;
2977     ULONG32 size = GetSize();
2978     LOG((LF_CORDB, LL_INFO10000, "CCode::CreateBreakpoint, offset=%d, size=%d, IsIl=%d, this=0x%p\n",
2979         offset, size, m_fIsIL, this));
2980
2981     // Make sure the offset is within range of the method.
2982     // If we're native code, then both offset & total code size are bytes of native code,
2983     // else they're both bytes of IL.
2984     if (offset >= size)
2985     {
2986         return CORDBG_E_UNABLE_TO_SET_BREAKPOINT;
2987     }
2988
2989     CordbFunctionBreakpoint *bp = new (nothrow) CordbFunctionBreakpoint(this, offset);
2990
2991     if (bp == NULL)
2992         return E_OUTOFMEMORY;
2993
2994     hr = bp->Activate(TRUE);
2995     if (SUCCEEDED(hr))
2996     {
2997         *ppBreakpoint = static_cast<ICorDebugFunctionBreakpoint*> (bp);
2998         bp->ExternalAddRef();
2999         return S_OK;
3000     }
3001     else
3002     {
3003         delete bp;
3004         return hr;
3005     }
3006 }
3007
3008 //-----------------------------------------------------------------------------
3009 // CordbCode::GetCode
3010 // Public method to get the code-bytes for this Code object. For an IL-code
3011 // object, this will be bytes of IL. For a native-code object, this will be
3012 // bytes of native opcodes.
3013 // The units of the offsets are the same as the units on the CordbCode object.
3014 // (eg, IL offsets for an IL code object, and native offsets for a native code object)
3015 // This will glue together hot + cold regions into a single blob.
3016 // 
3017 // Units are also logical (aka linear) values, which 
3018 // Parameters:
3019 //    startOffset - linear offset in Code to start copying from. 
3020 //    endOffset - linear offset in Code to end copying from. Total bytes copied would be (endOffset - startOffset)
3021 //    cBufferAlloc - number of bytes in the buffer supplied by the buffer[] parameter.
3022 //    buffer - caller allocated storage to copy bytes into.
3023 //    pcBufferSize - required out-parameter, holds number of bytes copied into buffer. 
3024 //
3025 // Returns:
3026 //    S_OK if copy successful. Else error.
3027 //-----------------------------------------------------------------------------
3028 HRESULT CordbCode::GetCode(ULONG32 startOffset,
3029                            ULONG32 endOffset,
3030                            ULONG32 cBufferAlloc,
3031                            BYTE buffer[],
3032                            ULONG32 *pcBufferSize)
3033 {
3034     PUBLIC_REENTRANT_API_ENTRY(this);
3035     FAIL_IF_NEUTERED(this);
3036     VALIDATE_POINTER_TO_OBJECT_ARRAY(buffer, BYTE, cBufferAlloc, true, true);
3037     VALIDATE_POINTER_TO_OBJECT(pcBufferSize, ULONG32 *);
3038
3039     LOG((LF_CORDB,LL_EVERYTHING, "CC::GC: for token:0x%x\n", m_pFunction->GetMetadataToken()));
3040
3041     ATT_REQUIRE_STOPPED_MAY_FAIL(GetProcess());
3042
3043     HRESULT hr = S_OK;
3044     *pcBufferSize = 0;
3045
3046     // Check ranges.
3047     ULONG32 totalSize = GetSize();
3048
3049     if (cBufferAlloc < endOffset - startOffset)
3050         endOffset = startOffset + cBufferAlloc;
3051
3052     if (endOffset > totalSize)
3053         endOffset = totalSize;
3054
3055     if (startOffset > totalSize)
3056         startOffset = totalSize;
3057
3058     // Check the continue counter since WriteMemory bumps it up.
3059     if ((m_rgbCode == NULL) ||
3060         (m_continueCounterLastSync < GetProcess()->m_continueCounter))
3061     {
3062         ReadCodeBytes();
3063         m_continueCounterLastSync = GetProcess()->m_continueCounter;
3064     }
3065
3066     // if we just got the code, we'll have to copy it over
3067     if (*pcBufferSize == 0 && m_rgbCode != NULL)
3068     {
3069         memcpy(buffer,
3070                m_rgbCode+startOffset,
3071                endOffset - startOffset);
3072         *pcBufferSize = endOffset - startOffset;
3073     }
3074     return hr;
3075
3076 } // CordbCode::GetCode
3077
3078 #include "dbgipcevents.h"
3079
3080 //-----------------------------------------------------------------------------
3081 // CordbCode::GetVersionNumber
3082 // Public method to get the EnC version number of the code.
3083 //
3084 // Parameters: 
3085 //    nVersion - OUT: on return, set to the version number.
3086 // 
3087 // Returns:
3088 //    S_OK on success.
3089 //-----------------------------------------------------------------------------
3090 HRESULT CordbCode::GetVersionNumber( ULONG32 *nVersion)
3091 {
3092     PUBLIC_API_ENTRY(this);
3093     FAIL_IF_NEUTERED(this);
3094     VALIDATE_POINTER_TO_OBJECT(nVersion, ULONG32 *);
3095
3096     LOG((LF_CORDB,LL_INFO10000,"R:CC:GVN:Returning 0x%x "
3097         "as version\n",m_nVersion));
3098
3099     *nVersion = (ULONG32)m_nVersion;
3100
3101 #ifndef EnC_SUPPORTED
3102     _ASSERTE(*nVersion == 1);
3103 #endif // EnC_SUPPORTED
3104
3105     return S_OK;
3106 }
3107
3108 // get the CordbFunction instance for this code object
3109 CordbFunction * CordbCode::GetFunction()
3110 {
3111     _ASSERTE(m_pFunction != NULL);
3112     return m_pFunction;
3113 }
3114
3115 /* ------------------------------------------------------------------------- *
3116  * CordbILCode class
3117  * ------------------------------------------------------------------------- */
3118
3119 //-----------------------------------------------------------------------------
3120 // CordbILCode ctor to make IL code.
3121 // Arguments:
3122 //    Input:
3123 //        pFunction      - pointer to the CordbFunction instance for this function
3124 //        codeRegionInfo - starting address and size in bytes of IL code blob
3125 //        nVersion       - EnC version number for this IL code blob
3126 //        localVarSigToken - LocalVarSig for this IL blob
3127 //        id             - the key when using ILCode in a CordbHashTable
3128 //    Output:
3129 //        fields of this instance of CordbILCode have been initialized
3130 //-----------------------------------------------------------------------------
3131 CordbILCode::CordbILCode(CordbFunction * pFunction, 
3132                          TargetBuffer    codeRegionInfo, 
3133                          SIZE_T          nVersion,
3134                          mdSignature     localVarSigToken,
3135                          UINT_PTR        id)
3136   : CordbCode(pFunction, id, nVersion, TRUE),
3137 #ifdef EnC_SUPPORTED
3138     m_fIsOld(FALSE),
3139 #endif
3140     m_codeRegionInfo(codeRegionInfo),
3141     m_localVarSigToken(localVarSigToken)
3142 {
3143 } // CordbILCode::CordbILCode
3144
3145
3146 #ifdef EnC_SUPPORTED
3147 //-----------------------------------------------------------------------------
3148 // CordbILCode::MakeOld
3149 // Internal method to perform any cleanup necessary when a code blob is no longer
3150 // the most current.
3151 //-----------------------------------------------------------------------------
3152 void CordbILCode::MakeOld()
3153 {
3154     m_fIsOld = TRUE;
3155 }
3156 #endif
3157
3158 //-----------------------------------------------------------------------------
3159 // CordbILCode::GetAddress
3160 // Public method to get the Entry address for the code.  This is the address
3161 // where the method first starts executing. 
3162 //
3163 // Parameters:
3164 //    pStart - out-parameter to hold start address.
3165 // 
3166 // Returns:
3167 //    S_OK if *pStart is properly updated.
3168 //-----------------------------------------------------------------------------
3169 HRESULT CordbILCode::GetAddress(CORDB_ADDRESS * pStart)
3170 {
3171     PUBLIC_REENTRANT_API_ENTRY(this);
3172     FAIL_IF_NEUTERED(this);
3173     VALIDATE_POINTER_TO_OBJECT(pStart, CORDB_ADDRESS *);
3174
3175
3176     _ASSERTE(this != NULL);
3177     _ASSERTE(this->GetFunction() != NULL);
3178     _ASSERTE(this->GetFunction()->GetModule() != NULL);
3179     _ASSERTE(this->GetFunction()->GetModule()->GetProcess() == GetProcess());
3180
3181     *pStart = (m_codeRegionInfo.pAddress);
3182
3183     return S_OK;
3184 } // CordbILCode::GetAddress
3185
3186 //-----------------------------------------------------------------------------
3187 // CordbILCode::ReadCodeBytes
3188 // Reads the actual bytes of IL code into the data member m_rgbCode
3189 // Arguments:
3190 //    none (uses data members)
3191 // Return value:
3192 //    standard HRESULT values
3193 //    also allocates and initializes m_rgbCode
3194 // Notes: assumes that the caller has checked to ensure that m_rgbCode doesn't
3195 //    hold valid data
3196 //-----------------------------------------------------------------------------
3197 HRESULT CordbILCode::ReadCodeBytes()
3198 {
3199     HRESULT hr = S_OK;
3200     EX_TRY
3201     {
3202         // We have an address & size, so we'll just call ReadMemory.
3203         // This will conveniently strip out any patches too.
3204         CORDB_ADDRESS pStart = m_codeRegionInfo.pAddress;
3205         ULONG32 cbSize = (ULONG32) m_codeRegionInfo.cbSize;
3206
3207         delete [] m_rgbCode;
3208         m_rgbCode = new BYTE[cbSize];    // throws
3209
3210         SIZE_T cbRead;
3211         hr = GetProcess()->ReadMemory(pStart, cbSize, m_rgbCode, &cbRead);
3212         IfFailThrow(hr);
3213
3214         SIMPLIFYING_ASSUMPTION(cbRead == cbSize);
3215     }
3216     EX_CATCH_HRESULT(hr);
3217     return hr;
3218 } // CordbILCode::ReadCodeBytes
3219
3220 //-----------------------------------------------------------------------------
3221 // CordbILCode::GetILToNativeMapping
3222 // Public method (implements ICorDebugCode) to get the IL-->{ Native Start, Native End} mapping.
3223 // Since 1 CordbILCode can map to multiple CordbNativeCode due to generics, we cannot reliably return the
3224 // mapping information in all cases.  So we always fail with CORDBG_E_NON_NATIVE_FRAME.  The caller should
3225 // call code:CordbNativeCode::GetILToNativeMapping instead.
3226 // 
3227 // Parameters:
3228 //    cMap - size of incoming map[] array (in elements).
3229 //    pcMap - OUT: full size of IL-->Native map (in elements). 
3230 //    map - caller allocated array to be filled in.
3231 // 
3232 // Returns:
3233 //    CORDBG_E_NON_NATIVE_FRAME in all cases
3234 //-----------------------------------------------------------------------------
3235 HRESULT CordbILCode::GetILToNativeMapping(ULONG32                    cMap,
3236                                           ULONG32 *                  pcMap,
3237                                           COR_DEBUG_IL_TO_NATIVE_MAP map[])
3238 {
3239     PUBLIC_API_ENTRY(this);
3240     FAIL_IF_NEUTERED(this);
3241     VALIDATE_POINTER_TO_OBJECT_OR_NULL(pcMap, ULONG32 *);
3242     VALIDATE_POINTER_TO_OBJECT_ARRAY_OR_NULL(map, COR_DEBUG_IL_TO_NATIVE_MAP *, cMap, true, true);
3243
3244     ATT_REQUIRE_STOPPED_MAY_FAIL(GetProcess());
3245
3246     return CORDBG_E_NON_NATIVE_FRAME;
3247 } // CordbILCode::GetILToNativeMapping
3248
3249
3250 /*
3251 * CordbILCode::GetLocalVarSig
3252 *
3253 * Get the method's local variable metadata signature. This may be cached, but for dynamic modules we'll always
3254 * read it from the metadata. This function also returns the count of local variables in the method.
3255 *
3256 * Parameters:
3257 *    pLocalSigParser - OUT: the local variable signature for the method.
3258 *    pLocalCount - OUT: the number of locals the method has.
3259 *
3260 * Returns:
3261 *    HRESULT for success or failure.
3262 *
3263 */
3264 HRESULT CordbILCode::GetLocalVarSig(SigParser *pLocalSigParser,
3265     ULONG *pLocalVarCount)
3266 {
3267     INTERNAL_SYNC_API_ENTRY(GetProcess());
3268
3269     CONTRACTL  // @dbgtodo  exceptions - convert to throws...
3270     {
3271         NOTHROW;
3272     }
3273     CONTRACTL_END;
3274
3275     FAIL_IF_NEUTERED(this);
3276     HRESULT hr = S_OK;
3277
3278     // A function will not have a local var sig if it has no locals!
3279     if (m_localVarSigToken != mdSignatureNil)
3280     {
3281         PCCOR_SIGNATURE localSignature;
3282         ULONG size;
3283         ULONG localCount;
3284
3285         EX_TRY // // @dbgtodo  exceptions  - push this up
3286         {
3287             GetFunction()->GetModule()->UpdateMetaDataCacheIfNeeded(m_localVarSigToken);
3288             hr = GetFunction()->GetModule()->GetMetaDataImporter()->GetSigFromToken(m_localVarSigToken,
3289                 &localSignature,
3290                 &size);
3291         }
3292         EX_CATCH_HRESULT(hr);
3293         if (FAILED(hr))
3294         {
3295             LOG((LF_CORDB, LL_WARNING, "CICF::GLVS caught hr=0x%x\n", hr));
3296         }
3297         IfFailRet(hr);
3298
3299         LOG((LF_CORDB, LL_INFO100000, "CIC::GLVS creating sig parser sig=0x%x size=0x%x\n", localSignature, size));
3300         SigParser sigParser = SigParser(localSignature, size);
3301
3302         ULONG data;
3303
3304         IfFailRet(sigParser.GetCallingConvInfo(&data));
3305
3306         _ASSERTE(data == IMAGE_CEE_CS_CALLCONV_LOCAL_SIG);
3307
3308         // Snagg the count of locals in the sig.
3309         IfFailRet(sigParser.GetData(&localCount));
3310         LOG((LF_CORDB, LL_INFO100000, "CIC::GLVS localCount=0x%x\n", localCount));
3311         if (pLocalSigParser != NULL)
3312         {
3313             *pLocalSigParser = sigParser;
3314         }
3315         if (pLocalVarCount != NULL)
3316         {
3317             *pLocalVarCount = localCount;
3318         }
3319     }
3320     else
3321     {
3322         //
3323         // Signature is Nil, so fill in everything with NULLs and zeros
3324         //
3325         if (pLocalSigParser != NULL)
3326         {
3327             *pLocalSigParser = SigParser(NULL, 0);
3328         }
3329
3330         if (pLocalVarCount != NULL)
3331         {
3332             *pLocalVarCount = 0;
3333         }
3334     }
3335     LOG((LF_CORDB, LL_INFO100000, "CIC::GLVS returning hr=0x%x\n", hr));
3336     return hr;
3337 }
3338
3339 //-----------------------------------------------------------------------------
3340 // CordbILCode::GetLocalVariableType
3341 // Internal method. Return the type of an IL local, specified by 0-based index.
3342 //
3343 // Parameters:
3344 //   dwIndex - 0-based index for IL local number.
3345 //   inst - instantiation information if this is a generic function. Eg, 
3346 //           if function is List<T>, inst describes T.
3347 //   res - out parameter, yields to CordbType of the local.
3348 //
3349 // Return:
3350 //   S_OK on success. 
3351 //
3352 HRESULT CordbILCode::GetLocalVariableType(DWORD dwIndex,
3353     const Instantiation * pInst,
3354     CordbType ** ppResultType)
3355 {
3356     ATT_ALLOW_LIVE_DO_STOPGO(GetProcess());
3357     LOG((LF_CORDB, LL_INFO10000, "CIC::GLVT dwIndex=0x%x pInst=0x%p\n", dwIndex, pInst));
3358     HRESULT hr = S_OK;
3359
3360     EX_TRY
3361     {
3362         // Get the local variable signature.
3363         SigParser sigParser;
3364         ULONG cLocals;
3365
3366         IfFailThrow(GetLocalVarSig(&sigParser, &cLocals));
3367
3368         // Check the index.
3369         if (dwIndex >= cLocals)
3370         {
3371             ThrowHR(E_INVALIDARG);
3372         }
3373
3374         // Run the signature and find the required argument.
3375         for (unsigned int i = 0; i < dwIndex; i++)
3376         {
3377             LOG((LF_CORDB, LL_INFO10000, "CIC::GLVT scanning index 0x%x\n", dwIndex));
3378             IfFailThrow(sigParser.SkipExactlyOne());
3379         }
3380
3381         hr = CordbType::SigToType(GetFunction()->GetModule(), &sigParser, pInst, ppResultType);
3382         LOG((LF_CORDB, LL_INFO10000, "CIC::GLVT CT::SigToType returned hr=0x%x\n", hr));
3383         IfFailThrow(hr);
3384
3385     } EX_CATCH_HRESULT(hr);
3386     return hr;
3387 }
3388
3389 mdSignature CordbILCode::GetLocalVarSigToken()
3390 {
3391     return m_localVarSigToken;
3392 }
3393
3394 CordbReJitILCode::CordbReJitILCode(CordbFunction *pFunction, SIZE_T encVersion, VMPTR_SharedReJitInfo vmSharedReJitInfo) :
3395 CordbILCode(pFunction, TargetBuffer(), encVersion, mdSignatureNil, VmPtrToCookie(vmSharedReJitInfo)),
3396 m_cClauses(0),
3397 m_cbLocalIL(0),
3398 m_cILMap(0)
3399 {
3400     _ASSERTE(!vmSharedReJitInfo.IsNull());
3401     DacSharedReJitInfo data = { 0 };
3402     IfFailThrow(GetProcess()->GetDAC()->GetSharedReJitInfoData(vmSharedReJitInfo, &data));
3403     IfFailThrow(Init(&data));
3404 }
3405
3406 //-----------------------------------------------------------------------------
3407 // CordbReJitILCode::Init
3408 //
3409 // Returns:
3410 //    S_OK if all fields are inited. Else error.
3411 HRESULT CordbReJitILCode::Init(DacSharedReJitInfo* pSharedReJitInfo)
3412 {
3413     HRESULT hr = S_OK;
3414
3415     // Instrumented IL map
3416     if (pSharedReJitInfo->m_cInstrumentedMapEntries)
3417     {
3418         if (pSharedReJitInfo->m_cInstrumentedMapEntries > 100000)
3419             return CORDBG_E_TARGET_INCONSISTENT;
3420         m_cILMap = pSharedReJitInfo->m_cInstrumentedMapEntries;
3421         m_pILMap = new (nothrow)COR_IL_MAP[m_cILMap];
3422         TargetBuffer mapBuffer(pSharedReJitInfo->m_rgInstrumentedMapEntries, m_cILMap*sizeof(COR_IL_MAP));
3423         IfFailRet(GetProcess()->SafeReadBuffer(mapBuffer, (BYTE*)m_pILMap.GetValue(), FALSE /* bThrowOnError */));
3424     }
3425
3426     // Read the method's IL header
3427     CORDB_ADDRESS pIlHeader = pSharedReJitInfo->m_pbIL;
3428     IMAGE_COR_ILMETHOD_FAT header = { 0 };
3429     bool headerMustBeTiny = false;
3430     ULONG32 headerSize = 0;
3431     hr = GetProcess()->SafeReadStruct(pIlHeader, &header);
3432     if (hr != S_OK)
3433     {
3434         // Its possible the header is tiny and there isn't enough memory to read a complete
3435         // FAT header
3436         headerMustBeTiny = true;
3437         IfFailRet(GetProcess()->SafeReadStruct(pIlHeader, (IMAGE_COR_ILMETHOD_TINY *)&header));
3438     }
3439
3440     // Read the ILCodeSize and LocalVarSigTok from header
3441     ULONG32 ilCodeSize = 0;
3442     IMAGE_COR_ILMETHOD_TINY *pMethodTinyHeader = (IMAGE_COR_ILMETHOD_TINY *)&header;
3443     bool isTinyHeader = ((pMethodTinyHeader->Flags_CodeSize & (CorILMethod_FormatMask >> 1)) == CorILMethod_TinyFormat);
3444     if (isTinyHeader)
3445     {
3446         ilCodeSize = (((unsigned)pMethodTinyHeader->Flags_CodeSize) >> (CorILMethod_FormatShift - 1));
3447         headerSize = sizeof(IMAGE_COR_ILMETHOD_TINY);
3448         m_localVarSigToken = mdSignatureNil;
3449     }
3450     else if (headerMustBeTiny)
3451     {
3452         // header was not CorILMethod_TinyFormat
3453         // this is not possible, must be an error when reading from data target
3454         return CORDBG_E_READVIRTUAL_FAILURE;
3455     }
3456     else
3457     {
3458         ilCodeSize = header.CodeSize;
3459         headerSize = header.Size * 4;
3460         m_localVarSigToken = header.LocalVarSigTok;
3461     }
3462     if (ilCodeSize == 0 || ilCodeSize > 100000)
3463     {
3464         return CORDBG_E_TARGET_INCONSISTENT;
3465     }
3466     
3467     m_codeRegionInfo.Init(pIlHeader + headerSize, ilCodeSize);
3468     m_pLocalIL = new (nothrow) BYTE[ilCodeSize];
3469     if (m_pLocalIL == NULL)
3470         return E_OUTOFMEMORY;
3471     m_cbLocalIL = ilCodeSize;
3472     IfFailRet(GetProcess()->SafeReadBuffer(m_codeRegionInfo, m_pLocalIL, FALSE /*throwOnError*/));
3473
3474     // Check if this il code has exception clauses
3475     if ((pMethodTinyHeader->Flags_CodeSize & CorILMethod_MoreSects) == 0)
3476     {
3477         return S_OK; // no EH, done initing
3478     }
3479
3480     // EH section starts at the 4 byte aligned address after the code
3481     CORDB_ADDRESS ehClauseHeader = ((pIlHeader + headerSize + ilCodeSize - 1) & ~3) + 4;
3482     BYTE kind = 0;
3483     IfFailRet(GetProcess()->SafeReadStruct(ehClauseHeader, &kind));
3484     if ((kind & CorILMethod_Sect_KindMask) != CorILMethod_Sect_EHTable)
3485     {
3486         return S_OK;
3487     }
3488     if (kind & CorILMethod_Sect_FatFormat)
3489     {
3490         // Read the section header to see how many clauses there are
3491         IMAGE_COR_ILMETHOD_SECT_FAT sectionHeader = { 0 };
3492         IfFailRet(GetProcess()->SafeReadStruct(ehClauseHeader, &sectionHeader));
3493         m_cClauses = (sectionHeader.DataSize - 4) / sizeof(IMAGE_COR_ILMETHOD_SECT_EH_CLAUSE_FAT);
3494         if (m_cClauses > 10000) // sanity check the data before allocating
3495         {
3496             return CORDBG_E_TARGET_INCONSISTENT;
3497         }
3498
3499         // Read in the clauses
3500         TargetBuffer buffer(ehClauseHeader + sizeof(IMAGE_COR_ILMETHOD_SECT_FAT), m_cClauses*sizeof(IMAGE_COR_ILMETHOD_SECT_EH_CLAUSE_FAT));
3501         NewArrayHolder<IMAGE_COR_ILMETHOD_SECT_EH_CLAUSE_FAT> pClauses = new (nothrow)IMAGE_COR_ILMETHOD_SECT_EH_CLAUSE_FAT[m_cClauses];
3502         if (pClauses == NULL)
3503             return E_OUTOFMEMORY;
3504         IfFailRet(GetProcess()->SafeReadBuffer(buffer, (BYTE*)pClauses.GetValue(), FALSE /*throwOnError*/));
3505
3506         // convert clauses
3507         m_pClauses = new (nothrow)CorDebugEHClause[m_cClauses];
3508         if (m_pClauses == NULL)
3509             return E_OUTOFMEMORY;
3510         for (ULONG32 i = 0; i < m_cClauses; i++)
3511         {
3512             BOOL isFilter = ((pClauses[i].Flags & COR_ILEXCEPTION_CLAUSE_FILTER) != 0);
3513             m_pClauses[i].Flags = pClauses[i].Flags;
3514             m_pClauses[i].TryOffset = pClauses[i].TryOffset;
3515             m_pClauses[i].TryLength = pClauses[i].TryLength;
3516             m_pClauses[i].HandlerOffset = pClauses[i].HandlerOffset;
3517             m_pClauses[i].HandlerLength = pClauses[i].HandlerLength;
3518             // these two fields are a union in the image, but are seperate in the struct ICorDebug returns
3519             m_pClauses[i].ClassToken = isFilter ? 0 : pClauses[i].ClassToken;
3520             m_pClauses[i].FilterOffset = isFilter ? pClauses[i].FilterOffset : 0;
3521         }
3522     }
3523     else
3524     {
3525         // Read in the section header to see how many small clauses there are
3526         IMAGE_COR_ILMETHOD_SECT_SMALL sectionHeader = { 0 };
3527         IfFailRet(GetProcess()->SafeReadStruct(ehClauseHeader, &sectionHeader));
3528         ULONG32 m_cClauses = (sectionHeader.DataSize - 4) / sizeof(IMAGE_COR_ILMETHOD_SECT_SMALL);
3529         if (m_cClauses > 10000) // sanity check the data before allocating
3530         {
3531             return CORDBG_E_TARGET_INCONSISTENT;
3532         }
3533
3534         // Read in the clauses
3535         TargetBuffer buffer(ehClauseHeader + sizeof(IMAGE_COR_ILMETHOD_SECT_SMALL), m_cClauses*sizeof(IMAGE_COR_ILMETHOD_SECT_EH_CLAUSE_SMALL));
3536         NewArrayHolder<IMAGE_COR_ILMETHOD_SECT_EH_CLAUSE_SMALL> pClauses = new (nothrow)IMAGE_COR_ILMETHOD_SECT_EH_CLAUSE_SMALL[m_cClauses];
3537         if (pClauses == NULL)
3538             return E_OUTOFMEMORY;
3539         IfFailRet(GetProcess()->SafeReadBuffer(buffer, (BYTE*)pClauses.GetValue(), FALSE /*throwOnError*/));
3540
3541         // convert clauses
3542         m_pClauses = new (nothrow)CorDebugEHClause[m_cClauses];
3543         if (m_pClauses == NULL)
3544             return E_OUTOFMEMORY;
3545         for (ULONG32 i = 0; i < m_cClauses; i++)
3546         {
3547             BOOL isFilter = ((pClauses[i].Flags & COR_ILEXCEPTION_CLAUSE_FILTER) != 0);
3548             m_pClauses[i].Flags = pClauses[i].Flags;
3549             m_pClauses[i].TryOffset = pClauses[i].TryOffset;
3550             m_pClauses[i].TryLength = pClauses[i].TryLength;
3551             m_pClauses[i].HandlerOffset = pClauses[i].HandlerOffset;
3552             m_pClauses[i].HandlerLength = pClauses[i].HandlerLength;
3553             // these two fields are a union in the image, but are seperate in the struct ICorDebug returns
3554             m_pClauses[i].ClassToken = isFilter ? 0 : pClauses[i].ClassToken;
3555             m_pClauses[i].FilterOffset = isFilter ? pClauses[i].FilterOffset : 0;
3556         }
3557     }
3558     return S_OK;
3559 }
3560
3561 #ifndef MIN
3562 #define MIN(a,b) ((a) < (b) ? (a) : (b))
3563 #endif
3564
3565 //-----------------------------------------------------------------------------
3566 // CordbReJitILCode::GetEHClauses
3567 // Public method to get the EH clauses for IL code
3568 // 
3569 // Parameters:
3570 //   cClauses - size of incoming clauses array (in elements).
3571 //   pcClauses - OUT param: cClauses>0 -> the number of elements written to in the clauses array.
3572 //                          cClauses=0 -> the number of EH clauses this IL code has
3573 //   clauses - caller allocated storage to hold the EH clauses.
3574 //
3575 // Returns:
3576 //    S_OK if successfully copied elements to clauses array.
3577 HRESULT CordbReJitILCode::GetEHClauses(ULONG32 cClauses, ULONG32 * pcClauses, CorDebugEHClause clauses[])
3578 {
3579     PUBLIC_API_ENTRY(this);
3580     FAIL_IF_NEUTERED(this);
3581     VALIDATE_POINTER_TO_OBJECT_OR_NULL(pcClauses, ULONG32 *);
3582     VALIDATE_POINTER_TO_OBJECT_ARRAY_OR_NULL(clauses, CorDebugEHClause *, cClauses, true, true);
3583     ATT_REQUIRE_STOPPED_MAY_FAIL(GetProcess());
3584
3585     if (cClauses != 0 && clauses == NULL)
3586     {
3587         return E_INVALIDARG;
3588     }
3589
3590     if (pcClauses != NULL)
3591     {
3592         if (cClauses == 0)
3593         {
3594             *pcClauses = m_cClauses;
3595         }
3596         else
3597         {
3598             *pcClauses = MIN(cClauses, m_cClauses);
3599         }
3600     }
3601
3602     if (clauses != NULL)
3603     {
3604         memcpy_s(clauses, sizeof(CorDebugEHClause)*cClauses, m_pClauses, sizeof(CorDebugEHClause)*MIN(cClauses, m_cClauses));
3605     }
3606     return S_OK;
3607 }
3608
3609 ULONG CordbReJitILCode::AddRef()
3610 {
3611     return CordbCode::AddRef();
3612 }
3613 ULONG CordbReJitILCode::Release()
3614 {
3615     return CordbCode::Release();
3616 }
3617
3618 HRESULT CordbReJitILCode::QueryInterface(REFIID riid, void** ppInterface)
3619 {
3620     if (riid == IID_ICorDebugILCode)
3621     {
3622         *ppInterface = static_cast<ICorDebugILCode*>(this);
3623     }
3624     else if (riid == IID_ICorDebugILCode2)
3625     {
3626         *ppInterface = static_cast<ICorDebugILCode2*>(this);
3627     }
3628     else
3629     {
3630         return CordbILCode::QueryInterface(riid, ppInterface);
3631     }
3632
3633     AddRef();
3634     return S_OK;
3635 }
3636
3637 HRESULT CordbReJitILCode::GetLocalVarSigToken(mdSignature *pmdSig)
3638 {
3639     PUBLIC_API_ENTRY(this);
3640     FAIL_IF_NEUTERED(this);
3641     VALIDATE_POINTER_TO_OBJECT(pmdSig, mdSignature *);
3642     ATT_REQUIRE_STOPPED_MAY_FAIL(GetProcess());
3643
3644     *pmdSig = m_localVarSigToken;
3645     return S_OK;
3646 }
3647
3648 HRESULT CordbReJitILCode::GetInstrumentedILMap(ULONG32 cMap, ULONG32 *pcMap, COR_IL_MAP map[])
3649 {
3650     PUBLIC_API_ENTRY(this);
3651     FAIL_IF_NEUTERED(this);
3652     VALIDATE_POINTER_TO_OBJECT_OR_NULL(pcClauses, ULONG32 *);
3653     VALIDATE_POINTER_TO_OBJECT_ARRAY_OR_NULL(map, COR_IL_MAP *, cMap, true, true);
3654     ATT_REQUIRE_STOPPED_MAY_FAIL(GetProcess());
3655
3656     if (cMap != 0 && map == NULL)
3657     {
3658         return E_INVALIDARG;
3659     }
3660
3661     if (pcMap != NULL)
3662     {
3663         if (cMap == 0)
3664         {
3665             *pcMap = m_cILMap;
3666         }
3667         else
3668         {
3669             *pcMap = MIN(cMap, m_cILMap);
3670         }
3671     }
3672
3673     if (map != NULL)
3674     {
3675         memcpy_s(map, sizeof(COR_IL_MAP)*cMap, m_pILMap, sizeof(COR_IL_MAP)*MIN(cMap, m_cILMap));
3676     }
3677     return S_OK;
3678 }
3679
3680 // FindNativeInfoInILVariableArray
3681 // Linear search through an array of NativeVarInfos, to find the variable of index dwIndex, valid
3682 // at the given ip. Returns CORDBG_E_IL_VAR_NOT_AVAILABLE if the variable isn't valid at the given ip.
3683 // Arguments:
3684 //     input:  dwIndex        - variable number    
3685 //             ip             - IP 
3686 //             nativeInfoList - list of instances of NativeVarInfo
3687 //     output: ppNativeInfo   - the element of nativeInfoList that corresponds to the IP and variable number
3688 //                              if we find such an element or NULL otherwise 
3689 // Return value: HRESULT: returns S_OK or CORDBG_E_IL_VAR_NOT_AVAILABLE if the variable isn't found             
3690 //             
3691 HRESULT FindNativeInfoInILVariableArray(DWORD                                               dwIndex,
3692                                         SIZE_T                                              ip,
3693                                         const DacDbiArrayList<ICorDebugInfo::NativeVarInfo> * nativeInfoList,
3694                                         const ICorDebugInfo::NativeVarInfo **                 ppNativeInfo)
3695 {
3696     _ASSERTE(ppNativeInfo != NULL);
3697     *ppNativeInfo = NULL;
3698
3699     // A few words about this search: it must be linear, and the
3700     // comparison of startOffset and endOffset to ip must be
3701     // <=/>. startOffset points to the first instruction that will
3702     // make the variable's home valid. endOffset points to the first
3703     // instruction at which the variable's home invalid.
3704     int lastGoodOne = -1;
3705     for (unsigned int i = 0; i < (unsigned)nativeInfoList->Count(); i++)
3706     {
3707         if ((*nativeInfoList)[i].varNumber == dwIndex)
3708         {
3709             if ( (lastGoodOne == -1) ||
3710                  ((*nativeInfoList)[lastGoodOne].startOffset < (*nativeInfoList)[i].startOffset) )
3711             {
3712                 lastGoodOne = i;
3713             }
3714
3715             if (((*nativeInfoList)[i].startOffset <= ip) &&
3716                 ((*nativeInfoList)[i].endOffset > ip))
3717             {
3718                 *ppNativeInfo = &((*nativeInfoList)[i]);
3719
3720                 return S_OK;
3721             }
3722         }
3723     }
3724
3725     // workaround:
3726     // 
3727     // We didn't find the variable. Was the endOffset of the last range for this variable
3728     // equal to the current IP? If so, go ahead and "lie" and report that as the
3729     // variable's home for now.
3730     //
3731     // Rationale:
3732     // 
3733     // * See TODO comment in code:Compiler::siUpdate (jit\scopeinfo.cpp). In optimized
3734     //     code, the JIT can report var lifetimes as being one instruction too short.
3735     //     This workaround makes up for that.  Example code:
3736     //     
3737     //         static void foo(int x)
3738     //         {
3739     //             int b = x; // Value of "x" would not be reported in optimized code without the workaround
3740     //             bar(ref b);
3741     //         }
3742     //         
3743     // * Since this is the first instruction after the last range a variable was alive,
3744     //     we're essentially assuming that since that instruction hasn't been executed
3745     //     yet, and since there isn't a new home for the variable, that the last home is
3746     //     still good. This actually turns out to be true 99.9% of the time, so we'll go
3747     //     with it for now.
3748     // * We've been lying like this since 1999, so surely it's safe.
3749     if ((lastGoodOne > -1) && ((*nativeInfoList)[lastGoodOne].endOffset == ip))
3750     {
3751         *ppNativeInfo = &((*nativeInfoList)[lastGoodOne]);
3752         return S_OK;
3753     }
3754
3755     return CORDBG_E_IL_VAR_NOT_AVAILABLE;
3756 } // FindNativeInfoInILVariableArray
3757
3758
3759 // * ------------------------------------------------------------------------- *
3760 // * Variable Enum class
3761 // * ------------------------------------------------------------------------- *
3762 //-----------------------------------------------------------------------------
3763 // CordbVariableHome constructor
3764 // Arguments:
3765 //    Input:
3766 //        pCode          - CordbNativeCode instance containing this variable home
3767 //        pNativeVarInfo - native location, lifetime, and index information for
3768 //                         this variable
3769 //        isLocal        - indicates whether the instance is a local variable,
3770 //                         as opposed to an argument
3771 //        index          - the argument or slot index
3772 //    Output:
3773 //        fields of the CordbVariableHome instance have been initialized
3774 //-----------------------------------------------------------------------------
3775 CordbVariableHome::CordbVariableHome(CordbNativeCode *pCode,
3776                                      const ICorDebugInfo::NativeVarInfo nativeVarInfo,
3777                                      BOOL isLocal,
3778                                      ULONG index) :
3779     CordbBase(pCode->GetModule()->GetProcess(), 0)
3780 {
3781     _ASSERTE(pCode != NULL);
3782     
3783     m_pCode.Assign(pCode);
3784     m_nativeVarInfo = nativeVarInfo;
3785     m_isLocal = isLocal;
3786     m_index = index;
3787 }
3788
3789 CordbVariableHome::~CordbVariableHome()
3790 {
3791     _ASSERTE(this->IsNeutered());
3792 }
3793
3794 void CordbVariableHome::Neuter()
3795 {
3796     m_pCode.Clear();
3797     CordbBase::Neuter();
3798 }
3799
3800 //-----------------------------------------------------------------------------
3801 // Public method for IUnknown::QueryInterface.
3802 // Has standard QI semantics.
3803 //-----------------------------------------------------------------------------
3804 HRESULT CordbVariableHome::QueryInterface(REFIID id, void **pInterface)
3805 {
3806     if (id == IID_ICorDebugVariableHome)
3807     {
3808         *pInterface = static_cast<ICorDebugVariableHome *>(this);
3809     }
3810     else if (id == IID_IUnknown)
3811     {
3812         *pInterface = static_cast<IUnknown *>(static_cast<ICorDebugVariableHome *>(this));
3813     }
3814     else
3815     {
3816         *pInterface = NULL;
3817         return E_NOINTERFACE;
3818     }
3819
3820     ExternalAddRef();
3821     return S_OK;
3822 }
3823
3824 //-----------------------------------------------------------------------------
3825 // CordbVariableHome::GetCode
3826 // Public method to get the Code object containing this variable home.
3827 // 
3828 // Parameters:
3829 //   ppCode - OUT: returns the Code object for this variable home.
3830 //
3831 // Returns:
3832 //   S_OK - on success.
3833 //-----------------------------------------------------------------------------
3834 HRESULT CordbVariableHome::GetCode(ICorDebugCode **ppCode)
3835 {
3836     PUBLIC_REENTRANT_API_ENTRY(this);
3837     FAIL_IF_NEUTERED(this);
3838     VALIDATE_POINTER_TO_OBJECT(ppCode, ICorDebugCode **);
3839     ATT_REQUIRE_STOPPED_MAY_FAIL(m_pCode->GetProcess());
3840
3841     HRESULT hr = m_pCode->QueryInterface(IID_ICorDebugCode, (LPVOID*)ppCode);
3842
3843     return hr;
3844 }
3845
3846 //-----------------------------------------------------------------------------
3847 // CordbVariableHome::GetSlotIndex
3848 // Public method to get the slot index for this variable home.
3849 // 
3850 // Parameters:
3851 //   pSlotIndex - OUT: returns the managed slot-index of this variable home.
3852 //
3853 // Returns:
3854 //   S_OK - on success
3855 //   E_FAIL - if the variable is not a local variable, but an argument
3856 //-----------------------------------------------------------------------------
3857 HRESULT CordbVariableHome::GetSlotIndex(ULONG32 *pSlotIndex)
3858 {
3859     PUBLIC_REENTRANT_API_ENTRY(this);
3860     FAIL_IF_NEUTERED(this);
3861     VALIDATE_POINTER_TO_OBJECT(pSlotIndex, ULONG32 *);
3862     ATT_REQUIRE_STOPPED_MAY_FAIL(m_pCode->GetProcess());
3863
3864     if (!m_isLocal)
3865     {
3866         return E_FAIL;
3867     }
3868     *pSlotIndex = m_index;
3869     return S_OK;
3870 }
3871
3872 //-----------------------------------------------------------------------------
3873 // CordbVariableHome::GetArgumentIndex
3874 // Public method to get the slot index for this variable home.
3875 // 
3876 // Parameters:
3877 //   pSlotIndex - OUT: returns the managed argument-index of this variable home.
3878 //
3879 // Returns:
3880 //   S_OK - on success
3881 //   E_FAIL - if the variable is not an argument, but a local variable
3882 //-----------------------------------------------------------------------------
3883 HRESULT CordbVariableHome::GetArgumentIndex(ULONG32 *pArgumentIndex)
3884 {
3885     PUBLIC_REENTRANT_API_ENTRY(this);
3886     FAIL_IF_NEUTERED(this);
3887     VALIDATE_POINTER_TO_OBJECT(pArgumentIndex, ULONG32 *);
3888     ATT_REQUIRE_STOPPED_MAY_FAIL(m_pCode->GetProcess());
3889
3890     if (m_isLocal)
3891     {
3892         return E_FAIL;
3893     }
3894     *pArgumentIndex = m_index;
3895     return S_OK;
3896 }
3897
3898 //-----------------------------------------------------------------------------
3899 // CordbVariableHome::GetLiveRange
3900 // Public method to get the native range over which this variable is live.
3901 // 
3902 // Parameters:
3903 //   pStartOffset - OUT: returns the logical offset at which the variable is
3904 //                  first live
3905 //   pEndOffset   - OUT: returns the logical offset immediately after that at
3906 //                  which the variable is last live
3907 //
3908 // Returns:
3909 //   S_OK - on success
3910 //-----------------------------------------------------------------------------
3911 HRESULT CordbVariableHome::GetLiveRange(ULONG32 *pStartOffset,
3912                                         ULONG32 *pEndOffset)
3913 {
3914     PUBLIC_REENTRANT_API_ENTRY(this);
3915     FAIL_IF_NEUTERED(this);
3916     VALIDATE_POINTER_TO_OBJECT(pStartOffset, ULONG32 *);
3917     VALIDATE_POINTER_TO_OBJECT(pEndOffset, ULONG32 *);
3918     ATT_REQUIRE_STOPPED_MAY_FAIL(m_pCode->GetProcess());
3919
3920     *pStartOffset = m_nativeVarInfo.startOffset;
3921     *pEndOffset = m_nativeVarInfo.endOffset;
3922     return S_OK;
3923 }
3924
3925 //-----------------------------------------------------------------------------
3926 // CordbVariableHome::GetLocationType
3927 // Public method to get the type of native location for this variable home.
3928 // 
3929 // Parameters:
3930 //   pLocationType - OUT: the type of native location
3931 //
3932 // Returns:
3933 //   S_OK - on success
3934 //-----------------------------------------------------------------------------
3935 HRESULT CordbVariableHome::GetLocationType(VariableLocationType *pLocationType)
3936 {
3937     PUBLIC_REENTRANT_API_ENTRY(this);
3938     FAIL_IF_NEUTERED(this);
3939     VALIDATE_POINTER_TO_OBJECT(pLocationType, VariableLocationType *);
3940     ATT_REQUIRE_STOPPED_MAY_FAIL(m_pCode->GetProcess());
3941
3942     switch (m_nativeVarInfo.loc.vlType)
3943     {
3944     case ICorDebugInfo::VLT_REG:
3945         *pLocationType = VLT_REGISTER;
3946         break;
3947     case ICorDebugInfo::VLT_STK:
3948         *pLocationType = VLT_REGISTER_RELATIVE;
3949         break;
3950     default:
3951         *pLocationType = VLT_INVALID;
3952     }
3953     return S_OK;
3954 }
3955
3956 //-----------------------------------------------------------------------------
3957 // CordbVariableHome::GetRegister
3958 // Public method to get the register or base register for this variable hom.
3959 // 
3960 // Parameters:
3961 //   pRegister - OUT: for VLT_REGISTER location types, gives the register.
3962 //                    for VLT_REGISTER_RELATIVE location types, gives the base
3963 //                    register.
3964 //
3965 // Returns:
3966 //   S_OK - on success
3967 //   E_FAIL - for VLT_INVALID location types
3968 //-----------------------------------------------------------------------------
3969 HRESULT CordbVariableHome::GetRegister(CorDebugRegister *pRegister)
3970 {
3971     PUBLIC_REENTRANT_API_ENTRY(this);
3972     FAIL_IF_NEUTERED(this);
3973     VALIDATE_POINTER_TO_OBJECT(pRegister, CorDebugRegister *);
3974     ATT_REQUIRE_STOPPED_MAY_FAIL(m_pCode->GetProcess());
3975     
3976     switch (m_nativeVarInfo.loc.vlType)
3977     {
3978     case ICorDebugInfo::VLT_REG:
3979         *pRegister = ConvertRegNumToCorDebugRegister(m_nativeVarInfo.loc.vlReg.vlrReg);
3980         break;
3981     case ICorDebugInfo::VLT_STK:
3982         *pRegister = ConvertRegNumToCorDebugRegister(m_nativeVarInfo.loc.vlStk.vlsBaseReg);
3983         break;
3984     default:
3985         return E_FAIL;
3986     }
3987     return S_OK;
3988 }
3989
3990 //-----------------------------------------------------------------------------
3991 // CordbVariableHome::GetOffset
3992 // Public method to get the offset from the base register for this variable home.
3993 // 
3994 // Parameters:
3995 //   pOffset - OUT: gives the offset from the base register
3996 //
3997 // Returns:
3998 //   S_OK - on success
3999 //   E_FAIL - for location types other than VLT_REGISTER_RELATIVE
4000 //-----------------------------------------------------------------------------
4001 HRESULT CordbVariableHome::GetOffset(LONG *pOffset)
4002 {
4003     PUBLIC_REENTRANT_API_ENTRY(this);
4004     FAIL_IF_NEUTERED(this);
4005     VALIDATE_POINTER_TO_OBJECT(pOffset, LONG *);
4006     ATT_REQUIRE_STOPPED_MAY_FAIL(m_pCode->GetProcess());
4007
4008     switch (m_nativeVarInfo.loc.vlType)
4009     {
4010     case ICorDebugInfo::VLT_STK:
4011         *pOffset = m_nativeVarInfo.loc.vlStk.vlsOffset;
4012         break;
4013     default:
4014         return E_FAIL;
4015     }
4016     return S_OK;
4017 }
4018
4019
4020 // * ------------------------------------------------------------------------- *
4021 // * Native Code class
4022 // * ------------------------------------------------------------------------- */
4023
4024
4025 //-----------------------------------------------------------------------------
4026 // CordbNativeCode ctor to make Native code.
4027 // Arguments:
4028 //    Input:
4029 //        pFunction              - the function for which this is the native code object
4030 //        pJitData               - the information about this code object retrieved from the DAC
4031 //        fIsInstantiatedGeneric - indicates whether this code object is an instantiated 
4032 //                                 generic
4033 //    Output:
4034 //        fields of this instance of CordbNativeCode have been initialized
4035 //-----------------------------------------------------------------------------
4036 CordbNativeCode::CordbNativeCode(CordbFunction *                pFunction, 
4037                                  const NativeCodeFunctionData * pJitData, 
4038                                  BOOL                           fIsInstantiatedGeneric)
4039   : CordbCode(pFunction, (UINT_PTR)pJitData->m_rgCodeRegions[kHot].pAddress, pJitData->encVersion, FALSE),
4040     m_vmNativeCodeMethodDescToken(pJitData->vmNativeCodeMethodDescToken),
4041     m_fCodeAvailable(TRUE),
4042     m_fIsInstantiatedGeneric(fIsInstantiatedGeneric != FALSE)
4043 {
4044     _ASSERTE(GetVersion() >= CorDB_DEFAULT_ENC_FUNCTION_VERSION);
4045  
4046     for (CodeBlobRegion region = kHot; region < MAX_REGIONS; ++region)
4047     {
4048         m_rgCodeRegions[region] = pJitData->m_rgCodeRegions[region];
4049     }
4050 } //CordbNativeCode::CordbNativeCode 
4051
4052 //-----------------------------------------------------------------------------
4053 // Public method for IUnknown::QueryInterface.
4054 // Has standard QI semantics.
4055 //-----------------------------------------------------------------------------
4056 HRESULT CordbNativeCode::QueryInterface(REFIID id, void ** pInterface)
4057 {
4058     if (id == IID_ICorDebugCode)
4059     {
4060         *pInterface = static_cast<ICorDebugCode *>(this);
4061     }
4062     else if (id == IID_ICorDebugCode2)
4063     {
4064         *pInterface = static_cast<ICorDebugCode2 *>(this);
4065     }
4066     else if (id == IID_ICorDebugCode3)
4067     {
4068         *pInterface = static_cast<ICorDebugCode3 *>(this);
4069     }
4070     else if (id == IID_ICorDebugCode4)
4071     {
4072         *pInterface = static_cast<ICorDebugCode4 *>(this);
4073     }
4074     else if (id == IID_IUnknown)
4075     {
4076         *pInterface = static_cast<IUnknown *>(static_cast<ICorDebugCode *>(this));
4077     }
4078     else
4079     {
4080         *pInterface = NULL;
4081         return E_NOINTERFACE;
4082     }
4083
4084     ExternalAddRef();
4085     return S_OK;
4086 }
4087
4088 //-----------------------------------------------------------------------------
4089 // CordbNativeCode::GetAddress
4090 // Public method to get the Entry address for the code.  This is the address
4091 // where the method first starts executing. 
4092 //
4093 // Parameters:
4094 //    pStart - out-parameter to hold start address.
4095 // 
4096 // Returns:
4097 //    S_OK if *pStart is properly updated.
4098 //-----------------------------------------------------------------------------
4099 HRESULT CordbNativeCode::GetAddress(CORDB_ADDRESS * pStart)
4100 {
4101     PUBLIC_REENTRANT_API_ENTRY(this);
4102     FAIL_IF_NEUTERED(this);
4103     VALIDATE_POINTER_TO_OBJECT(pStart, CORDB_ADDRESS *);
4104
4105
4106     _ASSERTE(this != NULL);
4107     _ASSERTE(this->GetFunction() != NULL);
4108     _ASSERTE(this->GetFunction()->GetModule() != NULL);
4109     _ASSERTE(this->GetFunction()->GetModule()->GetProcess() == GetProcess());
4110
4111     // Since we don't do code-pitching, the address points directly to the code.
4112     *pStart = (m_rgCodeRegions[kHot].pAddress);
4113
4114     if (*pStart == NULL)
4115     {
4116         return CORDBG_E_CODE_NOT_AVAILABLE;
4117     }
4118     return S_OK;
4119 } // CordbNativeCode::GetAddress
4120
4121 //-----------------------------------------------------------------------------
4122 // CordbNativeCode::ReadCodeBytes
4123 // Reads the actual bytes of native code from both the hot and cold regions
4124 // into the data member m_rgbCode
4125 // Arguments:
4126 //    none (uses data members)
4127 // Return value:
4128 //    standard HRESULT values
4129 //    also allocates and initializes m_rgbCode
4130 // Notes: assumes that the caller has checked to ensure that m_rgbCode doesn't
4131 //    hold valid data
4132 //-----------------------------------------------------------------------------
4133 HRESULT CordbNativeCode::ReadCodeBytes()
4134 {
4135     HRESULT hr = S_OK;
4136
4137     EX_TRY
4138     {
4139         // We have an address & size, so we'll just call ReadMemory.
4140         // This will conveniently strip out any patches too.
4141         CORDB_ADDRESS pHotStart = m_rgCodeRegions[kHot].pAddress;
4142         CORDB_ADDRESS pColdStart = m_rgCodeRegions[kCold].pAddress;
4143         ULONG32 cbHotSize = (ULONG32) m_rgCodeRegions[kHot].cbSize;
4144         ULONG32 cbColdSize = GetColdSize();
4145
4146         delete [] m_rgbCode;
4147         m_rgbCode = new BYTE[cbHotSize + cbColdSize];
4148
4149         SIZE_T cbRead;
4150         hr = GetProcess()->ReadMemory(pHotStart, cbHotSize, m_rgbCode, &cbRead);
4151         IfFailThrow(hr);
4152
4153         SIMPLIFYING_ASSUMPTION(cbRead == cbHotSize);
4154
4155         if (HasColdRegion())
4156         {
4157             hr = GetProcess()->ReadMemory(pColdStart, cbColdSize, (BYTE *) m_rgbCode + cbHotSize, &cbRead);
4158             IfFailThrow(hr);
4159
4160             SIMPLIFYING_ASSUMPTION(cbRead == cbColdSize);
4161         }
4162     }
4163     EX_CATCH_HRESULT(hr);
4164     return hr;
4165
4166 } // CordbNativeCode::ReadCodeBytes
4167
4168 //-----------------------------------------------------------------------------
4169 // CordbNativeCode::GetColdSize
4170 // Get the size of the cold regions in bytes. 
4171 //
4172 // Parameters:
4173 //   none--uses data member m_rgCodeRegions to compute total size.
4174 //
4175 // Returns:
4176 //   the size of the code in bytes.
4177 //-----------------------------------------------------------------------------
4178 ULONG32 CordbNativeCode::GetColdSize()
4179 {
4180     ULONG32 pcBytes = 0;
4181     for (CodeBlobRegion index = kCold; index < MAX_REGIONS; ++index)
4182     {
4183         pcBytes += m_rgCodeRegions[index].cbSize;
4184     }
4185     return pcBytes;
4186 } // CordbNativeCode::GetColdSize
4187
4188 //-----------------------------------------------------------------------------
4189 // CordbNativeCode::GetSize
4190 // Get the size of the code in bytes. 
4191 //
4192 // Parameters:
4193 //   none--uses data member m_rgCodeRegions to compute total size.
4194 //
4195 // Returns:
4196 //   the size of the code in bytes.
4197 //-----------------------------------------------------------------------------
4198 ULONG32 CordbNativeCode::GetSize()
4199 {
4200     ULONG32 pcBytes = 0;
4201     for (CodeBlobRegion index = kHot; index < MAX_REGIONS; ++index)
4202     {
4203         pcBytes += m_rgCodeRegions[index].cbSize;
4204     }
4205     return pcBytes;
4206 } // CordbNativeCode::GetSize
4207
4208 //-----------------------------------------------------------------------------
4209 // CordbNativeCode::GetILToNativeMapping
4210 // Public method (implements ICorDebugCode) to get the IL-->{ Native Start, Native End} mapping.
4211 // This can only be retrieved for native code.
4212 // This will copy as much of the map as can fit in the incoming buffer.
4213 // 
4214 // Parameters:
4215 //    cMap - size of incoming map[] array (in elements).
4216 //    pcMap - OUT: full size of IL-->Native map (in elements). 
4217 //    map - caller allocated array to be filled in.
4218 // 
4219 // Returns:
4220 //    S_OK on successful copying. 
4221 //-----------------------------------------------------------------------------
4222 HRESULT CordbNativeCode::GetILToNativeMapping(ULONG32                    cMap,
4223                                               ULONG32 *                  pcMap,
4224                                               COR_DEBUG_IL_TO_NATIVE_MAP map[])
4225 {
4226     PUBLIC_REENTRANT_API_ENTRY(this);
4227     FAIL_IF_NEUTERED(this);
4228     VALIDATE_POINTER_TO_OBJECT_OR_NULL(pcMap, ULONG32 *);
4229     VALIDATE_POINTER_TO_OBJECT_ARRAY_OR_NULL(map, COR_DEBUG_IL_TO_NATIVE_MAP *,cMap,true,true);
4230
4231     ATT_REQUIRE_STOPPED_MAY_FAIL(GetProcess());
4232
4233     HRESULT hr = S_OK;
4234     EX_TRY
4235     {
4236         LoadNativeInfo();
4237
4238         SequencePoints * pSeqPts = GetSequencePoints();
4239         DebuggerILToNativeMap * rgMapInt = pSeqPts->GetMapAddr();
4240         ULONG32 cMapIntCount = pSeqPts->GetEntryCount();
4241
4242         // If they gave us space to copy into...
4243         if (map != NULL)
4244         {
4245             // Only copy as much as either they gave us or we have to copy.
4246             ULONG32 cMapToCopy = min(cMap, cMapIntCount);
4247
4248             // Remember that we need to translate between our internal DebuggerILToNativeMap and the external
4249             // COR_DEBUG_IL_TO_NATIVE_MAP!
4250             ULONG32 size = GetSize();
4251             ExportILToNativeMap(cMapToCopy, map, rgMapInt, size);
4252         }
4253
4254         // return the full count of map entries
4255         if (pcMap)
4256         {
4257             *pcMap = cMapIntCount;
4258         }
4259     }
4260     EX_CATCH_HRESULT(hr);
4261     return hr;
4262 } // CordbNativeCode::GetILToNativeMapping
4263
4264 //-----------------------------------------------------------------------------
4265 // CordbNativeCode::GetCodeChunks
4266 // Public method to get the code regions of code. If the code
4267 // is broken into discontinuous regions (hot + cold), this lets a debugger 
4268 // find the number of regions, and (start,size) of each.
4269 // 
4270 // Parameters:
4271 //   cbufSize - size of incoming chunks array (in elements).
4272 //   pcnumChunks - OUT param: the number of elements written to in the chunk array.// 
4273 //   chunks - caller allocated storage to hold the code chunks.
4274 //
4275 // Returns:
4276 //    S_OK if successfully copied elements to Chunk array.
4277 //-----------------------------------------------------------------------------
4278 HRESULT CordbNativeCode::GetCodeChunks(
4279     ULONG32 cbufSize,
4280     ULONG32 * pcnumChunks,
4281     CodeChunkInfo chunks[]
4282 )
4283 {
4284     PUBLIC_API_ENTRY(this);
4285
4286     if (pcnumChunks == NULL)
4287     {
4288         return E_INVALIDARG;
4289     }
4290     if ((chunks == NULL) != (cbufSize == 0))
4291     {
4292         return E_INVALIDARG;
4293     }
4294
4295     // Current V2.0 implementation has at most 2 possible chunks right now (1 hot, and 1 cold).
4296     ULONG32 cActualChunks = HasColdRegion() ? 2 : 1;
4297
4298     // If no buf size, then we're querying the total number of chunks.
4299     if (cbufSize == 0)
4300     {
4301         *pcnumChunks = cActualChunks;
4302         return S_OK;
4303     }
4304
4305     // Else give them as many as they asked for.
4306     for (CodeBlobRegion index = kHot; (index < MAX_REGIONS) && ((int)cbufSize > index); ++index)
4307     {
4308         // Fill in the region information
4309         chunks[index].startAddr = m_rgCodeRegions[index].pAddress;
4310         chunks[index].length = (ULONG32) (m_rgCodeRegions[index].cbSize);
4311         *pcnumChunks = cbufSize;
4312     }
4313
4314     return S_OK;
4315 } // CordbNativeCode::GetCodeChunks
4316
4317 //-----------------------------------------------------------------------------
4318 // CordbNativeCode::GetCompilerFlags
4319 // Public entry point to get code flags for this Code object.
4320 // Originally, ICDCode had this method implemented independently from the 
4321 // ICDModule method GetJitCompilerFlags. This was because it was considered that 
4322 // the flags would be per function, rather than per module. 
4323 // In addition, GetCompilerFlags did two different things depending on whether 
4324 // the code had a native image. It turned out that was the wrong thing to do
4325 // .
4326 // 
4327 // Parameters:
4328 //    pdwFlags - OUT: code gen flags (see CorDebugJITCompilerFlags)
4329 // 
4330 // Return value:
4331 //    S_OK if pdwFlags is set properly.
4332 //-----------------------------------------------------------------------------
4333 HRESULT CordbNativeCode::GetCompilerFlags(DWORD * pdwFlags)
4334 {
4335     PUBLIC_API_ENTRY(this);
4336     FAIL_IF_NEUTERED(this);
4337     VALIDATE_POINTER_TO_OBJECT(pdwFlags, DWORD *);
4338     *pdwFlags = 0;
4339     ATT_REQUIRE_STOPPED_MAY_FAIL(GetProcess());
4340
4341     return GetFunction()->GetModule()->GetJITCompilerFlags(pdwFlags);
4342
4343 } // CordbNativeCode::GetCompilerFlags
4344
4345 //-----------------------------------------------------------------------------
4346 // Given an IL local variable number and a native IP offset, return the
4347 // location of the variable in jitted code.
4348 //-----------------------------------------------------------------------------
4349 HRESULT CordbNativeCode::ILVariableToNative(DWORD dwIndex,
4350                                             SIZE_T ip,
4351                                             const ICorDebugInfo::NativeVarInfo ** ppNativeInfo)
4352 {
4353     _ASSERTE(m_nativeVarData.IsInitialized());
4354
4355     return FindNativeInfoInILVariableArray(dwIndex,
4356                                            ip,
4357                                            m_nativeVarData.GetOffsetInfoList(),
4358                                            ppNativeInfo);
4359 } // CordbNativeCode::ILVariableToNative
4360
4361
4362 HRESULT CordbNativeCode::GetReturnValueLiveOffset(ULONG32 ILoffset, ULONG32 bufferSize, ULONG32 *pFetched, ULONG32 *pOffsets)
4363 {
4364     HRESULT hr = S_OK;
4365     
4366     PUBLIC_API_ENTRY(this);
4367     FAIL_IF_NEUTERED(this);
4368
4369     VALIDATE_POINTER_TO_OBJECT(pFetched, ULONG32 *);
4370
4371     ATT_REQUIRE_STOPPED_MAY_FAIL(GetProcess());
4372     EX_TRY
4373     {
4374         hr = GetReturnValueLiveOffsetImpl(NULL, ILoffset, bufferSize, pFetched, pOffsets);
4375     }
4376     EX_CATCH_HRESULT(hr);
4377     return hr;
4378 }
4379
4380 //-----------------------------------------------------------------------------
4381 // CordbNativeCode::EnumerateVariableHomes
4382 // Public method to get an enumeration of native variable homes. This may
4383 // include multiple ICorDebugVariableHomes for the same slot or argument index
4384 // if they have different homes at different points in the function.
4385 // 
4386 // Parameters:
4387 //   ppEnum - OUT: returns the enum of variable homes.
4388 //
4389 // Returns:
4390 //   HRESULT for success or failure.
4391 //-----------------------------------------------------------------------------
4392 HRESULT CordbNativeCode::EnumerateVariableHomes(ICorDebugVariableHomeEnum **ppEnum)
4393 {
4394     PUBLIC_REENTRANT_API_ENTRY(this);
4395     FAIL_IF_NEUTERED(this);
4396     VALIDATE_POINTER_TO_OBJECT(ppEnum, ICorDebugVariableHomeEnum **);
4397     ATT_REQUIRE_STOPPED_MAY_FAIL(GetProcess());
4398     
4399     HRESULT hr = S_OK;
4400     
4401     // Get the argument count
4402     ULONG argCount = 0;
4403     CordbFunction *func = GetFunction();
4404     _ASSERTE(func != NULL);
4405     IfFailRet(func->GetSig(NULL, &argCount, NULL));
4406
4407 #ifdef _DEBUG
4408     // Get the number of locals
4409     ULONG localCount = 0;
4410     EX_TRY
4411     {
4412         GetFunction()->GetILCode()->GetLocalVarSig(NULL, &localCount);
4413     }
4414     EX_CATCH_HRESULT(hr);
4415     IfFailRet(hr);
4416 #endif
4417     
4418     RSSmartPtr<CordbVariableHome> *rsHomes = NULL;
4419     
4420     EX_TRY
4421     {
4422         CordbProcess *pProcess = GetProcess();
4423         _ASSERTE(pProcess != NULL);
4424         
4425         const DacDbiArrayList<ICorDebugInfo::NativeVarInfo> *pOffsetInfoList = m_nativeVarData.GetOffsetInfoList();
4426         _ASSERTE(pOffsetInfoList != NULL);
4427         DWORD countHomes = 0;
4428         for (int i = 0; i < pOffsetInfoList->Count(); i++)
4429         {
4430             const ICorDebugInfo::NativeVarInfo *pNativeVarInfo = &((*pOffsetInfoList)[i]);
4431             _ASSERTE(pNativeVarInfo != NULL);
4432             
4433             // The variable information list can include variables
4434             // with special varNumbers representing, for instance, the
4435             // parameter types for generic methods. Here we are only
4436             // interested in local variables and arguments.
4437             if (pNativeVarInfo->varNumber < (DWORD)ICorDebugInfo::MAX_ILNUM)
4438             {
4439                 countHomes++;
4440             }
4441         }
4442         rsHomes = new RSSmartPtr<CordbVariableHome>[countHomes];
4443
4444         DWORD varHomeInd = 0;
4445         for (int i = 0; i < pOffsetInfoList->Count(); i++)
4446         {
4447             const ICorDebugInfo::NativeVarInfo *pNativeVarInfo = &((*pOffsetInfoList)[i]);
4448
4449             // Again, only look for native var info representing local
4450             // variables and arguments.
4451             if (pNativeVarInfo->varNumber < (DWORD)ICorDebugInfo::MAX_ILNUM)
4452             {
4453                 // determine whether this variable home represents and argument or local variable
4454                 BOOL isLocal = ((ULONG)pNativeVarInfo->varNumber >= argCount);
4455                 
4456                 // determine the argument-index or slot-index of this variable home
4457                 ULONG argOrSlotIndex;
4458                 if (isLocal) {
4459                     argOrSlotIndex = pNativeVarInfo->varNumber - argCount;
4460                     _ASSERTE(argOrSlotIndex < localCount);
4461                 } else {
4462                     argOrSlotIndex = pNativeVarInfo->varNumber;
4463                 }
4464
4465                 RSInitHolder<CordbVariableHome> pCVH(new CordbVariableHome(this,
4466                                                                            (*pOffsetInfoList)[i],
4467                                                                            isLocal,
4468                                                                            argOrSlotIndex));
4469                 pProcess->GetContinueNeuterList()->Add(pProcess, pCVH);
4470                 _ASSERTE(varHomeInd < countHomes);
4471                 rsHomes[varHomeInd].Assign(pCVH);
4472                 pCVH.ClearAndMarkDontNeuter();
4473                 varHomeInd++;
4474             }
4475         }
4476
4477         RSInitHolder<CordbVariableHomeEnumerator> pCDVHE(
4478             new CordbVariableHomeEnumerator(GetProcess(), &rsHomes, countHomes));
4479         pProcess->GetContinueNeuterList()->Add(pProcess, pCDVHE);
4480         pCDVHE.TransferOwnershipExternal(ppEnum);
4481     }
4482     EX_CATCH_HRESULT(hr);
4483
4484     return hr;
4485 }
4486
4487 int CordbNativeCode::GetCallInstructionLength(BYTE *ip, ULONG32 count)
4488 {
4489 #if defined(DBG_TARGET_ARM)
4490     return MAX_INSTRUCTION_LENGTH;
4491 #elif defined(DBG_TARGET_ARM64)
4492     return MAX_INSTRUCTION_LENGTH;
4493 #elif defined(DBG_TARGET_X86)
4494     if (count < 2)
4495         return -1;
4496
4497     // Skip instruction prefixes
4498     do 
4499     {
4500         switch (*ip)
4501         {
4502             // Segment overrides
4503         case 0x26: // ES
4504         case 0x2E: // CS
4505         case 0x36: // SS
4506         case 0x3E: // DS 
4507         case 0x64: // FS
4508         case 0x65: // GS
4509
4510             // Size overrides
4511         case 0x66: // Operand-Size
4512         case 0x67: // Address-Size
4513
4514             // Lock
4515         case 0xf0:
4516
4517             // String REP prefixes
4518         case 0xf1:
4519         case 0xf2: // REPNE/REPNZ
4520         case 0xf3:
4521             ip++;
4522             count--;
4523             continue;
4524
4525         default:
4526             break;
4527         }
4528     } while (0);
4529
4530     // Read the opcode
4531     BYTE opcode = *ip++;
4532     if (opcode == 0xcc)
4533     {
4534         // todo:  Can we actually get this result?  Doesn't ICorDebug hand out un-patched assembly?
4535         _ASSERTE(!"Hit break opcode!");
4536         return -1;
4537     }
4538
4539     // Analyze what we can of the opcode
4540     switch (opcode)
4541     {
4542     case 0xff:
4543     {
4544                  // Count may have been decremented by prefixes.
4545                  if (count < 2)
4546                      return -1;
4547
4548                  BYTE modrm = *ip++;
4549                  BYTE mod = (modrm & 0xC0) >> 6;
4550                  BYTE reg = (modrm & 0x38) >> 3;
4551                  BYTE rm  = (modrm & 0x07);
4552
4553                  int displace = -1;
4554
4555                  if ((reg != 2) && (reg != 3) && (reg != 4) && (reg != 5))
4556                  {
4557                      //
4558                      // This is not a CALL or JMP instruction, return, unknown.
4559                      //
4560                      _ASSERTE(!"Unhandled opcode!");
4561                      return -1;
4562                  }
4563
4564
4565                  // Only try to decode registers if we actually have reg sets.
4566                  switch (mod)
4567                  {
4568                  case 0:
4569                  case 1:
4570                  case 2:
4571
4572                      if (rm == 4)
4573                      {
4574                          if (count < 3)
4575                              return -1;
4576
4577                          //
4578                          // Get values from the SIB byte
4579                          //
4580                          BYTE ss    = (*ip & 0xC0) >> 6;
4581                          BYTE index = (*ip & 0x38) >> 3;
4582                          BYTE base  = (*ip & 0x7);
4583
4584                          //
4585                          // Finally add in the offset
4586                          //
4587                          if (mod == 0)
4588                          {
4589                              if (base == 5)
4590                                  displace = 7;
4591                              else
4592                                  displace = 3;
4593                          }
4594                          else if (mod == 1)
4595                          {
4596                              displace = 4;
4597                          }
4598                          else
4599                          {
4600                              displace = 7;
4601                          }
4602                      }
4603                      else
4604                      {
4605                          if (mod == 0)
4606                          {
4607                              if (rm == 5)
4608                                  displace = 6;
4609                              else
4610                                  displace = 2;
4611                          }
4612                          else if (mod == 1)
4613                          {
4614                              displace = 3;
4615                          }
4616                          else
4617                          {
4618                              displace = 6;
4619                          }
4620                      }
4621                      break;
4622
4623                  case 3:
4624                  default:
4625                      displace = 2;
4626                      break;
4627                  }
4628
4629                  return displace;
4630     }  // end of 0xFF case
4631
4632     case 0xe8:
4633         return 5;
4634
4635
4636     default:
4637         break;
4638     }
4639
4640
4641     _ASSERTE(!"Unhandled opcode!");
4642     return -1;
4643
4644 #elif defined(DBG_TARGET_AMD64)
4645     BYTE rex = NULL;
4646     BYTE prefix = *ip;
4647     BOOL fContainsPrefix = FALSE;
4648
4649     // Should not happen.
4650     if (prefix == 0xcc)
4651         return -1;
4652
4653     // Skip instruction prefixes
4654     //@TODO by euzem: 
4655     //This "loop" can't be really executed more than once so if CALL can really have more than one prefix we'll crash.
4656     //Some of these prefixes are not allowed for CALL instruction and we should treat them as invalid code.
4657     //It appears that this code was mostly copy/pasted from \NDP\clr\src\Debug\EE\amd64\amd64walker.cpp
4658     //with very minimum fixes.
4659     do 
4660     {
4661         switch (prefix)
4662         {
4663             // Segment overrides
4664         case 0x26: // ES
4665         case 0x2E: // CS
4666         case 0x36: // SS
4667         case 0x3E: // DS 
4668         case 0x64: // FS
4669         case 0x65: // GS
4670
4671             // Size overrides
4672         case 0x66: // Operand-Size
4673         case 0x67: // Address-Size
4674
4675             // Lock
4676         case 0xf0:
4677
4678             // String REP prefixes
4679         case 0xf2: // REPNE/REPNZ
4680         case 0xf3: 
4681             ip++;
4682             fContainsPrefix = TRUE;
4683             continue;
4684
4685             // REX register extension prefixes
4686         case 0x40:            
4687         case 0x41:
4688         case 0x42:
4689         case 0x43:
4690         case 0x44:
4691         case 0x45:
4692         case 0x46:
4693         case 0x47:
4694         case 0x48:
4695         case 0x49:
4696         case 0x4a:
4697         case 0x4b:
4698         case 0x4c:
4699         case 0x4d:
4700         case 0x4e:
4701         case 0x4f:
4702             // make sure to set rex to prefix, not *ip because *ip still represents the 
4703             // codestream which has a 0xcc in it.
4704             rex = prefix;
4705             ip++;
4706             fContainsPrefix = TRUE;
4707             continue;
4708
4709         default:
4710             break;
4711         }
4712     } while (0);
4713
4714     // Read the opcode
4715     BYTE opcode = *ip++;
4716
4717     // Should not happen.
4718     if (opcode == 0xcc)
4719         return -1;
4720
4721
4722     // Setup rex bits if needed
4723     BYTE rex_b = 0;
4724     BYTE rex_x = 0;
4725     BYTE rex_r = 0;
4726
4727     if (rex != NULL)
4728     {
4729         rex_b = (rex & 0x1);       // high bit to modrm r/m field or SIB base field or OPCODE reg field    -- Hmm, when which?
4730         rex_x = (rex & 0x2) >> 1;  // high bit to sib index field
4731         rex_r = (rex & 0x4) >> 2;  // high bit to modrm reg field
4732     }
4733
4734     // Analyze what we can of the opcode
4735     switch (opcode)
4736     {
4737     case 0xff:
4738     {
4739                  BYTE modrm = *ip++;
4740
4741                  _ASSERT(modrm != NULL);
4742
4743                  BYTE mod = (modrm & 0xC0) >> 6;
4744                  BYTE reg = (modrm & 0x38) >> 3;
4745                  BYTE rm  = (modrm & 0x07);
4746
4747                  reg   |= (rex_r << 3);
4748                  rm    |= (rex_b << 3);
4749
4750                  if ((reg < 2) || (reg > 5 && reg < 8) || (reg > 15)) {
4751                      // not a valid register for a CALL or BRANCH
4752                      _ASSERTE(!"Invalid opcode!");
4753                      return -1;
4754                  }
4755
4756                  BYTE *result;
4757                  WORD displace = -1;
4758
4759                  // See: Tables A-15,16,17 in AMD Dev Manual 3 for information
4760                  //      about how the ModRM/SIB/REX bytes interact.
4761
4762                  switch (mod) 
4763                  {
4764                  case 0:
4765                  case 1:
4766                  case 2:     
4767                      if ((rm & 0x07) == 4) // we have an SIB byte following
4768                      {   
4769                          //
4770                          // Get values from the SIB byte
4771                          //
4772                          BYTE sib   = *ip;
4773                          _ASSERT(sib != NULL);
4774
4775                          BYTE base  = (sib & 0x07);
4776                          base  |= (rex_b << 3);
4777
4778                          ip++;
4779
4780                          //
4781                          // Finally add in the offset
4782                          //
4783                          if (mod == 0) 
4784                          {
4785                              if ((base & 0x07) == 5) 
4786                                  displace = 7;
4787                              else 
4788                                  displace = 3;
4789                          } 
4790                          else if (mod == 1) 
4791                          {
4792                              displace = 4;
4793                          } 
4794                          else // mod == 2
4795                          {
4796                              displace = 7;
4797                          }
4798                      } 
4799                      else 
4800                      {
4801                          //
4802                          // Get the value we need from the register.
4803                          //
4804
4805                          // Check for RIP-relative addressing mode.
4806                          if ((mod == 0) && ((rm & 0x07) == 5)) 
4807                          {
4808                              displace = 6;   // 1 byte opcode + 1 byte modrm + 4 byte displacement (signed)
4809                          } 
4810                          else 
4811                          {
4812                              if (mod == 0) 
4813                                  displace = 2;
4814                              else if (mod == 1) 
4815                                  displace = 3;
4816                              else // mod == 2
4817                                  displace = 6;
4818                          }
4819                      }
4820
4821                      break;
4822
4823                  case 3:
4824                  default:
4825                      displace = 2;
4826                  }
4827
4828                  // Displace should be set by one of the cases above
4829                  if (displace == -1)
4830                  {
4831                      _ASSERTE(!"GetCallInstructionLength() encountered unexpected call instruction");
4832                      return -1;
4833                  }
4834
4835                  // Account for the 1 byte prefix (REX or otherwise)
4836                  if (fContainsPrefix)
4837                      displace++;
4838
4839                  // reg == 4 or 5 means that it is not a CALL, but JMP instruction
4840                  // so we will fall back to ASSERT after break
4841                  if ((reg != 4) && (reg != 5)) 
4842                      return displace;
4843                  break;
4844     }
4845     case 0xe8:
4846     {
4847                  //Near call with the target specified by a 32-bit relative displacement.
4848                  //[maybe 1 byte prefix] + [1 byte opcode E8h] + [4 bytes offset]
4849                  return 5 + (fContainsPrefix ? 1 : 0);
4850     }
4851     default:
4852         break;
4853     }
4854
4855     _ASSERTE(!"Invalid opcode!");
4856     return -1;
4857 #else
4858 #error Platform not implemented
4859 #endif
4860 }
4861
4862 HRESULT CordbNativeCode::GetSigParserFromFunction(mdToken mdFunction, mdToken *pClass, SigParser &parser, SigParser &methodGenerics)
4863 {
4864     // mdFunction may be a MemberRef, a MethodDef, or a MethodSpec.  We must handle all three cases.
4865     HRESULT hr = S_OK;
4866     IMetaDataImport* pImport = m_pFunction->GetModule()->GetMetaDataImporter();
4867     RSExtSmartPtr<IMetaDataImport2> pImport2;
4868     IfFailRet(pImport->QueryInterface(IID_IMetaDataImport2, (void**)&pImport2));
4869
4870     if (TypeFromToken(mdFunction) == mdtMemberRef)
4871     {
4872         PCCOR_SIGNATURE sig = 0;
4873         ULONG sigSize = 0;
4874         IfFailRet(pImport->GetMemberRefProps(mdFunction, pClass, NULL, 0, 0, &sig, &sigSize));
4875         parser = SigParser(sig, sigSize);
4876     }
4877     else if (TypeFromToken(mdFunction) == mdtMethodDef)
4878     {
4879         PCCOR_SIGNATURE sig = 0;
4880         ULONG sigSize = 0;
4881         IfFailRet(pImport->GetMethodProps(mdFunction, pClass, NULL, 0, NULL, NULL, &sig, &sigSize, NULL, NULL));
4882         parser = SigParser(sig, sigSize);
4883     }
4884     else if (TypeFromToken(mdFunction) == mdtMethodSpec)
4885     {
4886         // For a method spec, we use GetMethodSpecProps to get the generic singature and the parent token
4887         // (which is a MethodDef token).  We'll recurse to get the other properties from the parent token.
4888
4889         PCCOR_SIGNATURE sig = 0;
4890         ULONG sigSize = 0;
4891         mdToken parentToken = 0;
4892         IfFailRet(pImport2->GetMethodSpecProps(mdFunction, &parentToken, &sig, &sigSize));
4893         methodGenerics = SigParser(sig, sigSize);
4894
4895         if (pClass)
4896             *pClass = parentToken;
4897
4898         return GetSigParserFromFunction(parentToken, pClass, parser, methodGenerics);
4899     }
4900     else
4901     {
4902         // According to ECMA III.3.19, this can never happen.
4903         return E_UNEXPECTED;
4904     }
4905
4906     return S_OK;
4907 }
4908
4909 HRESULT CordbNativeCode::EnsureReturnValueAllowed(Instantiation *currentInstantiation, mdToken targetClass, SigParser &parser, SigParser &methodGenerics)
4910 {
4911     HRESULT hr = S_OK;
4912     ULONG genCount = 0;
4913     IfFailRet(SkipToReturn(parser, &genCount));
4914
4915     return EnsureReturnValueAllowedWorker(currentInstantiation, targetClass, parser, methodGenerics, genCount);
4916 }
4917
4918 HRESULT CordbNativeCode::EnsureReturnValueAllowedWorker(Instantiation *currentInstantiation, mdToken targetClass, SigParser &parser, SigParser &methodGenerics, ULONG genCount)
4919 {
4920     // There are a few considerations here:
4921     // 1.  Generic instantiations.  This is a "Foo<T>", and we need to check if that "Foo"
4922     //      fits one of the categories we disallow (such as a struct).
4923     // 2.  Void return.
4924     // 3.  ValueType - Unsupported this release.
4925     // 4.  MVAR - Method generics.  We need to get the actual generic type and recursively
4926     //      check if we allow that.
4927     // 5.  VAR - Class generics.  We need to get the actual generic type and recurse.
4928
4929     SigParser original(parser);
4930     HRESULT hr = S_OK;
4931     CorElementType returnType;
4932     IfFailRet(parser.GetElemType(&returnType));
4933     if (returnType == ELEMENT_TYPE_GENERICINST)
4934     {
4935         IfFailRet(parser.GetElemType(&returnType));
4936
4937         if (returnType == ELEMENT_TYPE_CLASS)
4938             return S_OK;
4939
4940         if (returnType != ELEMENT_TYPE_VALUETYPE)
4941             return META_E_BAD_SIGNATURE;
4942         
4943         if (currentInstantiation == NULL)
4944             return S_OK;  // We will check again when we have the instantiation.
4945
4946         NewArrayHolder<CordbType*> types;
4947         Instantiation inst;
4948         IfFailRet(CordbJITILFrame::BuildInstantiationForCallsite(GetModule(), types, inst, currentInstantiation, targetClass, SigParser(methodGenerics)));
4949
4950         CordbType *pType = 0;
4951         IfFailRet(CordbType::SigToType(GetModule(), &original, &inst, &pType));
4952
4953         
4954         IfFailRet(hr = pType->ReturnedByValue());
4955         if (hr == S_OK) // not S_FALSE
4956             return S_OK;
4957
4958         return CORDBG_E_UNSUPPORTED;
4959     }
4960
4961     if (returnType == ELEMENT_TYPE_VALUETYPE)
4962     {
4963         Instantiation inst;
4964         CordbType *pType = 0;
4965         IfFailRet(CordbType::SigToType(GetModule(), &original, &inst, &pType));
4966
4967         IfFailRet(hr = pType->ReturnedByValue());
4968         if (hr == S_OK) // not S_FALSE
4969             return S_OK;
4970
4971         return CORDBG_E_UNSUPPORTED;
4972     }
4973
4974     if (returnType == ELEMENT_TYPE_TYPEDBYREF)
4975         return CORDBG_E_UNSUPPORTED;
4976
4977     if (returnType == ELEMENT_TYPE_VOID)
4978         return E_UNEXPECTED;
4979
4980     if (returnType == ELEMENT_TYPE_MVAR)
4981     {
4982         // Get which generic parameter is referenced.
4983         ULONG genParam = 0;
4984         IfFailRet(parser.GetData(&genParam));
4985
4986         // Grab the calling convention of the method, ensure it's GENERICINST.
4987         ULONG callingConv = 0;
4988         IfFailRet(methodGenerics.GetCallingConvInfo(&callingConv));
4989         if (callingConv != IMAGE_CEE_CS_CALLCONV_GENERICINST)
4990             return META_E_BAD_SIGNATURE;
4991
4992         // Ensure sensible bounds.
4993         SigParser generics(methodGenerics);     // Make a copy since operations are destructive.
4994         ULONG maxCount = 0;
4995         IfFailRet(generics.GetData(&maxCount));
4996         if (maxCount <= genParam || genParam > 1024)
4997             return META_E_BAD_SIGNATURE;
4998
4999         // Walk to the parameter referenced.
5000         while (genParam--)
5001             IfFailRet(generics.SkipExactlyOne());
5002
5003         // Now recurse with "generics" at the location to continue parsing.
5004         return EnsureReturnValueAllowedWorker(currentInstantiation, targetClass, generics, methodGenerics, genCount);
5005     }
5006     
5007     
5008     if (returnType == ELEMENT_TYPE_VAR)
5009     {
5010         // Get which type parameter is reference.
5011         ULONG typeParam = 0;
5012         parser.GetData(&typeParam);
5013
5014         // Ensure something reasonable.
5015         if (typeParam > 1024)
5016             return META_E_BAD_SIGNATURE;
5017
5018         // Lookup the containing class's signature so we can get the referenced generic parameter.
5019         IMetaDataImport *pImport = m_pFunction->GetModule()->GetMetaDataImporter();
5020         PCCOR_SIGNATURE sig;
5021         ULONG countSig;
5022         IfFailRet(pImport->GetTypeSpecFromToken(targetClass, &sig, &countSig));
5023
5024         // Enusre the type's typespec is GENERICINST.
5025         SigParser typeParser(sig, countSig);
5026         CorElementType et;
5027         IfFailRet(typeParser.GetElemType(&et));
5028         if (et != ELEMENT_TYPE_GENERICINST)
5029             return META_E_BAD_SIGNATURE;
5030
5031         // Move to the correct location.
5032         IfFailRet(typeParser.GetElemType(&et));
5033         if (et != ELEMENT_TYPE_VALUETYPE && et != ELEMENT_TYPE_CLASS)
5034             return META_E_BAD_SIGNATURE;
5035         
5036         IfFailRet(typeParser.GetToken(NULL));
5037
5038         ULONG totalTypeCount = 0;
5039         IfFailRet(typeParser.GetData(&totalTypeCount));
5040         if (totalTypeCount < typeParam)
5041             return META_E_BAD_SIGNATURE;
5042
5043         while (typeParam--)
5044             IfFailRet(typeParser.SkipExactlyOne());
5045         
5046         // This is a temporary workaround for an infinite recursion here.  ALL of this code will
5047         // go away when we allow struct return values, but in the mean time this avoids a corner
5048         // case in the type system we haven't solved yet.
5049         IfFailRet(typeParser.PeekElemType(&et));
5050         if (et == ELEMENT_TYPE_VAR)
5051             return E_FAIL;
5052
5053         // Now that typeParser is at the location of the correct generic parameter, recurse.
5054         return EnsureReturnValueAllowedWorker(currentInstantiation, targetClass, typeParser, methodGenerics, genCount);
5055     }
5056
5057     // Everything else supported
5058     return S_OK;
5059 }
5060
5061 HRESULT CordbNativeCode::SkipToReturn(SigParser &parser, ULONG *genCount)
5062 {
5063     // Takes a method signature parser (at the beginning of a signature) and skips to the
5064     // return value.
5065     HRESULT hr = S_OK;
5066     
5067     // Skip calling convention
5068     ULONG uCallConv;
5069     IfFailRet(parser.GetCallingConvInfo(&uCallConv));
5070     if ((uCallConv == IMAGE_CEE_CS_CALLCONV_FIELD) || (uCallConv == IMAGE_CEE_CS_CALLCONV_LOCAL_SIG))
5071         return META_E_BAD_SIGNATURE;
5072
5073     // Skip type parameter count if function is generic
5074     if (uCallConv & IMAGE_CEE_CS_CALLCONV_GENERIC)
5075         IfFailRet(parser.GetData(genCount));
5076
5077     // Skip argument count
5078     IfFailRet(parser.GetData(NULL));
5079
5080     return S_OK;
5081 }
5082
5083 HRESULT CordbNativeCode::GetCallSignature(ULONG32 ILoffset, mdToken *pClass, mdToken *pFunction, SigParser &parser, SigParser &generics)
5084 {
5085     // check if specified IL offset is at a call instruction
5086     CordbILCode *pCode = this->m_pFunction->GetILCode();
5087     BYTE buffer[3];
5088     ULONG32 fetched = 0;
5089     HRESULT hr = pCode->GetCode(ILoffset, ILoffset+_countof(buffer), _countof(buffer), buffer, &fetched);
5090
5091     if (FAILED(hr))
5092         return hr;
5093     else if (fetched != _countof(buffer))
5094         return CORDBG_E_INVALID_OPCODE;
5095
5096     // tail.    - fe 14 (ECMA III.2.4)
5097     BYTE instruction = buffer[0];
5098     if (buffer[0] == 0xfe && buffer[1] == 0x14)
5099     {
5100         // tail call case.  We don't allow managed return values for tailcalls.
5101         return CORDBG_E_INVALID_OPCODE;
5102     }
5103     
5104     // call     - 28    (ECMA III.3.19)
5105     // callvirt - 6f    (ECMA III.4.2)
5106     if (instruction != 0x28 && instruction != 0x6f)
5107         return CORDBG_E_INVALID_OPCODE;
5108
5109     // Now grab the MD token of the call
5110     mdToken mdFunction = 0;
5111     const ULONG32 offset = ILoffset + 1;
5112     hr = pCode->GetCode(offset, offset+sizeof(mdToken), sizeof(mdToken), (BYTE*)&mdFunction, &fetched);
5113     if (FAILED(hr) || fetched != sizeof(mdToken))
5114         return CORDBG_E_INVALID_OPCODE;
5115
5116     if (pFunction)
5117         *pFunction = mdFunction;
5118
5119     // Convert to a signature parser
5120     return GetSigParserFromFunction(mdFunction, pClass, parser, generics);
5121 }
5122
5123 HRESULT CordbNativeCode::GetReturnValueLiveOffsetImpl(Instantiation *currentInstantiation, ULONG32 ILoffset, ULONG32 bufferSize, ULONG32 *pFetched, ULONG32 *pOffsets)
5124 {
5125     if (pFetched == NULL)
5126         return E_INVALIDARG;
5127         
5128     HRESULT hr = S_OK;
5129     ULONG32 found = 0;
5130     
5131     // verify that the call target actually returns something we allow
5132     SigParser signature, generics;
5133     mdToken mdClass = 0;
5134     IfFailRet(GetCallSignature(ILoffset, &mdClass, NULL, signature, generics));
5135     IfFailRet(EnsureReturnValueAllowed(currentInstantiation, mdClass, signature, generics));
5136
5137     // now find the native offset
5138     SequencePoints *pSP = GetSequencePoints();
5139     DebuggerILToNativeMap *pMap = pSP->GetCallsiteMapAddr();
5140
5141     for (ULONG32 i = 0; i < pSP->GetCallsiteEntryCount() && pMap; ++i, pMap++)
5142     {
5143         if (pMap->ilOffset == ILoffset && (pMap->source & ICorDebugInfo::CALL_INSTRUCTION) == ICorDebugInfo::CALL_INSTRUCTION)
5144         {
5145             // if we have a buffer, fill it in.
5146             if (pOffsets && found < bufferSize)
5147             {
5148                 // Fetch the actual assembly instructions
5149                 BYTE nativeBuffer[8];
5150
5151                 ULONG32 fetched = 0;
5152                 IfFailRet(GetCode(pMap->nativeStartOffset, pMap->nativeStartOffset+_countof(nativeBuffer), _countof(nativeBuffer), nativeBuffer, &fetched));
5153
5154                 int skipBytes = 0;
5155
5156 #if defined(DBG_TARGET_X86) && defined(FEATURE_CORESYSTEM)
5157                 // Skip nop sleds on x86 coresystem.  The JIT adds these instructions as a security measure,
5158                 // and incorrectly reports to us the wrong offset of the call instruction.
5159                 const BYTE nop_opcode = 0x90;
5160                 while (fetched && nativeBuffer[0] == nop_opcode)
5161                 {
5162                     skipBytes++;
5163
5164                     for (int j = 1; j < _countof(nativeBuffer) && nativeBuffer[j] == nop_opcode; ++j)
5165                         skipBytes++;
5166
5167                     // We must have at least one skip byte since the outer while ensures it.  Thus we always need to reread
5168                     // the buffer at the end of this loop.
5169                     IfFailRet(GetCode(pMap->nativeStartOffset+skipBytes, pMap->nativeStartOffset+skipBytes+_countof(nativeBuffer), _countof(nativeBuffer), nativeBuffer, &fetched));
5170                 }
5171 #endif
5172
5173                 // Get the length of the call instruction.
5174                 int offset = GetCallInstructionLength(nativeBuffer, fetched);
5175                 if (offset == -1)
5176                     return E_UNEXPECTED; // Could not decode instruction, this should never happen.
5177
5178                 pOffsets[found] = pMap->nativeStartOffset + offset + skipBytes;
5179             }
5180
5181             found++;
5182         }
5183     }
5184
5185     if (pOffsets)
5186         *pFetched = found < bufferSize ? found : bufferSize;
5187     else
5188         *pFetched = found;
5189
5190     if (found == 0)
5191         return E_FAIL;
5192
5193     if (pOffsets && found > bufferSize)
5194         return S_FALSE;
5195     
5196     return S_OK;
5197 }
5198
5199 //-----------------------------------------------------------------------------
5200 // Creates a CordbNativeCode (if it's not already created) and adds it to the
5201 // hash table of CordbNativeCode instances belonging to this module.
5202 // Used by CordbFunction::InitNativeCodeInfo.
5203 //
5204 // Arguments:
5205 //    Input:
5206 //       methodToken - the methodDef token of the function this native code belongs to
5207 //       methodDesc - the methodDesc for the jitted method
5208 //       startAddress - the hot code startAddress for this method
5209
5210 // Return value: 
5211 //      found or created CordbNativeCode pointer
5212 // Assumptions: methodToken is in the metadata for this module
5213 //              methodDesc and startAddress should be consistent for
5214 //              a jitted instance of methodToken's method
5215 //-----------------------------------------------------------------------------
5216 CordbNativeCode * CordbModule::LookupOrCreateNativeCode(mdMethodDef methodToken,
5217                                                         VMPTR_MethodDesc methodDesc,
5218                                                         CORDB_ADDRESS startAddress)
5219 {
5220     INTERNAL_SYNC_API_ENTRY(GetProcess());
5221     _ASSERTE(startAddress != NULL);
5222     _ASSERTE(methodDesc != VMPTR_MethodDesc::NullPtr());
5223
5224     CordbNativeCode * pNativeCode = NULL;
5225     NativeCodeFunctionData codeInfo;
5226     RSLockHolder lockHolder(GetProcess()->GetProcessLock());
5227
5228     // see if we already have this--if not, we'll make an instance, otherwise we'll just return the one we have. 
5229     pNativeCode = m_nativeCodeTable.GetBase((UINT_PTR) startAddress);
5230
5231     if (pNativeCode == NULL)
5232     {
5233         GetProcess()->GetDAC()->GetNativeCodeInfoForAddr(methodDesc, startAddress, &codeInfo);
5234
5235         // We didn't have an instance, so we'll build one and add it to the hash table
5236         LOG((LF_CORDB,
5237              LL_INFO10000,
5238              "R:CT::RSCreating code w/ ver:0x%x, md:0x%x, nativeStart=0x%08x, nativeSize=0x%08x\n",
5239              codeInfo.encVersion,
5240              VmPtrToCookie(codeInfo.vmNativeCodeMethodDescToken),
5241              codeInfo.m_rgCodeRegions[kHot].pAddress,
5242              codeInfo.m_rgCodeRegions[kHot].cbSize));
5243
5244         // Lookup the function object that this code should be bound to
5245         CordbFunction* pFunction = CordbModule::LookupOrCreateFunction(methodToken, codeInfo.encVersion);
5246         _ASSERTE(pFunction != NULL);
5247
5248         // There are bugs with the on-demand class load performed by CordbFunction in some cases. The old stack
5249         // tracing code avoided them by eagerly loading the parent class so I am following suit
5250         pFunction->InitParentClassOfFunction();
5251
5252         // First, create a new CordbNativeCode instance--we'll need this to make the CordbJITInfo instance
5253         pNativeCode = new (nothrow)CordbNativeCode(pFunction, &codeInfo, codeInfo.isInstantiatedGeneric != 0);
5254         _ASSERTE(pNativeCode != NULL);
5255
5256         m_nativeCodeTable.AddBaseOrThrow(pNativeCode);
5257     }
5258
5259     return pNativeCode;
5260 } // CordbNativeCode::LookupOrCreateFromJITData
5261
5262 // LoadNativeInfo loads from the left side any native variable info
5263 // from the JIT.
5264 //
5265 void CordbNativeCode::LoadNativeInfo()
5266 {
5267     THROW_IF_NEUTERED(this);
5268     INTERNAL_API_ENTRY(this->GetProcess()); 
5269
5270
5271     // If we've either never done this before (no info), or we have, but the version number has increased, we
5272     // should try and get a newer version of our JIT info.
5273     if(m_nativeVarData.IsInitialized())
5274     {
5275         return;
5276     }
5277
5278     // You can't do this if the function is implemented as part of the Runtime.
5279     if (GetFunction()->IsNativeImpl() == CordbFunction::kNativeOnly)
5280     {
5281         ThrowHR(CORDBG_E_FUNCTION_NOT_IL);
5282     }
5283      CordbProcess *pProcess = GetProcess();
5284     // Get everything via the DAC
5285     if (m_fCodeAvailable)
5286     {
5287         RSLockHolder lockHolder(pProcess->GetProcessLock());
5288         pProcess->GetDAC()->GetNativeCodeSequencePointsAndVarInfo(GetVMNativeCodeMethodDescToken(),
5289                                                                   GetAddress(),
5290                                                                   m_fCodeAvailable, 
5291                                                                   &m_nativeVarData,
5292                                                                   &m_sequencePoints);
5293     }
5294
5295 } // CordbNativeCode::LoadNativeInfo
5296
5297
5298