예제 #1
0
        private LinkerSymbol CreateCustomAttributeArgument(string symbolName, int count, string name, MosaCustomAttribute.Argument arg, bool isField)
        {
            string nameForSymbol = name ?? count.ToString();

            nameForSymbol = symbolName + ":" + nameForSymbol;
            var symbol  = Linker.DefineSymbol(Metadata.CustomAttributeArgument + nameForSymbol, SectionKind.ROData, TypeLayout.NativePointerAlignment, 0);
            var writer1 = new EndianAwareBinaryWriter(symbol.Stream, Architecture.Endianness);

            // 1. Pointer to name (if named)
            if (name != null)
            {
                var nameSymbol = EmitStringWithLength(Metadata.NameString + nameForSymbol, name);
                Linker.Link(LinkType.AbsoluteAddress, NativePatchType, symbol, writer1.Position, nameSymbol, 0);
            }
            writer1.WriteZeroBytes(TypeLayout.NativePointerSize);

            // 2. Is Argument A Field
            writer1.Write(isField, TypeLayout.NativePointerSize);

            // 3. Argument Type Pointer
            Linker.Link(LinkType.AbsoluteAddress, NativePatchType, symbol, writer1.Position, Metadata.TypeDefinition + arg.Type.FullName, 0);
            writer1.WriteZeroBytes(TypeLayout.NativePointerSize);

            // 4. Argument Size
            writer1.Write(ComputeArgumentSize(arg.Type, arg.Value), TypeLayout.NativePointerSize);

            // 5. Argument Value
            WriteArgument(writer1, symbol, arg.Type, arg.Value);

            return(symbol);
        }
예제 #2
0
        private void EmitDebugInfo(EndianAwareBinaryWriter wr)
        {
            // note: Compilation Unit Header != Debugging Information Entry

            // Compilation Unit Header
            var compilationUnitSizePosition = wr.Position;

            wr.Write((uint)7);           // length
            wr.Write((ushort)0x02);      // version
            wr.Write((uint)0);           // abbr tag offset.
            wr.WriteByte(4);             //addr size of platform

            var context = new DwarfWriteContext {
                Writer = wr, AbbrevList = AbbrevList
            };

            var textSection = Compiler.Linker.Sections[(int)SectionKind.Text];

            // Debugging Information Entry
            var cu = new DwarfCompilationUnit
            {
                Producer           = "Mosa Compiler",
                ProgramCounterLow  = (uint)textSection.VirtualAddress,
                ProgramCounterHigh = (uint)textSection.VirtualAddress + textSection.Size
            };

            cu.Emit(context);

            uint compilationUnitSize = (uint)(wr.Position - compilationUnitSizePosition - sizeof(uint));

            wr.Position = compilationUnitSizePosition;
            wr.Write(compilationUnitSize);
            wr.Position = wr.BaseStream.Length;
        }
예제 #3
0
        protected void WriteSectionHeaderStringSection(Section section)
        {
            Debug.Assert(section == sectionHeaderStringSection);

            section.Size = (uint)sectionHeaderStringTable.Count;
            writer.Write(sectionHeaderStringTable.ToArray());
        }
예제 #4
0
 internal void Write(EndianAwareBinaryWriter writer)
 {
     writer.Write(this.majorVersion);
     writer.Write(this.MinorVersion);
     writer.Write(this.buildNumber);
     writer.Write(this.revision);
 }
예제 #5
0
        /// <summary>
        /// Writes the structure to the given writer.
        /// </summary>
        /// <param name="writer">The writer.</param>
        public void Write(EndianAwareBinaryWriter writer)
        {
            if (writer == null)
                throw new ArgumentNullException(@"writer");

            writer.Write(this.VirtualAddress);
            writer.Write(this.Size);
        }
예제 #6
0
        private LinkerSymbol CreateAssemblyDefinition(MosaModule module)
        {
            // Emit assembly name
            var assemblyNameSymbol = EmitStringWithLength(Metadata.NameString + module.Assembly, module.Assembly);

            // Emit assembly table
            var assemblyTableSymbol = Linker.DefineSymbol(Metadata.AssemblyDefinition + module.Assembly, SectionKind.ROData, TypeLayout.NativePointerAlignment, 0);
            var writer = new EndianAwareBinaryWriter(assemblyTableSymbol.Stream, Architecture.Endianness);

            // 1. Pointer to Assembly Name
            Linker.Link(LinkType.AbsoluteAddress, NativePatchType, assemblyTableSymbol, writer.Position, assemblyNameSymbol, 0);
            writer.WriteZeroBytes(TypeLayout.NativePointerSize);

            // 2. Pointer to Custom Attributes
            if (module.CustomAttributes.Count > 0)
            {
                var customAttributeListSymbol = CreateCustomAttributesTable(module);
                Linker.Link(LinkType.AbsoluteAddress, NativePatchType, assemblyTableSymbol, writer.Position, customAttributeListSymbol, 0);
            }
            writer.WriteZeroBytes(TypeLayout.NativePointerSize);

            // 3. Attributes - IsReflectionOnly (32bit length)
            uint flags = 0x0;

            if (module.IsReflectionOnly)
            {
                flags |= 0x1;
            }
            writer.Write(flags, TypeLayout.NativePointerSize);

            // 4. Number of Types
            uint count = 0;

            writer.WriteZeroBytes(4);

            // 5. Pointers to Types
            foreach (var type in module.Types.Values)
            {
                if (type.IsModule)
                {
                    continue;
                }

                var typeTableSymbol = CreateTypeDefinition(type, assemblyTableSymbol);

                // Link
                Linker.Link(LinkType.AbsoluteAddress, NativePatchType, assemblyTableSymbol, writer.Position, typeTableSymbol, 0);
                writer.WriteZeroBytes(TypeLayout.NativePointerSize);

                count++;
            }

            writer.Position = 3 * TypeLayout.NativePointerSize;
            writer.Write(count, TypeLayout.NativePointerSize);

            return(assemblyTableSymbol);
        }
예제 #7
0
        private void EmitProtectedRegionTable()
        {
            var trace = CreateTraceLog("Regions");

            var protectedRegionTableSymbol = MethodCompiler.Linker.DefineSymbol(Metadata.ProtectedRegionTable + MethodCompiler.Method.FullName, SectionKind.ROData, NativeAlignment, 0);
            var writer = new EndianAwareBinaryWriter(protectedRegionTableSymbol.Stream, Architecture.Endianness);

            int sectioncount = 0;

            // 1. Number of Regions (filled in later)
            writer.Write((uint)0);

            foreach (var region in MethodCompiler.ProtectedRegions)
            {
                var handler = (uint)MethodCompiler.GetPosition(region.Handler.HandlerStart);

                trace?.Log($"Handler: {region.Handler.TryStart.ToString("X4")} to {region.Handler.TryEnd.ToString("X4")} Handler: {region.Handler.HandlerStart.ToString("X4")} Offset: [{handler.ToString("X4")}]");

                var sections = new List <Tuple <int, int> >();

                foreach (var block in region.IncludedBlocks)
                {
                    // Check if block continues to exist
                    if (!BasicBlocks.Contains(block))
                    {
                        continue;
                    }

                    int start = MethodCompiler.GetPosition(block.Label);
                    int end   = MethodCompiler.GetPosition(block.Label + 0x0F000000);

                    trace?.Log($"   Block: {block} [{start.ToString()}-{end.ToString()}]");

                    AddSection(sections, start, end);
                }

                foreach (var s in sections)
                {
                    int start = s.Item1;
                    int end   = s.Item2;

                    sectioncount++;

                    var name = Metadata.ProtectedRegionTable + MethodCompiler.Method.FullName + "$" + sectioncount.ToString();
                    var protectedRegionDefinition = CreateProtectedRegionDefinition(name, (uint)start, (uint)end, handler, region.Handler.ExceptionHandlerType, region.Handler.Type);
                    MethodCompiler.Linker.Link(LinkType.AbsoluteAddress, NativePatchType, protectedRegionTableSymbol, writer.Position, protectedRegionDefinition, 0);
                    writer.WriteZeroBytes(TypeLayout.NativePointerSize);

                    trace?.Log($"     Section: [{start.ToString()}-{end.ToString()}]");
                }
            }

            // 1. Number of Regions (now put the real number)
            writer.Position = 0;
            writer.Write(sectioncount);
        }
예제 #8
0
        /// <summary>
        /// Writes the structure to the given writer.
        /// </summary>
        /// <param name="writer">The writer.</param>
        public void Write(EndianAwareBinaryWriter writer)
        {
            if (writer == null)
            {
                throw new ArgumentNullException(@"writer");
            }

            writer.Write(this.VirtualAddress);
            writer.Write(this.Size);
        }
예제 #9
0
            internal void Write(EndianAwareBinaryWriter writer)
            {
                writer.Write((ushort)this.imageKind);
                writer.Write(this.lMajor);
                writer.Write(this.lMinor);
                writer.Write(this.codeSize);
                writer.Write(this.initializedDataSize);
                writer.Write(this.uninitializedDataSize);
                writer.Write(this.entryPointRVA);
                writer.Write(this.baseOfCode);
                switch (this.imageKind)
                {
                case PEImageKind.x86Image:
                    writer.Write(this.baseOfData);
                    break;

                case PEImageKind.x64Image:
                    break;

                case PEImageKind.RomImage:
                    throw new NotImplementedException();

                default:
                    throw new BadImageFormatException();
                }
            }
예제 #10
0
        private LinkerSymbol EmitStringWithLength(string name, string value)
        {
            // Strings are now going to be embedded objects since they are immutable
            var symbol = Linker.DefineSymbol(name, SectionKind.ROData, TypeLayout.NativePointerAlignment, 0);
            var writer = new EndianAwareBinaryWriter(symbol.Stream, Architecture.Endianness);

            Linker.Link(LinkType.AbsoluteAddress, NativePatchType, symbol, writer.Position, Metadata.TypeDefinition + "System.String", 0);
            writer.WriteZeroBytes(TypeLayout.NativePointerSize * 2);
            writer.Write(value.Length, TypeLayout.NativePointerSize);
            writer.Write(Encoding.Unicode.GetBytes(value));
            return(symbol);
        }
