Skip to content

Commit

Permalink
Update docs.
Browse files Browse the repository at this point in the history
  • Loading branch information
Washi1337 committed Jul 30, 2024
1 parent 2c34b63 commit 25eb02b
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 10 deletions.
36 changes: 31 additions & 5 deletions docs/guides/core/cfg-basics.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ Refer to the platform-specific documentation for more details.
## Nodes

Nodes in a control flow graph represent the individual basic blocks in the code, and are implemented by the `ControlFlowNode<TInstruction>` class.
They can be accessed from the `Nodes` property:
They can be accessed from the `Nodes` property, which can be iterated:

```csharp
ControlFlowGraph<TInstruction> cfg = ...;
Expand All @@ -37,14 +37,27 @@ foreach (var node in cfg.Nodes)
Console.WriteLine($"{node.Offset:X8}");
```

Nodes are indexed by offset.
They can be obtained via the `GetNodeByOffset` method:
Individual nodes can also be obtained by looking them up by offset:

```csharp
var node = cfg.GetNodeByOffset(offset: 0x1234);
var node = cfg.Nodes.GetByOffset(offset: 0x1234);
```

Every node exposes a basic blockc containing the instructions it executes:
This performs a linear search through all the nodes, and finds the first basic block that matches.
To ensure all nodes have updated offsets according to their contents, use the `UpdateOffsets` method:

```csharp
cfg.Nodes.UpdateOffsets();
```

If many nodes are supposed to be queried by offset, consider first creating an offset map; a dictionary that maps all basic block header offsets to their corresponding nodes:

```csharp
var offsetMap = cfg.Nodes.CreateOffsetMap();
var node = cfg.Nodes[0x1234];
```

Every node exposes a basic block containing the instructions it executes:

```csharp
ControlFlowNode<TInstruction> node = ...;
Expand Down Expand Up @@ -117,6 +130,19 @@ foreach (var predecessor in node.GetPredecessors())
```


New edges can be drawn by either mutating the outgoing edges properties, or by using the `ConnectWith` helper method:

```csharp
ControlFlowNode<TInstruction> node1 = ...;
ControlFlowNode<TInstruction> node2 = ...;
ControlFlowNode<TInstruction> node3 = ...;
ControlFlowNode<TInstruction> node4 = ...;

node1.ConnectWith(node2);
node2.ConnectWith(node3, ControlFlowEdgeType.Conditional);
node2.ConnectWith(node4, ControlFlowEdgeType.FallThrough);
```

## Regions

Control flow graphs can be subdivided into regions.
Expand Down
13 changes: 8 additions & 5 deletions docs/guides/core/cfg-construction.md
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ This interface takes a symbolic input state, and transforms it into a set of all
```csharp
IArchitecture<TInstruction> architecture = ...;
IStateTransitioner<TInstruction> transitioner = ...;
StateTransitioner<TInstruction> transitioner = ...;
IList<TInstruction> instructions = ...;
var builder = new SymbolicFlowGraphBuilder<TInstruction>(
Expand All @@ -79,12 +79,15 @@ var builder = new SymbolicFlowGraphBuilder<TInstruction>(
var cfg = builder.ConstructFlowGraph();
```
A by-product of symbolic graph building is that it also produces a **data flow graph**:
Most state transitioners produce a data flow graph as a by-product.
```csharp
var dfg = builder.DataFlowGraph;
```
// First create the CFG.
var cfg = builder.ConstructFlowGraph();
// After building the CFG, a DFG is populated in the transitioner.
var dfg = transitioner.DataFlowGraph;
```
> [!WARNING]
> While symbolic graph construction usually is more accurate, it is significantly slower than static graph construction and can take a lot of memory.
> While symbolic graph construction usually is more accurate, it is significantly slower than static graph construction and can take a lot of memory.

0 comments on commit 25eb02b

Please sign in to comment.