Commit Graph

356 Commits

Author SHA1 Message Date
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
Andrea Gussoni 616c162523 DotGraph and DotNode
This commit implements a simple wrapper class able to parse a GraphViz
file in an object implementing the LLVM `GraphTraits`.
2019-04-22 05:40:27 +02:00
Alessandro Di Federico dda91e8c90 ClassSentinel prevent test failures
`ClassSentinel` makes use of an undefined behavior to check if an object
has been destroyed. Disable this check in case of presence of address
sanitizer or even regular optimizations.
2019-04-04 22:58:21 +02:00
Alessandro Di Federico 63f0efbada Temporarily disable OSRA-related failing tests 2019-03-08 15:05:10 +01:00
Alessandro Di Federico 5904e78bdb Disable exceptions 2019-03-08 15:00:59 +01:00
Alessandro Di Federico 5dc8056b8c Introduce enforce-abi pass
This commit introduces the `enforce-abi` pass, which consumes the
information provided by the ABI analysis and enforces them in the
isolated functions adding actual arguments.

This commit also rewrites the logic of `ResultsPool::finalize` and
changes the semantic of `Yes` statements on arguments to `YesOrDead`.
2019-03-08 15:00:59 +01:00
Alessandro Di Federico 0fa2d79fe4 Introduce ZipMapIterator
`ZipMapIterator` allows you to iterate in parallel over two
`std::map`-like containers.

In the ABI analysis, this allows us to be much more efficient. In
practice, if we have two maps with M and N elements, we pass from
performing N*log(N) + M*log(M) queries to the size of the union of the
set of keys of the two maps.
2019-03-06 10:31:23 +01:00
Alessandro Di Federico 103df1e46c Backward BFSVisitor: include starting instruction
The `BFSVisitorBase` can go forward and backward starting from a certain
instruction. When going backward, it used to skip the starting
instruction.

For simmetry purposes, this commit changes that.
2019-03-06 10:31:22 +01:00
Alessandro Di Federico 45172f52d9 LazySmallBitVector: introduce operator<
`LazySmallBitVector` was lacking a comparison operator, which prevented
it from being used as the key of a `std::map`.

This commit implements such operator, along with the `reserve` method.
2019-03-06 09:04:58 +01:00
Pietro Fezzardi 33a8aeb64c MonotoneFramework: drop greaterThan from Lattices
All the definitions of `greaterThan` were `!lowerThanOrEqual`, and all
the uses were implicitly assuming this semantic.
However, this was confusing because in a Lattice the ordering is not
total, hence `!lowerThanOrEqual` is not equivalent to `greaterThan`.

This commit drops the `greaterThan` method altogether to avoid
confusion.
2019-03-06 09:04:58 +01:00
Alessandro Di Federico 53db84f7d6 s/revamb/revng/g 2019-02-11 16:09:23 +01:00
Alessandro Di Federico 2e241acae3 Introduce SA-based ABIDetection and FBD passes
This commit drops the old FunctionBoundariesDetectionPass and introduces
a new one based on the results provided by the StackAnalysis. A very
similar pass, the ABIDetectionPass, is now available to offer the
results of the ABI analysis too.

These two new passes are a thin shim depending on the appropriate
version of the StackAnalysis (with or withour ABI anlysis) and simply
call `serializeMetadata`, which decorates the LLVM IR with the requested
information.

In addition to drop the old analysis, this commit also isolates the
function boundaries detection pass from `revamb` making it available as
a library only.
2019-01-18 15:18:47 +01:00
Alessandro Di Federico 7a045d0c0d Drop revamb-dump in favor of plain passes
This commit does the following:

* It drops `revamb-dump` and transforms all the passes it featured in
  passes that can be used directly from `opt`.
* It rename `revamb` to `revng-lift`.
* It introduces a script called `revng` which acts as a driver for the
  whole rev.ng project. It replaces `translate`, `revcc`,
  `csv-to-ld-options` and `revamb-dump`, since it offers an `opt`
  subcommand which allows to easily invoke all the analysis passes.
* It makes the project a CMake package that can be easily used
  externally.
* It allows to easily create libraries of analysis to use through
  `revng-opt`.
2019-01-18 15:18:47 +01:00
Alessandro Di Federico 14476a354c Fix function isolation test dependencies 2019-01-18 15:18:47 +01:00
Alessandro Di Federico e9b4b8edf1 Use stack analysis in RDA
This commit lets the reaching definitions analysis employ results from
the stack analysis to propagate definitions across functions
calls. Specifically, the stack analysis provides a list of registers
that might be clobbered by the callee: definitions concerning those are
not propagated, all the others are propagated.

This change is key to detect jump tables whose address has been
materialized *before* a function call. A test for such situation has
been introduced.

To make this work, the RDA now works over the CFG provided by the
function identification analysis.
2019-01-18 15:18:47 +01:00
Alessandro Di Federico bd09716534 FCI: provide a custom CFG
The `FunctionCallIdentification` analysis now provides a custom view on
the CFG where 1) dispatcher-related basic blocks are absent, 2) nodes
performing functions calls have an edge to their return address and 3)
nodes ending with a return instruction have no successor.