예제 #11
0
        private void EmitDebugLine(EndianAwareBinaryWriter wr)
        {
            var compilationUnitSizePosition = wr.Position;

            wr.Write((uint)0);             // Placeholder for Compilation unit Size

            wr.WriteByte(0x02);            // DWARF Version
            wr.WriteByte(0x00);            // version (2 bytes)

            var headerSizePosition = wr.Position;

            wr.Write((uint)0);             // Placeholder for header size

            wr.WriteByte(0x01);            // Minimum Instruction length
            wr.WriteByte(0x01);            // Default is_stmt value
            wr.WriteByte(0xFB);            // Value doesn't matter, because we are not using special op codes
            wr.WriteByte(0x0E);            // Value doesn't matter, because we are not using special op codes
            wr.WriteByte(9 + 1);           // first special op code

            // the number of arguments for the 9 standard opcodes
            wr.WriteByte(0x00);             // 1
            wr.WriteByte(0x01);             // 2
            wr.WriteByte(0x01);             // ...
            wr.WriteByte(0x01);

            wr.WriteByte(0x01);
            wr.WriteByte(0x00);
            wr.WriteByte(0x00);
            wr.WriteByte(0x00);

            wr.WriteByte(0x01);             // 9

            AddFilenames();

            EmitDirectories(wr);
            EmitFiles(wr);

            // Write header size
            uint headerSize = (uint)(wr.Position - headerSizePosition - sizeof(uint));

            wr.Position = headerSizePosition;
            wr.Write(headerSize);
            wr.Position = wr.BaseStream.Length;

            EmitDebugLineTypes(wr);

            uint compilationUnitSize = (uint)(wr.Position - compilationUnitSizePosition - sizeof(uint));

            wr.Position = compilationUnitSizePosition;
            wr.Write(compilationUnitSize);
            wr.Position = wr.BaseStream.Length;
        }
예제 #12
0
 /// <summary>
 /// Writes the header to the given binary writer.
 /// </summary>
 /// <param name="writer">The binary writer to write to.</param>
 public void WriteTo(EndianAwareBinaryWriter writer)
 {
     writer.Write(Cb);
     writer.Write(MajorRuntimeVersion);
     writer.Write(MinorRuntimeVersion);
     Metadata.Write(writer);
     writer.Write((uint)Flags);
     writer.Write(EntryPointToken);
     Resources.Write(writer);
     StrongNameSignature.Write(writer);
     CodeManagerTable.Write(writer);
     VTableFixups.Write(writer);
     ExportAddressTableJumps.Write(writer);
     ManagedNativeHeader.Write(writer);
 }
예제 #13
0
        private LinkerSymbol CreateCustomAttributesTable(MosaUnit unit)
        {
            // Emit custom attributes table
            var customAttributesTableSymbol = Linker.CreateSymbol(unit.FullName + Metadata.CustomAttributesTable, SectionKind.ROData, TypeLayout.NativePointerAlignment, 0);
            var writer1 = new EndianAwareBinaryWriter(customAttributesTableSymbol.Stream, Architecture.Endianness);

            // 1. Number of Custom Attributes
            writer1.Write(unit.CustomAttributes.Count, TypeLayout.NativePointerSize);

            // 2. Pointers to Custom Attributes
            // Create the definitions along the way
            for (int i = 0; i < unit.CustomAttributes.Count; i++)
            {
                // Get custom attribute
                var ca = unit.CustomAttributes[i];

                // Build definition
                var customAttributeTableSymbol = CreateCustomAttribute(unit, ca, i);

                // Link
                Linker.Link(LinkType.AbsoluteAddress, NativePatchType, customAttributesTableSymbol, (int)writer1.Position, 0, customAttributeTableSymbol, 0);
                writer1.WriteZeroBytes(TypeLayout.NativePointerSize);
            }

            // Return customAttributesTableSymbol for linker usage
            return(customAttributesTableSymbol);
        }
예제 #14
0
        private LinkerSymbol CreateCustomAttributesTable(MosaUnit unit)
        {
            var symbolName = Metadata.CustomAttributesTable + unit.FullName;

            var customAttributesTableSymbol = Linker.GetSymbol(symbolName);

            if (customAttributesTableSymbol.Size != 0)
            {
                return(customAttributesTableSymbol);
            }

            // Emit custom attributes table
            customAttributesTableSymbol = Linker.DefineSymbol(symbolName, SectionKind.ROData, TypeLayout.NativePointerAlignment, 0);
            var writer = new EndianAwareBinaryWriter(customAttributesTableSymbol.Stream, Architecture.Endianness);

            // 1. Number of Custom Attributes
            writer.Write(unit.CustomAttributes.Count, TypeLayout.NativePointerSize);

            // 2. Pointers to Custom Attributes
            for (int i = 0; i < unit.CustomAttributes.Count; i++)
            {
                // Get custom attribute
                var ca = unit.CustomAttributes[i];

                // Build definition
                var customAttributeTableSymbol = CreateCustomAttribute(unit, ca, i);

                // Link
                Linker.Link(LinkType.AbsoluteAddress, NativePatchType, customAttributesTableSymbol, writer.Position, customAttributeTableSymbol, 0);
                writer.WriteZeroBytes(TypeLayout.NativePointerSize);
            }

            return(customAttributesTableSymbol);
        }
예제 #15
0
        private void WriteSectionHeaderStringSection(Section section, EndianAwareBinaryWriter writer)
        {
            Debug.Assert(section == sectionHeaderStringSection);

            section.Size = (uint)sectionHeaderStringTable.Count;
            writer.Write(sectionHeaderStringTable.ToArray());
        }
예제 #16
0
        private LinkerSymbol CreateParameterDefinition(MosaParameter parameter)
        {
            // Emit parameter name
            var parameterNameSymbol = EmitStringWithLength(Metadata.NameString + parameter, parameter.FullName);

            // Emit parameter table
            var parameterTableSymbol = Linker.DefineSymbol(Metadata.MethodDefinition + parameter.FullName, SectionKind.ROData, TypeLayout.NativePointerAlignment, 0);
            var writer = new EndianAwareBinaryWriter(parameterTableSymbol.Stream, Architecture.Endianness);

            // 1. Pointer to Name
            Linker.Link(LinkType.AbsoluteAddress, NativePatchType, parameterTableSymbol, writer.Position, parameterNameSymbol, 0);
            writer.WriteZeroBytes(TypeLayout.NativePointerSize);

            // 2. Pointer to Custom Attributes
            if (parameter.CustomAttributes.Count > 0)
            {
                var customAttributeListSymbol = CreateCustomAttributesTable(parameter);
                Linker.Link(LinkType.AbsoluteAddress, NativePatchType, parameterTableSymbol, writer.Position, customAttributeListSymbol, 0);
            }
            writer.WriteZeroBytes(TypeLayout.NativePointerSize);

            // 3. Attributes
            writer.Write((uint)parameter.ParameterAttributes, TypeLayout.NativePointerSize);

            // 4. Pointer to Parameter Type
            Linker.Link(LinkType.AbsoluteAddress, NativePatchType, parameterTableSymbol, writer.Position, Metadata.TypeDefinition + parameter.ParameterType.FullName, 0);
            writer.WriteZeroBytes(TypeLayout.NativePointerSize);

            return(parameterTableSymbol);
        }
예제 #17
0
        private LinkerSymbol CreateInterfaceMethodTable(MosaType type, MosaType interfaceType)
        {
            // Emit interface method table
            var interfaceMethodTableSymbol = Linker.DefineSymbol(Metadata.InterfaceMethodTable + type.FullName + "$" + interfaceType.FullName, SectionKind.ROData, TypeLayout.NativePointerAlignment, 0);
            var writer = new EndianAwareBinaryWriter(interfaceMethodTableSymbol.Stream, Architecture.Endianness);

            var interfaceMethodTable = TypeLayout.GetInterfaceTable(type, interfaceType) ?? new MosaMethod[0];

            // 1. Number of Interface Methods
            writer.Write((uint)interfaceMethodTable.Length, TypeLayout.NativePointerSize);

            // 2. Pointer to Interface Type
            Linker.Link(LinkType.AbsoluteAddress, NativePatchType, interfaceMethodTableSymbol, writer.Position, Metadata.TypeDefinition + interfaceType.FullName, 0);
            writer.WriteZeroBytes(TypeLayout.NativePointerSize);

            // 3. Pointers to Method Definitions
            foreach (var method in interfaceMethodTable)
            {
                // Create definition and get the symbol
                var methodDefinitionSymbol = CreateMethodDefinition(method);

                Linker.Link(LinkType.AbsoluteAddress, NativePatchType, interfaceMethodTableSymbol, writer.Position, methodDefinitionSymbol, 0);
                writer.WriteZeroBytes(TypeLayout.NativePointerSize);
            }

            return(interfaceMethodTableSymbol);
        }
예제 #18
0
        private void CreateFieldDefinitions(MosaType type)
        {
            foreach (MosaField field in type.Fields)
            {
                string fieldNameSymbol = field.FullName + @"$name";

                // Emit field name
                using (Stream stream = Linker.Allocate(fieldNameSymbol, SectionKind.ROData, 0, TypeLayout.NativePointerAlignment))
                {
                    using (EndianAwareBinaryWriter writer = new EndianAwareBinaryWriter(stream, Architecture.Endianness))
                    {
                        EmitStringWithLength(writer, field.Name);
                    }
                }

                string fieldDescSymbol = field.FullName + @"$desc";

                // Emit field descriptor
                using (Stream stream = Linker.Allocate(fieldDescSymbol, SectionKind.ROData, 0, TypeLayout.NativePointerAlignment))
                {
                    using (EndianAwareBinaryWriter writer = new EndianAwareBinaryWriter(stream, Architecture.Endianness))
                    {
                        // 1. Offset / Address
                        if (field.IsStatic && !field.IsLiteral)
                        {
                            Linker.Link(LinkType.AbsoluteAddress | LinkType.I4, BuiltInPatch.I4, fieldDescSymbol, (int)writer.Position, 0, field.FullName, 0);
                        }
                        else
                        {
                            writer.Write(TypeLayout.GetFieldOffset(field));
                            writer.Position -= 4;
                        }
                        writer.Position += TypeLayout.NativePointerSize;

                        // 2. Name
                        Linker.Link(LinkType.AbsoluteAddress | LinkType.I4, BuiltInPatch.I4, fieldDescSymbol, (int)writer.Position, 0, fieldNameSymbol, 0);
                        writer.Position += TypeLayout.NativePointerSize;

                        // 3. Size
                        writer.Write((uint)TypeLayout.GetFieldSize(field));

                        // 4. Metadata Token
                        writer.Write((uint)0); //FIXME!
                    }
                }
            }
        }
