Example #1
0
        private ulong HandleConstant(EcmaModule module, ConstantHandle constantHandle)
        {
            MetadataReader reader   = module.MetadataReader;
            Constant       constant = reader.GetConstant(constantHandle);
            BlobReader     blob     = reader.GetBlobReader(constant.Value);

            switch (constant.TypeCode)
            {
            case ConstantTypeCode.Byte:
                return((ulong)blob.ReadByte());

            case ConstantTypeCode.Int16:
                return((ulong)blob.ReadInt16());

            case ConstantTypeCode.Int32:
                return((ulong)blob.ReadInt32());

            case ConstantTypeCode.Int64:
                return((ulong)blob.ReadInt64());

            case ConstantTypeCode.SByte:
                return((ulong)blob.ReadSByte());

            case ConstantTypeCode.UInt16:
                return((ulong)blob.ReadUInt16());

            case ConstantTypeCode.UInt32:
                return((ulong)blob.ReadUInt32());

            case ConstantTypeCode.UInt64:
                return((ulong)blob.ReadUInt64());
            }
            System.Diagnostics.Debug.Assert(false);
            return(0);
        }
        void ParseEnum(TypeDefinition enumTypeDef)
        {
            // TODO: verify that int32 is the enums storage type for constant read below

            InspectorEnum ienum = new InspectorEnum();

            ienum.Name = metaReader.GetString(enumTypeDef.Name);

            InspectorEnums [ienum.Name] = ienum;

            var fields = enumTypeDef.GetFields();

            foreach (var fieldHandle in fields)
            {
                var inspectorField = new InspectorField();

                var fieldDef = metaReader.GetFieldDefinition(fieldHandle);

                if ((fieldDef.Attributes & FieldAttributes.HasDefault) != 0)
                {
                    var constantHandle = fieldDef.GetDefaultValue();
                    var constant       = metaReader.GetConstant(constantHandle);

                    BlobReader constantReader = metaReader.GetBlobReader(constant.Value);

                    ienum.Values [metaReader.GetString(fieldDef.Name)] = constantReader.ReadInt32();
                }
            }

            return;
        }
        private Mapping <ConstantHandle> MapConstantImpl(ConstantHandle handle)
        {
            Constant         constant = _sourceMetadata.GetConstant(handle);
            Mapping <Handle> parent   = MapHandle(constant.Parent);

            if (parent.Target.IsNil)
            {
                return(new Mapping <ConstantHandle>());
            }

            ConstantHandle targetHandle;

            switch (parent.Target.Kind)
            {
            case HandleKind.Parameter:
                Parameter targetParameter = _targetMetadata.GetParameter((ParameterHandle)parent.Target);
                targetHandle = targetParameter.GetDefaultValue();
                break;

            case HandleKind.FieldDefinition:
                FieldDefinition targetFieldDefinition = _targetMetadata.GetFieldDefinition((FieldDefinitionHandle)parent.Target);
                targetHandle = targetFieldDefinition.GetDefaultValue();
                break;

            case HandleKind.PropertyDefinition:
                PropertyDefinition targetPropertyDefinition = _targetMetadata.GetPropertyDefinition((PropertyDefinitionHandle)parent.Target);
                targetHandle = targetPropertyDefinition.GetDefaultValue();
                break;

            default:
                throw new InvalidOperationException();
            }

            if (targetHandle.IsNil)
            {
                return(new Mapping <ConstantHandle>());
            }

            Constant targetConstant = _targetMetadata.GetConstant(targetHandle);

            if (constant.TypeCode != targetConstant.TypeCode)
            {
                var candidateTargets = ImmutableArray.Create(targetHandle);
                var candidateReasons = ImmutableArray.Create("Mapped constant has a different type.");
                return(new Mapping <ConstantHandle>(candidateTargets, candidateReasons));
            }

            ImmutableArray <byte> sourceContent = _sourceMetadata.GetBlobContent(constant.Value);
            ImmutableArray <byte> targetContent = _targetMetadata.GetBlobContent(targetConstant.Value);

            if (!sourceContent.SequenceEqual(targetContent))
            {
                var candidateTargets = ImmutableArray.Create(targetHandle);
                var candidateReasons = ImmutableArray.Create("Mapped constant has a different value.");
                return(new Mapping <ConstantHandle>(candidateTargets, candidateReasons));
            }

            return(new Mapping <ConstantHandle>(targetHandle));
        }
Example #4
0
 public ConstantEntry(PEFile module, ConstantHandle handle)
 {
     this.metadataOffset = module.Reader.PEHeaders.MetadataStartOffset;
     this.module         = module;
     this.metadata       = module.Metadata;
     this.handle         = handle;
     this.constant       = metadata.GetConstant(handle);
 }
        //
        // This returns the underlying enum values as "ulong" regardless of the actual underlying type. Signed integral types
        // get sign-extended into the 64-bit value, unsigned types get zero-extended.
        //
        public static ulong ReadUnboxedEnumValue(MetadataReader metadataReader, ConstantHandle constantHandle)
        {
            if (constantHandle.IsNil)
            {
                throw new BadImageFormatException();
            }

            Constant constantValue = metadataReader.GetConstant(constantHandle);

            if (constantValue.Value.IsNil)
            {
                throw new BadImageFormatException();
            }

            BlobReader reader = metadataReader.GetBlobReader(constantValue.Value);

            switch (constantValue.TypeCode)
            {
            case ConstantTypeCode.Boolean:
                return(reader.ReadBoolean() ? 1UL : 0UL);;

            case ConstantTypeCode.Char:
                return((ulong)(long)reader.ReadChar());

            case ConstantTypeCode.SByte:
                return((ulong)(long)reader.ReadSByte());

            case ConstantTypeCode.Int16:
                return((ulong)(long)reader.ReadInt16());

            case ConstantTypeCode.Int32:
                return((ulong)(long)reader.ReadInt32());

            case ConstantTypeCode.Int64:
                return((ulong)(long)reader.ReadInt64());

            case ConstantTypeCode.Byte:
                return((ulong)(long)reader.ReadByte());

            case ConstantTypeCode.UInt16:
                return((ulong)(long)reader.ReadUInt16());

            case ConstantTypeCode.UInt32:
                return((ulong)(long)reader.ReadUInt32());

            case ConstantTypeCode.UInt64:
                return((ulong)(long)reader.ReadUInt64());
            }

            throw new BadImageFormatException();
        }
        private void WriteConstant()
        {
            AddHeader(
                "Parent",
                "Type",
                "Value"
                );

            for (int i = 1, count = reader.GetTableRowCount(TableIndex.Constant); i <= count; i++)
            {
                var entry = reader.GetConstant(MetadataTokens.ConstantHandle(i));

                AddRow(
                    Token(entry.Parent),
                    EnumValue <byte>(entry.Type),
                    Literal(entry.Value)
                    );
            }

            WriteRows("Constant (0x0b):");
        }
