Ejemplo n.º 1
0
 private void ExtractInstructions(IEnumerable <Cecil.Cil.Instruction> operations, IList <AnalysisNet.IInstruction> instructions)
 {
     foreach (Cecil.Cil.Instruction op in operations)
     {
         AnalysisNet.IInstruction instruction = ExtractInstruction(op);
         instructions.Add(instruction);
     }
 }
Ejemplo n.º 2
0
        private AnalysisNet.IInstruction ExtractInstruction(Cecil.Cil.Instruction operation)
        {
            AnalysisNet.IInstruction instruction = null;

            // cecil does not have an enum we require it for the switch statement
            Cecil.Cil.Code code = operation.OpCode.Code;
            switch (code)
            {
            case Mono.Cecil.Cil.Code.Add:
            case Mono.Cecil.Cil.Code.Add_Ovf:
            case Mono.Cecil.Cil.Code.Add_Ovf_Un:
            case Mono.Cecil.Cil.Code.And:
            case Mono.Cecil.Cil.Code.Ceq:
            case Mono.Cecil.Cil.Code.Cgt:
            case Mono.Cecil.Cil.Code.Cgt_Un:
            case Mono.Cecil.Cil.Code.Clt:
            case Mono.Cecil.Cil.Code.Clt_Un:
            case Mono.Cecil.Cil.Code.Div:
            case Mono.Cecil.Cil.Code.Div_Un:
            case Mono.Cecil.Cil.Code.Mul:
            case Mono.Cecil.Cil.Code.Mul_Ovf:
            case Mono.Cecil.Cil.Code.Mul_Ovf_Un:
            case Mono.Cecil.Cil.Code.Or:
            case Mono.Cecil.Cil.Code.Rem:
            case Mono.Cecil.Cil.Code.Rem_Un:
            case Mono.Cecil.Cil.Code.Shl:
            case Mono.Cecil.Cil.Code.Shr:
            case Mono.Cecil.Cil.Code.Shr_Un:
            case Mono.Cecil.Cil.Code.Sub:
            case Mono.Cecil.Cil.Code.Sub_Ovf:
            case Mono.Cecil.Cil.Code.Sub_Ovf_Un:
            case Mono.Cecil.Cil.Code.Xor:
                instruction = ProcessBasic(operation);
                break;

            //case Mono.Cecil.Cil.Code.Arglist:
            //    //expression = new RuntimeArgumentHandleExpression();
            //    break;

            //case Mono.Cecil.Cil.Code.Array_Create_WithLowerBound:
            //case Mono.Cecil.Cil.Code.Array_Create:
            case Mono.Cecil.Cil.Code.Newarr:
                instruction = ProcessCreateArray(operation);
                break;

            //case Mono.Cecil.Cil.Code.Array_Get:
            //    instruction = ProcessLoadArrayElement(operation, AnalysisNetBytecode.LoadArrayElementOperation.Content);
            //    break;
            //case Mono.Cecil.Cil.Code.Array_Addr:
            //    instruction = ProcessLoadArrayElement(operation, AnalysisNetBytecode.LoadArrayElementOperation.Address);
            //    break;

            //case Mono.Cecil.Cil.Code.Ldelem:
            case Mono.Cecil.Cil.Code.Ldelem_Any:
            case Mono.Cecil.Cil.Code.Ldelem_I:
            case Mono.Cecil.Cil.Code.Ldelem_I1:
            case Mono.Cecil.Cil.Code.Ldelem_I2:
            case Mono.Cecil.Cil.Code.Ldelem_I4:
            case Mono.Cecil.Cil.Code.Ldelem_I8:
            case Mono.Cecil.Cil.Code.Ldelem_R4:
            case Mono.Cecil.Cil.Code.Ldelem_R8:
            case Mono.Cecil.Cil.Code.Ldelem_U1:
            case Mono.Cecil.Cil.Code.Ldelem_U2:
            case Mono.Cecil.Cil.Code.Ldelem_U4:
            case Mono.Cecil.Cil.Code.Ldelem_Ref:
                instruction = ProcessLoadArrayElement(operation, AnalysisNetBytecode.LoadArrayElementOperation.Content);
                break;

            case Mono.Cecil.Cil.Code.Ldelema:
                instruction = ProcessLoadArrayElement(operation, AnalysisNetBytecode.LoadArrayElementOperation.Address);
                break;

            case Mono.Cecil.Cil.Code.Beq:
            case Mono.Cecil.Cil.Code.Beq_S:
            case Mono.Cecil.Cil.Code.Bne_Un:
            case Mono.Cecil.Cil.Code.Bne_Un_S:
            case Mono.Cecil.Cil.Code.Bge:
            case Mono.Cecil.Cil.Code.Bge_S:
            case Mono.Cecil.Cil.Code.Bge_Un:
            case Mono.Cecil.Cil.Code.Bge_Un_S:
            case Mono.Cecil.Cil.Code.Bgt:
            case Mono.Cecil.Cil.Code.Bgt_S:
            case Mono.Cecil.Cil.Code.Bgt_Un:
            case Mono.Cecil.Cil.Code.Bgt_Un_S:
            case Mono.Cecil.Cil.Code.Ble:
            case Mono.Cecil.Cil.Code.Ble_S:
            case Mono.Cecil.Cil.Code.Ble_Un:
            case Mono.Cecil.Cil.Code.Ble_Un_S:
            case Mono.Cecil.Cil.Code.Blt:
            case Mono.Cecil.Cil.Code.Blt_S:
            case Mono.Cecil.Cil.Code.Blt_Un:
            case Mono.Cecil.Cil.Code.Blt_Un_S:
                instruction = ProcessBinaryConditionalBranch(operation);
                break;

            case Mono.Cecil.Cil.Code.Br:
            case Mono.Cecil.Cil.Code.Br_S:
                instruction = ProcessUnconditionalBranch(operation);
                break;

            case Mono.Cecil.Cil.Code.Leave:
            case Mono.Cecil.Cil.Code.Leave_S:
                instruction = ProcessLeave(operation);
                break;

            case Mono.Cecil.Cil.Code.Break:
                instruction = ProcessBasic(operation);
                break;

            case Mono.Cecil.Cil.Code.Nop:
                instruction = ProcessBasic(operation);
                break;

            case Mono.Cecil.Cil.Code.Brfalse:
            case Mono.Cecil.Cil.Code.Brfalse_S:
            case Mono.Cecil.Cil.Code.Brtrue:
            case Mono.Cecil.Cil.Code.Brtrue_S:
                instruction = ProcessUnaryConditionalBranch(operation);
                break;

            case Mono.Cecil.Cil.Code.Call:
            case Mono.Cecil.Cil.Code.Callvirt:
            case Mono.Cecil.Cil.Code.Jmp:
                instruction = ProcessMethodCall(operation);
                break;

            case Mono.Cecil.Cil.Code.Calli:
                instruction = ProcessMethodCallIndirect(operation);
                break;

            case Mono.Cecil.Cil.Code.Castclass:
            case Mono.Cecil.Cil.Code.Isinst:
            case Mono.Cecil.Cil.Code.Box:
            case Mono.Cecil.Cil.Code.Unbox:
            case Mono.Cecil.Cil.Code.Unbox_Any:
            case Mono.Cecil.Cil.Code.Conv_I:
            case Mono.Cecil.Cil.Code.Conv_Ovf_I:
            case Mono.Cecil.Cil.Code.Conv_Ovf_I_Un:
            case Mono.Cecil.Cil.Code.Conv_I1:
            case Mono.Cecil.Cil.Code.Conv_Ovf_I1:
            case Mono.Cecil.Cil.Code.Conv_Ovf_I1_Un:
            case Mono.Cecil.Cil.Code.Conv_I2:
            case Mono.Cecil.Cil.Code.Conv_Ovf_I2:
            case Mono.Cecil.Cil.Code.Conv_Ovf_I2_Un:
            case Mono.Cecil.Cil.Code.Conv_I4:
            case Mono.Cecil.Cil.Code.Conv_Ovf_I4:
            case Mono.Cecil.Cil.Code.Conv_Ovf_I4_Un:
            case Mono.Cecil.Cil.Code.Conv_I8:
            case Mono.Cecil.Cil.Code.Conv_Ovf_I8:
            case Mono.Cecil.Cil.Code.Conv_Ovf_I8_Un:
            case Mono.Cecil.Cil.Code.Conv_U:
            case Mono.Cecil.Cil.Code.Conv_Ovf_U:
            case Mono.Cecil.Cil.Code.Conv_Ovf_U_Un:
            case Mono.Cecil.Cil.Code.Conv_U1:
            case Mono.Cecil.Cil.Code.Conv_Ovf_U1:
            case Mono.Cecil.Cil.Code.Conv_Ovf_U1_Un:
            case Mono.Cecil.Cil.Code.Conv_U2:
            case Mono.Cecil.Cil.Code.Conv_Ovf_U2:
            case Mono.Cecil.Cil.Code.Conv_Ovf_U2_Un:
            case Mono.Cecil.Cil.Code.Conv_U4:
            case Mono.Cecil.Cil.Code.Conv_Ovf_U4:
            case Mono.Cecil.Cil.Code.Conv_Ovf_U4_Un:
            case Mono.Cecil.Cil.Code.Conv_U8:
            case Mono.Cecil.Cil.Code.Conv_Ovf_U8:
            case Mono.Cecil.Cil.Code.Conv_Ovf_U8_Un:
            case Mono.Cecil.Cil.Code.Conv_R4:
            case Mono.Cecil.Cil.Code.Conv_R8:
            case Mono.Cecil.Cil.Code.Conv_R_Un:
                instruction = ProcessConversion(operation);
                break;

            //case Mono.Cecil.Cil.Code.Ckfinite:
            //    var operand = result = PopOperandStack();
            //    var chkfinite = new MutableCodeModel.MethodReference()
            //    {
            //        CallingConvention = Cci.CallingConvention.FastCall,
            //        ContainingType = host.PlatformType.SystemFloat64,
            //        Name = result = host.NameTable.GetNameFor("__ckfinite__"),
            //        Type = host.PlatformType.SystemFloat64,
            //        InternFactory = host.InternFactory,
            //    };
            //    expression = new MethodCall() { Arguments = new List<IExpression>(1) { operand }, IsStaticCall = true, Type = operand.Type, MethodToCall = chkfinite };
            //    break;

            case Mono.Cecil.Cil.Code.Constrained:
                instruction = ProcessConstrained(operation);
                break;

            case Mono.Cecil.Cil.Code.Cpblk:
                instruction = ProcessBasic(operation);
                break;

            case Mono.Cecil.Cil.Code.Cpobj:
                instruction = ProcessBasic(operation);
                break;

            case Mono.Cecil.Cil.Code.Dup:
                instruction = ProcessBasic(operation);
                break;

            case Mono.Cecil.Cil.Code.Endfilter:
            case Mono.Cecil.Cil.Code.Endfinally:
                instruction = ProcessBasic(operation);
                break;

            case Mono.Cecil.Cil.Code.Initblk:
                instruction = ProcessBasic(operation);
                break;

            case Mono.Cecil.Cil.Code.Initobj:
                instruction = ProcessInitObj(operation);
                break;

            case Mono.Cecil.Cil.Code.Ldarg:
            case Mono.Cecil.Cil.Code.Ldarg_0:
            case Mono.Cecil.Cil.Code.Ldarg_1:
            case Mono.Cecil.Cil.Code.Ldarg_2:
            case Mono.Cecil.Cil.Code.Ldarg_3:
            case Mono.Cecil.Cil.Code.Ldarg_S:
            case Mono.Cecil.Cil.Code.Ldarga:
            case Mono.Cecil.Cil.Code.Ldarga_S:
                instruction = ProcessLoadArgument(operation);
                break;

            case Mono.Cecil.Cil.Code.Ldloc:
            case Mono.Cecil.Cil.Code.Ldloc_0:
            case Mono.Cecil.Cil.Code.Ldloc_1:
            case Mono.Cecil.Cil.Code.Ldloc_2:
            case Mono.Cecil.Cil.Code.Ldloc_3:
            case Mono.Cecil.Cil.Code.Ldloc_S:
            case Mono.Cecil.Cil.Code.Ldloca:
            case Mono.Cecil.Cil.Code.Ldloca_S:
                instruction = ProcessLoadLocal(operation);
                break;

            case Mono.Cecil.Cil.Code.Ldfld:
            case Mono.Cecil.Cil.Code.Ldsfld:
            case Mono.Cecil.Cil.Code.Ldflda:
            case Mono.Cecil.Cil.Code.Ldsflda:
                instruction = ProcessLoadField(operation);
                break;

            case Mono.Cecil.Cil.Code.Ldftn:
            case Mono.Cecil.Cil.Code.Ldvirtftn:
                instruction = ProcessLoadMethodAddress(operation);
                break;

            case Mono.Cecil.Cil.Code.Ldc_I4:
            case Mono.Cecil.Cil.Code.Ldc_I4_0:
            case Mono.Cecil.Cil.Code.Ldc_I4_1:
            case Mono.Cecil.Cil.Code.Ldc_I4_2:
            case Mono.Cecil.Cil.Code.Ldc_I4_3:
            case Mono.Cecil.Cil.Code.Ldc_I4_4:
            case Mono.Cecil.Cil.Code.Ldc_I4_5:
            case Mono.Cecil.Cil.Code.Ldc_I4_6:
            case Mono.Cecil.Cil.Code.Ldc_I4_7:
            case Mono.Cecil.Cil.Code.Ldc_I4_8:
            case Mono.Cecil.Cil.Code.Ldc_I4_M1:
            case Mono.Cecil.Cil.Code.Ldc_I4_S:
            case Mono.Cecil.Cil.Code.Ldc_I8:
            case Mono.Cecil.Cil.Code.Ldc_R4:
            case Mono.Cecil.Cil.Code.Ldc_R8:
            case Mono.Cecil.Cil.Code.Ldnull:
            case Mono.Cecil.Cil.Code.Ldstr:
                instruction = ProcessLoadConstant(operation);
                break;

            case Mono.Cecil.Cil.Code.Ldind_I:
            case Mono.Cecil.Cil.Code.Ldind_I1:
            case Mono.Cecil.Cil.Code.Ldind_I2:
            case Mono.Cecil.Cil.Code.Ldind_I4:
            case Mono.Cecil.Cil.Code.Ldind_I8:
            case Mono.Cecil.Cil.Code.Ldind_R4:
            case Mono.Cecil.Cil.Code.Ldind_R8:
            case Mono.Cecil.Cil.Code.Ldind_Ref:
            case Mono.Cecil.Cil.Code.Ldind_U1:
            case Mono.Cecil.Cil.Code.Ldind_U2:
            case Mono.Cecil.Cil.Code.Ldind_U4:
            case Mono.Cecil.Cil.Code.Ldobj:
                instruction = ProcessLoadIndirect(operation);
                break;

            case Mono.Cecil.Cil.Code.Ldlen:
                instruction = ProcessBasic(operation);
                break;

            case Mono.Cecil.Cil.Code.Ldtoken:
                instruction = ProcessLoadToken(operation);
                break;

            case Mono.Cecil.Cil.Code.Localloc:
                instruction = ProcessBasic(operation);
                break;

            //case Mono.Cecil.Cil.Code.Mkrefany:
            //    expression = result = ParseMakeTypedReference(currentOperation);
            //    break;

            case Mono.Cecil.Cil.Code.Neg:
            case Mono.Cecil.Cil.Code.Not:
                instruction = ProcessBasic(operation);
                break;

            case Mono.Cecil.Cil.Code.Newobj:
                instruction = ProcessCreateObject(operation);
                break;

            //case Mono.Cecil.Cil.Code.No_:
            //    // If code out there actually uses this, I need to know sooner rather than later.
            //    // TODO: need object model support
            //    throw new NotImplementedException("Invalid opcode: No.");

            case Mono.Cecil.Cil.Code.Pop:
                instruction = ProcessBasic(operation);
                break;

            //case Mono.Cecil.Cil.Code.Readonly_:
            //    result = sawReadonly = true;
            //    break;

            //case Mono.Cecil.Cil.Code.Refanytype:
            //    expression = result = ParseGetTypeOfTypedReference();
            //    break;

            //case Mono.Cecil.Cil.Code.Refanyval:
            //    expression = result = ParseGetValueOfTypedReference(currentOperation);
            //    break;

            case Mono.Cecil.Cil.Code.Ret:
                instruction = ProcessBasic(operation);
                break;

            case Mono.Cecil.Cil.Code.Sizeof:
                instruction = ProcessSizeof(operation);
                break;

            case Mono.Cecil.Cil.Code.Starg:
            case Mono.Cecil.Cil.Code.Starg_S:
                instruction = ProcessStoreArgument(operation);
                break;

            //case Mono.Cecil.Cil.Code.Array_Set:
            //case Mono.Cecil.Cil.Code.Stelem:
            case Mono.Cecil.Cil.Code.Stelem_Any:
            case Mono.Cecil.Cil.Code.Stelem_I:
            case Mono.Cecil.Cil.Code.Stelem_I1:
            case Mono.Cecil.Cil.Code.Stelem_I2:
            case Mono.Cecil.Cil.Code.Stelem_I4:
            case Mono.Cecil.Cil.Code.Stelem_I8:
            case Mono.Cecil.Cil.Code.Stelem_R4:
            case Mono.Cecil.Cil.Code.Stelem_R8:
            case Mono.Cecil.Cil.Code.Stelem_Ref:
                instruction = ProcessStoreArrayElement(operation);
                break;

            case Mono.Cecil.Cil.Code.Stfld:
            case Mono.Cecil.Cil.Code.Stsfld:
                instruction = ProcessStoreField(operation);
                break;

            case Mono.Cecil.Cil.Code.Stind_I:
            case Mono.Cecil.Cil.Code.Stind_I1:
            case Mono.Cecil.Cil.Code.Stind_I2:
            case Mono.Cecil.Cil.Code.Stind_I4:
            case Mono.Cecil.Cil.Code.Stind_I8:
            case Mono.Cecil.Cil.Code.Stind_R4:
            case Mono.Cecil.Cil.Code.Stind_R8:
            case Mono.Cecil.Cil.Code.Stind_Ref:
            case Mono.Cecil.Cil.Code.Stobj:
                instruction = ProcessStoreIndirect(operation);
                break;

            case Mono.Cecil.Cil.Code.Stloc:
            case Mono.Cecil.Cil.Code.Stloc_0:
            case Mono.Cecil.Cil.Code.Stloc_1:
            case Mono.Cecil.Cil.Code.Stloc_2:
            case Mono.Cecil.Cil.Code.Stloc_3:
            case Mono.Cecil.Cil.Code.Stloc_S:
                instruction = ProcessStoreLocal(operation);
                break;

            case Mono.Cecil.Cil.Code.Switch:
                instruction = ProcessSwitch(operation);
                break;

            //case Mono.Cecil.Cil.Code.Tail_:
            //    result = sawTailCall = true;
            //    break;

            case Mono.Cecil.Cil.Code.Throw:
            case Mono.Cecil.Cil.Code.Rethrow:
                instruction = ProcessBasic(operation);
                break;

            //case Mono.Cecil.Cil.Code.Unaligned_:
            //    Contract.Assume(currentOperation.Value is byte);
            //    var alignment = (byte)currentOperation.Value;
            //    Contract.Assume(alignment == 1 || alignment == 2 || alignment == 4);
            //    result = alignment = alignment;
            //    break;

            //case Mono.Cecil.Cil.Code.Volatile_:
            //    result = sawVolatile = true;
            //    break;

            default:
                //Console.WriteLine("Unknown bytecode: {0}", operation.OperationCode);
                //throw new UnknownBytecodeException(operation);
                //continue;

                // Quick fix to preserve the offset in case it is a target location of some jump
                // Otherwise it will break the control-flow analysis later.
                instruction = new AnalysisNetBytecode.BasicInstruction((uint)operation.Offset, AnalysisNetBytecode.BasicOperation.Nop);
                break;
            }

            return(instruction);
        }