diff options
Diffstat (limited to 'src/debug/inc/dacdbistructures.h')
-rw-r--r-- | src/debug/inc/dacdbistructures.h | 790 |
1 files changed, 790 insertions, 0 deletions
diff --git a/src/debug/inc/dacdbistructures.h b/src/debug/inc/dacdbistructures.h new file mode 100644 index 0000000000..d6f2c0b943 --- /dev/null +++ b/src/debug/inc/dacdbistructures.h @@ -0,0 +1,790 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. +//***************************************************************************** +// File: DacDbiStructures.h +// + +// +// Declarations and inline functions for data structures shared between by the +// DAC/DBI interface functions and the right side. +// +// Note that for MAC these structures are marshalled between Windows and Mac +// and so their layout and size must be identical in both builds. Use the +// MSLAYOUT macro on every structure to avoid compiler packing differences. +// +//***************************************************************************** + +#ifndef DACDBISTRUCTURES_H_ +#define DACDBISTRUCTURES_H_ + +#include "./common.h" + +//------------------------------------------------------------------------------- +// classes shared by the DAC/DBI interface functions and the right side +//------------------------------------------------------------------------------- + +// DacDbiArrayList encapsulates an array and the number of elements in the array. +// Notes: +// - storage is always on the DacDbi heap +// - this class owns the memory. Its dtor will free. +// - Operations that initialize list elements use the assignment +// operator defined for type T. If T is a pointer type or has pointer +// type components and no assignment operator override, this will make a shallow copy of +// the element. If T has an assignment operator override that makes a deep copy of pointer +// types, T must also have a destructor that will deallocate any memory allocated. +// - this is NOT thread safe!!! +// - the array elements are always mutable, but the number of elements is fixed between allocations +// - you can gain access to the array using &(list[0]) but this is NOT safe if the array is empty. You +// can call IsEmpty to determine if it is safe to access the array portion +// This list is not designed to have unused elements at the end of the array (extra space) nor to be growable + +// usage examples: +// typedef DacDbiArrayList<Bar> BarList; // handy typedef +// void GetAListOfBars(BarList * pBarList) +// { +// DacDbiArrayList<Foo> fooList; // fooList is an empty array of objects of type Foo +// int elementCount = GetNumberOfFoos(); +// Bar * pBars = new Bar[elementCount]; +// +// fooList.Alloc(elementCount); // get space for the list of Foo instances +// for (int i = 0; i < fooList.Count(); ++i) +// { +// fooList[i] = GetNextFoo(); // copy elements into the list +// } +// ConvertFoosToBars(pBars, &fooList); // always pass by reference +// pBarList->Init(pBars, fooList.Count()); // initialize a list +// } +// +// void ConvertFoosToBars(Bar * pBars, DacDbiArrayList<Foo> * pFooList) +// { +// for (int i = 0; i < pFooList->Count(); ++i) +// { +// if ((*pFooList)[i].IsBaz()) +// pBars [i] = ConvertBazToBar(&(*pFooList)[i]); +// else pBars [i] = (*pFooList)[i].barPart; +// } +// } +// +template<class T> +class MSLAYOUT DacDbiArrayList +{ +public: + // construct an empty list + DacDbiArrayList(); + + // deep copy constructor + DacDbiArrayList(const T * list, int count); + + // destructor--sets list to empty state + ~DacDbiArrayList(); + + // explicitly deallocate the list and set it back to the empty state + void Dealloc(); + + // allocate a list with space for nElements items + void Alloc(int nElements); + + // allocate and initialize a DacDbiArrayList from an array of type T and a count + void Init(const T * list, int count); + + // predicate to indicate if the list is empty + bool IsEmpty() { return m_nEntries == 0; } + + // read-only element accessor + const T & operator [](int index) const; + + // writeable element accessor + T & operator [](int index); + + + // returns the number of elements in the list + int Count() const; + + // @dbgtodo Mac - cleaner way to expose this for serialization? + void PrepareForDeserialize() + { + m_pList = NULL; + } +private: + // because these are private (and unimplemented), calls will generate a compiler (or linker) error. + // This prevents accidentally invoking the default (shallow) copy ctor or assignment operator. + // This prevents having multiple instances point to the same list memory (eg. due to passing by value), + // which would result in memory corruption when the first copy is destroyed and the list memory is deallocated. + DacDbiArrayList(const DacDbiArrayList<T> & sourceList); + T & operator = (const DacDbiArrayList<T> & rhs); + +// data members +protected: + T * m_pList; // the list + + // - the count is managed by the member functions and is not settable, so (m_pList == NULL) == (m_nEntries == 0) + // is always true. + int m_nEntries; // the number of items in the list + +}; + + +// Describes a buffer in the target +struct MSLAYOUT TargetBuffer +{ + TargetBuffer(); + TargetBuffer(CORDB_ADDRESS pBuffer, ULONG cbSizeInput); + + // @dbgtodo : This ctor form confuses target and host address spaces. This should probably be PTR_VOID instead of void* + TargetBuffer(void * pBuffer, ULONG cbSizeInput); + + // + // Helper methods + // + + // Return a sub-buffer that's starts at byteOffset within this buffer and runs to the end. + TargetBuffer SubBuffer(ULONG byteOffset) const; + + // Return a sub-buffer that starts at byteOffset within this buffer and is byteLength long. + TargetBuffer SubBuffer(ULONG byteOffset, ULONG byteLength) const; + + // Returns true if the buffer length is 0. + bool IsEmpty() const; + + // Sets address to NULL and size to 0 + // IsEmpty() will be true after this. + void Clear(); + + // Initialize fields + void Init(CORDB_ADDRESS address, ULONG size); + + // Target address of buffer + CORDB_ADDRESS pAddress; + + // Size of buffer in bytes + ULONG cbSize; +}; + +//=================================================================================== +// Module properties, retrieved by DAC. +// Describes a VMPTR_DomainFile representing a module. +// In the VM, a raw Module may be domain neutral and shared by many appdomains. +// Whereas a DomainFile is like a { AppDomain, Module} pair. DomainFile corresponds +// much more to ICorDebugModule (which also has appdomain affinity). +//=================================================================================== +struct MSLAYOUT DomainFileInfo +{ + // The appdomain that the DomainFile is associated with. + // Although VMPTR_Module may be shared across multiple domains, a DomainFile has appdomain affinity. + VMPTR_AppDomain vmAppDomain; + + // The assembly this module belongs to. All modules live in an assembly. + VMPTR_DomainAssembly vmDomainAssembly; +}; + +struct MSLAYOUT ModuleInfo +{ + // The non-domain specific assembly which this module resides in. + VMPTR_Assembly vmAssembly; + + // The PE Base address and size of the module. These may be 0 if there is no image + // (such as for a dynamic module that's not persisted to disk). + CORDB_ADDRESS pPEBaseAddress; + + // The PEFile associated with the module. Every module (even non-file-based ones) has a PEFile. + // This is critical because DAC may ask for a metadata importer via PE-file. + // a PEFile may have 1 or more PEImage child objects (1 for IL, 1 for native image, etc) + VMPTR_PEFile vmPEFile; + + // The PE Base address and size of the module. These may be 0 if there is no image + // (such as for a dynamic module that's not persisted to disk). + ULONG nPESize; + + // Is this a dynamic (reflection.emit) module? + // This means that new classes can be added to the module; and so + // the module's metadata and symbols can be updated. Debugger will have to do extra work + // to keep up with the updates. + // Dynamic modules may be transient (entirely in-memory) or persisted to disk (have a file associated with them). + BOOL fIsDynamic; + + // Is this an inmemory module? + // Assemblies can be instantiated purely in-memory from just a Byte[]. + // This means the module (and pdb) are not in files, and thus the debugger + // needs to do extra work to retrieve them from the Target's memory. + BOOL fInMemory; +}; + +// the following two classes track native offsets for local variables and sequence +// points. This information is initialized on demand. + + +//=================================================================================== +// NativeVarData holds a list of structs that provide the following information for +// each local variable and fixed argument in a function: the offsets between which the +// variable or argument lives in a particular location, the location itself, and the +// variable number (ID). This allows us to determine where a value is at any given IP. + +// Lifetime management of the list is the responsibility of the NativeVarData class. +// Callers that allocate memory for a new list should NOT maintain a separate pointer +// to the list. + +// The arguments we track are the "fixed" arguments, specifically, the explicit arguments +// that appear in the source code and the "this" pointer for non-static methods. +// Varargs and other implicit arguments, such as the generic handle are counted in +// CordbJITILFrame::m_allArgsCount. + +// Although logically, we really don't differentiate between arguments and locals when +// all we want to know is where to find a value, we need to have two +// separate counts. The full explanation is in the comment in rsthread.cpp in +// CordbJITILFrame::ILVariableToNative, but the short version is that it allows us to +// compute the correct ID for a value. + +// m_fixedArgsCount, accessed through GetFixedArgCount, is the actual number of fixed +// arguments. +// m_allArgsCount, accessed through GetAllArgsCount, is the number of fixed args plus the +// number of varargs. + +// The number of entries in m_offsetInfo, accessed through Count(), is NOT the +// number of locals, nor the number of locals plus the number of arguments. It is the +// number of entries in the list. Any particular value may have an arbitrary number of +// entries, depending on how many different places it is stored during the execution of +// the method. The list is not sorted, so searches for data within it must be linear. +//=================================================================================== +class MSLAYOUT NativeVarData +{ +public: + // constructor + NativeVarData(); + // destructor + ~NativeVarData(); + + + // initialize the list of native var information structures, including the starting address of the list + // (m_pOffsetInfo, the number of entries (m_count) and the number of fixed args (m_fixedArgsCount). + // NativeVarData will manage the lifetime of the allocated memory for the list, so the caller should not + // hold on to its address. + void InitVarDataList(ICorDebugInfo::NativeVarInfo * plistStart, int fixedArgCount, int entryCount); + +private: + // non-existent copy constructor to disable the (shallow) compiler-generated + // one. If you attempt to use this, you will get a compiler or linker error. + NativeVarData(const NativeVarData & rhs) {}; + + // non-existent assignment operator to disable the (shallow) compiler-generated + // one. If you attempt to use this, you will get a compiler or linker error. + NativeVarData & operator=(const NativeVarData & rhs); + +//---------------------------------------------------------------------------------- +// Accessor Functions +//---------------------------------------------------------------------------------- +public: + + // get the list of native offset info + const DacDbiArrayList<ICorDebugInfo::NativeVarInfo> * GetOffsetInfoList() const + { + _ASSERTE(m_fInitialized); + return &m_offsetInfo; + } + + // get the number of explicit arguments for this function--this + // includes the fixed arguments for vararg methods, but not the variable ones + ULONG32 GetFixedArgCount() + { + _ASSERTE(IsInitialized()); + // this count includes explicit arguments plus one for the "this" pointer + // but doesn't count varargs + return m_fixedArgsCount; + } + + // get the number of all arguments, including varargs + ULONG32 GetAllArgsCount() + { + _ASSERTE(IsInitialized()); + return m_allArgsCount; + } + + // set the number of all arguments, including varargs + void SetAllArgsCount(ULONG32 count) + { + m_allArgsCount = count; + } + + // determine whether we have successfully initialized this + BOOL IsInitialized() + { + return m_fInitialized == true; + } + + +//---------------------------------------------------------------------------------- +// Data Members +//---------------------------------------------------------------------------------- + +// @dbgtodo Mac - making this public for serializing for remote DAC on mac. Need to make this private again. +public: + // contains a list of structs providing information about the location of a local + // variable or argument between a pair of offsets and the number of entries in the list + DacDbiArrayList<ICorDebugInfo::NativeVarInfo> m_offsetInfo; + + // number of fixed arguments to the function i.e., the explicit arguments and "this" pointer + ULONG32 m_fixedArgsCount; + + // number of fixed arguments plus number of varargs + ULONG32 m_allArgsCount; + + // indicates whether an attempt has been made toinitialize the var data already + bool m_fInitialized; +}; // class NativeVarData + +//=================================================================================== +// SequencePoints holds a list of sequence points that map IL offsets to native offsets. In addition, +// it keeps track of the number of entries in the list and whether the list is sorted. +//=================================================================================== +class MSLAYOUT SequencePoints +{ +public: + SequencePoints(); + + ~SequencePoints(); + + // Initialize the m_pMap data member to the address of an allocated chunk + // of memory (or to NULL if the count is zero). Set m_count as the + // number of entries in the map. + void InitSequencePoints(ULONG32 count); + +private: + // non-existent copy constructor to disable the (shallow) compiler-generated + // one. If you attempt to use this, you will get a compiler or linker error. + SequencePoints(const SequencePoints & rhs) {}; + + // non-existent assignment operator to disable the (shallow) compiler-generated + // one. If you attempt to use this, you will get a compiler or linker error. + SequencePoints & operator=(const SequencePoints & rhs); + + //---------------------------------------------------------------------------------- + // class MapSortILMap: A template class that will sort an array of DebuggerILToNativeMap. + // This class is intended to be instantiated on the stack / in temporary storage, and used + // to reorder the sequence map. + //---------------------------------------------------------------------------------- + class MapSortILMap : public CQuickSort<DebuggerILToNativeMap> + { + public: + //Constructor + MapSortILMap(DebuggerILToNativeMap * map, + int count) + : CQuickSort<DebuggerILToNativeMap>(map, count) {} + + // secondary key comparison--if two IL offsets are the same, + // we determine order based on native offset + int CompareInternal(DebuggerILToNativeMap * first, + DebuggerILToNativeMap * second); + + //Comparison operator + int Compare(DebuggerILToNativeMap * first, + DebuggerILToNativeMap * second); + }; + +//---------------------------------------------------------------------------------- +// Accessor Functions +//---------------------------------------------------------------------------------- +public: + // @dbgtodo Microsoft inspection: It would be very nice not to need this at all. Ideally, + // it would be better to make ExportILToNativeMap expect a DacDbiArrayList instead of the + // array and size. At present, there's a call to ExportILToNativeMap in debugger.cpp where + // DacDbiArrayLists aren't available, so at present, we need to pass the array and size. + // We should be able to eliminate the debugger.cpp call when we get rid of in-proc + // inspection. At that point, we can delete this function too, as well as GetEntryCount. + // In the meantime, it would be great if no one else took a dependency on this. + + // get value of m_pMap + DebuggerILToNativeMap * GetMapAddr() + { + // Please don't call this function + _ASSERTE(m_fInitialized); + return &(m_map[0]); + } + + // get value of m_count + ULONG32 GetEntryCount() + { + _ASSERTE(m_fInitialized); + return m_mapCount; + } + + ULONG32 GetCallsiteEntryCount() + { + _ASSERTE(m_fInitialized); + return m_map.Count() - m_mapCount; //m_map.Count(); + } + + DebuggerILToNativeMap * GetCallsiteMapAddr() + { + // Please don't call this function + _ASSERTE(m_fInitialized); + + if (m_map.Count() == m_mapCount) + return NULL; + + return &(m_map[m_mapCount]); + } + + + + // determine whether we have initialized this + BOOL IsInitialized() + { + return m_fInitialized == true; + } + + // Copy data from the VM map data to our own map structure and sort. The + // information comes to us in a data structure that differs slightly from the + // one we use out of process, so we have to copy it to the right-side struct. + void CopyAndSortSequencePoints(const ICorDebugInfo::OffsetMapping mapCopy[]); + + + // Set the IL offset of the last sequence point before the epilog. + // If a native offset maps to the epilog, we will return the this IL offset. + void SetLastILOffset(ULONG32 lastILOffset) + { + _ASSERTE(m_fInitialized); + m_lastILOffset = lastILOffset; + } + + // Map the given native offset to IL offset. Also return the mapping type. + DWORD MapNativeOffsetToIL(DWORD dwNativeOffset, + CorDebugMappingResult *pMapType); + +//---------------------------------------------------------------------------------- +// Data Members +//---------------------------------------------------------------------------------- + + // @dbgtodo Mac - making this public for serializing for remote DAC on mac. Need to make this private again. +public: + + // map of IL to native offsets for sequence points + DacDbiArrayList<DebuggerILToNativeMap> m_map; + + // + ULONG32 m_mapCount; + + // the IL offset of the last sequence point before the epilog + ULONG32 m_lastILOffset; + // indicates whether an attempt has been made to initialize the sequence points already + bool m_fInitialized; +}; // class SequencePoints + +//---------------------------------------------------------------------------------- +// declarations needed for getting native code regions +//---------------------------------------------------------------------------------- + +// Code may be split into Hot & Cold regions, so we need an extra address & size. +// The jitter doesn't do this optimization w/ debuggable code, so we'll +// rarely see the cold region information as non-null values. + +// This enumeration provides symbolic indices into m_rgCodeRegions. +typedef enum {kHot = 0, kCold, MAX_REGIONS} CodeBlobRegion; + +// This contains the information we need to initialize a CordbNativeCode object +class MSLAYOUT NativeCodeFunctionData +{ +public: + // set all fields to default values (NULL, FALSE, or zero as appropriate) + NativeCodeFunctionData(); + + // conversion constructor to convert from an instance of DebuggerIPCE_JITFUncData to an instance of + // NativeCodeFunctionData. + NativeCodeFunctionData(DebuggerIPCE_JITFuncData * source); + + // The hot region start address could be NULL in the following circumstances: + // 1. We haven't yet tried to get the information + // 2. We tried to get the information, but the function hasn't been jitted yet + // 3. We tried to get the information, but the MethodDesc wasn't available yet (very early in + // module initialization), which implies that the code isn't available either. + // 4. We tried to get the information, but a method edit has reset the MethodDesc, but the + // method hasn't been jitted yet. + // In all cases, we can check the hot region start address to determine whether the rest of the + // the information is valid. + BOOL IsValid() { return (m_rgCodeRegions[kHot].pAddress != NULL); } + void Clear(); + + // data members + // start addresses and sizes of hot & cold regions + TargetBuffer m_rgCodeRegions[MAX_REGIONS]; + + // indicates whether the function is a generic function, or a method inside a generic class (or both). + BOOL isInstantiatedGeneric; + + // MethodDesc for the function + VMPTR_MethodDesc vmNativeCodeMethodDescToken; + + // EnC version number of the function + SIZE_T encVersion; +}; + +//---------------------------------------------------------------------------------- +// declarations needed for getting type information +//---------------------------------------------------------------------------------- + +// FieldData holds data for each field within a class or type. This data +// is passed from the DAC to the DI in response to a request for class info. +// This type is also used by CordbClass and CordbType to hold the list of fields for the +// class. +class MSLAYOUT FieldData +{ +public: +#ifndef RIGHT_SIDE_COMPILE + // initialize various fields of an instance of FieldData from information in a FieldDesc + void Initialize(BOOL fIsStatic, BOOL fIsPrimitive, mdFieldDef mdToken); +#else + HRESULT GetFieldSignature(class CordbModule * pModule, /*OUT*/ SigParser * pSigParser); +#endif + + // clear various fields for a new instance of FieldData + void ClearFields(); + + // Make sure it's okay to get or set an instance field offset. + BOOL OkToGetOrSetInstanceOffset(); + + // Make sure it's okay to get or set a static field address. + BOOL OkToGetOrSetStaticAddress(); + + // If this is an instance field, store its offset + void SetInstanceOffset( SIZE_T offset ); + + // If this is a "normal" static, store its absolute address + void SetStaticAddress( TADDR addr ); + + // If this is an instance field, return its offset + // Note that this offset is allways a real offset (possibly larger than 22 bits), which isn't + // necessarily the same as the overloaded FieldDesc.dwOffset field which can have + // some special FIELD_OFFSET tokens. + SIZE_T GetInstanceOffset(); + + // If this is a "normal" static, get its absolute address + // TLS and context-specific statics are "special". + TADDR GetStaticAddress(); + +// +// Data members +// + mdFieldDef m_fldMetadataToken; + // m_fFldStorageAvailable is true whenever the storage for this field is available. + // If this is a field that is newly added with EnC and hasn't had any storage + // allocated yet, then fldEnCAvailable will be false. + BOOL m_fFldStorageAvailable; + + // Bits that specify what type of field this is + bool m_fFldIsStatic; // true if static field, false if instance field + bool m_fFldIsRVA; // true if static relative to module address + bool m_fFldIsTLS; // true if thread-specific static + bool m_fFldIsContextStatic; // true if context-specific static + bool m_fFldIsPrimitive; // Only true if this is a value type masquerading as a primitive. + bool m_fFldIsCollectibleStatic; // true if this is a static field on a collectible type + +private: + // The m_fldInstanceOffset and m_pFldStaticAddress are mutually exclusive. Only one is ever set at a time. + SIZE_T m_fldInstanceOffset; // The offset of a field within an object instance + // For EnC fields, this isn't actually within the object instance, + // but has been cooked to still be relative to the beginning of + // the object. + TADDR m_pFldStaticAddress; // The absolute target address of a static field + + PCCOR_SIGNATURE m_fldSignatureCache; // This is passed across as null. It is a RS-only cache, and SHOULD + // NEVER BE ACCESSED DIRECTLY! + ULONG m_fldSignatureCacheSize; // This is passed across as 0. It is a RS-only cache, and SHOULD + // NEVER BE ACCESSED DIRECTLY! +public: + VMPTR_FieldDesc m_vmFieldDesc; + +}; // class FieldData + + +// ClassInfo holds information about a type (class or other structured type), including a list of its fields +class MSLAYOUT ClassInfo +{ +public: + ClassInfo(); + + ~ClassInfo(); + + void Clear(); + + // Size of object in bytes, for non-generic types. Note: this is NOT valid for constructed value types, + // e.g. value type Pair<DateTime,int>. Use CordbType::m_objectSize instead. + SIZE_T m_objectSize; + + // list of structs containing information about all the fields in this Class, along with the number of entries + // in the list. Does not include inherited fields. DON'T KEEP POINTERS TO ELEMENTS OF m_fieldList AROUND!! + // This may be deleted if the class gets EnC'd. + DacDbiArrayList<FieldData> m_fieldList; +}; // class ClassInfo + +// EnCHangingFieldInfo holds information describing a field added with Edit And Continue. This data +// is passed from the DAC to the DI in response to a request for EnC field info. +class MSLAYOUT EnCHangingFieldInfo +{ +public: + // Init will initialize fields, taking into account whether the field is static or not. + void Init(VMPTR_Object pObject, + SIZE_T offset, + mdFieldDef fieldToken, + CorElementType elementType, + mdTypeDef metadataToken, + VMPTR_DomainFile vmDomainFile); + + DebuggerIPCE_BasicTypeData GetObjectTypeData() const { return m_objectTypeData; }; + mdFieldDef GetFieldToken() const { return m_fldToken; }; + VMPTR_Object GetVmObject() const { return m_vmObject; }; + SIZE_T GetOffsetToVars() const { return m_offsetToVars; }; + +private: + DebuggerIPCE_BasicTypeData m_objectTypeData; // type data for the EnC field + VMPTR_Object m_vmObject; // object instance to which the field has been added--if the field is + // static, this will be NULL instead of pointing to an instance + SIZE_T m_offsetToVars; // offset to the beginning of variable storage in the object + mdFieldDef m_fldToken; // metadata token for the added field + +}; // EnCHangingFieldInfo + +// TypeHandleToExpandedTypeInfo returns different DebuggerIPCE_ExpandedTypeData objects +// depending on whether the object value that the TypeData corresponds to is +// boxed or not. Different parts of the API transfer objects in slightly different ways. +// AllBoxed: +// For GetAndSendObjectData all values are boxed, +// +// OnlyPrimitivesUnboxed: +// When returning results from FuncEval only "true" structs +// get boxed, i.e. primitives are unboxed. +// +// NoValueTypeBoxing: +// TypeHandleToExpandedTypeInfo is also used to report type parameters, +// and in this case none of the types are considered boxed ( +enum AreValueTypesBoxed { NoValueTypeBoxing, OnlyPrimitivesUnboxed, AllBoxed }; + +// TypeRefData is used for resolving a type reference (see code:CordbModule::ResolveTypeRef and +// code:DacDbiInterfaceImpl::ResolveTypeReference) to store relevant information about the type +typedef struct MSLAYOUT +{ + // domain file for the type + VMPTR_DomainFile vmDomainFile; + // metadata token for the type. This may be a typeRef (for requests) or a typeDef (for responses). + mdToken typeToken; +} TypeRefData; + +// @dbgtodo Microsoft inspection: get rid of IPCE type. +// TypeInfoList encapsulates a list of type data instances and the length of the list. +typedef DacDbiArrayList<DebuggerIPCE_TypeArgData> TypeInfoList; + +// ArgInfoList encapsulates a list of type data instances for arguments for a top-level +// type and the length of the list. +typedef DacDbiArrayList<DebuggerIPCE_BasicTypeData> ArgInfoList; + +// TypeParamsList encapsulate a list of type parameters and the length of the list +typedef DacDbiArrayList<DebuggerIPCE_ExpandedTypeData> TypeParamsList; + +// A struct for passing version information from DBI to DAC. +// See code:CordbProcess::CordbProcess#DBIVersionChecking for more information. +const DWORD kCurrentDacDbiProtocolBreakingChangeCounter = 1; + +struct DbiVersion +{ + DWORD m_dwFormat; // the format of this DbiVersion instance + DWORD m_dwDbiVersionMS; // version of the DBI DLL, in the convention used by VS_FIXEDFILEINFO + DWORD m_dwDbiVersionLS; + DWORD m_dwProtocolBreakingChangeCounter; // initially this was reserved and always set to 0 + // Now we use it as a counter to explicitly introduce breaking changes + // between DBI and DAC when we have our IPC transport in the middle + // If DBI and DAC don't agree on the same value CheckDbiVersion will return CORDBG_E_INCOMPATIBLE_PROTOCOL + // Please document every time this value changes + // 0 - initial value + // 1 - Indicates that the protocol now supports the GetRemoteInterfaceHashAndTimestamp message + // The message must have ID 2, with signature: + // OUT DWORD & hash1, OUT DWORD & hash2, OUT DWORD & hash3, OUT DWORD & hash4, OUT DWORD & timestamp1, OUT DWORD & timestamp2 + // The hash can be used as an indicator of many other breaking changes providing + // easier automated enforcement during development. It is NOT recommended to use + // the hash as a release versioning mechanism however. + DWORD m_dwReservedMustBeZero1; // reserved for future use +}; + +// The way in which a thread is blocking on an object +enum DacBlockingReason +{ + DacBlockReason_MonitorCriticalSection, + DacBlockReason_MonitorEvent +}; + +// Information about an object which is blocking a managed thread +struct DacBlockingObject +{ + VMPTR_Object vmBlockingObject; + VMPTR_AppDomain vmAppDomain; + DWORD dwTimeout; + DacBlockingReason blockingReason; +}; + +// Opaque user defined data used in callbacks +typedef void* CALLBACK_DATA; + +struct MonitorLockInfo +{ + VMPTR_Thread lockOwner; + DWORD acquisitionCount; +}; + +struct MSLAYOUT DacGcReference +{ + VMPTR_AppDomain vmDomain; // The AppDomain of the handle/object, may be null. + union + { + CORDB_ADDRESS pObject; // A managed object, with the low bit set. + VMPTR_OBJECTHANDLE objHnd; // A reference to the object, valid if (pAddress & 1) == 0 + }; + DWORD dwType; // Where the root came from. + + /* + DependentSource - for HandleDependent + RefCount - for HandleStrongRefCount + Size - for HandleSizedByref + */ + UINT64 i64ExtraData; +}; // struct DacGcReference + +struct MSLAYOUT DacExceptionCallStackData +{ + VMPTR_AppDomain vmAppDomain; + VMPTR_DomainFile vmDomainFile; + CORDB_ADDRESS ip; + mdMethodDef methodDef; + BOOL isLastForeignExceptionFrame; +}; + +// These represent the various states a SharedReJitInfo can be in. +enum DacSharedReJitInfoState +{ + // The profiler has requested a ReJit, so we've allocated stuff, but we haven't + // called back to the profiler to get any info or indicate that the ReJit has + // started. (This Info can be 'reused' for a new ReJit if the + // profiler calls RequestReJit again before we transition to the next state.) + kStateRequested = 0x00000000, + + // We have asked the profiler about this method via ICorProfilerFunctionControl, + // and have thus stored the IL and codegen flags the profiler specified. Can only + // transition to kStateReverted from this state. + kStateActive = 0x00000001, + + // The methoddef has been reverted, but not freed yet. It (or its instantiations + // for generics) *MAY* still be active on the stack someplace or have outstanding + // memory references. + kStateReverted = 0x00000002, + + + kStateMask = 0x0000000F, +}; + +struct MSLAYOUT DacSharedReJitInfo +{ + DWORD m_state; + CORDB_ADDRESS m_pbIL; + DWORD m_dwCodegenFlags; + ULONG m_cInstrumentedMapEntries; + CORDB_ADDRESS m_rgInstrumentedMapEntries; +}; + +#include "dacdbistructures.inl" +#endif // DACDBISTRUCTURES_H_ |