This commit further centralizes the creation of allocas + ptrtoint. The
creation of these pair of instructions is problematic when the size of a
pointer in the input and target architecture differ.
In fact, in such cases, LLVM turns trunc into masking the integer to
suppresse the high bits. This results in problematic code.
This commit introduces an assumption that ensures LLVM does not do that.
When using revng through `revng daemon` the variable `InputPath` is not
populated, leading to `lddtree` failing silently. Fall back to the input
binary in the resume directory in case the the `InputPath` variable is
empty.
Clean up the `ProgramRunner` class:
* use llvm-provided wrappers and system-agnostic variables to compute
the `Paths` variable
* pre-compute the list of path variables so it's not re-computed on
every invocation of `run` or `isProgramAvailable`
* Wrap the logging code so that it's not triggered if the logger is
disabled
The `rp_manager_set_storage_credentials` is now skipped when running a
trace in `revng trace run`. This is needed because the storage backend
when running a trace is replaced with a local one and calling the
function does not make sense.
Change the `joinError` functions to have stronger guarantees when used:
* Change the template signature to `RangeOf` to ensure that the
container has `llvm::Error`s.
* Check that the size of the passed container is actually positive
before deferencing `.begin()`.
The `prettier` binary is now assumed to be installed as part of the
system. No need to manually install it and use the `--prettier`
command-line option.
Implement the DAGify pass. This pass, using the results exposed by the
`GenericRegionInfo` analysis, transforms all the retreating edges of
each identified `GenericRegion`, processed in a bottom-up fashion, into
a `goto` edge on the `ScopeGraph`.
Add the needed support for running `GenericRegionInfo` on the
`ScopeGraph`.
This needs a new ad-hoc `getGenericCycleInfo` helper in order to unwrap
the `Graph` object (pointing to the underlying `Function *`) from the
`Scope` wrapper object.
Do not assert if the marker function is not present in the input IR, the
`Builder` instantiation takes care of its on-the-fly declaration
instantiation.
This commit relaxes the assumption of the
CCodeGenerator::getModelGEPToken method, that previously crashed if the
BaseType and CurType were different.
Now this condition is only checked after skipping all typedefs, that
are transparent to ModelGEPs.
This commit ensures that, when the LLVM-based C code generation emits a
bitcast that would not compile in C if printed as a regular cast, it
uses __builtin_bit_cast instead.
This is necessary because the LLVM-based C backend is deprecated in
favor of the clift-based decompilation pipeline, so we're not actively
fixing bugs anymore, and it currently cannot guarantee that such invalid
casts are never emitted.
Before this commit, MakeModelCastPass was assuming that it would never
try to emit casts involving non-scalars, which don't compile in C.
From now on, the semantic of ModelCast in understood to be bitcast, and
it's valid also when involving non-scalar types.
This may cause the emission of ModelCast that are then emitted in C as
casts that don't compile.
Since the LLVM-based decompilation pipeline is deprecated in favor of
the clift-based decompilation pipeline, this is now considered
acceptable, as long as the C backend prints a warning and a comment on
the broken cast.
This commits reworks MakeModelCastPass so that the computation the of
arguments for the invocation of a ModelCast are now computed later: not
when we decided that a cast must be emitted, but right before we emit
the call.
This simplifies the code and lays the groundwork for relaxing some
assertions later.
This commit adds support in RemoveLoadStore for load/store instructions
such that the pointee of their pointer operand on LLVM is does not match
the pointee type on the Model (i.e. not areMemOpCompatible).
These cases are handled by emitting a Copy/Assign whose address operand
is a ModelGEP with a type matching the LLVM pointee, so that when these
are emitted as expressions in C the dereference operation is guaranteed
to access memory at a size that is compatible with LLVM, which represent
the semantic of what happens in the binary.
Before this commit, SwitchToStatement, in Legacy mode, was evaluating
the injection of Copy instruction an all uses at the same time, while
it's perfectly feasible, depending on how the surrounding IR is shaped,
that calls to Copy are only necessary on some of the uses.
This commit fixes, that evaluating the emission of a call to Copy on
each Use separately.
This commit adds a post-processing step to initModelTypes, to enable it
to better discover types of void * variables, by looking at their uses.
This is useful in scenarios like e.g.:
```c
struct s {
int32_t x;
int32_t y;
};
struct s* init() {
void *result = calloc(SIZE, 1);
*((int32_t *)(result)) = SOME_INIT_VALUE;
*((int32_t *)( (uin64_t)(result) + 4) = OTHER_INIT_VALUE;
return result;
```
This patch enables initModelTypes to look at uses of `result`, and to
enable other transformations that depend on initModelTypes (such as
MakeModelGEP, SwitchToStatements) to turn the above code into:
```c
struct s {
int32_t x;
int32_t y;
};
struct s* init() {
struct s *result = calloc(SIZE, 1);
result->x = SOME_INIT_VALUE;
result->y = OTHER_INIT_VALUE;
return result;
```