Example #1
0
        internal static MonoEventInfo Create(IMonoStructType klass, int index,
						      Cecil.EventDefinition einfo)
        {
            TargetType type = klass.File.MonoLanguage.LookupMonoType (einfo.EventType);

            bool is_static = false;
            MonoFunctionType add, remove, raise;

            TargetMemberAccessibility accessibility = TargetMemberAccessibility.Private;
            if (einfo.AddMethod != null) {
                add = klass.LookupFunction (einfo.AddMethod);
                is_static = einfo.AddMethod.IsStatic;
                accessibility = MonoMethodInfo.GetAccessibility (einfo.AddMethod);
            } else
                add = null;

            if (einfo.RemoveMethod != null) {
                remove = klass.LookupFunction (einfo.RemoveMethod);
                is_static = einfo.RemoveMethod.IsStatic;
                accessibility = MonoMethodInfo.GetAccessibility (einfo.RemoveMethod);
            } else
                remove = null;

            if (einfo.InvokeMethod != null) {
                raise = klass.LookupFunction (einfo.InvokeMethod);
                is_static = einfo.InvokeMethod.IsStatic;
                accessibility = MonoMethodInfo.GetAccessibility (einfo.InvokeMethod);
            } else
                raise = null;

            return new MonoEventInfo (
                klass, index, einfo, type, is_static, accessibility, add, remove, raise);
        }
Example #2
0
        public MonoClassType(MonoSymbolFile file, Cecil.TypeDefinition type)
            : base(file.MonoLanguage, TargetObjectKind.Class)
        {
            this.type = type;
            this.file = file;

            struct_type = new MonoStructType (file, this, type);

            if (type.GenericParameters.Count > 0) {
                StringBuilder sb = new StringBuilder (type.FullName);
                sb.Append ('<');
                for (int i = 0; i < type.GenericParameters.Count; i++) {
                    if (i > 0)
                        sb.Append (',');
                    sb.Append (type.GenericParameters [i].Name);
                }
                sb.Append ('>');
                full_name = sb.ToString ();
            } else
                full_name = type.FullName;

            DebuggerBrowsableState? browsable_state;
            MonoSymbolFile.CheckCustomAttributes (type,
                                  out browsable_state,
                                  out debugger_display,
                                  out type_proxy,
                                  out is_compiler_generated);
        }
Example #3
0
        private MonoStringType(MonoSymbolFile file, Cecil.TypeDefinition typedef,
					int object_size, int size)
            : base(file, typedef, "string", FundamentalKind.String, size)
        {
            this.ObjectSize = object_size;
            this.CreateString = file.MonoLanguage.MonoDebuggerInfo.CreateString;
        }
Example #4
0
        public MonoEnumType(MonoSymbolFile file, Cecil.TypeDefinition type)
            : base(file.MonoLanguage)
        {
            this.type = type;
            this.file = file;

            class_type = new MonoClassType (file, type);
        }
Example #5
0
        public MonoEnumInfo(MonoEnumType type, TargetType field_type, int index, int pos,
				     Cecil.FieldDefinition finfo)
            : base(field_type, finfo.Name, index, finfo.IsStatic,
				MonoFieldInfo.GetAccessibility (finfo),
				pos, 0, finfo.HasConstant)
        {
            FieldInfo = finfo;
        }
Example #6
0
        public Type FindType(Cecil.TypeReference typeRef)
        {
            var type = resolver.FindType(typeRef);
            if (type == null) {
                throw new Exception(String.Format("Cannot resolve type {0}", typeRef));
            }

            return type;
        }
Example #7
0
        public static void InstrumentAssembly(Cecil.AssemblyDefinition assembly)
        {
            var typeCount = assembly.Modules.Sum(mod => mod.Types.Count);

            foreach (var module in assembly.Modules) {
                foreach (var type in module.Types) {
                    InstrumentType(type);
                }
            }
        }
