Esempio n. 1
0
 public static void WriteRectangleArray(EndianAwareBinaryWriter writer, Rectangle[] values)
 {
     WriteFloatArray(writer, values.Select(n => n.MinX).ToArray());
     WriteFloatArray(writer, values.Select(n => n.MinY).ToArray());
     WriteFloatArray(writer, values.Select(n => n.MaxX).ToArray());
     WriteFloatArray(writer, values.Select(n => n.MaxY).ToArray());
 }
Esempio n. 2
0
 public static void WritePropertyDataHelper <T>(EndianAwareBinaryWriter writer, T[] values, Action <EndianAwareBinaryWriter, T> writeProc)
 {
     foreach (var val in values)
     {
         writeProc(writer, val);
     }
 }
Esempio n. 3
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);
        }
Esempio n. 4
0
        public static void WriteLengthPrefixedString(EndianAwareBinaryWriter writer, string value)
        {
            var stringBytes = RobloxEncoding.GetBytes(value);

            writer.WriteInt32(stringBytes.Length);
            writer.WriteBytes(stringBytes);
        }
Esempio n. 5
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);
        }
Esempio n. 6
0
 private void Serialize(EndianAwareBinaryWriter writer)
 {
     writer.WriteInt32(TypeId);
     Util.WriteLengthPrefixedString(writer, Name);
     writer.WriteByte((byte)PropertyType);
     SerializeValues(writer);
 }
Esempio n. 7
0
        private void WriteSectionHeaderStringSection(Section section, EndianAwareBinaryWriter writer)
        {
            Debug.Assert(section == sectionHeaderStringSection);

            section.Size = (uint)sectionHeaderStringTable.Count;
            writer.Write(sectionHeaderStringTable.ToArray());
        }
Esempio n. 8
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);
        }
Esempio n. 9
0
 internal void Write(EndianAwareBinaryWriter writer)
 {
     writer.Write(this.majorVersion);
     writer.Write(this.MinorVersion);
     writer.Write(this.buildNumber);
     writer.Write(this.revision);
 }
Esempio n. 10
0
        private void WriteProgramHeaders(EndianAwareBinaryWriter writer)
        {
            writer.Position = elfheader.ProgramHeaderOffset;

            foreach (var section in Sections)
            {
                if (section.Size == 0 && section.SectionKind != SectionKind.BSS)
                {
                    continue;
                }

                var pheader = new ProgramHeader
                {
                    Alignment       = 0,
                    FileSize        = section.AlignedSize,
                    MemorySize      = section.AlignedSize,
                    Offset          = section.FileOffset,
                    VirtualAddress  = (uint)section.VirtualAddress,
                    PhysicalAddress = (uint)section.VirtualAddress,
                    Type            = ProgramHeaderType.Load,
                    Flags           =
                        (section.SectionKind == SectionKind.Text) ? ProgramHeaderFlags.Read | ProgramHeaderFlags.Execute :
                        (section.SectionKind == SectionKind.ROData) ? ProgramHeaderFlags.Read : ProgramHeaderFlags.Read | ProgramHeaderFlags.Write
                };

                pheader.Write(writer);
            }
        }
Esempio n. 11
0
 private void EmitDebugLineFileName(EndianAwareBinaryWriter wr, uint directoryIndex, string name)
 {
     wr.WriteNullTerminatedString(name);
     wr.WriteULEB128(directoryIndex);
     wr.WriteULEB128(DwarfConstants.NullFileTime);
     wr.WriteULEB128(DwarfConstants.NullFileLength);
 }
        protected override void PrimitiveCollectionSerializeOverride(StreamLimiter stream, int? itemLength, int? itemCount)
        {
            var typeNode = (ListTypeNode)TypeNode;
            var childSerializer = (ValueValueNode)typeNode.Child.CreateSerializer(this);

            var writer = new EndianAwareBinaryWriter(stream, Endianness);
            var childSerializedType = childSerializer.TypeNode.GetSerializedType();

            var list = BoundValue as IList;

            if (list == null)
                return;

            // Handle const-sized mismatched collections
            if (itemCount != null && list.Count != itemCount)
            {
                var tempList = list;
                list = (IList)CreateCollection(itemCount.Value);

                for (int i = 0; i < Math.Min(tempList.Count, list.Count); i++)
                    list[i] = tempList[i];
            }

            foreach (var value in list)
            {
                if (stream.IsAtLimit)
                    break;

                childSerializer.Serialize(writer, value, childSerializedType, itemLength);
            }
        }
