Browse Source

Non-conditional branch does not have 'fall-through' node as successor.

Add explicit 'goto' statement after each basic black.
More GUI debugging options.
pull/1/head^2
David Srbecký 18 years ago
parent
commit
7df6c364c6
  1. 15
      src/AstMetodBodyBuilder.cs
  2. 11
      src/ControlFlow/Node.cs
  3. 38
      src/ControlFlow/Nodes.cs
  4. 19
      src/MainForm.Designer.cs
  5. 6
      src/MainForm.cs
  6. 5
      src/Options.cs

15
src/AstMetodBodyBuilder.cs

@ -64,13 +64,20 @@ namespace Decompiler @@ -64,13 +64,20 @@ namespace Decompiler
IEnumerable<Ast.INode> TransformNode(Node node)
{
yield return MakeComment("// " + node.ToString());
if (Options.NodeComments) {
yield return MakeComment("// " + node.ToString());
}
yield return new Ast.LabelStatement(node.Label);
if (node is BasicBlock) {
yield return new Ast.LabelStatement(((BasicBlock)node).Label);
foreach(StackExpression expr in ((BasicBlock)node).Body) {
yield return TransformExpression(expr);
}
Node next = ((BasicBlock)node).FallThroughBasicBlock;
if (next != null) {
yield return new Ast.GotoStatement(next.Label);
}
} else if (node is AcyclicGraph) {
Ast.BlockStatement blockStatement = new Ast.BlockStatement();
blockStatement.Children.AddRange(TransformNodes(node.Childs));
@ -88,7 +95,9 @@ namespace Decompiler @@ -88,7 +95,9 @@ namespace Decompiler
throw new Exception("Bad node type");
}
yield return MakeComment("");
if (Options.NodeComments) {
yield return MakeComment("");
}
}
Ast.Statement TransformExpression(StackExpression expr)

11
src/ControlFlow/Node.cs

@ -57,6 +57,12 @@ namespace Decompiler.ControlFlow @@ -57,6 +57,12 @@ namespace Decompiler.ControlFlow
get { return successors; }
}
public string Label {
get {
return this.GetType().Name + "_" + ID;
}
}
public Node(Node parent)
{
this.parent = parent;
@ -75,6 +81,11 @@ namespace Decompiler.ControlFlow @@ -75,6 +81,11 @@ namespace Decompiler.ControlFlow
i++; // Next
}
}
// If it result is single acyclic node, eliminate it
if (this.Childs.Count == 1 && this.Childs[0] is AcyclicGraph) {
this.headChild = this.Childs[0].HeadChild;
this.childs = this.Childs[0].Childs;
}
}
static void MergeChilds(Node head, Node tail)

38
src/ControlFlow/Nodes.cs