This CFG is now employed by the reaching definitions analysis and OSRA.

Additionally, the implementation of the `visitSuccessors` and
`visitPredecessors` method has been reviewed. It now consists in a class
that needs to be inherited and for which two methods should be
implemented, one to perform the visit of a block and another one to
enumerate the successors.

In addition, all the users of `visitSuccessors`/`visitPredecessors` have
been updated, a simple set of tests has been introduced and
`GeneratedCodeBasicInfo::visitPredecessors` has been dropped.
2019-01-18 15:18:46 +01:00
Alessandro Di Federico 7ead8d68cc Collect simple literals (return addresses) as JTs
This commit fixes a problem that led to use SET to discover very very
simple jump targets: the return addresses of functions call.

Since in this situation, for each call, we needed to run SET, this
commit leads to a *huge* improvements in terms of translation
performance.

This commit also enforces renaming of the translated basic blocks after
they get split and update the ground truth for several analysis tests.
2018-12-17 08:15:45 +01:00
Alessandro Di Federico 9ce805415b Improve Reaching Definitions Analysis
The Reaching Definitions Analysis used to ignore all the memory access
that were not relative to a CSV or an `alloca`. In certain situations,
in particular in x86 which makes heavy use of the stack, this led to
miss certain links that were vital for a correct identification of
certain jump targets.

As an example consider the following example:

    cmp    DWORD PTR [rbx+0x8],0x5
    ja     4bc5c8 <uw_update_context_1+0x148>
    mov    eax,DWORD PTR [rbx+0x8]
    movsxd rax,DWORD PTR [r12+rax*4]
    add    rax,r12
    jmp    rax

The constaint on `rbx+0x8` is not propagated to the use after the jump,
due to a missing link.

This commit fixes this by tracking all the memory accesses within the
expressive power of the `MemoryAccess` class, in particular those
expressed as register plus offset.

Additionally, this commit also makes RDA consider as reaching
definitions for a `load` only those definitions that match exactly the
load address, while previously we were considering all the `mayAlias`
definitions. This situation, in combination with the previous change,
led to have paths with multiple reaching definitions, which was
problematic for the path sensitive merge.

Finally, we consider a definition to be clobbered only if there's an
exact store to the esame address, instead of a store on an aliasing
address.
2018-12-17 08:15:45 +01:00
Alessandro Di Federico ef2d16db15 Install headers and libraries 2018-12-15 08:34:36 +01:00
Alessandro Di Federico 655f25fdff Factor out code for generating modules in tests 2018-12-13 18:03:11 +01:00
Alessandro Di Federico abb47bb964 Minor changes 2018-11-15 08:48:26 +01:00
Alessandro Di Federico bc0de2c88f Fix tests due to changes in QEMU
In QEMU we should suppress the emission of the debug_insn
pseudo-instruction (which delimits the tiny code instructions
corresponding to an original input instruction) in case of a delay slot.

However, this was not happening due to a wrong `#ifdef`. Since this has
now been fixed in QEMU, this commit updates the results of the tests
accordingly.
2018-11-14 09:34:49 +01:00
Pietro Fezzardi b9273210d0 Update to LLVM 7
Updating to LLVM 7 mainly involved the following steps:

* Upgrade APIs for folding ConstantExpr.
* Upgrade APIs for GraphTraits.
* Upgrade APIs for DominatorTreeBase.
* Upgrade APIs for BinaryFormat to parse ELFs.
* Fix the LLVM Linker to properly link the QEMU helpers.
* Disable the new optnone attribute even with optimization -O0. This is
  necessary to allow SROA to do its job properly.
* Upgrade APIs to delete Instructions.
* Properly cleaning up orphaned metadata still referring to Instructions
  that have been destroyed. Recent versions of LLVM are more strict in
  this respect, and will assert when compiled in debug.
* Avoid using LLVM `getGlobalContext` which has been removed from newer
  versions of LLVM.
* Upgrade tests to use the new APIs.
* Upgrade APIs for instruction iterators and reverse iterators.
2018-11-13 18:11:05 +01:00
Alessandro Di Federico dee2cf0d04 Reimplement the reaching definition analyses
This commit reimplements the (conditional) reaching definitions passes
as an instance of a monotone framework.

The `ConditionNumberingPass` has also been reworked in the way it
exposes its results, but it's otherwise unchanged.

A proper unit testing framework is also available to ensure everything
works as supposed to.
2018-10-16 17:39:22 +02:00
Alessandro Di Federico 8348766b4e Make stack analysis' output more deterministic
In stack analysis' output, the list of basic blocks composing a function
was not sorted. This lead a test to fail due to the presence of the
`--order` flag when comparing the output.

