400 Commits

Author SHA1 Message Date
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 05b1833ee6 Add ExternalJumpsHandlerBlock to BlockType 2019-01-18 15:18:47 +01:00
Alessandro Di Federico ef708e9912 Let --debug-log work without main involvement 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
Pietro Fezzardi dbb25bef2c Apply information about CSV aliasing
This commit introduces alias information to state that memory accesses
relative to CSVs do not alias memory accesses of the original program.
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 8877946be3 Handle codeless programs
Programs without code (e.g., no executable segment) led to miss the
`env` variable, making the `CpuLoopExitPass` fail. This commit, fixes
the problem by simply populating the `cpu_loop_exit` function with a
`ret`.
2018-12-15 08:34:36 +01:00
Alessandro Di Federico ac5dea43b4 Reduce exceptions thrown (e.g., due to tail calls)
In function isolation, every time we met a jump to an unexpected basic
block (i.e., a basic block that is not part of the current function), we
used to throw an exception. However this is unnecessary since oftentimes
it is sufficient to call the `function_dispatcher` or even perform a
regular function call.

The most obvious example is the case of a direct tail call. In this
situation performing a function call to the corresponding isolated
function is the most appopriate thing to do.
2018-12-15 08:34:36 +01:00
Alessandro Di Federico 2003b5c79f Being a callee is more important than being read
We used to black list memory portions target of memory read, so that
they couldn't become function entry points. However, this led to false
positives, in particular with functions that are explicitly called.

This commit ensures that we black list those addresses only if they are
not targets of function calls.
2018-12-13 18:03:11 +01:00
Andrea Gussoni af6f963d77 Improve exception handling
When optimizing a module to which function isolation has been applied the
`prune-eh` pass lead to several issues, specifically:

* `support.c` is now compiled with support for exceptions, to prevent
  `raise_exception_helper` from being marked `nounwind` during the
  link phase.
* Added a fake `ret` at the end of the `catchblock` to avoid promotion
  of `invoke`s to regular `call`s.
