Commit Graph

6113 Commits

Author SHA1 Message Date
Pietro Fezzardi 37b894b36c RegionCFG: fix combing for switches
Before this commit, switches were treated as normal conditional nodes.
This was wrong, because treating a switch as a conditional node does not
guarantee that all the parts of the control flow representing each case
are really combed.

This commit removes switch nodes from conditional nodes, and creates a
dummy for each case. All the dummy cases are treated as conditional
nodes inducing duplication separately, instead of the actual switch.
This has the consequence of enabling the combing to proper comb the
switch cases from each other, without altering the combing algorithm.

Each switch case is combed until the combing finds the post-dominator
of the switch, not the post-dominator of the case.
2020-07-27 12:15:40 +02:00
Pietro Fezzardi 342300cf9c RegionCFGTree: remove costly method orderNodes
This method was used to sort vector of nodes either in post-order or in
reverse-post-order.

It had 2 problems:
- the boolean argument used to select between POT and RPOT was no longer
  used, since all the remaining call sites passed false.
- it was expensive to call, because it took a vector, it created a set
  from it, and performed a reverse-post-order-traversal of the whole
  graph while pushing the nodes to sort back into a newly allocated
  vector. This was particularly problematic because in one of the call
  sites a reverse-post-order-traversal was already available, but the
  method did calculate a new one nonetheless.

The method is removed in this commit.
All the call sites have been modified to use the
reverse-post-order-traversal object if already available, and they
avoid allocating a new set for the computation and a new vector for the
results. The initialization is now performed directly into a set, and
the sorted results are pushed into a vector. This effectively saves the
allocation of a vector in each call site.
2020-07-27 12:15:40 +02:00
Pietro Fezzardi 140f0962ab weave: remove useless early exit on cases
The weaving routine included a check that the candidate node for weaving
was not one of the case blocks of the switch. This check was likely
introduce to mask an old malfunction, caused by a missing update of the
CaseSet data structure, that has since then been removed.
This check was now useless and this commit removes it.
2020-07-27 12:15:40 +02:00
Pietro Fezzardi 3dd149f995 RegionCFGTree: remove useless recomputation of DT 2020-07-27 12:15:40 +02:00
Pietro Fezzardi 1664c6b060 RegionCFGTree: improve logging 2020-07-27 12:15:40 +02:00
Pietro Fezzardi 08bcfa3384 RegionCFGTree: remove unused local variable 2020-07-27 12:15:40 +02:00
Pietro Fezzardi 8c936422f4 RegionCFGTree: remove method getInterestingNodes
The removed method was now unused.
2020-07-27 12:15:40 +02:00
Pietro Fezzardi 3286789a9e SwitchNode: fix embedding of original BasicBlock
Before this commit, the original llvm BasicBlock was not embedded
properly in the GHAST SwitchNodes. This caused problems and crashes in
decompilation.

This commit SwitchNode constructors so the that the BasicBlock properly
reaches the GHAST and it is printed correctly by the decompiler.
2020-07-23 18:51:15 +02:00
Pietro Fezzardi 6d10120e2e Decompiler: fix emission of code before branches
Before this commit, the C statements before an IfNode or a SwitchNode
were not guaranteed to be emitted if they were not involved in the
computation of the branch condition.

This commit fixes this problem.
2020-07-22 17:27:02 +02:00
Pietro Fezzardi fc98fc69f5 Fix detection of isolated functions using metadata 2020-07-22 17:27:02 +02:00
Pietro Fezzardi 1895a2de3e CDecompilerPass: fix detection of isolated funcs 2020-07-22 17:27:02 +02:00
Pietro Fezzardi f77b904d2a CDecompilerPass: remove dead code 2020-07-22 17:27:02 +02:00
Pietro Fezzardi e34dbe1b70 Add RemoveNewPCCallsPass
This pass removes all the calls to `newpc`.
This pass needs to run before the DLA and before the decompilation pass.
2020-07-20 19:02:20 +02:00
Pietro Fezzardi 2be51e97cd RemovePCStoresPass: fix return of runOnFunction 2020-07-20 19:02:20 +02:00
Pietro Fezzardi bbbe537b18 RemovePCStoresPass: prevent removing self loops 2020-07-20 19:02:20 +02:00
Pietro Fezzardi 5a826848fe RemovePCStoresPass: properly detect isolated funcs 2020-07-20 19:02:20 +02:00
Pietro Fezzardi 1a9ae59e4a RestructureCFG: major refactoring of switches
Now edges have sets representing labels.
There's no distinction between Dispatchers and Regular switches at the
GHAST level anymore.
2020-07-20 19:02:19 +02:00
Pietro Fezzardi bebd3a3f33 Fix creation of new nodes during weave
Before this commit, all the nodes created by weaving were dispatcher
switches. This is wrong, because when you weave a switch coming from
original assembly code you lose information if you lower it to a
dispatcher (for example which variable you are switching on).

