Exemple #1
0
        private void WriteOperandOffset(X86OffsetType type, int offset)
        {
            switch (type)
            {
            case X86OffsetType.None:
                break;

            case X86OffsetType.Short:
                _writer.WriteSByte((sbyte)offset);
                break;

            case X86OffsetType.Long:
                _writer.WriteInt32(offset);
                break;

            default:
                throw new NotSupportedException("Unrecognized or unsupported offset type.");
            }
        }
Exemple #2
0
        private void WriteOperand(CilInstruction instruction)
        {
            switch (instruction.OpCode.OperandType)
            {
            case CilOperandType.InlineNone:
                break;

            case CilOperandType.ShortInlineI:
                _writer.WriteSByte(OperandToSByte(instruction));
                break;

            case CilOperandType.InlineI:
                _writer.WriteInt32(OperandToInt32(instruction));
                break;

            case CilOperandType.InlineI8:
                _writer.WriteInt64(OperandToInt64(instruction));
                break;

            case CilOperandType.ShortInlineR:
                _writer.WriteSingle(OperandToFloat32(instruction));
                break;

            case CilOperandType.InlineR:
                _writer.WriteDouble(OperandToFloat64(instruction));
                break;

            case CilOperandType.ShortInlineVar:
                _writer.WriteByte((byte)OperandToLocalIndex(instruction));
                break;

            case CilOperandType.InlineVar:
                _writer.WriteUInt16(OperandToLocalIndex(instruction));
                break;

            case CilOperandType.ShortInlineArgument:
                _writer.WriteByte((byte)OperandToArgumentIndex(instruction));
                break;

            case CilOperandType.InlineArgument:
                _writer.WriteUInt16(OperandToArgumentIndex(instruction));
                break;

            case CilOperandType.ShortInlineBrTarget:
                _writer.WriteSByte((sbyte)OperandToBranchDelta(instruction));
                break;

            case CilOperandType.InlineBrTarget:
                _writer.WriteInt32(OperandToBranchDelta(instruction));
                break;

            case CilOperandType.InlineSwitch:
                var labels = (IList <ICilLabel>)instruction.Operand;
                _writer.WriteInt32(labels.Count);

                int baseOffset = (int)_writer.Offset + labels.Count * sizeof(int);
                for (int i = 0; i < labels.Count; i++)
                {
                    _writer.WriteInt32(labels[i].Offset - baseOffset);
                }

                break;

            case CilOperandType.InlineString:
                _writer.WriteUInt32(_operandBuilder.GetStringToken(instruction.Operand));
                break;

            case CilOperandType.InlineField:
            case CilOperandType.InlineMethod:
            case CilOperandType.InlineSig:
            case CilOperandType.InlineTok:
            case CilOperandType.InlineType:
                _writer.WriteUInt32(_operandBuilder.GetMemberToken(instruction.Operand).ToUInt32());
                break;

            default:
                throw new ArgumentOutOfRangeException();
            }
        }
