Commit Graph

6113 Commits

Author SHA1 Message Date
Alessandro Di Federico a7f1097988 Improve testsuite
* Add a label for runtime and analysis tests
* Add support for per-test custom compile flags
2016-12-04 00:28:57 +01:00
Alessandro Di Federico 3e77bb443f s/function boundaries/functions boundaries/ 2016-12-04 00:28:57 +01:00
Alessandro Di Federico d7c2ca7f7e General improvements on debugging information
* Don't dump entry point addres, not very interesting
* Handle `nullptr` in `getName`
2016-12-04 00:28:57 +01:00
Alessandro Di Federico f67f7aef77 Reorganize testsuite
So far the only tests we had were end to end tests to assess the
functionality of simple programs and, in particular, certain helper
functions. In the perspective of being able to test individual features,
and in particular check that we have no regressions in our analyses, we
isolated these end to end tests in the Runtime directory. We kept in the
root test directory the mechanism to compile a binary for a certain
architecture so that all the test types can use it.
2016-12-04 00:28:57 +01:00
Alessandro Di Federico 387f2c6688 Improve ConditionalReachingDefintionPass
This commit introduces the following feature in
`ConditionalReachingDefintionPass`:

* Propagation of conditions associated to branch instructions across
  basic blocks, unless a basic block defines them or the condition is
  being propagated by theh current branch.
* Before propagating a definition, sopress in it all the conditions
  defined in the target basic block.
* Before propagating a definition, force the condition being propagated
  by the current branch to be active in it and its opposite do be
  inactive.
2016-12-04 00:28:57 +01:00
Alessandro Di Federico ec12b5ec0d ConditionNumberingPass: track the defining BBs
`ConditionNumberingPass` now also keeps track of which basic blocks
define the value of a certain condition. This helps the conditional
reaching definition analysis to reset all the definitions associated to
that condition when they are propagated to a basic block which defines
that condition.
2016-12-04 00:28:57 +01:00
Alessandro Di Federico fe907a38b5 Enforce LHS >= 0 only in ULE and ULT comparisons
Fix a bug which lead to enforce that the left-hand side operand of an
unsigned greater than or greater than or equal comparison was <= 0. This
was the result of some intimate desire for symmetry in my mind which
does not actually exist.
2016-12-04 00:28:57 +01:00
Alessandro Di Federico 4add54fcde Make PSM debugging information more verbose 2016-12-04 00:28:57 +01:00
Alessandro Di Federico 85a39958d7 Increase maximum exploration depth in PSM to 10 2016-12-04 00:28:57 +01:00
Alessandro Di Federico 56d551f2c1 revamb-dump: add support for - for stdout
If an output path is `-`, consider it stdout.
2016-12-04 00:28:57 +01:00
Alessandro Di Federico b649681c21 CpuLoopExitPass: fix bug using a possible nullptr
Do not call `purgeNoReturn` on the `CpuLoopExit` function before
checking if the function has ever been created.
2016-12-04 00:28:57 +01:00
Alessandro Di Federico e7383f0662 Consider infinite loops as killer basic blocks
When in `NoFunctionCallsCFG` form it's easy to identify small infinite
loops (i.e., loops without exiting basic blocks), which are often used
to implement the last chance behavior of `abort` or `exit`
functions. Therefore, we include all the involved basic blocks as killer
BBs, which will participate in the computation of the final killer set.
2016-12-04 00:28:57 +01:00
Alessandro Di Federico df5bf548e2 Do not "purge" non-empty basic blocks
The `purgeBranch` function used to delete the target basic block of the
branch in case no predecessors survived, but this is not correct, in
particular if we already populated it, since we are risking to delete a
basic block already registered as a jump target.

This is probably only a partial solution, since we should check against
JTM if the basic block is registered, but this requires to move the
function in JTM.
2016-12-04 00:28:57 +01:00
Alessandro Di Federico 090366150a Backport CollectNoreturn::runOnFunction 2016-12-04 00:28:56 +01:00
Alessandro Di Federico d3d731596d Rework the noreturn detection
This commit improves the `NoreturnAnalysis` by inflating the set of
killer basic blocks using the set of basic blocks post-dominated by the
set of killer basic blocks. To do so, we temporarily replace the
successor of all the killer basic blocks with a single basic block (the
"sink") and then computed the set of basic blocks it post-dominates.

To improve the precision of our analysis we work on the CFG in
`NoFunctionCallsCFG` form, so we don't "infect" functions called by kill
basic blocks. However, since we work in this CFG form, we need to
manually collect the list of basic blocks calling a killer function and
compute the set of basic blocks they post-dominate.
2016-12-04 00:28:56 +01:00
Alessandro Di Federico 09e25267e7 Introduce the NoFunctionCallsCFG CFG form
`NoFunctionCallsCFG` is a form of the CFG where all the function call
edges are replaced with jumps to the return address. This is beneficial
in certain analysis to pretend we're working on a function-level.

