public ClrmdPrimitiveType(ITypeHelpers helpers, ClrModule module, ClrHeap heap, ClrElementType type) { Module = module; ClrObjectHelpers = helpers.ClrObjectHelpers; Heap = heap; ElementType = type; }
public MDValue(object value, ClrElementType cet) { m_value = value; m_cet = cet; if (m_value == null) { m_cet = ClrElementType.Unknown; } switch (m_cet) { case ClrElementType.NativeUInt: // native unsigned int case ClrElementType.Pointer: case ClrElementType.FunctionPointer: m_cet = ClrElementType.UInt64; break; case ClrElementType.String: if (m_value == null) { m_cet = ClrElementType.Unknown; } break; case ClrElementType.Class: case ClrElementType.Array: case ClrElementType.SZArray: m_cet = ClrElementType.Object; break; } }
public void GetArrayElementValue(ulong objRef, int index, out IMDValue ppValue) { object value = m_type.GetArrayElementValue(objRef, index); ClrElementType elementType = m_type.ArrayComponentType != null ? m_type.ArrayComponentType.ElementType : ClrElementType.Unknown; ppValue = new MDValue(value, elementType); }
public string GetEnumString(object valObj, ClrElementType enumElem) { long val = ConvertToLong(valObj, enumElem); string name = GetEnumName(val); return(val.ToString() + " " + name); }
private ulong GetFieldAddress(string fieldName, ClrElementType element, string typeName, out ClrType type) { if (IsNull) { throw new NullReferenceException(); } type = Type; ClrInstanceField field = type.GetFieldByName(fieldName); if (field == null) { throw new ArgumentException($"Type '{type.Name}' does not contain a field named '{fieldName}'"); } if (field.ElementType != element) { throw new InvalidOperationException($"Field '{type.Name}.{fieldName}' is not of type '{typeName}'."); } ulong address = ClrRuntime.IsObjectReference(ElementType) ? Object : Address; address = field.GetAddress(address, Interior); return(address); }
public string GetEnumString(ulong addr, ClrType clrType, ClrElementType enumElem) { long val = GetEnumValue(addr, clrType, enumElem); string name = GetEnumName(val); return(val.ToString() + " " + name); }
public ClrPrimitiveValue(object value, ClrElementType type) { if (value == null) throw new ArgumentNullException("value"); m_value = value; m_type = type; }
public CorDebugValue(RuntimeBase runtime, ICorDebug.ICorDebugValue value) : base(runtime) { _value = value; ICorDebug.CorElementType el; value.GetType(out el); _elementType = (ClrElementType)el; }
public static void AddElemType(ElementTypeCount[] ary, ClrElementType tp, int typeId) { if (tp == ClrElementType.Unknown) { return; } int ndx = (int)tp; ary[ndx]._typeIds.Add(typeId); }
public ClrmdPrimitiveType(ITypeHelpers helpers, ClrModule module, ClrHeap heap, ClrElementType type) { if (helpers is null) throw new ArgumentNullException(nameof(helpers)); ClrObjectHelpers = helpers.ClrObjectHelpers; Module = module ?? throw new ArgumentNullException(nameof(module)); Heap = heap ?? throw new ArgumentNullException(nameof(heap)); ElementType = type; }
public void AddType(int ndx, string name, string reversedName, ClrElementType elem) { Names[ndx] = name; ReversedNames[ndx] = reversedName; ReversedNamesMap[ndx] = ndx; MethodTables[ndx] = Constants.InvalidAddress; ElementTypes[ndx] = elem; MethodTablesMap[ndx] = Constants.InvalidIndex; Bases[ndx] = Constants.InvalidIndex; }
public ClrPrimitiveValue(object value, ClrElementType type) { if (value == null) { throw new ArgumentNullException("value"); } m_value = value; m_type = type; }
public DesktopPointerType(DesktopGCHeap heap, DesktopBaseModule module, ClrElementType eltype, uint token, string nameHint) : base(0, heap, module, token) { ElementType = ClrElementType.Pointer; _pointerElement = eltype; if (nameHint != null) { BuildName(nameHint); } }
public ClrtType(string name, ulong mthdTbl, ClrElementType elem, string baseName, int id) { Name = name; MthdTbl = mthdTbl; Id = id; Element = elem; BaseName = baseName; FieldTypeNames = StaticFieldTypeNames = null; FieldNameIds = StaticFieldNameIds = InterfaceNameIds = Utils.EmptyArray <int> .Value; FieldMts = StaticFieldMts = Utils.EmptyArray <ulong> .Value; }
public DesktopArrayType(DesktopGCHeap heap, DesktopBaseModule module, ClrElementType eltype, int ranks, uint token, string nameHint) : base(0, heap, module, token) { ElementType = ClrElementType.Array; _arrayElement = eltype; _ranks = ranks; if (nameHint != null) { BuildName(nameHint); } }
public bool PeekElemType(out ClrElementType etype) { if (PeekElemType(out int e)) { etype = (ClrElementType)e; return(true); } etype = ClrElementType.Unknown; return(false); }
internal static int GetSize(BaseDesktopHeapType type, ClrElementType cet) { // todo: What if we have a struct which is not fully constructed (null MT, // null type) and need to get the size of the field? switch (cet) { case ClrElementType.Struct: if (type == null) { return(1); } return(type.BaseSize); case ClrElementType.Int8: case ClrElementType.UInt8: case ClrElementType.Boolean: return(1); case ClrElementType.Float: case ClrElementType.Int32: case ClrElementType.UInt32: return(4); case ClrElementType.Double: // double case ClrElementType.Int64: case ClrElementType.UInt64: return(8); case ClrElementType.String: case ClrElementType.Class: case ClrElementType.Array: case ClrElementType.SZArray: case ClrElementType.Object: case ClrElementType.NativeInt: // native int case ClrElementType.NativeUInt: // native unsigned int case ClrElementType.Pointer: case ClrElementType.FunctionPointer: case ClrElementType.Unknown: case ClrElementType.Var: if (type == null) { return(IntPtr.Size); // todo: fixme } return((int)type.DesktopHeap.PointerSize); case ClrElementType.UInt16: case ClrElementType.Int16: case ClrElementType.Char: // u2 return(2); } throw new Exception("Unexpected element type."); }
private static void CheckField(ClrType type, string fieldName, ClrElementType element, string typeName, int size) { ClrInstanceField field = type.GetFieldByName(fieldName); Assert.NotNull(field); Assert.NotNull(field.Type); Assert.Equal(element, field.ElementType); Assert.Equal(typeName, field.Type.Name); Assert.Equal(size, field.Size); }
internal static Type GetTypeForElementType(ClrElementType type) { switch (type) { case ClrElementType.Boolean: return(typeof(bool)); case ClrElementType.Char: return(typeof(char)); case ClrElementType.Double: return(typeof(double)); case ClrElementType.Float: return(typeof(float)); case ClrElementType.Pointer: case ClrElementType.NativeInt: case ClrElementType.FunctionPointer: return(typeof(IntPtr)); case ClrElementType.NativeUInt: return(typeof(UIntPtr)); case ClrElementType.Int16: return(typeof(short)); case ClrElementType.Int32: return(typeof(int)); case ClrElementType.Int64: return(typeof(long)); case ClrElementType.Int8: return(typeof(sbyte)); case ClrElementType.UInt16: return(typeof(ushort)); case ClrElementType.UInt32: return(typeof(uint)); case ClrElementType.UInt64: return(typeof(ulong)); case ClrElementType.UInt8: return(typeof(byte)); default: return(null); } }
internal static string GetFuncName(ClrElementType elementType) { switch (elementType) { case ClrElementType.Boolean: return(nameof(_bool)); case ClrElementType.Double: return(nameof(_double)); case ClrElementType.Float: return(nameof(_float)); case ClrElementType.Char: return(nameof(_char)); case ClrElementType.Int16: return(nameof(_short)); case ClrElementType.Int32: return(nameof(_int)); case ClrElementType.Int64: return(nameof(_long)); case ClrElementType.Int8: return(nameof(_byte)); case ClrElementType.String: return(nameof(_string)); case ClrElementType.UInt16: return(nameof(_ushort)); case ClrElementType.UInt32: return(nameof(_uint)); case ClrElementType.UInt64: return(nameof(_ulong)); case ClrElementType.Pointer: case ClrElementType.NativeInt: case ClrElementType.NativeUInt: return(nameof(_ptr)); default: return(nameof(_obj)); } }
public void AddRefs(int typeId, int baseId, ClrElementType elem, int staticFldCnt, int fldCnt) { Debug.Assert(typeId >= 0); lock (_lock) { if (_fieldCounts.Length <= typeId) { var newSize = _fieldCounts.Length == 0 ? MaxRefCnt : _fieldCounts.Length + _fieldCounts.Length / 2; ResizeRefs(newSize); Debug.Assert(_fieldCounts.Length > typeId); } _baseTypeAndElementIds[typeId] = ((uint)elem << 24) | (uint)baseId; _fieldCounts[typeId] = (uint)staticFldCnt << 16 | (uint)fldCnt; } }
private ClrType TryBuildType(ClrHeap heap) { var runtime = heap.Runtime; var domains = runtime.AppDomains; ClrType[] types = new ClrType[domains.Count]; ClrElementType elType = ElementType; if (ClrRuntime.IsPrimitive(elType) || elType == ClrElementType.String) { return(((DesktopGCHeap)heap).GetBasicType(elType)); } int count = 0; foreach (var domain in domains) { object value = GetValue(domain); if (value != null && value is ulong && ((ulong)value != 0)) { types[count++] = heap.GetObjectType((ulong)value); } } int depth = int.MaxValue; ClrType result = null; for (int i = 0; i < count; ++i) { ClrType curr = types[i]; if (curr == result || curr == null) { continue; } int nextDepth = GetDepth(curr); if (nextDepth < depth) { result = curr; depth = nextDepth; } } return(result); }
private ulong GetFieldAddress(string fieldName, ClrElementType element, string typeName) { ClrInstanceField field = Type.GetFieldByName(fieldName); if (field == null) { throw new ArgumentException($"Type '{Type.Name}' does not contain a field named '{fieldName}'"); } if (field.ElementType != element) { throw new InvalidOperationException($"Field '{Type.Name}.{fieldName}' is not of type '{typeName}'."); } ulong address = field.GetAddress(Address, _interior); return(address); }
private ulong GetFieldAddress(string fieldName, ClrElementType element, string typeName) { ClrInstanceField field = _type.GetFieldByName(fieldName); if (field == null) { throw new ArgumentException(String.Format("Type '{0}' does not contain a field named '{1}'", _type.Name, fieldName)); } if (field.ElementType != element) { throw new InvalidOperationException(String.Format("Field '{0}.{1}' is not of type '{2}'.", _type.Name, fieldName, typeName)); } ulong address = field.GetAddress(_address, _interior); return(address); }
public EnumValues(ClrType type) { Debug.Assert(type.IsEnum); enumNames = type.GetEnumNames().ToArray(); enumValues = new long[enumNames.Length]; enumKind = type.GetEnumElementType(); for (int i = 0, icnt = enumNames.Length; i < icnt; ++i) { object obj; if (type.TryGetEnumValue(enumNames[i], out obj)) { enumValues[i] = ConvertToLong(obj, enumKind); } else { enumValues[i] = InvalidEnumValue; } } }
/// <summary> /// Retrieves a field from this value. /// </summary> /// <param name="name">The name of the field.</param> /// <returns>A ClrValue representing this field.</returns> public virtual ClrValue GetField(string name) { ClrElementType el = ElementType; if (ClrRuntime.IsPrimitive(el)) { // Primitives only have one field, named m_value. if (name != "m_value") { throw new ArgumentException(string.Format("Field '{0}' does not exist in type '{1}'.", name, Type.Name)); } // Getting m_value is the same as this ClrValue... return(this); } if (ClrRuntime.IsObjectReference(el) || !Interior) { return(AsObject().GetField(name)); } Debug.Assert(ClrRuntime.IsValueClass(el)); ulong address = Address; if (address == 0) { throw new NullReferenceException(); } ClrType type = Type; ClrInstanceField field = type.GetFieldByName(name); if (field == null) { throw new ArgumentException(string.Format("Field '{0}' does not exist in type '{1}'.", name, Type.Name)); } ulong result = field.GetAddress(address, Interior); return(new ClrValueImpl(_runtime, result, field)); }
internal override ulong GetThreadStaticPointer(ulong thread, ClrElementType type, uint offset, uint moduleId, bool shared) { ulong addr = offset; if (!_sos.GetThreadLocalModuleData(thread, moduleId, out ThreadLocalModuleData data)) { return(0); } if (type.IsObjectReference() || type.IsValueClass()) { addr += data.GCStaticDataStart; } else { addr += data.NonGCStaticDataStart; } return(addr); }
public override object GetValue(ClrAppDomain appDomain, bool convertStrings = true) { if (!HasSimpleValue) { return(null); } ulong addr = GetAddress(appDomain); if (ElementType == ClrElementType.String) { object val = _containingType.DesktopHeap.GetValueAtAddress(ClrElementType.Object, addr); Debug.Assert(val == null || val is ulong); if (val == null || !(val is ulong)) { return(convertStrings ? null : (object)(ulong)0); } addr = (ulong)val; if (!convertStrings) { return(addr); } } // Structs are stored as objects. ClrElementType elementType = ElementType; if (elementType == ClrElementType.Struct) { elementType = ClrElementType.Object; } if (elementType == ClrElementType.Object && addr == 0) { return((ulong)0); } return(_containingType.DesktopHeap.GetValueAtAddress(elementType, addr)); }
public void ComponentTypeEventuallyFilledTest() { // https://github.com/microsoft/clrmd/issues/108 // Ensure that a previously created type with a erronous null ComponentType eventually // gets its ComponentType set. using DataTarget dt = TestTargets.Types.LoadFullDump(); using ClrRuntime runtime = dt.ClrVersions.Single().CreateRuntime(); ClrType fooType = runtime.GetModule(ModuleName).GetTypeByName("Types"); ClrStaticField cq = fooType.GetStaticFieldByName("s_cq"); Assert.NotNull(cq); ClrInstanceField m_head = cq.Type.GetFieldByName("m_head"); ClrInstanceField m_array = m_head.Type.GetFieldByName("m_array"); bool hasSimpleValue = m_array.HasSimpleValue; ClrElementType elementType = m_array.ElementType; ClrType componentType = m_array.Type.ComponentType; // If this assert fails, remove the test. This value is null because currently CLR's // debugging layer doesn't tell us the component type of an array. If we eventually // fix that issue, we would return a non-null m_array.Type.ComponentType, causing // this test to fail but the underlying issue would be fixed. Assert.Null(componentType); ClrObject m_arrayObj = cq.ReadObject().GetObjectField("m_head").GetObjectField("m_array"); // Ensure we are looking at the same ClrType if (dt.CacheOptions.CacheTypes) { Assert.Same(m_array.Type, m_arrayObj.Type); } else { Assert.Equal(m_array.Type, m_arrayObj.Type); } // Assert that we eventually filled in ComponentType after we got a real object for the type Assert.NotNull(m_arrayObj.Type.ComponentType); }
public static ElementTypeCount[] LoadMap(string path, out string error) { error = null; BinaryReader br = null; try { ElementTypeCount[] ary = CreateElemTypeArray(true); br = new BinaryReader(File.Open(path, FileMode.Open)); var acnt = br.ReadInt32(); Debug.Assert(acnt == ary.Length); for (int i = 0; i < acnt; ++i) { ClrElementType et = (ClrElementType)br.ReadInt32(); Debug.Assert(ary[i].Type == et); ary[i].Count = br.ReadInt32(); var typeIdCount = br.ReadInt32(); if (typeIdCount > 0) { ary[i]._typeIds = new List <int>(typeIdCount); for (int j = 0; j < typeIdCount; ++j) { var tid = br.ReadInt32(); ary[i]._typeIds.Add(tid); } } } br.Close(); br = null; return(ary); } catch (Exception ex) { Utils.GetExceptionErrorString(ex); return(null); } finally { br?.Close(); } }
public override object GetArrayElementValue(ulong objRef, int index) { ulong addr = GetArrayElementAddress(objRef, index); if (addr == 0) { return(null); } ClrElementType cet = ClrElementType.Unknown; var componentType = this.ComponentType; if (componentType != null) { cet = componentType.ElementType; } else { // Slow path, we need to get the element type of the array. IObjectData data = DesktopHeap.DesktopRuntime.GetObjectData(objRef); if (data == null) { return(null); } cet = data.ElementType; } if (cet == ClrElementType.Unknown) { return(null); } if (cet == ClrElementType.String && !DesktopHeap.MemoryReader.ReadPtr(addr, out addr)) { return(null); } return(DesktopHeap.GetValueAtAddress(cet, addr)); }
internal static string GetFuncName(ClrElementType elementType) { switch(elementType) { case ClrElementType.Boolean: return nameof(_bool); case ClrElementType.Double: return nameof(_double); case ClrElementType.Float: return nameof(_float); case ClrElementType.Char: return nameof(_char); case ClrElementType.Int16: return nameof(_short); case ClrElementType.Int32: return nameof(_int); case ClrElementType.Int64: return nameof(_long); case ClrElementType.Int8: return nameof(_byte); case ClrElementType.String: return nameof(_string); case ClrElementType.UInt16: return nameof(_ushort); case ClrElementType.UInt32: return nameof(_uint); case ClrElementType.UInt64: return nameof(_ulong); case ClrElementType.Pointer: case ClrElementType.NativeInt: case ClrElementType.NativeUInt: return nameof(_ptr); default: return nameof(_obj); } }
public DesktopPointerType(DesktopGCHeap heap, DesktopBaseModule module, ClrElementType eltype, uint token, string nameHint) : base(heap, module, token) { ElementType = ClrElementType.Pointer; _pointerElement = eltype; if (nameHint != null) BuildName(nameHint); }
internal abstract ulong GetThreadStaticPointer(ulong thread, ClrElementType type, uint offset, uint moduleId, bool shared);
internal override ulong GetThreadStaticPointer(ulong thread, ClrElementType type, uint offset, uint moduleId, bool shared) { // TODO return 0; }
internal override void SetElementType(ClrElementType value) { if (m_elementType == ClrElementType.Unknown && value != ClrElementType.Class) m_elementType = value; }
internal override void SetElementType(ClrElementType ElementType) { }
public MDValue(object value, ClrElementType cet) { m_value = value; m_cet = cet; if (m_value == null) m_cet = ClrElementType.Unknown; switch (m_cet) { case ClrElementType.NativeUInt: // native unsigned int case ClrElementType.Pointer: case ClrElementType.FunctionPointer: m_cet = ClrElementType.UInt64; break; case ClrElementType.String: if (m_value == null) m_cet = ClrElementType.Unknown; break; case ClrElementType.Class: case ClrElementType.Array: case ClrElementType.SZArray: m_cet = ClrElementType.Object; break; } }
internal abstract void SetElementType(ClrElementType ElementType);
internal static int GetSize(BaseDesktopHeapType type, ClrElementType cet) { // todo: What if we have a struct which is not fully constructed (null MT, // null type) and need to get the size of the field? switch (cet) { case ClrElementType.Struct: if (type == null) return 1; return type.BaseSize; case ClrElementType.Int8: case ClrElementType.UInt8: case ClrElementType.Boolean: return 1; case ClrElementType.Float: case ClrElementType.Int32: case ClrElementType.UInt32: return 4; case ClrElementType.Double: // double case ClrElementType.Int64: case ClrElementType.UInt64: return 8; case ClrElementType.String: case ClrElementType.Class: case ClrElementType.Array: case ClrElementType.SZArray: case ClrElementType.Object: case ClrElementType.NativeInt: // native int case ClrElementType.NativeUInt: // native unsigned int case ClrElementType.Pointer: case ClrElementType.FunctionPointer: if (type == null) return IntPtr.Size; // todo: fixme return (int)type.DesktopHeap.PointerSize; case ClrElementType.UInt16: case ClrElementType.Int16: case ClrElementType.Char: // u2 return 2; } throw new Exception("Unexpected element type."); }
internal static bool IsObjectReference(ClrElementType cet) { return cet == ClrElementType.String || cet == ClrElementType.Class || cet == ClrElementType.Array || cet == ClrElementType.SZArray || cet == ClrElementType.Object; }
internal static Type GetTypeForElementType(ClrElementType type) { switch (type) { case ClrElementType.Boolean: return typeof(bool); case ClrElementType.Char: return typeof(char); case ClrElementType.Double: return typeof(double); case ClrElementType.Float: return typeof(float); case ClrElementType.Pointer: case ClrElementType.NativeInt: case ClrElementType.FunctionPointer: return typeof(IntPtr); case ClrElementType.NativeUInt: return typeof(UIntPtr); case ClrElementType.Int16: return typeof(short); case ClrElementType.Int32: return typeof(int); case ClrElementType.Int64: return typeof(long); case ClrElementType.Int8: return typeof(sbyte); case ClrElementType.UInt16: return typeof(ushort); case ClrElementType.UInt32: return typeof(uint); case ClrElementType.UInt64: return typeof(ulong); case ClrElementType.UInt8: return typeof(byte); default: return null; } }
public DesktopArrayType(DesktopGCHeap heap, DesktopBaseModule module, ClrElementType eltype, int ranks, uint token, string nameHint) : base(heap, module, token) { ElementType = ClrElementType.Array; _arrayElement = eltype; _ranks = ranks; if (nameHint != null) BuildName(nameHint); }
internal static bool IsPrimitive(ClrElementType cet) { return cet >= ClrElementType.Boolean && cet <= ClrElementType.Double || cet == ClrElementType.NativeInt || cet == ClrElementType.NativeUInt || cet == ClrElementType.Pointer || cet == ClrElementType.FunctionPointer; }
internal override ulong GetThreadStaticPointer(ulong thread, ClrElementType type, uint offset, uint moduleId, bool shared) { ulong addr = offset; V45ThreadLocalModuleData data; if (_sos.GetThreadLocalModuleData(thread, moduleId, out data) < 0) return 0; if (IsObjectReference(type) || IsValueClass(type)) addr += data.pGCStaticDataStart; else addr += data.pNonGCStaticDataStart; return addr; }
internal static bool IsValueClass(ClrElementType cet) { return cet == ClrElementType.Struct; }