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); }
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; }
protected void WriteSectionHeaderStringSection(Section section) { Debug.Assert(section == sectionHeaderStringSection); section.Size = (uint)sectionHeaderStringTable.Count; writer.Write(sectionHeaderStringTable.ToArray()); }
internal void Write(EndianAwareBinaryWriter writer) { writer.Write(this.majorVersion); writer.Write(this.MinorVersion); writer.Write(this.buildNumber); writer.Write(this.revision); }
/// <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); }
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); }
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); }
/// <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); }
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(); } }
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); }
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; }
/// <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); }
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); }
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); }
private void WriteSectionHeaderStringSection(Section section, EndianAwareBinaryWriter writer) { Debug.Assert(section == sectionHeaderStringSection); section.Size = (uint)sectionHeaderStringTable.Count; writer.Write(sectionHeaderStringTable.ToArray()); }
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); }
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); }
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! } } } }
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); } }
/// <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); }
/// <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); }
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); } } }
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); }
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); }
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); }
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); } }
/// <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); }
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); }
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); }
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); }
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); }
/// <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 }
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); }
/// <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; } }
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; } } }
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); } }
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)); } } }
private void EmitStringWithLength(EndianAwareBinaryWriter stream, string value) { stream.Write(value.Length); stream.Write(System.Text.ASCIIEncoding.ASCII.GetBytes(value)); }
/// <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"); }
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); }
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); }
/// <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); }
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; } }
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); }
/// <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); }
/// <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); }