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.
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.
* 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`.
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`.
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.
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.
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.
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`.
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`).
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.
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`.
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.
`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.
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.
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.
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.
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`.
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.
This commit enforces, through `scripts/check-conventions.sh`, the
absence of `assert(false)` and direct calls to `assert`, `abort` and
`llvm_unreachable`.
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.
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.
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.
`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.
`.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.
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.