Commit Graph

1642 Commits

Author SHA1 Message Date
Alessandro Di Federico 655f25fdff Factor out code for generating modules in tests 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 a1120e4caf SA: precompute CSV indices
The stack analysis identifies CSV as `CPU+x` where `x` is an index that
uniquely identifies a CSV. We used to compute this index multiple times,
going through the list of global variables.

After we switched from metadata to global variables for strings
representing disassembled instructions, such process became very slow to
the point of being a bottleneck due to the large amount of global
variables.

This commit precomputes, once and for all, the unique identifier of each
CSV and saves it in a `std::set`.
2018-12-13 18:03:07 +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
Pietro Fezzardi 451177bae9 Fix check-conventions.sh to use ! not not 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
Andrea Gussoni 039896fb41 Fix OBJ and CSV variables in translate script
Moved the definition of `OBJ` before its first use.

Moved the definition of `CSV` outside the lifting scope, to avoid
erroneous behaviors when invoking the script with the `-s` option.
2018-11-29 11:25:01 +01:00
Alessandro Di Federico e2fdee1597 Merge branch 'feature/mipsel-support' 2018-11-15 16:05: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 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 37b4917ea5 delay slots are no longer relevant 2018-11-14 09:34:49 +01:00
Alessandro Di Federico 9606c8df35 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 bdd327e127 Function calls have a single link register
In certain cases we find more than one instruction storing the return
address to a register. In particular, this happens with a `bltzal`
instruction in MIPS, where the return address is stored both in `ra` and
`btarget`.

For now, do not consider these as actual function calls.
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 09b9fbba39 Drop trailing semi-colon in messageless assertions 2018-11-14 09:34:49 +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
Alessandro Di Federico 37fb3d6e56 Introduce support for little endian MIPS 2018-11-14 09:34:49 +01:00
Alessandro Di Federico 509625cb30 Do not clobber helper functions' debug info
`DebugAnnotationWriter` creates debug information for each instruction
in the generated LLVM IR module. Before this commit, it used to clobber
any debug information in any function, which lead to wrong debug
information on helper functions.

This commit ensures that debug information of helper functions are
untouched, so that they can be used while debugging.
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 4c66e41352 Merge branch 'feature/rda-rewrite' 2018-10-16 17:43:44 +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 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 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 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 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 944dcbc747 Merge branch 'feature/new-names-assert-logging-options' 2018-10-03 23:11:20 +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