Commit Graph

102 Commits

Author SHA1 Message Date
Alessandro Di Federico 4d7a175996 Extract TupleTree 2021-12-22 17:47:54 +01:00
Antonio Frighetto 10f45c593a Move StackAnalysis to EarlyFunctionAnalysis 2021-12-15 18:03:30 +01:00
Antonio Frighetto ffd5ac7f57 Drop old StackAnalysis 2021-12-15 18:03:30 +01:00
Alessandro Di Federico 3a3eea0cf5 Introduce support for dynamic functions 2021-10-21 15:01:19 +02:00
Alessandro Di Federico a023bfa7f5 Introduce ABI handling 2021-10-18 20:44:58 +02:00
Alessandro Di Federico 34ae75c800 model: handle 80 bits floats (12 bytes) 2021-10-18 20:44:58 +02:00
Pietro Fezzardi 3d38451abd Enable error checking on Model deserialization
This commit changes the `TupleTree::deserialize` method to return an
`llvm::ErrorOr<TupleTree>`, enabling users to choose their policies on
error reporting.
2021-09-02 14:42:51 +02:00
Pietro Fezzardi 48f6a60629 Fix callOnPathSteps for KeyedObjectContainer
callOnPathSteps was using linear scan search in KeyedObjectContainer.
This commit fixes it for using binary search, dramatically improving
performance in workloads that do lots of lookups.
2021-09-02 14:39:23 +02:00
Ivan Krysak 612461cffa Enable more explicit edge iteration
Add reverse iterator support
2021-09-02 11:09:29 +03:00
Ivan Krysak 509ee3c41a Disallow label-less mutable edge graphs 2021-09-02 11:09:17 +03:00
Ivan Krysak 009a5ae060 Rework EdgeView to improve code consistency 2021-09-02 11:08:14 +03:00
Ivan Krysak 334cdf9f05 Make iterators and mapping filters consistent 2021-09-02 11:07:39 +03:00
Ivan Krysak f15e41433f Make graph testing node type agnostic 2021-09-02 11:04:44 +03:00
Ivan Krysak c8a60f9d8e Implement safe node removal 2021-09-02 09:14:20 +03:00
Ivan Krysak 5b60c22feb Implement the core of the mutable edge node 2021-09-02 09:14:20 +03:00
Ivan Krysak fbf90f8b17 Implement revng::SmallMap::contains 2021-09-01 16:32:56 +02:00
Alessandro Di Federico fd30d3de42 Import the model's type system
This commit introduces the type system of the model along with several
various other improvements to the model and its users.

* Introduce the type system.
* Introduce possibility to tag certain fields in the model as to be
  optional during YAML serialization.
* All the `Name` fields have been replaced in favor of `CustomName` plus
  a `name` method that will use `CustomName` if available, or an
  automatically generated name otherwise.
* Make TupleTreeReferences behavior more robust: now you either need to
  have a valid pointer to `Root` and a `Path` or be default constructed
  (`nullptr` for `Root` and an empty `Path`). Any other configuration is
  invalid.
* The type system introduces `RawFunctionType`: this superseds the
  previous way in which we were specifying arguments and return
  values. Users of such information have been updated accordingly.
2021-07-21 18:22:58 +02:00
Alessandro Di Federico 0f8fa271d9 TupleTree: reduce INTROSPECTION responsibilities
This commit also introduces support for optional YAML serialization of
fields.
2021-07-21 18:19:45 +02:00
Pietro Fezzardi 6f7de910a6 Enable warning -Wunused-local-typedefs 2021-06-14 23:04:02 +02:00
Pietro Fezzardi a7a55f974a Require TupleTreeCompatible concept on TupleTree 2021-06-09 20:13:27 +02:00
Alessandro Di Federico 871931b9cd Test TupleTreeDiff on Model
`TupleTreeDiff` was not being tested.

This commit implements several `operator==` that are required to
successfully instantiate `TupleTreeDiff`.
2021-05-06 15:42:16 +02:00
Alessandro Di Federico e62f888381 Drop KeyTraits
This commit drops the KeyTraits in favor of a std::any-like solution.
Basically, we type erase any key the user wants to employ, just exposing
a virtual version of the destructor, a comparison operator and a clone
primitive.
2021-05-06 15:42:00 +02:00
Pietro Fezzardi b58693b8e8 RecursiveCoroutine: enable direct continuation
Before this commit, the execution logic of RecursiveCoroutine used an
underlying std::stack allocated on the heap to hold all the
coroutine_handles. It also manually managed passing return values from
callees to callers.

