Example #1
0
        /// <summary>
        /// Fixes instructions offsets according .NET Micro Framework operands sizes.
        /// </summary>
        /// <param name="methodDefinition">Target method for fixing offsets</param>
        /// <param name="stringTable">String table for populating strings from method.</param>
        public static IEnumerable <Tuple <UInt32, UInt32> > PreProcessMethod(
            MethodDefinition methodDefinition,
            TinyStringTable stringTable)
        {
            if (!methodDefinition.HasBody)
            {
                yield break;
            }

            var offset        = 0;
            var offsetChanged = true;

            foreach (var instruction in methodDefinition.Body.Instructions)
            {
                if (offset != 0)
                {
                    if (offsetChanged)
                    {
                        yield return(new Tuple <UInt32, UInt32>(
                                         (UInt32)instruction.Offset, (UInt32)(instruction.Offset + offset)));

                        offsetChanged = false;
                    }
                    instruction.Offset += offset;
                }

                switch (instruction.OpCode.OperandType)
                {
                case OperandType.InlineSwitch:
                    var targets = (Instruction[])instruction.Operand;
                    offset       -= 3;                  // One bye used instead of Int32
                    offset       -= 2 * targets.Length; // each target use Int16 instead of Int32
                    offsetChanged = true;
                    break;

                case OperandType.InlineString:
                    stringTable.GetOrCreateStringId((String)instruction.Operand, false);
                    offset       -= 2;
                    offsetChanged = true;
                    break;

                case OperandType.InlineMethod:
                case OperandType.InlineField:
                case OperandType.InlineType:
                case OperandType.InlineBrTarget:
                    // In full .NET these instructions followed by double word operand
                    // but in .NET Micro Framework these instruction's operand are word
                    offset       -= 2;
                    offsetChanged = true;
                    break;
                }
            }
        }
Example #2
0
        /// <summary>
        /// Fixes instructions offsets according .NET Micro Framework operands sizes.
        /// </summary>
        /// <param name="methodDefinition">Target method for fixing offsets</param>
        /// <param name="stringTable">String table for populating strings from method.</param>
        public static IEnumerable<Tuple<UInt32, UInt32>> PreProcessMethod(
            MethodDefinition methodDefinition,
            TinyStringTable stringTable)
        {
            if (!methodDefinition.HasBody)
            {
                yield break;
            }

            var offset = 0;
            var offsetChanged = true;
            foreach (var instruction in methodDefinition.Body.Instructions)
            {
                if (offset != 0)
                {
                    if (offsetChanged)
                    {
                        yield return new Tuple<UInt32, UInt32>(
                            (UInt32)instruction.Offset, (UInt32)(instruction.Offset + offset));
                        offsetChanged = false;
                    }
                    instruction.Offset += offset;
                }

                switch (instruction.OpCode.OperandType)
                {
                    case OperandType.InlineSwitch:
		                var targets = (Instruction[]) instruction.Operand;
                        offset -= 3; // One bye used instead of Int32
		                offset -= 2 * targets.Length; // each target use Int16 instead of Int32
                        offsetChanged = true;
                        break;
                    case OperandType.InlineString:
                        stringTable.GetOrCreateStringId((String) instruction.Operand, false);
                        offset -= 2;
                        offsetChanged = true;
                        break;
                    case OperandType.InlineMethod:
                    case OperandType.InlineField:
                    case OperandType.InlineType:
                    case OperandType.InlineBrTarget:
                        // In full .NET these instructions followed by double word operand
                        // but in .NET Micro Framework these instruction's operand are word
                        offset -= 2;
                        offsetChanged = true;
                        break;
                }
            }
        }
