コード例 #1
0
ファイル: MethodBodyMirror.cs プロジェクト: nlhepler/mono
		// Adapted from Cecil
		List<ILInstruction> ReadCilBody (BinaryReader br, int code_size)
		{
			long start = br.BaseStream.Position;
			ILInstruction last = null;
			//GenericContext context = new GenericContext (body.Method);
			List<ILInstruction> code = new List<ILInstruction> ();

			var by_offset = new Dictionary<int, ILInstruction> ();

			if (!opcodes_inited) {
				foreach (FieldInfo fi in typeof (OpCodes).GetFields (BindingFlags.Static|BindingFlags.Public)) {
					var val = (OpCode)fi.GetValue (null);

					if (val.Op1 == 0xff)
						OneByteOpCode [val.Op2] = val;
					else
						TwoBytesOpCode [val.Op2] = val;
				}
				opcodes_inited = true;
			}

			while (br.BaseStream.Position < start + code_size) {
				OpCode op;
				long offset = br.BaseStream.Position - start;
				int cursor = br.ReadByte ();
				int token;
				ResolvedToken t;

				if (cursor == 0xfe)
					op = TwoBytesOpCode [br.ReadByte ()];
				else
					op = OneByteOpCode [cursor];

				ILInstruction instr = new ILInstruction ((int)offset, op, null);

				by_offset [instr.Offset] = instr;

				switch (op.OperandType) {
				case OperandType.InlineNone :
					break;
				case OperandType.InlineSwitch :
					uint length = br.ReadUInt32 ();
					int [] branches = new int [length];
					int [] buf = new int [length];
					for (int i = 0; i < length; i++)
						buf [i] = br.ReadInt32 ();
					for (int i = 0; i < length; i++)
						branches [i] = Convert.ToInt32 (br.BaseStream.Position - start + buf [i]);
					instr.Operand = branches;
					break;
				case OperandType.ShortInlineBrTarget :
					sbyte sbrtgt = br.ReadSByte ();
					instr.Operand = Convert.ToInt32 (br.BaseStream.Position - start + sbrtgt);
					break;
				case OperandType.InlineBrTarget :
					int brtgt = br.ReadInt32 ();
					instr.Operand = Convert.ToInt32 (br.BaseStream.Position - start + brtgt);
					break;
				case OperandType.ShortInlineI :
					if (op == OpCodes.Ldc_I4_S)
						instr.Operand = br.ReadSByte ();
					else
						instr.Operand = br.ReadByte ();
					break;
				case OperandType.ShortInlineVar :
					instr.Operand = br.ReadByte ();
					break;
				case OperandType.ShortInlineArg :
					instr.Operand = br.ReadByte ();
					break;
				case OperandType.InlineSig :
					br.ReadInt32 ();
					//instr.Operand = GetCallSiteAt (br.ReadInt32 (), context);
					break;
				case OperandType.InlineI :
					instr.Operand = br.ReadInt32 ();
					break;
				case OperandType.InlineVar :
					instr.Operand = br.ReadInt16 ();
					break;
				case OperandType.InlineArg :
					instr.Operand = br.ReadInt16 ();
					break;
				case OperandType.InlineI8 :
					instr.Operand = br.ReadInt64 ();
					break;
				case OperandType.ShortInlineR :
					instr.Operand = br.ReadSingle ();
					break;
				case OperandType.InlineR :
					instr.Operand = br.ReadDouble ();
					break;
				case OperandType.InlineString :
					token = br.ReadInt32 ();
					t = ResolveToken (token);
					if (t.Type == TokenType.STRING)
						instr.Operand = t.Str;
					break;
				case OperandType.InlineField :
				case OperandType.InlineMethod :
				case OperandType.InlineType :
				case OperandType.InlineTok :
					token = br.ReadInt32 ();

					t = ResolveToken (token);

					switch (t.Type) {
					case TokenType.TYPE:
						instr.Operand = vm.GetType (t.Id);
						break;
					case TokenType.FIELD:
						instr.Operand = vm.GetField (t.Id);
						break;
					case TokenType.METHOD:
						instr.Operand = vm.GetMethod (t.Id);
						break;
					case TokenType.UNKNOWN:
						break;
					default:
						throw new NotImplementedException ("Unknown token type: " + t.Type);
					}
					break;
				}

				if (last != null) {
					last.Next = instr;
					instr.Previous = last;
				}

				last = instr;

				code.Add (instr);
			}

			// resolve branches
			foreach (ILInstruction i in code) {
				switch (i.OpCode.OperandType) {
				case OperandType.ShortInlineBrTarget:
				case OperandType.InlineBrTarget:
					i.Operand = by_offset [(int)i.Operand];
					break;
				case OperandType.InlineSwitch:
					int [] lbls = (int []) i.Operand;
					ILInstruction [] instrs = new ILInstruction [lbls.Length];
					for (int j = 0; j < lbls.Length; j++)
						instrs [j] = by_offset [lbls [j]];
					i.Operand = instrs;
					break;
				}
			}

			return code;
		}
コード例 #2
0
		string Disassemble (ILInstruction ins)
		{
			string oper;
			if (ins.Operand is MethodMirror)
				oper = ((MethodMirror)ins.Operand).FullName;
			else if (ins.Operand is TypeMirror)
				oper = ((TypeMirror)ins.Operand).FullName;
			else if (ins.Operand is ILInstruction)
				oper = ((ILInstruction)ins.Operand).Offset.ToString ("x8");
			else if (ins.Operand == null)
				oper = string.Empty;
			else
				oper = ins.Operand.ToString ();
			
			return ins.OpCode + " " + oper;
		}