This commit likely breaks the emitted C code (which was actually broken
anyway in case a code switch was lowered to a dispatcher).
Later commits will propagate this change to the emission of C code to
fix it.
2020-07-20 19:02:19 +02:00
Pietro Fezzardi 1ca39d25f0 Add Weaved field to BasicBlockNode<T>
This is meant to represent the fact that a node was created during the
switch weaving.
2020-07-20 19:02:19 +02:00
Pietro Fezzardi a7b3e34d85 RegionCFGTree: add assertions in addArtificialNode
This is meant to ensure that we never create artificial nodes with
unexpected Kind.

Expected kinds are only Empty, Break, Continue.
2020-07-20 19:02:19 +02:00
Pietro Fezzardi 0e5dceeed4 ASTNode: fix isEqual method for switch nodes
This was broken after the introduction of `SwitchDispatcherNode`,
because
both `SwitchDispatcherNode` and `RegularSwitchNode` used the `isEqual`
method from `SwitchNode`.

Now the `isEqual` method is implemented only for the `ASTNode` base
class, and each leaf of the llvm-RTTI hierarchy of `ASTNode` properly
implements the comparison.
2020-07-20 19:02:19 +02:00
Pietro Fezzardi 7f6ce70c82 Refactor RegionCFG::inflate() method 2020-07-16 10:48:12 +02:00
Pietro Fezzardi bc9ac5f9eb Add void RegionCFG::dumpDotOnFile(const char *)
This method is just a wrapper, useful when debugging, when creating a
std::string from within gdb is painful.
2020-07-14 21:22:21 +02:00
Andrea Gussoni 47f797ba9a RegionCFGTree: fix AST simplification for switches
In presence of a switch node, which contains a case made up of
entirely a sequence of empty nodes (simplified by the
`simplifyAtomicSequence` recursive function), enable the removal of the
aforementioned case from the switch node.
2020-07-14 15:28:20 +02:00
Pietro Fezzardi a89ebde96a RegionCFGTree: handle switches in AST simplify
The functions `simplifyAtomicSequence` and `simplifyDummies` did not
handle switches properly.
This commit ensures they are handled.
2020-07-10 16:49:40 +02:00
Pietro Fezzardi 023a703e43 RegionCFGTree: update CaseSet for nested weaving 2020-07-10 16:49:40 +02:00
Pietro Fezzardi 0505b1754f RegionCFGTree: weave also switches with 3 cases 2020-07-10 16:49:40 +02:00
Pietro Fezzardi c28bcda012 RegionCFGTree: keep InlinedEdges up-to-date 2020-07-10 16:49:40 +02:00
Pietro Fezzardi 05e79bb607 RegionCFGTree: remove dead code 2020-07-10 16:49:40 +02:00
Pietro Fezzardi a078be2478 RestructureCFG: avoid dedicated untangling of root
This commit removes a call to untangle() that was performed before the
whole combing algorithm on the root RegionCFG.

The call was redundant before introducing the weaving, and became
plainly wrong after adding the weaving, because it ended up trying to
untangle the root RegionCFG before weaving (which is supposed to run
first).

Removing the dedicated call fixes the bug, because weaving is performed
first as part of the call to generateAst().
2020-07-09 18:17:20 +02:00
Pietro Fezzardi c5f584db65 RegionCFGTree: fix untangle dominance criterion
The untangle procedure evaluates the cost of Combing, the cost of
performing Untangling on the 'then' side, and the cost of performing the
Untangling on the 'else' side.
To compute the costs related to 'then' and 'else' branches, it uses the
dominance relationships between then/else and the nodes they can reach.

To do so, it builds a set of nodes that are dominated by the 'then'
__edge__, and by the 'else' __edge__.
Notice, __edge__ is important here.

Before this commit, the computation of these two sets was wrong.
To decide if node was dominated by the 'then' __edge__ it checked if the
node was actually dominated by the __target node of the 'then' edge__,
which is not correct. For a case where this is wrong see the following:

A --(else edge)-> B --> C --> D
 \                      ^
  \                    /
   -----(then edge)----

Here D is not dominated by the (then edge), but it is dominated by C,
which is the target of the (then edge).
A similar example can be devised for the else edge.

This commit fixes the computation of the two sets, using the dominance
w.r.t. the edge instead of the dominance w.r.t. the target node of the
edge.

