This was disabled because it triggered errors when compiling with older
versions of llvm-12 and -Werror.
With llvm-12 this needed anymore, so we can re-enable it
Notable changes:
- Split in multiple files the existing revng-merge-dynamic script
- Add the option to merge additional LOAD segments in the resulting
binary
- Align the new .dynstr to a 4 byte boundary
- Ensure the last verneed entry is marked as such (vn_next == 0)
- Ensure LOAD PHDRs are listed in ascending order,
as mandated by ELF spec
This is intended to be used by all projects that adopt rev.ng coding
conventions for C++. Each project can create a symbolic link to the
installed .clang-format file, so that IDEs and other dev tools can pick
it up easily while keeping it up-to-date when updating revng.
This commit performs the changes necessary in order to integrate with
revng-qa, the new project for cross-project quality assurance.
Basically, the source code of all the tests has been moved in revng-qa,
which will take care of producing "artifacts" (i.e., compiled programs),
using the appropriate cross-compilers.
revng will then consume them and produce new artifacts to be consumed by
other tools down the pipeline.
The directory structure of the tests has been reworked to reflect
`revng-qa`. A large amount of boilerplate code has been dropped.
Note that certain actions, that used to be carried out during testing,
are now part of the regular build process. Specifically, lifting the
tests is performed at build time, so that they can be installed.
At this point, this branch is guaranteed to build without warnings with
our two supported compilers: clang-9 and gcc-9.
The dependencies are:
- llvm-9
- clang-9
- boost-1.71
- c++2a
This commit replicates the structure of the install directory into the
build directory in order to simplify the management of RPATHs.
This commit also drop `QEMU_INSTALL_PATH`.
* Introduce `ShrinkInstructionOperandsPass`: a transformation shrinking
operands and the results of instructions if they are
zero/sign-extended immediately before and after the instruction.
* Introduce `ConstantRangeSet`: similar to `ConstantRange` but allows
disjoint ranges.
* Introduce `MaterializedValue`: a class that can represent a constant
value or a symbol plus offset pair.
* Introduce `DropHelperCallsPass`: a transformation removing calls to
helpers and replacing them with a function call reading the CSVs that
the helper reads and writing the CSVs that the helper writes
(according to CSAA).
* Introduce `DropRangeMetadataPass`: a transformation dropping the
`range` metadata, which, in certain situations, lowers the quality of
the results provided by `LazyValueInfo`.
* Introduce `AdvancedValueInfo`: an analysis exploiting results of
`LazyValueInfo` but collecting them as `ConstantRangeSet` with a
monotone framework. It produces `MaterializedValue`.
* Anticipate linking of helpers: `AVI` requires `CSAA`, which requires
helper functions to be linked in.
* Drop `--no-link`.
* Force x86-64 `DataLayout`.
* Reorganize harvesting to either collect simple literals or go with
(incremental) `AVI`.
* Drop `SET`, `OSRA`, the reaching definition analysis, the
`SimplifyComparisonsPass` and all the sumjump-related code: e now
clone `root`, optimize it and analyze it with `AVI`.
* Temporarily drop the `NoReturnAnalysis`.
* Link `libLLVMInstCombine`, `libLLVMCodeGen` and `libLLVMPasses`.
* Introduce tests for `AdvancedValueInfo`,
`ShrinkInstructionOperandsPass` and `ConstantRangeSet`.
* Fix test results.
* Add `llvm.bswap.i64` and `@pc` to the LLVM template module for unit
tests.
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.
When installing programs we used to add to `RPATH` the `../lib`
directory. However, this is not enough, since the analysis libraries
reside in `../lib/revng/analyses`. This commit fixes the issue.
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`.
We now optimize `support.c`. We didn't do that since we were optimizing
everything after linking anyway, however, without `-O2`, functions in
`support.c` were getting an `optnone` attribute which inhibited any
optimization. In particular `newpc` and analogous functions were not
inlined. Resolving this issue led to a gigantic improvement in terms of
performance of the output program.
When optimizing a module to which function isolation has been applied the
`prune-eh` pass lead to several issues, specifically:
* `support.c` is now compiled with support for exceptions, to prevent
`raise_exception_helper` from being marked `nounwind` during the
link phase.
* Added a fake `ret` at the end of the `catchblock` to avoid promotion
of `invoke`s to regular `call`s.
* Marked the `invoke` instructions as `noinline`.
`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.
We used to include `.` and `include/`, but the former is no longer
necessary and the latter has to have the highest priority to avoid that
installed headers take higher precedence, leading to a build employing
outdated headers.
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 checks if valgrind headers are available and, if so, defines
a macro. In this way, if the heders are not available,
`valgrindhelper.h` can be aware of this fact and become a no-op.
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.
This commit simply reduces the length of lines in CMake by splitting the
statements over multiple lines. This is particularly useful when listing
the translation units composing a program/library. In fact, it makes
merge much easier.
Doxygen doc used to look for source files in the source root directory
only. We now use `git ls-files` to figure out which files need to be
part of the documentation.
A set of assertion-related functions has been introduced:
* `revng_abort(message)`: aborts, in release builds too.
* `revng_check(what, message)`: asserts `what`, in release builds
too. Also emits a `__builtin_assume`, that can lead to additional
optimizations in clang.
* `revng_unreahcable(message)`: identical to `revng_abort`, but in
release builds emits `__built_unreachable`.
* `revng_assert(what, message)`: asserts in debug builds, otherwise
emits `sizeof(what)` (to suppress unused variable warnings) and
`__builtin_assume`.
The adoption of these function has the following benefits:
* Nice stack traces.
* The developer can choose to enforce an `assert` (or an `unreachable`)
at release-time too by using `check`/`abort`.
* Most warnings about unused variables in release mode should be gone.
* When using clang, the `assert`s become `assume`s, which might enable
additional optimizations (with no run-time costs).
* The `assert(Condition && "Reason")` trick is no longer needed, we now
have a proper argument.
This commit adds a new analysis pass: `CPUStateAccessAnalysisPass`.
This pass currently performs 4 operations.
1. A preliminary analysis of the call graph, to select the functions
that are reachable from the root function through direct calls. All
the other performed operations are executed on this set of reachable
functions.
2. An interprocedural forward taint analysis, starting from the uses of
`env`, the global variable pointing to the QEMU struct continaint the
CPU. This analysis taints all the instructions that use the address
of `env`, until a load or a store is met. If a load or a store uses a
tainted Value as address it means that it is accessing a CSV at a
given offset (which at this point is still unknown).
3. An interprocedural offset analysis, which deduces the possible
offsets used by every tainted load/store to access the CSV. This
analysis initially works backwards, exploring all the Values that
contribute at the computation of the addresses used by tainted
load/stores. Once it finds all the sources, it starts propagating the
values forward, collecting the offsets computed along the way. It
does this until it reaches the tainted load/stores again. At that
point the analysis knows all the possible offsets used by each
tainted load/store to access the CPU state.
4. The results of the previous steps are used to do 3 things:
* marking all the indirect calls with tainted arguments as illegal;
this is necessary because those calls may access the CPU State in
unpredictable ways;
* attaching metadata to all the call sites to QEMU helpers in the root
function; these metadata provide information on which parts of the
CPU State may be accessed from that call site, which is a
potentially useful information for users of libtinycode that we also
plan to use in other parts of revamb;
* substituting loads, stores, and memcpys to and from the CPU state
with accesses to global variables; this operation effectively
replaces what was previously done by the CorrectCPUStateUsagePass,
which is now obsolete and was removed in this commit.