Example #8
0
        /// <summary>
        /// Find runtime type in current AppDomain based on Cecil.TypeReference.
        /// Do the actual lookup for type
        /// </summary>
        private Type LookupType(Cecil.TypeReference typeDef)
        {
            if (typeDef.IsGenericInstance) {
                var genericTypeDef = (Cecil.GenericInstanceType)typeDef;
                var ourArgs = genericTypeDef.GenericArguments.Select((arg) => {
                    return FindType(arg);
                }).ToArray();

                var ourBaseType = FindType(genericTypeDef.ElementType);
                return ourBaseType.MakeGenericType(ourArgs);
            }

            string assemblyName;
            try {
                assemblyName = typeDef.AssemblyQualifiedName;
                assemblyName = assemblyName.Substring(assemblyName.IndexOf(", ") + 2);
                //map our donor assembly to original loaded assembly
                assemblyName = assemblyName.Replace("Assembly-HotPatch-CSharp", "Assembly-CSharp");
            }
            catch (Mono.Cecil.AssemblyResolutionException e) {
                //wtf. cecil bug?
                //sometimes happens with assemblies like System
                assemblyName = e.AssemblyReference.FullName;
            }

            var ourAssembly = AppDomain.CurrentDomain.GetAssemblies().FirstOrDefault(
                (assembly) => assemblyName.StartsWith(assembly.FullName));

            if (ourAssembly == null) {
                return null;
            }

            if (typeDef.DeclaringType != null) {
                var parentType = FindType(typeDef.DeclaringType);
                return parentType.GetNestedType(typeDef.Name,
                    Reflection.BindingFlags.NonPublic | Reflection.BindingFlags.Public);
            }

            var typedefName = typeDef.FullName;

            if (typeDef.IsArray) {
                typedefName = typedefName.Replace("[]", "");
            }

            var ourType = ourAssembly.GetTypes().FirstOrDefault((typ) => typ.FullName == typedefName);
            if (ourType == null) {
                return null;
            }

            if (typeDef.IsArray) {
                return ourType.MakeArrayType();
            }

            return ourType;
        }
Example #9
0
        private MonoEventInfo(IMonoStructType klass, int index, Cecil.EventDefinition einfo,
				       TargetType type, bool is_static,
				       TargetMemberAccessibility accessibility, MonoFunctionType add,
				       MonoFunctionType remove, MonoFunctionType raise)
            : base(type, einfo.Name, index, is_static, accessibility, add, remove, raise)
        {
            this.Klass = klass;
            this.AddType = add;
            this.RemoveType = remove;
            this.RaiseType = raise;
        }
Example #10
0
        /// <summary>
        /// Find runtime type in current AppDomain based on Cecil.TypeReference.
        /// </summary>
        /// <param name="typeDef">Cecil type reference.</param>
        /// <returns>Runtime Type.</returns>
        public Type FindType(Cecil.TypeReference typeDef)
        {
            Type cachedType;
            if (typeCache.TryGetValue(typeDef.FullName, out cachedType)) {
                return cachedType;
            }

            var foundType = LookupType(typeDef);
            typeCache[typeDef.FullName] = foundType;
            return foundType;
        }
		public override void Run()
		{
			var redirectMethods = new[]
			{
				"Write",
				"WriteLine"
			};

			SourceDefinition.MainModule.ForEachInstruction((method, instruction) =>
			{
				var mth = instruction.Operand as MethodReference;
				if (mth != null && mth.DeclaringType.FullName == "System.Console")
				{
					if (redirectMethods.Contains(mth.Name))
					{
						var mthReference = this.Resolve(mth);
						if (mthReference != null)
							instruction.Operand = SourceDefinition.MainModule.Import(mthReference);
					}
				}
			});
		}