コード例 #3
0
ファイル: MethodBodyMirror.cs プロジェクト: yonder/mono
        // Adapted from Cecil
        List <ILInstruction> ReadCilBody(BinaryReader br, int code_size)
        {
            long          start = br.BaseStream.Position;
            ILInstruction last  = null;
            //GenericContext context = new GenericContext (body.Method);
            List <ILInstruction> code = new List <ILInstruction> ();

            var by_offset = new Dictionary <int, ILInstruction> ();

            if (!opcodes_inited)
            {
                foreach (FieldInfo fi in typeof(OpCodes).GetFields(BindingFlags.Static | BindingFlags.Public))
                {
                    var val = (OpCode)fi.GetValue(null);

                    if (val.Op1 == 0xff)
                    {
                        OneByteOpCode [val.Op2] = val;
                    }
                    else
                    {
                        TwoBytesOpCode [val.Op2] = val;
                    }
                }
                opcodes_inited = true;
            }

            while (br.BaseStream.Position < start + code_size)
            {
                OpCode        op;
                long          offset = br.BaseStream.Position - start;
                int           cursor = br.ReadByte();
                int           token;
                ResolvedToken t;

                if (cursor == 0xfe)
                {
                    op = TwoBytesOpCode [br.ReadByte()];
                }
                else
                {
                    op = OneByteOpCode [cursor];
                }

                ILInstruction instr = new ILInstruction((int)offset, op, null);

                by_offset [instr.Offset] = instr;

                switch (op.OperandType)
                {
                case OperandType.InlineNone:
                    break;

                case OperandType.InlineSwitch:
                    uint   length   = br.ReadUInt32();
                    int [] branches = new int [length];
                    int [] buf      = new int [length];
                    for (int i = 0; i < length; i++)
                    {
                        buf [i] = br.ReadInt32();
                    }
                    for (int i = 0; i < length; i++)
                    {
                        branches [i] = Convert.ToInt32(br.BaseStream.Position - start + buf [i]);
                    }
                    instr.Operand = branches;
                    break;

                case OperandType.ShortInlineBrTarget:
                    sbyte sbrtgt = br.ReadSByte();
                    instr.Operand = Convert.ToInt32(br.BaseStream.Position - start + sbrtgt);
                    break;

                case OperandType.InlineBrTarget:
                    int brtgt = br.ReadInt32();
                    instr.Operand = Convert.ToInt32(br.BaseStream.Position - start + brtgt);
                    break;

                case OperandType.ShortInlineI:
                    if (op == OpCodes.Ldc_I4_S)
                    {
                        instr.Operand = br.ReadSByte();
                    }
                    else
                    {
                        instr.Operand = br.ReadByte();
                    }
                    break;

                case OperandType.ShortInlineVar:
                    instr.Operand = br.ReadByte();
                    break;

                case OperandType.ShortInlineArg:
                    instr.Operand = br.ReadByte();
                    break;

                case OperandType.InlineSig:
                    br.ReadInt32();
                    //instr.Operand = GetCallSiteAt (br.ReadInt32 (), context);
                    break;

                case OperandType.InlineI:
                    instr.Operand = br.ReadInt32();
                    break;

                case OperandType.InlineVar:
                    instr.Operand = br.ReadInt16();
                    break;

                case OperandType.InlineArg:
                    instr.Operand = br.ReadInt16();
                    break;

                case OperandType.InlineI8:
                    instr.Operand = br.ReadInt64();
                    break;

                case OperandType.ShortInlineR:
                    instr.Operand = br.ReadSingle();
                    break;

                case OperandType.InlineR:
                    instr.Operand = br.ReadDouble();
                    break;

                case OperandType.InlineString:
                    token = br.ReadInt32();
                    t     = vm.conn.Method_ResolveToken(Method.Id, token);
                    if (t.Type == TokenType.STRING)
                    {
                        instr.Operand = t.Str;
                    }
                    break;

                case OperandType.InlineField:
                case OperandType.InlineMethod:
                case OperandType.InlineType:
                case OperandType.InlineTok:
                    token = br.ReadInt32();

                    t = vm.conn.Method_ResolveToken(Method.Id, token);

                    switch (t.Type)
                    {
                    case TokenType.TYPE:
                        instr.Operand = vm.GetType(t.Id);
                        break;

                    case TokenType.FIELD:
                        // FIXME: No vm.GetField ()
                        //instr.Operand = vm.GetField (t.Id);
                        break;

                    case TokenType.METHOD:
                        instr.Operand = vm.GetMethod(t.Id);
                        break;

                    case TokenType.UNKNOWN:
                        break;

                    default:
                        throw new NotImplementedException("Unknown token type: " + t.Type);
                    }
                    break;
                }

                if (last != null)
                {
                    last.Next      = instr;
                    instr.Previous = last;
                }

                last = instr;

                code.Add(instr);
            }

            // resolve branches
            foreach (ILInstruction i in code)
            {
                switch (i.OpCode.OperandType)
                {
                case OperandType.ShortInlineBrTarget:
                case OperandType.InlineBrTarget:
                    i.Operand = by_offset [(int)i.Operand];
                    break;

                case OperandType.InlineSwitch:
                    int []           lbls   = (int [])i.Operand;
                    ILInstruction [] instrs = new ILInstruction [lbls.Length];
                    for (int j = 0; j < lbls.Length; j++)
                    {
                        instrs [j] = by_offset [lbls [j]];
                    }
                    i.Operand = instrs;
                    break;
                }
            }

            return(code);
        }