Various parts of revng replace `llvm::GlobalVariable`s representing CSVs
with Allocal/Load/Store. In particular, these are PromoteCSV,
RootAnalyzer and PromoteGlobalToLocalVars.
Before this commit, those places were sloppy when replacing CSVs with
Alloca/Load/Store, and did that iterating on a container sorted by
pointers. This caused Alloca/Load/Store to be emitted in different order
accross runs, which in turn caused more non-determinism down the
pipeline.
This commit fixes the non-deterministic behavior, sorting CSVs based on
their names, which should always be present and deterministic.
This commit switches the approach with which we run the ABI analyses: we
now run them until we reach a fixed point. This enables proper
interprocedural propagation of arguments and return values.
Basically, we now inject reads before call sites, so that, if a function
immediately calls another one, the arguments of the callee are
propagated to the caller.
This commit also updates the logic with which we propagate function
prototypes (and names) to callers. The main advantage of this, is that
function wrappers (in particular, PLT entries) now have the same name as
the function they wrap.
This commit drops calls to `_init_$CPU_STATE` for non-general purpose
registers. Instead, these part of the CPU state are initialized using
the initializer of the CSV, which is in turn provided by QEMU.
This enables us to properly initialize as appropriate fields such as
x86-64's DF flag.
During this phase (EnforceABI) the binary is not meant to be run
so the debug info is not useful anymore, so we are striping them
now in order to avoid taking care of them during the pipeline.
This commit improves the formalization of how we handle names.
The main changes are:
* Now `_` is a reserved prefix and all the generated names start with
`_`.
* The model verification routine now checks that `CustomName`s in the
global scope do not collide with any local namespace (e.g., fields of
a `StructType`).
* We changed the prefix `prefix_` to `unreserved_` to better convey the
fact that the prefix has been introduce to use an non-reserved name.
Before this commit, we were blinding adding the `nomerge` attribute to
function calls. Now we copy attributes over, so we preserve all the
attributes.
In this way the only place where we add the `nomerge` attribute becomes
Isolate.
This commit drops the `CallToLifted` tag in favor of a
`getCallToIsolatedFunction` function which checks if the call has the
`IsolatedFunction` tag. The function also assumes that indirect calls
are calls to lifted functions.
SimplifyCFG with instruction sinking enabled sometimes can merge two
call sites that are identical at LLVM IR level, but originally come from
two distinct addresses in the original binary.
The nomerge attribute prevents this type of problematic deduplication.
This commit introduces `BasicBlockID` as the unique identifier for a
`efa::BasicBlock` into the CFG. A `BasicBlockID` is defined by a
`MetaAddress` plus an incremental integer. This enables us to have
multiple instances of the same block in a single function, which is
particularly useful when inlining multiple times the same function.
Apart from this, the commit also does the following:
* It drops representing `MetaAddress`es a `structs` in the IR. This created
several issues related to ABI. We now represent them as strings.
* It defines more functions in `support.h`, instead of defining prototypes
by hand in `CodeGenerator.cpp` and the like. Specifically, `unknownPC`
and `raise_exception_helper`. We also introduce a C "constructor" for
`PlainMetaAddress`.
* It significantly reduces the API of `GeneratedCodeBasicInfo`, which
was supposed to be put on a diet since a long time. Specifically,
many jump target related methods have been moved to free functions in
`IRHelpers.h`. Also `GCBI::getSuccessors` has been pushed into its
only user, `PruneRetSuccessors`, to prevent further usage of a
deprecated API. In the future, it would be nice to drop it entirely.
* It introduces `efa::BasicBlock::InlinedFrom`.
* Introduce an enum to represent named argument indices for `newpc`.
This enables us to more effectively manipulate its argument list.
* It improves the verification and error reporting for
`efa::FunctionMetadata`.
* Update tests.
This commit is preliminary to another piece of work to improve the
generality of inlining beyond the simple "fake function" scenario, for
which the feature was originally conceived.
This change makes sure that CollectCFG is always intertwined
with FunctionIsolation, as it needs to run before the latter
executed. To avoid possible rearrangements on the pipeline
in the future, CollectCFG pass is now registered within FI.
FunctionMetadata was being deserialized every time they were
inspected. This commit introduces a cache structure to prevent this
excessive deserializations.
PromteCSVs creates wrappers around helpers. These helpers used to return
a struct in case the helper was changing a CSV.
In order to simplify the downstream pipeline, we now use out arguments
instead of returning a struct.