Example #12
0
        internal MonoFunctionType(IMonoStructType klass, Cecil.MethodDefinition mdef)
            : base(klass.File.MonoLanguage)
        {
            this.klass = klass;
            this.method_info = mdef;
            this.token = MonoDebuggerSupport.GetMethodToken (mdef);
            this.name = GetMethodName (mdef) + MonoSymbolFile.GetMethodSignature (mdef);

            Cecil.TypeReference rtype;
            if (mdef.IsConstructor) {
                rtype = mdef.DeclaringType;
                has_return_type = true;
            } else {
                rtype = mdef.ReturnType.ReturnType;
                has_return_type = rtype.FullName != "System.Void";
            }
            return_type = klass.File.MonoLanguage.LookupMonoType (rtype);

            parameter_types = new TargetType [mdef.Parameters.Count];
            for (int i = 0; i < mdef.Parameters.Count; i++)
                parameter_types [i] = klass.File.MonoLanguage.LookupMonoType (
                    mdef.Parameters[i].ParameterType);
        }
        Ast.Expression Convert(Ast.Expression expr, Cecil.TypeReference actualType, Cecil.TypeReference reqType)
        {
            if (reqType == null || actualType == reqType) {
                return expr;
            } else {
                bool actualIsIntegerOrEnum = TypeAnalysis.IsIntegerOrEnum(actualType);
                bool requiredIsIntegerOrEnum = TypeAnalysis.IsIntegerOrEnum(reqType);

                if (TypeAnalysis.IsBoolean(reqType)) {
                    if (TypeAnalysis.IsBoolean(actualType))
                        return expr;
                    if (actualIsIntegerOrEnum) {
                        return new BinaryOperatorExpression(expr, BinaryOperatorType.InEquality, MakePrimitive(0, actualType));
                    } else {
                        return new BinaryOperatorExpression(expr, BinaryOperatorType.InEquality, new NullReferenceExpression());
                    }
                }
                if (TypeAnalysis.IsBoolean(actualType) && requiredIsIntegerOrEnum) {
                    return new ConditionalExpression {
                        Condition = expr,
                        TrueExpression = MakePrimitive(1, reqType),
                        FalseExpression = MakePrimitive(0, reqType)
                    };
                }
                if (actualIsIntegerOrEnum && requiredIsIntegerOrEnum) {
                    return expr.CastTo(AstBuilder.ConvertType(reqType));
                }
                return expr;
            }
        }
Example #14
0
        static IEnumerable<Cecil.MethodDefinition> GetMethods(Cecil.TypeDefinition type, bool constructor)
        {
            foreach (var method in type.Methods) {
                if (constructor && method.IsConstructor)
                    yield return method;

                if (!constructor && !method.IsConstructor)
                    yield return method;
            }
        }
Example #15
0
 void EmitInstruction(ILGenerator il, OpCode opcode, Cecil.Cil.VariableDefinition operand)
 {
     il.Emit(opcode, operand.Index);
 }
Example #16
0
        public MonoFunctionType LookupFunction(Cecil.MethodDefinition mdef)
        {
            int token = MonoDebuggerSupport.GetMethodToken (mdef);
            if (function_hash == null)
                function_hash = new Dictionary<int,MonoFunctionType> ();
            if (!function_hash.ContainsKey (token)) {
                MonoFunctionType function = new MonoFunctionType (this, mdef);
                function_hash.Add (token, function);
                return function;
            }

            return function_hash [token];
        }
Example #17
0
 internal static TargetMemberAccessibility GetAccessibility(Cecil.MethodDefinition method)
 {
     switch (method.Attributes & Cecil.MethodAttributes.MemberAccessMask) {
     case Cecil.MethodAttributes.Public:
         return TargetMemberAccessibility.Public;
     case Cecil.MethodAttributes.Family:
     case Cecil.MethodAttributes.FamANDAssem:
         return TargetMemberAccessibility.Protected;
     case Cecil.MethodAttributes.Assembly:
     case Cecil.MethodAttributes.FamORAssem:
         return TargetMemberAccessibility.Internal;
     default:
         return TargetMemberAccessibility.Private;
     }
 }