Esempio n. 13
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);
 }
Esempio n. 14
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;
        }
Esempio n. 15
0
        private void WriteLinkerSection(Section section, EndianAwareBinaryWriter writer)
        {
            var linkerSection = linker.Sections[(int)section.SectionKind];

            writer.Position = section.Offset;
            linker.WriteTo(writer.BaseStream, linkerSection);
        }
Esempio n. 16
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);
        }
        protected override void PrimitiveCollectionSerializeOverride(StreamLimiter stream, int? itemLength, int? itemCount)
        {
            var typeNode = (ArrayTypeNode)TypeNode;
            var childSerializer = (ValueValueNode)typeNode.Child.CreateSerializer(this);

            var writer = new EndianAwareBinaryWriter(stream, Endianness);
            var childSerializedType = childSerializer.TypeNode.GetSerializedType();

            var array = BoundValue as Array;

            if (array == null)
                return;

            // Handle const-sized mismatched collections
            if (itemCount != null && array.Length != itemCount)
            {
                var tempArray = array;
                array = (Array)CreateCollection(itemCount.Value);
                Array.Copy(tempArray, array, Math.Min(tempArray.Length, array.Length));
            }

            for (int i = 0; i < array.Length; i++)
            {
                if (stream.IsAtLimit)
                    break;

                var value = array.GetValue(i);
                childSerializer.Serialize(writer, value, childSerializedType, itemLength);
            }
        }
Esempio n. 18
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();
                }
            }
Esempio n. 19
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);
        }
Esempio n. 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.VirtualAddress);
            writer.Write(this.Size);
        }
Esempio n. 21
0
        public byte[] Serialize()
        {
            var stream = new MemoryStream();
            var writer = new EndianAwareBinaryWriter(stream);

            Serialize(writer);

            return(stream.GetBuffer().Take((int)stream.Length).ToArray());
        }
Esempio n. 22
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);
        }
Esempio n. 23
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);
        }
Esempio n. 24
0
        private void EmitDirectories(EndianAwareBinaryWriter wr)
        {
            foreach (var entry in Directories.OrderBy(e => e.Value))             // order matters!
            {
                EmitDebugLineDirectoryName(wr, entry.Value, entry.Key);
            }

            wr.WriteByte(DwarfConstants.EndOfDirectories);
        }
Esempio n. 25
0
        private void EmitDebugAbbrev(EndianAwareBinaryWriter wr)
        {
            foreach (var abbr in AbbrevList)
            {
                EmitDebugAbbrev(wr, abbr);
            }

            wr.WriteULEB128(DwarfConstants.NullTag);
        }
Esempio n. 26
0
        private void EmitFiles(EndianAwareBinaryWriter wr)
        {
            foreach (var file in FileList)             // order matters!
            {
                EmitDebugLineFileName(wr, file.DirectoryNum, file.Name);
            }

            wr.WriteByte(DwarfConstants.EndOfFiles);
        }
Esempio n. 27
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);
        }
Esempio n. 28
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);
        }
Esempio n. 29
0
 public static void WriteNumberSequence(EndianAwareBinaryWriter writer, NumberSequence sequence)
 {
     writer.WriteInt32(sequence.Keypoints.Length);
     for (var i = 0; i < sequence.Keypoints.Length; i++)
     {
         writer.WriteSingle(sequence.Keypoints[i].Time);
         writer.WriteSingle(sequence.Keypoints[i].Value);
         writer.WriteSingle(sequence.Keypoints[i].Envelope);
     }
 }
Esempio n. 30
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);
 }
