Checking if a `SwitchInst` has a certain case triggers a linear search.
When we have *a lot* of jump targets this is an issue.
This commit assumes that when we add a case to a dispatcher, that case
is not already there.
FunctionTags goal is to solve the long-standing problem of identifying
what type of function are we dealing with. Is it a lifted function? An
helper?
Now we have a sane way to determine this using Metadata and a proper
API.
This commit makes `PCH::getUniqueJumpTarget` more robust:
1. We bail out only if we find a non-constant write to a field of
`MetaAddress` for which we already have a value. Before, any
non-constant write would lead to bailing out.
2. In case we meet an helper, we now bail out only if we didn't saw any
write to a portion of the `MetaAddress`.
This commit extracts a plain `struct` from the `MetaAddress` class. This
enables us to use `MetaAddress` from C and therefore, runtime.
The definition of such `struct`, `PlainMetaAddress`, is in
`PlainMetaAddress.h`, which is included by `early-linked.c`.
A function to print the content of a `PlainMetaAddress` has also been
introduced.
Also, anticipating the linkage of `early-linked.c` triggered a
superflous assertion in `CPUStateAccessAnalysis`. This commit removes
it.
* Introduce GCBI::buildDispatcher
* Introduce GCBI::getJumpTarget{,Block} and GCBI::getBlocksGeneratedByPC
to easily map `BasicBlock *` to jump targets and viceversa.
* PCH::buildDispatcher now returns a list of the newly created basic
blocks.
* Other minor changes
This commit fixes a bug that lead to be unable to instantiate from a
`Module` `ProgramCounterHandler`. The reason for this was that
`ProgramCounterHandler` was using `Module::getGlobalVariable` which, by
default, ignores variables with internal linkage.
Rationale: it is a widespread practice, both in revng and in projects
that depend on it, to write verification functions that check specific
properties hold after different transformations on various data
structures.
Often, these verification function are very useful for debugging and
during development, but they can be very costly and we don't want to
always execute them at runtime.
This patch adds a global public Logger, called VerifyLog, that can be
enabled with the --debug-log=verify command line argument.
This Logger is intended to be used in revng and in projects that depend
on it, as a guard for costly calls to verification functions that do not
need to be performed on a typical execution, but only when debugging.
For now the only user is JumpTargetManager, but other uses are already
envisioned.
Unlike the previous iteration of `MetaAddress`, which tried to stuff all
the parts of `MetaAddress` within the existing `PC` CSV, this
implementation adds a set of new CSVs (or marks some existing ones as) to
represent the four portions of the current PC's `MetaAddress`.
* Introduce `ProgramCounterHandler`: a class responsible to maintain the
PC-related CSVs. This class is also used to manipulate the new
dispatcher.
* `AdvancedValueInfo`: update for new MetaAddress.
* External jump handler: do not clobber registers.
When introducing support for dynamic binaries, we didn't realize that
in x86-64 we were clobbering `r11`. To avoid this, we have to jump to
an address stored in memory. However, due to the new `MetaAddress`,
obtaining a *jumpable* address from the PC-related CSVs might require
some computations (and it does in ARM). Therefore, we introduce a new
global variable, `jumpablepc`, whose only role is to contain the
jumpable version of the program counter and then be the target of the
memory-indirect jump instruction.
* Labels care only about absolute addresses.
* CSAA: mark call site, even if no accesses.
`MetaAddress` replaces all the `uint64_t` used to represent a virtual
address. Its main features are:
* It has a non-zero representation of invalid addresses.
* It supports tags to represent code that has different interpretations but
resides at the same address in memory (namely ARM vs Thumb).
* Arithmetic operations cannot overflow.
* It supports epochs, a way we intend to employ to handle self-modifying code
(i.e., different code at the same address at different times).
* It supports "address spaces", which enable handling architectures with
multiple address spaces.
* It fits in two 64-bit registers.
* Drop unused argument names from function prototypes
* Make `static` some methods
* Disable some copy constructors
* Fix casing of Doxygen `\file` directives
* Add some casts to make the compiler happy
* Initialize `hasRelocationAddend` for AArch64
* Use references in range-for where possible
* Drop default for `switch` statements covering all the entries of an `enum`
* Make some global variables `static`
* Drop dead functions
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`.
`extern` declarations of template specializations for Logger<true> and
Logger<false> caused weak symbols to be emitted in librevngSupport.so
and into its users.
Dynamic loading then failed because both symbols were weak.
This commit removes the `extern` declarations so that dynamic loading
succeeds.
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.
In most cases, a user of MonotoneFramework does not need a
interprocedural analysis, nor an analysis whose results on
terminal labels have to be aggregated in a FinalResults.
DefaultInterrupt<LatticeElement> is designed exactly for those
cases, and is hence used as default template parameter for
MonotoneFramework.
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 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.
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`.
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`.