예제 #19
0
        public void Write(EndianAwareBinaryWriter writer)
        {
            writer.Write(this.offset);
            writer.Write(this.size);
            int nameLength = this.name.Length;

            if ((nameLength & 3) == 0)
            {
                writer.Write(this.name, 0, nameLength);
            }
            else
            {
                byte[] name = new byte[(nameLength + 3) << 2 >> 2];
                Array.ConstrainedCopy(this.name, 0, name, 0, nameLength);
                writer.Write(name, 0, name.Length);
            }
        }
예제 #20
0
        /// <summary>
        /// Writes the structure to the given writer.
        /// </summary>
        /// <param name="writer">The writer.</param>
        public void Write(EndianAwareBinaryWriter writer)
        {
            if (writer == null)
                throw new ArgumentNullException(@"writer");

            writer.Write(this.Signature);
            this.FileHeader.Write(writer);
            this.OptionalHeader.Write(writer);
        }
예제 #21
0
        /// <summary>
        /// Writes the structure to the given writer.
        /// </summary>
        /// <param name="writer">The writer.</param>
        public void Write(EndianAwareBinaryWriter writer)
        {
            if (writer == null)
            {
                throw new ArgumentNullException(@"writer");
            }

            writer.Write(this.Signature);
            this.FileHeader.Write(writer);
            this.OptionalHeader.Write(writer);
        }
예제 #22
0
        private void CreateAssemblyDefinitionTable(ITypeModule typeModule)
        {
            string assemblyNameSymbol = typeModule.Name + @"$aname";

            // Emit assembly name
            using (Stream stream = linker.Allocate(assemblyNameSymbol, SectionKind.ROData, 0, typeLayout.NativePointerAlignment))
            {
                using (EndianAwareBinaryWriter writer = new EndianAwareBinaryWriter(stream, architecture.IsLittleEndian))
                {
                    EmitStringWithLength(writer, typeModule.Name);
                }
            }

            uint moduleTypes = 0;

            foreach (RuntimeType type in typeModule.GetAllTypes())
            {
                if (!type.IsModule)
                    moduleTypes++;
            }

            string assemblyTableSymbol = typeModule.Name + @"$atable";

            using (Stream stream = linker.Allocate(assemblyTableSymbol, SectionKind.ROData, 0, typeLayout.NativePointerAlignment))
            {
                using (EndianAwareBinaryWriter writer = new EndianAwareBinaryWriter(stream, architecture.IsLittleEndian))
                {
                    // 1. Pointer to Assembly Name
                    linker.Link(LinkType.AbsoluteAddress | LinkType.NativeI4, assemblyTableSymbol, 0, 0, assemblyNameSymbol, IntPtr.Zero);
                    writer.Position += typeLayout.NativePointerSize;

                    // 2. Number of types
                    writer.Write(moduleTypes);

                    // 3. Pointer to list of types
                    foreach (var type in typeModule.GetAllTypes())
                    {
                        if (!type.IsModule && !(type.Module is InternalTypeModule))
                            linker.Link(LinkType.AbsoluteAddress | LinkType.NativeI4, assemblyTableSymbol, (int)writer.Position, 0, type.FullName + @"$dtable", IntPtr.Zero);

                        writer.Position += typeLayout.NativePointerSize;
                    }
                }
            }

            foreach (var type in typeModule.GetAllTypes())
            {
                if (!type.IsModule)
                {
                    CreateTypeDefinitionTable(type, assemblyTableSymbol);
                }
            }
        }
예제 #23
0
        private LinkerSymbol CreateProtectedRegionDefinition(string name, uint start, uint end, uint handler, ExceptionHandlerType handlerType, MosaType exceptionType)
        {
            // Emit parameter table
            var protectedRegionDefinitionSymbol = MethodCompiler.Linker.DefineSymbol(name, SectionKind.ROData, 0 /*TypeLayout.NativePointerAlignment*/, 0);
            var writer1 = new EndianAwareBinaryWriter(protectedRegionDefinitionSymbol.Stream, Architecture.Endianness);

            // 1. Offset to start
            writer1.Write(start, TypeLayout.NativePointerSize);

            // 2. Offset to end
            writer1.Write(end, TypeLayout.NativePointerSize);

            // 3. Offset to handler
            writer1.Write(handler, TypeLayout.NativePointerSize);

            // 4. Handler type
            writer1.Write((uint)handlerType, TypeLayout.NativePointerSize);

            // 5. Exception object type
            if (handlerType == ExceptionHandlerType.Exception)
            {
                // Store method table pointer of the exception object type
                // The VES exception runtime will uses this to compare exception object types
                Linker.Link(LinkType.AbsoluteAddress, NativePatchType, protectedRegionDefinitionSymbol, writer1.Position, Metadata.TypeDefinition + exceptionType.FullName, 0);
            }
            else if (handlerType == ExceptionHandlerType.Filter)
            {
                // TODO: There are no plans in the short term to support filtered exception clause as C# does not use them
            }
            else
            {
            }

            writer1.WriteZeroBytes(TypeLayout.NativePointerSize);

            // Return protectedRegionSymbol for linker usage
            return(protectedRegionDefinitionSymbol);
        }
예제 #24
0
 internal void Write(EndianAwareBinaryWriter writer)
 {
     writer.Write(this.signature);
     writer.Write((ushort)this.machine);
     writer.Write(this.sectionCount);
     writer.Write(this.secondsElapsedSinceEpoc);
     symbolTableRVAndSize.Write(writer);
     writer.Write(optionalHeaderSize);
     writer.Write((ushort)this.characteristics);
 }
예제 #25
0
        private LinkerSymbol CreateCustomAttribute(MosaUnit unit, MosaCustomAttribute ca, int position)
        {
            // Emit custom attribute list
            string name = unit.FullName + ">>" + position.ToString() + ":" + ca.Constructor.DeclaringType.Name;

            var customAttributeSymbol = Linker.DefineSymbol(Metadata.CustomAttribute + name, SectionKind.ROData, TypeLayout.NativePointerAlignment, 0);
            var writer1 = new EndianAwareBinaryWriter(customAttributeSymbol.Stream, Architecture.Endianness);

            // 1. Pointer to Attribute Type
            Linker.Link(LinkType.AbsoluteAddress, NativePatchType, customAttributeSymbol, writer1.Position, Metadata.TypeDefinition + ca.Constructor.DeclaringType.FullName, 0);
            writer1.WriteZeroBytes(TypeLayout.NativePointerSize);

            // 2. Pointer to Constructor Method Definition
            Linker.Link(LinkType.AbsoluteAddress, NativePatchType, customAttributeSymbol, writer1.Position, Metadata.MethodDefinition + ca.Constructor.FullName, 0);

            writer1.WriteZeroBytes(TypeLayout.NativePointerSize);

            // 3. Number of Arguments (Both unnamed and named)
            writer1.Write((uint)(ca.Arguments.Length + ca.NamedArguments.Length), TypeLayout.NativePointerSize);

            // 4. Pointers to Custom Attribute Arguments (Both unnamed and named)
            for (int i = 0; i < ca.Arguments.Length; i++)
            {
                // Build definition
                var customAttributeArgumentSymbol = CreateCustomAttributeArgument(name, i, null, ca.Arguments[i], false);

                // Link
                Linker.Link(LinkType.AbsoluteAddress, NativePatchType, customAttributeSymbol, writer1.Position, customAttributeArgumentSymbol, 0);
                writer1.WriteZeroBytes(TypeLayout.NativePointerSize);
            }

            foreach (var namedArg in ca.NamedArguments)
            {
                // Build definition
                var customAttributeArgumentSymbol = CreateCustomAttributeArgument(name, 0, namedArg.Name, namedArg.Argument, namedArg.IsField);

                // Link
                Linker.Link(LinkType.AbsoluteAddress, NativePatchType, customAttributeSymbol, writer1.Position, customAttributeArgumentSymbol, 0);
                writer1.WriteZeroBytes(TypeLayout.NativePointerSize);
            }

            return(customAttributeSymbol);
        }
예제 #26
0
        private void CreateDefinitionTables()
        {
            // Emit assembly list
            var assemblyListSymbol = Linker.DefineSymbol(Metadata.AssembliesTable, SectionKind.ROData, TypeLayout.NativePointerAlignment, 0);
            var writer             = new EndianAwareBinaryWriter(assemblyListSymbol.Stream, Architecture.Endianness);

            // 1. Number of Assemblies
            writer.Write((uint)TypeSystem.Modules.Count, TypeLayout.NativePointerSize);

            // 2. Pointers to Assemblies
            foreach (var module in TypeSystem.Modules)
            {
                var assemblyTableSymbol = CreateAssemblyDefinition(module);

                // Link
                Linker.Link(LinkType.AbsoluteAddress, NativePatchType, assemblyListSymbol, writer.Position, assemblyTableSymbol, 0);
                writer.WriteZeroBytes(TypeLayout.NativePointerSize);
            }
        }
예제 #27
0
        /// <summary>
        /// Writes the dos header of the PE file.
        /// </summary>
        /// <param name="writer">The writer.</param>
        private void WriteDosHeader(EndianAwareBinaryWriter writer)
        {
            /*
             * This code block generates the default DOS header of a PE image.
             * These constants are not further documented here, please consult
             * MSDN for their meaning.
             */

            dosHeader.e_magic    = ImageDosHeader.DOS_HEADER_MAGIC;
            dosHeader.e_cblp     = 0x0090;
            dosHeader.e_cp       = 0x0003;
            dosHeader.e_cparhdr  = 0x0004;
            dosHeader.e_maxalloc = 0xFFFF;
            dosHeader.e_sp       = 0xb8;
            dosHeader.e_lfarlc   = 0x0040;
            dosHeader.e_lfanew   = 0x00000080;
            dosHeader.Write(writer);

            writer.Write(dosmessage);
        }
