TargetType ReadType(TargetMemoryAccess memory, MonoTypeEnum type, TargetAddress data) { switch (type) { case MonoTypeEnum.MONO_TYPE_BOOLEAN: return BuiltinTypes.BooleanType; case MonoTypeEnum.MONO_TYPE_CHAR: return BuiltinTypes.CharType; case MonoTypeEnum.MONO_TYPE_I1: return BuiltinTypes.SByteType; case MonoTypeEnum.MONO_TYPE_U1: return BuiltinTypes.ByteType; case MonoTypeEnum.MONO_TYPE_I2: return BuiltinTypes.Int16Type; case MonoTypeEnum.MONO_TYPE_U2: return BuiltinTypes.UInt16Type; case MonoTypeEnum.MONO_TYPE_I4: return BuiltinTypes.Int32Type; case MonoTypeEnum.MONO_TYPE_U4: return BuiltinTypes.UInt32Type; case MonoTypeEnum.MONO_TYPE_I8: return BuiltinTypes.Int64Type; case MonoTypeEnum.MONO_TYPE_U8: return BuiltinTypes.UInt64Type; case MonoTypeEnum.MONO_TYPE_R4: return BuiltinTypes.SingleType; case MonoTypeEnum.MONO_TYPE_R8: return BuiltinTypes.DoubleType; case MonoTypeEnum.MONO_TYPE_STRING: return BuiltinTypes.StringType; case MonoTypeEnum.MONO_TYPE_OBJECT: return BuiltinTypes.ObjectType; case MonoTypeEnum.MONO_TYPE_I: return BuiltinTypes.IntType; case MonoTypeEnum.MONO_TYPE_U: return BuiltinTypes.UIntType; case MonoTypeEnum.MONO_TYPE_VOID: return BuiltinTypes.VoidType; case MonoTypeEnum.MONO_TYPE_PTR: { TargetType target_type = ReadType (memory, data); return new MonoPointerType (target_type); } case MonoTypeEnum.MONO_TYPE_VALUETYPE: case MonoTypeEnum.MONO_TYPE_CLASS: return LookupMonoClass (memory, data); case MonoTypeEnum.MONO_TYPE_SZARRAY: { TargetType etype = ReadMonoClass (memory, data); return new MonoArrayType (etype, 1); } case MonoTypeEnum.MONO_TYPE_ARRAY: { TargetAddress klass = MetadataHelper.MonoArrayTypeGetClass (memory, data); int rank = MetadataHelper.MonoArrayTypeGetRank (memory, data); MetadataHelper.MonoArrayTypeGetBounds (memory, data); TargetType etype = ReadMonoClass (memory, klass); return new MonoArrayType (etype, rank); } case MonoTypeEnum.MONO_TYPE_GENERICINST: return ReadGenericClass (memory, data, true); case MonoTypeEnum.MONO_TYPE_VAR: case MonoTypeEnum.MONO_TYPE_MVAR: { MetadataHelper.GenericParamInfo info = MetadataHelper.GetGenericParameter ( memory, data); return new MonoGenericParameterType (this, info.Name); } default: Report.Error ("UNKNOWN TYPE: {0}", type); return null; } }
private object ReadValue(MonoTypeEnum type, long addr) { switch (type) { case MonoTypeEnum.Boolean: return(_view.ReadBool(addr)); case MonoTypeEnum.U1: return(_view.ReadByte(addr)); case MonoTypeEnum.I1: return(_view.ReadSByte(addr)); case MonoTypeEnum.I2: return(_view.ReadShort(addr)); case MonoTypeEnum.U2: return(_view.ReadUshort(addr)); case MonoTypeEnum.Char: return((char)_view.ReadUshort(addr)); case MonoTypeEnum.I: case MonoTypeEnum.I4: return(_view.ReadInt(addr)); case MonoTypeEnum.U: case MonoTypeEnum.U4: return(_view.ReadUint(addr)); case MonoTypeEnum.I8: return(_view.ReadLong(addr)); case MonoTypeEnum.U8: return(_view.ReadUlong(addr)); case MonoTypeEnum.R4: return(_view.ReadFloat(addr)); case MonoTypeEnum.R8: return(_view.ReadDouble(addr)); case MonoTypeEnum.Szarray: addr = _view.ReadUint(addr); // deref object var vt = _view.ReadUint(addr); var pArrClass = _view.ReadUint(vt); var arrClass = new MonoClass(_view, pArrClass); var elClass = new MonoClass(_view, _view.ReadUint(pArrClass)); var count = _view.ReadInt(addr + 12); var start = addr + 16; var result = new object[count]; for (var i = 0; i < count; i++) { var ea = start + i * arrClass.Size; if (elClass.IsValueType) { if (elClass.ByvalArg.Type == MonoTypeEnum.ValueType) { result[i] = new MonoStruct(_view, elClass, (uint)ea); } else if (elClass.ByvalArg.Type == MonoTypeEnum.GenericInst) { result[i] = new MonoStruct(_view, elClass, (uint)ea); } else { result[i] = ReadValue(elClass.ByvalArg.Type, ea); } } else if (elClass.ByvalArg.Type == MonoTypeEnum.String) { result[i] = ReadValue(elClass.ByvalArg.Type, ea); } else { var po = _view.ReadUint(ea); if (po == 0) { result[i] = null; } else { result[i] = new MonoObject(_view, po); } } } return(result); case MonoTypeEnum.String: var pArr = _view.ReadUint(addr); if (pArr == 0) { return(null); } var strlen = _view.ReadInt(pArr + 8); if (strlen == 0) { return(string.Empty); } var buf = new byte[2 * strlen]; _view.ReadBytes(buf, 0, strlen * 2, pArr + 12); return(Encoding.Unicode.GetString(buf)); default: throw new Exception($"{type} not implemented"); } }
public ProfileData ReadAllData(Stream stream) { byte[] buf = new byte [16]; int len = stream.Read(buf, 0, MAGIC.Length); if (len != MAGIC.Length) { throw new IOException("Input file is too small."); } var magic = new String(Encoding.UTF8.GetChars(buf, 0, MAGIC.Length)); if (magic != MAGIC) { throw new IOException("Input file is not a AOT profiler output file."); } // Profile files are not expected to be large, so reading them is ok len = (int)stream.Length - MAGIC.Length; data = new byte [len]; pos = 0; int count = stream.Read(data, 0, len); if (count != len) { throw new IOException("Can't read profile file."); } int version = ReadInt(); int expected_version = (MAJOR_VERSION << 16) | MINOR_VERSION; if (version != expected_version) { throw new IOException(String.Format("Expected file version 0x{0:x}, got 0x{1:x}.", expected_version, version)); } var modules = new List <ModuleRecord> (); var types = new List <TypeRecord> (); var methods = new List <MethodRecord> (); Dictionary <int, ProfileRecord> records = new Dictionary <int, ProfileRecord> (); while (true) { RecordType rtype = (RecordType)data [pos]; pos++; if (rtype == RecordType.NONE) { break; } int id = ReadInt(); switch (rtype) { case RecordType.IMAGE: { string name = ReadString(); string mvid = ReadString(); var module = new ModuleRecord(id, name, mvid); records [id] = module; modules.Add(module); break; } case RecordType.GINST: { int argc = ReadInt(); TypeRecord[] tr = new TypeRecord [argc]; for (int i = 0; i < argc; ++i) { int type_id = ReadInt(); tr [i] = (TypeRecord)records [type_id]; } var ginst = new GenericInstRecord(id, tr); records [id] = ginst; break; } case RecordType.TYPE: { MonoTypeEnum ttype = (MonoTypeEnum)ReadByte(); switch (ttype) { case MonoTypeEnum.MONO_TYPE_CLASS: { int image_id = ReadInt(); int ginst_id = ReadInt(); string name = ReadString(); GenericInstRecord inst = null; if (ginst_id != -1) { inst = (GenericInstRecord)records [ginst_id]; } var module = (ModuleRecord)records [image_id]; var type = new TypeRecord(id, module, name, inst); types.Add(type); records [id] = type; break; } default: throw new NotImplementedException(); } break; } case RecordType.METHOD: { int class_id = ReadInt(); int ginst_id = ReadInt(); int param_count = ReadInt(); string name = ReadString(); string sig = ReadString(); var type = (TypeRecord)records [class_id]; GenericInstRecord ginst = ginst_id != -1 ? (GenericInstRecord)records [ginst_id] : null; var method = new MethodRecord(id, type, ginst, name, sig, param_count); methods.Add(method); records [id] = method; break; } default: throw new NotImplementedException(rtype.ToString()); } } return(new ProfileData(modules.ToArray(), types.ToArray(), methods.ToArray())); }