This commit drops this unnecessary auxiliary stack.
When a RecursiveCoroutine co_awaits another one, the handle of the
awaiter is injected into the awaitee, so that when the awaitee is done
it can directly execute the remaining part of the awaiter as a
continuation.
2021-05-05 17:48:04 +02:00
Alessandro Di Federico 9650369fa7 Import TupleTree and TupleTreeReference 2021-05-05 17:10:12 +02:00
Alessandro Di Federico 0d77258109 Introduce HasKeyObjectTraits concept 2021-05-05 17:10:12 +02:00
Alessandro Di Federico 702f4230ac Import UpcastablePointer 2021-05-05 17:10:12 +02:00
Pietro Fezzardi 50681284c0 Conceptify revng
Use concepts across revng wherever possible, to keep the code concise
and easier to understand.
2021-05-05 17:10:12 +02:00
Alessandro Di Federico aeb81c4218 Don't implicitly use StringRef as std::string 2021-04-22 18:06:27 +02:00
Alessandro Di Federico 33fbcd7ac2 AVI: stop backward exploration at dispatcher
This commit greatly improves the performance by ensuring that, when
computing the set of nodes we want to consider for AVI, we do not
traverse the dispatcher.

Doing so, means including *a lot* of irrelevant nodes and wasting a lot
of computation, since the CFG usually is not influenced by stuff
happening before an indirect jump.

In at least a situation the speedup is in the order of 20x, however this
depends on the size of the binary, since traversing the dispatcher means
including all the binary in the computations (as opposed to just the set
of blocks involved in the dataflow to compute a certain expression).
2021-04-22 18:05:39 +02:00
Alessandro Di Federico 9171452342 Test instantiation of passes in new pass manager 2021-03-16 11:55:58 +01:00
Alessandro Di Federico 47e34bf897 Make MutableSet copiable
We were using a `std::map<const key_t, value_t>` as internal storage,
which was not copiable. This commit drops the `const`.
2021-03-06 16:56:25 +01:00
Alessandro Di Federico 82605514c4 model: prepare for ABI information
This commit also drops some dead code and fixes Model tests accordingly.
2021-02-19 09:39:49 +01:00
Alessandro Di Federico 49287e9de7 Improve Model and TupleTree
This commit:

* Drops `KeyTraits::toString`: if needed, use `getNameFromYAMLScalar`.
* Makes many methods in TupleTree.h return `nullptr` or `std::optional`
  in order to gracefully handle failures.
* Provides `KeyTraits` specializations for integral types and tuple-like
  composed by types providing `KeyTraits`.
* Introduces `CompositeScalar`, which enables tuple-like objects to be
  YAML-serializable scalars by joining the YAML-serialization of its
  members through a customziable character.
* Implements `PathMatcher`, a very simple "regular expression" mechanism
  for paths on tuple trees.
* Introduce testing for the Model.
2021-02-17 11:48:46 +01:00
Alessandro Di Federico 6e6483b5eb Whitespace changes 2021-02-17 11:44:41 +01:00
Pietro Fezzardi 8ffcd49dd2 RecursiveCoroutine: fix reference arguments
Before this commit, recursive coroutines did not work properly if they
had out arguments with reference type.
The reason is that `rc_run` was inferring the type of its arguments from
the arguments themselves, not from the prototype of the recursive
coroutine.

Hence, code snippets like the following did not work properly, because
`rc_run` was taking x by value, not by reference.

```
RecursiveCoroutine<void> accumulate_on_i(int &i) {
  // ...
}

int f() {
  int x = 0;
  rc_run(accumulate_on_i, x);
  return x;
}
```