Example #7
0
        public static object ToRawObject(this ConstantHandle constantHandle, MetadataReader metadataReader)
        {
            if (constantHandle.IsNil)
            {
                throw new BadImageFormatException();
            }

            Constant constantValue = metadataReader.GetConstant(constantHandle);

            if (constantValue.Value.IsNil)
            {
                throw new BadImageFormatException();
            }

            BlobReader reader = metadataReader.GetBlobReader(constantValue.Value);

            switch (constantValue.TypeCode)
            {
            case ConstantTypeCode.Boolean:
                return(reader.ReadBoolean());

            case ConstantTypeCode.Char:
                return(reader.ReadChar());

            case ConstantTypeCode.SByte:
                return(reader.ReadSByte());

            case ConstantTypeCode.Int16:
                return(reader.ReadInt16());

            case ConstantTypeCode.Int32:
                return(reader.ReadInt32());

            case ConstantTypeCode.Int64:
                return(reader.ReadInt64());

            case ConstantTypeCode.Byte:
                return(reader.ReadByte());

            case ConstantTypeCode.UInt16:
                return(reader.ReadUInt16());

            case ConstantTypeCode.UInt32:
                return(reader.ReadUInt32());

            case ConstantTypeCode.UInt64:
                return(reader.ReadUInt64());

            case ConstantTypeCode.Single:
                return(reader.ReadSingle());

            case ConstantTypeCode.Double:
                return(reader.ReadDouble());

            case ConstantTypeCode.String:
                return(reader.ReadUTF16(reader.Length));

            case ConstantTypeCode.NullReference:
                // Partition II section 22.9:
                // The encoding of Type for the nullref value is ELEMENT_TYPE_CLASS with a Value of a 4-byte zero.
                // Unlike uses of ELEMENT_TYPE_CLASS in signatures, this one is not followed by a type token.
                if (reader.ReadUInt32() == 0)
                {
                    return(null);
                }
                break;
            }
            throw new BadImageFormatException();
        }
Example #8
0
 public static string ToString(this MetadataReader reader, ConstantHandle x) => reader.ToString(reader.GetConstant(x));
        public static object?ToRawObject(this ConstantHandle constantHandle, MetadataReader metadataReader)
        {
            if (constantHandle.IsNil)
            {
                throw new BadImageFormatException();
            }

            Constant constantValue = metadataReader.GetConstant(constantHandle);

            // Partition II section 24.2.4:
            // The first entry in both these heaps is the empty 'blob' that consists of the single byte 0x00.
            //
            // This means zero value is valid for string and is used to represent the empty string.
            if (constantValue.Value.IsNil && constantValue.TypeCode != ConstantTypeCode.String)
            {
                throw new BadImageFormatException();
            }

            BlobReader reader = metadataReader.GetBlobReader(constantValue.Value);

            switch (constantValue.TypeCode)
            {
            case ConstantTypeCode.Boolean:
                return(reader.ReadBoolean());

            case ConstantTypeCode.Char:
                return(reader.ReadChar());

            case ConstantTypeCode.SByte:
                return(reader.ReadSByte());

            case ConstantTypeCode.Int16:
                return(reader.ReadInt16());

            case ConstantTypeCode.Int32:
                return(reader.ReadInt32());

            case ConstantTypeCode.Int64:
                return(reader.ReadInt64());

            case ConstantTypeCode.Byte:
                return(reader.ReadByte());

            case ConstantTypeCode.UInt16:
                return(reader.ReadUInt16());

            case ConstantTypeCode.UInt32:
                return(reader.ReadUInt32());

            case ConstantTypeCode.UInt64:
                return(reader.ReadUInt64());

            case ConstantTypeCode.Single:
                return(reader.ReadSingle());

            case ConstantTypeCode.Double:
                return(reader.ReadDouble());

            case ConstantTypeCode.String:
                return(reader.ReadUTF16(reader.Length));

            case ConstantTypeCode.NullReference:
                // Partition II section 22.9:
                // The encoding of Type for the nullref value is ELEMENT_TYPE_CLASS with a Value of a 4-byte zero.
                // Unlike uses of ELEMENT_TYPE_CLASS in signatures, this one is not followed by a type token.
                if (reader.ReadUInt32() == 0)
                {
                    return(null);
                }
                break;
            }
            throw new BadImageFormatException();
        }
Example #10
0
 public static Constant GetConstant(this ConstantHandle handle, MetadataReader reader) => reader.GetConstant(handle);