Commit Graph

144 Commits

Author SHA1 Message Date
Alessandro Di Federico 27b58695a1 Let FunctionIsolation and EnforceABI use the Model 2021-02-19 09:39:49 +01:00
Alessandro Di Federico 3f0e715b98 Decrease verbosity of tests 2021-02-19 09:39:49 +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 a655507a0c Use relative paths during builds 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 6bfae0409b FunctionIsolation: drop isolate-no-safety-checks
This commit drops the `--isolate-no-safety-checks` flags since we
adopted a new approach later on in the decompilation pipeline, i.e.,
dropping calls to `raise_exception_helper` and running dead code
elimination.
2020-11-02 11:21:32 +01:00
Andrea Gussoni fac6b4d8ed Add artifacts with no dispatcher inline
Add artifacts for decompilation that do not inline the function
dispatcher during the enforceABI. Also, serialize as `.ll` all the
artifacts.
2020-10-30 14:17:57 +01:00
Alessandro Di Federico 2e995fdaa7 Pretty print JSONs 2020-10-22 11:25:31 +02:00
Alessandro Di Federico 078daef537 More robust StackAnalysis test reference results
We recently bumped the GCC version used for the x86-64 toolchain. The
newer version makes slightly different choices of instruction breaking
the names of basic blocks.

This commit drops them, since they are not really necessary: checking
the order is already more than enough.
2020-10-22 11:22:26 +02:00
Alessandro Di Federico 782eb09ffc Switch to produce bitcode where possible 2020-10-21 10:34:34 +02:00
Alessandro Di Federico 0e4c4aad59 Make --use-debug-symbols the default 2020-10-21 10:34:34 +02: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
Alessandro Di Federico 85ec2e2e05 Produce artifacts for decompilation 2020-09-04 23:54:26 +02:00
Alessandro Di Federico 270595632c Fix dependencies for revng-qa artifacts 2020-09-04 23:52:45 +02:00
Andrea Gussoni d48a15e607 Run revng translation test with function isolation
Re-enable the use of function isolation for the `translation` test
integrated in revng.
2020-08-03 22:11:18 +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 9401e33d3f Re-enable working tests
Some tests have been disabled in the past, but they work.
Specifically, this commit re-enables the `memset` and `fibonacci` tests.
The commit also describes why the test remaining disabled are so.
2020-06-02 21:14:57 +02:00
Alessandro Di Federico 99486d0b6b Update tests' references after new dispatcher 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 de172232e6 Run the most specific tests first 2020-05-14 11:59:05 +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 9e52b0c473 Switch ARM tests to Thumb 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
Alessandro Di Federico c1a768ff21 Drop InstructionTranslator::ForceNewPC
It was a leftover for a problem (marking post-helper addresses as jump
targets) that we appear to have solved in another way.
2020-03-02 12:38:01 +01:00
Pietro Fezzardi 6d5699c174 Unit Tests: replace revng_assert with revng_check
Calls to `revng_assert` are removed when compiling in release, calls to
`revng_check` are not.
This replacemente makes tests more robust in release.
2020-02-26 18:35:59 +01:00
Alessandro Di Federico 12d093b459 Rethink testing
This commit performs the changes necessary in order to integrate with
revng-qa, the new project for cross-project quality assurance.

Basically, the source code of all the tests has been moved in revng-qa,
which will take care of producing "artifacts" (i.e., compiled programs),
using the appropriate cross-compilers.

revng will then consume them and produce new artifacts to be consumed by
other tools down the pipeline.

The directory structure of the tests has been reworked to reflect
`revng-qa`. A large amount of boilerplate code has been dropped.

Note that certain actions, that used to be carried out during testing,
are now part of the regular build process. Specifically, lifting the
tests is performed at build time, so that they can be installed.
2020-02-20 12:16:56 +01:00
Alessandro Di Federico 0901fd7024 Reintroduce BOOST_TEST_DYN_LINK 2020-02-11 17:23:14 +01:00
Alessandro Di Federico ed00c19a12 Switch to the Boost CMake package 2019-11-24 22:52:23 +01:00
Alessandro Di Federico 72f9c633d4 Make ConstantRangeSet LLVM 9-compliant
A `ConstantRange` such as `[5,0)` was not handled correctly in
`ConstantRangeSet` due to a spurious 0 at the end of the range.