Example #18
0
 public MonoFunctionType LookupFunction(Cecil.MethodDefinition mdef)
 {
     get_methods ();
     return function_hash [mdef];
 }
Example #19
0
 internal static string GetMethodName(Cecil.MethodDefinition mdef)
 {
     Cecil.GenericParameterCollection gen_params = mdef.GenericParameters;
     if ((gen_params == null) || (gen_params.Count == 0))
         return mdef.Name;
     else
         return mdef.Name + "`" + gen_params.Count;
 }
Example #20
0
        public MonoFieldInfo(IMonoStructType type, TargetType field_type, int pos,
				      Cecil.FieldDefinition finfo)
            : base(field_type, finfo.Name, pos, finfo.IsStatic,
				GetAccessibility (finfo), pos, 0, finfo.HasConstant)
        {
            FieldInfo = finfo;

            DebuggerTypeProxyAttribute type_proxy;
            MonoSymbolFile.CheckCustomAttributes (finfo,
                                  out browsable_state,
                                  out debugger_display,
                                  out type_proxy,
                                  out is_compiler_generated);
        }
Example #21
0
        public DynamicMethod RecompileMethod(Cecil.MethodDefinition methodDef)
        {
            Debug.Trace("Recompiling method: {0}", methodDef.FullName);

            var declaringType = FindType(methodDef.DeclaringType);
            var returnType = FindType(methodDef.ReturnType);
            Type[] paramTypes = methodDef.Parameters.Select((paramDef) => {
                return FindType(paramDef.ParameterType);
            }).ToArray();

            if (!methodDef.IsStatic) {
                paramTypes = new Type[] { declaringType }.Concat(paramTypes).ToArray();
            }

            var dynMethod = new DynamicMethod(methodDef.Name, returnType, paramTypes, true);
            ILGenerator il = dynMethod.GetILGenerator();
            dynMethod.InitLocals = methodDef.Body.InitLocals;
            foreach (var variable in methodDef.Body.Variables) {
                var localType = FindType(variable.VariableType);
                Debug.Trace("Declaring local (cecil type: {0}) of type (runtime type: {1})", variable.VariableType, localType);
                il.DeclareLocal(localType);
            }

            var labels = new Dictionary<Cecil.Cil.Instruction, Label>();

            foreach (var inst in methodDef.Body.Instructions) {
                if (inst.Operand != null && inst.Operand.GetType() == typeof(Cecil.Cil.Instruction)) {
                    var opinst = (Cecil.Cil.Instruction)(inst.Operand);
                    labels[opinst] = il.DefineLabel();
                }
            }

            foreach (var inst in Instrument.IterateInstructions(methodDef)) {
                Debug.Trace("Emitting: {0}", inst);

                Label label;
                if (labels.TryGetValue(inst, out label)) {
                    il.MarkLabel(label);
                }

                var ilop = FindOpcode(inst.OpCode);

                if (inst.Operand != null) {
                    var operand = inst.Operand;
                    var operandType = operand.GetType();

                    // Dynamic dispatch implementation:

                    // We have to run different processing code depending on the type of instruction
                    // operand. Visitor pattern cannot be implemented here, because we don't actually
                    // own the classes that are the operands (and some of them are primitive or system
                    // types).

                    // Therefore, dynamic dispatcher is used. Method for each operand type is implemented
                    // in this class, and reflection is used to find correct method to call.

                    // In newer .net versions we would be able to do EmitInstruction(il, ilop, (dynamic)operand),
                    // but the .net version we are targeting (because of Unity compatibility) does not
                    // have `dynamic`.

                    if (operandType == typeof(Cecil.Cil.Instruction)) {
                        //branch location
                        var operandInst = (Cecil.Cil.Instruction)operand;

                        il.Emit(ilop, labels[operandInst]);
                    }
                    else if (primitiveOperandTypes.Contains(operandType)) {
                        //if operand is primitive, call il.Emit directly
                        Reflection.MethodInfo method;
                        if (!EmitPrimitiveCache.TryGetValue(operandType, out method)) {
                            method = typeof(ILGenerator).GetMethod("Emit", new Type[] { typeof(OpCode), operandType });
                            EmitPrimitiveCache[operandType] = method;
                        }

                        if (method == null) {
                            throw new Exception(String.Format("Emit method for primitive type {0} not found.", operandType.Name));
                        }

                        method.Invoke(il, new object[] { ilop, operand });
                    }
                    else {
                        //or else, call our EmitInstruction
                        Reflection.MethodInfo method;
                        if (!EmitInstructionCache.TryGetValue(operandType, out method)) {
                            method = GetType().GetMethod("EmitInstruction",
                                bindingAttr: bflags_all_instance,
                                binder: null,
                                modifiers: null,
                                types: new Type[] { typeof(ILGenerator), typeof(OpCode), operandType });
                            EmitInstructionCache[operandType] = method;
                        }

                        if (method == null) {
                            throw new Exception(String.Format("Don't know what to do with operand {0}", operandType.Name));
                        }

                        method.Invoke(this, new object[] { il, ilop, operand });
                    }
                }
                else {
                    il.Emit(ilop);
                }
            }

            return dynMethod;
        }
