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; }
private void Serialize(EndianAwareBinaryWriter writer) { writer.WriteInt32(TypeId); Util.WriteLengthPrefixedString(writer, Name); writer.WriteByte((byte)PropertyType); SerializeValues(writer); }
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); }
private void EmitFiles(EndianAwareBinaryWriter wr) { foreach (var file in FileList) // order matters! { EmitDebugLineFileName(wr, file.DirectoryNum, file.Name); } wr.WriteByte(DwarfConstants.EndOfFiles); }
public void Serialize(EndianAwareBinaryWriter writer) { writer.WriteInt32(TypeId); Util.WriteLengthPrefixedString(writer, Name); writer.WriteByte((byte)(AdditionalData != null ? 1 : 0)); writer.WriteInt32(InstanceCount); Util.WriteReferentArray(writer, Referents); if (AdditionalData != null) { writer.WriteBytes(AdditionalData); } }
public static void WritePhysicalProperties(EndianAwareBinaryWriter writer, PhysicalProperties value) { writer.WriteByte((byte)(value.Enabled ? 1 : 0)); if (value.Enabled) { writer.WriteSingle(value.Density); writer.WriteSingle(value.Friction); writer.WriteSingle(value.Elasticity); writer.WriteSingle(value.FrictionWeight); writer.WriteSingle(value.ElasticityWeight); } }
public static void WriteCFrameArray(EndianAwareBinaryWriter writer, CFrame[] values) { // Write matrix values for (int i = 0; i < values.Length; i++) { var specialMatrixType = GetSpecialMatrixType(values[i]); if (specialMatrixType != 0) { writer.WriteByte(specialMatrixType); } else { writer.WriteByte(0); writer.WriteSingle(values[i].Matrix.M00); writer.WriteSingle(values[i].Matrix.M01); writer.WriteSingle(values[i].Matrix.M02); writer.WriteSingle(values[i].Matrix.M10); writer.WriteSingle(values[i].Matrix.M11); writer.WriteSingle(values[i].Matrix.M12); writer.WriteSingle(values[i].Matrix.M20); writer.WriteSingle(values[i].Matrix.M21); writer.WriteSingle(values[i].Matrix.M22); } } // Write position values // TODO This could be made more efficient by creating a streaming method for writing interleaved arrays var xValues = new float[values.Length]; var yValues = new float[values.Length]; var zValues = new float[values.Length]; for (var i = 0; i < values.Length; i++) { xValues[i] = values[i].Position.X; yValues[i] = values[i].Position.Y; zValues[i] = values[i].Position.Z; } WriteFloatArray(writer, xValues); WriteFloatArray(writer, yValues); WriteFloatArray(writer, zValues); }
public static void SerializeParentData(EndianAwareBinaryWriter writer, Tuple <int, int>[] parentData) { // This could be improved by creating an incremental version of WriteReferentArray var children = new int[parentData.Length]; var parents = new int[parentData.Length]; for (var i = 0; i < parentData.Length; i++) { children[i] = parentData[i].Item1; parents[i] = parentData[i].Item2; } writer.WriteByte(0); // Reserved writer.WriteInt32(parentData.Length); WriteReferentArray(writer, children); WriteReferentArray(writer, parents); }
private void EmitDebugAbbrev(EndianAwareBinaryWriter wr, DwarfAbbrev abbr) { wr.WriteULEB128(abbr.Number); wr.WriteULEB128((uint)abbr.Tag); wr.WriteByte(abbr.HasChildren ? DwarfConstants.DW_CHILDREN_yes : DwarfConstants.DW_CHILDREN_no); foreach (var attr in abbr.Attributes) { wr.WriteULEB128((uint)attr.Attribute); wr.WriteULEB128((uint)attr.Form); } wr.WriteULEB128(DwarfConstants.NullAttributeName); wr.WriteULEB128(DwarfConstants.NullAttributeValue); if (abbr.HasChildren) { foreach (var child in abbr.Children) { EmitDebugAbbrev(wr, child); } } }
private void EmitDebugLineTypes(EndianAwareBinaryWriter wr) { uint line = 1; uint file = 1; foreach (var type in TypeSystem.AllTypes) { if (type.IsModule) { continue; } foreach (var method in type.Methods) { if (!method.HasImplementation) { continue; } var symbol = Linker.GetSymbol(method.FullName); if (symbol == null) { continue; } if (symbol.VirtualAddress == 0) { continue; } var methodData = Compiler.CompilerData.GetMethodData(method); if (methodData == null) { continue; } uint methodVirtAddr = (uint)symbol.VirtualAddress; var locations = SourceRegions.GetSourceRegions(methodData); if (locations.Count == 0) { continue; } var pc = methodVirtAddr + (uint)locations[0].Address; wr.WriteByte(0); // signals an extended opcode wr.WriteULEB128(0x05); // number of bytes after this used by the extended opcode (unsigned LEB128 encoded) wr.Write((byte)DwarfExtendedOpcode.DW_LNE_set_address); wr.Write(pc); foreach (var loc in locations) { uint newPc = methodVirtAddr + (uint)loc.Address; uint pcDiff = newPc - pc; int lineDiff = loc.StartLine - (int)line; var newFile = FileHash[loc.Filename].FileNum; if (newFile != file) { file = newFile; wr.Write((byte)DwarfOpcodes.DW_LNS_set_file); wr.WriteULEB128(file); } wr.Write((byte)DwarfOpcodes.DW_LNS_advance_pc); wr.WriteSLEB128(pcDiff); wr.Write((byte)DwarfOpcodes.DW_LNS_advance_line); wr.WriteSLEB128(lineDiff); wr.Write((byte)DwarfOpcodes.DW_LNS_set_column); wr.WriteULEB128((uint)loc.StartColumn); wr.Write((byte)DwarfOpcodes.DW_LNS_copy); pc += pcDiff; line = (uint)loc.StartLine; } } } }
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; }