From fb78fcb07b4b18358fa82e2a4ef973e5c9e272a1 Mon Sep 17 00:00:00 2001 From: gompoc <91314780+gompoc@users.noreply.github.com> Date: Sun, 25 Aug 2024 13:11:40 +0100 Subject: [PATCH] Core.Tests: Add another graph test case/cleanup --- .../BasicGraph.cs} | 6 +- .../Graphing/ExceptionThrowingGraph.cs | 101 ++++++++++++++++++ Cpp2IL.Core/Graphs/ISILControlFlowGraph.cs | 37 ------- .../Graphs/Processors/MetadataProcessor.cs | 2 +- 4 files changed, 105 insertions(+), 41 deletions(-) rename Cpp2IL.Core.Tests/{GraphingTests.cs => Graphing/BasicGraph.cs} (96%) create mode 100644 Cpp2IL.Core.Tests/Graphing/ExceptionThrowingGraph.cs diff --git a/Cpp2IL.Core.Tests/GraphingTests.cs b/Cpp2IL.Core.Tests/Graphing/BasicGraph.cs similarity index 96% rename from Cpp2IL.Core.Tests/GraphingTests.cs rename to Cpp2IL.Core.Tests/Graphing/BasicGraph.cs index 77513725..5a7865d6 100644 --- a/Cpp2IL.Core.Tests/GraphingTests.cs +++ b/Cpp2IL.Core.Tests/Graphing/BasicGraph.cs @@ -1,16 +1,16 @@ using Cpp2IL.Core.Graphs; using Cpp2IL.Core.ISIL; -namespace Cpp2IL.Core.Tests; +namespace Cpp2IL.Core.Tests.Graphing; -public class GraphingTests +public class BasicGraph { ISILControlFlowGraph graph; [SetUp] public void Setup() { - IsilBuilder isilBuilder = new IsilBuilder(); + var isilBuilder = new IsilBuilder(); isilBuilder.ShiftStack(0x0000, -40); isilBuilder.Compare(0x0001, InstructionSetIndependentOperand.MakeRegister("test1"), InstructionSetIndependentOperand.MakeRegister("test2")); diff --git a/Cpp2IL.Core.Tests/Graphing/ExceptionThrowingGraph.cs b/Cpp2IL.Core.Tests/Graphing/ExceptionThrowingGraph.cs new file mode 100644 index 00000000..caaddd9e --- /dev/null +++ b/Cpp2IL.Core.Tests/Graphing/ExceptionThrowingGraph.cs @@ -0,0 +1,101 @@ +using Cpp2IL.Core.Graphs; +using Cpp2IL.Core.ISIL; + +namespace Cpp2IL.Core.Tests.Graphing; +public class ExceptionThrowingGraph +{ + ISILControlFlowGraph graph; + + [SetUp] + public void Setup() + { + var isilBuilder = new IsilBuilder(); + + isilBuilder.Push(001, InstructionSetIndependentOperand.MakeRegister("sp"), InstructionSetIndependentOperand.MakeRegister("reg1")); + isilBuilder.ShiftStack(002, -80); + isilBuilder.Compare(003, InstructionSetIndependentOperand.MakeRegister("reg2"), InstructionSetIndependentOperand.MakeImmediate(0)); + isilBuilder.Move(004, InstructionSetIndependentOperand.MakeRegister("reg3"), InstructionSetIndependentOperand.MakeRegister("reg4")); + isilBuilder.JumpIfNotEqual(005, 9); + isilBuilder.Move(006, InstructionSetIndependentOperand.MakeRegister("reg5"), InstructionSetIndependentOperand.MakeImmediate(0)); + isilBuilder.Call(007, 0xDEADBEEF); + isilBuilder.Move(008, InstructionSetIndependentOperand.MakeRegister("reg6"), InstructionSetIndependentOperand.MakeImmediate(1)); + isilBuilder.Compare(009, InstructionSetIndependentOperand.MakeRegister("reg7"), InstructionSetIndependentOperand.MakeImmediate(0)); + isilBuilder.JumpIfEqual(010, 35); + isilBuilder.Move(011, InstructionSetIndependentOperand.MakeRegister("reg8"), InstructionSetIndependentOperand.MakeImmediate(1)); + isilBuilder.Move(012, InstructionSetIndependentOperand.MakeRegister("reg9"), InstructionSetIndependentOperand.MakeImmediate(2)); + isilBuilder.Move(013, InstructionSetIndependentOperand.MakeRegister("reg10"), InstructionSetIndependentOperand.MakeImmediate(3)); + isilBuilder.Move(014, InstructionSetIndependentOperand.MakeStack(0x40), InstructionSetIndependentOperand.MakeRegister("reg11")); + isilBuilder.Move(015, InstructionSetIndependentOperand.MakeRegister("reg12"), InstructionSetIndependentOperand.MakeImmediate("input")); + isilBuilder.Move(016, InstructionSetIndependentOperand.MakeStack(0x30), InstructionSetIndependentOperand.MakeRegister("reg13")); + isilBuilder.Compare(017, InstructionSetIndependentOperand.MakeRegister("reg14"), InstructionSetIndependentOperand.MakeImmediate(2)); + isilBuilder.Move(018, InstructionSetIndependentOperand.MakeStack(0x20), InstructionSetIndependentOperand.MakeRegister("reg15")); + isilBuilder.Move(019, InstructionSetIndependentOperand.MakeStack(0x40), InstructionSetIndependentOperand.MakeImmediate(1)); + isilBuilder.Move(020, InstructionSetIndependentOperand.MakeStack(0x38), InstructionSetIndependentOperand.MakeRegister("reg16")); + isilBuilder.JumpIfEqual(021, 25); + isilBuilder.Compare(022, InstructionSetIndependentOperand.MakeMemory(new IsilMemoryOperand(InstructionSetIndependentOperand.MakeRegister("reg17"), 224)), InstructionSetIndependentOperand.MakeImmediate(0)); + isilBuilder.JumpIfNotEqual(023, 25); + isilBuilder.Call(024, 0xDEADBEEF); + isilBuilder.Move(025, InstructionSetIndependentOperand.MakeRegister("reg18"), InstructionSetIndependentOperand.MakeImmediate(0)); + isilBuilder.LoadAddress(026, InstructionSetIndependentOperand.MakeRegister("reg19"), InstructionSetIndependentOperand.MakeStack(0x20)); + isilBuilder.Move(027, InstructionSetIndependentOperand.MakeRegister("reg20"), InstructionSetIndependentOperand.MakeRegister("reg21")); + isilBuilder.Call(028, 0xDEADBEEF); + isilBuilder.Compare(029, InstructionSetIndependentOperand.MakeRegister("reg22"), InstructionSetIndependentOperand.MakeImmediate(0)); + isilBuilder.JumpIfEqual(030, 46); + isilBuilder.Move(031, InstructionSetIndependentOperand.MakeRegister("reg23"), InstructionSetIndependentOperand.MakeStack(0x20)); + isilBuilder.ShiftStack(032, 80); + isilBuilder.Pop(033, InstructionSetIndependentOperand.MakeRegister("sp"), InstructionSetIndependentOperand.MakeRegister("reg24")); + isilBuilder.Return(034, InstructionSetIndependentOperand.MakeRegister("reg25")); + isilBuilder.Move(035, InstructionSetIndependentOperand.MakeRegister("reg26"), InstructionSetIndependentOperand.MakeImmediate(0)); + isilBuilder.Call(036, 0xDEADBEEF); + isilBuilder.Move(037, InstructionSetIndependentOperand.MakeRegister("reg27"), InstructionSetIndependentOperand.MakeImmediate("input")); + isilBuilder.Move(038, InstructionSetIndependentOperand.MakeRegister("reg28"), InstructionSetIndependentOperand.MakeImmediate(0)); + isilBuilder.Move(039, InstructionSetIndependentOperand.MakeRegister("reg29"), InstructionSetIndependentOperand.MakeRegister("reg30")); + isilBuilder.Move(040, InstructionSetIndependentOperand.MakeRegister("reg31"), InstructionSetIndependentOperand.MakeRegister("reg32")); + isilBuilder.Call(041, 0xDEADBEEF); + isilBuilder.Move(042, InstructionSetIndependentOperand.MakeRegister("reg33"), InstructionSetIndependentOperand.MakeMemory(new IsilMemoryOperand(0xDEADBEEF))); + isilBuilder.Move(043, InstructionSetIndependentOperand.MakeRegister("reg34"), InstructionSetIndependentOperand.MakeRegister("reg35")); + isilBuilder.Call(044, 0xDEADBEEF); + isilBuilder.Interrupt(045); + isilBuilder.Move(046, InstructionSetIndependentOperand.MakeRegister("reg36"), InstructionSetIndependentOperand.MakeImmediate(0)); + isilBuilder.LoadAddress(047, InstructionSetIndependentOperand.MakeRegister("reg37"), InstructionSetIndependentOperand.MakeStack(0x20)); + isilBuilder.Call(048, 0xDEADBEEF); + isilBuilder.Move(049, InstructionSetIndependentOperand.MakeRegister("reg38"), InstructionSetIndependentOperand.MakeMemory(new IsilMemoryOperand(0x1809C39E0))); + isilBuilder.Move(050, InstructionSetIndependentOperand.MakeRegister("reg39"), InstructionSetIndependentOperand.MakeRegister("reg40")); + isilBuilder.Call(051, 0xDEADBEEF); + + isilBuilder.FixJumps(); + + graph = new(); + graph.Build(isilBuilder.BackingStatementList); + } + + [Test] + public void VerifyNumberOfBlocks() + { + Assert.That(graph.Blocks.Count == 18); + } + + [Test] + public void VerifyBlockEdges() + { + foreach (var block in graph.Blocks) + { + switch (block.BlockType) + { + case BlockType.Entry: + Assert.That(block.Predecessors.Count == 0); + Assert.That(block.Successors.Count > 0); + break; + case BlockType.Exit: + Assert.That(block.Successors.Count == 0); + Assert.That(block.Predecessors.Count > 0); + break; + default: + Assert.That(block.Successors.Count >= 1); + Assert.That(block.Predecessors.Count >= 1); + break; + } + } + } +} + diff --git a/Cpp2IL.Core/Graphs/ISILControlFlowGraph.cs b/Cpp2IL.Core/Graphs/ISILControlFlowGraph.cs index 6aea3b44..c4ac34a2 100644 --- a/Cpp2IL.Core/Graphs/ISILControlFlowGraph.cs +++ b/Cpp2IL.Core/Graphs/ISILControlFlowGraph.cs @@ -289,41 +289,4 @@ private void AddDirectedEdge(Block from, Block to) } protected void AddNode(Block block) => blockSet.Add(block); - - private void TraverseAndPreExecute(Block block, Action action) - { - block.Visited = true; - action(block); - foreach (var successor in block.Successors) - if (!successor.Visited) - TraverseAndPreExecute(successor, action); - } - - public string Print(bool instructions = false) - { - var sb = new StringBuilder(); - foreach (var node in blockSet) - { - /* - sb.Append("=========================\n"); - sb.Append( - $"ID: {node.ID}, FC: {node.FlowControl}, Successors:{string.Join(",", node.Successors.Select(i => i.ID))}, Predecessors:{string.Join(",", node.Predecessors.Select(i => i.ID))}"); - if (node.IsConditionalBranch) - sb.Append($", Condition: {node.Condition?.ConditionString ?? "Null"}"); - if (node.Instructions.Count > 0) - sb.Append($", Address {node.GetFormattedInstructionAddress(node.Instructions.First())}"); - sb.Append($", Number of Statements: {node.Statements.Count}"); - sb.Append("\n"); - if (instructions) - foreach (var instruction in node.Instructions) - sb.AppendLine(instruction?.ToString()); - else - foreach (var v in node.Statements) - sb.Append(v.GetTextDump(0)); - sb.Append('\n'); - */ - } - - return sb.ToString(); - } } diff --git a/Cpp2IL.Core/Graphs/Processors/MetadataProcessor.cs b/Cpp2IL.Core/Graphs/Processors/MetadataProcessor.cs index 24723a18..19ad5bdb 100644 --- a/Cpp2IL.Core/Graphs/Processors/MetadataProcessor.cs +++ b/Cpp2IL.Core/Graphs/Processors/MetadataProcessor.cs @@ -31,7 +31,7 @@ public void Process(MethodAnalysisContext methodAnalysisContext, Block block) { // Try instead check if its type metadata usage var metadataUsage = LibCpp2IlMain.GetTypeGlobalByAddress((ulong)memoryOp.Addend); - if (metadataUsage != null) + if (metadataUsage != null && methodAnalysisContext.DeclaringType is not null) { var typeAnalysisContext = metadataUsage.ToContext(methodAnalysisContext.DeclaringType!.DeclaringAssembly); if (typeAnalysisContext != null)