Example #22
0
        internal static MonoPropertyInfo Create(IMonoStructType klass, int index,
							 Cecil.PropertyDefinition pinfo)
        {
            TargetType type = klass.File.MonoLanguage.LookupMonoType (pinfo.PropertyType);

            bool is_static = false;
            MonoFunctionType getter, setter;
            TargetMemberAccessibility accessibility = TargetMemberAccessibility.Private;
            if (pinfo.SetMethod != null) {
                setter = klass.LookupFunction (pinfo.SetMethod);
                is_static = pinfo.SetMethod.IsStatic;
                accessibility = MonoMethodInfo.GetAccessibility (pinfo.SetMethod);
            } else
                setter = null;

            if (pinfo.GetMethod != null) {
                getter = klass.LookupFunction (pinfo.GetMethod);
                is_static = pinfo.GetMethod.IsStatic;
                accessibility = MonoMethodInfo.GetAccessibility (pinfo.GetMethod);
            } else
                getter = null;

            return new MonoPropertyInfo (
                type, klass, index, is_static, pinfo, accessibility, getter, setter);
        }
Example #23
0
        private MonoPropertyInfo(TargetType type, IMonoStructType klass, int index,
					  bool is_static, Cecil.PropertyDefinition pinfo,
					  TargetMemberAccessibility accessibility,
					  MonoFunctionType getter, MonoFunctionType setter)
            : base(type, pinfo.Name, index, is_static, accessibility, getter, setter)
        {
            this.Klass = klass;
            this.GetterType = getter;
            this.SetterType = setter;

            bool is_compiler_generated;
            DebuggerTypeProxyAttribute type_proxy;
            MonoSymbolFile.CheckCustomAttributes (pinfo,
                                  out browsable_state,
                                  out debugger_display,
                                  out type_proxy,
                                  out is_compiler_generated);
        }
