Commit Graph

299 Commits

Author SHA1 Message Date
Alessandro Di Federico 85058249c5 Avoid pygraphviz crash with Python 3
Just a workaround.
2020-09-04 17:40:00 +02:00
Andrea Gussoni a590159993 Use c++ compiler for linking the translated module
We now make use of the `__gxx_personality_v0` personality function to
handle the exception behavior.

For this reason, we now need to use a c++ compiler for linking the final
module after the translation process of a binary.
2020-08-03 22:11:18 +02:00
Alessandro Di Federico e190c3189e check-conventions.sh: always run clang-format 2020-06-13 10:36:08 +02:00
Alessandro Di Federico e51d6e5458 Make the revng script compatible with clang's ASan 2020-05-14 11:59:05 +02:00
Pietro Fezzardi a0102592b5 Lifting non-x86 dynamic ELFs: fix error message 2020-02-27 11:55:09 +01:00
Alessandro Di Federico 525325d1c6 Add revng translate --output 2020-02-19 12:19:59 +01:00
Alessandro Di Federico 0a79b3d0f2 scripts/revng: fix order of post -- arguments 2020-02-19 12:19:31 +01:00
Alessandro Di Federico d247745df8 revng: informative error message on missing file 2019-09-04 11:52:07 +02:00
Alessandro Di Federico 981389d80a revng: handle different version of pyelftools
The contents of ELF dynamic tags is return either as a `str` or a
`bytes` depending on the versions of `pyelftools`.

This commit forces it to be a string to ensure compatibility with both
options.
2019-06-06 17:39:42 +02:00
AndreaJegher 8492c56333 Enable AArch64 support (no tests)
This commit enables AArch64 as an input architecture. However, tests are
not enabled yet due to some known bugs.
2019-05-27 19:36:12 +02:00
Alessandro Di Federico 50396ab721 revng-merge-dynamic: handle missing DT_VERNEED 2019-05-27 19:36:12 +02:00
Alessandro Di Federico 706b1d8e71 revng script: use sh instead of env
`env` sometimes is not a real executable but a shebang script spawning
/usr/bin/coreutils, which makes gdb unhappy.
2019-05-27 19:36:12 +02:00
Alessandro Di Federico 19f6f84d73 Various improvements to the revng script
* Handle SIGINT in children gracefully (`run` function).
* `run_translate`: return 0 on success.
* Move useful information about the `revng` installation from
  `--version` to `--help`.
* Do not `execv` on external commands, otherwise the script will not
  proceed.
* Print current directory-relative paths with `--verbose`.
2019-05-22 18:42:32 +02:00
Alessandro Di Federico d411978af7 revng translate: invoke revng-lift directly 2019-04-22 05:40:27 +02:00
Alessandro Di Federico 4d5493fe7f Warning on translation of non-x86-64 dynamic ELF
We can currently successfully translate only dynamic binaries for
x86-64. Warn the user about this early on instead of failing in
`revng-merge-dynamic`.
2019-04-21 10:17:08 +02:00
Alessandro Di Federico 39a5a217c4 revng script: detect AArch64 2019-04-21 10:16:51 +02:00
Alessandro Di Federico 2f2b1f6ffe revng script: wrap executables 2019-04-12 19:17:23 +02:00
Alessandro Di Federico 9f4711b770 Improve revng help and ASAN support
This commit improves the output of `--help` and reduces the output of
`--version`.  This commit, when calling `opt`, injects a `LD_PRELOAD`
for `libasan.so` in case a `librevng*.so` library uses it.
2019-04-11 18:16:53 +02:00
Alessandro Di Federico 4076fbc8cd revng script: use -load and debugging options
Due to `opt` loading multiple times the same library, we had to switch
to `LD_PRELOAD`. However, this is suboptimal. This commit goes back to
use the `-load` flag but excludes the libraries that are dependencies of
other libraries. This requires parsing the ELF but it's a more neat
solution.

