Beispiel #1
0
        static void Main(string[] args)
        {
            ParseArguments(args);

            Console.WriteLine("[UnsafeUtilityPatcher] Patching assembly : " + s_AssemblyPath + " to : " + s_OutputPath);

            var assembly = AssemblyDefinition.ReadAssembly(s_AssemblyPath, new ReaderParameters {
                SymbolReaderProvider = CreateDebugReaderProviderFor(s_AssemblyPath)
            });

            var UnsafeUtilityType = assembly.MainModule.Types.Single(t => t.Name.Equals(kUnsafeUtilityIdentifier));

            var ctx = new UnsafeUtilityPatcherContext(UnsafeUtilityType, false);

            InjectUtilityCopyPtrToStructure(ctx);
            InjectUtilityCopyStructureToPtr(ctx);
            InjectUtilityAddressOf(ctx);
            InjectUtilitySizeOf(ctx);
            InjectUtilityAlignOf(ctx);
            InjectUtilityReadArrayElement(ctx);
            InjectUtilityReadArrayElementWithStride(ctx);
            InjectUtilityWriteArrayElement(ctx);
            InjectUtilityWriteArrayElementWithStride(ctx);
            InjectUtilityAsRef(ctx);

            EnsureTargetFolderExists(s_OutputPath);
            assembly.Write(s_OutputPath, new WriterParameters {
                SymbolWriterProvider = CreateDebugWriterProviderFor(s_AssemblyPath)
            });
        }
Beispiel #2
0
        private static void InjectUtilityArrayElementAsRef(UnsafeUtilityPatcherContext ctx)
        {
            var ilProcessor = GetILProcessorForMethod(ctx, kUnsafeUtilityArrayElementAsRef);

            /*
             *  ldarg.0
             *  ldarg.1
             *  sizeof !T
             *  mul
             *  add
             *  ret
             */

            var method = ctx.m_PatchedClass.Methods.Single(m => m.Name.Equals(kUnsafeUtilityArrayElementAsRef));

            ilProcessor.Append(ilProcessor.Create(OpCodes.Ldarg_0));
            ilProcessor.Append(ilProcessor.Create(OpCodes.Ldarg_1));
            ilProcessor.Append(ilProcessor.Create(OpCodes.Conv_I8));
            ilProcessor.Append(ilProcessor.Create(OpCodes.Sizeof, method.GenericParameters[0]));
            ilProcessor.Append(ilProcessor.Create(OpCodes.Conv_I8));
            ilProcessor.Append(ilProcessor.Create(OpCodes.Mul));
            ilProcessor.Append(ilProcessor.Create(OpCodes.Conv_I));
            ilProcessor.Append(ilProcessor.Create(OpCodes.Add));
            ilProcessor.Append(ilProcessor.Create(OpCodes.Ret));
        }
Beispiel #3
0
        private static void InjectUtilityWriteArrayElementWithStride(UnsafeUtilityPatcherContext ctx)
        {
            var ilProcessor = GetILProcessorForMethod(ctx, kUnsafeUtilityWriteArrayElementWithStride);

            /*
             *  ldarg.0
             *  ldarg.1
             *  conv.i8
             *  ldarg.2
             *  conv.i8
             *  mul
             *  conv.i
             *  add
             *  ldarg.3
             *  stobj !T
             *  ret
             */

            var method = ctx.m_PatchedClass.Methods.Single(m => m.Name.Equals(kUnsafeUtilityWriteArrayElementWithStride));

            ilProcessor.Append(ilProcessor.Create(OpCodes.Ldarg_0));
            ilProcessor.Append(ilProcessor.Create(OpCodes.Ldarg_1));
            ilProcessor.Append(ilProcessor.Create(OpCodes.Conv_I8));
            ilProcessor.Append(ilProcessor.Create(OpCodes.Ldarg_2));
            ilProcessor.Append(ilProcessor.Create(OpCodes.Conv_I8));
            ilProcessor.Append(ilProcessor.Create(OpCodes.Mul));
            ilProcessor.Append(ilProcessor.Create(OpCodes.Conv_I));
            ilProcessor.Append(ilProcessor.Create(OpCodes.Add));
            ilProcessor.Append(ilProcessor.Create(OpCodes.Ldarg_3));
            ilProcessor.Append(ilProcessor.Create(OpCodes.Stobj, method.GenericParameters[0]));
            ilProcessor.Append(ilProcessor.Create(OpCodes.Ret));
        }
Beispiel #4
0
        private static void LoadField(UnsafeUtilityPatcherContext ctx, string fieldName, ILProcessor ilProcessor)
        {
            ilProcessor.Append(ilProcessor.Create(OpCodes.Ldarg_0));
            var field          = ctx.m_PatchedClass.Fields.Single(f => f.Name == fieldName);
            var fieldReference = new FieldReference(field.Name, field.FieldType, ctx.m_GenericInstanceType);

            ilProcessor.Append(ilProcessor.Create(OpCodes.Ldfld, fieldReference));
        }