Example #24
0
        private MonoMethodInfo(IMonoStructType klass, int index, Cecil.MethodDefinition minfo,
					MonoFunctionType type)
            : base(type, MonoFunctionType.GetMethodName (minfo), index,
				minfo.IsStatic, GetAccessibility (minfo), type.FullName)
        {
            FunctionType = type;
        }
        Ast.Expression Convert(Ast.Expression expr, Cecil.TypeReference actualType, Cecil.TypeReference reqType)
        {
            if (actualType == null || reqType == null || TypeAnalysis.IsSameType(actualType, reqType)) {
                return expr;
            } else if (actualType is ByReferenceType && reqType is PointerType && expr is DirectionExpression) {
                return Convert(
                    new UnaryOperatorExpression(UnaryOperatorType.AddressOf, ((DirectionExpression)expr).Expression.Detach()),
                    new PointerType(((ByReferenceType)actualType).ElementType),
                    reqType);
            } else if (actualType is PointerType && reqType is ByReferenceType) {
                expr = Convert(expr, actualType, new PointerType(((ByReferenceType)reqType).ElementType));
                return new DirectionExpression {
                    FieldDirection = FieldDirection.Ref,
                    Expression = new UnaryOperatorExpression(UnaryOperatorType.Dereference, expr)
                };
            } else if (actualType is PointerType && reqType is PointerType) {
                if (actualType.FullName != reqType.FullName)
                    return expr.CastTo(AstBuilder.ConvertType(reqType));
                else
                    return expr;
            } else {
                bool actualIsIntegerOrEnum = TypeAnalysis.IsIntegerOrEnum(actualType);
                bool requiredIsIntegerOrEnum = TypeAnalysis.IsIntegerOrEnum(reqType);

                if (TypeAnalysis.IsBoolean(reqType)) {
                    if (TypeAnalysis.IsBoolean(actualType))
                        return expr;
                    if (actualIsIntegerOrEnum) {
                        return new BinaryOperatorExpression(expr, BinaryOperatorType.InEquality, AstBuilder.MakePrimitive(0, actualType));
                    } else {
                        return new BinaryOperatorExpression(expr, BinaryOperatorType.InEquality, new NullReferenceExpression());
                    }
                }
                if (TypeAnalysis.IsBoolean(actualType) && requiredIsIntegerOrEnum) {
                    return new ConditionalExpression {
                        Condition = expr,
                        TrueExpression = AstBuilder.MakePrimitive(1, reqType),
                        FalseExpression = AstBuilder.MakePrimitive(0, reqType)
                    };
                }

                if (expr is PrimitiveExpression && !requiredIsIntegerOrEnum && TypeAnalysis.IsEnum(actualType))
                {
                    return expr.CastTo(AstBuilder.ConvertType(actualType));
                }

                bool actualIsPrimitiveType = actualIsIntegerOrEnum
                    || actualType.MetadataType == MetadataType.Single || actualType.MetadataType == MetadataType.Double;
                bool requiredIsPrimitiveType = requiredIsIntegerOrEnum
                    || reqType.MetadataType == MetadataType.Single || reqType.MetadataType == MetadataType.Double;
                if (actualIsPrimitiveType && requiredIsPrimitiveType) {
                    return expr.CastTo(AstBuilder.ConvertType(reqType));
                }
                return expr;
            }
        }
Example #26
0
 protected MonoObjectType(MonoSymbolFile file, Cecil.TypeDefinition typedef, int size)
     : base(file.MonoLanguage, "object", size)
 {
     this.file = file;
     this.typedef = typedef;
 }
Example #27
0
 static Ast.Expression Convert(Ast.Expression expr, Cecil.TypeReference reqType)
 {
     if (reqType == null) {
         return expr;
     } else {
         return Convert(expr, reqType.FullName);
     }
 }
Example #28
0
        public MonoClassType(MonoSymbolFile file, Cecil.TypeDefinition typedef,
				      MonoClassInfo class_info)
            : this(file, typedef)
        {
            this.class_info = class_info;
        }
Example #29
0
 public MonoStructType(MonoSymbolFile file, TargetClassType type, Cecil.TypeDefinition typedef)
 {
     this.File = file;
     this.Type = type;
     this.TypeDef = typedef;
 }
Example #30
0
        internal static MonoMethodInfo Create(IMonoStructType klass, int index,
						       Cecil.MethodDefinition minfo)
        {
            MonoFunctionType type = klass.LookupFunction (minfo);
            return new MonoMethodInfo (klass, index, minfo, type);
        }