예제 #28
0
        private LinkerSymbol CreateInterfaceSlotTable(MosaType type)
        {
            // Emit interface slot table
            var interfaceSlotTableSymbol = Linker.CreateSymbol(type.FullName + Metadata.InterfaceSlotTable, SectionKind.ROData, TypeLayout.NativePointerAlignment, 0);
            var writer1 = new EndianAwareBinaryWriter(interfaceSlotTableSymbol.Stream, Architecture.Endianness);

            var slots = new List <MosaType>(TypeLayout.Interfaces.Count);

            foreach (MosaType interfaceType in TypeLayout.Interfaces)
            {
                if (type.Interfaces.Contains(interfaceType))
                {
                    slots.Add(interfaceType);
                }
                else
                {
                    slots.Add(null);
                }
            }

            // 1. Number of Interface slots
            writer1.Write((uint)slots.Count, TypeLayout.NativePointerSize);

            // 2. Pointers to Interface Method Tables
            foreach (MosaType interfaceType in slots)
            {
                if (interfaceType != null)
                {
                    var interfaceMethodTableSymbol = CreateInterfaceMethodTable(type, interfaceType);

                    // Link
                    Linker.Link(LinkType.AbsoluteAddress, NativePatchType, interfaceSlotTableSymbol, (int)writer1.Position, 0, interfaceMethodTableSymbol, 0);
                }
                writer1.WriteZeroBytes(TypeLayout.NativePointerSize);
            }

            // Return interfaceSlotTableSymbol for linker usage
            return(interfaceSlotTableSymbol);
        }
예제 #29
0
        /// <summary>
        /// Writes the dos header of the PE file.
        /// </summary>
        /// <param name="writer">The writer.</param>
        private void WriteDosHeader(EndianAwareBinaryWriter writer)
        {
            /*
             * This code block generates the default DOS header of a PE image.
             * These constants are not further documented here, please consult
             * MSDN for their meaning.
             */

            dosHeader.e_magic = ImageDosHeader.DOS_HEADER_MAGIC;
            dosHeader.e_cblp = 0x0090;
            dosHeader.e_cp = 0x0003;
            dosHeader.e_cparhdr = 0x0004;
            dosHeader.e_maxalloc = 0xFFFF;
            dosHeader.e_sp = 0xb8;
            dosHeader.e_lfarlc = 0x0040;
            dosHeader.e_lfanew = 0x00000080;
            dosHeader.Write(writer);

            writer.Write(dosmessage);
        }
예제 #30
0
        private LinkerSymbol CreateMethodDefinition(MosaMethod method)
        {
            var symbolName        = Metadata.MethodDefinition + method.FullName;
            var methodTableSymbol = Linker.GetSymbol(symbolName);

            if (methodTableSymbol.Size != 0)
            {
                return(methodTableSymbol);
            }

            // Emit method name
            var methodNameSymbol = EmitStringWithLength(Metadata.NameString + method.FullName, method.FullName);

            // Emit method table
            methodTableSymbol = Linker.DefineSymbol(symbolName, SectionKind.ROData, TypeLayout.NativePointerAlignment, (method.Signature.Parameters.Count + 9) * TypeLayout.NativePointerSize);
            var writer = new EndianAwareBinaryWriter(methodTableSymbol.Stream, Architecture.Endianness);

            // 1. Pointer to Name
            Linker.Link(LinkType.AbsoluteAddress, NativePatchType, methodTableSymbol, writer.Position, methodNameSymbol, 0);
            writer.WriteZeroBytes(TypeLayout.NativePointerSize);

            // 2. Pointer to Custom Attributes
            if (method.CustomAttributes.Count > 0)
            {
                var customAttributeListSymbol = CreateCustomAttributesTable(method);
                Linker.Link(LinkType.AbsoluteAddress, NativePatchType, methodTableSymbol, writer.Position, customAttributeListSymbol, 0);
            }
            writer.WriteZeroBytes(TypeLayout.NativePointerSize);

            // 3. Attributes
            writer.Write((uint)method.MethodAttributes, TypeLayout.NativePointerSize);

            var targetMethodData = GetTargetMethodData(method);

            // 4. Local Stack Size (16 Bits) && Parameter Stack Size (16 Bits)
            writer.Write(targetMethodData.LocalMethodStackSize | (targetMethodData.ParameterStackSize << 16), TypeLayout.NativePointerSize);

            // 5. Pointer to Method
            if (targetMethodData.HasCode)
            {
                Linker.Link(LinkType.AbsoluteAddress, NativePatchType, methodTableSymbol, writer.Position, targetMethodData.Method.FullName, 0);
            }
            writer.WriteZeroBytes(TypeLayout.NativePointerSize);

            // 6. Pointer to return type
            Linker.Link(LinkType.AbsoluteAddress, NativePatchType, methodTableSymbol, writer.Position, Metadata.TypeDefinition + method.Signature.ReturnType.FullName, 0);
            writer.WriteZeroBytes(TypeLayout.NativePointerSize);

            // 7. Pointer to Exception Handler Table
            if (targetMethodData.HasProtectedRegions && targetMethodData.HasCode)
            {
                Linker.Link(LinkType.AbsoluteAddress, NativePatchType, methodTableSymbol, writer.Position, Metadata.ProtectedRegionTable + targetMethodData.Method.FullName, 0);
            }
            writer.WriteZeroBytes(TypeLayout.NativePointerSize);

            // 8. Pointer to GC Tracking information
            // TODO: This has yet to be designed.
            writer.WriteZeroBytes(TypeLayout.NativePointerSize);

            // 9. Number of Parameters
            writer.Write((uint)method.Signature.Parameters.Count, TypeLayout.NativePointerSize);

            // 10. Pointers to Parameter Definitions
            foreach (var parameter in method.Signature.Parameters)
            {
                // Create definition and get the symbol
                var parameterDefinitionSymbol = CreateParameterDefinition(parameter);

                // Link
                Linker.Link(LinkType.AbsoluteAddress, NativePatchType, methodTableSymbol, writer.Position, parameterDefinitionSymbol, 0);
                writer.WriteZeroBytes(TypeLayout.NativePointerSize);
            }

            return(methodTableSymbol);
        }
예제 #31
0
        private LinkerSymbol CreatePropertyDefinitions(MosaType type)
        {
            // Emit properties table
            var propertiesTableSymbol = Linker.DefineSymbol(Metadata.PropertiesTable + type.FullName, SectionKind.ROData, TypeLayout.NativePointerAlignment, 0);
            var writer = new EndianAwareBinaryWriter(propertiesTableSymbol.Stream, Architecture.Endianness);

            // 1. Number of Properties
            writer.Write((uint)type.Properties.Count, TypeLayout.NativePointerSize);

            // 2. Pointers to Property Definitions
            foreach (var property in type.Properties)
            {
                // Emit field name
                var fieldNameSymbol = EmitStringWithLength(Metadata.NameString + property.FullName, property.Name);

                // Emit property definition
                var propertyDefSymbol = Linker.DefineSymbol(Metadata.PropertyDefinition + property.FullName, SectionKind.ROData, TypeLayout.NativePointerAlignment, 0);
                var writer2           = new EndianAwareBinaryWriter(propertyDefSymbol.Stream, Architecture.Endianness);

                // 1. Name
                Linker.Link(LinkType.AbsoluteAddress, NativePatchType, propertyDefSymbol, writer2.Position, fieldNameSymbol, 0);
                writer2.WriteZeroBytes(TypeLayout.NativePointerSize);

                // 2. Pointer to Custom Attributes
                if (property.CustomAttributes.Count > 0)
                {
                    var customAttributesTableSymbol = CreateCustomAttributesTable(property);
                    Linker.Link(LinkType.AbsoluteAddress, NativePatchType, propertyDefSymbol, writer.Position, customAttributesTableSymbol, 0);
                }
                writer.WriteZeroBytes(TypeLayout.NativePointerSize);

                // 3. Attributes
                writer.Write((uint)property.PropertyAttributes, TypeLayout.NativePointerSize);

                // 4. Pointer to Property Type
                Linker.Link(LinkType.AbsoluteAddress, NativePatchType, propertyDefSymbol, writer2.Position, Metadata.TypeDefinition + property.PropertyType.FullName, 0);
                writer2.WriteZeroBytes(TypeLayout.NativePointerSize);

                // If the type is a interface then skip linking the methods
                if (!type.IsInterface)
                {
                    // TODO: Replace .HasImpelement with .HasCode

                    // 5. Pointer to Getter Method Definition
                    if (property.GetterMethod != null && property.GetterMethod.HasImplementation && !property.GetterMethod.HasOpenGenericParams)
                    {
                        Linker.Link(LinkType.AbsoluteAddress, NativePatchType, propertyDefSymbol, writer2.Position, Metadata.MethodDefinition + property.GetterMethod.FullName, 0);
                    }
                    writer2.WriteZeroBytes(TypeLayout.NativePointerSize);

                    // 6. Pointer to Setter Method Definition
                    if (property.SetterMethod != null && property.SetterMethod.HasImplementation && !property.SetterMethod.HasOpenGenericParams)
                    {
                        Linker.Link(LinkType.AbsoluteAddress, NativePatchType, propertyDefSymbol, writer2.Position, Metadata.MethodDefinition + property.SetterMethod.FullName, 0);
                    }
                    writer2.WriteZeroBytes(TypeLayout.NativePointerSize);
                }
                else
                {
                    // Fill 5 and 6 with zeros.
                    writer.WriteZeroBytes(TypeLayout.NativePointerSize * 2);
                }

                // Add pointer to properties table
                Linker.Link(LinkType.AbsoluteAddress, NativePatchType, propertiesTableSymbol, writer.Position, propertyDefSymbol, 0);
                writer.WriteZeroBytes(TypeLayout.NativePointerSize);
            }

            return(propertiesTableSymbol);
        }