This commit ensures that this list is ordered, by basic block name.
2018-10-03 23:11:13 +02:00
Alessandro Di Federico cc02713f6d Abandon argparse in favor of LLVM's CommandLine
This commit dismisses the `argparse` library (the only non-runtime C
component of rev.ng) in favor of LLVM's CommandLine library, which
offers several benefits. Among others, now command line arguments can be
easily specified as a global variable, decentralizing their management
and avoiding the long list of arguments in the constructor of singleton
objects such as `CodeGenerator`.
2018-10-03 23:11:13 +02:00
Alessandro Di Federico cfba8372cf Remove extra --debug-symbols in tests invocation 2018-10-03 23:11:12 +02:00
Alessandro Di Federico 076aeac7f3 Move and rename all files
This commit moves around most files. The new directory structure is as
follows:

* `lib/$LIBRARY/`: contains a library, i.e., a set of `.cpp` files used
  by multiple libraries/tools.
* `include/revng/$LIBRARY/`: contains the public headers associated to
  the library in `lib/$LIBRARY/`.
* `tools/$TOOL/`: directory where all the `.cpp` files (and private
  headers) for a tool reside. Currently we have two tools: `revamb` and
  `revamb-dump`.

On top of this, all file names are now in camel case.
2018-10-03 23:11:12 +02:00
Alessandro Di Federico 6bb7f4e8f1 Declare prototype of non-static functions
Certain non-`static` functions were missing prototype declarations,
triggering a compiler warning.

This was due to a missing header or due to a bug in boost.

This commit resolves this situation.
2018-09-29 13:05:16 +02:00
Alessandro Di Federico 047ae0d4d8 Apply clang-format globally
This commit applies our `clang-format` rules globally. From now on, all
commits should respect our configuration file.

Pretty large change.
2018-09-21 20:08:45 +02:00
Alessandro Di Federico 960286f419 Reorder Boost includes
Include directives are groups by library, the groups should be sorted
from the most general (i.e., the STL) to the most specific (the local
includes).

This commit ensures that Boost includes are before LLVM includes.
2018-09-21 20:08:23 +02:00
Alessandro Di Federico 31e5d1c96f Add braces around else
Sometimes the true-branch of an `if` statement was using braces but the
false-branch was not. This commit fixes this.
2018-09-21 20:05:18 +02:00
Alessandro Di Federico 5513ae606c Force the text segment at 0x20000 on ARM
For a long time we had an issue on ARM: the linker would use as the
first page 0x10000. However, on many distros, that matches the first
page that can be mapped (see `/proc/sys/vm/mmap_min_addr`). Therefore,
this shouldn't be a problem, except the fact that the translated program
also needs the preceeding page for the (outer) ELF header.

We used to suggest users to run:

    echo 4096 | sudo tee /proc/sys/vm/mmap_min_addr

Now in our tests, we force the text segment page to be at 0x20000,
therefore, this will no longer be necessary.
2018-09-21 17:27:22 +02:00
Andrea Gussoni 500d77f43e Register and add among JT reasons FunctionSymbol
The symbol handling has been extended to register whether a symbol
represents a function or not. This information is then used to register,
during the global data harvesting phase, all the function symbols and
explicitly mark them through the "FunctionSymbol" `JTReason`.

We use this information during the CFEP harvesting phase to integrate
the information produced by the function boundaries detection with
potential unidentified CFEPs.

This option can be enabled with the `--use-debug-symbols`, which
supersedes `--use-sections`.
2018-09-20 17:52:10 +02:00
Alessandro Di Federico 1aa65aa211 Fix trivial bug in test_stackanalysis 2018-09-19 19:59:10 +02:00
Alessandro Di Federico 7fe00c08dd Rewrite the stack and introduce the ABI analyses
This is a very large commit importing the reviewed (and heavily
simplified) stack analysis and the new ABI analysis, which provides
information on the calling convention of each function and so on.

For an overview of the new analyses please consult OVERVIEW.md.
2018-09-18 15:58:20 +02:00
Alessandro Di Federico fb7ad64070 CMake: one argument per line
This commit simply reduces the length of lines in CMake by splitting the
statements over multiple lines. This is particularly useful when listing
the translation units composing a program/library. In fact, it makes
merge much easier.
2018-08-31 09:00:33 +02:00
Alessandro Di Federico 6b39f031e1 Generate as much debug info as possible in tests 2018-08-31 08:42:31 +02:00
Alessandro Di Federico a0f4e0bb41 Introduce new assertion framework
A set of assertion-related functions has been introduced:

* `revng_abort(message)`: aborts, in release builds too.
* `revng_check(what, message)`: asserts `what`, in release builds
  too. Also emits a `__builtin_assume`, that can lead to additional
  optimizations in clang.
* `revng_unreahcable(message)`: identical to `revng_abort`, but in
  release builds emits `__built_unreachable`.
* `revng_assert(what, message)`: asserts in debug builds, otherwise
  emits `sizeof(what)` (to suppress unused variable warnings) and
  `__builtin_assume`.

The adoption of these function has the following benefits:

* Nice stack traces.
* The developer can choose to enforce an `assert` (or an `unreachable`)
  at release-time too by using `check`/`abort`.
* Most warnings about unused variables in release mode should be gone.
* When using clang, the `assert`s become `assume`s, which might enable
  additional optimizations (with no run-time costs).
* The `assert(Condition && "Reason")` trick is no longer needed, we now
  have a proper argument.
2018-08-18 16:25:40 +02:00