In addition, several shortcuts for popular debugging tools (namely,
`gdb`, `valgrind`, `callgrind`, `heaptrack` and `perf`) have been added
to the root command.
2019-03-06 10:31:23 +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
Pietro Fezzardi ba433e60a0 Fix check on static in check-conventions.sh
Now the `static` keyword in headers is considered an error only if it's
followed by a whitespace.
2019-03-06 09:04:58 +01:00
Alessandro Di Federico 94a99fe57c Force linking of all the original libraries
Certain libraries linked to the input executable sometimes are not
required by the executable or other dynamic libraries. Therefore, the
`ld -l` switch ignores them.

This commit forces linking of all the required libraries, no matter
what, by wrapping the list of dynamic libraries in `-Wl,--no-as-needed`
and `-Wl,--as-needed`.
2019-02-19 18:23:29 +01:00
Alessandro Di Federico 00b9ade51f Handle libraries not ending with .so
Sometimes dynamic libraries linked to executables do not end in
`.so`. Previously, we assumed that a version of the library ending in
`.so` was available on the system. However, this is not always the
case. In particular, Ubuntu 16.04 links `ls` to `libselinux.so.1` but no
`libselinux.so` file is available. This can lead to a linking failure.

This commit, correctly handles libraries whose name doesn't end in `.so`
by using the `-l:` linker option (e.g., `-l:libselinux.so.1`).
2019-02-19 17:57:28 +01:00
Alessandro Di Federico 543ab2253d revng-merge-dynamic: improve is_rela detection 2019-02-12 18:40:30 +01:00
Alessandro Di Federico 2b99f8e811 Use LD_PRELOAD instead of opt -load
In `opt -load`, the order in which the libraries are provided
matters. Using `LD_PRELOAD` circumvents this issue.
2019-02-12 18:40:30 +01:00
Alessandro Di Federico 6ae0610e2d Force Python versions
This commit switches all scripts to Python 3, except for
`revng-merge-dynamic` which requires Python 2 due to a limitation of
pyelftools.
2019-02-12 18:40:24 +01:00
Alessandro Di Federico 53db84f7d6 s/revamb/revng/g 2019-02-11 16:09:23 +01:00
Alessandro Di Federico ee1c8cae15 Add opt options to moderate runtime
Pass to the Global Value Numbering pass the `enable-pre=false` and
`enable-load-pre=false` since they have been identified as a major
source of slowdown with very large binaries.
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 9cbcef37d5 Disallow #if [01]
Sometimes code is commented using preprocessor directives. This is fine
for temporary testing stuffs, but it should never end up in a commit.
2019-01-18 08:38:46 +01:00
Alessandro Di Federico 034621e2ec monotone-framework.py: restore Python 3 compat
Due to a minor error, `monotone-framework.py` loss its Python 3
compatibility. This commit fixes the situation.
2019-01-09 22:31:26 +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 0010b6c704 Import revcc
`revcc` is a simple script that forwards its arguments to a specified
compiler, except in the case in which the compiler is asked to link the
final program. In such case, the compiler is invoked as appropriate, but
the resulting binary is then translated using rev.ng and replaced by the
translated version.
2018-12-13 18:03:11 +01:00
Alessandro Di Federico 4c446a38fe Check for include guards starting with _ 2018-12-13 18:03:11 +01:00
Pietro Fezzardi 451177bae9 Fix check-conventions.sh to use ! not not 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 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 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 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 9230bc3dc4 Ban assert(false) and non-revng_ assertions
This commit enforces, through `scripts/check-conventions.sh`, the
absence of `assert(false)` and direct calls to `assert`, `abort` and
`llvm_unreachable`.
2018-09-29 16:50:32 +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 037fca46ae Check 80 columns limit
This commit introduces an additional check in `check-conventions.sh` to
detect lines in source files exceeding 80 columns.
2018-09-21 20:04:25 +02:00
Alessandro Di Federico 6cfabd96f8 Prevent committing WIP code
This commit introduces a check in `check-conventions.sh` to prevent
committing code denoted by a `// WIP` comment, that are supposed to be
used to remind the developer something has to be changed before
submitting a pull request.
2018-09-21 20:03:21 +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 e6bc62f760 Twine: use them only as const Twine & arguments
`Twine`s are very cool but very subtle objects. You basically have to
use them as `const Twine &` arguments only. In fact, a Twine keeps a
reference to objects whose lifetime corresponds to the current
statament. Therefore, a `Twine` can easily end up holding a reference to
invalid objects.

