Example #1
0
        /// <inheritdoc />
        public override DispatchResult Execute(CilExecutionContext context, CilInstruction instruction)
        {
            var environment = context.GetService <ICilRuntimeEnvironment>();

            var variables = new IVariable[1];

            if (environment.Architecture.GetReadVariables(instruction, variables) != 1)
            {
                throw new DispatchException(
                          $"Architecture returned an incorrect number of variables being read from instruction {instruction}.");
            }

            switch (variables[0])
            {
            case CilParameter parameter:
                var value = environment.CliMarshaller.ToCliValue(
                    context.ProgramState.Variables[variables[0]],
                    parameter.Parameter.ParameterType);

                context.ProgramState.Stack.Push(value);
                return(base.Execute(context, instruction));

            default:
                return(DispatchResult.InvalidProgram());
            }
        }
Example #2
0
        /// <inheritdoc />
        public override DispatchResult Execute(ExecutionContext context, CilInstruction instruction)
        {
            var stack = context.ProgramState.Stack;

            // Pop arguments.
            var lengthValue        = (ICliValue)stack.Pop();
            var sourceAddress      = (ICliValue)stack.Pop();
            var destinationAddress = (ICliValue)stack.Pop();

            // Interpret arguments.
            if (!(destinationAddress is IPointerValue destinationPointer) || !(sourceAddress is IPointerValue sourcePointer))
            {
                return(DispatchResult.InvalidProgram());
            }

            if (!lengthValue.IsKnown)
            {
                throw new DispatchException("Number of bytes to copy is unknown.");
            }
            int length = lengthValue.InterpretAsI4().I32;

            // Copy data.
            Span <byte> data    = stackalloc byte[length];
            Span <byte> bitmask = stackalloc byte[length];

            sourcePointer.ReadBytes(0, data, bitmask);
            destinationPointer.WriteBytes(0, data, bitmask);

            return(base.Execute(context, instruction));
        }
Example #3
0
File: Ret.cs Project: lanicon/Echo
        /// <inheritdoc />
        public DispatchResult Execute(CilExecutionContext context, CilInstruction instruction)
        {
            var environment = context.GetService <ICilRuntimeEnvironment>();

            // If the containing method is expected to return a value, the stack should contain exactly one value,
            // and no values otherwise.

            int popCount = environment.Architecture.GetStackPopCount(instruction);

            if (context.ProgramState.Stack.Size != popCount)
            {
                return(DispatchResult.InvalidProgram());
            }

            // Pop result.
            if (popCount == 1)
            {
                context.Result.ReturnValue = context.ProgramState.Stack.Pop();
            }

            return(new DispatchResult
            {
                HasTerminated = true
            });
        }
Example #4
0
        /// <inheritdoc />
        public override DispatchResult Execute(ExecutionContext context, CilInstruction instruction)
        {
            var environment = context.GetService <ICilRuntimeEnvironment>();

            var variables = new IVariable[1];

            if (environment.Architecture.GetWrittenVariables(instruction, variables) != 1)
            {
                throw new DispatchException(
                          $"Architecture returned an incorrect number of variables being written by instruction {instruction}.");
            }

            switch (variables[0])
            {
            case CilVariable cilVariable:
                var value = environment.CliMarshaller.ToCtsValue(
                    (ICliValue)context.ProgramState.Stack.Pop(),
                    cilVariable.Variable.VariableType);

                context.ProgramState.Variables[variables[0]] = value;
                return(base.Execute(context, instruction));

            default:
                return(DispatchResult.InvalidProgram());
            }
        }