Esempio n. 31
0
 /// <summary>
 /// Writes the elf header
 /// </summary>
 /// <param name="elfType">Type of the elf.</param>
 /// <param name="writer">The writer.</param>
 public void Write(LinkerFormatType elfType, EndianAwareBinaryWriter writer)
 {
     if (elfType == LinkerFormatType.Elf32)
     {
         Write32(writer);
     }
     else             // if (elfType == ElfType.Elf64)
     {
         Write64(writer);
     }
 }
Esempio n. 32
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);
        }
Esempio n. 33
0
        public byte[] Serialize()
        {
            var stream = new MemoryStream();
            var writer = new EndianAwareBinaryWriter(stream);

            Serialize(writer);
            var buffer = new byte[stream.Length];

            Array.Copy(stream.GetBuffer(), buffer, stream.Length);
            return(buffer);
        }
Esempio n. 34
0
        public static byte[] SerializeParentData(Tuple <int, int>[] parentData)
        {
            var stream = new MemoryStream();
            var writer = new EndianAwareBinaryWriter(stream);

            SerializeParentData(writer, parentData);
            var buffer = new byte[stream.Length];

            Array.Copy(stream.GetBuffer(), buffer, stream.Length);
            return(buffer);
        }
Esempio n. 35
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);
                }
            }
        }
Esempio n. 36
0
        protected override void EmitImplementation(Stream stream)
        {
            var writer = new EndianAwareBinaryWriter(stream, Encoding.Unicode, Endianness);

            // Write the PE headers
            WriteDosHeader(writer);
            WritePEHeader(writer);

            foreach (var section in Sections)
            {
                stream.Position = (long)FILE_SECTION_ALIGNMENT;
                section.WriteTo(stream);
            }
        }
Esempio n. 37
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!
                    }
                }
            }
        }
Esempio n. 38
0
        /// <summary>
        /// Emits the implementation.
        /// </summary>
        /// <param name="stream">The stream.</param>
        protected override void EmitImplementation(Stream stream)
        {
            var writer = new EndianAwareBinaryWriter(stream, Encoding.Unicode, Endianness);

            // Write ELF header
            WriteElfHeader(writer);

            // Write program headers
            WriteProgramHeaders(writer);

            // Write section headers
            WriteSectionHeaders(writer);

            // Write sections
            foreach (var section in Sections)
            {
                stream.Position = section.FileOffset;
                section.WriteTo(stream);
            }

            WriteStringSection(writer);
        }
Esempio n. 39
0
 private void WriteStringHeaderSection(EndianAwareBinaryWriter writer)
 {
     stringSection.Name = AddToStringTable(".shstrtab");
     stringSection.Type = SectionType.StringTable;
     stringSection.Flags = (SectionAttribute)0;
     stringSection.Address = 0;
     stringSection.Offset = GetSection(SectionKind.BSS).FileOffset + GetSection(SectionKind.BSS).AlignedSize;
     stringSection.Size = (uint)stringTable.Count;
     stringSection.Link = 0;
     stringSection.Info = 0;
     stringSection.AddressAlignment = SectionAlignment;
     stringSection.EntrySize = 0;
     stringSection.Write(writer);
 }
Esempio n. 40
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);
 }
Esempio n. 41
0
        /// <summary>
        /// Creates the PE file.
        /// </summary>
        private void CreatePEFile()
        {
            // Open the output file
            using (FileStream fs = new FileStream(this.OutputFile, FileMode.Create, FileAccess.ReadWrite, FileShare.Read))
            {
                using (EndianAwareBinaryWriter writer = new EndianAwareBinaryWriter(fs, Encoding.Unicode, true))
                {
                    // Write the PE headers
                    WriteDosHeader(writer);
                    WritePEHeader(writer);

                    // Iterate all sections and store their data
                    long position = writer.BaseStream.Position;
                    foreach (Section section in this.sections.Values)
                    {
                        if (section.Length > 0)
                        {
                            // Write the section
                            section.Write(writer);

                            // Add padding...
                            position += section.Length;
                            position += (this.fileAlignment - (position % this.fileAlignment));
                            WritePaddingToPosition(writer, position);
                        }
                    }

                    // Do we need to set the checksum?
                    if (this.setChecksum)
                    {
                        // Flush all data to disk
                        writer.Flush();

                        // Write the checksum to the file
                        ntHeaders.OptionalHeader.CheckSum = CalculateChecksum(this.OutputFile);
                        fs.Position = this.dosHeader.e_lfanew;
                        ntHeaders.Write(writer);
                    }
                }
            }
        }