@ -1,6 +1,8 @@ @@ -1,6 +1,8 @@
using System;
using System.Collections.Generic;
using Mono.Cecil.Cil;
namespace Decompiler.ControlFlow
{
public class MethodBodyGraph: Node
@ -24,14 +26,20 @@ namespace Decompiler.ControlFlow @@ -24,14 +26,20 @@ namespace Decompiler.ControlFlow
exprs[i].BasicBlock = basicBlock;
}
// Add fall-though links
// Add fall-through links
for(int i = 0; i < exprs.Count - 1; i++) {
BasicBlock node = exprs[i].BasicBlock;
BasicBlock target = exprs[i + 1].BasicBlock;
if (node != target) {
node.Successors.Add(target);
target.Predecessors.Add(node);
}
// Still same basic block - ignore
if (node == target) continue;
// Non-conditional branch does not fall-through
if (exprs[i].LastByteCode.OpCode.Code == Code.Br) continue;
node.FallThroughBasicBlock = target;
node.Successors.Add(target);
target.Predecessors.Add(node);
}
// Add branch links
@ -39,6 +47,8 @@ namespace Decompiler.ControlFlow @@ -39,6 +47,8 @@ namespace Decompiler.ControlFlow
if (exprs[i].BranchTarget != null) {
BasicBlock node = exprs[i].BasicBlock;
BasicBlock target = exprs[i].BranchTarget.BasicBlock;
node.BranchBasicBlock = target;
node.Successors.Add(target);
target.Predecessors.Add(node);
}
@ -65,17 +75,23 @@ namespace Decompiler.ControlFlow @@ -65,17 +75,23 @@ namespace Decompiler.ControlFlow
public class BasicBlock: Node
{
List<StackExpression> body = new List<StackExpression>();
public string Label {
get {
return "BasicBlock_" + ID;
}
}
BasicBlock fallThroughBasicBlock;
BasicBlock branchBasicBlock;
public List<StackExpression> Body {
get { return body; }
}
public BasicBlock FallThroughBasicBlock {
get { return fallThroughBasicBlock; }
set { fallThroughBasicBlock = value; }
}
public BasicBlock BranchBasicBlock {
get { return branchBasicBlock; }
set { branchBasicBlock = value; }
}
public BasicBlock(Node parent): base(parent)
{
}

19
src/MainForm.Designer.cs generated

@ -38,6 +38,7 @@ namespace Decompiler @@ -38,6 +38,7 @@ namespace Decompiler
this.reduceBtn = new System.Windows.Forms.Button();
this.decompileBtn = new System.Windows.Forms.Button();
this.sourceCodeBox = new System.Windows.Forms.RichTextBox();
this.nodeComments = new System.Windows.Forms.CheckBox();
((System.ComponentModel.ISupportInitialize)(this.collapseCount)).BeginInit();
((System.ComponentModel.ISupportInitialize)(this.reduceCount)).BeginInit();
this.SuspendLayout();
@ -116,18 +117,30 @@ namespace Decompiler @@ -116,18 +117,30 @@ namespace Decompiler
| System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.sourceCodeBox.Font = new System.Drawing.Font("Courier New", 10F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.sourceCodeBox.Location = new System.Drawing.Point(12, 45);
this.sourceCodeBox.Location = new System.Drawing.Point(12, 74);
this.sourceCodeBox.Name = "sourceCodeBox";
this.sourceCodeBox.Size = new System.Drawing.Size(736, 632);
this.sourceCodeBox.Size = new System.Drawing.Size(736, 603);
this.sourceCodeBox.TabIndex = 6;
this.sourceCodeBox.Text = "";
this.sourceCodeBox.WordWrap = false;
//
// nodeComments
//
this.nodeComments.AutoSize = true;
this.nodeComments.Location = new System.Drawing.Point(12, 44);
this.nodeComments.Name = "nodeComments";
this.nodeComments.Size = new System.Drawing.Size(147, 24);
this.nodeComments.TabIndex = 7;
this.nodeComments.Text = "Node comments";
this.nodeComments.UseVisualStyleBackColor = true;
this.nodeComments.CheckedChanged += new System.EventHandler(this.NodeCommentsCheckedChanged);
//
// MainForm
//
this.AutoScaleDimensions = new System.Drawing.SizeF(9F, 20F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(760, 689);
this.Controls.Add(this.nodeComments);
this.Controls.Add(this.sourceCodeBox);
this.Controls.Add(this.decompileBtn);
this.Controls.Add(this.reduceBtn);
@ -139,7 +152,9 @@ namespace Decompiler @@ -139,7 +152,9 @@ namespace Decompiler
((System.ComponentModel.ISupportInitialize)(this.collapseCount)).EndInit();
((System.ComponentModel.ISupportInitialize)(this.reduceCount)).EndInit();
this.ResumeLayout(false);
this.PerformLayout();
}
private System.Windows.Forms.CheckBox nodeComments;
private System.Windows.Forms.RichTextBox sourceCodeBox;
private System.Windows.Forms.Button decompileBtn;
private System.Windows.Forms.Button reduceBtn;

6
src/MainForm.cs

@ -34,6 +34,7 @@ namespace Decompiler @@ -34,6 +34,7 @@ namespace Decompiler
ControlFlow.Node.NextNodeID = 0;
Options.CollapseExpression = (int)collapseCount.Value;
Options.ReduceGraph = (int)reduceCount.Value;
Options.NodeComments = nodeComments.Checked;
AssemblyDefinition assembly = AssemblyFactory.GetAssembly(filename);
AstBuilder codeDomBuilder = new AstBuilder();
@ -67,5 +68,10 @@ namespace Decompiler @@ -67,5 +68,10 @@ namespace Decompiler
{
Decompile();
}
void NodeCommentsCheckedChanged(object sender, EventArgs e)
{
Decompile();
}
}
}

5
src/Options.cs

@ -4,7 +4,8 @@ namespace Decompiler @@ -4,7 +4,8 @@ namespace Decompiler
{
public static class Options
{
public static int CollapseExpression = 0;
public static int ReduceGraph = 0;
public static int CollapseExpression = int.MaxValue;
public static int ReduceGraph = int.MaxValue;
public static bool NodeComments = false;
}
}

Loading…
Cancel
Save