Exemple #3
0
        private void WriteValue(IBinaryStreamWriter writer, TypeSignature argumentType, ITypeCodedIndexProvider provider, object value)
        {
            if (argumentType.IsTypeOf("System", "Type"))
            {
                writer.WriteSerString(TypeNameBuilder.GetAssemblyQualifiedName((TypeSignature)value));
                return;
            }

            switch (argumentType.ElementType)
            {
            case ElementType.Boolean:
                writer.WriteByte((byte)((bool)value ? 1 : 0));
                break;

            case ElementType.Char:
                writer.WriteUInt16((char)value);
                break;

            case ElementType.I1:
                writer.WriteSByte((sbyte)value);
                break;

            case ElementType.U1:
                writer.WriteByte((byte)value);
                break;

            case ElementType.I2:
                writer.WriteInt16((short)value);
                break;

            case ElementType.U2:
                writer.WriteUInt16((ushort)value);
                break;

            case ElementType.I4:
                writer.WriteInt32((int)value);
                break;

            case ElementType.U4:
                writer.WriteUInt32((uint)value);
                break;

            case ElementType.I8:
                writer.WriteInt64((long)value);
                break;

            case ElementType.U8:
                writer.WriteUInt64((ulong)value);
                break;

            case ElementType.R4:
                writer.WriteSingle((float)value);
                break;

            case ElementType.R8:
                writer.WriteDouble((double)value);
                break;

            case ElementType.String:
                writer.WriteSerString(value as string);
                break;

            case ElementType.Object:
                var valueType    = value.GetType();
                var innerTypeSig = argumentType.Module.CorLibTypeFactory.FromName(valueType.Namespace, valueType.Name);
                TypeSignature.WriteFieldOrPropType(writer, innerTypeSig);
                WriteValue(writer, innerTypeSig, provider, value);
                break;

            case ElementType.Class:
            case ElementType.Enum:
            case ElementType.ValueType:
                var enumTypeDef = argumentType.Resolve();
                if (enumTypeDef != null && enumTypeDef.IsEnum)
                {
                    WriteValue(writer, enumTypeDef.GetEnumUnderlyingType(), provider, Value);
                }
                else
                {
                    throw new NotImplementedException();
                }
                break;

            default:
                throw new ArgumentOutOfRangeException();
            }
        }
        /// <inheritdoc />
        public override void Write(MetadataBuffer buffer, IBinaryStreamWriter writer)
        {
            if (Value == null)
            {
                writer.WriteSerString(null);
                return;
            }

            switch (Type.GetTypeCode(Value.GetType()))
            {
            case TypeCode.Boolean:
                writer.WriteByte((byte)((bool)Value ? 1 : 0));
                break;

            case TypeCode.Byte:
                writer.WriteByte((byte)Value);
                break;

            case TypeCode.Char:
                writer.WriteUInt16((char)Value);
                break;

            case TypeCode.Double:
                writer.WriteDouble((double)Value);
                break;

            case TypeCode.Int16:
                writer.WriteInt16((short)Value);
                break;

            case TypeCode.Int32:
                writer.WriteInt32((int)Value);
                break;

            case TypeCode.Int64:
                writer.WriteInt64((long)Value);
                break;

            case TypeCode.SByte:
                writer.WriteSByte((sbyte)Value);
                break;

            case TypeCode.Single:
                writer.WriteSingle((float)Value);
                break;

            case TypeCode.String:
                writer.WriteSerString((string)Value);
                break;

            case TypeCode.UInt16:
                writer.WriteUInt16((ushort)Value);
                break;

            case TypeCode.UInt32:
                writer.WriteUInt32((uint)Value);
                break;

            case TypeCode.UInt64:
                writer.WriteUInt64((ulong)Value);
                break;

            default:
                if (Value is TypeSignature typeSignature)
                {
                    writer.WriteSerString(TypeNameBuilder.GetAssemblyQualifiedName(typeSignature));
                }
                else
                {
                    throw new NotSupportedException();
                }
                break;
            }
        }
Exemple #5
0
        /// <summary>
        /// Writes the operand of the instruction to the output stream.
        /// </summary>
        /// <param name="instruction"></param>
        /// <exception cref="InvalidOperationException"></exception>
        private void WriteOperand(CilInstruction instruction)
        {
            switch (instruction.OpCode.OperandType)
            {
            case CilOperandType.InlineArgument:
                _writer.WriteUInt16((ushort)_builder.GetParameterIndex(instruction.Operand as ParameterSignature));
                break;

            case CilOperandType.ShortInlineArgument:
                _writer.WriteByte((byte)_builder.GetParameterIndex(instruction.Operand as ParameterSignature));
                break;

            case CilOperandType.InlineVar:
                _writer.WriteUInt16((ushort)_builder.GetVariableIndex(instruction.Operand as VariableSignature));
                break;

            case CilOperandType.ShortInlineVar:
                _writer.WriteByte((byte)_builder.GetVariableIndex(instruction.Operand as VariableSignature));
                break;

            case CilOperandType.ShortInlineI:
                _writer.WriteSByte((sbyte)instruction.Operand);
                break;

            case CilOperandType.InlineI:
                _writer.WriteInt32((int)instruction.Operand);
                break;

            case CilOperandType.InlineI8:
                _writer.WriteInt64((long)instruction.Operand);
                break;

            case CilOperandType.ShortInlineR:
                _writer.WriteSingle((float)instruction.Operand);
                break;

            case CilOperandType.InlineR:
                _writer.WriteDouble((double)instruction.Operand);
                break;

            case CilOperandType.InlineBrTarget:
                _writer.WriteInt32(((CilInstruction)instruction.Operand).Offset -
                                   (instruction.Offset + instruction.Size));
                break;

            case CilOperandType.ShortInlineBrTarget:
                _writer.WriteSByte((sbyte)(((CilInstruction)instruction.Operand).Offset -
                                           (instruction.Offset + instruction.Size)));
                break;

            case CilOperandType.InlineField:
            case CilOperandType.InlineMethod:
            case CilOperandType.InlineSig:
            case CilOperandType.InlineTok:
            case CilOperandType.InlineType:
                var token = _builder.GetMetadataToken((IMetadataMember)instruction.Operand);
                if (token.Rid == 0)
                {
                    throw new InvalidOperationException($"Member {instruction.Operand} has an invalid metadata token.");
                }

                _writer.WriteUInt32(token.ToUInt32());
                break;

            case CilOperandType.InlineString:
                _writer.WriteUInt32(_builder.GetStringOffset((string)instruction.Operand));
                break;

            case CilOperandType.InlineSwitch:
                var targets = (IList <CilInstruction>)instruction.Operand;
                _writer.WriteInt32(targets.Count);
                foreach (var target in targets)
                {
                    _writer.WriteInt32(target.Offset - (instruction.Offset + instruction.Size));
                }
                break;

            case CilOperandType.InlineNone:
                break;
            }
        }
