Commit Graph

2366 Commits

Author SHA1 Message Date
Andrea Gussoni a8b25fdd52 Differentiate entry and exit dispatcher
Differentiate the entry and exit dispatchers introduced during the
restructuring with a different `Kind` enum inside the node.
2020-06-15 15:06:23 +02:00
Andrea Gussoni 0a2ae1a19e Update dom and postdom at each waveing iteration
We now update the dominator and postdominator trees after each iteration
of the waveing algorithm.
2020-06-15 15:06:22 +02:00
Andrea Gussoni 17809e0ad1 Rename throttle in wave
Change the name of the throttle function into waveing, accordingly to
our conventions.
2020-06-15 15:06:22 +02:00
Andrea Gussoni c2bd0f2654 Set the postdominator for cases nodes
We now set the postdominator (meaning the point where the combing stop
the exploration for dominated nodes) for the case nodes using the
postdominator of the switch node corresponding to the case.
2020-06-15 15:06:22 +02:00
Andrea Gussoni 3be06929b5 Workaround to always catch nodes
Workaround that resort to looking for the original switch node in the IR
to force the creation of a switch node even if we have < 4 nodes under
our domination.
2020-06-15 15:06:22 +02:00
Andrea Gussoni 6ac4334ad2 First implementation of the waveing pass
First implementation sketch of the waveing pass.

The implementation operates by going through the postdominator tree, and
by adding preposterous switch nodes in case we have a topology that we
cannot emit using standard switches.
In this way, we build a tree of nested switch costructs.
2020-06-15 15:06:22 +02:00
Andrea Gussoni fb2e01dda1 Add skeleton for waveing pass
Add the skeleton for the weaving pass and the graph dumping before and
after the pass to improve debuggability.
2020-06-15 15:06:22 +02:00
Andrea Gussoni d4111aaa20 Document the untangle 2020-06-15 15:06:22 +02:00
Andrea Gussoni 93d4095584 Add new dispatcher node
Added a new constructor for the dispatcher nodes which will be emitted
as `switch` nodes by the decompiler.
These nodes are introduced during the restructuring phase as loop
dispatchers.
2020-06-15 15:06:22 +02:00
Andrea Gussoni 0fb4fc6503 Enable the untangle procedure again 2020-06-15 15:06:22 +02:00
Andrea Gussoni c7975effc9 Do not consider postdominator as case in switch
We avoid to add the postdominator node of a switch node as one of the
cases of the switch AST node.
2020-06-15 15:06:22 +02:00
Andrea Gussoni eaac9ec0f9 Improve switch node creation in AST creation phase
Improved the creation of `Regular` and `Check` switch nodes types during
the preliminary AST creation phase performed on the `RegionCFG`.

In particular, we now handle the dispatchers creating the right AST node
type.
2020-06-15 15:06:22 +02:00
Andrea Gussoni 0616cdbfdd New constructor for SwitchCheck AST node
Added a new constructor for the `SwitchCheck` node type in order to
build AST nodes with a successor field.
2020-06-15 15:06:22 +02:00
Andrea Gussoni 63b6409a17 Handle more node types during flattening 2020-06-15 15:06:22 +02:00
Andrea Gussoni 2bc60d9c27 Dispatcher node type in RegionCFG
Created a new node type in the RegionCFG to represent the dispatcher
nodes.
2020-06-15 15:06:22 +02:00
Andrea Gussoni 9e869e7e23 Fix indentation 2020-06-15 15:06:22 +02:00
Andrea Gussoni dce994acdb Fix SwitchNode bug in Clone method
Explicitly handle the `RegularSwitchNode` type in the `ASTNode` cloning
method.
2020-06-15 15:06:22 +02:00
Andrea Gussoni 36af400ab8 Fix bug using wrong LLVM context 2020-06-15 15:06:22 +02:00
Andrea Gussoni f2f659d57a Search and set post dominator node for switches
When building the switch AST node search for its post dominator, and add
this information into the AST node just created.
2020-06-15 15:06:22 +02:00
Andrea Gussoni cbcabfef39 Handle SwitchNode during preliminary AST build 2020-06-15 15:06:22 +02:00
Andrea Gussoni 4777bf3083 Load also unexpectedpc blocks 2020-06-15 15:06:22 +02:00
Andrea Gussoni 59fc142dc9 Build RegularSwitchNode during AST creation
Create directly regular switch nodes in the AST build starting from the
`RegionCFG`.

As of now, a switch node is built only if we find a node that
immediately dominates more than 3 nodes.

