Пример #1
0
        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");
            }
        }
Пример #3
0
        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()));
        }