예제 #32
0
        private LinkerSymbol CreateFieldDefinitions(MosaType type)
        {
            // Emit fields table
            var fieldsTableSymbol = Linker.DefineSymbol(Metadata.FieldsTable + type.FullName, SectionKind.ROData, TypeLayout.NativePointerAlignment, 0);
            var writer1           = new EndianAwareBinaryWriter(fieldsTableSymbol.Stream, Architecture.Endianness);

            // 1. Number of Fields
            writer1.Write((uint)type.Fields.Count, TypeLayout.NativePointerSize);

            // 2. Pointers to Field Definitions
            foreach (var field in type.Fields)
            {
                // Emit field name
                var fieldNameSymbol = EmitStringWithLength(Metadata.NameString + field.FullName, field.Name);

                // Emit field definition
                var fieldDefSymbol = Linker.DefineSymbol(Metadata.FieldDefinition + field.FullName, SectionKind.ROData, TypeLayout.NativePointerAlignment, 0);
                var writer2        = new EndianAwareBinaryWriter(fieldDefSymbol.Stream, Architecture.Endianness);

                // 1. Name
                Linker.Link(LinkType.AbsoluteAddress, NativePatchType, fieldDefSymbol, writer2.Position, fieldNameSymbol, 0);
                writer2.WriteZeroBytes(TypeLayout.NativePointerSize);

                // 2. Pointer to Custom Attributes
                if (field.CustomAttributes.Count > 0)
                {
                    var customAttributesTableSymbol = CreateCustomAttributesTable(field);
                    Linker.Link(LinkType.AbsoluteAddress, NativePatchType, fieldDefSymbol, writer2.Position, customAttributesTableSymbol, 0);
                }
                writer2.WriteZeroBytes(TypeLayout.NativePointerSize);

                // 3. Attributes
                writer2.Write((uint)field.FieldAttributes, TypeLayout.NativePointerSize);

                // 4. Pointer to Field Type
                Linker.Link(LinkType.AbsoluteAddress, NativePatchType, fieldDefSymbol, writer2.Position, Metadata.TypeDefinition + field.FieldType.FullName, 0);
                writer2.WriteZeroBytes(TypeLayout.NativePointerSize);

                // 5 & 6. Offset / Address + Size
                if (field.IsStatic && !field.IsLiteral && !type.HasOpenGenericParams)
                {
                    if (Compiler.MethodScanner.IsFieldAccessed(field))
                    {
                        Linker.Link(LinkType.AbsoluteAddress, NativePatchType, fieldDefSymbol, writer2.Position, field.FullName, 0);
                    }
                    writer2.WriteZeroBytes(TypeLayout.NativePointerSize);
                    writer2.Write(field.Data?.Length ?? 0, TypeLayout.NativePointerSize);
                }
                else
                {
                    writer2.WriteZeroBytes(TypeLayout.NativePointerSize);
                    writer2.Write(TypeLayout.GetFieldOffset(field), TypeLayout.NativePointerSize);
                }

                // Add pointer to field list
                Linker.Link(LinkType.AbsoluteAddress, NativePatchType, fieldsTableSymbol, writer1.Position, fieldDefSymbol, 0);
                writer1.WriteZeroBytes(TypeLayout.NativePointerSize);
            }

            return(fieldsTableSymbol);
        }
예제 #33
0
 /// <summary>
 /// Writes the elf header
 /// </summary>
 /// <param name="writer">The writer.</param>
 protected void Write64(EndianAwareBinaryWriter writer)
 {
     writer.Seek(0, SeekOrigin.Begin);
     writer.Write(Ident);                    // ident
     writer.Write((ushort)Type);             // type
     writer.Write((ushort)Machine);          // machine
     writer.Write((uint)Version);            // version
     writer.Write(EntryAddress);             // entry
     writer.Write((ulong)ProgramHeaderOffset);      // phoff
     writer.Write((ulong)SectionHeaderOffset);      // shoff
     writer.Write(Flags);                    // flags
     writer.Write(ElfHeaderSize64);            // ehsize
     writer.Write(ProgramHeader.EntrySize64);   // phentsize
     writer.Write(ProgramHeaderNumber);      // phnum
     writer.Write(SectionHeaderEntry.EntrySize64);   // shentsize
     writer.Write((ushort)SectionHeaderNumber);      // shnum
     writer.Write((ushort)SectionHeaderStringIndex); // shstrndx
 }
예제 #34
0
        public static void PatchSyslinux_6_03(PartitionDevice partitionDevice, FatFileSystem fat)
        {
            // Locate ldlinux.sys file for patching
            string filename = "ldlinux.sys";
            string name = (Path.GetFileNameWithoutExtension(filename) + Path.GetExtension(filename).PadRight(4).Substring(0, 4)).ToUpper();

            var location = fat.FindEntry(new Mosa.FileSystem.FAT.Find.WithName(name), 0);

            if (!location.IsValid)
                throw new InvalidProgramException("Unable to find syslinux.sys");

            // Get the file size & number of sectors used
            uint fileSize = fat.GetFileSize(location.DirectorySector, location.DirectorySectorIndex);

            var sectors = new List<uint>();

            // Create list of the sectors of the file
            for (uint cluster = location.FirstCluster; (cluster != 0); cluster = fat.GetNextCluster(cluster))
            {
                uint sec = fat.GetSectorByCluster(cluster);
                for (uint i = 0; i < fat.SectorsPerCluster; i++)
                {
                    sectors.Add(sec + i);
                }
            }

            // Get the ldlinux.sys file stream
            var ldlinux = new FatFileStream(fat, location);

            var ldlinuxReader = new EndianAwareBinaryReader(ldlinux, Endianness.Little);

            // Search for 0x3EB202FE (magic)
            while ((ldlinuxReader.ReadUInt32() != Syslinux.LDLINUX_MAGIC) && (ldlinux.Position < ldlinux.Length)) ;

            if (ldlinux.Position >= ldlinux.Length || ldlinux.Position <= 0)
                throw new InvalidProgramException("Unable to find patch location for syslinux");

            uint patchArea = (uint)ldlinux.Position - 4;

            // Get Extended Patch Area offset
            ldlinux.Position = patchArea + Syslinux.PatchAreaOffset.EPAOffset;
            ushort epa = ldlinuxReader.ReadUInt16();

            ldlinux.Position = epa + Syslinux.ExtendedPatchAreaOffset.Sect1Ptr0;
            uint sect1Ptr0 = (uint)ldlinuxReader.ReadUInt16();

            ldlinux.Position = epa + Syslinux.ExtendedPatchAreaOffset.Sect1Ptr1;
            uint sect1Ptr1 = (uint)ldlinuxReader.ReadUInt16();

            ldlinux.Position = epa + Syslinux.ExtendedPatchAreaOffset.SecPtrOffset;
            uint ex = (uint)ldlinuxReader.ReadUInt16();

            ldlinux.Position = epa + Syslinux.ExtendedPatchAreaOffset.SecPtrCnt;
            uint nptrs = (uint)ldlinuxReader.ReadUInt16();

            ldlinux.Position = epa + Syslinux.ExtendedPatchAreaOffset.AdvPtrOffset;
            uint advptrs = (uint)ldlinuxReader.ReadUInt16();

            if (sectors.Count > nptrs)
                throw new InvalidProgramException("Insufficient space for patching syslinux");

            var ldlinuxWriter = new EndianAwareBinaryWriter(ldlinux, Endianness.Little);

            // Set up the totals
            ldlinux.Position = patchArea + Syslinux.PatchAreaOffset.DataSectors;
            ldlinuxWriter.Write((ushort)sectors.Count);

            ldlinux.Position = patchArea + Syslinux.PatchAreaOffset.DataSectors;
            ldlinuxWriter.Write((ushort)2);

            ldlinux.Position = patchArea + Syslinux.PatchAreaOffset.DataSectors;
            ldlinuxWriter.Write((uint)fileSize >> 2);

            // Generate Extents
            var extents = GenerateExtents(sectors);

            ldlinux.Position = ex;

            // Write out extents
            foreach (var extent in extents)
            {
                ldlinuxWriter.Write((ulong)extent.Start);
                ldlinuxWriter.Write((ushort)extent.Length);
            }

            // Write out ADV
            ldlinux.Position = advptrs;
            ldlinuxWriter.Write((ulong)sectors[sectors.Count - 2]);
            ldlinuxWriter.Write((ulong)sectors[sectors.Count - 1]);

            // Clear out checksum
            ldlinux.Position = patchArea + Syslinux.PatchAreaOffset.Checksum;
            ldlinuxWriter.Write((uint)0);

            // Write back the updated cluster
            ldlinuxWriter.Flush();

            // Re-Calculate checksum
            ldlinux.Position = 0;
            uint csum = Syslinux.LDLINUX_MAGIC;
            for (uint index = 0; index < (ldlinux.Length >> 2); index++)
            {
                csum = csum + ldlinuxReader.ReadUInt32();
            }

            // Set the checksum
            ldlinux.Position = patchArea + Syslinux.PatchAreaOffset.Checksum;
            ldlinuxWriter.Write(csum);

            // Write patched cluster back to disk
            ldlinuxWriter.Flush();

            // Read boot sector
            var fatBootSector = new BinaryFormat(partitionDevice.ReadBlock(0, 1));

            // Set the first sector location of the file
            fatBootSector.SetUInt(sect1Ptr0, fat.GetSectorByCluster(location.FirstCluster));
            fatBootSector.SetUInt(sect1Ptr1, 0);   // since only 32-bit offsets are support, the high portion of 64-bit value is zero

            // Write back patched boot sector
            partitionDevice.WriteBlock(0, 1, fatBootSector.Data);
        }
예제 #35
0
    /// <summary>
    /// 
    /// </summary>
    /// <param name="strFileName"></param>
    public static IEnumerator SendVideoViaRenderTexture(int intDeviceScreenWidth, int intDeviceScreenHeight)
    {
        if (blnSendingScreenShot == false)
        {
            blnSendingScreenShot = true;
            yield return new WaitForEndOfFrame();

            RenderTexture rtRenderTexture = new RenderTexture(intDeviceScreenWidth, intDeviceScreenHeight, 24);
            Camera.main.targetTexture = rtRenderTexture;
            Texture2D txtScreenShot = new Texture2D(intDeviceScreenWidth, intDeviceScreenHeight, TextureFormat.RGB24, false);
            Camera.main.Render();
            yield return 0;
            RenderTexture.active = rtRenderTexture;
            txtScreenShot.ReadPixels(new Rect(0, 0, intDeviceScreenWidth, intDeviceScreenHeight), 0, 0);
            Camera.main.targetTexture = null;
            RenderTexture.active = null;
            GameObject.Destroy(rtRenderTexture);

            yield return 0;
            byte[] bytTexture = TextureUtilities.TextureToBytes(txtScreenShot);
            Int32 intCompressedSize = bytTexture.Length;

            yield return 0;
            UnityEngine.Debug.Log("about to write data to stream");
            MemoryStream stream = new MemoryStream();
            using (EndianAwareBinaryWriter writer = new EndianAwareBinaryWriter(stream, false))
            {
                writer.Write(ViewerConstants.MESSAGE_IMAGE);
                writer.Write(intDeviceScreenWidth);
                writer.Write(intDeviceScreenHeight);
                writer.Write(intCompressedSize);
                writer.Write(bytTexture);
            }

            UnityEngine.Debug.Log("convert stream to byte array");

            byte[] bytTxData = stream.ToArray();

            //send the texture to the clients
            ClientControl.Instance.SendTx(bytTxData);

            blnSendingScreenShot = false;
        }
    }