Example #5
0
        /// <inheritdoc />
        public override DispatchResult Execute(ExecutionContext context, CilInstruction instruction)
        {
            var stack = context.ProgramState.Stack;

            // Pop arguments.
            var valueValue = (ICliValue)stack.Pop();
            var indexValue = (ICliValue)stack.Pop();
            var arrayValue = (ICliValue)stack.Pop();

            // Check if both array and index are known.
            if (!arrayValue.IsKnown)
            {
                throw new DispatchException($"Destination array value for instruction at offset IL_{instruction.Offset:X4} is unknown.");
            }
            if (!indexValue.IsKnown)
            {
                throw new DispatchException($"Index for instruction at offset IL_{instruction.Offset:X4} is unknown.");
            }

            // Expect an int32 or a native int for index, and extract its value.
            if (indexValue.CliValueType != CliValueType.Int32 && indexValue.CliValueType != CliValueType.NativeInt)
            {
                return(DispatchResult.InvalidProgram());
            }

            int index = indexValue.InterpretAsI4().I32;

            // Expect an O value with a .NET array in it.
            switch (arrayValue)
            {
            case OValue {
                    IsZero: { Value : TrileanValue.True }
            } :
                // Pushed array object is null.
                return(new DispatchResult(new NullReferenceException()));
Example #6
0
        /// <inheritdoc />
        public override DispatchResult Execute(CilExecutionContext context, CilInstruction instruction)
        {
            var environment = context.GetService <ICilRuntimeEnvironment>();
            var factory     = environment.Module.CorLibTypeFactory;

            var stack        = context.ProgramState.Stack;
            var valueValue   = stack.Pop();
            var pointerValue = (IPointerValue)stack.Pop();

            var marshaller = environment.CliMarshaller;

            switch (instruction.OpCode.Code)
            {
            case CilCode.Stind_I:
                if (pointerValue.Is32Bit)
                {
                    pointerValue.WriteInteger32(0, valueValue.InterpretAsI4());
                }
                else
                {
                    pointerValue.WriteInteger64(0, valueValue.InterpretAsI8());
                }
                break;

            case CilCode.Stind_I1:
                pointerValue.WriteInteger8(0,
                                           (Integer8Value)marshaller.ToCtsValue(valueValue.InterpretAsI1(), factory.SByte));
                break;

            case CilCode.Stind_I2:
                pointerValue.WriteInteger16(0,
                                            (Integer16Value)marshaller.ToCtsValue(valueValue.InterpretAsI2(), factory.Int16));
                break;

            case  CilCode.Stind_I4:
                pointerValue.WriteInteger32(0,
                                            (Integer32Value)marshaller.ToCtsValue(valueValue.InterpretAsI4(), factory.Int32));
                break;

            case CilCode.Stind_I8:
                pointerValue.WriteInteger64(0,
                                            (Integer64Value)marshaller.ToCtsValue(valueValue.InterpretAsI8(), factory.Int64));
                break;

            case CilCode.Stind_R4:
                pointerValue.WriteFloat32(0,
                                          (Float32Value)marshaller.ToCtsValue(valueValue.InterpretAsR4(), factory.Single));
                break;

            case CilCode.Stind_R8:
                pointerValue.WriteFloat64(0,
                                          (Float64Value)marshaller.ToCtsValue(valueValue.InterpretAsR8(), factory.Double));
                break;

            default:
                return(DispatchResult.InvalidProgram());
            }

            return(base.Execute(context, instruction));
        }
Example #7
0
        /// <inheritdoc />
        public override DispatchResult Execute(CilExecutionContext context, CilInstruction instruction)
        {
            var stack = context.ProgramState.Stack;

            // Pop arguments.
            var indexValue = stack.Pop();
            var arrayValue = stack.Pop();

            // Check if both array and index are known.
            if (!arrayValue.IsKnown || !indexValue.IsKnown)
            {
                stack.Push(GetUnknownElementValue(context, instruction));
                return(base.Execute(context, instruction));
            }

            // Expect an int32 or a native int for index, and extract its value.
            if (indexValue.CliValueType != CliValueType.Int32 && indexValue.CliValueType != CliValueType.NativeInt)
            {
                return(DispatchResult.InvalidProgram());
            }
            int index = indexValue.InterpretAsI4().I32;

            // Obtain element.
            ICliValue elementValue;

            switch (arrayValue)
            {
            case OValue {
                    IsZero: { Value : TrileanValue.True }
            } :
                // Pushed array object is null.
                return(new DispatchResult(new NullReferenceException()));
Example #8
0
        /// <inheritdoc />
        public DispatchResult Execute(CilExecutionContext context, CilInstruction instruction)
        {
            var(left, right) = BinaryOperationHelper.PopBinaryOperationArguments(context);

            var result = (left, right) switch
            {
                (IntegerValue a, IntegerValue b) => Execute(context, instruction, a, b),
                (FValue a, FValue b) => Execute(context, instruction, a, b),
                (OValue a, OValue b) => Execute(context, instruction, a, b),
                _ => DispatchResult.InvalidProgram(),
            };
Example #9
0
        /// <inheritdoc />
        public DispatchResult Execute(CilExecutionContext context, CilInstruction instruction)
        {
            var argument = context.ProgramState.Stack.Pop();

            var result = argument switch
            {
                FValue float64Value => Execute(context, float64Value),
                IntegerValue integerValue => Execute(context, integerValue),
                _ => DispatchResult.InvalidProgram()
            };

            if (result.IsSuccess)
            {
                context.ProgramState.ProgramCounter += instruction.Size;
            }

            return(result);
        }
Example #10
0
        /// <inheritdoc />
        public DispatchResult Execute(ExecutionContext context, CilInstruction instruction)
        {
            var(left, right) = PopArguments(context);

            var result = (left, right) switch
            {
                (IntegerValue value, int shiftCount) => Execute(context, instruction, value, shiftCount),
                (IntegerValue value, null) => ExecuteDefault(context, value, left),
                _ => DispatchResult.InvalidProgram()
            };

            if (result.IsSuccess)
            {
                context.ProgramState.ProgramCounter += instruction.Size;
            }

            return(result);
        }
Example #11
0
        /// <inheritdoc />
        public override DispatchResult Execute(CilExecutionContext context, CilInstruction instruction)
        {
            var environment = context.GetService <ICilRuntimeEnvironment>();
            var stack       = context.ProgramState.Stack;

            var sizeValue = (ICliValue)stack.Pop();

            if (!sizeValue.IsKnown)
            {
                return(DispatchResult.InvalidProgram());
            }

            int size        = sizeValue.InterpretAsI4().I32;
            var memoryValue = environment.ValueFactory.AllocateMemory(size, true);

            stack.Push(environment.CliMarshaller.ToCliValue(memoryValue,
                                                            new PointerTypeSignature(environment.Module.CorLibTypeFactory.Byte)));

            return(base.Execute(context, instruction));
        }
Example #12
0
        /// <inheritdoc />
        public override DispatchResult Execute(CilExecutionContext context, CilInstruction instruction)
        {
            var environment = context.GetService <ICilRuntimeEnvironment>();
            var stack       = context.ProgramState.Stack;

            var sizeValue = stack.Pop();

            if (!sizeValue.IsKnown)
            {
                return(DispatchResult.InvalidProgram());
            }

            var elementType = ((ITypeDefOrRef)instruction.Operand).ToTypeSignature();
            int size        = sizeValue.InterpretAsI4().I32;
            var array       = environment.ValueFactory.AllocateArray(elementType, size);

            stack.Push(environment.CliMarshaller.ToCliValue(array, new SzArrayTypeSignature(elementType)));

            return(base.Execute(context, instruction));
        }
Example #13
0
        /// <inheritdoc />
        public override DispatchResult Execute(CilExecutionContext context, CilInstruction instruction)
        {
            var environment = context.GetService <ICilRuntimeEnvironment>();
            var stack       = context.ProgramState.Stack;

            // Pop address to dereference.
            var elementValue = stack.Pop();
            var addressValue = stack.Pop();

            if (!(addressValue is IPointerValue pointerValue))
            {
                return(DispatchResult.InvalidProgram());
            }

            // Determine type layout.
            var type         = ((ITypeDefOrRef)instruction.Operand).ToTypeSignature();
            var memoryLayout = environment.ValueFactory.GetTypeMemoryLayout(type);

            // Write
            pointerValue.WriteStruct(0, environment.ValueFactory, memoryLayout, elementValue);

            return(DispatchResult.Success());
        }
Example #14
0
        /// <inheritdoc />
        public override DispatchResult Execute(CilExecutionContext context, CilInstruction instruction)
        {
            var stack = context.ProgramState.Stack;

            // Pop arguments.
            var lengthValue = stack.Pop();
            var initValue   = stack.Pop();
            var address     = stack.Pop();

            // Interpret arguments.
            if (!(address is IPointerValue pointerValue))
            {
                return(DispatchResult.InvalidProgram());
            }

            if (!lengthValue.IsKnown)
            {
                throw new DispatchException("Number of bytes to initialize is unknown.");
            }
            int length = lengthValue.InterpretAsI4().I32;

            var byteInitValue = initValue.InterpretAsU1();

            // Prepare initialization data.
            Span <byte> data = stackalloc byte[length];

            data.Fill((byte)(byteInitValue.U32 & 0xFF));

            Span <byte> bitmask = stackalloc byte[length];

            bitmask.Fill((byte)(byteInitValue.Mask & 0xFF));

            // Write data.
            pointerValue.WriteBytes(0, data, bitmask);

            return(base.Execute(context, instruction));
        }
Example #15
0
        /// <inheritdoc />
        public override DispatchResult Execute(ExecutionContext context, CilInstruction instruction)
        {
            var environment       = context.GetService <ICilRuntimeEnvironment>();
            var corLibTypeFactory = environment.Module.CorLibTypeFactory;

            var stack        = context.ProgramState.Stack;
            var pointerValue = (IPointerValue)stack.Pop();

            var(value, type) = instruction.OpCode.Code switch
            {
                CilCode.Ldind_I => (pointerValue.Is32Bit
                    ? (IConcreteValue)pointerValue.ReadInteger32(0)
                    : pointerValue.ReadInteger64(0), corLibTypeFactory.IntPtr),
                CilCode.Ldind_I1 => (pointerValue.ReadInteger8(0), corLibTypeFactory.SByte),
                CilCode.Ldind_I2 => (pointerValue.ReadInteger16(0), corLibTypeFactory.Int16),
                CilCode.Ldind_I4 => (pointerValue.ReadInteger32(0), corLibTypeFactory.Int32),
                CilCode.Ldind_I8 => (pointerValue.ReadInteger64(0), corLibTypeFactory.Int64),
                CilCode.Ldind_U1 => (pointerValue.ReadInteger8(0), corLibTypeFactory.Byte),
                CilCode.Ldind_U2 => (pointerValue.ReadInteger16(0), corLibTypeFactory.UInt16),
                CilCode.Ldind_U4 => (pointerValue.ReadInteger32(0), corLibTypeFactory.UInt32),
                CilCode.Ldind_R4 => (pointerValue.ReadFloat32(0), corLibTypeFactory.Single),
                CilCode.Ldind_R8 => (pointerValue.ReadFloat64(0), corLibTypeFactory.Double),
                _ => (null, null)
            };

            if (value is null)
            {
                return(DispatchResult.InvalidProgram());
            }

            var cliValue = environment.CliMarshaller.ToCliValue(value, type);

            stack.Push(cliValue);

            return(base.Execute(context, instruction));
        }
Example #16
0
        /// <inheritdoc />
        public override DispatchResult Execute(ExecutionContext context, CilInstruction instruction)
        {
            var environment = context.GetService <ICilRuntimeEnvironment>();
            var stack       = context.ProgramState.Stack;

            // Pop address to dereference.
            var addressValue = stack.Pop();

            if (!(addressValue is PointerValue pointerValue))
            {
                return(DispatchResult.InvalidProgram());
            }

            // Determine type layout.
            var type         = ((ITypeDefOrRef)instruction.Operand).ToTypeSignature();
            var memoryLayout = environment.MemoryAllocator.GetTypeMemoryLayout(type);

            // Dereference.
            var structureValue = pointerValue.ReadStruct(0, environment.MemoryAllocator, memoryLayout);

            stack.Push(environment.CliMarshaller.ToCliValue(structureValue, type));

            return(DispatchResult.Success());
        }
Example #17
0
 /// <inheritdoc />
 protected override DispatchResult Execute(ExecutionContext context, CilInstruction instruction, 
     OValue left, OValue right)
 {
     return DispatchResult.InvalidProgram();
 }
Example #18
0
 /// <inheritdoc />
 protected override DispatchResult Execute(ExecutionContext context, Float64Value value) =>
 DispatchResult.InvalidProgram();