* Marked the `invoke` instructions as `noinline`.
2018-12-13 18:03:11 +01:00
Alessandro Di Federico 9d13ce343d OSRA: handle computations on constants
This commit fixes an issue in OSRA with computations on constants. If a
constant was added to another constant, a new constant bounded value
would be created. However, such bounded value wouldn't get propagated
further. This commit fixes the problem by creating an OSRA relative to
the original constant plus an offset.
2018-12-13 18:03:11 +01:00
Alessandro Di Federico ecfb842073 Force FCI during basic block harvesting
This commit forces the function call identification analysis during
harvesting of new basic blocks. Additionally, the appropriate jump
target reasons are associated to the involved basic blocks.
2018-12-13 18:03:11 +01:00
Alessandro Di Federico 2669d78206 Add some dump methods 2018-12-13 18:03:11 +01:00
Alessandro Di Federico 5cc504e117 Whitespace and other minor changes 2018-12-13 18:03:11 +01:00
Alessandro Di Federico f2dd01cea2 Handle [p_filesz, p_memsz] segment portion
`BinaryFile::readRawValue` scans the segment list to identify which
segment contains a certain address. However, it was failing if the
target address was in `.bss`, i.e., the portion of a segment after
`p_filesz` but `before `p_memsz`.

This commit lets `BinaryFile::readRawValue` return 0 in that situation.
2018-11-30 17:47:03 +01:00
Alessandro Di Federico 823f277d2d Do not assert on calls targeting multiple symbols 2018-11-30 17:47:03 +01:00
Alessandro Di Federico 90d2df3cca Mark dynamic function calls in isolated code too 2018-11-30 17:42:33 +01:00
Andrea Gussoni ffa035fc99 Detect invalid fallthrough after helper
Fix for a situation where the fallthrough basic block of an instruction
calling a helper function is not in an executable segment and therefore
not created.
2018-11-29 16:02:10 +01:00
Andrea Gussoni ce22b9c496 Fix SET interval overflow
Quick fix to detect overflow in SET interval computation.
2018-11-29 16:02:10 +01:00
Alessandro Di Federico be7ac56f07 Purge orphan basic blocks only when harvesting
This commit fixes a huge performance issue due to performing a orphan
basic block cleanup every time `JumpTargetManager::peek` was called
instead of only when actual harvesting was required.
2018-11-29 16:02:10 +01:00
Andrea Gussoni 3663f574e8 Use new module when isolating functions
Now using the `root` function of the cloned module as a starting point
for the isolation process.

In this way we can ignore the old module, and in particular we can
drop the `ModuleCloningVMap`, a giant map that was used to keep the
match between old and new global objects and was used in the instruction
cloning phase.

Also changed the creation of the trampoline for the isolated function,
using a new basic block and later purging all the unreachable basic
blocks in the `root` function.
2018-11-29 16:02:10 +01:00
Alessandro Di Federico e21eed118c Tag function_call targeting external symbols
This commit uses SET, information about canonical values and labels to
detect if an indirect function call is targeting an external symbol.

The strings used for the name of external symbols are uniqued global
variables. This commit also uses this approach for the disassembly of
original instructions, which used to be metadata.
2018-11-15 16:03:09 +01:00
Alessandro Di Federico abb47bb964 Minor changes 2018-11-15 08:48:26 +01:00
Alessandro Di Federico cc4dfbce4c Introduce labels, relocation and canonical values
So far we've been tracking only base-relative relocations in an ad-hoc
fashion. This commit introduces a data structure that can describe the
most common relocations, including those for `.got`, `.got.plt`,
base-relative and `R_*_COPY`.

A label describes a range of the binary. A label can be generated from a
symbol (basically assigning a name to range of the binary) or from a
relocation, describing the content of a certain range.

This commit generates labels from symbols and relocations, including
MIPS implicit relocations.

This commit also introduces canonical values.

A register can have a canonical value, i.e., a value that register will
assume when the analyzed module is being run. This is typically useful
for the value of the global pointer, which is different from one module
to another but, within a module, is stable.

This commit registers the canonical value of `gp` (in MIPS), if
available.
2018-11-15 08:48:26 +01:00
Alessandro Di Federico fc72f95f70 Ignore non-executable segments in segments_count
`segments_count` provides a way for the runtime to know how many
executable segments the original program had. This is used to implement
the `is_executable` function.

While the `segment_boundaries` contained only the executable segments,
`segments_count` included non-executable segments too, leading to an
out-of-bound read which sometimes led to a spurious `Unknown PC` error.
2018-11-14 09:34:49 +01:00
Alessandro Di Federico 979111aa65 Improve handling of undef in OSRA 2018-11-14 09:34:49 +01:00
Alessandro Di Federico 3a4d994d16 Fix disassembly (for delay slots and other stuff) 2018-11-14 09:34:49 +01:00
Alessandro Di Federico abce8cea14 Backport to QMD: add 64 bits ints 2018-11-14 09:34:49 +01:00
Alessandro Di Federico 3ccc0d666d Do not fail upon meeting a ToPurge basic block
While translating the code, it might happen that a basic block needs to
be splitted and the second part to be revisited. In such cases, the
second part is register for being "purged" at the next iteration.

Translation failed if we met such a basic block before purging. This
commit correctly handles such situations.
2018-11-14 09:34:49 +01:00
Alessandro Di Federico d0100ae12c OSRA: ignore undef 2018-11-14 09:34:49 +01:00
Alessandro Di Federico 1b171f6c1c CPUSAA: do nothing if env is unused 2018-11-14 09:34:49 +01:00
Pietro Fezzardi 67daef6e70 CPUStateAccessAnalysis: handle more instructions 2018-11-14 09:34:49 +01:00
Alessandro Di Federico c950294c1e Do use PT_DYNAMIC
We used to check if the address associated to the `PT_DYNAMIC` program
header matched the one of the `.dynamic` section. However, we were not
recording it, which is required in case sections headers are
missing/corrupt.
2018-11-14 09:34:49 +01:00
Alessandro Di Federico 7fab462593 Don't fail if section headers are corrupt 2018-11-14 09:34:49 +01:00
Alessandro Di Federico 37fb3d6e56 Introduce support for little endian MIPS 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 4538d520a6 SET: fix use after free in assertion
An `assert` used to check the type of a deleted object. This commit
delays the deletion of such object.
2018-10-16 16:59:08 +02:00
Alessandro Di Federico 1c5bb1a84c Whitespace and other minor changes 2018-10-16 16:58:57 +02:00
Alessandro Di Federico 5872dc1ffc Handle top in BoundedValue::setSignedness
In case of a top `BoundedValue` which appears to be used with an
inconsistent signedness, simply change the signedness and keep it to
top.
2018-10-16 16:57:53 +02:00
Alessandro Di Federico 826accaa0a OSRA: fix "It's already on the stack" message
This message used to be emitted unconditionally. It is now emitted only
as appropriate.
2018-10-16 16:57:07 +02:00
Alessandro Di Federico f4c5942d62 Introduce the registerjt logger
This commit introduces a new logger that prints out the name and reason
for each newly registered basic block.
2018-10-16 16:55:57 +02:00
Alessandro Di Federico a704926ddc Ensure blocks are always reachable in root
Through `JumpTargetManager::setCFGForm` the `root` function CFG can be
changed so that the `dispatcher` is minimized, i.e., it jumps only to
those basic blocks that would be otherwise unreachable. This allows us
to perform more accurate and simpler analyses.

To bring the function in this state we used to check if there was at
least a non-dispatcher predecessor, however this did not work with loops
reachable only from the dispatcher, since they had a predecessor, but
that didn't mean it was reachable from the entry.

This commit fixes the problem by navigating the CFG in reverse-post
order, registering all the reachable blocks and then restoring the edge
from the dispatcher to those that are not reachable.

Additionally:

* Basic blocks with no predecessors are now purged before
  `JumpTargetManager::harvest`.
* The `CFGForm` enum is now a namespace.
2018-10-16 16:26:35 +02:00
Alessandro Di Federico 81c003d997 Use MDBuilder to create alias.scope
This commit also fixes a bug due to some problem in how we were building
the self-referencing metadata associated to `alias.scope`.
2018-10-03 23:11:13 +02:00
Alessandro Di Federico 9dcefc8151 Add argument to InlineAsm function
`InlineAsm` instructions resemble function calls. You also have to
provide the prototype of the called function. Before this commit, we
were employing `void(void)`, which was wrong since we were passing in a
CSV.

In this commit we add a pointer argument to this prototype, which
prevents an assertion in LLVM from being triggered.
2018-10-03 23:11:13 +02:00
Alessandro Di Federico 648e4e5945 Fix assertion in function isolation
Update an assertion trying to enforce the fact that `alloca`s copied
from `root` where in the original entry block, while they should be in
the `dummy` entry block.

Additionally, an improvement has been introduced which ensures only one
`alloca` is copied per-function, while, before, we were creating a new
`alloca` for each use in that function.
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 43cf36bfce Introduce revng_log and abandon DBG(...)
This commit introduces `revng_log`, a macro analagous to `revng_assert`,
which basically allows to have the benefit of the `Logger` class without
having to compute the expression to log if the logger is disabled.

This commit also completely dismisses the `DBG` macro, converting all
the old code to `Logger` + `revng_log`.
2018-10-03 23:11:13 +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