Commit Graph

987 Commits

Author SHA1 Message Date
Alessandro Di Federico 98c99e9406 Make StackAnalysis::getClobbered const 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 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 d4b8fe847d GCBI: use getBlockType in isTranslated 2018-12-13 18:03:11 +01:00
Alessandro Di Federico a43fad370f GCBI: introduce the EntryPoint BlockType
`getType` didn't have a `BlockType` to represent the entry basic block
of the `root` function. Therefore, such basic block was erroneously
identified as a translated basic block.
2018-12-13 18:03:11 +01:00
Alessandro Di Federico 4f64816ac3 GCBI::getFunctionCall: skip markers
`GCBI::getFunctionCall` used to stop to the first marker function call,
instead of going through all of them looking for `function_call`.
2018-12-13 18:03:11 +01:00
Alessandro Di Federico 0c9945c2d0 Introduce QuickMetadata::get() 2018-12-13 18:03:11 +01:00
Alessandro Di Federico bba5bdf4fb Use std::iterator_traits in IteratorWrapper
Using `std::iterator_traits` allows `IteratorWrapper` to be employed on
pointers too.
2018-12-13 18:03:11 +01:00
Alessandro Di Federico 371c38d6b8 Add nodce to the list of marker functions 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 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 6748032643 Extend FCI interface to identify function calls 2018-11-14 14:41:25 +01:00
Alessandro Di Federico 9606c8df35 QMD: add 64 bits ints 2018-11-14 09:34:49 +01:00
Alessandro Di Federico 09b9fbba39 Drop trailing semi-colon in messageless assertions 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 b34a421ec4 getResetColors: return nullptr when appropriate
A method in RDA was returning nullptr when a basic block *had* a color
and a dangling reference when it did not.
2018-10-24 17:21:57 +02: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 b6ee8480da Extend MonotoneFrameworkSet
This commit simply adds a couple of handy methods to
`MonotoneFrameworkSet` such as `begin`, `end`, `erase`, `erase_if`,
`contains` and `size`.
2018-10-16 16:55:12 +02:00
Alessandro Di Federico f305541d5e Introduce MonotoneFramework::handleEdge
In a `MonotoneFramework` it is sometimes necessary to change the
information propagated on a branch w.r.t. another branch.

This commit introduces the `handleEdge` function that allows
`MonotoneFramework` implementors to modify the `LatticeElement` produced
by `transfer`.
2018-10-16 16:52:24 +02:00
Alessandro Di Federico 873dd13dd5 Introduce dumpModule
`dumpModule` is a debug function that can be called from GDB to dump a
`Module *` to a chosen path.
2018-10-16 16:51:52 +02:00
Alessandro Di Federico e80b05a48e Move MonotoneFramework.h to libSupport
`MonotoneFramework.h` has been moved into `include/revng/Support` so
that it can be employed by components outside `libStackAnalysis`.
2018-10-16 16:25:29 +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 cf8d6d530e Whitespaces and other minor fixes 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 386492e8fe Fix definition of ID for templated passes
`FunctionPass` has a static field `ID`. In templated passes, this needs
to be declared in the header file and defined in a `.cpp` file.

This does this, the right way.
2018-09-29 16:50:36 +02:00
Alessandro Di Federico e74ee1431d Enforce struct/class usage coherency 2018-09-29 13:05:16 +02:00
Alessandro Di Federico f819962527 Switch to new assertion system globally
This commit enforces on the whole project the usage of our own assertion
system. This means all calls to `abort`, `assert` and `llvm_unreachable`
have been replaced with calls to `revng_abort`, `revng_assert` and
`revng_unreachable`, respectively.

The error messages, usually expressed as `assert(Condition &&
"Message")` have now been replaced using the second (optional) argument
of `revng_assert`.

Additionally, all the `assert(false)` statements have been replaced with
calls to `revng_abort`. Apart from readibility, this ensures the
compilers is aware of the fact that call will never return.

This change will enable us to drop many statements whose sole purpose
was marking a variable employed in an assertion as used in release
mode. In fact, with the new assertion system this is no longer
necessary.
2018-09-29 13:05:16 +02:00
Alessandro Di Federico e053b215d8 Drop _ prefix in include guards
We used to have a `_` prefix for include guards macros, however,
according to the standard, macros starting with an underscore are
reserved. This commit drops them all.
2018-09-26 08:59:59 +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 384c317ef1 Introduce using to increase readibility
This commit introduces `using` statements and `constexpr` functions to
increase readibility of various types.
2018-09-21 20:05:18 +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