Exemple #6
0
        private void WriteOperand(CilInstruction instruction)
        {
            switch (instruction.OpCode.OperandType)
            {
            case CilOperandType.InlineNone:
                break;

            case CilOperandType.ShortInlineI:
                _writer.WriteSByte((sbyte)instruction.Operand);
                break;

            case CilOperandType.InlineI:
                _writer.WriteInt32((int)instruction.Operand);
                break;

            case CilOperandType.InlineI8:
                _writer.WriteInt64((long)instruction.Operand);
                break;

            case CilOperandType.ShortInlineR:
                _writer.WriteSingle((float)instruction.Operand);
                break;

            case CilOperandType.InlineR:
                _writer.WriteDouble((double)instruction.Operand);
                break;

            case CilOperandType.ShortInlineVar:
                _writer.WriteSByte((sbyte)_operandBuilder.GetVariableIndex(instruction.Operand));
                break;

            case CilOperandType.InlineVar:
                _writer.WriteUInt16((ushort)_operandBuilder.GetVariableIndex(instruction.Operand));
                break;

            case CilOperandType.ShortInlineArgument:
                _writer.WriteSByte((sbyte)_operandBuilder.GetArgumentIndex(instruction.Operand));
                break;

            case CilOperandType.InlineArgument:
                _writer.WriteUInt16((ushort)_operandBuilder.GetArgumentIndex(instruction.Operand));
                break;

            case CilOperandType.ShortInlineBrTarget:
                sbyte shortOffset = (sbyte)(((ICilLabel)instruction.Operand).Offset - (int)(_writer.Offset + sizeof(sbyte)));
                _writer.WriteSByte(shortOffset);
                break;

            case CilOperandType.InlineBrTarget:
                int longOffset = ((ICilLabel)instruction.Operand).Offset - (int)(_writer.Offset + sizeof(int));
                _writer.WriteInt32(longOffset);
                break;

            case CilOperandType.InlineSwitch:
                var labels = (IList <ICilLabel>)instruction.Operand;
                _writer.WriteInt32(labels.Count);

                int baseOffset = (int)_writer.Offset + labels.Count * sizeof(int);
                for (int i = 0; i < labels.Count; i++)
                {
                    _writer.WriteInt32(labels[i].Offset - baseOffset);
                }

                break;

            case CilOperandType.InlineString:
                _writer.WriteUInt32(_operandBuilder.GetStringToken(instruction.Operand));
                break;

            case CilOperandType.InlineField:
            case CilOperandType.InlineMethod:
            case CilOperandType.InlineSig:
            case CilOperandType.InlineTok:
            case CilOperandType.InlineType:
                _writer.WriteUInt32(_operandBuilder.GetMemberToken(instruction.Operand).ToUInt32());
                break;

            default:
                throw new ArgumentOutOfRangeException();
            }
        }