예제 #36
0
        private void EmitProtectedBlockTable()
        {
            List<ProtectedBlock> entries = new List<ProtectedBlock>();

            foreach (var clause in MethodCompiler.Method.ExceptionBlocks)
            {
                ProtectedBlock prev = new ProtectedBlock();

                foreach (BasicBlock block in exceptionBlocks[clause])
                {
                    uint start = (uint)codeEmitter.GetPosition(block.Label);
                    uint end = (uint)codeEmitter.GetPosition(block.Label + 0x0F000000);

                    ExceptionHandlerType kind = clause.HandlerType;

                    uint handler = 0;
                    uint filter = 0;
                    MosaType type = clause.Type;

                    handler = (uint)codeEmitter.GetPosition(clause.HandlerOffset);

                    if (kind == ExceptionHandlerType.Filter)
                    {
                        filter = (uint)codeEmitter.GetPosition(clause.FilterOffset.Value);
                    }

                    // TODO: Optimization - Search for existing exception protected region (before or after) to merge the current block

                    // Simple optimization assuming blocks are somewhat sorted by position
                    if (prev.End == start && prev.Kind == kind && prev.Handler == handler && prev.Filter == filter && prev.Type == type)
                    {
                        // merge protected blocks sequence
                        prev.End = end;
                    }
                    else if (prev.Start == end && prev.Kind == kind && prev.Handler == handler && prev.Filter == filter && prev.Type == type)
                    {
                        // merge protected blocks sequence
                        prev.Start = start;
                    }
                    else
                    {
                        // new protection block sequence
                        ProtectedBlock entry = new ProtectedBlock(start, end, handler, kind, type, filter);
                        entries.Add(entry);
                        prev = entry;
                    }
                }
            }

            int tableSize = (entries.Count * NativePointerSize * 5) + NativePointerSize;

            string section = MethodCompiler.Method.FullName + @"$etable";

            using (Stream stream = MethodCompiler.Linker.Allocate(section, SectionKind.ROData, tableSize, NativePointerAlignment))
            {
                using (EndianAwareBinaryWriter writer = new EndianAwareBinaryWriter(stream, Architecture.Endianness))
                {
                    foreach (ProtectedBlock entry in entries)
                    {
                        // FIXME: Assumes x86 platform
                        writer.Write((uint)entry.Kind);
                        writer.Write(entry.Start);
                        writer.Write(entry.Length);
                        writer.Write(entry.Handler);

                        if (entry.Kind == ExceptionHandlerType.Exception)
                        {
                            // Store method table pointer of the exception object type
                            // The VES exception runtime will uses this to compare exception object types
                            MethodCompiler.Linker.Link(LinkType.AbsoluteAddress | LinkType.I4, BuiltInPatch.I4, section, (int)writer.Position, 0, entry.Type.FullName + "$mtable", 0);

                            writer.Position += NativePointerSize;
                        }
                        else if (entry.Kind == ExceptionHandlerType.Filter)
                        {
                            // TODO: There are no plans in the short term to support filtered exception clause as C# does not use them
                            writer.Position += NativePointerSize;
                        }
                        else
                        {
                            writer.Position += NativePointerSize;
                        }
                    }

                    // Mark end of table
                    writer.Position += TypeLayout.NativePointerSize;
                }
            }
        }
예제 #37
0
        private void CreateAssemblyListTable()
        {
            string assemblyListSymbol = @"<$>AssemblyList";

            using (Stream stream = linker.Allocate(assemblyListSymbol, SectionKind.ROData, 0, typeLayout.NativePointerAlignment))
            {
                using (EndianAwareBinaryWriter writer = new EndianAwareBinaryWriter(stream, architecture.IsLittleEndian))
                {
                    // 1. Number of assemblies (modules)
                    writer.Write((uint)typeSystem.TypeModules.Count);

                    // 2. Pointers to assemblies
                    foreach (var module in typeSystem.TypeModules)
                    {
                        linker.Link(LinkType.AbsoluteAddress | LinkType.NativeI4, assemblyListSymbol, (int)writer.Position, 0, module.Name + "$atable", IntPtr.Zero);
                        writer.Position += typeLayout.NativePointerSize;
                    }
                }
            }

            // Create a table per assembly
            foreach (var module in typeSystem.TypeModules)
            {
                CreateAssemblyDefinitionTable(module);
            }
        }
예제 #38
0
        private void CreateTypeDefinitionTable(RuntimeType type, string assemblySymbol)
        {
            string typeNameSymbol = type + @"$tname";

            // Emit type name
            using (Stream stream = linker.Allocate(typeNameSymbol, SectionKind.ROData, 0, typeLayout.NativePointerAlignment))
            {
                using (EndianAwareBinaryWriter writer = new EndianAwareBinaryWriter(stream, architecture.IsLittleEndian))
                {
                    EmitStringWithLength(writer, type.FullName);
                }
            }

            string typeTableSymbol = type.FullName + @"$dtable";

            using (Stream stream = linker.Allocate(typeTableSymbol, SectionKind.ROData, 0, typeLayout.NativePointerAlignment))
            {
                using (EndianAwareBinaryWriter writer = new EndianAwareBinaryWriter(stream, architecture.IsLittleEndian))
                {
                    // 1. Size
                    writer.Write((uint)typeLayout.GetTypeSize(type));

                    // 2. Metadata Token
                    writer.Write((uint)type.Token.ToUInt32());

                    // 3. Pointer to Name
                    linker.Link(LinkType.AbsoluteAddress | LinkType.NativeI4, typeTableSymbol, (int)writer.Position, 0, typeNameSymbol, IntPtr.Zero);
                    writer.Position += typeLayout.NativePointerSize;

                    // 4. Pointer to Assembly Definition
                    linker.Link(LinkType.AbsoluteAddress | LinkType.NativeI4, typeTableSymbol, (int)writer.Position, 0, assemblySymbol, IntPtr.Zero);
                    writer.Position += typeLayout.NativePointerSize;

                    // 5. TODO: Constructor that accept no parameters, if any, for this type
                    writer.WriteZeroBytes(typeLayout.NativePointerSize);

                    // 6. Flag: IsInterface
                    writer.WriteByte((byte)(type.IsInterface ? 1 : 0));
                }
            }
        }
예제 #39
0
 private void EmitStringWithLength(EndianAwareBinaryWriter stream, string value)
 {
     stream.Write(value.Length);
     stream.Write(System.Text.ASCIIEncoding.ASCII.GetBytes(value));
 }
예제 #40
0
    /// <summary>
    /// 
    /// </summary>
    /// <returns></returns>
    public static IEnumerator SendVideoStream(int intDeviceScreenWidth, int intDeviceScreenHeight)
    {
        byte[] bytTexture;

        //UnityEngine.Debug.Log("Entered SendVideoStream");
        //make sure we dont start a new image tx until the last one is complete
        //also make sure that we are already connected to the device
        if (blnSendingScreenShot == false && ClientControl.Instance.IsConnected() == true)
        {
            UnityEngine.Debug.Log("sending new screen shot");
            blnSendingScreenShot = true;
            // wait for graphics to render
            yield return new WaitForEndOfFrame();

            // create a texture to pass to encoding
            Texture2D txtScreenCapture = TextureUtilities.CaptureScreenShot();

            //if the device screen size is different than this one, then resize it
            if (txtScreenCapture.width != intDeviceScreenWidth || txtScreenCapture.height != intDeviceScreenHeight)
            {
                yield return 0;
                // scale the texture down
                TextureUtilities.TextureScale.Point(txtScreenCapture, intDeviceScreenWidth, intDeviceScreenHeight);
            }
            yield return 0;

            //txtScreenCapture.format = TextureFormat.ATC_RGBA8;

            bytTexture = TextureUtilities.TextureToBytes(txtScreenCapture);
            Int32 intCompressedSize = bytTexture.Length;

            UnityEngine.Debug.Log("about to write data to stream");
            MemoryStream stream = new MemoryStream();
            using (EndianAwareBinaryWriter writer = new EndianAwareBinaryWriter(stream, false))
            {
                writer.Write(ViewerConstants.MESSAGE_IMAGE);
                writer.Write(intDeviceScreenWidth);
                writer.Write(intDeviceScreenHeight);
                writer.Write(intCompressedSize);
                writer.Write(bytTexture);
            }

            UnityEngine.Debug.Log("convert stream to byte array");

            byte[] bytTxData = stream.ToArray();

            //send the texture to the clients
            ClientControl.Instance.SendTx(bytTxData);
            yield return 0;

            //System.Threading.Thread.Sleep(5000);

            // Tell unity to delete the texture, by default it seems to keep hold of it and memory crashes will occur after too many screenshots.
            //DestroyObject(txtScreenCapture);
            blnSendingScreenShot = false;
        }
        //UnityEngine.Debug.Log("Leaving SendVideoStream");
    }
예제 #41
0
 /// <summary>
 /// Writes the header to the given binary writer.
 /// </summary>
 /// <param name="writer">The binary writer to write to.</param>
 public void WriteTo(EndianAwareBinaryWriter writer)
 {
     writer.Write(Cb);
     writer.Write(MajorRuntimeVersion);
     writer.Write(MinorRuntimeVersion);
     Metadata.Write(writer);
     writer.Write((uint)Flags);
     writer.Write(EntryPointToken);
     Resources.Write(writer);
     StrongNameSignature.Write(writer);
     CodeManagerTable.Write(writer);
     VTableFixups.Write(writer);
     ExportAddressTableJumps.Write(writer);
     ManagedNativeHeader.Write(writer);
 }
