public static Instruction FindInstruction(AssemblyDefinition assembly, string typeName, string testMethodName, OpCode testInstruction) { MethodDefinition testMethod = FindMethod(assembly, typeName, testMethodName); Assert.IsNotNull(testMethod); return FindInstruction(testMethod, testInstruction); }
private static int GetNegativeModifier(OpCode opCode) { switch (opCode.StackBehaviourPop) { case StackBehaviour.Pop0: return 0; case StackBehaviour.Pop1: case StackBehaviour.Popi: case StackBehaviour.Popref: case StackBehaviour.Varpop: return 1; case StackBehaviour.Pop1_pop1: case StackBehaviour.Popi_pop1: case StackBehaviour.Popi_popi: case StackBehaviour.Popi_popi8: case StackBehaviour.Popi_popr4: case StackBehaviour.Popi_popr8: case StackBehaviour.Popref_pop1: case StackBehaviour.Popref_popi: return 2; case StackBehaviour.Popi_popi_popi: case StackBehaviour.Popref_popi_popi: case StackBehaviour.Popref_popi_popi8: case StackBehaviour.Popref_popi_popr4: case StackBehaviour.Popref_popi_popr8: case StackBehaviour.Popref_popi_popref: return 3; case StackBehaviour.PopAll: return 1000; } return 0; }
public static Instruction Create(OpCode opcode) { if (opcode.OperandType != OperandType.InlineNone) throw new ArgumentException ("opcode"); return new Instruction (opcode, null); }
static DynamicMethodDefinition() { foreach (FieldInfo field in typeof(System.Reflection.Emit.OpCodes).GetFields(BindingFlags.Public | BindingFlags.Static)) { System.Reflection.Emit.OpCode reflOpCode = (System.Reflection.Emit.OpCode)field.GetValue(null); _ReflOpCodes[reflOpCode.Value] = reflOpCode; } foreach (FieldInfo field in typeof(Mono.Cecil.Cil.OpCodes).GetFields(BindingFlags.Public | BindingFlags.Static)) { Mono.Cecil.Cil.OpCode cecilOpCode = (Mono.Cecil.Cil.OpCode)field.GetValue(null); _CecilOpCodes[cecilOpCode.Value] = cecilOpCode; } foreach (MethodInfo method in typeof(ILGenerator).GetMethods()) { if (method.Name != "Emit") { continue; } ParameterInfo[] args = method.GetParameters(); if (args.Length != 2) { continue; } if (args[0].ParameterType != typeof(System.Reflection.Emit.OpCode)) { continue; } _Emitters[args[1].ParameterType] = method; } }
public static bool ReadSigKey(MethodDefinition DecryptMethod, OpCode[] KeySig, ref object val) { int score = 0; for (int i = 0; i < DecryptMethod.Body.Instructions.Count; i++) { if (DecryptMethod.Body.Instructions[i].OpCode == KeySig[score]) { score++; if (score == KeySig.Length) { if (DecryptMethod.Body.Instructions[i].Next != null) { if (DecryptMethod.Body.Instructions[i].Next.Operand != null) { val = DecryptMethod.Body.Instructions[i].Next.Operand; return true; } } } } else { score = 0; } } return false; }
static Instruction create(OpCode opcode, object operand) { return(new Instruction { OpCode = opcode, Operand = operand, }); }
private OpCodeInfo(Mono.Cecil.Cil.OpCode opcode) { base(); this.opcode = opcode; this.set_CanThrow(true); return; }
public Instruction Create (OpCode opcode) { if (opcode.OperandType != OperandType.InlineNone) throw new ArgumentException ("opcode"); return FinalCreate (opcode); }
private static AssemblyDefinition CreateTestAssembly(OpCode arithmeticOperator) { var name = new AssemblyNameDefinition("TestBitwiseOperatorTurtleOr", new Version(1, 0)); var assembly = AssemblyDefinition.CreateAssembly(name, "TestClass", ModuleKind.Dll); var type = new TypeDefinition("TestBitwiseOperatorTurtleOr", "TestClass", TypeAttributes.Class | TypeAttributes.Public); var intType = assembly.MainModule.Import(typeof(int)); var method = new MethodDefinition("TestMethod", MethodAttributes.Public, intType); var leftParam = new ParameterDefinition("left", ParameterAttributes.In, intType); var rightParam = new ParameterDefinition("right", ParameterAttributes.In, intType); method.Parameters.Add(leftParam); method.Parameters.Add(rightParam); var resultVariable = new VariableDefinition(intType); method.Body.Variables.Add(resultVariable); var processor = method.Body.GetILProcessor(); method.Body.Instructions.Add(processor.Create(OpCodes.Ldarg, leftParam)); method.Body.Instructions.Add(processor.Create(OpCodes.Ldarg, rightParam)); method.Body.Instructions.Add(processor.Create(arithmeticOperator)); method.Body.Instructions.Add(processor.Create(OpCodes.Stloc, resultVariable)); method.Body.Instructions.Add(processor.Create(OpCodes.Ldloc, resultVariable)); method.Body.Instructions.Add(processor.Create(OpCodes.Ret)); type.Methods.Add(method); assembly.MainModule.Types.Add(type); return assembly; }
/// <summary> /// /// </summary> /// <param name="toSimplify"></param> /// <returns></returns> private static OpCode SimplifyOpCode(OpCode toSimplify) { switch (toSimplify.Code) { case Code.Br_S: return OpCodes.Br; case Code.Brfalse_S: return OpCodes.Brfalse; case Code.Brtrue_S: return OpCodes.Brtrue; case Code.Beq_S: return OpCodes.Beq; case Code.Bge_S: return OpCodes.Bge; case Code.Bgt_S: return OpCodes.Bgt; case Code.Ble_S: return OpCodes.Ble; case Code.Blt_S: return OpCodes.Blt; case Code.Bne_Un_S: return OpCodes.Bne_Un; case Code.Bge_Un_S: return OpCodes.Bge_Un; case Code.Bgt_Un_S: return OpCodes.Bgt_Un; case Code.Ble_Un_S: return OpCodes.Ble_Un; case Code.Blt_Un_S: return OpCodes.Blt_Un; case Code.Leave_S: return OpCodes.Leave; default: return toSimplify; } }
internal static void AssertInstruction(Instruction actual, OpCode opCode, MemberReference expectedCtor) { Assert.AreEqual(opCode, actual.OpCode); MethodReference actualCtor = (MethodReference)actual.Operand; Assert.AreEqual(expectedCtor.DeclaringType.Name, actualCtor.DeclaringType.Name, opCode.ToString()); Assert.AreEqual(expectedCtor, actualCtor.Resolve(), opCode.ToString()); }
private bool TryGetInstruction(List<ILRange> ilRanges, OpCode opCode, out Instruction instruction) { int fromOffset = 0; int toOffset = 0; if (ilRanges == null || ilRanges.Count == 0) { instruction = null; return false; } fromOffset = ilRanges[0].From; toOffset = ilRanges[0].To; instruction = InstructionAt(fromOffset); do { if (instruction.OpCode == opCode) { return true; } instruction = instruction.Next; fromOffset = instruction.Offset; } while (fromOffset != toOffset); return instruction.OpCode == opCode; }
private static AssemblyDefinition CreateTestAssembly(OpCode opCode, bool invert) { var name = new AssemblyNameDefinition("TestConditionalsBoundaryTurtle", new Version(1, 0)); var assembly = AssemblyDefinition.CreateAssembly(name, "TestClass", ModuleKind.Dll); var type = new TypeDefinition("TestConditionalsBoundaryTurtle", "TestClass", TypeAttributes.Class | TypeAttributes.Public); var intType = assembly.MainModule.Import(typeof(int)); var boolType = assembly.MainModule.Import(typeof(bool)); var method = new MethodDefinition("TestMethod", MethodAttributes.Public, intType); var param = new ParameterDefinition("input", ParameterAttributes.In, intType); method.Parameters.Add(param); var resultVariable = new VariableDefinition(boolType); method.Body.Variables.Add(resultVariable); var processor = method.Body.GetILProcessor(); Instruction loadReturnValueInstruction = processor.Create(OpCodes.Ldloc, resultVariable); method.Body.Instructions.Add(processor.Create(OpCodes.Ldarg, param)); method.Body.Instructions.Add(processor.Create(OpCodes.Ldc_I4, 0)); method.Body.Instructions.Add(processor.Create(opCode)); if (invert) { method.Body.Instructions.Add(processor.Create(OpCodes.Ldc_I4, 0)); method.Body.Instructions.Add(processor.Create(OpCodes.Ceq)); } method.Body.Instructions.Add(processor.Create(OpCodes.Stloc, resultVariable)); method.Body.Instructions.Add(loadReturnValueInstruction); method.Body.Instructions.Add(processor.Create(OpCodes.Ret)); type.Methods.Add(method); assembly.MainModule.Types.Add(type); return assembly; }
public Instruction Create (OpCode opcode, FieldReference field) { if (opcode.OperandType != OperandType.InlineField && opcode.OperandType != OperandType.InlineTok) throw new ArgumentException ("opcode"); return FinalCreate (opcode, field); }
public Instruction Create (OpCode opcode, MethodReference meth) { if (opcode.OperandType != OperandType.InlineMethod && opcode.OperandType != OperandType.InlineTok) throw new ArgumentException ("opcode"); return FinalCreate (opcode, meth); }
public Instruction Create (OpCode opcode, TypeReference type) { if (opcode.OperandType != OperandType.InlineType && opcode.OperandType != OperandType.InlineTok) throw new ArgumentException ("opcode"); return FinalCreate (opcode, type); }
static void AssertOpCodeSequence (OpCode [] expected, MethodBody body) { var opcodes = body.Instructions.Select (i => i.OpCode).ToArray (); Assert.AreEqual (expected.Length, opcodes.Length); for (int i = 0; i < opcodes.Length; i++) Assert.AreEqual (expected [i], opcodes [i]); }
public static bool ReadSigKey(MethodDefinition DecryptMethod, OpCode[] KeySig, ref string val) { object value = null; bool ret = ReadSigKey(DecryptMethod, KeySig, ref value); if (value != null) val = value.ToString(); return ret; }
public static bool ReadSigKey(MethodDefinition DecryptMethod, OpCode[] KeySig, ref int val) { object value = null; bool ret = ReadSigKey(DecryptMethod, KeySig, ref value); if (value != null) val = Convert.ToInt32(value); return ret; }
public Instruction Create (OpCode opcode, CallSite site) { if (site == null) throw new ArgumentNullException ("site"); if (opcode.Code != Code.Calli) throw new ArgumentException ("code"); return FinalCreate (opcode, site); }
public PatternInstruction(OpCode[] eligibleOpCodes, Terminal terminal = null, Predicate predicate = null) { if (eligibleOpCodes == null) throw new ArgumentNullException(Name.Of(eligibleOpCodes)); if (eligibleOpCodes.Length == 0) throw new ArgumentException("Array length must be greater than zero", Name.Of(eligibleOpCodes)); EligibleOpCodes = eligibleOpCodes; Terminal = terminal; this.predicate = predicate ?? PredicateDummy; }
private bool isAnotherPath(OpCode opCode) { if (opCode.FlowControl == FlowControl.Branch) return true; if (opCode.Code == Code.Jmp) return true; return false; }
public Instruction Create (OpCode opcode, byte value) { if (opcode.OperandType == OperandType.ShortInlineVar) return Instruction.Create (opcode, body.Variables [value]); if (opcode.OperandType == OperandType.ShortInlineArg) return Instruction.Create (opcode, body.GetParameter (value)); return Instruction.Create (opcode, value); }
ROpCode convertOpCode(OpCode opcode) { ROpCode ropcode; if (cecilToReflection.TryGetValue(opcode, out ropcode)) { return(ropcode); } return(ROpCodes.Nop); }
internal static OpCode Map(Cil.OpCode cecilOpCode) { OpCode opCode; if (!_opCodes.TryGetValue(cecilOpCode.Code.ToString(), out opCode)) { opCode = OpCodes.Nop; } return(opCode); }
void InjectNewWriter(MethodDefinition sendData, ILProcessor processor, out VariableDefinition mswriter, out OpCode binaryWriter) { var buffer = sendData.Body.Instructions.First( x => x.OpCode == OpCodes.Ldsfld && (x.Operand as FieldReference).Name == "buffer" ); while (!(buffer.Next.OpCode == OpCodes.Callvirt && (buffer.Next.Operand as MethodReference).Name == "set_Position")) { processor.Remove(buffer.Next); } processor.Remove(buffer.Next); //processor.Remove(buffer); //VariableDefinition mswriter; sendData.Body.Variables.Add(mswriter = new VariableDefinition("mswriter", this.SourceDefinition.MainModule.Import(typeof(MemoryStream)) )); var res = processor.InsertBefore(buffer.Previous.Previous, new { OpCodes.Newobj, Operand = this.SourceDefinition.MainModule.Import(typeof(MemoryStream) .GetConstructors() .Single(x => x.GetParameters().Count() == 0) ) }, new { OpCodes.Stloc, Operand = mswriter }, new { OpCodes.Ldloc, Operand = mswriter } ); buffer.Previous.Previous.ReplaceTransfer(res[0], sendData); processor.Remove(buffer.Previous); processor.Remove(buffer.Previous); buffer.OpCode = OpCodes.Newobj; buffer.Operand = this.SourceDefinition.MainModule.Import(typeof(BinaryWriter) .GetConstructors() .Single(x => x.GetParameters().Count() == 1) ); if (buffer.Next.OpCode != OpCodes.Ldloc_1) { throw new NotSupportedException("Expected Ldloc_1"); } /*var*/ binaryWriter = buffer.Next.OpCode; processor.InsertAfter(buffer, new { OpCodes.Stloc_1 } ); }
private static Instruction FindInstruction(Mono.Collections.Generic.Collection<Instruction> instructions, OpCode opCode, string operand) { foreach(var ins in instructions) { if(ins.OpCode.Code == opCode.Code && ins.Operand.ToString() == operand) { return ins; } } return null; }
public static bool isFallThrough(OpCode opCode) { switch (opCode.FlowControl) { case FlowControl.Call: return opCode != OpCodes.Jmp; case FlowControl.Cond_Branch: case FlowControl.Next: return true; default: return false; } }
protected override void ImplementProceed(MethodDefinition methodInfo, MethodBody methodBody, ILProcessor il, FieldReference methodInfoField, MethodReference proceed, Action<ILProcessor> emitProceedTarget, MethodReference proceedTargetMethod, OpCode proceedOpCode) { // If T is an interface, then we want to check if target is null; if so, we want to just return the default value var targetNotNull = il.Create(OpCodes.Nop); EmitProxyFromProceed(il); il.Emit(OpCodes.Ldfld, ClassWeaver.Target); // Load "target" from "this" il.Emit(OpCodes.Brtrue, targetNotNull); // If target is not null, jump below CecilExtensions.CreateDefaultMethodImplementation(methodBody.Method, il); il.Append(targetNotNull); // Mark where the previous branch instruction should jump to base.ImplementProceed(methodInfo, methodBody, il, methodInfoField, proceed, emitProceedTarget, proceedTargetMethod, proceedOpCode); }
static unsafe CecilILGenerator() { foreach (FieldInfo field in typeof(OpCodes).GetFields(BindingFlags.Public | BindingFlags.Static)) { OpCode cecilOpCode = (OpCode)field.GetValue(null); _MCCOpCodes[cecilOpCode.Value] = cecilOpCode; } Label l = default; *(int *)&l = -1; NullLabel = l; }
public bool TryGetOpCode(AstNode node, OpCode[] opCodes, out Instruction instruction) { List<ILRange> ilRanges = node.Annotation<List<ILRange>>(); instruction = null; foreach (var opCode in opCodes) { if (TryGetInstruction(ilRanges, opCode, out instruction)) { return true; } } return false; }
public static void ExpandMacro(ref OpCode opCode, ref object operand, MethodBody methodBody) { if (opCode.OpCodeType != OpCodeType.Macro) return; switch (opCode.Code) { case Code.Ldarg_0: opCode = OpCodes.Ldarg; operand = methodBody.GetParameter(0); break; case Code.Ldarg_1: opCode = OpCodes.Ldarg; operand = methodBody.GetParameter(1); break; case Code.Ldarg_2: opCode = OpCodes.Ldarg; operand = methodBody.GetParameter(2); break; case Code.Ldarg_3: opCode = OpCodes.Ldarg; operand = methodBody.GetParameter(3); break; case Code.Ldloc_0: opCode = OpCodes.Ldloc; operand = methodBody.Variables[0]; break; case Code.Ldloc_1: opCode = OpCodes.Ldloc; operand = methodBody.Variables[1]; break; case Code.Ldloc_2: opCode = OpCodes.Ldloc; operand = methodBody.Variables[2]; break; case Code.Ldloc_3: opCode = OpCodes.Ldloc; operand = methodBody.Variables[3]; break; case Code.Stloc_0: opCode = OpCodes.Stloc; operand = methodBody.Variables[0]; break; case Code.Stloc_1: opCode = OpCodes.Stloc; operand = methodBody.Variables[1]; break; case Code.Stloc_2: opCode = OpCodes.Stloc; operand = methodBody.Variables[2]; break; case Code.Stloc_3: opCode = OpCodes.Stloc; operand = methodBody.Variables[3]; break; case Code.Ldarg_S: opCode = OpCodes.Ldarg; break; case Code.Ldarga_S: opCode = OpCodes.Ldarga; break; case Code.Starg_S: opCode = OpCodes.Starg; break; case Code.Ldloc_S: opCode = OpCodes.Ldloc; break; case Code.Ldloca_S: opCode = OpCodes.Ldloca; break; case Code.Stloc_S: opCode = OpCodes.Stloc; break; case Code.Ldc_I4_M1: opCode = OpCodes.Ldc_I4; operand = -1; break; case Code.Ldc_I4_0: opCode = OpCodes.Ldc_I4; operand = 0; break; case Code.Ldc_I4_1: opCode = OpCodes.Ldc_I4; operand = 1; break; case Code.Ldc_I4_2: opCode = OpCodes.Ldc_I4; operand = 2; break; case Code.Ldc_I4_3: opCode = OpCodes.Ldc_I4; operand = 3; break; case Code.Ldc_I4_4: opCode = OpCodes.Ldc_I4; operand = 4; break; case Code.Ldc_I4_5: opCode = OpCodes.Ldc_I4; operand = 5; break; case Code.Ldc_I4_6: opCode = OpCodes.Ldc_I4; operand = 6; break; case Code.Ldc_I4_7: opCode = OpCodes.Ldc_I4; operand = 7; break; case Code.Ldc_I4_8: opCode = OpCodes.Ldc_I4; operand = 8; break; case Code.Ldc_I4_S: opCode = OpCodes.Ldc_I4; operand = (int) (sbyte) operand; break; case Code.Br_S: opCode = OpCodes.Br; break; case Code.Brfalse_S: opCode = OpCodes.Brfalse; break; case Code.Brtrue_S: opCode = OpCodes.Brtrue; break; case Code.Beq_S: opCode = OpCodes.Beq; break; case Code.Bge_S: opCode = OpCodes.Bge; break; case Code.Bgt_S: opCode = OpCodes.Bgt; break; case Code.Ble_S: opCode = OpCodes.Ble; break; case Code.Blt_S: opCode = OpCodes.Blt; break; case Code.Bne_Un_S: opCode = OpCodes.Bne_Un; break; case Code.Bge_Un_S: opCode = OpCodes.Bge_Un; break; case Code.Bgt_Un_S: opCode = OpCodes.Bgt_Un; break; case Code.Ble_Un_S: opCode = OpCodes.Ble_Un; break; case Code.Blt_Un_S: opCode = OpCodes.Blt_Un; break; case Code.Leave_S: opCode = OpCodes.Leave; break; } }
static _DMDEmit() { foreach (FieldInfo field in typeof(System.Reflection.Emit.OpCodes).GetFields(BindingFlags.Public | BindingFlags.Static)) { System.Reflection.Emit.OpCode reflOpCode = (System.Reflection.Emit.OpCode)field.GetValue(null); _ReflOpCodes[reflOpCode.Value] = reflOpCode; } foreach (FieldInfo field in typeof(Mono.Cecil.Cil.OpCodes).GetFields(BindingFlags.Public | BindingFlags.Static)) { Mono.Cecil.Cil.OpCode cecilOpCode = (Mono.Cecil.Cil.OpCode)field.GetValue(null); _CecilOpCodes[cecilOpCode.Value] = cecilOpCode; } }
public static Instruction FindInstruction(MethodDefinition method, OpCode opCode) { Instruction current = method.Body.Instructions[0]; Instruction instruction = current; while (instruction != null && instruction.OpCode != opCode) { instruction = instruction.Next; } Assert.IsNotNull(instruction); Assert.AreEqual(opCode, instruction.OpCode); current = instruction; return current; }
public static Instruction FindInstructionSeq(MethodBody body, OpCode[] instrs) { for (int i = 0; i < body.Instructions.Count - instrs.Length; i++) { for (int j = 0; j < instrs.Length; j++) { if (body.Instructions[i + j].OpCode.Code != instrs[j].Code) goto next_try; } return body.Instructions[i]; next_try: ; } return null; }
public static bool IsUnconditionalBranch(OpCode opcode) { if (opcode.OpCodeType == OpCodeType.Prefix) return false; switch (opcode.FlowControl) { case FlowControl.Branch: case FlowControl.Throw: case FlowControl.Return: return true; case FlowControl.Next: case FlowControl.Call: case FlowControl.Cond_Branch: return false; default: throw new NotSupportedException(opcode.FlowControl.ToString()); } }
static void InsertMusicHook() { // First, add the UpdateMusicHook() function that TMain will override. var updateMusicHook = new MethodDefinition("UpdateMusicHook", MethodAttributes.Public | MethodAttributes.HideBySig | MethodAttributes.NewSlot | MethodAttributes.Virtual, _typeSystem.Void); var proc = updateMusicHook.Body.GetILProcessor(); proc.Emit(OpCodes.Ret); mainTypeDef.Methods.Add(updateMusicHook); // Then add a hook to call it. OpCode[] searchSeq = new OpCode[] { OpCodes.Ldarg_0, // IL_0e31: ldarg.0 OpCodes.Ldfld, // IL_0e32: ldfld int32 Terraria.Main::newMusic OpCodes.Stsfld // IL_0e37: stsfld int32 Terraria.Main::curMusic }; var updateMusic = mainTypeDef.GetMethod("UpdateMusic").Body; proc = updateMusic.GetILProcessor(); var firstInstr = CecilHelper.FindInstructionSeq(updateMusic, searchSeq); if (firstInstr == null) { Console.WriteLine("Mainpatcher.InsertMusicHook() was unable to locate the instruction sequence that indicates curMusic being set to newMusic. Terraria.Main.UpdateMusic() has probably changed and this hook needs to be modified accordingly."); } else { var musicHook = mainTypeDef.GetMethod("UpdateMusicHook"); var lastInstr = firstInstr; for (int i = 1; i < searchSeq.Length; i++) { lastInstr = lastInstr.Next; } var call_hook = new[] { Instruction.Create(OpCodes.Ldarg_0), Instruction.Create(OpCodes.Callvirt, musicHook) }; for (int i = call_hook.Length - 1; i >= 0; i--) { proc.InsertAfter(lastInstr, call_hook[i]); } } }
private void _EmitInlineVar(OpCode opcode, int index) { // System.Reflection.Emit has only got (Short)InlineVar and allows index refs. // Mono.Cecil has also got (Short)InlineArg and requires definition refs. switch (opcode.OperandType) { case MCC.OperandType.ShortInlineArg: case MCC.OperandType.InlineArg: Emit(IL.Create(opcode, IL.Body.Method.Parameters[index])); break; case MCC.OperandType.ShortInlineVar: case MCC.OperandType.InlineVar: Emit(IL.Create(opcode, IL.Body.Variables[index])); break; default: throw new NotSupportedException( $"Unsupported SRE InlineVar -> Cecil {opcode.OperandType} for {opcode} {index}"); } }
public static bool IsUnconditionalBranch(Mono.Cecil.Cil.OpCode opcode) { if (opcode.get_OpCodeType() == 4) { return(false); } switch (opcode.get_FlowControl()) { case 0: case 7: case 8: { return(true); } case 1: case 4: case 6: { Label0: V_1 = opcode.get_FlowControl(); throw new NotSupportedException(V_1.ToString()); } case 2: case 3: case 5: { return(false); } default: { goto Label0; } } }
public void Add(OpCode opcode, VariableDefinition op) => Add(Instruction.Create(opcode, op));
public void Add(OpCode opcode) => Add(Instruction.Create(opcode));
public FluentEmitter Emit(OpCode opcode) { return(Emit(Instruction.Create(opcode))); }
public FluentEmitter Emit(OpCode opcode, double arg) { return(Emit(Instruction.Create(opcode, arg))); }
public FluentEmitter Emit(OpCode opcode, FieldInfo arg) { return(Emit(Instruction.Create(opcode, Module.SafeImport(arg)))); }
public void Emit(OpCode opcode, Type type) => _Insert(IL.Create(opcode, type));
private static System.Reflection.Emit.OpCode MapOpCode(Mono.Cecil.Cil.OpCode cecilOpcode) { switch (cecilOpcode.Code) { case Code.Nop: return(System.Reflection.Emit.OpCodes.Nop); case Code.Break: return(System.Reflection.Emit.OpCodes.Break); case Code.Ldarg_0: return(System.Reflection.Emit.OpCodes.Ldarg_0); case Code.Ldarg_1: return(System.Reflection.Emit.OpCodes.Ldarg_1); case Code.Ldarg_2: return(System.Reflection.Emit.OpCodes.Ldarg_2); case Code.Ldarg_3: return(System.Reflection.Emit.OpCodes.Ldarg_3); case Code.Ldloc_0: return(System.Reflection.Emit.OpCodes.Ldloc_0); case Code.Ldloc_1: return(System.Reflection.Emit.OpCodes.Ldloc_1); case Code.Ldloc_2: return(System.Reflection.Emit.OpCodes.Ldloc_2); case Code.Ldloc_3: return(System.Reflection.Emit.OpCodes.Ldloc_3); case Code.Stloc_0: return(System.Reflection.Emit.OpCodes.Stloc_0); case Code.Stloc_1: return(System.Reflection.Emit.OpCodes.Stloc_1); case Code.Stloc_2: return(System.Reflection.Emit.OpCodes.Stloc_2); case Code.Stloc_3: return(System.Reflection.Emit.OpCodes.Stloc_3); case Code.Ldarg_S: return(System.Reflection.Emit.OpCodes.Ldarg_S); case Code.Ldarga_S: return(System.Reflection.Emit.OpCodes.Ldarga_S); case Code.Starg_S: return(System.Reflection.Emit.OpCodes.Starg_S); case Code.Ldloc_S: return(System.Reflection.Emit.OpCodes.Ldloc_S); case Code.Ldloca_S: return(System.Reflection.Emit.OpCodes.Ldloca_S); case Code.Stloc_S: return(System.Reflection.Emit.OpCodes.Stloc_S); case Code.Ldnull: return(System.Reflection.Emit.OpCodes.Ldnull); case Code.Ldc_I4_M1: return(System.Reflection.Emit.OpCodes.Ldc_I4_M1); case Code.Ldc_I4_0: return(System.Reflection.Emit.OpCodes.Ldc_I4_0); case Code.Ldc_I4_1: return(System.Reflection.Emit.OpCodes.Ldc_I4_1); case Code.Ldc_I4_2: return(System.Reflection.Emit.OpCodes.Ldc_I4_2); case Code.Ldc_I4_3: return(System.Reflection.Emit.OpCodes.Ldc_I4_3); case Code.Ldc_I4_4: return(System.Reflection.Emit.OpCodes.Ldc_I4_4); case Code.Ldc_I4_5: return(System.Reflection.Emit.OpCodes.Ldc_I4_5); case Code.Ldc_I4_6: return(System.Reflection.Emit.OpCodes.Ldc_I4_6); case Code.Ldc_I4_7: return(System.Reflection.Emit.OpCodes.Ldc_I4_7); case Code.Ldc_I4_8: return(System.Reflection.Emit.OpCodes.Ldc_I4_8); case Code.Ldc_I4_S: return(System.Reflection.Emit.OpCodes.Ldc_I4_S); case Code.Ldc_I4: return(System.Reflection.Emit.OpCodes.Ldc_I4); case Code.Ldc_I8: return(System.Reflection.Emit.OpCodes.Ldc_I8); case Code.Ldc_R4: return(System.Reflection.Emit.OpCodes.Ldc_R4); case Code.Ldc_R8: return(System.Reflection.Emit.OpCodes.Ldc_R8); case Code.Dup: return(System.Reflection.Emit.OpCodes.Dup); case Code.Pop: return(System.Reflection.Emit.OpCodes.Pop); case Code.Jmp: return(System.Reflection.Emit.OpCodes.Jmp); case Code.Call: return(System.Reflection.Emit.OpCodes.Call); case Code.Calli: return(System.Reflection.Emit.OpCodes.Calli); case Code.Ret: return(System.Reflection.Emit.OpCodes.Ret); case Code.Br_S: return(System.Reflection.Emit.OpCodes.Br_S); case Code.Brfalse_S: return(System.Reflection.Emit.OpCodes.Brfalse_S); case Code.Brtrue_S: return(System.Reflection.Emit.OpCodes.Brtrue_S); case Code.Beq_S: return(System.Reflection.Emit.OpCodes.Beq_S); case Code.Bge_S: return(System.Reflection.Emit.OpCodes.Bge_S); case Code.Bgt_S: return(System.Reflection.Emit.OpCodes.Bgt_S); case Code.Ble_S: return(System.Reflection.Emit.OpCodes.Ble_S); case Code.Blt_S: return(System.Reflection.Emit.OpCodes.Blt_S); case Code.Bne_Un_S: return(System.Reflection.Emit.OpCodes.Bne_Un_S); case Code.Bge_Un_S: return(System.Reflection.Emit.OpCodes.Bge_Un_S); case Code.Bgt_Un_S: return(System.Reflection.Emit.OpCodes.Bgt_Un_S); case Code.Ble_Un_S: return(System.Reflection.Emit.OpCodes.Ble_Un_S); case Code.Blt_Un_S: return(System.Reflection.Emit.OpCodes.Blt_Un_S); case Code.Br: return(System.Reflection.Emit.OpCodes.Br); case Code.Brfalse: return(System.Reflection.Emit.OpCodes.Brfalse); case Code.Brtrue: return(System.Reflection.Emit.OpCodes.Brtrue); case Code.Beq: return(System.Reflection.Emit.OpCodes.Beq); case Code.Bge: return(System.Reflection.Emit.OpCodes.Bge); case Code.Bgt: return(System.Reflection.Emit.OpCodes.Bgt); case Code.Ble: return(System.Reflection.Emit.OpCodes.Ble); case Code.Blt: return(System.Reflection.Emit.OpCodes.Blt); case Code.Bne_Un: return(System.Reflection.Emit.OpCodes.Bne_Un); case Code.Bge_Un: return(System.Reflection.Emit.OpCodes.Bge_Un); case Code.Bgt_Un: return(System.Reflection.Emit.OpCodes.Bgt_Un); case Code.Ble_Un: return(System.Reflection.Emit.OpCodes.Ble_Un); case Code.Blt_Un: return(System.Reflection.Emit.OpCodes.Blt_Un); case Code.Switch: return(System.Reflection.Emit.OpCodes.Switch); case Code.Ldind_I1: return(System.Reflection.Emit.OpCodes.Ldind_I1); case Code.Ldind_U1: return(System.Reflection.Emit.OpCodes.Ldind_U1); case Code.Ldind_I2: return(System.Reflection.Emit.OpCodes.Ldind_I2); case Code.Ldind_U2: return(System.Reflection.Emit.OpCodes.Ldind_U2); case Code.Ldind_I4: return(System.Reflection.Emit.OpCodes.Ldind_I4); case Code.Ldind_U4: return(System.Reflection.Emit.OpCodes.Ldind_U4); case Code.Ldind_I8: return(System.Reflection.Emit.OpCodes.Ldind_I8); case Code.Ldind_I: return(System.Reflection.Emit.OpCodes.Ldind_I); case Code.Ldind_R4: return(System.Reflection.Emit.OpCodes.Ldind_R4); case Code.Ldind_R8: return(System.Reflection.Emit.OpCodes.Ldind_R8); case Code.Ldind_Ref: return(System.Reflection.Emit.OpCodes.Ldind_Ref); case Code.Stind_Ref: return(System.Reflection.Emit.OpCodes.Stind_Ref); case Code.Stind_I1: return(System.Reflection.Emit.OpCodes.Stind_I1); case Code.Stind_I2: return(System.Reflection.Emit.OpCodes.Stind_I2); case Code.Stind_I4: return(System.Reflection.Emit.OpCodes.Stind_I4); case Code.Stind_I8: return(System.Reflection.Emit.OpCodes.Stind_I8); case Code.Stind_R4: return(System.Reflection.Emit.OpCodes.Stind_R4); case Code.Stind_R8: return(System.Reflection.Emit.OpCodes.Stind_R8); case Code.Add: return(System.Reflection.Emit.OpCodes.Add); case Code.Sub: return(System.Reflection.Emit.OpCodes.Sub); case Code.Mul: return(System.Reflection.Emit.OpCodes.Mul); case Code.Div: return(System.Reflection.Emit.OpCodes.Div); case Code.Div_Un: return(System.Reflection.Emit.OpCodes.Div_Un); case Code.Rem: return(System.Reflection.Emit.OpCodes.Rem); case Code.Rem_Un: return(System.Reflection.Emit.OpCodes.Rem_Un); case Code.And: return(System.Reflection.Emit.OpCodes.And); case Code.Or: return(System.Reflection.Emit.OpCodes.Or); case Code.Xor: return(System.Reflection.Emit.OpCodes.Xor); case Code.Shl: return(System.Reflection.Emit.OpCodes.Shl); case Code.Shr: return(System.Reflection.Emit.OpCodes.Shr); case Code.Shr_Un: return(System.Reflection.Emit.OpCodes.Shr_Un); case Code.Neg: return(System.Reflection.Emit.OpCodes.Neg); case Code.Not: return(System.Reflection.Emit.OpCodes.Not); case Code.Conv_I1: return(System.Reflection.Emit.OpCodes.Conv_I1); case Code.Conv_I2: return(System.Reflection.Emit.OpCodes.Conv_I2); case Code.Conv_I4: return(System.Reflection.Emit.OpCodes.Conv_I4); case Code.Conv_I8: return(System.Reflection.Emit.OpCodes.Conv_I8); case Code.Conv_R4: return(System.Reflection.Emit.OpCodes.Conv_R4); case Code.Conv_R8: return(System.Reflection.Emit.OpCodes.Conv_R8); case Code.Conv_U4: return(System.Reflection.Emit.OpCodes.Conv_U4); case Code.Conv_U8: return(System.Reflection.Emit.OpCodes.Conv_U8); case Code.Callvirt: return(System.Reflection.Emit.OpCodes.Callvirt); case Code.Cpobj: return(System.Reflection.Emit.OpCodes.Cpobj); case Code.Ldobj: return(System.Reflection.Emit.OpCodes.Ldobj); case Code.Ldstr: return(System.Reflection.Emit.OpCodes.Ldstr); case Code.Newobj: return(System.Reflection.Emit.OpCodes.Newobj); case Code.Castclass: return(System.Reflection.Emit.OpCodes.Castclass); case Code.Isinst: return(System.Reflection.Emit.OpCodes.Isinst); case Code.Conv_R_Un: return(System.Reflection.Emit.OpCodes.Conv_R_Un); case Code.Unbox: return(System.Reflection.Emit.OpCodes.Unbox); case Code.Throw: return(System.Reflection.Emit.OpCodes.Throw); case Code.Ldfld: return(System.Reflection.Emit.OpCodes.Ldfld); case Code.Ldflda: return(System.Reflection.Emit.OpCodes.Ldflda); case Code.Stfld: return(System.Reflection.Emit.OpCodes.Stfld); case Code.Ldsfld: return(System.Reflection.Emit.OpCodes.Ldsfld); case Code.Ldsflda: return(System.Reflection.Emit.OpCodes.Ldsflda); case Code.Stsfld: return(System.Reflection.Emit.OpCodes.Stsfld); case Code.Stobj: return(System.Reflection.Emit.OpCodes.Stobj); case Code.Conv_Ovf_I1_Un: return(System.Reflection.Emit.OpCodes.Conv_Ovf_I1_Un); case Code.Conv_Ovf_I2_Un: return(System.Reflection.Emit.OpCodes.Conv_Ovf_I2_Un); case Code.Conv_Ovf_I4_Un: return(System.Reflection.Emit.OpCodes.Conv_Ovf_I4_Un); case Code.Conv_Ovf_I8_Un: return(System.Reflection.Emit.OpCodes.Conv_Ovf_I8_Un); case Code.Conv_Ovf_U1_Un: return(System.Reflection.Emit.OpCodes.Conv_Ovf_U1_Un); case Code.Conv_Ovf_U2_Un: return(System.Reflection.Emit.OpCodes.Conv_Ovf_U2_Un); case Code.Conv_Ovf_U4_Un: return(System.Reflection.Emit.OpCodes.Conv_Ovf_U4_Un); case Code.Conv_Ovf_U8_Un: return(System.Reflection.Emit.OpCodes.Conv_Ovf_U8_Un); case Code.Conv_Ovf_I_Un: return(System.Reflection.Emit.OpCodes.Conv_Ovf_I_Un); case Code.Conv_Ovf_U_Un: return(System.Reflection.Emit.OpCodes.Conv_Ovf_U_Un); case Code.Box: return(System.Reflection.Emit.OpCodes.Box); case Code.Newarr: return(System.Reflection.Emit.OpCodes.Newarr); case Code.Ldlen: return(System.Reflection.Emit.OpCodes.Ldlen); case Code.Ldelema: return(System.Reflection.Emit.OpCodes.Ldelema); case Code.Ldelem_I1: return(System.Reflection.Emit.OpCodes.Ldelem_I1); case Code.Ldelem_U1: return(System.Reflection.Emit.OpCodes.Ldelem_U1); case Code.Ldelem_I2: return(System.Reflection.Emit.OpCodes.Ldelem_I2); case Code.Ldelem_U2: return(System.Reflection.Emit.OpCodes.Ldelem_U2); case Code.Ldelem_I4: return(System.Reflection.Emit.OpCodes.Ldelem_I4); case Code.Ldelem_U4: return(System.Reflection.Emit.OpCodes.Ldelem_U4); case Code.Ldelem_I8: return(System.Reflection.Emit.OpCodes.Ldelem_I8); case Code.Ldelem_I: return(System.Reflection.Emit.OpCodes.Ldelem_I); case Code.Ldelem_R4: return(System.Reflection.Emit.OpCodes.Ldelem_R4); case Code.Ldelem_R8: return(System.Reflection.Emit.OpCodes.Ldelem_R8); case Code.Ldelem_Ref: return(System.Reflection.Emit.OpCodes.Ldelem_Ref); case Code.Stelem_I: return(System.Reflection.Emit.OpCodes.Stelem_I); case Code.Stelem_I1: return(System.Reflection.Emit.OpCodes.Stelem_I1); case Code.Stelem_I2: return(System.Reflection.Emit.OpCodes.Stelem_I2); case Code.Stelem_I4: return(System.Reflection.Emit.OpCodes.Stelem_I4); case Code.Stelem_I8: return(System.Reflection.Emit.OpCodes.Stelem_I8); case Code.Stelem_R4: return(System.Reflection.Emit.OpCodes.Stelem_R4); case Code.Stelem_R8: return(System.Reflection.Emit.OpCodes.Stelem_R8); case Code.Stelem_Ref: return(System.Reflection.Emit.OpCodes.Stelem_Ref); case Code.Ldelem_Any: return(System.Reflection.Emit.OpCodes.Ldelem); // * case Code.Stelem_Any: return(System.Reflection.Emit.OpCodes.Stelem); // * case Code.Unbox_Any: return(System.Reflection.Emit.OpCodes.Unbox_Any); case Code.Conv_Ovf_I1: return(System.Reflection.Emit.OpCodes.Conv_Ovf_I1); case Code.Conv_Ovf_U1: return(System.Reflection.Emit.OpCodes.Conv_Ovf_U1); case Code.Conv_Ovf_I2: return(System.Reflection.Emit.OpCodes.Conv_Ovf_I2); case Code.Conv_Ovf_U2: return(System.Reflection.Emit.OpCodes.Conv_Ovf_U2); case Code.Conv_Ovf_I4: return(System.Reflection.Emit.OpCodes.Conv_Ovf_I4); case Code.Conv_Ovf_U4: return(System.Reflection.Emit.OpCodes.Conv_Ovf_U4); case Code.Conv_Ovf_I8: return(System.Reflection.Emit.OpCodes.Conv_Ovf_I8); case Code.Conv_Ovf_U8: return(System.Reflection.Emit.OpCodes.Conv_Ovf_U8); case Code.Refanyval: return(System.Reflection.Emit.OpCodes.Refanyval); case Code.Ckfinite: return(System.Reflection.Emit.OpCodes.Ckfinite); case Code.Mkrefany: return(System.Reflection.Emit.OpCodes.Mkrefany); case Code.Ldtoken: return(System.Reflection.Emit.OpCodes.Ldtoken); case Code.Conv_U2: return(System.Reflection.Emit.OpCodes.Conv_U2); case Code.Conv_U1: return(System.Reflection.Emit.OpCodes.Conv_U1); case Code.Conv_I: return(System.Reflection.Emit.OpCodes.Conv_I); case Code.Conv_Ovf_I: return(System.Reflection.Emit.OpCodes.Conv_Ovf_I); case Code.Conv_Ovf_U: return(System.Reflection.Emit.OpCodes.Conv_Ovf_U); case Code.Add_Ovf: return(System.Reflection.Emit.OpCodes.Add_Ovf); case Code.Add_Ovf_Un: return(System.Reflection.Emit.OpCodes.Add_Ovf_Un); case Code.Mul_Ovf: return(System.Reflection.Emit.OpCodes.Mul_Ovf); case Code.Mul_Ovf_Un: return(System.Reflection.Emit.OpCodes.Mul_Ovf_Un); case Code.Sub_Ovf: return(System.Reflection.Emit.OpCodes.Sub_Ovf); case Code.Sub_Ovf_Un: return(System.Reflection.Emit.OpCodes.Sub_Ovf_Un); case Code.Endfinally: return(System.Reflection.Emit.OpCodes.Endfinally); case Code.Leave: return(System.Reflection.Emit.OpCodes.Leave); case Code.Leave_S: return(System.Reflection.Emit.OpCodes.Leave_S); case Code.Stind_I: return(System.Reflection.Emit.OpCodes.Stind_I); case Code.Conv_U: return(System.Reflection.Emit.OpCodes.Conv_U); case Code.Arglist: return(System.Reflection.Emit.OpCodes.Arglist); case Code.Ceq: return(System.Reflection.Emit.OpCodes.Ceq); case Code.Cgt: return(System.Reflection.Emit.OpCodes.Cgt); case Code.Cgt_Un: return(System.Reflection.Emit.OpCodes.Cgt_Un); case Code.Clt: return(System.Reflection.Emit.OpCodes.Clt); case Code.Clt_Un: return(System.Reflection.Emit.OpCodes.Clt_Un); case Code.Ldftn: return(System.Reflection.Emit.OpCodes.Ldftn); case Code.Ldvirtftn: return(System.Reflection.Emit.OpCodes.Ldvirtftn); case Code.Ldarg: return(System.Reflection.Emit.OpCodes.Ldarg); case Code.Ldarga: return(System.Reflection.Emit.OpCodes.Ldarga); case Code.Starg: return(System.Reflection.Emit.OpCodes.Starg); case Code.Ldloc: return(System.Reflection.Emit.OpCodes.Ldloc); case Code.Ldloca: return(System.Reflection.Emit.OpCodes.Ldloca); case Code.Stloc: return(System.Reflection.Emit.OpCodes.Stloc); case Code.Localloc: return(System.Reflection.Emit.OpCodes.Localloc); case Code.Endfilter: return(System.Reflection.Emit.OpCodes.Endfilter); case Code.Unaligned: return(System.Reflection.Emit.OpCodes.Unaligned); case Code.Volatile: return(System.Reflection.Emit.OpCodes.Volatile); case Code.Tail: return(System.Reflection.Emit.OpCodes.Tailcall); // * case Code.Initobj: return(System.Reflection.Emit.OpCodes.Initobj); case Code.Constrained: return(System.Reflection.Emit.OpCodes.Constrained); case Code.Cpblk: return(System.Reflection.Emit.OpCodes.Cpblk); case Code.Initblk: return(System.Reflection.Emit.OpCodes.Initblk); //case Code.No: return System.Reflection.Emit.OpCodes.No; // no such opcode case Code.Rethrow: return(System.Reflection.Emit.OpCodes.Rethrow); case Code.Sizeof: return(System.Reflection.Emit.OpCodes.Sizeof); case Code.Refanytype: return(System.Reflection.Emit.OpCodes.Refanytype); case Code.Readonly: return(System.Reflection.Emit.OpCodes.Readonly); default: throw new NotSupportedException(string.Format("Unsupported opcode: {0}.", cecilOpcode)); } }
public void Emit(OpCode opcode, CallSite site) => _Insert(IL.Create(opcode, site));
public void Emit(OpCode opcode, int value) => _Insert(IL.Create(opcode, value));
public void Emit(OpCode opcode, FieldInfo field) => _Insert(IL.Create(opcode, field));
public void Emit(OpCode opcode, VariableDefinition variable) => _Insert(IL.Create(opcode, variable));
public void Emit(OpCode opcode, object operand) => _Insert(IL.Create(opcode, operand));
public void Add(OpCode opcode, FieldReference op) => Add(Instruction.Create(opcode, op));
public void Add(OpCode opcode, Instruction op) => Add(Instruction.Create(opcode, op));
public void Emit(OpCode opcode, FieldReference field) => _Insert(IL.Create(opcode, field));
private void ExtractBasicBlocksOfMethod(MethodReference method_reference) { MethodReference original_method_reference = method_reference; _methods_done.Add(original_method_reference.FullName); // MethodReference new_method_reference = original_method_reference.SubstituteMethod2(); // method_reference = new_method_reference != null ? new_method_reference : original_method_reference; MethodDefinition method_definition = method_reference.Resolve(); if (method_definition == null || method_definition.Body == null) { return; } int change_set = Cfg.StartChangeSet(); int instruction_count = method_definition.Body.Instructions.Count; List <INST> split_point = new List <INST>(); CFG.Vertex basic_block = (CFG.Vertex)Cfg.AddVertex(new CFG.Vertex() { Name = Cfg.NewNodeNumber().ToString() }); basic_block._method_definition = method_definition; basic_block._method_reference = original_method_reference; basic_block.Entry = basic_block; basic_block.Exit = basic_block; basic_block.Entry.BlocksOfMethod = new List <CFG.Vertex>(); basic_block.Entry.BlocksOfMethod.Add(basic_block); Cfg.Entries.Add(basic_block); // Add instructions to the basic block, including debugging information. // First, get debugging information on line/column/offset in method. if (!original_method_reference.Module.HasSymbols) { // Try to get symbols, but if none available, don't worry about it. try { original_method_reference.Module.ReadSymbols(); } catch { } } var symbol_reader = original_method_reference.Module.SymbolReader; var method_debug_information = symbol_reader?.Read(method_definition); Collection <SequencePoint> sequence_points = method_debug_information != null ? method_debug_information.SequencePoints : new Collection <SequencePoint>(); Mono.Cecil.Cil.MethodBody body = method_definition.Body; if (body == null) { throw new Exception("Body null, not expecting it to be."); } if (body.Instructions == null) { throw new Exception("Body has instructions collection."); } if (body.Instructions.Count == 0) { throw new Exception("Body instruction count is zero."); } SequencePoint previous_sp = null; for (int j = 0; j < instruction_count; ++j) { Mono.Cecil.Cil.Instruction instruction = body.Instructions[j]; SequencePoint sp = sequence_points.Where(s => { return(s.Offset == instruction.Offset); }).FirstOrDefault(); if (sp == null) { sp = previous_sp; } INST wrapped_instruction = INST.Wrap(instruction, basic_block, sp); basic_block.Instructions.Add(wrapped_instruction); if (sp != null) { previous_sp = sp; } } var instructions_before_splits = basic_block.Instructions.ToList(); // Accumulate targets of jumps. These are split points for block "v". // Accumalated splits are in "leader_list" following this for-loop. for (int j = 0; j < instruction_count; ++j) { INST wrapped_instruction = basic_block.Instructions[j]; Mono.Cecil.Cil.OpCode opcode = wrapped_instruction.OpCode; Mono.Cecil.Cil.FlowControl flow_control = opcode.FlowControl; switch (flow_control) { case Mono.Cecil.Cil.FlowControl.Branch: case Mono.Cecil.Cil.FlowControl.Cond_Branch: { object operand = wrapped_instruction.Operand; // Two cases of branches: // 1) operand is a single instruction; // 2) operand is an array of instructions via a switch instruction. // In doing this type casting, the resulting instructions are turned // into def's, and operands no longer correspond to what was in the original // method. We override the List<> compare to correct this problem. Mono.Cecil.Cil.Instruction single_instruction = operand as Mono.Cecil.Cil.Instruction; Mono.Cecil.Cil.Instruction[] array_of_instructions = operand as Mono.Cecil.Cil.Instruction[]; if (single_instruction != null) { INST sp = null; for (int i = 0; i < basic_block.Instructions.Count(); ++i) { if (basic_block.Instructions[i].Offset == single_instruction.Offset && basic_block.Instructions[i].OpCode == single_instruction.OpCode) { sp = basic_block.Instructions[i]; break; } } if (sp == null) { throw new Exception("Instruction go to not found."); } bool found = false; foreach (INST split in split_point) { if (split.Offset == sp.Offset && split.OpCode == sp.OpCode) { found = true; break; } } if (!found) { split_point.Add(sp); } } else if (array_of_instructions != null) { foreach (var ins in array_of_instructions) { Debug.Assert(ins != null); INST sp = null; for (int i = 0; i < basic_block.Instructions.Count(); ++i) { if (basic_block.Instructions[i].Offset == ins.Offset && basic_block.Instructions[i].OpCode == ins.OpCode) { sp = basic_block.Instructions[i]; break; } } if (sp == null) { throw new Exception("Instruction go to not found."); } bool found = false; foreach (INST split in split_point) { if (split.Offset == sp.Offset && split.OpCode == sp.OpCode) { found = true; break; } } if (!found) { split_point.Add(sp); } } } else { throw new Exception("Unknown operand type for basic block partitioning."); } } break; } // Split blocks after certain instructions, too. switch (flow_control) { case Mono.Cecil.Cil.FlowControl.Branch: case Mono.Cecil.Cil.FlowControl.Call: case Mono.Cecil.Cil.FlowControl.Cond_Branch: case Mono.Cecil.Cil.FlowControl.Return: case Mono.Cecil.Cil.FlowControl.Throw: { if (flow_control == Mono.Cecil.Cil.FlowControl.Call && !Campy.Utils.Options.IsOn("split_at_calls")) { break; } if (j + 1 < instruction_count) { var ins = basic_block.Instructions[j + 1].Instruction; INST sp = null; for (int i = 0; i < basic_block.Instructions.Count(); ++i) { if (basic_block.Instructions[i].Offset == ins.Offset && basic_block.Instructions[i].OpCode == ins.OpCode) { sp = basic_block.Instructions[i]; break; } } if (sp == null) { throw new Exception("Instruction go to not found."); } bool found = false; foreach (INST split in split_point) { if (split.Offset == sp.Offset && split.OpCode == sp.OpCode) { found = true; break; } } if (!found) { split_point.Add(sp); } } } break; } } // Get try-catch blocks and add those split points. foreach (var eh in body.ExceptionHandlers) { var start = eh.TryStart; var end = eh.TryEnd; // Split at try start. Instruction ins = start; INST sp = null; for (int i = 0; i < basic_block.Instructions.Count(); ++i) { if (basic_block.Instructions[i].Offset == ins.Offset && basic_block.Instructions[i].OpCode == ins.OpCode) { sp = basic_block.Instructions[i]; break; } } if (sp == null) { throw new Exception("Instruction go to not found."); } bool found = false; foreach (INST split in split_point) { if (split.Offset == sp.Offset && split.OpCode == sp.OpCode) { found = true; break; } } if (!found) { split_point.Add(sp); } } // Note, we assume that these splits are within the same method. // Order the list according to offset from beginning of the method. List <INST> ordered_leader_list = new List <INST>(); for (int j = 0; j < instruction_count; ++j) { // Order jump targets. These denote locations // where to split blocks. However, it's ordered, // so that splitting is done from last instruction in block // to first instruction in block. INST i = basic_block.Instructions[j]; if (split_point.Contains(i, new LambdaComparer <INST>( (INST a, INST b) => { if (a.Offset != b.Offset) { return(false); } if (a.OpCode != b.OpCode) { return(false); } return(true); }))) { ordered_leader_list.Add(i); } } if (ordered_leader_list.Count != split_point.Count) { throw new Exception( "Mono Cecil giving weird results for instruction operand type casting. Size of original split points not the same as order list of split points."); } // Split block at all jump targets. foreach (INST i in ordered_leader_list) { var owner = Cfg.PeekChangeSet(change_set).Where( n => n.Instructions.Where(ins => { if (ins.Offset != i.Offset) { return(false); } if (ins.OpCode != i.OpCode) { return(false); } return(true); } ).Any()).ToList(); // Check if there are multiple nodes with the same instruction or if there isn't // any node found containing the instruction. Either way, it's a programming error. if (owner.Count != 1) { throw new Exception("Cannot find instruction!"); } CFG.Vertex target_node = owner.FirstOrDefault(); var j = target_node.Instructions.FindIndex(a => { if (a.Offset != i.Offset) { return(false); } if (a.OpCode != i.OpCode) { return(false); } return(true); }); CFG.Vertex new_node = Split(target_node, j); } LambdaComparer <Instruction> fixed_comparer = new LambdaComparer <Instruction>( (Instruction a, Instruction b) => a.Offset == b.Offset && a.OpCode == b.OpCode ); // Add in all edges. var list_new_nodes = Cfg.PopChangeSet(change_set); foreach (var node in list_new_nodes) { int node_instruction_count = node.Instructions.Count; INST last_instruction = node.Instructions[node_instruction_count - 1]; Mono.Cecil.Cil.OpCode opcode = last_instruction.OpCode; Mono.Cecil.Cil.FlowControl flow_control = opcode.FlowControl; // Add jump edge. switch (flow_control) { case Mono.Cecil.Cil.FlowControl.Branch: case Mono.Cecil.Cil.FlowControl.Cond_Branch: { // Two cases: i.Operand is a single instruction, or an array of instructions. if (last_instruction.Operand as Mono.Cecil.Cil.Instruction != null) { // Handel leave instructions with code below. if (!(last_instruction.OpCode.Code == Code.Leave || last_instruction.OpCode.Code == Code.Leave_S)) { Mono.Cecil.Cil.Instruction target_instruction = last_instruction.Operand as Mono.Cecil.Cil.Instruction; CFG.Vertex target_node = list_new_nodes.FirstOrDefault( (CFG.Vertex x) => { if (!fixed_comparer.Equals(x.Instructions.First().Instruction, target_instruction)) { return(false); } return(true); }); if (target_node != null) { Cfg.AddEdge(new CFG.Edge() { From = node, To = target_node }); } } } else if (last_instruction.Operand as Mono.Cecil.Cil.Instruction[] != null) { foreach (Mono.Cecil.Cil.Instruction target_instruction in (last_instruction.Operand as Mono.Cecil.Cil.Instruction[])) { CFG.Vertex target_node = list_new_nodes.FirstOrDefault( (CFG.Vertex x) => { if (!fixed_comparer.Equals(x.Instructions.First().Instruction, target_instruction)) { return(false); } return(true); }); if (target_node != null) { Cfg.AddEdge(new CFG.Edge() { From = node, To = target_node }); } } } else { throw new Exception("Unknown operand type for conditional branch."); } break; } } // Add fall through edge. switch (flow_control) { //case Mono.Cecil.Cil.FlowControl.Branch: //case Mono.Cecil.Cil.FlowControl.Break: case Mono.Cecil.Cil.FlowControl.Call: case Mono.Cecil.Cil.FlowControl.Cond_Branch: case Mono.Cecil.Cil.FlowControl.Meta: case Mono.Cecil.Cil.FlowControl.Next: case Mono.Cecil.Cil.FlowControl.Phi: case Mono.Cecil.Cil.FlowControl.Throw: { int next = instructions_before_splits.FindIndex( n => { var r = n == last_instruction; return(r); } ); if (next < 0) { break; } next += 1; if (next >= instructions_before_splits.Count) { break; } var next_instruction = instructions_before_splits[next]; var owner = next_instruction.Block; CFG.Vertex target_node = owner; Cfg.AddEdge(new CFG.Edge() { From = node, To = target_node }); } break; case Mono.Cecil.Cil.FlowControl.Return: if (last_instruction.Instruction.OpCode.Code == Code.Endfinally) { // Although the exception handling is like a procedure call, // local variables are all accessible. So, we need to copy stack // values around. In addition, we have to create a fall through // even though there is stack unwinding. int next = instructions_before_splits.FindIndex( n => { var r = n == last_instruction; return(r); } ); if (next < 0) { break; } next += 1; if (next >= instructions_before_splits.Count) { break; } var next_instruction = instructions_before_splits[next]; var owner = next_instruction.Block; CFG.Vertex target_node = owner; Cfg.AddEdge(new CFG.Edge() { From = node, To = target_node }); } break; } } // Get inclusive start/exclusive end ranges of try/catch/finally. Dictionary <int, int> exclusive_eh_range = new Dictionary <int, int>(); foreach (var eh in body.ExceptionHandlers) { int try_start = eh.TryStart.Offset; int eh_end = eh.TryEnd != null ? eh.TryEnd.Offset : 0; if (eh.TryEnd != null && eh.TryEnd.Offset > eh_end) { eh_end = eh.TryEnd.Offset; } if (eh.HandlerEnd != null && eh.HandlerEnd.Offset > eh_end) { eh_end = eh.HandlerEnd.Offset; } exclusive_eh_range[try_start] = eh_end; } // Get inclusive start/inclusive end ranges of try/catch/finally. Dictionary <int, int> inclusive_eh_range = new Dictionary <int, int>(); foreach (var pair in exclusive_eh_range) { int previous_instruction_address = 0; foreach (var i in body.Instructions) { if (pair.Value == i.Offset) { inclusive_eh_range[pair.Key] = previous_instruction_address; break; } previous_instruction_address = i.Offset; } } // Get "finally" blocks for each try, if there is one. Dictionary <int, CFG.Vertex> try_finally_block = new Dictionary <int, CFG.Vertex>(); foreach (var eh in body.ExceptionHandlers) { if (eh.HandlerType == ExceptionHandlerType.Finally) { var finally_entry_block = list_new_nodes.Where( n => { var first = n.Instructions.First().Instruction; if (first.Offset == eh.HandlerStart.Offset) { return(true); } else { return(false); } }).First(); try_finally_block[eh.TryStart.Offset] = finally_entry_block; } } // Set block properties. foreach (var eh in body.ExceptionHandlers) { var block = list_new_nodes.Where( n => { var first = n.Instructions.First().Instruction; if (first.Offset == eh.HandlerStart.Offset) { return(true); } else { return(false); } }).First(); block.CatchType = eh.CatchType; block.IsCatch = eh.HandlerType == ExceptionHandlerType.Catch; block.ExceptionHandler = eh; } // Get "try" block for each try. Dictionary <int, CFG.Vertex> try_entry_block = new Dictionary <int, CFG.Vertex>(); foreach (var pair in inclusive_eh_range) { int start = pair.Key; var entry_block = list_new_nodes.Where( n => { var first = n.Instructions.First().Instruction; if (first.Offset == start) { return(true); } else { return(false); } }).First(); try_entry_block[start] = entry_block; } // Get entry block for each exception handler. Dictionary <int, CFG.Vertex> eh_entry_block = new Dictionary <int, CFG.Vertex>(); foreach (var eh in body.ExceptionHandlers) { int start = eh.HandlerStart.Offset; var entry_block = list_new_nodes.Where( n => { var first = n.Instructions.First().Instruction; if (first.Offset == start) { return(true); } else { return(false); } }).First(); eh_entry_block[start] = entry_block; } foreach (var eh in body.ExceptionHandlers) { int start = eh.TryStart.Offset; var try_block = try_entry_block[start]; int eh_start = eh.HandlerStart.Offset; var eh_block = eh_entry_block[eh_start]; if (eh.HandlerType == ExceptionHandlerType.Finally) { continue; } foreach (var prev in list_new_nodes.First()._graph.Predecessors(try_block)) { Cfg.AddEdge(new CFG.Edge() { From = prev, To = eh_block }); } } // Go through all CIL "leave" instructions and draw up edges. Any leave to end of // endfinally block requires edge to finally block, not the following instruction. foreach (var node in list_new_nodes) { int node_instruction_count = node.Instructions.Count; INST leave_instruction = node.Instructions[node_instruction_count - 1]; Mono.Cecil.Cil.OpCode opcode = leave_instruction.OpCode; Mono.Cecil.Cil.FlowControl flow_control = opcode.FlowControl; if (!(leave_instruction.OpCode.Code == Code.Leave || leave_instruction.OpCode.Code == Code.Leave_S)) { continue; } // Link up any leave instructions object operand = leave_instruction.Operand; Mono.Cecil.Cil.Instruction single_instruction = operand as Mono.Cecil.Cil.Instruction; Mono.Cecil.Cil.Instruction[] array_of_instructions = operand as Mono.Cecil.Cil.Instruction[]; if (single_instruction == null) { throw new Exception("Malformed leave instruction."); } KeyValuePair <int, int> pair = inclusive_eh_range.Where(p => p.Key <= leave_instruction.Instruction.Offset && leave_instruction.Instruction.Offset <= p.Value).FirstOrDefault(); // pair indicates what try/catch/finally block. If not in a try/catch/finally, // draw edge to destination. If the destination is outside try/catch/finally, // draw edge to destination. if (pair.Value == 0 || single_instruction.Offset >= pair.Key && single_instruction.Offset <= pair.Value) { var whereever = list_new_nodes.Where( n => { var first = n.Instructions.First().Instruction; if (first.Offset == single_instruction.Offset) { return(true); } else { return(false); } }).First(); Cfg.AddEdge(new CFG.Edge() { From = node, To = whereever }); continue; } if (try_finally_block.ContainsKey(pair.Key)) { Cfg.AddEdge(new CFG.Edge() { From = node, To = try_finally_block[pair.Key] }); } else { var whereever = list_new_nodes.Where( n => { var first = n.Instructions.First().Instruction; if (first.Offset == single_instruction.Offset) { return(true); } else { return(false); } }).First(); Cfg.AddEdge(new CFG.Edge() { From = node, To = whereever }); } } if (Campy.Utils.Options.IsOn("detailed_import_computation_trace")) { Cfg.OutputDotGraph(); } if (Campy.Utils.Options.IsOn("detailed_import_computation_trace")) { Cfg.OutputEntireGraph(); } }
public void Emit(OpCode opcode, MethodBase method) => _Insert(IL.Create(opcode, method));
private void ExtractBasicBlocksOfMethod(Tuple <MethodReference, List <TypeReference> > definition) { MethodReference method_reference = definition.Item1; MethodReference original_method_reference = method_reference; _methods_done.Add(original_method_reference.FullName); MethodDefinition method_definition = Rewrite(original_method_reference); if (method_definition == null || method_definition.Body == null) { return; } _methods_done.Add(method_definition.FullName); int change_set = Cfg.StartChangeSet(); int instruction_count = method_definition.Body.Instructions.Count; List <Mono.Cecil.Cil.Instruction> split_point = new List <Mono.Cecil.Cil.Instruction>(); // Each method is a leader of a block. CFG.Vertex basic_block = (CFG.Vertex)Cfg.AddVertex(new CFG.Vertex() { Name = Cfg.NewNodeNumber().ToString() }); basic_block._method_definition = method_definition; basic_block._original_method_reference = original_method_reference; basic_block.Entry = basic_block; Cfg.Entries.Add(basic_block); // Add instructions to the basic block, including debugging information. // First, get debugging information on line/column/offset in method. if (!original_method_reference.Module.HasSymbols) { // Try to get symbols, but if none available, don't worry about it. try { original_method_reference.Module.ReadSymbols(); } catch { } } var symbol_reader = original_method_reference.Module.SymbolReader; var method_debug_information = symbol_reader?.Read(method_definition); Collection <SequencePoint> sequence_points = method_debug_information != null ? method_debug_information.SequencePoints : new Collection <SequencePoint>(); Mono.Cecil.Cil.MethodBody body = method_definition.Body; if (body == null) { throw new Exception("Body null, not expecting it to be."); } if (body.Instructions == null) { throw new Exception("Body has instructions collection."); } if (body.Instructions.Count == 0) { throw new Exception("Body instruction count is zero."); } for (int j = 0; j < instruction_count; ++j) { Mono.Cecil.Cil.Instruction instruction = body.Instructions[j]; INST wrapped_instruction = INST.Wrap(instruction, body, basic_block, sequence_points.Where(sp => { return(sp.Offset == instruction.Offset); }).FirstOrDefault()); basic_block.Instructions.Add(wrapped_instruction); } // Accumulate targets of jumps. These are split points for block "v". // Accumalated splits are in "leader_list" following this for-loop. for (int j = 0; j < instruction_count; ++j) { INST wrapped_instruction = basic_block.Instructions[j]; Mono.Cecil.Cil.OpCode opcode = wrapped_instruction.OpCode; Mono.Cecil.Cil.FlowControl flow_control = opcode.FlowControl; switch (flow_control) { case Mono.Cecil.Cil.FlowControl.Branch: case Mono.Cecil.Cil.FlowControl.Cond_Branch: { object operand = wrapped_instruction.Operand; // Two cases of branches: // 1) operand is a single instruction; // 2) operand is an array of instructions via a switch instruction. Mono.Cecil.Cil.Instruction single_instruction = operand as Mono.Cecil.Cil.Instruction; Mono.Cecil.Cil.Instruction[] array_of_instructions = operand as Mono.Cecil.Cil.Instruction[]; if (single_instruction != null) { if (!split_point.Contains(single_instruction)) { split_point.Add(single_instruction); } } else if (array_of_instructions != null) { foreach (var ins in array_of_instructions) { Debug.Assert(ins != null); if (!split_point.Contains(single_instruction)) { split_point.Add(ins); } } } else { throw new Exception("Unknown operand type for basic block partitioning."); } } break; } // Split blocks after certain instructions, too. switch (flow_control) { case Mono.Cecil.Cil.FlowControl.Branch: case Mono.Cecil.Cil.FlowControl.Call: case Mono.Cecil.Cil.FlowControl.Cond_Branch: case Mono.Cecil.Cil.FlowControl.Return: case Mono.Cecil.Cil.FlowControl.Throw: { if (flow_control == Mono.Cecil.Cil.FlowControl.Call && !Campy.Utils.Options.IsOn("split_at_calls")) { break; } if (j + 1 < instruction_count) { var ins = basic_block.Instructions[j + 1].Instruction; if (!split_point.Contains(ins)) { split_point.Add(ins); } } } break; } } // Note, we assume that these splits are within the same method. // Order the list according to offset from beginning of the method. List <Mono.Cecil.Cil.Instruction> ordered_leader_list = new List <Mono.Cecil.Cil.Instruction>(); for (int j = 0; j < instruction_count; ++j) { // Order jump targets. These denote locations // where to split blocks. However, it's ordered, // so that splitting is done from last instruction in block // to first instruction in block. Mono.Cecil.Cil.Instruction i = method_definition.Body.Instructions[j]; if (split_point.Contains(i)) { ordered_leader_list.Add(i); } } // Split block at all jump targets. foreach (var i in ordered_leader_list) { var owner = Cfg.Vertices.Where( n => n.Instructions.Where(ins => ins.Instruction == i).Any()).ToList(); // Check if there are multiple nodes with the same instruction or if there isn't // any node found containing the instruction. Either way, it's a programming error. if (owner.Count != 1) { throw new Exception("Cannot find instruction!"); } CFG.Vertex target_node = owner.FirstOrDefault(); var j = target_node.Instructions.FindIndex(a => a.Instruction == i); CFG.Vertex new_node = Split(target_node, j); } // Add in all edges. var list_new_nodes = Cfg.PopChangeSet(change_set); foreach (var node in list_new_nodes) { int node_instruction_count = node.Instructions.Count; INST last_instruction = node.Instructions[node_instruction_count - 1]; Mono.Cecil.Cil.OpCode opcode = last_instruction.OpCode; Mono.Cecil.Cil.FlowControl flow_control = opcode.FlowControl; // Add jump edge. switch (flow_control) { case Mono.Cecil.Cil.FlowControl.Branch: case Mono.Cecil.Cil.FlowControl.Cond_Branch: { // Two cases: i.Operand is a single instruction, or an array of instructions. if (last_instruction.Operand as Mono.Cecil.Cil.Instruction != null) { Mono.Cecil.Cil.Instruction target_instruction = last_instruction.Operand as Mono.Cecil.Cil.Instruction; CFG.Vertex target_node = Cfg.Vertices.FirstOrDefault( (CFG.Vertex x) => { if (!x.Instructions.First().Instruction.Equals(target_instruction)) { return(false); } return(true); }); if (target_node != null) { Cfg.AddEdge(new CFG.Edge() { From = node, To = target_node }); } } else if (last_instruction.Operand as Mono.Cecil.Cil.Instruction[] != null) { foreach (Mono.Cecil.Cil.Instruction target_instruction in (last_instruction.Operand as Mono.Cecil.Cil.Instruction[])) { CFG.Vertex target_node = Cfg.Vertices.FirstOrDefault( (CFG.Vertex x) => { if (!x.Instructions.First().Instruction.Equals(target_instruction)) { return(false); } return(true); }); if (target_node != null) { Cfg.AddEdge(new CFG.Edge() { From = node, To = target_node }); } } } else { throw new Exception("Unknown operand type for conditional branch."); } break; } } // Add fall through edge. switch (flow_control) { //case Mono.Cecil.Cil.FlowControl.Branch: //case Mono.Cecil.Cil.FlowControl.Break: case Mono.Cecil.Cil.FlowControl.Call: case Mono.Cecil.Cil.FlowControl.Cond_Branch: case Mono.Cecil.Cil.FlowControl.Meta: case Mono.Cecil.Cil.FlowControl.Next: case Mono.Cecil.Cil.FlowControl.Phi: //case Mono.Cecil.Cil.FlowControl.Return: case Mono.Cecil.Cil.FlowControl.Throw: { int next = method_definition.Body.Instructions.ToList().FindIndex( n => { var r = n == last_instruction.Instruction && n.Offset == last_instruction.Instruction.Offset ; return(r); } ); if (next < 0) { break; } next += 1; if (next >= method_definition.Body.Instructions.Count) { break; } var next_instruction = method_definition.Body.Instructions[next]; var owner = Cfg.Vertices.Where( n => n.Instructions.Where(ins => ins.Instruction == next_instruction).Any()).ToList(); if (owner.Count != 1) { throw new Exception("Cannot find instruction!"); } CFG.Vertex target_node = owner.FirstOrDefault(); Cfg.AddEdge(new CFG.Edge() { From = node, To = target_node }); } break; } } Cfg.OutputDotGraph(); Cfg.OutputEntireGraph(); }
public FluentEmitter Emit(OpCode opcode, SystemTypeOrTypeReference arg) { return(Emit(Instruction.Create(opcode, arg.GetTypeReference(Module)))); }
public void Emit(OpCode opcode, ParameterDefinition parameter) => _Insert(IL.Create(opcode, parameter));
public void Emit(OpCode opcode, Instruction target) => _Insert(IL.Create(opcode, target));