This commit introduces two new methods that describe the return value of
a function:
* `returnMethod`: describes how the return value is passed to the
caller.
* `returnValueAggregateType`: the type of the aggregate that is being
returned, in case `returnMethod` is `LocalVariable`.
InlineHelpers often inlines functions that contain a switch on an
argument that is constant on the call site. Specifically, this is true
for the `cc_compute_c` and `cc_compute_all` helpers of x86
architectures. The LLVM inliner, in such situations, is smart and
inlines a reduced amount of code, significantly reducing the maximum
size of the modules we work with.
However, before this commit, we couldn't capture this fact due to
`newpc` preventing constant propagation of the values of CSV set in an
instruction into their usage in the next instruction.
Running `PromoteCSV` before `InlineHelpers`, along with `mem2reg`
enables us to capture this behavior effectively.
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.
DetectStackSize only updates RawFunctionTypes. However it must also
handle CABIFunctionTypes, when met in a call site. This commit employs
abi::FunctionType::Layout to fix the situation.
This commit:
1. Introduces an alloca for stack arguments of a function. This enables
us to "write" to stack argument. In order to do so, we simply map the
relevant stack portion to the alloca that, since it's a memory
object, can be `load`'d from and `store`'d to.
Note that `llvm::Argument`s are always scalar since if the original
argument was an aggregate, it would have been passed as a pointer,
which is a scalar.
Note also that previously we were using scalar arguments as if they
were *pointers* to the stack arguments. This commit fixes that too
(and updates the tests accordingly).
2. Introduces an alloca for *scalar* stack arguments of a call site.
The alloca is then mapped to the corresponding part of the stack.
Previously, there was no redirection and negative offsets from
`_stack_frame` would pop up.
This commit splits in two stages handleCallSite and
handleMemoryAccess. Running the latter after all the call sites have
been handled, is necessary in order to properly replace certain memory
accesses targeting stack arguments of a call site.
We used to manually purge `raise_exception_helper`, which has now been
split in `_abort` and `_unreachable`. We want to purge the latter but
keep the former. The latter is marked as `Exceptional`, so this commit
updates the logic to purge all functions with `Exceptional` tag.
Also, due to the inability of the backend to emit globals of `struct`
type, we ban `set_PlainMetaAddress`, which is not critical for
decompiled code.
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.
Fix the needed attributes to allow navigation from the use of an
artificial return struct for raw functions to their definition in
`types-and-globals.h`.
Now CompactCompatibleArrays runs after ArrangeAccessesHierarchically.
Rearranging the accesses hierarchically first allows the following step,
that compacts compatible arrays, to achieve better results, and overall
recover much better looking arrays.
This commit extends the CompactCompatibleArrays DLAStep to also consider
non-strided accesses.
Strided accesses are still always considered first, and they are still
considered the only real source of information on arrays, but after
having tried to compact all the compatible arrays,
CompactCompatibleArrays now also considers non-strided instance edges to
see if they can be compacted with the rest of the inferred array.
This has shown to handle gracefully a number of real-world examples and
reduce unions.