예제 #42
0
        private void CreateTypeDefinitionTable(MosaType type)
        {
            string typeNameSymbol = type + @"$tname";

            // Emit type name
            using (Stream stream = Linker.Allocate(typeNameSymbol, SectionKind.ROData, 0, TypeLayout.NativePointerAlignment))
            {
                using (EndianAwareBinaryWriter writer = new EndianAwareBinaryWriter(stream, Architecture.Endianness))
                {
                    EmitStringWithLength(writer, type.FullName);
                }
            }

            string typeTableSymbol = type.FullName + @"$dtable";

            using (Stream stream = Linker.Allocate(typeTableSymbol, SectionKind.ROData, 0, TypeLayout.NativePointerAlignment))
            {
                using (EndianAwareBinaryWriter writer = new EndianAwareBinaryWriter(stream, Architecture.Endianness))
                {
                    // 1. Size
                    writer.Write((uint)TypeLayout.GetTypeSize(type));

                    // 2. Metadata Token
                    //writer.Write((uint)type.Token.ToUInt32());
                    writer.Write((uint)0); //FIXME! ^^^

                    // 3. Pointer to Name
                    Linker.Link(LinkType.AbsoluteAddress | LinkType.I4, BuiltInPatch.I4, typeTableSymbol, (int)writer.Position, 0, typeNameSymbol, 0);
                    writer.Position += TypeLayout.NativePointerSize;

                    // 4. Pointer to Assembly Definition
                    //linker.Link(LinkType.AbsoluteAddress | LinkType.I4, BuiltInPatch.I4, typeTableSymbol, (int)writer.Position, 0, assemblySymbol, 0);
                    writer.Position += TypeLayout.NativePointerSize;

                    // 5. TODO: Constructor that accepts no parameters, if any, for this type
                    writer.WriteZeroBytes(TypeLayout.NativePointerSize);

                    // 6. Flag: IsInterface
                    writer.WriteByte((byte)(type.IsInterface ? 1 : 0));
                }
            }

            CreateFieldDefinitions(type);
        }
예제 #43
0
        public static void PatchSyslinux_6_03(PartitionDeviceDriver partitionDevice, FatFileSystem fat)
        {
            // Locate ldlinux.sys file for patching
            string filename = "ldlinux.sys";
            string name     = (Path.GetFileNameWithoutExtension(filename) + Path.GetExtension(filename).PadRight(4).Substring(0, 4)).ToUpper();

            var location = fat.FindEntry(name);

            if (!location.IsValid)
            {
                throw new InvalidProgramException("Unable to find syslinux.sys");
            }

            // Get the file size & number of sectors used
            uint fileSize = fat.GetFileSize(location.DirectorySector, location.DirectorySectorIndex);

            var sectors = new List <uint>();

            // Create list of the sectors of the file
            for (uint cluster = location.FirstCluster; (cluster != 0); cluster = fat.GetNextCluster(cluster))
            {
                uint sec = fat.GetSectorByCluster(cluster);
                for (uint i = 0; i < fat.SectorsPerCluster; i++)
                {
                    sectors.Add(sec + i);
                }
            }

            // Get the ldlinux.sys file stream
            var ldlinux = new FatFileStream(fat, location);

            var ldlinuxReader = new EndianAwareBinaryReader(ldlinux, Endianness.Little);

            // Search for 0x3EB202FE (magic)
            while ((ldlinuxReader.ReadUInt32() != Syslinux.LDLINUX_MAGIC) && (ldlinux.Position < ldlinux.Length))
            {
                ;
            }

            if (ldlinux.Position >= ldlinux.Length || ldlinux.Position <= 0)
            {
                throw new InvalidProgramException("Unable to find patch location for syslinux");
            }

            uint patchArea = (uint)ldlinux.Position - 4;

            // Get Extended Patch Area offset
            ldlinux.Position = patchArea + Syslinux.PatchAreaOffset.EPAOffset;
            ushort epa = ldlinuxReader.ReadUInt16();

            ldlinux.Position = epa + Syslinux.ExtendedPatchAreaOffset.Sect1Ptr0;
            uint sect1Ptr0 = ldlinuxReader.ReadUInt16();

            ldlinux.Position = epa + Syslinux.ExtendedPatchAreaOffset.Sect1Ptr1;
            uint sect1Ptr1 = ldlinuxReader.ReadUInt16();

            ldlinux.Position = epa + Syslinux.ExtendedPatchAreaOffset.SecPtrOffset;
            uint ex = ldlinuxReader.ReadUInt16();

            ldlinux.Position = epa + Syslinux.ExtendedPatchAreaOffset.SecPtrCnt;
            uint nptrs = ldlinuxReader.ReadUInt16();

            ldlinux.Position = epa + Syslinux.ExtendedPatchAreaOffset.AdvPtrOffset;
            uint advptrs = ldlinuxReader.ReadUInt16();

            if (sectors.Count > nptrs)
            {
                throw new InvalidProgramException("Insufficient space for patching syslinux");
            }

            var ldlinuxWriter = new EndianAwareBinaryWriter(ldlinux, Endianness.Little);

            // Set up the totals
            ldlinux.Position = patchArea + Syslinux.PatchAreaOffset.DataSectors;
            ldlinuxWriter.Write((ushort)sectors.Count);

            ldlinux.Position = patchArea + Syslinux.PatchAreaOffset.DataSectors;
            ldlinuxWriter.Write((ushort)2);

            ldlinux.Position = patchArea + Syslinux.PatchAreaOffset.DataSectors;
            ldlinuxWriter.Write(fileSize >> 2);

            // Generate Extents
            var extents = GenerateExtents(sectors);

            ldlinux.Position = ex;

            // Write out extents
            foreach (var extent in extents)
            {
                ldlinuxWriter.Write(extent.Start);
                ldlinuxWriter.Write(extent.Length);
            }

            // Write out ADV
            ldlinux.Position = advptrs;
            ldlinuxWriter.Write((ulong)sectors[sectors.Count - 2]);
            ldlinuxWriter.Write((ulong)sectors[sectors.Count - 1]);

            // Clear out checksum
            ldlinux.Position = patchArea + Syslinux.PatchAreaOffset.Checksum;
            ldlinuxWriter.Write((uint)0);

            // Write back the updated cluster
            ldlinuxWriter.Flush();

            // Re-Calculate checksum
            ldlinux.Position = 0;
            uint csum = Syslinux.LDLINUX_MAGIC;

            for (uint index = 0; index < (ldlinux.Length >> 2); index++)
            {
                csum = csum + ldlinuxReader.ReadUInt32();
            }

            // Set the checksum
            ldlinux.Position = patchArea + Syslinux.PatchAreaOffset.Checksum;
            ldlinuxWriter.Write(csum);

            // Write patched cluster back to disk
            ldlinuxWriter.Flush();

            // Read boot sector
            var fatBootSector = new DataBlock(partitionDevice.ReadBlock(0, 1));

            // Set the first sector location of the file
            fatBootSector.SetUInt(sect1Ptr0, fat.GetSectorByCluster(location.FirstCluster));
            fatBootSector.SetUInt(sect1Ptr1, 0);               // since only 32-bit offsets are support, the high portion of 64-bit value is zero

            // Write back patched boot sector
            partitionDevice.WriteBlock(0, 1, fatBootSector.Data);
        }
예제 #44
0
파일: Linker.cs 프로젝트: tea/MOSA-Project
        /// <summary>
        /// Writes the dos header of the PE file.
        /// </summary>
        /// <param name="writer">The writer.</param>
        private void WriteDosHeader(EndianAwareBinaryWriter writer)
        {
            /*
             * This code block generates the default DOS header of a PE image.
             * These constants are not further documented here, please consult
             * MSDN for their meaning.
             */
            this.dosHeader.e_magic = ImageDosHeader.DOS_HEADER_MAGIC;
            this.dosHeader.e_cblp = 0x0090;
            this.dosHeader.e_cp = 0x0003;
            this.dosHeader.e_cparhdr = 0x0004;
            this.dosHeader.e_maxalloc = 0xFFFF;
            this.dosHeader.e_sp = 0xb8;
            this.dosHeader.e_lfarlc = 0x0040;
            this.dosHeader.e_lfanew = 0x00000080;
            this.dosHeader.Write(writer);

            // Write the following 64 bytes, which represent the default x86 code to
            // print a message on the screen.
            byte[] message = new byte[] {
                0x0E, 0x1F, 0xBA, 0x0E, 0x00, 0xB4, 0x09, 0xCD, 0x21, 0xB8, 0x01, 0x4C, 0xCD, 0x21, 0x54, 0x68,
                0x69, 0x73, 0x20, 0x70, 0x72, 0x6F, 0x67, 0x72, 0x61, 0x6D, 0x20, 0x72, 0x65, 0x71, 0x75, 0x69,
                0x72, 0x65, 0x73, 0x20, 0x61, 0x20, 0x4D, 0x4F, 0x53, 0x41, 0x20, 0x70, 0x6F, 0x77, 0x65, 0x72,
                0x65, 0x64, 0x20, 0x4F, 0x53, 0x2E, 0x0D, 0x0D, 0x0A, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
            };
            writer.Write(message);
        }
예제 #45
0
        private void WriteArgument(EndianAwareBinaryWriter writer, LinkerSymbol symbol, MosaType type, object value)
        {
            if (type.IsEnum)
            {
                type = type.GetEnumUnderlyingType();
            }
            switch (type.TypeCode)
            {
            // 1 byte
            case MosaTypeCode.Boolean:
                writer.Write((bool)value);
                break;

            case MosaTypeCode.U1:
                writer.Write((byte)value);
                break;

            case MosaTypeCode.I1:
                writer.Write((sbyte)value);
                break;

            // 2 bytes
            case MosaTypeCode.Char:
                writer.Write((char)value);
                break;

            case MosaTypeCode.U2:
                writer.Write((ushort)value);
                break;

            case MosaTypeCode.I2:
                writer.Write((short)value);
                break;

            // 4 bytes
            case MosaTypeCode.U4:
                writer.Write((uint)value);
                break;

            case MosaTypeCode.I4:
                writer.Write((int)value);
                break;

            case MosaTypeCode.R4:
                writer.Write((float)value);
                break;

            // 8 bytes
            case MosaTypeCode.U8:
                writer.Write((ulong)value);
                break;

            case MosaTypeCode.I8:
                writer.Write((long)value);
                break;

            case MosaTypeCode.R8:
                writer.Write((double)value);
                break;

            // SZArray
            case MosaTypeCode.SZArray:
                Debug.Assert(value is MosaCustomAttribute.Argument[]);
                var arr = (MosaCustomAttribute.Argument[])value;
                writer.Write(arr.Length, TypeLayout.NativePointerSize);
                foreach (var elem in arr)
                {
                    WriteArgument(writer, symbol, elem.Type, elem.Value);
                }
                break;

            // String
            case MosaTypeCode.String:

                // Since strings are immutable, make it an object that we can just use
                var str = (string)value;
                Linker.Link(LinkType.AbsoluteAddress, NativePatchType, symbol, writer.Position, Metadata.TypeDefinition + "System.String", 0);
                writer.WriteZeroBytes(TypeLayout.NativePointerSize * 2);
                writer.Write(str.Length, TypeLayout.NativePointerSize);
                writer.Write(System.Text.Encoding.Unicode.GetBytes(str));
                break;

            default:
                if (type.FullName == "System.Type")
                {
                    var valueType = (MosaType)value;
                    Linker.Link(LinkType.AbsoluteAddress, NativePatchType, symbol, writer.Position, Metadata.TypeDefinition + valueType.FullName, 0);
                    writer.WriteZeroBytes(TypeLayout.NativePointerSize);
                }
                else
                {
                    throw new NotSupportedException();
                }

                break;
            }
        }