Esempio n. 42
0
 /// <summary>
 /// Writes the elf header
 /// </summary>
 /// <param name="elfType">Type of the elf.</param>
 /// <param name="writer">The writer.</param>
 public void Write(LinkerFormatType elfType, EndianAwareBinaryWriter writer)
 {
     if (elfType == LinkerFormatType.Elf32)
         Write32(writer);
     else // if (elfType == ElfType.Elf64)
         Write64(writer);
 }
Esempio n. 43
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
 }
Esempio n. 44
0
        /// <summary>
        /// Creates the elf32 file.
        /// </summary>
        private void CreateElf64File()
        {
            using (FileStream fs = new FileStream(this.OutputFile, FileMode.Create, FileAccess.Write, FileShare.None))
            {
                Header header = new Header();
                header.Type = FileType.Executable;
                header.Machine = Machine;
                header.SectionHeaderNumber = (ushort)(Sections.Count + 2);
                header.SectionHeaderOffset = header.ElfHeaderSize;

                header.CreateIdent(IdentClass.Class64, IdentData.Data2LSB, null);

                // Calculate the concatenated size of all section's data
                uint offset = 0;
                foreach (Section section in Sections)
                {
                    offset += (uint)section.Length;
                }
                offset += (uint)nullSection.Length;
                offset += (uint)stringTableSection.Length;

                // Calculate offsets
                header.ProgramHeaderOffset = (uint)header.ElfHeaderSize + (uint)header.SectionHeaderEntrySize * (uint)header.SectionHeaderNumber + offset;
                header.SectionHeaderStringIndex = (ushort)((ushort)header.ProgramHeaderOffset + (ushort)header.ProgramHeaderNumber * (ushort)header.ProgramHeaderEntrySize);

                EndianAwareBinaryWriter writer = new EndianAwareBinaryWriter(fs, IsLittleEndian);

                // Write the ELF Header
                header.Write(writer);

                // Overjump the Section Header Table and write the section's data first
                long tmp = fs.Position;
                writer.Seek((int)(tmp + header.SectionHeaderNumber * header.SectionHeaderEntrySize), SeekOrigin.Begin);

                nullSection.Write(writer);
                stringTableSection.Write(writer);

                // Write the sections
                foreach (Section section in Sections)
                    section.Write(writer);

                // Jump back to the Section Header Table
                writer.Seek((int)tmp, SeekOrigin.Begin);

                nullSection.WriteHeader(writer);
                stringTableSection.WriteHeader(writer);

                // Write the section headers
                foreach (Section section in Sections)
                    section.WriteHeader(writer);
            }
        }
Esempio n. 45
0
        private void WriteElfHeader(EndianAwareBinaryWriter writer)
        {
            ushort sectons = (ushort)(CountNonEmptySections() + 1);

            elfheader.Type = FileType.Executable;
            elfheader.Machine = (MachineType)MachineID;
            elfheader.EntryAddress = (uint)EntryPoint.VirtualAddress;
            elfheader.CreateIdent(IdentClass.Class32, Endianness == Endianness.Little ? IdentData.Data2LSB : IdentData.Data2MSB, null);
            elfheader.ProgramHeaderOffset = Header.ElfHeaderSize;
            elfheader.ProgramHeaderNumber = sectons;
            elfheader.SectionHeaderNumber = (ushort)(sectons + 2);
            elfheader.SectionHeaderOffset = (uint)(elfheader.ProgramHeaderOffset + (Header.ProgramHeaderEntrySize * elfheader.ProgramHeaderNumber));
            elfheader.SectionHeaderStringIndex = (ushort)(sectons + 1);
            elfheader.Write(writer);
        }
Esempio n. 46
0
 /// <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);
 }
Esempio n. 47
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);
        }
