Exemplo n.º 1
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;
                    }
                }
            }
        }