예제 #46
0
        private LinkerSymbol CreateTypeDefinition(MosaType type, LinkerSymbol assemblyTableSymbol)
        {
            // Emit type table
            var typeNameSymbol  = EmitStringWithLength(Metadata.NameString + type.FullName, type.FullName);
            var typeTableSymbol = Linker.DefineSymbol(Metadata.TypeDefinition + type.FullName, SectionKind.ROData, TypeLayout.NativePointerAlignment, 0);
            var writer          = new EndianAwareBinaryWriter(typeTableSymbol.Stream, Architecture.Endianness);

            // 1. Pointer to Name
            Linker.Link(LinkType.AbsoluteAddress, NativePatchType, typeTableSymbol, writer.Position, typeNameSymbol, 0);
            writer.WriteZeroBytes(TypeLayout.NativePointerSize);

            // 2. Pointer to Custom Attributes
            if (type.CustomAttributes.Count > 0)
            {
                var customAttributeListSymbol = CreateCustomAttributesTable(type);
                Linker.Link(LinkType.AbsoluteAddress, NativePatchType, typeTableSymbol, writer.Position, customAttributeListSymbol, 0);
            }
            writer.WriteZeroBytes(TypeLayout.NativePointerSize);

            // 3. Type Code & Attributes
            writer.Write(((uint)type.TypeCode << 24) + (uint)type.TypeAttributes, TypeLayout.NativePointerSize);

            // 4. Size
            writer.Write((uint)TypeLayout.GetTypeSize(type), TypeLayout.NativePointerSize);

            // 5. Pointer to Assembly Definition
            Linker.Link(LinkType.AbsoluteAddress, NativePatchType, typeTableSymbol, writer.Position, assemblyTableSymbol, 0);
            writer.WriteZeroBytes(TypeLayout.NativePointerSize);

            // 6. Pointer to Base Type
            if (type.BaseType != null)
            {
                Linker.Link(LinkType.AbsoluteAddress, NativePatchType, typeTableSymbol, writer.Position, Metadata.TypeDefinition + type.BaseType.FullName, 0);
            }
            writer.WriteZeroBytes(TypeLayout.NativePointerSize);

            // 7. Pointer to Declaring Type
            if (type.DeclaringType != null)
            {
                Linker.Link(LinkType.AbsoluteAddress, NativePatchType, typeTableSymbol, writer.Position, Metadata.TypeDefinition + type.DeclaringType.FullName, 0);
            }
            writer.WriteZeroBytes(TypeLayout.NativePointerSize);

            // 8. Pointer to Element Type
            if (type.ElementType != null)
            {
                Linker.Link(LinkType.AbsoluteAddress, NativePatchType, typeTableSymbol, writer.Position, Metadata.TypeDefinition + type.ElementType.FullName, 0);
            }
            writer.WriteZeroBytes(TypeLayout.NativePointerSize);

            // 9. Constructor that accepts no parameters, if any, for this type
            foreach (var method in type.Methods)
            {
                if (!method.IsConstructor || method.Signature.Parameters.Count != 0 || method.HasOpenGenericParams)
                {
                    continue;
                }

                var targetMethodData = GetTargetMethodData(method);

                if (targetMethodData.HasCode)
                {
                    Linker.Link(LinkType.AbsoluteAddress, NativePatchType, typeTableSymbol, writer.Position, Metadata.MethodDefinition + targetMethodData.Method.FullName, 0);
                }

                break;
            }
            writer.WriteZeroBytes(TypeLayout.NativePointerSize);

            // 10. Properties (if any)
            if (type.Properties.Count > 0)
            {
                var propertiesSymbol = CreatePropertyDefinitions(type);
                Linker.Link(LinkType.AbsoluteAddress, NativePatchType, typeTableSymbol, writer.Position, propertiesSymbol, 0);
            }
            writer.WriteZeroBytes(TypeLayout.NativePointerSize);

            // If the type is not an interface continue, otherwise just pad until the end
            if (!type.IsInterface)
            {
                // 11. Fields (if any)
                if (type.Fields.Count > 0)
                {
                    var fieldsSymbol = CreateFieldDefinitions(type);
                    Linker.Link(LinkType.AbsoluteAddress, NativePatchType, typeTableSymbol, writer.Position, fieldsSymbol, 0);
                }
                writer.WriteZeroBytes(TypeLayout.NativePointerSize);

                var interfaces = type.HasOpenGenericParams ? null : GetInterfaces(type);

                // If the type doesn't use interfaces then skip 9 and 10
                if (interfaces != null && interfaces.Count > 0)
                {
                    // 12. Pointer to Interface Slots
                    var interfaceSlotTableSymbol = CreateInterfaceSlotTable(type, interfaces);
                    Linker.Link(LinkType.AbsoluteAddress, NativePatchType, typeTableSymbol, writer.Position, interfaceSlotTableSymbol, 0);
                    writer.WriteZeroBytes(TypeLayout.NativePointerSize);

                    // 13. Pointer to Interface Bitmap
                    var interfaceBitmapSymbol = CreateInterfaceBitmap(type, interfaces);
                    Linker.Link(LinkType.AbsoluteAddress, NativePatchType, typeTableSymbol, writer.Position, interfaceBitmapSymbol, 0);
                    writer.WriteZeroBytes(TypeLayout.NativePointerSize);
                }
                else
                {
                    // Fill 12 and 13 with zeros
                    writer.WriteZeroBytes(TypeLayout.NativePointerSize * 2);
                }

                // For the next part we'll need to get the list of methods from the MosaTypeLayout
                var methodList = TypeLayout.GetMethodTable(type) ?? new List <MosaMethod>();

                // 14. Number of Methods
                writer.Write(methodList.Count, TypeLayout.NativePointerSize);

                // 15. Pointer to Methods
                foreach (var method in methodList)
                {
                    var targetMethodData = GetTargetMethodData(method);

                    if (targetMethodData.HasCode)
                    {
                        Linker.Link(LinkType.AbsoluteAddress, NativePatchType, typeTableSymbol, writer.Position, targetMethodData.Method.FullName, 0);
                    }
                    writer.WriteZeroBytes(TypeLayout.NativePointerSize);
                }

                // 16. Pointer to Method Definitions
                foreach (var method in methodList)
                {
                    // Create definition and get the symbol
                    var methodDefinitionSymbol = CreateMethodDefinition(method);

                    Linker.Link(LinkType.AbsoluteAddress, NativePatchType, typeTableSymbol, writer.Position, methodDefinitionSymbol, 0);
                    writer.WriteZeroBytes(TypeLayout.NativePointerSize);
                }
            }
            else
            {
                // Fill 11, 12, 13, 14 with zeros, 15 & 16 can be left out.
                writer.WriteZeroBytes(TypeLayout.NativePointerSize * 4);
            }

            return(typeTableSymbol);
        }
예제 #47
0
 /// <summary>
 /// Writes the header to the given binary writer.
 /// </summary>
 /// <param name="writer">The binary writer to write to.</param>
 public void Write(EndianAwareBinaryWriter writer)
 {
     writer.Write(e_magic);
     writer.Write(e_cblp);
     writer.Write(e_cp);
     writer.Write(e_crlc);
     writer.Write(e_cparhdr);
     writer.Write(e_minalloc);
     writer.Write(e_maxalloc);
     writer.Write(e_ss);
     writer.Write(e_sp);
     writer.Write(e_csum);
     writer.Write(e_ip);
     writer.Write(e_cs);
     writer.Write(e_lfarlc);
     writer.Write(e_ovno);
     writer.Write(e_res00);
     writer.Write(e_res01);
     writer.Write(e_res02);
     writer.Write(e_res03);
     writer.Write(e_oemid);
     writer.Write(e_oeminfo);
     writer.Write(e_res20);
     writer.Write(e_res21);
     writer.Write(e_res22);
     writer.Write(e_res23);
     writer.Write(e_res24);
     writer.Write(e_res25);
     writer.Write(e_res26);
     writer.Write(e_res27);
     writer.Write(e_res28);
     writer.Write(e_res29);
     writer.Write(e_lfanew);
 }
예제 #48
0
파일: Header.cs 프로젝트: tea/MOSA-Project
 /// <summary>
 /// Writes the specified fs.
 /// </summary>
 /// <param name="writer">The writer.</param>
 public void Write(EndianAwareBinaryWriter writer)
 {
     writer.Seek(0, SeekOrigin.Begin);
     writer.Write(Ident);
     writer.Write((ushort)Type);
     writer.Write((ushort)Machine);
     writer.Write((uint)Version);
     writer.Write(EntryAddress);
     writer.Write(ProgramHeaderOffset);
     writer.Write(SectionHeaderOffset);
     writer.Write(Flags);
     writer.Write(ElfHeaderSize);
     writer.Write(ProgramHeaderEntrySize);
     writer.Write(ProgramHeaderNumber);
     writer.Write(SectionHeaderEntrySize);
     writer.Write(SectionHeaderNumber);
     SectionHeaderStringIndex = 1;
     writer.Write(SectionHeaderStringIndex);
 }