Esempio n. 48
0
        /// <summary>
        /// Writes the PE header.
        /// </summary>
        /// <param name="writer">The writer.</param>
        private void WritePEHeader(EndianAwareBinaryWriter writer)
        {
            // Write the PE signature and headers
            ntHeaders.Signature = ImageNtHeaders.PE_SIGNATURE;

            // Prepare the file header
            ntHeaders.FileHeader.Machine = ImageFileHeader.IMAGE_FILE_MACHINE_I386;
            ntHeaders.FileHeader.NumberOfSections = CountSections();
            ntHeaders.FileHeader.TimeDateStamp = (uint)(DateTime.Now - new DateTime(1970, 1, 1, 0, 0, 0)).TotalSeconds;
            ntHeaders.FileHeader.PointerToSymbolTable = 0;
            ntHeaders.FileHeader.NumberOfSymbols = 0;
            ntHeaders.FileHeader.SizeOfOptionalHeader = 0x00E0;
            ntHeaders.FileHeader.Characteristics = 0x010E; // FIXME: Use an enum here

            // Prepare the "optional" headers
            ntHeaders.OptionalHeader.Magic = ImageOptionalHeader.IMAGE_OPTIONAL_HEADER_MAGIC;
            ntHeaders.OptionalHeader.MajorLinkerVersion = 6;
            ntHeaders.OptionalHeader.MinorLinkerVersion = 0;
            ntHeaders.OptionalHeader.SizeOfCode = AlignValue(GetSectionLength(SectionKind.Text), this.sectionAlignment);
            ntHeaders.OptionalHeader.SizeOfInitializedData = AlignValue(GetSectionLength(SectionKind.Data) + GetSectionLength(SectionKind.ROData), this.sectionAlignment);
            ntHeaders.OptionalHeader.SizeOfUninitializedData = AlignValue(GetSectionLength(SectionKind.BSS), this.sectionAlignment);
            ntHeaders.OptionalHeader.AddressOfEntryPoint = (uint)(this.EntryPoint.VirtualAddress.ToInt64() - this.BaseAddress);
            ntHeaders.OptionalHeader.BaseOfCode = (uint)(GetSectionAddress(SectionKind.Text) - this.BaseAddress);

            long sectionAddress = GetSectionAddress(SectionKind.Data);
            if (sectionAddress != 0)
                ntHeaders.OptionalHeader.BaseOfData = (uint)(sectionAddress - this.BaseAddress);

            ntHeaders.OptionalHeader.ImageBase = (uint)this.BaseAddress; // FIXME: Linker Script/cmdline
            ntHeaders.OptionalHeader.SectionAlignment = this.sectionAlignment; // FIXME: Linker Script/cmdline
            ntHeaders.OptionalHeader.FileAlignment = this.fileAlignment; // FIXME: Linker Script/cmdline
            ntHeaders.OptionalHeader.MajorOperatingSystemVersion = 4;
            ntHeaders.OptionalHeader.MinorOperatingSystemVersion = 0;
            ntHeaders.OptionalHeader.MajorImageVersion = 0;
            ntHeaders.OptionalHeader.MinorImageVersion = 0;
            ntHeaders.OptionalHeader.MajorSubsystemVersion = 4;
            ntHeaders.OptionalHeader.MinorSubsystemVersion = 0;
            ntHeaders.OptionalHeader.Win32VersionValue = 0;
            ntHeaders.OptionalHeader.SizeOfImage = CalculateSizeOfImage();
            ntHeaders.OptionalHeader.SizeOfHeaders = this.fileAlignment; // FIXME: Use the full header size
            ntHeaders.OptionalHeader.CheckSum = 0;
            ntHeaders.OptionalHeader.Subsystem = 0x03;
            ntHeaders.OptionalHeader.DllCharacteristics = 0x0540;
            ntHeaders.OptionalHeader.SizeOfStackReserve = 0x100000;
            ntHeaders.OptionalHeader.SizeOfStackCommit = 0x1000;
            ntHeaders.OptionalHeader.SizeOfHeapReserve = 0x100000;
            ntHeaders.OptionalHeader.SizeOfHeapCommit = 0x1000;
            ntHeaders.OptionalHeader.LoaderFlags = 0;
            ntHeaders.OptionalHeader.NumberOfRvaAndSizes = ImageOptionalHeader.IMAGE_NUMBEROF_DIRECTORY_ENTRIES;
            ntHeaders.OptionalHeader.DataDirectory = new ImageDataDirectory[ImageOptionalHeader.IMAGE_NUMBEROF_DIRECTORY_ENTRIES];

            // Populate the CIL data directory
            ntHeaders.OptionalHeader.DataDirectory[14].VirtualAddress = 0;// (uint)GetSymbol(CLI_HEADER.SymbolName).VirtualAddress.ToInt64();
            ntHeaders.OptionalHeader.DataDirectory[14].Size = 0; // CLI_HEADER.Length;

            ntHeaders.Write(writer);

            // Write the section headers
            uint address = this.fileAlignment;
            foreach (LinkerSection section in this.sections.Values)
            {
                if (section.Length > 0)
                {
                    ImageSectionHeader ish = new ImageSectionHeader();
                    ish.Name = section.Name;
                    ish.VirtualSize = (uint)section.Length;
                    ish.VirtualAddress = (uint)(section.VirtualAddress.ToInt64() - this.BaseAddress);

                    if (section.SectionKind != SectionKind.BSS)
                        ish.SizeOfRawData = (uint)section.Length;

                    ish.PointerToRawData = address;
                    ish.PointerToRelocations = 0;
                    ish.PointerToLinenumbers = 0;
                    ish.NumberOfRelocations = 0;
                    ish.NumberOfLinenumbers = 0;

                    switch (section.SectionKind)
                    {
                        case SectionKind.BSS:
                            ish.Characteristics = 0x40000000 | 0x80000000 | 0x00000080;
                            break;

                        case SectionKind.Data:
                            ish.Characteristics = 0x40000000 | 0x80000000 | 0x00000040;
                            break;

                        case SectionKind.ROData:
                            ish.Characteristics = 0x40000000 | 0x00000040;
                            break;

                        case SectionKind.Text:
                            ish.Characteristics = 0x20000000 | 0x40000000 | 0x80000000 | 0x00000020;
                            break;
                    }

                    ish.Write(writer);

                    address += (uint)section.Length;
                    address = AlignValue(address, this.fileAlignment);
                }
            }

            WritePaddingToPosition(writer, this.fileAlignment);
        }