Beispiel #5
0
        private static void InjectUtilityAsRef(UnsafeUtilityPatcherContext ctx)
        {
            var ilProcessor = GetILProcessorForMethod(ctx, kUnsafeUtilityAsRef);

            /*
             *  ldarg.0
             *  ret
             */

            ilProcessor.Append(ilProcessor.Create(OpCodes.Ldarg_0));
            ilProcessor.Append(ilProcessor.Create(OpCodes.Ret));
        }
Beispiel #6
0
        private static void InjectUtilityAlignOf(UnsafeUtilityPatcherContext ctx)
        {
            var ilProcessor = GetILProcessorForMethod(ctx, kUnsafeUtilityAlignOf);

            /*
             *  // @todo : Implement
             *  ldc.i4 4
             *  ret
             */

            ilProcessor.Append(ilProcessor.Create(OpCodes.Ldc_I4, 4));
            ilProcessor.Append(ilProcessor.Create(OpCodes.Ret));
        }
Beispiel #7
0
        private static void InjectUtilitySizeOfNonGeneric(UnsafeUtilityPatcherContext ctx)
        {
            var ilProcessor = GetILProcessorForMethod(ctx, kUnsafeUtilitySizeOfNonGeneric);

            /*
             *  sizeof !T
             *  ret
             */

            var method = ctx.m_PatchedClass.Methods.Single(m => m.Name.Equals(kUnsafeUtilitySizeOf) && m.HasGenericParameters);

            ilProcessor.Append(ilProcessor.Create(OpCodes.Sizeof, method.GenericParameters[0]));
            ilProcessor.Append(ilProcessor.Create(OpCodes.Ret));
        }
Beispiel #8
0
        private static ILProcessor GetILProcessorForMethod(UnsafeUtilityPatcherContext ctx, string methodName, bool clear = true)
        {
            var method      = ctx.m_PatchedClass.Methods.Single(m => m.Name.Equals(methodName) && m.HasGenericParameters);
            var ilProcessor = method.Body.GetILProcessor();

            if (clear)
            {
                ilProcessor.Body.Instructions.Clear();
                ilProcessor.Body.Variables.Clear();
                ilProcessor.Body.ExceptionHandlers.Clear();
            }

            return(ilProcessor);
        }
Beispiel #9
0
        private static void InjectUtilityInternalEnumToInt(UnsafeUtilityPatcherContext ctx)
        {
            var ilProcessor = GetILProcessorForMethod(ctx, kUnsafeUtilityInternalEnumToInt);

            /*
             *  ldarg.0
             *  conv.i4
             *  ret
             */

            ilProcessor.Append(ilProcessor.Create(OpCodes.Ldarg_0));
            ilProcessor.Append(ilProcessor.Create(OpCodes.Conv_I4));
            ilProcessor.Append(ilProcessor.Create(OpCodes.Ret));
        }
Beispiel #10
0
        private static void CallMethod(UnsafeUtilityPatcherContext ctx, string methodName, ILProcessor ilProcessor)
        {
            var method = ctx.m_PatchedClass.GetMethods().Single(m => m.Name == methodName);

            var methodReference = new MethodReference(method.Name, method.ReturnType, ctx.m_GenericInstanceType)
            {
                CallingConvention = method.CallingConvention,
                HasThis           = method.HasThis,
            };

            foreach (var param in method.Parameters)
            {
                methodReference.Parameters.Add(param);
            }

            ilProcessor.Append(ilProcessor.Create(OpCodes.Call, methodReference));
        }
Beispiel #11
0
        private static void InjectUtilityCopyStructureToPtr(UnsafeUtilityPatcherContext ctx)
        {
            var ilProcessor = GetILProcessorForMethod(ctx, kUnsafeUtilityCopyStructureToPtr);

            /*
             *  ldarg.0
             *  ldobj !T
             *  ldarg.1
             *  stind.i
             *  ret
             */

            var method = ctx.m_PatchedClass.Methods.Single(m => m.Name.Equals(kUnsafeUtilityCopyStructureToPtr));

            ilProcessor.Append(ilProcessor.Create(OpCodes.Ldarg_1));
            ilProcessor.Append(ilProcessor.Create(OpCodes.Ldarg_0));
            ilProcessor.Append(ilProcessor.Create(OpCodes.Ldobj, method.GenericParameters[0]));
            ilProcessor.Append(ilProcessor.Create(OpCodes.Stobj, method.GenericParameters[0]));
            ilProcessor.Append(ilProcessor.Create(OpCodes.Ret));
        }
Beispiel #12
0
        private static void InjectUtilityEnumEquals(UnsafeUtilityPatcherContext ctx)
        {
            var ilProcessor = GetILProcessorForMethod(ctx, kUnsafeUtilityEnumEquals);

            /*
             *  ldarg.0
             *  conv.i8
             *  ldarg.1
             *  conv.i8
             *  ceq
             *  ret
             */

            ilProcessor.Append(ilProcessor.Create(OpCodes.Ldarg_0));
            ilProcessor.Append(ilProcessor.Create(OpCodes.Conv_I8));
            ilProcessor.Append(ilProcessor.Create(OpCodes.Ldarg_1));
            ilProcessor.Append(ilProcessor.Create(OpCodes.Conv_I8));
            ilProcessor.Append(ilProcessor.Create(OpCodes.Ceq));
            ilProcessor.Append(ilProcessor.Create(OpCodes.Ret));
        }