Пример #1
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;
        }
Пример #2
0
 private void Serialize(EndianAwareBinaryWriter writer)
 {
     writer.WriteInt32(TypeId);
     Util.WriteLengthPrefixedString(writer, Name);
     writer.WriteByte((byte)PropertyType);
     SerializeValues(writer);
 }
Пример #3
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);
        }
Пример #4
0
        private void EmitFiles(EndianAwareBinaryWriter wr)
        {
            foreach (var file in FileList)             // order matters!
            {
                EmitDebugLineFileName(wr, file.DirectoryNum, file.Name);
            }

            wr.WriteByte(DwarfConstants.EndOfFiles);
        }
Пример #5
0
 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);
     }
 }
Пример #6
0
 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);
     }
 }
Пример #7
0
        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);
        }
Пример #8
0
        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);
        }
Пример #9
0
        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);
                }
            }
        }
Пример #10
0
        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;
                    }
                }
            }
        }
Пример #11
0
        private void EmitDebugLine(EndianAwareBinaryWriter wr)
        {
            var compilationUnitSizePosition = wr.Position;

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

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

            var headerSizePosition = wr.Position;

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

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

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

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

            wr.WriteByte(0x01);             // 9

            AddFilenames();

            EmitDirectories(wr);
            EmitFiles(wr);

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

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

            EmitDebugLineTypes(wr);

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

            wr.Position = compilationUnitSizePosition;
            wr.Write(compilationUnitSize);
            wr.Position = wr.BaseStream.Length;
        }