Esempio n. 49
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.
             */
            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);
        }
Esempio n. 50
0
        /// <summary>
        /// Creates the final linked file.
        /// </summary>
        protected override void CreateFile()
        {
            using (FileStream fs = new FileStream(OutputFile, FileMode.Create, FileAccess.Write, FileShare.None))
            {
                Header header = new Header();
                header.Type = FileType.Executable;
                header.Machine = (MachineType)MachineID;
                header.SectionHeaderNumber = (ushort)(Sections.Length + 2);
                header.SectionHeaderOffset = header.ElfHeaderSize;
                header.EntryAddress = (uint)EntryPoint.VirtualAddress;

                header.CreateIdent(IdentClass.Class32, Endianness == Endianness.Little ? IdentData.Data2LSB : IdentData.Data2MSB, null);

                // Calculate the concatenated size of all section's data
                uint offset = 0;
                ushort programHeaderNumber = 0;
                foreach (Elf32LinkerSection section in Sections)
                {
                    offset += (uint)section.Length;
                    if (section.SectionKind != SectionKind.BSS && section.Length > 0)
                        programHeaderNumber++;
                }
                offset += (uint)nullSection.Length;
                offset += (uint)stringTableSection.Length;

                // Calculate offsets
                header.ProgramHeaderOffset = header.ElfHeaderSize + header.SectionHeaderEntrySize * (uint)header.SectionHeaderNumber + offset;
                header.ProgramHeaderNumber = programHeaderNumber;
                header.SectionHeaderStringIndex = 1;

                EndianAwareBinaryWriter writer = new EndianAwareBinaryWriter(fs, Endianness);

                // Write the ELF Header
                header.Write(writer);

                // Overjump the Section Header Table and write the section's data first
                long tmp = fs.Position;
                writer.Seek((int)(tmp + header.SectionHeaderNumber * header.SectionHeaderEntrySize), SeekOrigin.Begin);

                nullSection.Write(writer);
                stringTableSection.Write(writer);

                // Write the _sections
                foreach (Elf32LinkerSection section in Sections)
                    section.Write(writer);

                // Jump back to the Section Header Table
                writer.Seek((int)tmp, SeekOrigin.Begin);

                nullSection.WriteHeader(writer);
                stringTableSection.WriteHeader(writer);

                // Write the section headers
                foreach (Elf32LinkerSection section in Sections)
                    section.WriteHeader(writer);

                writer.Seek((int)header.ProgramHeaderOffset, SeekOrigin.Begin);
                foreach (Elf32LinkerSection section in Sections)
                {
                    if (section.SectionKind == SectionKind.BSS || section.Length == 0)
                        continue;

                    ProgramHeader pheader = new ProgramHeader
                    {
                        Alignment = 0,
                        FileSize = (uint)section.Length,
                        MemorySize = (uint)section.Length,
                        Offset = section.Header.Offset,
                        VirtualAddress = (uint)section.VirtualAddress,
                        PhysicalAddress = (uint)section.VirtualAddress,
                        Type = ProgramHeaderType.Load,
                        Flags =
                            (section.SectionKind == SectionKind.Text) ? ProgramHeaderFlags.Read | ProgramHeaderFlags.Execute :
                            (section.SectionKind == SectionKind.ROData) ? ProgramHeaderFlags.Read :
                            ProgramHeaderFlags.Read | ProgramHeaderFlags.Write
                    };

                    pheader.Write(writer);
                }
            }
        }