In the future, we will need to refine this criterion.
2020-06-15 15:06:22 +02:00
Andrea Gussoni a867854e1d Fix RegularSwitchNode dump bug 2020-06-15 15:06:22 +02:00
Andrea Gussoni 026baf03d0 Handle switch nodes in inflate
The switch nodes are now considered as conditional nodes, and therefore
processed by the combing.
2020-06-15 15:06:22 +02:00
Andrea Gussoni 4775492d97 Handle switch node during RegionCFG initialization
During the RegionCFG creation from the LLVM IR handle the creation of
nodes with possibly more than two successors.

In this way we do not have to disassemble the switch nodes in nested if
trees.
2020-06-15 15:06:22 +02:00
Andrea Gussoni aacb65238a HACK: temporarily disable untangle
Disable the untangle processing until we understand what we need to do
with the new switch nodes.

In this way we can proceed with the prototyping.
2020-06-15 15:06:22 +02:00
Pietro Fezzardi b0835a6aaf Remove unused FlattenLog Logger
This Logger was also defined as `static` into a public header, making it
bug-prone.
2020-06-15 15:04:04 +02:00
Pietro Fezzardi 227e649175 Fix use of comparison parameter C in SmallMap 2020-06-14 23:51:36 +02:00
Pietro Fezzardi e4c8e7962a Make Iteratall a bidirectional iterator 2020-06-14 23:51:36 +02:00
Pietro Fezzardi 2bc5a52ef9 Iteratall: add constructors and public typedefs
These are necessary for this iterator to be a forward_iterator according
to the standard.
Missing these causes compilation errors in some cases when using
functions from the Standard Template Library with these iterators.
2020-06-14 23:51:36 +02:00
Pietro Fezzardi 2fc342d2e4 Add a global public Logger: VerifyLog
Rationale: it is a widespread practice, both in revng and in projects
that depend on it, to write verification functions that check specific
properties hold after different transformations on various data
structures.
Often, these verification function are very useful for debugging and
during development, but they can be very costly and we don't want to
always execute them at runtime.

This patch adds a global public Logger, called VerifyLog, that can be
enabled with the --debug-log=verify command line argument.
This Logger is intended to be used in revng and in projects that depend
on it, as a guard for costly calls to verification functions that do not
need to be performed on a typical execution, but only when debugging.

For now the only user is JumpTargetManager, but other uses are already
envisioned.
2020-06-14 23:34:14 +02:00
Pietro Fezzardi 0eb179baf8 GCBI: relax assumptions on AnyPC and UnexpectedPC
This commit makes possible to execute the GeneratedCodeBasicInfo (GCBI)
Pass even on LLVM IR where the AnyPC and UnexpectedPC BasicBlocks are
not present.
This makes the GCBI pass more flexible, enabling more other passes to
depend on it and to use it to retrieve informations on the generated
code without architecture-dependent hacks.

As an example, one can now use GCBI to retrieve the CSV representing the
Stack Pointer Register or the Program Counter Register without relying
on the register names (which are architecture-specific), even if some
optimization pass along the decompilation pipeline has removed AnyPC or
UnexpectedPC.

Notice that the contracts of GCBI's methods has not been changed.
Calling anyPC() or unexpectedPC() still asserts that those are not
nullptr.
The contract has just been moved from the execution stage of the pass
(basically runOnModule), to the APIs used to query the results.
2020-06-14 23:33:02 +02:00
Pietro Fezzardi ddebd55629 Add FilteredGraphTraits with tests
This patch adds a two markers for llvm::GraphTraits:
 - NodePairFilteredGraph
 - EdgeFilteredGraph

Both these markers allow to specify a static predicate that is used to
filter edges.
This predicate is a boolean function such that:
  - for NodePairFilteredGraph, it takes a pair of const NodeRef & that
    are used to represent an edge, and it evaluates a given property of
    that pair;
  - for EdgeFilteredGraph, it takes a const EdgeRef & that represents an
    edge, and it evaluates a given property on the edge.
The filtered graph contains only the edges for which the predicate
evaluates true.

Notice that the predicate must have static lifetime, meaning that all
the edge properties must be entirely evaluated on the pair of node (for
NodePairFilteredGraph) or on the edge (for EdgeFilteredGraph).
This means that you cannot pass mutable state to the predicate at
runtime.

The new markers are designed to interoperate well with llvm::Inverse and
to allow you to traverse the marked graphs with llvm::depth_first,
llvm::inverse_depth_first, llvm::breadth_first, and to compute dominator
trees and post-dominator trees on filtered graphs.
2020-06-13 10:36:08 +02:00
Pietro Fezzardi d39c124344 DotGraphObject: support Dom and PostDom Trees 2020-06-13 10:36:08 +02:00
Pietro Fezzardi 45516f89b8 Add Inverse GraphTraits for DotNode and DotGraph 2020-06-13 10:36:08 +02:00
Pietro Fezzardi 2bf702b74b DotGraph: add EdgeRef and ChildEdgeIteratorType
Add EdgeRef and ChildEdgeIteratorType to GraphTraits<DotNode *> and to
GraphTraits<const DotNode *>.

