internal override uint GetMetadataToken(ulong mt) { uint token = uint.MaxValue; IMethodTableData mtData = GetMethodTableData(mt); if (mtData != null) { byte[] buffer = CLRVersion == DesktopVersion.v2 ? GetByteArrayForStruct <V2EEClassData>() : GetByteArrayForStruct <V4EEClassData>(); if (Request(DacRequests.EECLASS_DATA, mtData.EEClass, buffer)) { if (CLRVersion == DesktopVersion.v2) { GCHandle handle = GCHandle.Alloc(buffer, GCHandleType.Pinned); V2EEClassData result = (V2EEClassData)Marshal.PtrToStructure(handle.AddrOfPinnedObject(), typeof(V2EEClassData)); handle.Free(); token = result.Token; } else { GCHandle handle = GCHandle.Alloc(buffer, GCHandleType.Pinned); V4EEClassData result = (V4EEClassData)Marshal.PtrToStructure(handle.AddrOfPinnedObject(), typeof(V4EEClassData)); handle.Free(); token = result.Token; } } } return(token); }
internal override ulong GetModuleForMT(ulong mt) { if (mt == 0) { return(0); } IMethodTableData mtData = GetMethodTableData(mt); if (mtData == null) { return(0); } IEEClassData classData; if (CLRVersion == DesktopVersion.v2) { classData = Request <IEEClassData, V2EEClassData>(DacRequests.EECLASS_DATA, mtData.EEClass); } else { classData = Request <IEEClassData, V4EEClassData>(DacRequests.EECLASS_DATA, mtData.EEClass); } if (classData == null) { return(0); } return(classData.Module); }
private void CreateFreeType() { ulong free = NativeRuntime.GetFreeType(); IMethodTableData mtData = NativeRuntime.GetMethodTableData(free); _free = new NativeType(this, _types.Count, _mrtModule, "Free", free, mtData); _indices[free] = _types.Count; _types.Add(_free); }
private void CreateFreeType() { ulong free = m_runtime.GetFreeType(); IMethodTableData mtData = m_runtime.GetMethodTableData(free); m_free = new RhType(this, m_types.Count, m_mrtModule, "Free", free, mtData); m_indices[free] = m_types.Count; m_types.Add(m_free); }
internal override IFieldInfo GetFieldInfo(ulong mt) { IMethodTableData mtData = GetMethodTableData(mt); IFieldInfo fieldData; if (CLRVersion == DesktopVersion.v2) { fieldData = Request <IFieldInfo, V2EEClassData>(DacRequests.EECLASS_DATA, mtData.EEClass); } else { fieldData = Request <IFieldInfo, V4EEClassData>(DacRequests.EECLASS_DATA, mtData.EEClass); } return(fieldData); }
internal override IList <ulong> GetMethodDescList(ulong methodTable) { IMethodTableData mtData = Request <IMethodTableData, LegacyMethodTableData>(DacRequests.METHODTABLE_DATA, methodTable); ulong[] values = new ulong[mtData.NumMethods]; if (mtData.NumMethods == 0) { return(values); } CodeHeaderData codeHeader = new CodeHeaderData(); byte[] slotArgs = new byte[0x10]; byte[] result = new byte[sizeof(ulong)]; WriteValueToBuffer(methodTable, slotArgs, 0); for (int i = 0; i < mtData.NumMethods; ++i) { WriteValueToBuffer(i, slotArgs, sizeof(ulong)); if (!Request(DacRequests.METHODTABLE_SLOT, slotArgs, result)) { continue; } ulong ip = BitConverter.ToUInt64(result, 0); if (!RequestStruct(DacRequests.CODEHEADER_DATA, ip, ref codeHeader)) { continue; } values[i] = codeHeader.MethodDesc; } return(values); }
internal DesktopHeapType(string typeName, DesktopModule module, uint token, ulong mt, IMethodTableData mtData, DesktopGCHeap heap) : base(heap, module, token) { _name = typeName; _constructedMT = mt; Shared = mtData.Shared; _parent = mtData.Parent; _baseSize = mtData.BaseSize; _componentSize = mtData.ComponentSize; _containsPointers = mtData.ContainsPointers; _hasMethods = mtData.NumMethods > 0; }
internal override ClrType GetTypeByMethodTable(ulong mt, ulong cmt, ulong obj) { if (mt == 0) { return(null); } ClrType componentType = null; if (mt == DesktopRuntime.ArrayMethodTable) { if (cmt != 0) { componentType = GetTypeByMethodTable(cmt, 0); if (componentType != null) { cmt = componentType.MethodTable; } else if (obj != 0) { componentType = TryGetComponentType(obj, cmt); if (componentType != null) { cmt = componentType.MethodTable; } } } else { componentType = ObjectType; cmt = ObjectType.MethodTable; } } else { cmt = 0; } TypeHandle hnd = new TypeHandle(mt, cmt); ClrType ret = null; // See if we already have the type. if (_indices.TryGetValue(hnd, out int index)) { ret = _types[index]; } else if (mt == DesktopRuntime.ArrayMethodTable && cmt == 0) { // Handle the case where the methodtable is an array, but the component method table // was not specified. (This happens with fields.) In this case, return System.Object[], // with an ArrayComponentType set to System.Object. uint token = DesktopRuntime.GetMetadataToken(mt); if (token == 0xffffffff) { return(null); } ModuleEntry modEnt = new ModuleEntry(ArrayType.Module, token); ret = ArrayType; index = _types.Count; _indices[hnd] = index; _typeEntry[modEnt] = index; _types.Add(ret); Debug.Assert(_types[index] == ret); } else { // No, so we'll have to construct it. ulong moduleAddr = DesktopRuntime.GetModuleForMT(hnd.MethodTable); DesktopModule module = DesktopRuntime.GetModule(moduleAddr); uint token = DesktopRuntime.GetMetadataToken(mt); bool isFree = mt == DesktopRuntime.FreeMethodTable; if (token == 0xffffffff && !isFree) { return(null); } // Dynamic functions/modules uint tokenEnt = token; if (!isFree && (module == null || module.IsDynamic)) { tokenEnt = (uint)mt; } ModuleEntry modEnt = new ModuleEntry(module, tokenEnt); if (ret == null) { IMethodTableData mtData = DesktopRuntime.GetMethodTableData(mt); if (mtData == null) { return(null); } ret = new DesktopHeapType(() => GetTypeName(hnd, module, token), module, token, mt, mtData, this) { ComponentType = componentType }; index = _types.Count; ((DesktopHeapType)ret).SetIndex(index); _indices[hnd] = index; _typeEntry[modEnt] = index; _types.Add(ret); Debug.Assert(_types[index] == ret); } } if (obj != 0 && ret.ComponentType == null && ret.IsArray) { ret.ComponentType = TryGetComponentType(obj, cmt); } return(ret); }
private ClrType ConstructObjectType(ulong eeType) { IMethodTableData mtData = NativeRuntime.GetMethodTableData(eeType); if (mtData == null) { return(null); } ulong componentType = mtData.ElementTypeHandle; bool isArray = componentType != 0; // EEClass is the canonical method table. I stuffed the pointer there instead of creating a new property. ulong canonType = isArray ? componentType : mtData.EEClass; if (!isArray && canonType != 0) { int index; if (!isArray && _indices.TryGetValue(canonType, out index)) { _indices[eeType] = index; // Link the original eeType to its canonical GCHeapType. return(_types[index]); } ulong tmp = eeType; eeType = canonType; canonType = tmp; } NativeModule module = FindContainingModule(eeType); if (module == null && canonType != 0) { module = FindContainingModule(canonType); } string name = null; if (module != null) { Debug.Assert(module.ImageBase < eeType); PdbInfo pdb = module.Pdb; ISymbolResolver resolver; if (pdb != null) { if (!_resolvers.TryGetValue(module, out resolver)) { _resolvers[module] = resolver = _symProvider.GetSymbolResolver(pdb.FileName, pdb.Guid, pdb.Revision); } name = resolver == null ? null : resolver.GetSymbolNameByRVA((uint)(eeType - module.ImageBase)); } } if (name == null) { string moduleName = module != null?Path.GetFileNameWithoutExtension(module.FileName) : "UNKNWON"; name = string.Format("{0}_{1:x}", moduleName, eeType); } int len = name.Length; if (name.EndsWith("::`vftable'")) { len -= 11; } int i = name.IndexOf('!') + 1; name = name.Substring(i, len - i); if (isArray) { name += "[]"; } if (module == null) { module = _mrtModule; } NativeType type = new NativeType(this, _types.Count, module, name, eeType, mtData); _indices[eeType] = _types.Count; if (!isArray) { _indices[canonType] = _types.Count; } _types.Add(type); return(type); }
internal override ClrType GetTypeByMethodTable(ulong mt, ulong _, ulong obj) { if (mt == 0) { return(null); } ClrType ret = null; // See if we already have the type. if (_indices.TryGetValue(mt, out int index)) { ret = _types[index]; } else { // No, so we'll have to construct it. ulong moduleAddr = DesktopRuntime.GetModuleForMT(mt); DesktopModule module = DesktopRuntime.GetModule(moduleAddr); uint token = DesktopRuntime.GetMetadataToken(mt); bool isFree = mt == DesktopRuntime.FreeMethodTable; if (token == 0xffffffff && !isFree) { return(null); } // Dynamic functions/modules uint tokenEnt = token; if (!isFree && (module == null || module.IsDynamic)) { tokenEnt = unchecked ((uint)mt); } ModuleEntry modEnt = new ModuleEntry(module, tokenEnt); if (ret == null) { IMethodTableData mtData = DesktopRuntime.GetMethodTableData(mt); if (mtData == null) { return(null); } IMethodTableCollectibleData mtCollectibleData = DesktopRuntime.GetMethodTableCollectibleData(mt); ret = new DesktopHeapType(() => GetTypeName(mt, module, token), module, token, mt, mtData, this, mtCollectibleData); index = _types.Count; _indices[mt] = index; // Arrays share a common token, so it's not helpful to look them up here. if (!ret.IsArray) { _typeEntry[modEnt] = index; } _types.Add(ret); Debug.Assert(_types[index] == ret); } } if (obj != 0 && ret.ComponentType == null && ret.IsArray) { ret.ComponentType = TryGetComponentType(obj, 0); } return(ret); }
internal DesktopHeapType(string typeName, DesktopModule module, uint token, ulong mt, IMethodTableData mtData, DesktopGCHeap heap, int index) : base(heap, module, token) { m_name = typeName; m_index = index; m_handle = mt; Shared = mtData.Shared; m_parent = mtData.Parent; m_baseSize = mtData.BaseSize; m_componentSize = mtData.ComponentSize; m_containsPointers = mtData.ContainsPointers; m_hasMethods = mtData.NumMethods > 0; }
private ClrType ConstructObjectType(ulong eeType) { IMethodTableData mtData = NativeRuntime.GetMethodTableData(eeType); if (mtData == null) { return(null); } ulong componentType = mtData.ElementTypeHandle; bool isArray = componentType != 0; // EEClass is the canonical method table. I stuffed the pointer there instead of creating a new property. ulong canonType = isArray ? componentType : mtData.EEClass; if (!isArray && canonType != 0) { int index; if (!isArray && _indices.TryGetValue(canonType, out index)) { _indices[eeType] = index; // Link the original eeType to its canonical GCHeapType. return(_types[index]); } ulong tmp = eeType; eeType = canonType; canonType = tmp; } string name = NativeRuntime.ResolveSymbol(eeType); if (string.IsNullOrEmpty(name)) { name = NativeRuntime.ResolveSymbol(canonType); if (name == null) { name = string.Format("unknown type {0:x}", eeType); } } int len = name.Length; if (name.EndsWith("::`vftable'")) { len -= 11; } int i = name.IndexOf('!') + 1; name = name.Substring(i, len - i); if (isArray) { name += "[]"; } NativeModule module = FindContainingModule(eeType); if (module == null && canonType != 0) { module = FindContainingModule(canonType); } if (module == null) { module = _mrtModule; } NativeType type = new NativeType(this, _types.Count, module, name, eeType, mtData); _indices[eeType] = _types.Count; if (!isArray) { _indices[canonType] = _types.Count; } _types.Add(type); return(type); }
internal DesktopHeapType(Func <string> typeNameFactory, DesktopModule module, uint token, ulong mt, IMethodTableData mtData, DesktopGCHeap heap) : base(mt, heap, module, token) { _name = new Lazy <string>(typeNameFactory); Shared = mtData.Shared; _parent = mtData.Parent; _baseSize = mtData.BaseSize; _componentSize = mtData.ComponentSize; _containsPointers = mtData.ContainsPointers; _hasMethods = mtData.NumMethods > 0; }