This commit fixes a bug in function isolation (which would show up only
if optimizations are enabled) due to a misusage of
`Twine`. Additionally, it reduces its usage to safe places in
`statistics.h`. Finally, we added an assertion in `check-conventions.sh`
to ensure that no variables of type `Twine` are ever declared.
2018-09-17 19:20:17 +02:00
Alessandro Di Federico 9a85cc3a04 Introduce check-conventions.sh, .clang-format
`.clang-format` is the configuration file for the `clang-format` tool,
which can help us to enforce a consistent coding style.

`check-conventions.sh` is a a simple bash script that checks (using
mostly `git grep`) if, after running `clang-format`, there are some
undesired situations such as lines ending with "(" or "<".

This script should produce no output before a merge request is
merged. However, currently this is not the case, therefore the script
should be used mostly for new code (in particular, files) only.
2018-08-18 17:09:23 +02:00
Alessandro Di Federico 61cfbdfc56 Introduce support for dynamic binaries
This commit introduces support for dynamic programs. The current
implementation translate the main binary and uses native libraries. This
works only if the target architecture is the same as the source
one. Currently we only handle x86-64.

* The `ExternalJumpsHandler` class has been introduced. It basically
  takes care of extending the dispatcher handling the case in which the
  program counter is an address outside the range of executable
  addresses of the input program. In this case, a `setjmp` is perfomed,
  the CPU state is serialized to physical registers and jump to the
  value of the program counter is performed.

  Once the target code will try to return to the translated program, a
  segmentation fault will be triggered, a `longjmp` is performed and the
  CPU state is deserialized so that the execution can resume (from the
  dispatcher).

* `early-linked.c` has been introduced. Its purposes is to provide
  declarations of variables and functions defined in `support.c`. In the
  past, we had to manually create these definitions, a cumbersome and
  error prone we now avoid by letting `clang` compile `early-linked.c`
  and then linking it in.

* The old `support.h` is now known as `commonconstants.h`. `support.h`
  now contains declarations that have to be consumed by
  `early-linked.c`.

* Each architecture now provides additional information:

  1. Which registers are part of the ABI and have to be preserved. If
     necessary the QEMU name can be provided. For each register it's
     also possible to provide their position within the `mcontext_t`
     structure, provided by the signal handler.
  2. Three assembly snippets, one to write a register, one to read it
     and one perform an indirect jump.

  Some of this information is also exposed in the output module as
  metadata.

* `support.c` now installs a SIGSEGV signal handler. Since pages that
  were originally executable are no longer executable, jumping there
  (typically, from a library) will trigger a SIGSEGV that we will
  handle. This allows us to properly deserialize the CPU state and
  resume execution of the translate code.

* Now also a dynamic version of each test program is translated and
  tested.

* The `merge-dynamic.py` script has been introduced: it takes case of
  rewriting the translated binary so to tell the linker to performe both
  the relocations of the translate program and the relocations of the
  original program. It does so by rewriting a large portion of the
  sections employed by the dynamic linker such as `.dynamic`, `.dynsym`
  and so on.

* The `compile-time-constants.py` script has been introduced: it a
  user-specified compiler on a source file producing an object
  file. This object file is inspected and the value of global read-only
  variables is produced in a CSV.
2018-05-29 15:10:51 +02:00