Example #3
0
        private void WriteOperand(
            Instruction instruction)
        {
            var opcode      = instruction.OpCode;
            var operandType = opcode.OperandType;

            if (operandType == OperandType.InlineNone)
            {
                return;
            }

            var operand = instruction.Operand;

            if (operand == null)
            {
                throw new ArgumentException();
            }

            switch (operandType)
            {
            case OperandType.InlineSwitch:
            {
                var targets = (Instruction[])operand;
                _writer.WriteByte((Byte)targets.Length);
                var diff = instruction.Offset + opcode.Size + 2 * targets.Length + 1;
                foreach (var item in targets)
                {
                    _writer.WriteInt16((Int16)(GetTargetOffset(item) - diff));
                }
                break;
            }

            case OperandType.ShortInlineBrTarget:
            {
                var target = (Instruction)operand;
                _writer.WriteSByte((SByte)
                                   (GetTargetOffset(target) - (instruction.Offset + opcode.Size + 1)));
                break;
            }

            case OperandType.InlineBrTarget:
            {
                var target = (Instruction)operand;
                _writer.WriteInt16((Int16)
                                   (GetTargetOffset(target) - (instruction.Offset + opcode.Size + 2)));
                break;
            }

            case OperandType.ShortInlineVar:
                _writer.WriteByte((byte)GetVariableIndex((VariableDefinition)operand));
                break;

            case OperandType.ShortInlineArg:
                _writer.WriteByte((byte)GetParameterIndex((ParameterDefinition)operand));
                break;

            case OperandType.InlineVar:
                _writer.WriteInt16((short)GetVariableIndex((VariableDefinition)operand));
                break;

            case OperandType.InlineArg:
                _writer.WriteInt16((short)GetParameterIndex((ParameterDefinition)operand));
                break;

            case OperandType.InlineSig:
                // TODO: implement this properly after finding when such code is generated
                //WriteMetadataToken (GetStandAloneSignature ((CallSite) operand));
                break;

            case OperandType.ShortInlineI:
                if (opcode == OpCodes.Ldc_I4_S)
                {
                    _writer.WriteSByte((SByte)operand);
                }
                else
                {
                    _writer.WriteByte((Byte)operand);
                }
                break;

            case OperandType.InlineI:
                _writer.WriteInt32((Int32)operand);
                break;

            case OperandType.InlineI8:
                _writer.WriteInt64((Int64)operand);
                break;

            case OperandType.ShortInlineR:
                _writer.WriteSingle((Single)operand);
                break;

            case OperandType.InlineR:
                _writer.WriteDouble((Double)operand);
                break;

            case OperandType.InlineString:
                var stringReferenceId = _stringTable.GetOrCreateStringId((String)operand, false);
                _writer.WriteUInt16(stringReferenceId);
                break;

            case OperandType.InlineMethod:
                _writer.WriteUInt16(_context.GetMethodReferenceId((MethodReference)operand));
                break;

            case OperandType.InlineType:
                _writer.WriteUInt16(GetTypeReferenceId((TypeReference)operand));
                break;

            case OperandType.InlineField:
                _writer.WriteUInt16(GetFieldReferenceId((FieldReference)operand));
                break;

            case OperandType.InlineTok:
                _writer.WriteUInt32(GetMetadataToken((IMetadataTokenProvider)operand));
                break;

            default:
                throw new ArgumentException();
            }
        }
        public TinyTablesContext(
            AssemblyDefinition assemblyDefinition,
            List<String> explicitTypesOrder,
            ICustomStringSorter stringSorter,
            Boolean applyAttributesCompression)
        {
            AssemblyDefinition = assemblyDefinition;

            foreach (var item in assemblyDefinition.CustomAttributes)
            {
                _ignoringAttributes.Add(item.AttributeType.FullName);
            }

            NativeMethodsCrc = new NativeMethodsCrc(assemblyDefinition);

            var mainModule = AssemblyDefinition.MainModule;

            // External references

            AssemblyReferenceTable = new TinyAssemblyReferenceTable(
                mainModule.AssemblyReferences, this);

            var typeReferences = mainModule.GetTypeReferences()
                .Where(item => !IsAttribute(item))
                .ToList();
            TypeReferencesTable = new TinyTypeReferenceTable(
                typeReferences, this);

            var typeReferencesNames = new HashSet<String>(
                typeReferences.Select(item => item.FullName),
                StringComparer.Ordinal);
            var memberReferences = mainModule.GetMemberReferences()
                .Where(item => typeReferencesNames.Contains(item.DeclaringType.FullName))
                .ToList();
            FieldReferencesTable = new TinyFieldReferenceTable(
                memberReferences.OfType<FieldReference>(), this);
            MethodReferencesTable = new TinyMethodReferenceTable(
                memberReferences.OfType<MethodReference>(), this);

            // Internal types definitions

            var types = GetOrderedTypes(mainModule, explicitTypesOrder);

            TypeDefinitionTable = new TinyTypeDefinitionTable(types, this);
            
            var fields = types
                .SelectMany(item => GetOrderedFields(item.Fields.Where(field => !field.HasConstant)))
                .ToList();
            FieldsTable = new TinyFieldDefinitionTable(fields, this);

            var methods = types.SelectMany(item => GetOrderedMethods(item.Methods)).ToList();

            MethodDefinitionTable = new TinyMethodDefinitionTable(methods, this);

            AttributesTable = new TinyAttributesTable(
                GetAttributes(types, applyAttributesCompression),
                GetAttributes(fields, applyAttributesCompression),
                GetAttributes(methods, applyAttributesCompression),
                this);

            TypeSpecificationsTable = new TinyTypeSpecificationsTable(this);

            // Resources information

            ResourcesTable = new TinyResourcesTable(
                mainModule.Resources, this);
            ResourceDataTable = new TinyResourceDataTable();

            // Strings and signatures

            SignaturesTable = new TinySignaturesTable(this);
            StringTable = new TinyStringTable(stringSorter);

            // Byte code table
            ByteCodeTable = new TinyByteCodeTable(this);

            // Additional information

            ResourceFileTable = new TinyResourceFileTable(this);

            // Pre-allocate strings from some tables
            AssemblyReferenceTable.AllocateStrings();
            TypeReferencesTable.AllocateStrings();
            foreach (var item in memberReferences)
            {
                StringTable.GetOrCreateStringId(item.Name);
                
                var fieldReference = item as FieldReference;
                if (fieldReference != null)
                {
                    SignaturesTable.GetOrCreateSignatureId(fieldReference);
                }

                var methodReference = item as MethodReference;
                if (methodReference != null)
                {
                    SignaturesTable.GetOrCreateSignatureId(methodReference);
                }
            }
        }
        public TinyTablesContext(
            AssemblyDefinition assemblyDefinition,
            List <String> explicitTypesOrder,
            ICustomStringSorter stringSorter,
            Boolean applyAttributesCompression)
        {
            AssemblyDefinition = assemblyDefinition;

            var assemblyAttributes = new HashSet <String>(
                assemblyDefinition.CustomAttributes.Select(item => item.AttributeType.FullName),
                StringComparer.Ordinal)
            {
                "System.Reflection.AssemblyCultureAttribute",
                "System.Reflection.AssemblyVersionAttribute",
                "System.Runtime.CompilerServices.MethodImplAttribute",
                "System.Runtime.CompilerServices.MethodImplOptions",
                "System.Runtime.InteropServices.StructLayoutAttribute",
                "System.Runtime.InteropServices.OutAttribute",
                "System.Runtime.InteropServices.LayoutKind",
                "System.SerializableAttribute",
                "System.Runtime.CompilerServices.ExtensionAttribute",
                "System.Diagnostics.DebuggerBrowsableAttribute",
                "System.Diagnostics.DebuggerBrowsableState",
                "System.Diagnostics.DebuggerHiddenAttribute",
                "System.Diagnostics.ConditionalAttribute",
                "System.ParamArrayAttribute"
            };

            NativeMethodsCrc = new NativeMethodsCrc(assemblyDefinition);

            var mainModule = AssemblyDefinition.MainModule;

            // External references

            AssemblyReferenceTable = new TinyAssemblyReferenceTable(
                mainModule.AssemblyReferences, this);

            var typeReferences = mainModule.GetTypeReferences()
                                 .Where(item => !IsAttribute(item, assemblyAttributes))
                                 .ToList();

            TypeReferencesTable = new TinyTypeReferenceTable(
                typeReferences, this);

            var typeReferencesNames = new HashSet <String>(
                typeReferences.Select(item => item.FullName),
                StringComparer.Ordinal);
            var memberReferences = mainModule.GetMemberReferences()
                                   .Where(item => typeReferencesNames.Contains(item.DeclaringType.FullName))
                                   .ToList();

            FieldReferencesTable = new TinyFieldReferenceTable(
                memberReferences.OfType <FieldReference>(), this);
            MethodReferencesTable = new TinyMethodReferenceTable(
                memberReferences.OfType <MethodReference>(), this);

            // Internal types definitions

            var types = GetOrderedTypes(mainModule, explicitTypesOrder);

            TypeDefinitionTable = new TinyTypeDefinitionTable(types, this);

            var fields = types
                         .SelectMany(item => GetOrderedFields(item.Fields.Where(field => !field.HasConstant)))
                         .ToList();

            FieldsTable = new TinyFieldDefinitionTable(fields, this);

            var methods = types.SelectMany(item => GetOrderedMethods(item.Methods)).ToList();

            MethodDefinitionTable = new TinyMethodDefinitionTable(methods, this);

            var ignoringAttributes = new HashSet <String>(StringComparer.Ordinal)
            {
                "System.Runtime.CompilerServices.ExtensionAttribute",
                "System.Diagnostics.DebuggerBrowsableAttribute",
                "System.Diagnostics.DebuggerBrowsableState",
                "System.Diagnostics.DebuggerHiddenAttribute",
                "System.Diagnostics.ConditionalAttribute",
                "System.ParamArrayAttribute"
            };

            AttributesTable = new TinyAttributesTable(
                GetAttributes(types, applyAttributesCompression, ignoringAttributes),
                GetAttributes(fields, applyAttributesCompression, ignoringAttributes),
                GetAttributes(methods, applyAttributesCompression, ignoringAttributes),
                this);

            TypeSpecificationsTable = new TinyTypeSpecificationsTable(this);

            // Resources information

            ResourcesTable = new TinyResourcesTable(
                mainModule.Resources, this);
            ResourceDataTable = new TinyResourceDataTable();

            // Strings and signatures

            SignaturesTable = new TinySignaturesTable(this);
            StringTable     = new TinyStringTable(stringSorter);

            // Byte code table
            ByteCodeTable = new TinyByteCodeTable(this);

            // Additional information

            ResourceFileTable = new TinyResourceFileTable(this);

            // Pre-allocate strings from some tables
            AssemblyReferenceTable.AllocateStrings();
            TypeReferencesTable.AllocateStrings();
            foreach (var item in memberReferences)
            {
                StringTable.GetOrCreateStringId(item.Name);

                var fieldReference = item as FieldReference;
                if (fieldReference != null)
                {
                    SignaturesTable.GetOrCreateSignatureId(fieldReference);
                }

                var methodReference = item as MethodReference;
                if (methodReference != null)
                {
                    SignaturesTable.GetOrCreateSignatureId(methodReference);
                }
            }
        }
        public TinyTablesContext(
            AssemblyDefinition assemblyDefinition,
            List <String> explicitTypesOrder,
            ICustomStringSorter stringSorter,
            Boolean applyAttributesCompression)
        {
            AssemblyDefinition = assemblyDefinition;

            foreach (var item in assemblyDefinition.CustomAttributes)
            {
                _ignoringAttributes.Add(item.AttributeType.FullName);
            }

            NativeMethodsCrc = new NativeMethodsCrc(assemblyDefinition);

            var mainModule = AssemblyDefinition.MainModule;

            // External references

            AssemblyReferenceTable = new TinyAssemblyReferenceTable(
                mainModule.AssemblyReferences, this);

            var typeReferences = mainModule.GetTypeReferences()
                                 .Where(item => !IsAttribute(item))
                                 .ToList();

            TypeReferencesTable = new TinyTypeReferenceTable(
                typeReferences, this);

            var typeReferencesNames = new HashSet <String>(
                typeReferences.Select(item => item.FullName),
                StringComparer.Ordinal);
            var memberReferences = mainModule.GetMemberReferences()
                                   .Where(item => typeReferencesNames.Contains(item.DeclaringType.FullName))
                                   .ToList();

            FieldReferencesTable = new TinyFieldReferenceTable(
                memberReferences.OfType <FieldReference>(), this);
            MethodReferencesTable = new TinyMethodReferenceTable(
                memberReferences.OfType <MethodReference>(), this);

            // Internal types definitions

            var types = GetOrderedTypes(mainModule, explicitTypesOrder);

            TypeDefinitionTable = new TinyTypeDefinitionTable(types, this);

            var fields = types
                         .SelectMany(item => GetOrderedFields(item.Fields.Where(field => !field.HasConstant)))
                         .ToList();

            FieldsTable = new TinyFieldDefinitionTable(fields, this);

            var methods = types.SelectMany(item => GetOrderedMethods(item.Methods)).ToList();

            MethodDefinitionTable = new TinyMethodDefinitionTable(methods, this);

            AttributesTable = new TinyAttributesTable(
                GetAttributes(types, applyAttributesCompression),
                GetAttributes(fields, applyAttributesCompression),
                GetAttributes(methods, applyAttributesCompression),
                this);

            TypeSpecificationsTable = new TinyTypeSpecificationsTable(this);

            // Resources information

            ResourcesTable = new TinyResourcesTable(
                mainModule.Resources, this);
            ResourceDataTable = new TinyResourceDataTable();

            // Strings and signatures

            SignaturesTable = new TinySignaturesTable(this);
            StringTable     = new TinyStringTable(stringSorter);

            // Byte code table
            ByteCodeTable = new TinyByteCodeTable(this);

            // Additional information

            ResourceFileTable = new TinyResourceFileTable(this);

            // Pre-allocate strings from some tables
            AssemblyReferenceTable.AllocateStrings();
            TypeReferencesTable.AllocateStrings();
            foreach (var item in memberReferences)
            {
                StringTable.GetOrCreateStringId(item.Name);

                var fieldReference = item as FieldReference;
                if (fieldReference != null)
                {
                    SignaturesTable.GetOrCreateSignatureId(fieldReference);
                }

                var methodReference = item as MethodReference;
                if (methodReference != null)
                {
                    SignaturesTable.GetOrCreateSignatureId(methodReference);
                }
            }
        }