* Make the following private headers public:
* Lift/CPUStateAccessAnalysisPass.h
* Lift/CSVOffsets.h
* Lift/PTCDump.h
* Lift/VariableManager.h
* Move from revngSupport to revngLift:
* IRAnnotators.{h,cpp}
* SelfReferencingDbgAnnotationWriter.{h,cpp}
* Move from revngSupport to revngModel:
* FunctionTags.{h,cpp}
* ProgramCounterHandler.{h,cpp}
* Move from revngSupport to revngRecompile:
* OriginalAssemblyAnnotationWriter.{h,cpp}
Before this commit, initModelTypes always looked at uses of each
instructions to see if its knowledge of the instruction's model type
could be improved.
This is useful in some cases, but it's detrimental when building model
casts, because this requires to see the exact type computed for an
instruction.
This commit introduces a new function initModeTypesConsideringUses,
which works like old initModelTypes, considering uses.
In this way we can make sure that uses are considered when necessary,
like when computing types to build new local variables, and ignored when
necessary, e.g. when building model casts.
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;
```
Before this commit, initModelTypes could return integers of the wrong
size for IntToPtrInst, whenever the integer being casted to pointer did
not have the exact same size of the pointer on the model.
This commit fixes the problem. Now initModelTypes, even if it might be
forced to return an integer type for IntToPtr, it makes sure that the
size of that integer matches the size of the pointer on the model.
This commit drops ValueManipulationAnalysis, which in its original
design based on MinCut and Karger, was never enabled in the
decompilation pipeline.
Until now, VMA was only used in a severely weakened form in
initModelTypes. That for was so weakened that it barely did anything.
We already have a new design for VMA so that it can work before
DataLayoutAnalysis, and on Clift.
At this point, the old VMA is basically useless anyway, and the very few
occasions where it can do something will simply be solved by the
upcoming work on making some of the remaining casts implicit.
At this point it does not make sense to keep VMA alive anymore.
This commit heavily reworks how we handle returned values, making things
a bit more elegant.
Apart from this, it fixes how were handling types that on the model are
aggregates but were being returned via registers on the IR.
This Tag is used to tag all the funcitons that we use to decorate
integer literals to decide how to print them.
Using a single Tag shared among all the decorators enables more concise
code to handle it.
Before this commit initModelTypes wasn't able to detect the type of the
callee operand for calls to isolated functions.
This commit properly supports this case.
Now extractvalue instruction are replaced by dedicated
OpaqueExtractValue custom opcode, that prevents LLVM from doing strange
things with extractvalues during optimizations (such as e.g. sinking).
This is important since extractvalue instructions and struct-typed
values in general in our LLVM IR are not real first-class citizens, but
only a byproduct of the binary lifting process, and they actually
represent bundles of registers that are returned from isolated
functions.
This commit introduces modelType, which supersedes `llvmIntToModelType`
in order to better handle translation of LLVM types into model types
after introduction of opaque pointer types. The main differences is
that `modelType` accepts the `Value` (instead of just the `Type`), so it
can better handle `AllocaInst` and `GlobalVariable`, which provide
information about the pointee.
This commit does various things oriented at reducing the number of local
variables emitted in C:
- MarkAssignments now know that @Copy and @Assign involving
@LocalVariable only have side effects that affect the local variable
itself; this enables to reduce the number of times we're forced to
emit a local variable due to interfering side effects
- Drop the @AssignmentMarker FunctionTag; AddAssignmentMarkerPass now
doesn't emit @AssignmentMarker anymore; instead it emits groups of
@LocalVariable, @Copy, and @Assign, which benefit from the previous
point
- Drop 2 MarkAssignments::Reasons: HasManyUses and HasUsesOutsideOfBB;
both these have now been aggregated into the AlwaysAssign reason for
simplicity, representing all reasons non involving side effects
- Update BeautifyGHAST and how it reasons about side effects when
beautifying; before this commit it used @AssignmentMarker, now it
looks at @Assign
- Simplify ExitSSA; before this commit it was trying hard to be smart on
where it emitted the store instructions representing the incoming
values of the PHI that was being destroyed; this seemed smart when we
originally did it but it generated C code that was not really better
to read, so this useless complexity is finally gone
This commit adds a new pass, PrettyIntFormatting, that injects calls to
decorator functions print_hex, print_char, and print_bool around
llvm::ConstantInt in various situations.
It also updates the rest of passes of the decompilation pipelin to
understand these new decorator functions and to properly emit decorated
integer literals in the decompiled C code.