To implement such a form of CFG we now emit right before the terminator
of each caller basic block a call to the "function_call" function
passing as the first parameter the callee basic block and as the second
one the return basic block. Using this function calls, switching to
`NoFunctionCallsCFG` and back becomes straightforward.
2016-12-04 00:28:56 +01:00
Alessandro Di Federico c579da6043 Add support to switch between different CFG forms
This commit introduces `JumpTargetManager::setCFGForm` which allows to
choose which type of CFG the user currently wants. The default and final
form should be `SemanticPreservingCFG`, which is the most conservative
one. However for certain analysis might be beneficial to have a reduced
CFG with almost no dispatcher (in particular for OSRA and SET).

This new function handles the switching between the two currently
available forms of CFG by changing the behavior of the `anyPC` and
`unexpectedPC` basic blocks and rebuilding the dispatcher as
appropriate.
2016-12-04 00:28:56 +01:00
Alessandro Di Federico 800ae6e717 Looking for function calls, consider delay slots 2016-12-04 00:28:56 +01:00
Alessandro Di Federico c069700bc5 Keep the CFG simple: do not jump to the dispatcher
Every time we don't know where an indirect jump can go, we used to emit
a jump to the dispatcher, however this complicates our analyses, in
particular the computed dominator tree provides less useful information
than it could.

This commit transforms all the jumps to the dispatcher into jumps to a
"anypc" basic block which during analysis just contains an unreachable
instruction, but during finalization this instruction is replaced with a
jump to the dispatcher. A similar (temporary) situation is for the
"unexpectepc" case.

This commit also makes the `visit(Sucessors|Predecessors)` functions
more idiomatic by employing a trait for black lists.
2016-12-04 00:28:56 +01:00
Alessandro Di Federico e577f74bfa Introduce revamb-dump
`revamb-dump` is a tool to extract various information from the LLVM IR
generated by `revamb` and output them in a more human-friendly format,
typically CSV. The main source of information are the various metadata.

Currently `revamb-dump` can collect the CFG, function boundaries and
`noreturn` functions.
2016-12-04 00:26:10 +01:00
Alessandro Di Federico 04ab209dde Leave calls to newpc in the final output
This commit leaves calls to `newpc` in the final IR even if tracing is
not enabled. The `newpc` function is internal and does nothing.
2016-12-03 08:46:12 +01:00
Alessandro Di Federico 0cf1d2b44a Associate to noreturn BBs a noreturn metadata 2016-12-03 08:46:12 +01:00
Alessandro Di Federico 5ca3200114 Update command line description of revamb 2016-12-03 08:46:12 +01:00
Alessandro Di Federico 786c809e6f Associate each BB with the functions it belongs to
Create a MDNode for each identified function and associate to the
terminator instruction of each basic block a list containing a reference
to the MDNodes identifying the functions it belongs to.
2016-12-03 08:46:12 +01:00
Alessandro Di Federico bc6a732ad7 Don't compute function boundaries by default 2016-12-03 08:46:12 +01:00
Alessandro Di Federico 4f60a23d9a JTM::readRawValue: fix endianess bug
`JumpTargetManager::readRawValue` used to take into account the
endianess information from `DataLayout`, i.e., the output endianess,
while the input endianess should be take into account.

The commit also checks that during final basic block finalization we
have no empty basic blocks.
2016-12-03 08:46:12 +01:00
Alessandro Di Federico 83ea2caacd Isolate ELF code and remove architecture parameter
This commit removes all the ELF-specific code from the `CodeGenerator`
class by creating a new class, `BinaryFile` which contains all the
information about the program that might be needed in an image format
independent way. However, `BinaryFile` has some fields which are
specific to ELF, we might want to address this when additional file
formats are supported.

A key benefit of isolating this code is that we can anticipate the
parsing of the input file, so that we have its architecture available
earlier than when `CodeGenerator` is instantiated, therefore we can drop
the `--architecture` parameter.
2016-12-03 08:46:12 +01:00
Alessandro Di Federico 4460770b07 Handle binaries without syscalls correctly 2016-12-03 08:46:12 +01:00
Alessandro Di Federico c50dcc5c5d Use symbols to produce meaningful names
This commit introduces the usage of symbols, if they are available. We
employ them to produce meaningful names for basic block names.

* Collect the symbols from `.symtab`/`.dynsym`
* Box the `Segments` into a new data structure (`BinaryInfo`) which also
  handles symbols.
* `JumpTargetManager::nameForAddress`: produce a meaningful name using
  symbols, if possible.
