Implement out of context stack unwinder (#13302)
[platform/upstream/coreclr.git] / src / debug / daccess / dacfn.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 // File: dacfn.cpp
6 // 
7
8 //
9 // Dac function implementations.
10 //
11 //*****************************************************************************
12
13 #include "stdafx.h"
14
15 #include <encee.h>
16 #ifdef FEATURE_PREJIT
17 #include "compile.h"
18 #endif // FEATURE_PREJIT
19 #include <virtualcallstub.h>
20 #include "peimagelayout.inl"
21
22 #include "gcinterface.h"
23 #include "gcinterface.dac.h"
24
25
26 DacTableInfo g_dacTableInfo;
27 DacGlobals g_dacGlobals;
28
29 struct DacHostVtPtrs
30 {
31 #define VPTR_CLASS(name) PVOID name;
32 #define VPTR_MULTI_CLASS(name, keyBase) PVOID name##__##keyBase;
33 #include <vptr_list.h>
34 #undef VPTR_CLASS
35 #undef VPTR_MULTI_CLASS
36 };
37
38
39 const WCHAR *g_dacVtStrings[] =
40 {
41 #define VPTR_CLASS(name) W(#name),
42 #define VPTR_MULTI_CLASS(name, keyBase) W(#name),
43 #include <vptr_list.h>
44 #undef VPTR_CLASS
45 #undef VPTR_MULTI_CLASS
46 };
47
48 DacHostVtPtrs g_dacHostVtPtrs;
49
50 HRESULT
51 DacGetHostVtPtrs(void)
52 {
53 #define VPTR_CLASS(name) \
54     g_dacHostVtPtrs.name = name::VPtrHostVTable();
55 #define VPTR_MULTI_CLASS(name, keyBase) \
56     g_dacHostVtPtrs.name##__##keyBase = name::VPtrHostVTable();
57 #include <vptr_list.h>
58 #undef VPTR_CLASS
59 #undef VPTR_MULTI_CLASS
60
61     return S_OK;
62 }
63
64 bool
65 DacExceptionFilter(Exception* ex, ClrDataAccess* access,
66                    HRESULT* status)
67 {
68     SUPPORTS_DAC_HOST_ONLY;
69
70     // The DAC support functions throw HRExceptions and
71     // the underlying code can throw the normal set of
72     // CLR exceptions.  Handle any exception
73     // other than an unexpected SEH exception.
74     // If we're not debugging, handle SEH exceptions also
75     // so that dac absorbs all exceptions by default.
76     if ((access && access->m_debugMode) &&
77         ex->IsType(SEHException::GetType()))
78     {
79         // Indicate this exception should be rethrown.
80         return FALSE;
81     }
82
83     // Indicate this exception is handled.
84     // XXX Microsoft - The C++-based EH has broken the ability
85     // to get proper SEH results.  Make sure that the
86     // error returned is actually an error code as
87     // often it's just zero.
88     *status = ex->GetHR();
89     if (!FAILED(*status))
90     {
91         *status = E_FAIL;
92     }
93     return TRUE;
94 }
95
96 void __cdecl
97 DacWarning(__in char* format, ...)
98 {
99     char text[256];
100     va_list args;
101
102     va_start(args, format);
103     _vsnprintf_s(text, sizeof(text), _TRUNCATE, format, args);
104     text[sizeof(text) - 1] = 0;
105     va_end(args);
106     OutputDebugStringA(text);
107 }
108
109 void
110 DacNotImpl(void)
111 {
112     EX_THROW(HRException, (E_NOTIMPL));
113 }
114
115 void
116 DacError(HRESULT err)
117 {
118     EX_THROW(HRException, (err));
119 }
120
121 // Ideally DacNoImpl and DacError would be marked no-return, but that will require changing a bunch of existing
122 // code to avoid "unreachable code" warnings. 
123 void DECLSPEC_NORETURN
124 DacError_NoRet(HRESULT err)
125 {
126     EX_THROW(HRException, (err));
127 }
128
129 TADDR
130 DacGlobalBase(void)
131 {
132     if (!g_dacImpl)
133     {
134         DacError(E_UNEXPECTED);
135         UNREACHABLE();
136     }
137
138     return g_dacImpl->m_globalBase;
139 }
140
141 HRESULT
142 DacReadAll(TADDR addr, PVOID buffer, ULONG32 size, bool throwEx)
143 {
144     if (!g_dacImpl)
145     {
146         DacError(E_UNEXPECTED);
147         UNREACHABLE();
148     }
149
150     ClrSafeInt<TADDR> end = ClrSafeInt<TADDR>(addr) + ClrSafeInt<TADDR>(size);
151     if( end.IsOverflow() )
152     {
153         // Overflow - corrupt data
154         DacError(CORDBG_E_TARGET_INCONSISTENT);
155     }
156
157     HRESULT status;
158     ULONG32 returned;
159
160 #if defined(DAC_MEASURE_PERF)
161     unsigned __int64  nStart, nEnd;
162     nStart = GetCycleCount();
163 #endif // #if defined(DAC_MEASURE_PERF)
164     
165     status = g_dacImpl->m_pTarget->
166         ReadVirtual(addr, (PBYTE)buffer, size, &returned);
167
168 #if defined(DAC_MEASURE_PERF)
169     nEnd = GetCycleCount();
170     g_nReadVirtualTotalTime += nEnd - nStart;
171 #endif // #if defined(DAC_MEASURE_PERF)
172     
173     if (status != S_OK)
174     {
175         // Regardless of what status is, it's very important for dump debugging to
176         // always return CORDBG_E_READVIRTUAL_FAILURE.
177         if (throwEx)
178         {
179             DacError(CORDBG_E_READVIRTUAL_FAILURE);
180         }
181         return CORDBG_E_READVIRTUAL_FAILURE;
182     }
183     if (returned != size)
184     {
185         if (throwEx)
186         {
187             DacError(HRESULT_FROM_WIN32(ERROR_PARTIAL_COPY));
188         }
189         return HRESULT_FROM_WIN32(ERROR_PARTIAL_COPY);
190     }
191
192     return S_OK;
193 }
194
195 HRESULT
196 DacWriteAll(TADDR addr, PVOID buffer, ULONG32 size, bool throwEx)
197 {
198     if (!g_dacImpl)
199     {
200         DacError(E_UNEXPECTED);
201         UNREACHABLE();
202     }
203
204     HRESULT status;
205
206     status = g_dacImpl->m_pMutableTarget->WriteVirtual(addr, (PBYTE)buffer, size);
207     if (status != S_OK)
208     {
209         if (throwEx)
210         {
211             DacError(status);
212         }
213         return status;
214     }
215
216     return S_OK;
217 }
218
219 #ifdef FEATURE_PAL
220
221 static BOOL DacReadAllAdapter(PVOID address, PVOID buffer, SIZE_T size)
222 {
223     HRESULT hr = DacReadAll((TADDR)address, (PVOID)buffer, size, false);
224     return SUCCEEDED(hr);
225 }
226
227 HRESULT 
228 DacVirtualUnwind(DWORD threadId, PT_CONTEXT context, PT_KNONVOLATILE_CONTEXT_POINTERS contextPointers)
229 {
230     if (!g_dacImpl)
231     {
232         DacError(E_UNEXPECTED);
233         UNREACHABLE();
234     }
235
236     // The DAC code doesn't use these context pointers but zero them out to be safe.
237     if (contextPointers != NULL)
238     {
239         memset(contextPointers, 0, sizeof(T_KNONVOLATILE_CONTEXT_POINTERS));
240     }
241
242     HRESULT hr = S_OK;
243
244 #ifdef FEATURE_DATATARGET4
245     ReleaseHolder<ICorDebugDataTarget4> dt;
246     hr = g_dacImpl->m_pTarget->QueryInterface(IID_ICorDebugDataTarget4, (void **)&dt);
247     if (SUCCEEDED(hr))
248     {
249         hr = dt->VirtualUnwind(threadId, sizeof(CONTEXT), (BYTE*)context);
250     }
251     else 
252 #endif
253     {
254         SIZE_T baseAddress = DacGlobalBase();
255         if (baseAddress == 0 || !PAL_VirtualUnwindOutOfProc(context, contextPointers, baseAddress, DacReadAllAdapter))
256         {
257             hr = E_FAIL;
258         }
259     }
260
261     return hr;
262 }
263
264 #endif // FEATURE_PAL
265
266 // DacAllocVirtual - Allocate memory from the target process
267 // Note: this is only available to clients supporting the legacy
268 // ICLRDataTarget2 interface.  It's currently used by SOS for notification tables.
269 HRESULT
270 DacAllocVirtual(TADDR addr, ULONG32 size,
271                 ULONG32 typeFlags, ULONG32 protectFlags,
272                 bool throwEx, TADDR* mem)
273 {
274     if (!g_dacImpl)
275     {
276         DacError(E_UNEXPECTED);
277         UNREACHABLE();
278     }
279
280     ICLRDataTarget2 * pTarget2 = g_dacImpl->GetLegacyTarget2();
281     if (pTarget2 == NULL)
282     {
283         DacError(E_NOTIMPL);
284         UNREACHABLE();
285     }
286
287     CLRDATA_ADDRESS cdaMem;
288     HRESULT status = pTarget2->AllocVirtual(
289         TO_CDADDR(addr), size, typeFlags, protectFlags, &cdaMem);
290     if (status != S_OK)
291     {
292         if (throwEx)
293         {
294             DacError(status);
295             UNREACHABLE();
296         }
297
298         return status;
299     }
300
301     *mem = CLRDATA_ADDRESS_TO_TADDR(cdaMem);
302     return S_OK;
303 }
304
305 // DacFreeVirtual - Free memory from the target process
306 // Note: this is only available to clients supporting the legacy
307 // ICLRDataTarget2 interface.  This is not currently used.
308 HRESULT
309 DacFreeVirtual(TADDR mem, ULONG32 size, ULONG32 typeFlags,
310                bool throwEx)
311 {
312     if (!g_dacImpl)
313     {
314         DacError(E_UNEXPECTED);
315         UNREACHABLE();
316     }
317
318     ICLRDataTarget2 * pTarget2 = g_dacImpl->GetLegacyTarget2();
319     if (pTarget2 == NULL)
320     {
321         DacError(E_NOTIMPL);
322         UNREACHABLE();
323     }
324
325     HRESULT status = pTarget2->FreeVirtual(
326         TO_CDADDR(mem), size, typeFlags);
327
328     if (status != S_OK && throwEx)
329     {
330         DacError(status);
331         UNREACHABLE();
332     }
333
334     return status;
335 }
336
337 PVOID
338 DacInstantiateTypeByAddressHelper(TADDR addr, ULONG32 size, bool throwEx, bool fReport)
339 {
340 #ifdef _PREFIX_
341
342     // Dac accesses are not interesting for PREfix and cause alot of PREfix noise
343     // so we just return the unmodified pointer for our PREFIX builds
344     return (PVOID)addr;
345
346 #else // !_PREFIX_
347
348     if (!g_dacImpl)
349     {
350         DacError(E_UNEXPECTED);
351         UNREACHABLE();
352     }
353
354     // Preserve special pointer values.
355     if (!addr || addr == (TADDR)-1)
356     {
357         return (PVOID)addr;
358     }
359
360     // DacInstanceManager::Alloc will assert (with a non-obvious message) on 0-size instances. 
361     // Fail sooner and more obviously here.
362     _ASSERTE_MSG( size > 0, "DAC coding error: instance size cannot be 0" );
363     
364     // Do not attempt to allocate more than 64megs for one object instance.  While we should
365     // never even come close to this size, in cases of heap corruption or bogus data passed
366     // into the dac, we can allocate huge amounts of data if we are unlucky.  This santiy
367     // checks the size to ensure we don't allocate gigs of data.
368     if (size > 0x4000000)
369     {
370         if (throwEx)
371         {
372             DacError(E_OUTOFMEMORY);
373         }
374         return NULL;
375     }
376
377     //
378     // Check the cache for an existing DPTR instance.
379     // It's possible that a previous access may have been
380     // smaller than the current access, so we have to
381     // allow an existing instance to be superseded.
382     //
383
384     DAC_INSTANCE* inst = g_dacImpl->m_instances.Find(addr);
385     DAC_INSTANCE* oldInst = NULL;
386     if (inst)
387     {
388         // If the existing instance is large enough we
389         // can reuse it, otherwise we need to promote.
390         // We cannot promote a VPTR as the VPTR data
391         // has been updated with a host vtable and we
392         // don't want to lose that.  This shouldn't
393         // happen anyway.
394         if (inst->size >= size)
395         {
396             return inst + 1;
397         }
398         else
399         {
400             // Existing instance is too small and must
401             // be superseded.
402             if (inst->usage == DAC_VPTR)
403             {
404                 // The same address has already been marshalled as a VPTR, now we're trying to marshal as a 
405                 // DPTR.  This is not allowed.
406                 _ASSERTE_MSG(false, "DAC coding error: DPTR/VPTR usage conflict");
407                 DacError(E_INVALIDARG);
408                 UNREACHABLE();
409             }
410
411             // Promote the larger instance into the hash
412             // in place of the smaller, but keep the
413             // smaller instance around in case code still
414             // has a pointer to it. But ensure that we can
415             // create the larger instance and add it to the
416             // hash table before removing the old one.
417             oldInst = inst;
418         }
419     }
420
421     inst = g_dacImpl->m_instances.Alloc(addr, size, DAC_DPTR);
422     if (!inst)
423     {
424         DacError(E_OUTOFMEMORY);
425         UNREACHABLE();
426     }
427
428     if (fReport == false)
429     {
430         // mark the bit if necessary
431         inst->noReport = 1;
432     }
433     else
434     {
435         // clear the bit
436         inst->noReport = 0;
437     }
438     HRESULT status = DacReadAll(addr, inst + 1, size, false);
439     if (status != S_OK)
440     {
441         g_dacImpl->m_instances.ReturnAlloc(inst);
442         if (throwEx)
443         {
444             DacError(status);
445         }
446         return NULL;
447     }
448
449     if (!g_dacImpl->m_instances.Add(inst))
450     {
451         g_dacImpl->m_instances.ReturnAlloc(inst);
452         DacError(E_OUTOFMEMORY);
453         UNREACHABLE();        
454     }
455
456     if (oldInst)
457     {
458         g_dacImpl->m_instances.Supersede(oldInst);
459     }
460
461     return inst + 1;
462
463 #endif // !_PREFIX_
464 }
465
466 PVOID   DacInstantiateTypeByAddress(TADDR addr, ULONG32 size, bool throwEx)
467 {
468     return DacInstantiateTypeByAddressHelper(addr, size, throwEx, true);
469 }
470
471 PVOID   DacInstantiateTypeByAddressNoReport(TADDR addr, ULONG32 size, bool throwEx)
472 {
473     return DacInstantiateTypeByAddressHelper(addr, size, throwEx, false);
474 }
475
476
477 PVOID
478 DacInstantiateClassByVTable(TADDR addr, ULONG32 minSize, bool throwEx)
479 {
480 #ifdef _PREFIX_
481
482     // Dac accesses are not interesting for PREfix and cause alot of PREfix noise
483     // so we just return the unmodified pointer for our PREFIX builds
484     return (PVOID)addr;
485
486 #else // !_PREFIX_
487
488     if (!g_dacImpl)
489     {
490         DacError(E_UNEXPECTED);
491         UNREACHABLE();
492     }
493
494     // Preserve special pointer values.
495     if (!addr || addr == (TADDR)-1)
496     {
497         return (PVOID)addr;
498     }
499     
500     // Do not attempt to allocate more than 64megs for one object instance.  While we should
501     // never even come close to this size, in cases of heap corruption or bogus data passed
502     // into the dac, we can allocate huge amounts of data if we are unlucky.  This santiy
503     // checks the size to ensure we don't allocate gigs of data.
504     if (minSize > 0x4000000)
505     {
506         if (throwEx)
507         {
508             DacError(E_OUTOFMEMORY);
509         }
510         return NULL;
511     }
512
513     //
514     // Check the cache for an existing VPTR instance.
515     // If there is an instance we assume that it's
516     // the right object.
517     //
518
519     DAC_INSTANCE* inst = g_dacImpl->m_instances.Find(addr);
520     DAC_INSTANCE* oldInst = NULL;
521     if (inst)
522     {
523         // If the existing instance is a VPTR we can
524         // reuse it, otherwise we need to promote.
525         if (inst->usage == DAC_VPTR)
526         {
527             // Sanity check that the object we're returning is big enough to fill the PTR type it's being
528             // accessed with.  For more information, see the similar check below for the case when the 
529             // object isn't already cached
530             _ASSERTE_MSG(inst->size >= minSize, "DAC coding error: Attempt to instantiate a VPTR from an object that is too small");
531
532             return inst + 1;
533         }
534         else
535         {
536             // Existing instance is not a match and must
537             // be superseded.
538             // Promote the new instance into the hash
539             // in place of the old, but keep the
540             // old instance around in case code still
541             // has a pointer to it. But ensure that we can
542             // create the larger instance and add it to the
543             // hash table before removing the old one.
544             oldInst = inst;
545         }
546     }
547
548     HRESULT status;
549     TADDR vtAddr;
550     ULONG32 size;
551     PVOID hostVtPtr;
552
553     // Read the vtable pointer to get the actual
554     // implementation class identity.
555     if ((status = DacReadAll(addr, &vtAddr, sizeof(vtAddr), throwEx)) != S_OK)
556     {
557         return NULL;
558     }
559
560     //
561     // Instantiate the right class, using the vtable as
562     // class identity.
563     //
564
565 #define VPTR_CLASS(name)                       \
566     if (vtAddr == g_dacImpl->m_globalBase +    \
567         g_dacGlobals.name##__vtAddr)           \
568     {                                          \
569         size = sizeof(name);                   \
570         hostVtPtr = g_dacHostVtPtrs.name;      \
571     }                                          \
572     else
573 #define VPTR_MULTI_CLASS(name, keyBase)        \
574     if (vtAddr == g_dacImpl->m_globalBase +    \
575         g_dacGlobals.name##__##keyBase##__mvtAddr) \
576     {                                          \
577         size = sizeof(name);                   \
578         hostVtPtr = g_dacHostVtPtrs.name##__##keyBase; \
579     }                                          \
580     else
581 #include <vptr_list.h>
582 #undef VPTR_CLASS
583 #undef VPTR_MULTI_CLASS
584
585     {
586         // Can't identify the vtable pointer.
587         if (throwEx)
588         {
589             _ASSERTE_MSG(false,"DAC coding error: Unrecognized vtable pointer in VPTR marshalling code");
590             DacError(E_INVALIDARG);
591         }
592         return NULL;
593     }
594
595     // Sanity check that the object we're returning is big enough to fill the PTR type it's being
596     // accessed with.
597     // If this is not true, it means the type being marshalled isn't a sub-type (or the same type)
598     // as the PTR type it's being used as.  For example, trying to marshal an instance of a SystemDomain 
599     // object into a PTR_AppDomain will cause this ASSERT to fire (because both SystemDomain and AppDomain
600     // derived from BaseDomain, and SystemDomain is smaller than AppDomain).
601     _ASSERTE_MSG(size >= minSize, "DAC coding error: Attempt to instantiate a VPTR from an object that is too small");
602
603     inst = g_dacImpl->m_instances.Alloc(addr, size, DAC_VPTR);
604     if (!inst)
605     {
606         DacError(E_OUTOFMEMORY);
607         UNREACHABLE();
608     }
609
610     // Copy the object contents into the host instance.  Note that this assumes the host and target
611     // have the same exact layout.  Specifically, it assumes the host and target vtable pointers are
612     // the same size.
613     if ((status = DacReadAll(addr, inst + 1, size, false)) != S_OK)
614     {
615         g_dacImpl->m_instances.ReturnAlloc(inst);
616         if (throwEx)
617         {
618             DacError(status);
619         }
620         return NULL;
621     }
622
623     // We now have a proper target object with a target
624     // vtable.  We need to patch the vtable to the appropriate
625     // host vtable so that the virtual functions can be
626     // called in the host process.
627     *(PVOID*)(inst + 1) = hostVtPtr;
628
629     if (!g_dacImpl->m_instances.Add(inst))
630     {
631         g_dacImpl->m_instances.ReturnAlloc(inst);
632         DacError(E_OUTOFMEMORY);
633         UNREACHABLE();        
634     }
635
636     if (oldInst)
637     {
638         g_dacImpl->m_instances.Supersede(oldInst);
639     }
640     return inst + 1;
641
642 #endif // !_PREFIX_
643 }
644
645 #define LOCAL_STR_BUF 256
646
647 PSTR
648 DacInstantiateStringA(TADDR addr, ULONG32 maxChars, bool throwEx)
649 {
650 #ifdef _PREFIX_
651
652     // Dac accesses are not interesting for PREfix and cause alot of PREfix noise
653     // so we just return the unmodified pointer for our PREFIX builds
654     return (PSTR)addr;
655
656 #else // !_PREFIX_
657
658     HRESULT status;
659
660     if (!g_dacImpl)
661     {
662         DacError(E_UNEXPECTED);
663         UNREACHABLE();
664     }
665
666     // Preserve special pointer values.
667     if (!addr || addr == (TADDR)-1)
668     {
669         return (PSTR)addr;
670     }
671     
672     
673     // Do not attempt to allocate more than 64megs for a string.  While we should
674     // never even come close to this size, in cases of heap corruption or bogus data passed
675     // into the dac, we can allocate huge amounts of data if we are unlucky.  This santiy
676     // checks the size to ensure we don't allocate gigs of data.
677     if (maxChars > 0x4000000)
678     {
679         if (throwEx)
680         {
681             DacError(E_OUTOFMEMORY);
682         }
683         return NULL;
684     }
685
686     //
687     // Look for an existing string instance.
688     //
689
690     DAC_INSTANCE* inst = g_dacImpl->m_instances.Find(addr);
691     if (inst && inst->usage == DAC_STRA)
692     {
693         return (PSTR)(inst + 1);
694     }
695
696     //
697     // Determine the length of the string
698     // by iteratively reading blocks and scanning them
699     // for a terminator.
700     //
701
702     char buf[LOCAL_STR_BUF];
703     TADDR scanAddr = addr;
704     ULONG32 curBytes = 0;
705     ULONG32 returned;
706
707     for (;;)
708     {
709         status = g_dacImpl->m_pTarget->
710             ReadVirtual(scanAddr, (PBYTE)buf, sizeof(buf),
711                         &returned);
712         if (status != S_OK)
713         {
714             // We hit invalid memory before finding a terminator.
715             if (throwEx)
716             {
717                 DacError(CORDBG_E_READVIRTUAL_FAILURE);
718             }
719             return NULL;
720         }
721
722         PSTR scan = (PSTR)buf;
723         PSTR scanEnd = scan + (returned / sizeof(*scan));
724         while (scan < scanEnd)
725         {
726             if (!*scan)
727             {
728                 break;
729             }
730
731             scan++;
732         }
733
734         if (!*scan)
735         {
736             // Found a terminator.
737             scanAddr += ((scan + 1) - buf) * sizeof(*scan);
738             break;
739         }
740
741         // Ignore any partial character reads.  The character
742         // will be reread on the next loop if necessary.
743         returned &= ~(sizeof(buf[0]) - 1);
744
745         // The assumption is that a memory read cannot wrap
746         // around the address space, thus if we have read to
747         // the top of memory scanAddr cannot wrap farther
748         // than to zero.
749         curBytes += returned;
750         scanAddr += returned;
751
752         if (!scanAddr ||
753             (curBytes + sizeof(buf[0]) - 1) / sizeof(buf[0]) >= maxChars)
754         {
755             // Wrapped around the top of memory or
756             // we didn't find a terminator within the given bound.
757             if (throwEx)
758             {
759                 DacError(E_INVALIDARG);
760             }
761             return NULL;
762         }
763     }
764
765     // Now that we know the length we can create a
766     // host copy of the string.
767     PSTR retVal = (PSTR)
768         DacInstantiateTypeByAddress(addr, (ULONG32)(scanAddr - addr), throwEx);
769     if (retVal &&
770         (inst = g_dacImpl->m_instances.Find(addr)))
771     {
772         inst->usage = DAC_STRA;
773     }
774     return retVal;
775
776 #endif // !_PREFIX_
777 }
778
779 PWSTR
780 DacInstantiateStringW(TADDR addr, ULONG32 maxChars, bool throwEx)
781 {
782 #ifdef _PREFIX_
783
784     // Dac accesses are not interesting for PREfix and cause alot of PREfix noise
785     // so we just return the unmodified pointer for our PREFIX builds
786     return (PWSTR)addr;
787
788 #else // !_PREFIX_
789
790     HRESULT status;
791
792     if (!g_dacImpl)
793     {
794         DacError(E_UNEXPECTED);
795         UNREACHABLE();
796     }
797
798     // Preserve special pointer values.
799     if (!addr || addr == (TADDR)-1)
800     {
801         return (PWSTR)addr;
802     }
803     
804     // Do not attempt to allocate more than 64megs for a string.  While we should
805     // never even come close to this size, in cases of heap corruption or bogus data passed
806     // into the dac, we can allocate huge amounts of data if we are unlucky.  This santiy
807     // checks the size to ensure we don't allocate gigs of data.
808     if (maxChars > 0x4000000)
809     {
810         if (throwEx)
811         {
812             DacError(E_OUTOFMEMORY);
813         }
814         return NULL;
815     }
816
817
818     //
819     // Look for an existing string instance.
820     //
821
822     DAC_INSTANCE* inst = g_dacImpl->m_instances.Find(addr);
823     if (inst && inst->usage == DAC_STRW)
824     {
825         return (PWSTR)(inst + 1);
826     }
827
828     //
829     // Determine the length of the string
830     // by iteratively reading blocks and scanning them
831     // for a terminator.
832     //
833
834     WCHAR buf[LOCAL_STR_BUF];
835     TADDR scanAddr = addr;
836     ULONG32 curBytes = 0;
837     ULONG32 returned;
838
839     for (;;)
840     {
841         status = g_dacImpl->m_pTarget->
842             ReadVirtual(scanAddr, (PBYTE)buf, sizeof(buf),
843                         &returned);
844         if (status != S_OK)
845         {
846             // We hit invalid memory before finding a terminator.
847             if (throwEx)
848             {
849                 DacError(CORDBG_E_READVIRTUAL_FAILURE);
850             }
851             return NULL;
852         }
853
854         PWSTR scan = (PWSTR)buf;
855         PWSTR scanEnd = scan + (returned / sizeof(*scan));
856         while (scan < scanEnd)
857         {
858             if (!*scan)
859             {
860                 break;
861             }
862
863             scan++;
864         }
865
866         if (!*scan)
867         {
868             // Found a terminator.
869             scanAddr += ((scan + 1) - buf) * sizeof(*scan);
870             break;
871         }
872
873         // Ignore any partial character reads.  The character
874         // will be reread on the next loop if necessary.
875         returned &= ~(sizeof(buf[0]) - 1);
876
877         // The assumption is that a memory read cannot wrap
878         // around the address space, thus if we have read to
879         // the top of memory scanAddr cannot wrap farther
880         // than to zero.
881         curBytes += returned;
882         scanAddr += returned;
883
884         if (!scanAddr ||
885             (curBytes + sizeof(buf[0]) - 1) / sizeof(buf[0]) >= maxChars)
886         {
887             // Wrapped around the top of memory or
888             // we didn't find a terminator within the given bound.
889             if (throwEx)
890             {
891                 DacError(E_INVALIDARG);
892             }
893             return NULL;
894         }
895     }
896
897     // Now that we know the length we can create a
898     // host copy of the string.
899     PWSTR retVal = (PWSTR)
900         DacInstantiateTypeByAddress(addr, (ULONG32)(scanAddr - addr), throwEx);
901     if (retVal &&
902         (inst = g_dacImpl->m_instances.Find(addr)))
903     {
904         inst->usage = DAC_STRW;
905     }
906     return retVal;
907
908 #endif // !_PREFIX_
909 }
910
911 TADDR
912 DacGetTargetAddrForHostAddr(LPCVOID ptr, bool throwEx)
913 {
914 #ifdef _PREFIX_
915
916     // Dac accesses are not interesting for PREfix and cause alot of PREfix noise
917     // so we just return the unmodified pointer for our PREFIX builds
918     return (TADDR) ptr;
919
920 #else // !_PREFIX_
921
922     // Preserve special pointer values.
923     if (ptr == NULL || ((TADDR) ptr == (TADDR)-1))
924     {
925         return 0;
926     }
927     else
928     {
929         TADDR addr = 0;
930         HRESULT status = E_FAIL;
931
932         EX_TRY
933         {
934             DAC_INSTANCE* inst = (DAC_INSTANCE*)ptr - 1;
935             if (inst->sig == DAC_INSTANCE_SIG)
936             {
937                 addr = inst->addr;
938                 status = S_OK;
939             }
940             else
941             {
942                 status = E_INVALIDARG;
943             }
944         }
945         EX_CATCH
946         {
947             status = E_INVALIDARG;
948         }
949         EX_END_CATCH(SwallowAllExceptions)
950
951         if (status != S_OK)
952         {
953             if (g_dacImpl && g_dacImpl->m_debugMode)
954             {
955                 DebugBreak();
956             }
957
958             if (throwEx)
959             {
960                 // This means a pointer was supplied which doesn't actually point to the beginning of 
961                 // a marshalled DAC instance.
962                 _ASSERTE_MSG(false, "DAC coding error: Attempt to get target address from a host pointer "
963                                     "which is not an instance marshalled by DAC!");
964                 DacError(status);
965             }
966         }
967
968         return addr;
969     }
970
971 #endif // !_PREFIX_
972 }
973
974 // Similar to DacGetTargetAddrForHostAddr above except that ptr can represent any pointer within a host data
975 // structure marshalled from the target (rather than just a pointer to the first field).
976 TADDR
977 DacGetTargetAddrForHostInteriorAddr(LPCVOID ptr, bool throwEx)
978 {
979     // Our algorithm for locating the containing DAC instance will search backwards through memory in
980     // DAC_INSTANCE_ALIGN increments looking for a valid header. The following constant determines how many of
981     // these iterations we'll perform before deciding the caller made a mistake and didn't marshal the
982     // containing instance from the target to the host properly. Lower values will determine the maximum
983     // offset from the start of a marshalled structure at which an interior pointer can appear. Higher values
984     // will bound the amount of time it takes to report an error in the case where code has been incorrectly
985     // DAC-ized.
986     const DWORD kMaxSearchIterations = 100;
987
988 #ifdef _PREFIX_
989
990     // Dac accesses are not interesting for PREfix and cause alot of PREfix noise
991     // so we just return the unmodified pointer for our PREFIX builds
992     return (TADDR) ptr;
993
994 #else // !_PREFIX_
995
996     // Preserve special pointer values.
997     if (ptr == NULL || ((TADDR) ptr == (TADDR)-1))
998     {
999         return 0;
1000     }
1001     else
1002     {
1003         TADDR addr = 0;
1004         HRESULT status = E_FAIL;
1005
1006         EX_TRY
1007         {
1008             // We're going to search backwards through memory from the pointer looking for a valid DAC
1009             // instance header. Initialize this search pointer to the first legal value it could hold.
1010             // Intuitively this would be ptr - sizeof(DAC_INSTANCE), but DAC_INSTANCE headers are further
1011             // constrained to lie on DAC_INSTANCE_ALIGN boundaries. DAC_INSTANCE_ALIGN is large (16 bytes) due
1012             // to the need to keep the marshalled structure also aligned for any possible need, so we gain
1013             // considerable performance from only needing to test for DAC_INSTANCE headers at
1014             // DAC_INSTANCE_ALIGN aligned addresses.
1015             DAC_INSTANCE * inst = (DAC_INSTANCE*)(((ULONG_PTR)ptr - sizeof(DAC_INSTANCE)) & ~(DAC_INSTANCE_ALIGN - 1));
1016
1017             // When code is DAC'ized correctly then our search algorithm is guaranteed to terminate safely
1018             // before reading memory that doesn't belong to the containing DAC instance. Since people do make
1019             // mistakes we want to limit how long and far we search however. The counter below will let us
1020             // assert if we've likely tried to locate an interior host pointer in a non-marshalled structure.
1021             DWORD cIterations = 0;
1022
1023             bool tryAgain = false;
1024
1025             // Scan backwards in memory looking for a DAC_INSTANCE header.
1026             while (true)
1027             {
1028                 // Step back DAC_INSTANCE_ALIGN bytes at a time (the initialization of inst above guarantees
1029                 // we start with an aligned pointer value. Stop every time our potential DAC_INSTANCE header
1030                 // has a correct signature value.
1031                 while (tryAgain || inst->sig != DAC_INSTANCE_SIG)
1032                 {
1033                     tryAgain = false;
1034                     inst = (DAC_INSTANCE*)((BYTE*)inst - DAC_INSTANCE_ALIGN);
1035
1036                     // If we've searched a lot of memory (currently 100 * 16 == 1600 bytes) without success,
1037                     // then assume this is due to an issue DAC-izing code (if you really do have a field within a
1038                     // DAC marshalled structure whose offset is >1600 bytes then feel free to update the
1039                     // constant at the start of this method).
1040                     if (++cIterations > kMaxSearchIterations)
1041                     {
1042                         status = E_INVALIDARG;
1043                         break;
1044                     }
1045                 }
1046
1047                 // Fall through to a DAC error if we searched too long without finding a header candidate.
1048                 if (status == E_INVALIDARG)
1049                     break;
1050
1051                 // Validate our candidate header by looking up the target address it claims to map in the
1052                 // instance hash. The entry should both exist and correspond exactly to our candidate instance
1053                 // pointer.
1054                 // TODO: but what if the same memory was marshalled more than once (eg. once as a DPTR, once as a VPTR)?
1055                 if (inst == g_dacImpl->m_instances.Find(inst->addr))
1056                 {
1057                     // We've found a valid DAC instance. Now validate that the marshalled structure it
1058                     // represents really does enclose the pointer we're asking about. If not, someone hasn't
1059                     // marshalled a containing structure before trying to map a pointer within that structure
1060                     // (we've just gone and found the previous, unrelated marshalled structure in host memory).
1061                     BYTE * parent = (BYTE*)(inst + 1);
1062                     if (((BYTE*)ptr + sizeof(LPCVOID)) <= (parent + inst->size))
1063                     {
1064                         // Everything checks out: we've found a DAC instance header and its address range
1065                         // encompasses the pointer we're interested in. Compute the corresponding target
1066                         // address by taking into account the offset of the interior pointer into its
1067                         // enclosing structure.
1068                         addr = inst->addr + ((BYTE*)ptr - parent);
1069                         status = S_OK;
1070                     }
1071                     else
1072                     {
1073                         // We found a valid DAC instance but it doesn't cover the address range containing our
1074                         // input pointer. Fall though to report an erroring DAC-izing code.
1075                         status = E_INVALIDARG;
1076                     }
1077                     break;
1078                 }
1079                 else
1080                 {
1081                     // This must not really be a match, perhaps a coincidence?
1082                     // Keep searching
1083                     tryAgain = true;
1084                 }
1085             }
1086         }
1087         EX_CATCH
1088         {
1089             status = E_INVALIDARG;
1090         }
1091         EX_END_CATCH(SwallowAllExceptions)
1092
1093         if (status != S_OK)
1094         {
1095             if (g_dacImpl && g_dacImpl->m_debugMode)
1096             {
1097                 DebugBreak();
1098             }
1099
1100             if (throwEx)
1101             {
1102                 // This means a pointer was supplied which doesn't actually point to somewhere in a marshalled
1103                 // DAC instance.
1104                 _ASSERTE_MSG(false, "DAC coding error: Attempt to get target address from a host interior "
1105                                     "pointer which is not an instance marshalled by DAC!");
1106                 DacError(status);
1107             }
1108         }
1109
1110         return addr;
1111     }
1112 #endif // !_PREFIX_
1113 }
1114
1115 PWSTR    DacGetVtNameW(TADDR targetVtable)
1116 {
1117     PWSTR pszRet = NULL;
1118
1119     ULONG *targ = &g_dacGlobals.Thread__vtAddr;
1120     ULONG *targStart = targ;
1121     for (ULONG i = 0; i < sizeof(g_dacHostVtPtrs) / sizeof(PVOID); i++)
1122     {
1123         if (targetVtable == (*targ + DacGlobalBase()))
1124         {
1125             pszRet = (PWSTR) *(g_dacVtStrings + (targ - targStart));
1126             break;
1127         }
1128
1129         targ++;
1130     }
1131     return pszRet;
1132 }
1133
1134 TADDR
1135 DacGetTargetVtForHostVt(LPCVOID vtHost, bool throwEx)
1136 {
1137     PVOID* host;
1138     ULONG* targ;
1139     ULONG i;
1140
1141     // The host vtable table exactly parallels the
1142     // target vtable table, so just iterate to a match
1143     // return the matching entry.
1144     host = &g_dacHostVtPtrs.Thread;
1145     targ = &g_dacGlobals.Thread__vtAddr;
1146     for (i = 0; i < sizeof(g_dacHostVtPtrs) / sizeof(PVOID); i++)
1147     {
1148         if (*host == vtHost)
1149         {
1150             return *targ + DacGlobalBase();
1151         }
1152
1153         host++;
1154         targ++;
1155     }
1156
1157     if (throwEx)
1158     {
1159         DacError(E_INVALIDARG);
1160     }
1161     return 0;
1162 }
1163
1164 // 
1165 // DacEnumMemoryRegion - report a region of memory to the dump generation code
1166 // 
1167 // Parameters:
1168 //   addr           - target address of the beginning of the memory region
1169 //   size           - number of bytes to report
1170 //   fExpectSuccess - whether or not ASSERTs should be raised if some memory in this region
1171 //                    is found to be unreadable.  Generally we should only report readable
1172 //                    memory (unless the target is corrupt, in which case we expect asserts
1173 //                    if target consistency checking is enabled).  Reporting memory that
1174 //                    isn't fully readable often indicates an issue that could cause much worse
1175 //                    problems (loss of dump data, long/infinite loops in dump generation),
1176 //                    so we want to try and catch any such usage.  Ocassionally we can't say
1177 //                    for sure how much of the reported region will be readable (eg. for the
1178 //                    LoaderHeap, we only know the length of the allocated address space, not
1179 //                    the size of the commit region for every block).  In these special cases,
1180 //                    we pass false to indicate that we're happy reporting up to the first
1181 //                    unreadable byte.  This should be avoided if at all possible.
1182 //                    
1183 bool DacEnumMemoryRegion(TADDR addr, TSIZE_T size, bool fExpectSuccess /*=true*/)
1184 {
1185     if (!g_dacImpl)
1186     {
1187         DacError(E_UNEXPECTED);
1188         UNREACHABLE();
1189     }
1190
1191     return g_dacImpl->ReportMem(addr, size, fExpectSuccess);
1192 }
1193
1194 //
1195 // DacUpdateMemoryRegion - updates/poisons a region of memory of generated dump
1196 // 
1197 // Parameters:
1198 //   addr           - target address of the beginning of the memory region
1199 //   bufferSize     - number of bytes to update/poison
1200 //   buffer         - data to be written at given target address
1201 //
1202 bool DacUpdateMemoryRegion(TADDR addr, TSIZE_T bufferSize, BYTE* buffer)
1203 {
1204     if (!g_dacImpl)
1205     {
1206         DacError(E_UNEXPECTED);
1207         UNREACHABLE();
1208     }
1209
1210     return g_dacImpl->DacUpdateMemoryRegion(addr, bufferSize, buffer);
1211 }
1212
1213 HRESULT
1214 DacWriteHostInstance(PVOID host, bool throwEx)
1215 {
1216     if (!g_dacImpl)
1217     {
1218         DacError(E_UNEXPECTED);
1219         UNREACHABLE();
1220     }
1221
1222     TADDR addr = DacGetTargetAddrForHostAddr(host, throwEx);
1223     if (!addr)
1224     {
1225         return S_OK;
1226     }
1227
1228     DAC_INSTANCE* inst = (DAC_INSTANCE*)host - 1;
1229     return g_dacImpl->m_instances.Write(inst, throwEx);
1230 }
1231
1232 bool
1233 DacHostPtrHasEnumMark(LPCVOID host)
1234 {
1235     if (!DacGetTargetAddrForHostAddr(host, false))
1236     {
1237         // Make it easy to ignore invalid pointers when enumerating.
1238         return true;
1239     }
1240
1241     DAC_INSTANCE* inst = ((DAC_INSTANCE*)host) - 1;
1242     bool marked = inst->enumMem ? true : false;
1243     inst->enumMem = true;
1244     return marked;
1245 }
1246
1247 bool
1248 DacHasMethodDescBeenEnumerated(LPCVOID pMD)
1249 {
1250     if (!DacGetTargetAddrForHostAddr(pMD, false))
1251     {
1252         // Make it easy to ignore invalid pointers when enumerating.
1253         return true;
1254     }
1255
1256     DAC_INSTANCE* inst = ((DAC_INSTANCE*) pMD) - 1;
1257     bool MDEnumed = inst->MDEnumed ? true : false;
1258     return MDEnumed;
1259 }
1260
1261 bool
1262 DacSetMethodDescEnumerated(LPCVOID pMD)
1263 {
1264     if (!DacGetTargetAddrForHostAddr(pMD, false))
1265     {
1266         // Make it easy to ignore invalid pointers when enumerating.
1267         return true;
1268     }
1269
1270     DAC_INSTANCE* inst = ((DAC_INSTANCE*) pMD) - 1;
1271     bool MDEnumed = inst->MDEnumed ? true : false;
1272     inst->MDEnumed = true;
1273     return MDEnumed;
1274 }
1275
1276 // This gets called from DAC-ized code in the VM. 
1277 IMDInternalImport*
1278 DacGetMDImport(const PEFile* peFile, bool throwEx)
1279 {
1280     if (!g_dacImpl)
1281     {
1282         DacError(E_UNEXPECTED);
1283         UNREACHABLE();
1284     }
1285
1286     return g_dacImpl->GetMDImport(peFile, throwEx);
1287 }
1288
1289 IMDInternalImport*
1290 DacGetMDImport(const ReflectionModule* reflectionModule, bool throwEx)
1291 {
1292     if (!g_dacImpl)
1293     {
1294         DacError(E_UNEXPECTED);
1295         UNREACHABLE();
1296     }
1297
1298     return g_dacImpl->GetMDImport(reflectionModule, throwEx);
1299 }
1300
1301 COR_ILMETHOD*
1302 DacGetIlMethod(TADDR methAddr)
1303 {
1304     ULONG32 methodSize = static_cast<ULONG32>(PEDecoder::ComputeILMethodSize(methAddr));
1305
1306     // Sometimes when reading from dumps and inspect NGEN images, but we end up reading metadata from IL image
1307     // the method RVA could not match and we could read from a random address that will translate in inconsistent
1308     // IL code header. If we see the size of the code bigger than 64 Megs we are probably reading a bad IL code header.
1309     // For details see issue DevDiv 273199.
1310     if (methodSize > 0x4000000)
1311     {
1312         DacError(CORDBG_E_TARGET_INCONSISTENT);
1313         UNREACHABLE();
1314     }
1315     return (COR_ILMETHOD*)
1316         DacInstantiateTypeByAddress(methAddr, methodSize,
1317                                     true);
1318 }
1319
1320 #ifdef FEATURE_MINIMETADATA_IN_TRIAGEDUMPS
1321 void 
1322 DacMdCacheAddEEName(TADDR taEE, const SString& ssEEName)
1323 {
1324     if (!g_dacImpl)
1325     {
1326         DacError(E_UNEXPECTED);
1327         UNREACHABLE();
1328     }
1329
1330     g_dacImpl->MdCacheAddEEName(taEE, ssEEName);
1331 }
1332 bool 
1333 DacMdCacheGetEEName(TADDR taEE, SString & eeName)
1334 {
1335     if (!g_dacImpl)
1336     {
1337         DacError(E_UNEXPECTED);
1338         UNREACHABLE();
1339     }
1340
1341     return g_dacImpl->MdCacheGetEEName(taEE, eeName);
1342 }
1343
1344 #endif // FEATURE_MINIMETADATA_IN_TRIAGEDUMPS
1345
1346 PVOID
1347 DacAllocHostOnlyInstance(ULONG32 size, bool throwEx)
1348 {
1349     SUPPORTS_DAC_HOST_ONLY;
1350     if (!g_dacImpl)
1351     {
1352         DacError(E_UNEXPECTED);
1353         UNREACHABLE();
1354     }
1355
1356     DAC_INSTANCE* inst = g_dacImpl->m_instances.Alloc(0, size, DAC_DPTR);
1357     if (!inst)
1358     {
1359         DacError(E_OUTOFMEMORY);
1360         UNREACHABLE();
1361     }
1362
1363     g_dacImpl->m_instances.AddSuperseded(inst);
1364
1365     return inst + 1;
1366 }
1367
1368 //
1369 // Queries whether ASSERTs should be raised when inconsistencies in the target are detected
1370 //
1371 // Return Value:
1372 //   true if ASSERTs should be raised in DACized code.  
1373 //   false if ASSERTs should be ignored.
1374 //   
1375 // Notes:
1376 //   See code:ClrDataAccess::TargetConsistencyAssertsEnabled for details.
1377 bool DacTargetConsistencyAssertsEnabled()
1378 {
1379     if (!g_dacImpl)
1380     {
1381         // No ClrDataAccess instance available (maybe we're still initializing).  Any asserts when this is
1382         // the case should only be host-asserts (i.e. always bugs), and so we should just return true.
1383         return true; 
1384     }
1385
1386     return g_dacImpl->TargetConsistencyAssertsEnabled();
1387 }
1388
1389 // 
1390 // DacEnumCodeForStackwalk
1391 // This is a helper function to enumerate the instructions around a call site to aid heuristics
1392 // used by debugger stack walkers.
1393 // 
1394 // Arguments:
1395 //     taCallEnd - target address of the instruction just after the call instruction for the stack
1396 //                 frame we want to examine(i.e. the return address for the next frame).
1397 // 
1398 // Note that this is shared by our two stackwalks during minidump generation, 
1399 // code:Thread::EnumMemoryRegionsWorker and code:ClrDataAccess::EnumMemWalkStackHelper.  Ideally 
1400 // we'd only have one stackwalk, but we currently have two different APIs for stackwalking 
1401 // (CLR StackFrameIterator and IXCLRDataStackWalk), and we must ensure that the memory needed 
1402 // for either is captured in a minidump.  Eventually, all clients should get moved over to the
1403 // arrowhead debugging architecture, at which time we can rip out all the IXCLRData APIs, and
1404 // so this logic could just be private to the EnumMem code for Thread.
1405 //
1406 void DacEnumCodeForStackwalk(TADDR taCallEnd)
1407 {
1408     if (taCallEnd == 0)
1409         return;
1410     //
1411     // x86 stack walkers often end up having to guess
1412     // about what's a return address on the stack.
1413     // Doing so involves looking at the code at the
1414     // possible call site and seeing if it could
1415     // reach the callee.  Save enough code and around
1416     // the call site to allow this with a dump.
1417     //
1418     // For whatever reason 64-bit platforms require us to save
1419     // the instructions around the call sites on the stack as well.
1420     // Otherwise we cannnot show the stack in a minidump.
1421     //
1422     // Note that everything we do here is a heuristic that won't always work in general.
1423     // Eg., part of the 2xMAX_INSTRUCTION_LENGTH range might not be mapped (we could be
1424     // right on a page boundary).  More seriously, X86 is not necessarily parsable in reverse
1425     // (eg. there could be a segment-override prefix in front of the call instruction that
1426     // we miss).  So we'll dump what we can and ignore any failures.  Ideally we'd better
1427     // quantify exactly what debuggers need and why, and try and avoid these ugly heuristics.
1428     // It seems like these heuristics are too tightly coupled to the implementation details
1429     // of some specific debugger stackwalking algorithm.
1430     //  
1431     DacEnumMemoryRegion(taCallEnd - MAX_INSTRUCTION_LENGTH, MAX_INSTRUCTION_LENGTH * 2, false);
1432
1433 #if defined(_TARGET_X86_)
1434     // If it was an indirect call we also need to save the data indirected through.
1435     // Note that this only handles absolute indirect calls (ModR/M byte of 0x15), all the other forms of
1436     // indirect calls are register-relative, and so we'd have to do a much more complicated decoding based
1437     // on the register context.  Regardless, it seems like this is fundamentally error-prone because it's 
1438     // aways possible that the call instruction was not 6 bytes long, and we could have some other instructions
1439     // that happen to match the pattern we're looking for.
1440     PTR_BYTE callCode = PTR_BYTE(taCallEnd - 6);
1441     PTR_BYTE callMrm = PTR_BYTE(taCallEnd - 5);
1442     PTR_TADDR callInd = PTR_TADDR(taCallEnd - 4);
1443     if (callCode.IsValid() &&
1444         (*callCode == 0xff) &&
1445         callMrm.IsValid() &&
1446         (*callMrm == 0x15) &&
1447         callInd.IsValid())
1448     {
1449         DacEnumMemoryRegion(*callInd, sizeof(TADDR), false);
1450     }
1451 #endif // #ifdef _TARGET_X86_
1452 }
1453
1454 // ----------------------------------------------------------------------------
1455 // DacReplacePatches
1456 //
1457 // Description: 
1458 //    Given the address and the size of a memory range which is stored in the buffer, replace all the patches 
1459 //    in the buffer with the real opcodes.  This is especially important on X64 where the unwinder needs to 
1460 //    disassemble the native instructions.
1461 //
1462 // Arguments:
1463 //    * range   - the address and the size of the memory range
1464 //    * pBuffer - the buffer containting the memory range
1465 //
1466 // Return Value:
1467 //    Return S_OK if everything succeeds.
1468 //
1469 // Assumptions:
1470 //    * The debuggee has to be stopped.
1471 //
1472 // Notes:
1473 //    * @dbgtodo  ICDProcess - When we DACize code:CordbProcess::ReadMemory,
1474 //        we should change it to use this function.
1475 //
1476
1477 HRESULT DacReplacePatchesInHostMemory(MemoryRange range, PVOID pBuffer)
1478 {
1479     SUPPORTS_DAC;
1480
1481     // If the patch table is invalid, then there is no patch to replace.
1482     if (!DebuggerController::GetPatchTableValid())
1483     {
1484         return S_OK;
1485     }
1486
1487     HASHFIND info;
1488
1489     DebuggerPatchTable *      pTable = DebuggerController::GetPatchTable();
1490     DebuggerControllerPatch * pPatch = pTable->GetFirstPatch(&info);
1491
1492     // <PERF>
1493     // The unwinder needs to read the stack very often to restore pushed registers, retrieve the 
1494     // return addres, etc.  However, stack addresses should never be patched.
1495     // One way to optimize this code is to pass the stack base and the stack limit of the thread to this 
1496     // function and use those two values to filter out stack addresses.
1497     //
1498     // Another thing we can do is instead of enumerating the patches, we could enumerate the address.
1499     // This is more efficient when we have a large number of patches and a small memory range.  Perhaps
1500     // we could do a hybrid approach, i.e. use the size of the range and the number of patches to dynamically
1501     // determine which enumeration is more efficient.
1502     // </PERF>
1503     while (pPatch != NULL)
1504     {
1505         CORDB_ADDRESS patchAddress = (CORDB_ADDRESS)dac_cast<TADDR>(pPatch->address);
1506
1507         if (patchAddress != NULL)
1508         {
1509             PRD_TYPE opcode = pPatch->opcode;
1510
1511             CORDB_ADDRESS address = (CORDB_ADDRESS)(dac_cast<TADDR>(range.StartAddress()));
1512             SIZE_T        cbSize  = range.Size();
1513
1514             // Check if the address of the patch is in the specified memory range.
1515             if (IsPatchInRequestedRange(address, cbSize, patchAddress))
1516             {
1517                 // Replace the patch in the buffer with the original opcode.
1518                 CORDbgSetInstructionEx(reinterpret_cast<PBYTE>(pBuffer), address, patchAddress, opcode, cbSize);
1519             }
1520         }
1521
1522         pPatch = pTable->GetNextPatch(&info);
1523     }
1524
1525     return S_OK;
1526 }