XML debug symbols

This commit is contained in:
Joshua "Yoshi" Askharoun
2025-11-28 18:06:19 -06:00
parent 396d4f4015
commit 806d697e79
5 changed files with 79 additions and 23 deletions
-1
View File
@@ -62,7 +62,6 @@ internal class DecompileContext
DebugSymbols = new() DebugSymbols = new()
{ {
CompiledFileName = _loadResult.ErrorContextUri, CompiledFileName = _loadResult.ErrorContextUri,
ScriptSymbols = [],
}; };
_instructions = ObjectSection.Decode(_loadResult.ObjectSection) _instructions = ObjectSection.Decode(_loadResult.ObjectSection)
+2 -11
View File
@@ -622,10 +622,6 @@ partial class Decompiler
public string FormatSyntaxNode(SyntaxNode root, CancellationToken cancellationToken = default) public string FormatSyntaxNode(SyntaxNode root, CancellationToken cancellationToken = default)
{ {
uint? scriptOffset = null; uint? scriptOffset = null;
ScriptDebugSymbols debugSymbols = new()
{
SourceMap = []
};
root = root.NormalizeWhitespace(); root = root.NormalizeWhitespace();
@@ -636,7 +632,7 @@ partial class Decompiler
var location = node.GetLocation(); var location = node.GetLocation();
debugSymbols.SourceMap[offset] = new(location.SourceSpan.Start, location.SourceSpan.End); //debugSymbols.SourceMap[offset] = new(location.SourceSpan.Start, location.SourceSpan.End);
if (scriptOffset is null && node is CompilationUnitSyntax) if (scriptOffset is null && node is CompilationUnitSyntax)
scriptOffset = offset; scriptOffset = offset;
@@ -646,12 +642,7 @@ partial class Decompiler
.SyntaxTree .SyntaxTree
.GetText(cancellationToken); .GetText(cancellationToken);
debugSymbols.SourceCode = sourceText.ToString(); return sourceText.ToString();
if (scriptOffset is not null)
_context.DebugSymbols.ScriptSymbols[scriptOffset.Value] = debugSymbols;
return debugSymbols.SourceCode;
} }
private bool TryDecompileExpression(Instruction instruction, Stack<object> stack, ControlFlowAnalyzer cfa = null) private bool TryDecompileExpression(Instruction instruction, Stack<object> stack, ControlFlowAnalyzer cfa = null)
+54 -10
View File
@@ -143,7 +143,7 @@ public partial class Decompiler
return xDoc; return xDoc;
} }
public string DecompileToSource() public string DecompileToSource(bool generateDebugSymbols)
{ {
var xmlDoc = Decompile(); var xmlDoc = Decompile();
@@ -159,7 +159,47 @@ public partial class Decompiler
{ {
xmlDoc.WriteTo(writer); xmlDoc.WriteTo(writer);
} }
return sb.ToString();
var xmlStr = sb.ToString();
if (generateDebugSymbols)
PopulateDebugSymbolsWithXml(xmlDoc, xmlStr);
return xmlStr;
}
public void PopulateDebugSymbolsWithXml(XDocument xmlDoc, string xmlStr)
{
// Reparse the file to get line info
var xmlDocWithLineInfo = XDocument.Parse(xmlStr, LoadOptions.SetLineInfo);
var lineInfoNodes = xmlDocWithLineInfo.DescendantNodes();
var offsetInfoNodes = xmlDoc.DescendantNodes();
foreach (var (liNode, oiNode) in lineInfoNodes.Zip(offsetInfoNodes, (l, o) => (l, o)))
{
var offsetInfo = oiNode.Annotation<UIBOffsetXmlAnnotation>();
if (offsetInfo is null)
continue;
if (liNode is not IXmlLineInfo lineInfo || !lineInfo.HasLineInfo())
continue;
var offset = offsetInfo.Offset;
var start = new SourcePosition(lineInfo.LineNumber, lineInfo.LinePosition);
var elementStr = oiNode.ToString();
var endLine = start.Line + elementStr.Count(c => c == '\n');
var endColumn = elementStr.Length;
var idxLastLine = elementStr.LastIndexOf('\n');
if (idxLastLine > 0)
endColumn -= idxLastLine;
var end = new SourcePosition(endLine, endColumn);
var span = new SourceSpan(start, end);
DebugSymbols.SourceMap.Xml[offset] = span;
}
} }
public FileDebugSymbols DebugSymbols => _context.DebugSymbols; public FileDebugSymbols DebugSymbols => _context.DebugSymbols;
@@ -189,7 +229,7 @@ public partial class Decompiler
case OpCode.ConstructObject: case OpCode.ConstructObject:
var typeToCtor = _context.GetImportedType(instruction.Operands.ElementAt(0)); var typeToCtor = _context.GetImportedType(instruction.Operands.ElementAt(0));
var xObj = new XElement(_context.GetXName(typeToCtor)); var xObj = new XElement(_context.GetXName(typeToCtor)).WithOffset(instruction);
stack.Push(new IrisObject(xObj, typeToCtor)); stack.Push(new IrisObject(xObj, typeToCtor));
break; break;
@@ -213,7 +253,8 @@ public partial class Decompiler
var target = stack.Pop(); var target = stack.Pop();
var xTarget = (XElement)ToXmlFriendlyObject(target); var xTarget = (XElement)ToXmlFriendlyObject(target);
PropertyAssignOnXElement(xTarget, propertyToInit, IrisObject.Create(newPropValue, propertyToInit.PropertyType, _context, initType)); var xPropSetter = PropertyAssignOnXElement(xTarget, propertyToInit, IrisObject.Create(newPropValue, propertyToInit.PropertyType, _context, initType));
xPropSetter.SetOffset(instruction);
stack.Push(new IrisObject(xTarget, propertyToInit.Owner)); stack.Push(new IrisObject(xTarget, propertyToInit.Owner));
break; break;
@@ -231,10 +272,10 @@ public partial class Decompiler
var dictValueObj = IrisObject.Create(dictValue, dictValueType, _context, initType); var dictValueObj = IrisObject.Create(dictValue, dictValueType, _context, initType);
var targetDictPropertyIndex = (ushort)instruction.Operands.ElementAt(0).Value; var targetDictPropertyIndex = (ushort)instruction.Operands.ElementAt(0).Value;
if (targetDictPropertyIndex is ushort.MaxValue) var xKeyValue = targetDictPropertyIndex is ushort.MaxValue
PropertyDictionaryAddOnXElement(targetInstance, dictValueObj, key); ? PropertyDictionaryAddOnXElement(targetInstance, dictValueObj, key)
else : PropertyDictionaryAddOnXElement(targetInstance, _context.ImportTables.PropertyImports[targetDictPropertyIndex], dictValueObj, key);
PropertyDictionaryAddOnXElement(targetInstance, _context.ImportTables.PropertyImports[targetDictPropertyIndex], dictValueObj, key); xKeyValue.SetOffset(instruction);
break; break;
case OpCode.PropertyListAdd: case OpCode.PropertyListAdd:
@@ -252,6 +293,7 @@ public partial class Decompiler
var targetInstance2 = (XElement)ToXmlFriendlyObject(stack.Peek()); var targetInstance2 = (XElement)ToXmlFriendlyObject(stack.Peek());
XObject xListItem;
var targetListPropertyIndex = (ushort)instruction.Operands.First().Value; var targetListPropertyIndex = (ushort)instruction.Operands.First().Value;
if (targetListPropertyIndex != ushort.MaxValue) if (targetListPropertyIndex != ushort.MaxValue)
{ {
@@ -264,12 +306,14 @@ public partial class Decompiler
valueToAddObj = valueToAddObj with { Type = valueToAddType }; valueToAddObj = valueToAddObj with { Type = valueToAddType };
} }
PropertyListAddOnXElement(targetInstance2, targetListProperty, valueToAddObj); xListItem = PropertyListAddOnXElement(targetInstance2, targetListProperty, valueToAddObj);
} }
else else
{ {
PropertyListAddOnXElement(targetInstance2, valueToAddObj); xListItem = PropertyListAddOnXElement(targetInstance2, valueToAddObj);
} }
xListItem.SetOffset(instruction);
break; break;
case OpCode.InitializeInstance: case OpCode.InitializeInstance:
+22
View File
@@ -1,5 +1,6 @@
using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis;
using Microsoft.Iris.Asm.Models; using Microsoft.Iris.Asm.Models;
using System.Xml.Linq;
namespace Microsoft.Iris.DecompXml; namespace Microsoft.Iris.DecompXml;
@@ -23,5 +24,26 @@ internal static class UIBOffsetAnnotation
} }
public static uint GetOffset(SyntaxAnnotation offsetAnnotation) => uint.Parse(offsetAnnotation.Data); public static uint GetOffset(SyntaxAnnotation offsetAnnotation) => uint.Parse(offsetAnnotation.Data);
public static void SetOffset(this XObject xObj, uint offset) => xObj.AddAnnotation(new UIBOffsetXmlAnnotation(offset));
public static void SetOffset(this XObject xObj, Instruction instruction) => xObj.SetOffset(instruction.Offset);
public static XObject WithOffset(this XObject xObj, Instruction instruction)
{
xObj.SetOffset(instruction.Offset);
return xObj;
} }
public static XObject WithNewOffset(this XObject xObj, Instruction instruction)
{
if (xObj.GetOffset() is null)
xObj.SetOffset(instruction.Offset);
return xObj;
}
public static uint? GetOffset(this XObject xObj) => xObj.Annotation<UIBOffsetXmlAnnotation>()?.Offset;
}
internal record UIBOffsetXmlAnnotation(uint Offset);