This allows iterating on edges of DotGraphs, which will be useful for
some testing on edge properties.
2020-06-10 00:23:54 +02:00
Pietro Fezzardi a955cb9a50 [DotGraphObject.h] Fix DotGraph::end() methods
This commits fixes a typo, probably a leftover from copy-paste, that
caused `DotGraph::end()` methods to actually return `begin()`.

Nobody was relying on this, which caused this bug to go unnoticed.
2020-06-10 00:23:51 +02:00
Alessandro Di Federico 23f1a7b342 Reduce blocks analyzed by AVI
AVI and InstCombine are the bottleneck of the lifting process.
This commit introduces a whitelist of jump targets that are considered
by AVI during harvesting.
The whitelist is initialized by the jump targets that are new with
respect to the last run of AVI. Then, it's expanded with all the jump
targets that can reach the initial set of jump targets through direct
jumps.
2020-06-02 21:14:50 +02:00
Alessandro Di Federico 6e6aeac45d Keep sum of pushed values in RunningStatistics 2020-06-02 10:57:02 +02:00
Alessandro Di Federico 773e386f22 Prevent SIGSEGV in translation with guard pages
When translation of code overflows into an unmapped page, we can get a
SIGSEGV. To avoid this, for each set of contiguous pages, we add "guard
page" containing an architecture-specific pattern that ensure basic
block termination.
2020-06-02 10:57:02 +02:00
Alessandro Di Federico d10178483d Introduce the new MetaAddress
Unlike the previous iteration of `MetaAddress`, which tried to stuff all
the parts of `MetaAddress` within the existing `PC` CSV, this
implementation adds a set of new CSVs (or marks some existing ones as) to
represent the four portions of the current PC's `MetaAddress`.

* Introduce `ProgramCounterHandler`: a class responsible to maintain the
  PC-related CSVs. This class is also used to manipulate the new
  dispatcher.
* `AdvancedValueInfo`: update for new MetaAddress.
* External jump handler: do not clobber registers.
  When introducing support for dynamic binaries, we didn't realize that
  in x86-64 we were clobbering `r11`. To avoid this, we have to jump to
  an address stored in memory. However, due to the new `MetaAddress`,
  obtaining a *jumpable* address from the PC-related CSVs might require
  some computations (and it does in ARM). Therefore, we introduce a new
  global variable, `jumpablepc`, whose only role is to contain the
  jumpable version of the program counter and then be the target of the
  memory-indirect jump instruction.
* Labels care only about absolute addresses.
* CSAA: mark call site, even if no accesses.
2020-06-02 10:57:02 +02:00
Alessandro Di Federico b5a1fa2c32 Disable Architecture's copy constructor 2020-05-14 21:59:03 +02:00
Alessandro Di Federico d704e88550 getBasicBlockPC: handle empty blocks 2020-05-14 11:59:05 +02:00
Alessandro Di Federico 2548df7092 QuickMetadata: improve ConstantInt handling 2020-05-14 11:59:05 +02:00
Alessandro Di Federico 22232441dd getName: print pointer as fallback 2020-05-14 11:59:05 +02:00
Alessandro Di Federico 34d7a8e364 Let ConstantRangeSet::dump work on any stream 2020-05-14 11:59:05 +02:00
Alessandro Di Federico 2531cc3c60 The link register has to be an ABI register
This is to prevent the PC (or similar CSVs) from being considerate as a
link register.
2020-05-14 11:59:05 +02:00
Alessandro Di Federico dc48188f37 Introduce MetaAddress
`MetaAddress` replaces all the `uint64_t` used to represent a virtual
address. Its main features are:

* It has a non-zero representation of invalid addresses.
* It supports tags to represent code that has different interpretations but
  resides at the same address in memory (namely ARM vs Thumb).
* Arithmetic operations cannot overflow.
* It supports epochs, a way we intend to employ to handle self-modifying code
  (i.e., different code at the same address at different times).
* It supports "address spaces", which enable handling architectures with
  multiple address spaces.
* It fits in two 64-bit registers.
2020-05-14 11:58:18 +02:00
Alessandro Di Federico e336a33545 Move GCBI::getPC to IRHepers.h 2020-05-14 11:58:18 +02:00
Alessandro Di Federico 20c367b88f Add ArchitectureName to revng.input.architecture 2020-05-14 11:58:18 +02:00