This commit fixes the problem. Now the arguments of `rc_run` are
properly forwarded to the recursive coroutine.
2021-02-17 11:37:00 +01:00
Alain Carlucci 8e275ed957 ADT: Add SerializableGraph 2021-02-09 22:44:01 +01:00
Alessandro Di Federico 4982ba6922 KeyedObjectContainers: ensure serializability
This commit fixes a couple of bugs preventing SortedVector and
MutableSet from being serialized.
Also, it introduces minimal testing for serialization.
2021-01-28 17:45:14 +01:00
Massimo Fioravanti 8ba9930638 Invert inheritance of GenericGraph nodes
GenericGraphs no longer require CRTP.
2021-01-27 19:46:53 +01:00
Alessandro Di Federico 28cb935d39 ZipMapIterator: handle dishomogeneous containers
ZipMapIterator can now handle containers of different type, as long as
their keys are comparable.
2021-01-27 19:46:52 +01:00
Alessandro Di Federico 8aab914037 Import MutableSet and SortedVector
These data structures are substitutes for a `std::map<Key, Value>` where
`Key` is embedded in `Value`. Their main goal is to be serializable in a
YAML sequence while preserving the order enforced by the key.

`MutableSet` is implemented using a map.
`SortedVector` is implemented using a sorted vector.
2021-01-27 19:46:52 +01:00
Pietro Fezzardi e1b283b0b6 Add RecursiveCoroutine headers and tests
RecursiveCoroutines are a facility intended to be used as-drop in
replacement of recursive functions.

They provide the following features.
- They can be written almost as regular recursive functions,
  with 4 caveats.
  1. A recursive coroutine that returns a type `T`, needs to be declared
     to return a `RecursiveCoroutine<T>`.
  2. Inside the body of a recursive coroutine, when recursively calling
     another recursive coroutine, the recursive call needs to be
     prepended by the new keyword `rc_recur`.
  3. Inside the body of a recursive coroutine, the `return` statement
     needs to be substituted with `rc_return`.
  4. When launching a recursive coroutine `A` from a function that is
     not a recursive coroutine, `A` needs to be called with the provided
     dedicated template wrapper `rc_run`.
     The syntax is the following `rc_run(A, arg0, arg1, ...)`.
     This is necessary to enable swapping off recursive coroutine and
     fall back to regular recursion for debug.
     See below for how to do it.
- Unlike regular recursive functions, they don't use the system stack
  for recursion. They use a custom heap-allocated stack to manage
  recursion. This makes them more robust for implementing recursive
  functions that manipulate user-defined input, because they are much
  less likely to trigger stack overflow.
- They can be turned off compiling with
  `-DDISABLE_RECURSIVE_COROUTINES`, falling back to regular recursion,
  for debug purposes.
- They support both direct and indirect recursion, i.e. a recursive
  coroutine A can recursively call itself, or it can recursively call
  another recursive coroutine B, which in turns recursively calls A.
2020-12-29 16:15:31 +01:00
Alessandro Di Federico c6d0ce9dec Don't use RPOT for DisjointRanges
Sorting the BasicBlocks on which DisjointRanges works is detrimental for
performance.  Using a random order takes less time. This is due to the
fact that the number of BasicBlocks to analyze is significantly smaller
than the whole list of BasicBlocks.
2020-11-23 14:52:46 +01:00
Pietro Fezzardi cd9bc34d9d Enforce new include conventions 2020-11-13 10:00:24 +01:00
Alessandro Di Federico d72f69c975 Import GenericGraph
This commit imports `GenericGraph`, its tests and fixes some related
issues in `FilteredGraphTraits`.
2020-10-21 10:34:01 +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 49b3c4b2c9 Upgrade to LLVM 10 2020-06-13 10:36:08 +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
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 149ef61759 Fix unit tests linking
For unit tests we used to call `add_executable` directly. However, this
prevents using RPATH as appropriate.
2020-05-14 11:59:05 +02:00
Alessandro Di Federico 8deab9c7ea Whitespace and other minor changes
* Drop unused argument names from function prototypes
* Make `static` some methods
* Disable some copy constructors
* Fix casing of Doxygen `\file` directives
* Add some casts to make the compiler happy
* Initialize `hasRelocationAddend` for AArch64
* Use references in range-for where possible
* Drop default for `switch` statements covering all the entries of an `enum`
* Make some global variables `static`
* Drop dead functions
2020-05-14 11:58:18 +02:00