Esempio n. 51
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");
    }
Esempio n. 52
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));
                }
            }
        }
Esempio n. 53
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;
                }
            }
        }
Esempio n. 54
0
        private void WriteProgramHeaders(EndianAwareBinaryWriter writer)
        {
            writer.Position = elfheader.ProgramHeaderOffset;

            foreach (var section in Sections)
            {
                if (section.Size == 0 && section.SectionKind != SectionKind.BSS)
                    continue;

                var pheader = new ProgramHeader
                {
                    Alignment = section.SectionAlignment,
                    FileSize = section.AlignedSize,
                    MemorySize = section.AlignedSize,
                    Offset = section.FileOffset,
                    VirtualAddress = (uint)section.VirtualAddress,
                    PhysicalAddress = (uint)section.VirtualAddress,
                    Type = ProgramHeaderType.Load,
                    Flags =
                        (section.SectionKind == SectionKind.Text) ? ProgramHeaderFlags.Read | ProgramHeaderFlags.Execute :
                        (section.SectionKind == SectionKind.ROData) ? ProgramHeaderFlags.Read : ProgramHeaderFlags.Read | ProgramHeaderFlags.Write
                };

                pheader.Write(writer);
            }
        }
Esempio n. 55
0
        private void WriteSectionHeaders(EndianAwareBinaryWriter writer)
        {
            writer.Position = elfheader.SectionHeaderOffset;

            WriteNullHeaderSection(writer);

            foreach (var section in Sections)
            {
                if (section.Size == 0 && section.SectionKind != SectionKind.BSS)
                    continue;

                var sheader = new SectionHeader();

                sheader.Name = AddToStringTable(section.Name);

                switch (section.SectionKind)
                {
                    case SectionKind.Text: sheader.Type = SectionType.ProgBits; sheader.Flags = SectionAttribute.AllocExecute; break;
                    case SectionKind.Data: sheader.Type = SectionType.ProgBits; sheader.Flags = SectionAttribute.Alloc | SectionAttribute.Write; break;
                    case SectionKind.ROData: sheader.Type = SectionType.ProgBits; sheader.Flags = SectionAttribute.Alloc; break;
                    case SectionKind.BSS: sheader.Type = SectionType.NoBits; sheader.Flags = SectionAttribute.Alloc | SectionAttribute.Write; break;
                }

                sheader.Address = (uint)section.VirtualAddress;
                sheader.Offset = section.FileOffset;
                sheader.Size = section.AlignedSize;
                sheader.Link = 0;
                sheader.Info = 0;
                sheader.AddressAlignment = section.SectionAlignment;
                sheader.EntrySize = 0;
                sheader.Write(writer);
            }

            WriteStringHeaderSection(writer);
        }