This fixes some cases where the untangling was taking the wrong
decision.
2020-07-09 18:17:20 +02:00
Pietro Fezzardi 6c1721dbdd RegionCFGTree: remove dead code from untangling 2020-07-09 17:12:47 +02:00
Andrea Gussoni c35a186e58 [SWITCH] Correct createSequence for switch
Fix the `createSequence` function by actually replacing the cases of a
`SwitchNode`.
2020-06-30 18:11:32 +02:00
Andrea Gussoni 2ab2e779d9 [SWITCH] Introduce case replace methods
Introduce methods to replace the `ASTNode`s pointed by a `SwitchNode`.

This methods will be used in the during the AST refinement procedures.
2020-06-30 18:11:32 +02:00
Alessandro Di Federico b7660a06c3 [MetaAddress] Fix tie type
The tuple returned by the `tie` method used to have the type of the
`Type` field (`uint16_t`) for the `Address` field (`uint64_t`) and
viceversa.
2020-06-29 23:49:52 +02:00
Alain Carlucci be9bc6ce0a MetaAddress: remove header dependency from IRBuilder 2020-06-25 14:28:07 +02:00
Alessandro Di Federico 314cae3a1e Abandon removeUnreachableBlocks
`llvm::removeUnreachableBlocks` doesn't just drop dead basic blocks,
it also turns certain `SwitchInst` into `BranchInst`, which leads to
hard-to-debug issues in parts of the code where we don't assume
unexpected changes such as this.
2020-06-23 15:01:52 +02:00
Alessandro Di Federico d8cbc86b1c Isolate: handle IndirectBranchDispatcherHelper
Function isolation used to mishandle blocks of type
`BlockType::IndirectBranchDispatcherHelperBlock`. This led to have
empty basic blocks instead of the dispatcher for handling indirect
branches.
2020-06-23 14:55:13 +02:00
Pietro Fezzardi f7e8599c5e Enforce check-conventions.sh
All commits should pass check-conventions.sh from now on.
2020-06-15 15:40:02 +02:00
Pietro Fezzardi 7c1ee4ac6b Make isASwitch inline 2020-06-15 15:30:08 +02:00
Pietro Fezzardi 921092aa6f Uniform ReversePostOrderTraversalExt with LLVM.
The other `_ext` graph iterators from LLVM all use `std::set` as default
template parameter used for the set types.
This commit make `ReversePostOrderTraversalExt` behave the same.
2020-06-15 15:27:47 +02:00
Andrea Gussoni 6367b822a0 Add default case in RegularSwitch
The switch node generation now takes care of setting the correct default
case in presence of a `RegularSwitchNode`. We cross check the default
case with the underlying switch instruction in the LLVM IR.
2020-06-15 15:06:23 +02:00
Andrea Gussoni afa0cfbab4 Emit actual case values for regular switches
We now emit `RegularSwitch` node type creating the vector containing the
case values by inspecting the actual values of the `ConstantInt` in the
IR.

Due to the introduction of weaving, we can have a cascade of switches,
and in this case the top switch should bring to a certain weaving switch
for multiple values of the case label.
For this reason, switch case are now represented by sets, which are
usually populated by a single value, but in presence of a weaving
switches they can represent the fact that for each value contained in
the set we must take a certain case label.
The backend of the decompiler has been updated to reflect this change,
in order to emit all the values for a certain `CaseSet` in `or` if the
size of the seat is greater than 1.
2020-06-15 15:06:23 +02:00
Andrea Gussoni 95dbc22a36 Remove IfDispatcherNode
Remove the `IfDispatcherNode` from the hierarchy of the `ASTNode`s.
Disable the beautify routines since they are not relevant anymore.
2020-06-15 15:06:23 +02:00
Andrea Gussoni a264117aac Rename IfCheck in IfDispatcher
Now that check nodes are nomore a thing, rename the `ifcheck` in the
AST with a meaningful name.
2020-06-15 15:06:23 +02:00
Andrea Gussoni dc944d35f5 Rename SwitchCheck in SwitchDispatcher
Now that check nodes are nomore a thing, rename the switches in the AST
with a meaningful name.
2020-06-15 15:06:23 +02:00
Andrea Gussoni 933dd20e44 Restructure dispatcher creation
Now that `Check` nodes are nomore a thing, restructure the dispatcher
creation code in order to be more clean.
2020-06-15 15:06:23 +02:00
Andrea Gussoni ca22f8567d Declare variables as late as possible 2020-06-15 15:06:23 +02:00
Andrea Gussoni 3a31495a50 Move cases in the switch constructors
Move case nodes using `std::move` during the construction of `switch`
AST nodes.
2020-06-15 15:06:23 +02:00
Andrea Gussoni e611e47a20 Remove Check nodes
Check nodes are nomore a thing. Remove all methods and accessor related
to them.
2020-06-15 15:06:23 +02:00