This commit also fixes the testing infrastructure that was not checking
the size of the range before making the comparison with the reference
vector.
2019-11-21 23:50:59 +01:00
Alessandro Di Federico 7b2744f0ab Register ModuleAnalysisManager in new PassManager 2019-11-21 23:35:42 +01:00
Alessandro Di Federico 8d664c1588 Fix RPATHs
This commit replicates the structure of the install directory into the
build directory in order to simplify the management of RPATHs.

This commit also drop `QEMU_INSTALL_PATH`.
2019-09-04 11:52:07 +02:00
Alessandro Di Federico 5009074e9e Introduce AdvancedValueInfo for JT discovery
* Introduce `ShrinkInstructionOperandsPass`: a transformation shrinking
  operands and the results of instructions if they are
  zero/sign-extended immediately before and after the instruction.
* Introduce `ConstantRangeSet`: similar to `ConstantRange` but allows
  disjoint ranges.
* Introduce `MaterializedValue`: a class that can represent a constant
  value or a symbol plus offset pair.
* Introduce `DropHelperCallsPass`: a transformation removing calls to
  helpers and replacing them with a function call reading the CSVs that
  the helper reads and writing the CSVs that the helper writes
  (according to CSAA).
* Introduce `DropRangeMetadataPass`: a transformation dropping the
  `range` metadata, which, in certain situations, lowers the quality of
  the results provided by `LazyValueInfo`.
* Introduce `AdvancedValueInfo`: an analysis exploiting results of
  `LazyValueInfo` but collecting them as `ConstantRangeSet` with a
  monotone framework. It produces `MaterializedValue`.
* Anticipate linking of helpers: `AVI` requires `CSAA`, which requires
  helper functions to be linked in.
* Drop `--no-link`.
* Force x86-64 `DataLayout`.
* Reorganize harvesting to either collect simple literals or go with
  (incremental) `AVI`.
* Drop `SET`, `OSRA`, the reaching definition analysis, the
  `SimplifyComparisonsPass` and all the sumjump-related code: e now
  clone `root`, optimize it and analyze it with `AVI`.
* Temporarily drop the `NoReturnAnalysis`.
* Link `libLLVMInstCombine`, `libLLVMCodeGen` and `libLLVMPasses`.
* Introduce tests for `AdvancedValueInfo`,
  `ShrinkInstructionOperandsPass` and `ConstantRangeSet`.
* Fix test results.
* Add `llvm.bswap.i64` and `@pc` to the LLVM template module for unit
  tests.
2019-05-22 21:30:29 +02:00
Alessandro Di Federico c8998cdece StackAnalysis: election of return SP value
Any stack pointer value greater than or equal to the original one used
to be OK for stack analysis to recognize an instruction as a
return. This commit changes this policy by collecting the value of the
stack pointer on all the return points and, at the end, elect a final
stack pointer value. All non-compliant returns are marked a
`BranchType::BrokenReturn`. The function is now considered fake only if
all the return instructions agree on a specific value of the stack
pointer, and it's lower than the original one.

* Drop `BranchType::IndirectTail`.
* `s/BranchType::FunctionSummary/BranchType::RegularFunction/`.
2019-05-22 21:30:29 +02:00
Alessandro Di Federico a9de053243 Introduce GraphAlgorithms
A series of algorithms working on `llvm::GraphTraits`.

* `nodesBetween` computes the set of nodes on all the paths from a node
  A to B.
* Factor out code to iterate over infinite loops into
  `exitless_scc_range`.
* Introduce unit tests.
2019-05-22 18:42:32 +02:00
Alessandro Di Federico 806108d34a Tag unit tests with the unit label
Now you can run them in a single shot with `ctest -L unit`.
2019-05-22 18:42:32 +02:00
Alessandro Di Federico 6ae3b6f22f Whitespace and other minor changes
* `GeneratedCodeBasicInfo::getCSVUsedByHelperCall` and
  `GeneratedCodeBasicInfo::extractCSVs`: make the call argument an
  `Instruction`.
* Introduce `blockByName`
* Introduce `getUniqueUser`.
* Fix linking issues.
2019-05-14 16:27:13 +02:00
Alessandro Di Federico feb06d180c Use revng --verbose in tests
This enables more informative debug logs.
2019-04-22 05:40:28 +02:00
Alessandro Di Federico 17eaaa1b0c Whitelist architectures in tests
We used to list all the architectures supported by QEMU in tests,
however this not optimal. This commit switches to a whitelist for the
list of architectures to tests so that we don't test architectures for
which we have a toolchain but aren't ready for the testsuite.
2019-04-22 05:40:28 +02:00