Without this attribute, newer versions of llvm are not able to
remove calls to `ReadOnly` functions whose return value is unused.
This is instead the expected behavior for the functions that are
generated by `revng` with the `ReadOnly` attribute.
* Introduce some documentation for the model.
* Improve the way enums are serialized/deserialized.
* Mark certain fields of model data structures as optional.
* introduces some error messages during model validation.
This commit introduces the type system of the model along with several
various other improvements to the model and its users.
* Introduce the type system.
* Introduce possibility to tag certain fields in the model as to be
optional during YAML serialization.
* All the `Name` fields have been replaced in favor of `CustomName` plus
a `name` method that will use `CustomName` if available, or an
automatically generated name otherwise.
* Make TupleTreeReferences behavior more robust: now you either need to
have a valid pointer to `Root` and a `Path` or be default constructed
(`nullptr` for `Root` and an empty `Path`). Any other configuration is
invalid.
* The type system introduces `RawFunctionType`: this superseds the
previous way in which we were specifying arguments and return
values. Users of such information have been updated accordingly.
With llvm-12 thera are more stringent requirement on the propagation of
DebugLoc on CallInst and InvokeInst.
Various CallInst and InvokeInst created during lifting did not fulfill
these requirements, causing the Module to not verify() with llvm-12.
This commit fixes the problem, properly propagating the debug locations.
RemoveExceptionalCalls is a simple pass whose goal is to drop all the
calls to functions marked as `Exceptional` and replace them with an
`UnrechableInst`.
This is mainly useful in the decompilation pipeline.
This commit takes out of EnforceABI the part taking care of creating
wrappers for calls to helpers and promoting CSV to local variables.
This decoupling, enables to run -promote-csvs multiple times, for
instance after inlining.
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.
Isolated functions return structs. These structs used to be constructed
using `IRBuilder::CreateAggregateRet`, which is implemented using
`insertvalue` instructions. However, this approach led to ugly
decompiled code.
This commit introduces "constructor" functions that can be easily
pattern matched down the pipeline.
This commit ensures that FunctionIsolation and EnforceABI do only
thing. This means that they no longer modify `root`.
Instead, we have a new pass, `invoke-isolated-functions` that needs to
be run after them and replaces the entry point of the functions with
invokes to the isolated functions, possibly with the appropriate
arguments.
Changes include:
- `getFunctionCall` has been moved in IRHelpers.h
- `getFallthrough` and `getFunctionCallCallee`
have been simplified and added in IRHelpers.h (their old versions
have been removed respectively from FCI.h and revng.h)
- `FCI::getCall` and `FCI::isCall` have been removed
due to redundancy with `getFunctionCall`.
Add an additional opaque store the the `pc` after each function call in
the enforced functions. In this way, when the `pc` will be promoted to
an alloca, we won't have an inconsistent state of the IR (the callee
cannot propagate the correct value of pc, the safety check introduced by
the function isolation will always be false, and llvm will place a
`llvm.assume` which will in turn make the rest of the code dead and
purged by an additional `-simplifycfg`).
This commit drops the `--isolate-no-safety-checks` flags since we
adopted a new approach later on in the decompilation pipeline, i.e.,
dropping calls to `raise_exception_helper` and running dead code
elimination.
FunctionIsolation used to base its work on calls to the marker function
`function_call`, as opposed to information provided by the StackAnalysis
(i.e., `revng.member.type` along with `func.call`).
This also affected EnforceABI, which took care of finishing the work
left over by FunctionIsolation. This was hackish and inelegant.
This commit makes FunctionIsolation work exclusively employing
information from StackAnalysis and purges away code that is no longer
necessary from EnforceABI.
When the `--enforce-no-safety-checks` flag is passed during the
enforcing, we avoid emitting the inlined `function_dispatcher` and we
emit instead a call to an `indirect_handle` disposable call created on
the fly to respect the ABI information on the callsite.
EnforceABI promotes global variables representing parts of the CPU
states to arguments and return values of isolated functions.
This commit enables the promotion of CSV that are used in isolated
functions only indirectly, through `ConstantExpr`s casts.
`llvm::removeUnreachableBlocks` doesn't just drop dead basic blocks,
it also turns certain `SwitchInst` into `BranchInst`, which leads to
hard-to-debug issues in parts of the code where we don't assume
unexpected changes such as this.
Function isolation used to mishandle blocks of type
`BlockType::IndirectBranchDispatcherHelperBlock`. This led to have
empty basic blocks instead of the dispatcher for handling indirect
branches.
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.