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; } } } }