* Spread some `const`-ness
2016-09-28 00:03:13 +02:00
Alessandro Di Federico d48715494d Improve installation
* Use "$ORIGIN/../lib/" as RPATH when linking the installed binary
* Install also support material such as "support.c"
* Import the `translate` script for easy end-to-end translation
2016-09-22 22:44:16 +02:00
Alessandro Di Federico 59c871afc5 Make revamb portable
Add different search paths for QEMU components, in paritcular relative
to the program's path.
Also, install the revamb.
2016-09-22 18:45:59 +02:00
Alessandro Di Federico ccd5795d37 Remove wrong assertion related to forced BVs 2016-09-21 21:39:00 +02:00
Alessandro Di Federico 95cf77d3b3 Downgrade from C++14 to C++11 2016-09-21 04:50:17 +02:00
Alessandro Di Federico d01ee1f437 Copyright notices, license and credits 2016-09-21 01:45:26 +02:00
Alessandro Di Federico 53b1dfbb5d Improve autodetection of QEMU's location 2016-09-21 01:45:26 +02:00
Alessandro Di Federico b98c163c3e Implement the path function in support.c
The `path` function allows support.c to decide how to modify the path
opened by the translated program.
2016-09-21 01:45:26 +02:00
Alessandro Di Federico f0c12bfac4 Fixes to the testing infrastructure
* Disable PIE if enabled by default
* Link librt.so to compiled binaries (sometimes the QEMU runtime needs
  it)
* Replace `strtonum` with `int` in `awk` script
* Specify the compiler, not the triple
2016-09-21 01:45:26 +02:00
Alessandro Di Federico c7990ae60c Autodetect the compiler to use
Check in PATH if there's a compiler compatible with the supported ones
(i.e., using uclibc or musl) and use that triple.
2016-09-21 01:45:19 +02:00
Alessandro Di Federico 29879c8de2 Remove some dead code 2016-09-17 15:33:57 +02:00
Alessandro Di Federico adb45173ef Preserve user's CMAKE_CXX_FLAGS 2016-09-17 15:33:57 +02:00
Alessandro Di Federico 5af920a69d Enforce 80 columns 2016-09-17 15:33:57 +02:00
Alessandro Di Federico 4acae6beed Limit propagation of reaching definitions
This commit handles two cases related to function calls where we want to
limit the propagation of reaching definitions. In the first case down
through function calls, in the second case back up through return
instructions.

For the call instructions, we choose to stop the propagation of reaching
definitions to the callee, since we assume each function should check
its arguments if they affect the control-flow. In particular, this
allows a larger coverage of the function body in case, being able to
enumerate all the calls, we consider dead code those parts that, in the
current program would nevere be executed. Right now we do it in all
cases, it would be more appropriate to do this only if the address of
the function is taken. Also, we should expand this also for tail calls.

For what concerns return instructions, a function called from a lot of
different locations in the code receives a huge number of reaching
definitions. If its close to a no-op, it will also propagate most of
them through the return path. This is an hack to limit how such
definitions spread around the code.

A proper solution, requires to detect the calling convention and allow
to propagate along return paths only return values.
2016-09-17 15:33:57 +02:00
Alessandro Di Federico cc87ad607d Introduce NoreturnAnalysis
This commit introduces the `noreturn` analysis, whose aim is to detect
all the basic blocks the are doomed to lead to a `noreturn` syscall such
as `execve` or `exit`.

* Implement `NoreturnAnalysis`.
* Include and initialize in the `Architecture` data structure all the
  necessary information to detect `noreturn` syscalls. Specifically, the
  name of the QEMU helper for syscalls, the name of the register holding
  the syscall number and the syscall numbers representing `noreturn`
  syscalls.
* `ReachingDefinitionsPass`: make reaching definitions available both in
  reaching definitions mode and reached loads mode. This part needs
  further cleanup. We also might be willing to implement this with a
  `Boost.Bimap`.
* Use `SET` to collect information useful for the
  `NoreturnAnalysis`. Also restructure how the `OperationsStack` works
  to be more streamlined and keep track of multiple information about
  the instruction currently being tracked.
2016-09-17 15:33:57 +02:00
Alessandro Di Federico 37de0a0002 Introduce FunctionBoundariesDetectionPass
`FunctionBoundariesDetectionPass` implements our function detection
system.
2016-09-17 15:33:57 +02:00
Alessandro Di Federico 8dfda3d55a Keep track of memory ranges read by SET 2016-09-17 15:33:56 +02:00
Alessandro Di Federico f168621aa7 If OSRA provides no useful information, use SET 2016-09-17 15:33:56 +02:00
Alessandro Di Federico e9834e25b9 Exploit the power of unsigned comparisons
An unsigned comparison such as `x - 3 < 5` carries two information: the
first is the obvious one (`x < 8`), but the other one is even more
interesting. In fact any unsigned comparison implies that the LHS is not
negative, therefore we also can state that `x >= 3`. This commit
implements the usage of this information.
2016-09-17 15:33:56 +02:00
Alessandro Di Federico 621095c31a Create OSRs also for trunc and zext instructions 2016-09-17 15:33:56 +02:00
Alessandro Di Federico bdc0c221bd Consider AllocaInst in RDA 2016-09-17 15:33:56 +02:00
Alessandro Di Federico f51c0c2771 Ignore undef values in SET 2016-09-17 15:33:56 +02:00