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.
If the base pointer that we're trying to use to build a ModelGEP points
to a zero-sized type, just ignore it, since we wouldn't be able to
traverse that type in any sensible way.
This commit enables to emit accesses with the square bracket array
access operator on pointers.
This is accomplished by adding an additional mandatory argument to
ModelGEP (AND NOT to ModelGEPRef) to represent this case.
MakeModelGEPPass is updated to take this into account, together with all
the other passes that handle ModelGEPs.
This commit is a major refactor of the data structures underlying the
MakeModelGEPPass, and of all the functions that manipulate them.
The refactor is aimed at fixing a major but of the previous design,
that made impossible to support MakeModelGEPs with partial mismatch.
This meant that until now we were emitting code that was not
semantically preserving whenever we could only match a part of the IR of
with a ModelGEP.
In particular, whenever a partial match was detected, the ModelGEP of
the matched part was still emitted, but we completely failed to emit the
mismatching part as raw pointer arithmetic.
This was due to the old design of the data structure, that cause the old
algorithm to lose track of the mismatch part at some point, without any
safeguard to avoid that.
Now all the data structures have been designed to properly represent the
mismatching part, so that the algorithms can avoid to lose track of
them, and finally emit the proper ModelGEP with additional pointer
arithmetic in case of partial match.
Since MakeModelGEP works Use-wise, if a `Value` was used multiple times
in a phi, we used to replace them with distinct model GEPs. This led to
generate illegal IR.
This commit fixes this situation by detecting the situation and reusing
the same model GEP.
Before this commit we couldn't handle gracefully situations where the
model had an array with elements of given size X and the IR had strided
accesses with a stride Y that was larger than X.
This commit gracefully handles that case, but for now it always bail
out.
In the future we could think of handling this better if Y is a multiple
of X.
Before this commit, MakeModelGEPPass was materializing all possible
traversals of the type system to select the best match for translating
some pointer arithmetic on the IR into ModelGEPs.
This proved to be very slow and to do a lot of useless computation on
larger binaries with big type systems.
This commit partially rewrites MakeModelGEPPass to adopt a
branch-and-bound approach to only explore paths on the type system that
have some chance of improving the best match.
This commit removes the bugged addPointerQualifier helper function,
that was wrongly pushing the pointer qualifier at the end.
Instead, we now use the correct model::Binary::getPointerTo method.