From f024dfbbce747af2278139313c814b763822aab7 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 7 May 2026 21:52:05 +0000 Subject: [PATCH 1/3] Initial plan From 6637378da4d8f80dbe2cc2ff4803c0b1e9518cb7 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 7 May 2026 21:59:00 +0000 Subject: [PATCH 2/3] Fix ARM64 profile disassembly CFG parsing Agent-Logs-Url: https://github.com/microsoft/profile-explorer/sessions/73d867c4-8362-43ed-ab4f-a1772c3f20c6 Co-authored-by: jhpohovey <42473764+jhpohovey@users.noreply.github.com> --- .../ASM/DisassemblerSectionLoader.cs | 18 +++++++- .../ASMParserTests.cs | 41 +++++++++++++++++++ 2 files changed, 57 insertions(+), 2 deletions(-) create mode 100644 src/ProfileExplorerCoreTests/ASMParserTests.cs diff --git a/src/ProfileExplorerCore/Compilers/ASM/DisassemblerSectionLoader.cs b/src/ProfileExplorerCore/Compilers/ASM/DisassemblerSectionLoader.cs index eb5b7dc0..9c30c429 100644 --- a/src/ProfileExplorerCore/Compilers/ASM/DisassemblerSectionLoader.cs +++ b/src/ProfileExplorerCore/Compilers/ASM/DisassemblerSectionLoader.cs @@ -2,7 +2,9 @@ // Licensed under the MIT license. using System; using System.Collections.Generic; +using System.Reflection.PortableExecutable; using ProfileExplorer.Core.Binary; +using ProfileExplorer.Core.Compilers.Architecture; using ProfileExplorer.Core.IR; using ProfileExplorer.Core.Providers; @@ -24,8 +26,8 @@ public sealed class DisassemblerSectionLoader : IRTextSectionLoader { public DisassemblerSectionLoader(string binaryFilePath, ICompilerInfoProvider compilerInfo, IDebugInfoProvider debugInfo, bool preloadFunctions = true, bool isManagedImage = false) { - Initialize(compilerInfo.IR, false); binaryFilePath_ = binaryFilePath; + Initialize(SelectIRInfo(compilerInfo, binaryFilePath), false); debugInfo_ = debugInfo; debugFileFinder_ = compilerInfo.DebugFileFinder; debugInfoProviderFactory_ = compilerInfo.DebugInfoProviderFactory; @@ -36,6 +38,18 @@ public DisassemblerSectionLoader(string binaryFilePath, ICompilerInfoProvider co funcToDebugInfoMap_ = new Dictionary(); } + private static ICompilerIRInfo SelectIRInfo(ICompilerInfoProvider compilerInfo, string binaryFilePath) { + var binaryInfo = PEBinaryInfoProvider.GetBinaryFileInfo(binaryFilePath); + + return binaryInfo?.Architecture switch { + Machine.Arm64 => new ASMCompilerIRInfo(IRMode.ARM64), + Machine.Arm => new ASMCompilerIRInfo(IRMode.ARM64), + Machine.I386 => new ASMCompilerIRInfo(IRMode.x86_64), + Machine.Amd64 => new ASMCompilerIRInfo(IRMode.x86_64), + _ => compilerInfo.IR + }; + } + public IDebugInfoProvider DebugInfo { get => debugInfo_; set => debugInfo_ = value; @@ -233,4 +247,4 @@ protected override void Dispose(bool disposing) { disassembler_?.Dispose(); debugInfo_?.Dispose(); } -} \ No newline at end of file +} diff --git a/src/ProfileExplorerCoreTests/ASMParserTests.cs b/src/ProfileExplorerCoreTests/ASMParserTests.cs new file mode 100644 index 00000000..f91362e2 --- /dev/null +++ b/src/ProfileExplorerCoreTests/ASMParserTests.cs @@ -0,0 +1,41 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT license. +using Microsoft.VisualStudio.TestTools.UnitTesting; +using ProfileExplorer.Core; +using ProfileExplorer.Core.Compilers.ASM; +using ProfileExplorer.Core.Compilers.Architecture; +using ProfileExplorer.Core.IR; + +namespace ProfileExplorer.CoreTests; + +[TestClass] +public class ASMParserTests { + [TestMethod] + public void Parse_ARM64ConditionalBranch_CreatesBasicBlocksAndCFGEdges() { + string text = + """ + 1000: 54000040 b.eq #0x1008 + 1004: d503201f nop + 1008: d65f03c0 ret + """; + + var function = ParseARM64(text, 12); + + Assert.AreEqual(3, function.BlockCount); + Assert.AreEqual(2, function.EntryBlock.Successors.Count); + CollectionAssert.Contains(function.EntryBlock.Successors, function.Blocks[1]); + CollectionAssert.Contains(function.EntryBlock.Successors, function.Blocks[2]); + Assert.IsTrue(function.EntryBlock.FirstInstruction.IsBranch); + Assert.IsTrue(function.Blocks[2].FirstInstruction.IsReturn); + } + + private static FunctionIR ParseARM64(string text, long functionSize) { + var irInfo = new ASMCompilerIRInfo(IRMode.ARM64); + var parentFunction = new IRTextFunction("test"); + var output = new IRPassOutput(0, text.Length, 1, text.Split('\n').Length); + var section = new IRTextSection(parentFunction, parentFunction.Name, output); + var parser = new ASMIRSectionParser(functionSize, irInfo, irInfo.CreateParsingErrorHandler()); + + return parser.ParseSection(section, text); + } +} From a07e287abf095a6e9f7df2a860fe24f151a3a196 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 7 May 2026 22:02:29 +0000 Subject: [PATCH 3/3] Narrow disassembly IR selection to ARM64 Agent-Logs-Url: https://github.com/microsoft/profile-explorer/sessions/73d867c4-8362-43ed-ab4f-a1772c3f20c6 Co-authored-by: jhpohovey <42473764+jhpohovey@users.noreply.github.com> --- .../Compilers/ASM/DisassemblerSectionLoader.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/ProfileExplorerCore/Compilers/ASM/DisassemblerSectionLoader.cs b/src/ProfileExplorerCore/Compilers/ASM/DisassemblerSectionLoader.cs index 9c30c429..9a4a21b9 100644 --- a/src/ProfileExplorerCore/Compilers/ASM/DisassemblerSectionLoader.cs +++ b/src/ProfileExplorerCore/Compilers/ASM/DisassemblerSectionLoader.cs @@ -43,7 +43,6 @@ private static ICompilerIRInfo SelectIRInfo(ICompilerInfoProvider compilerInfo, return binaryInfo?.Architecture switch { Machine.Arm64 => new ASMCompilerIRInfo(IRMode.ARM64), - Machine.Arm => new ASMCompilerIRInfo(IRMode.ARM64), Machine.I386 => new ASMCompilerIRInfo(IRMode.x86_64), Machine.Amd64 => new ASMCompilerIRInfo(IRMode.x86_64), _ => compilerInfo.IR