Esempio n. 56
0
 private void EmitStringWithLength(EndianAwareBinaryWriter stream, string value)
 {
     stream.Write(value.Length);
     stream.Write(System.Text.ASCIIEncoding.ASCII.GetBytes(value));
 }
Esempio n. 57
0
 private static void WriteNullHeaderSection(EndianAwareBinaryWriter writer)
 {
     var nullsection = new SectionHeader();
     nullsection.Name = 0;
     nullsection.Type = SectionType.Null;
     nullsection.Flags = 0;
     nullsection.Address = 0;
     nullsection.Offset = 0;
     nullsection.Size = 0;
     nullsection.Link = 0;
     nullsection.Info = 0;
     nullsection.AddressAlignment = 0;
     nullsection.EntrySize = 0;
     nullsection.Write(writer);
 }
Esempio n. 58
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;
        }
    }
Esempio n. 59
0
        /// <summary>
        /// Creates the elf32 file.
        /// </summary>
        /// <param name="compiler">The compiler.</param>
        private void CreateElf32File()
        {
            using (FileStream fs = new FileStream(OutputFile, FileMode.Create, FileAccess.Write, FileShare.None))
            {
                Header header = new Header();
                header.Type = FileType.Executable;
                header.Machine = Machine;
                header.SectionHeaderNumber = (ushort)(Sections.Count + 2);
                header.SectionHeaderOffset = header.ElfHeaderSize;

                header.CreateIdent(IdentClass.Class32, IsLittleEndian ? IdentData.Data2LSB : IdentData.Data2MSB, null);

                // Calculate the concatenated size of all section's data
                uint offset = 0;
                foreach (Section section in Sections)
                {
                    offset += (uint)section.Length;
                }
                offset += (uint)nullSection.Length;
                offset += (uint)stringTableSection.Length;

                // Calculate offsets
                header.ProgramHeaderOffset = header.ElfHeaderSize + header.SectionHeaderEntrySize * (uint)header.SectionHeaderNumber + offset;
                header.ProgramHeaderNumber = 1;
                header.SectionHeaderStringIndex = 1;

                EndianAwareBinaryWriter writer = new EndianAwareBinaryWriter(fs, IsLittleEndian);

                // Write the ELF Header
                header.Write(writer);

                // Overjump the Section Header Table and write the section's data first
                long tmp = fs.Position;
                writer.Seek((int)(tmp + header.SectionHeaderNumber * header.SectionHeaderEntrySize), SeekOrigin.Begin);

                nullSection.Write(writer);
                stringTableSection.Write(writer);

                // Write the _sections
                foreach (Section section in Sections)
                    section.Write(writer);

                // Jump back to the Section Header Table
                writer.Seek((int)tmp, SeekOrigin.Begin);

                nullSection.WriteHeader(writer);
                stringTableSection.WriteHeader(writer);

                // Write the section headers
                foreach (Section section in Sections)
                    section.WriteHeader(writer);

                ProgramHeader pheader = new ProgramHeader
                {
                    Alignment = 0,
                    FileSize = (uint)GetSection(SectionKind.Text).Length
                };

                pheader.MemorySize = pheader.FileSize;
                pheader.VirtualAddress = 0xFF0000;
                pheader.Flags = ProgramHeaderFlags.Execute | ProgramHeaderFlags.Read | ProgramHeaderFlags.Write;
                pheader.Offset = ((Section)GetSection(SectionKind.Text)).Header.Offset;
                pheader.Type = ProgramHeaderType.Load;

                writer.Seek((int)header.ProgramHeaderOffset, SeekOrigin.Begin);
                pheader.Write(writer);
            }
        }
Esempio n. 60
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);
            }
        }