Commit Graph

255 Commits

Author SHA1 Message Date
Pietro Fezzardi 8e3b1c0080 DLACollapseSingleChild: preserve InterferingInfo 2022-03-08 17:21:08 +01:00
Pietro Fezzardi 3546eda055 DLATypeSystem.cpp: improve .dot for Instance edges 2022-03-08 17:20:49 +01:00
Pietro Fezzardi 9a6a0369e7 DLADeduplicateUnionFields.cpp: fix log 2022-03-08 17:20:32 +01:00
Pietro Fezzardi cb51965f6e DLAComputeNonInterferingComponents: fix moveEdges
This DLAStep was moving edges improperly before this commit.
In particular, edges were detected solely looking at source and target
edge, not looking at the edge itself. This was leading to wrong results
whenever a node N1 had many outgoing edges to a child node N2, at
different offsets, where all the edges were moved instead of just the
correct ones.

In order to fix this, this commit:
- reworks the logic of `moveEdges`, switching to iterator-based logic
- reworks the struct OrderedChild used internally by
  DLAComputeNonInterferingComponents, so that it is also iterator-based
- re-uses common code for field size computation
2022-03-01 12:52:58 +01:00
Pietro Fezzardi 3a94aab82a DLA: extract field size computation logic
This commit moves the logic for the computation of field sizes to a
separate .cpp file.
At the moment this is only used by DLAComputeUpperMemberAccess, but in
the future it will also be re-used DLAComputeNonInterferingComponents,
which at the moment employs very similar code.
2022-03-01 12:52:58 +01:00
Pietro Fezzardi 60f9141a07 DLA: move DLAHelpers.{cpp,h} to Middleend 2022-03-01 12:18:23 +01:00
Pietro Fezzardi 050af6e5c6 Move getLoadStoreSizeFromPtrOpUse to DLA frontend
This helper was only used once in DLACreateIntraProceduralTypes.cpp.
This commit moves it there, paving the way for better isolation of
helpers.
2022-03-01 12:18:22 +01:00
Pietro Fezzardi b0d3ab2b84 DLACollapseSingleChild: relax assertion on node collapse 2022-03-01 11:38:04 +01:00
Pietro Fezzardi e2a82f8dfc Drop useless include DLAHelpers.h 2022-03-01 11:38:04 +01:00
Pietro Fezzardi 7132ffa3e3 DLA: improve handling of stack arguments
Before this commit the case where the DLA recovered narrower sizes for
stack arguments than what expected on the Model was not handled
properly.

Now the scenario is handled explicitly, in two ways
- if the DLA recovers a stack argument with struct type, the fields are
  copied to the model in the type representing the stack argument;
- if the DLA recovers a stack argument with a type T that is non-struct,
  then the type in the model representing that stack argument is a
  struct with a single field at offset 0 and type T.
2022-02-28 18:12:27 +01:00
Pietro Fezzardi 1f39ed42e6 Fix update of stack sizes on Model by DLA
Before this commit, if the DLA was detecting stack sizes that were
smaller than expected by the Model, the size of struct recovered by the
DLA was edited in-place, enlarging it an possibly leading to a
malformed Model.

This commit fixes the problem:
- the size of the stack struct recovered by DLA is not changed
- the fields of the stack struct recovered by DLA are copied inside
  inside the Model in the struct representing the stack
2022-02-28 18:12:06 +01:00
Pietro Fezzardi b6520330fb DLADeduplicateUnionFields: fix use-after-poison
This commit fixes a use-after-poison bug.

DLADeduplicateUnionFields::runOnTypeSystem iterates over the DLA graph
while mutating it.
Due to iterations on copies of the edges, there were some edges to dead
nodes that were still hanging around and could be accessed.

This commit fixes the problem by not saving copies of the edges, but
saving LayoutTypeSystemNode * and iterating lazily on the edges starting
from the node itself every time.
In this way, if the graph is mutated, we never have outdated edges
pointing to dead nodes, and we don't have use-after-poison.
2022-02-28 18:11:49 +01:00
Pietro Fezzardi 94d875b559 Improve dla::LayoutTypeSystem::moveEdges
Before this commit, this method could not move Inheritance edges to
offsets different than 0.
This commit enables this action. Inheritance edges that are moved to
offset different than 0 become Instance edges.
2022-02-28 18:11:31 +01:00
Pietro Fezzardi 9c5e1750c7 DLATypeSystem: use lower_bound and upper_bound
This commit changes a bunch of methods of LayoutTypeSystem that were
dealing with edge removal and editing.
The previous version was using linear search with std::find_if on the
neighbours.
This commit switches to using std::set::lower_bound and
std::set::upper_bound, exploiting the fact that edges are ordered based
on the address of the target node.
This makes the code more concise and more efficient.
2022-02-28 18:11:13 +01:00
Pietro Fezzardi a58d960440 DLA: avoid late insertion of Inheritance edges
Inheritance edges have a specific semantic that must derive directly
from the binary, and are often treated specially by DLA steps.
For this reason is not correct to inject them late in the pipeline.
2022-02-28 18:10:57 +01:00
Pietro Fezzardi bd99db4711 DLADeduplicateUnionFields: fix use-after-free
This DLA Step works iterating in post-order on a graph while mutating
it. The post-order traversal is done with llvm::post_order, which holds
an iterator to the next children to visit.
Before this commit, the mutation of the graph could invalidate this
iterator.
This commit fixes the iteration logic, by computing the post-order ahead
of time, without holding around iterators that could be invalidated.
This is possible thanks to the fact that the mutation applied by the
DLADeduplicateUnionFields step on the graph do not change the post-order
visit, so the order computed beforehand remains valid throughout all the
computation despite the mutations that could take place.
2022-02-28 18:10:20 +01:00
Pietro Fezzardi 64d30a4790 DLATypeSystemBuilder: isolate assertion methods
The assertGetLayoutTypePreConditions methods didn't really need to be
exposed as methods in a header. This commit moves them to static
standalone functions in the only place they're used.
2022-02-28 18:06:44 +01:00
Pietro Fezzardi 078c56bbb1 DLAComputeUpperMemberAccess: improve debug logging 2022-02-28 18:06:28 +01:00
Pietro Fezzardi 41a62366fc DLATypeSystem: color edges when printing to .dot 2022-02-28 18:06:10 +01:00
Pietro Fezzardi 5cdc63cda6 Apply new revng coding conventions 2022-02-28 18:02:25 +01:00
Pietro Fezzardi d237bc439e IRCanonicalization: switch to FunctionTags 2022-01-14 14:29:05 +01:00
Filippo Cremonese b940af4692 Import recent changes to the model 2022-01-14 14:06:59 +01:00
Pietro Fezzardi 3c7d46a294 DLAPass.cpp: drop useless include 2022-01-04 16:22:47 +01:00
Pietro Fezzardi 818156e06a DLA upgrades stack's and stack arguments' types 2022-01-04 16:21:07 +01:00
Pietro Fezzardi decbbc56df Merge librevngcUtils into librevngcSupport 2021-12-22 17:46:45 +01:00
Pietro Fezzardi 81336b9c78 Update #include directive due to renaming 2021-12-22 17:39:43 +01:00
Alessandro Di Federico 904684e2f5 Prefix all libraries with "revngc" 2021-12-22 13:43:21 +01:00
Alessandro Di Federico cdc05640b8 DLA: handle the extra argument for stack arguments 2021-12-17 14:01:05 +01:00
Alessandro Di Federico 24f5515842 Import passes of the new stack promotion pipeline 2021-12-17 14:01:00 +01:00
Alessandro Di Federico 8a337a4525 DLA: ignore loops with trip count 0 2021-12-17 13:50:46 +01:00
Pietro Fezzardi 39ec9a32ee DLAMakeLayouts: drop too strict assertion
This assertion was conceived to check that DLADeduplicateUnionFields was
doing its job, ensuring that we never created a union with only one
field.

However, the assertion is too strict, and there are situation that union
deduplication cannot handle and that still generate a union with one
single field. Here's an example

    Node A, with Interfering Children
       Instance Edge -> Node B
       Offset 12 Edge -> Node C

    Node C
       Offset 12 Edge -> Node D

    Node C: uint32_t

    Node D: uint32_t

Hence we need to remove the assertion.
2021-12-17 11:02:14 +01:00
Pietro Fezzardi abee369841 Handle calls whose callee is not an llvm::Function 2021-12-14 16:57:41 +01:00
Pietro Fezzardi 375eb70dc8 SCEVBaseAddressExplorer: ignore non-const strides 2021-12-14 16:56:51 +01:00
Pietro Fezzardi 3a28bb0611 DLAMakeModelTypes: use isValid for TTR 2021-12-01 17:40:01 +01:00
Alvise de Faveri 89091510d5 DLA: Handle functions with same prototype in FE
Since in the model a FunctionPrototype can be shared among different
functions or indirect calls, we should take into account this fact when
initializing the DLA.

In particular, if the aforementioned case happens, we want to add
equality edges between the return value(s) and the arguments of all the
functions that have the same prototype. These will then be merged by
later steps in the middle-end, and the resulting information will be
shared among all the merged nodes.
2021-11-16 17:00:53 +01:00
Alvise de Faveri 5b8529edd5 DLA: Generate Model Types
Add `MakeModelTypes` and `UpdateFuncPrototypes` to the DLA backend:
* `MakeModelTypes` adds to the model all the types recovered by the DLA
* `UpdateFuncPrototypes` updates function prototypes in the model that
have generic return values or arguments to use the types recovered by
the DLA
2021-11-16 17:00:53 +01:00
Alvise de Faveri 4c8215fc47 DLA: Add pointers
* Changes to the `LayoutTypeSystem` graph

Pointers are identified in the TypeSystem graph as leaf nodes which
have a new type of edge (PointerEdge) that connects them to another
node of the graph. The destination of the edge represents the layout of
the pointed type.

* Changes to the Front-end

Pointer edges, and their destination nodes, are created by the DLA
front-end (`DLACreateIntraProceduralTypes`) whenever an access node has
a size that is compatible with the size of a pointer in the current
Architecture.
Successors might then be added to the newly generated node, if any,
by looking up the llvm::Value it is attached to.

* Changes to the Middle-end

Most of the DLA passes should ignore Pointer Edges, so they are modified
accordingly. Most notably, nodes that represent pointed layouts should
never be merged/pruned-off.

* Changes to the Back-end

The `TypeDeclCreationAction` of the decompiler and the `DLAMakeLayouts`
step of the DLA back-end are modified to take into account the new
information about pointers.

⚠️ There is a known issue with this version of the decompiler,
namely the fact that type loops are not detected and can cause the
emitter to enter an infinite loop.
2021-11-16 17:00:34 +01:00
Alvise de Faveri 92712396ee DLA: Fix multi-edge children in DedupUnionFields
When deduplicating unions, for each union we compare each successor
with all other successors. However, the same successor node might be
reachable by more than one edge from the parent.

This can cause problems when a node gets merged while the comparison is
still ongoing. In particular, since the comparison is done using a copy
of the successor list, to avoid iterator invalidation, the links in
the worklist are not updated when a node gets merged, causing links to
the merged node to have an invalid destination.

The fix here is to keep a list of **nodes** to visit, and a list of
**edges** that have already been visited, so that, if a node is merged
through one of its links, we are not visiting other links connected to
the same node after the merge.
2021-11-16 17:00:34 +01:00
Pietro Fezzardi 032463c539 Fix handling of calls with unnamed callees 2021-10-12 09:57:30 +02:00
Alvise de Faveri e90020b94c Don't visit the same union twice during dedup
Optimization to avoid checking the same union node multiple times.
2021-10-11 18:28:03 +02:00
Alvise de Faveri a6d0d52107 Remove leftover call from debugging session
RemoveConflicts should not be needed here, as it runs before in a
separate step and is also ran during deduplication.
2021-10-11 18:25:18 +02:00
Alvise de Faveri e2dd34e08e Avoid comparing a node with itself in union dedup 2021-10-11 18:21:53 +02:00
Alvise de Faveri 43ae7a91cb DLA: Add DeduplicateUnionFields Step
Add a step that recognizes if two subtrees of a union node are
topologically equivalent and merges them. This corresponds to removing
duplicate fields in unions.

This deduplication was prevously done while emitting layouts.

A check is inserted into DLAMakeLayouts to assert that, after
constructing unions, no union has only one child, which could be the
case if we didn't deduplicate union fields in the graph.
2021-10-06 16:37:37 +02:00
Alvise de Faveri 637bf70ff3 DLA: Make CollapseSingleChild a function
Since the reasoning behind single child collapsing can be reused in
other points of the DLA pipeline, move the logic that acts on a single
node in a static function out of the CollapseSingleChild step.
2021-10-05 18:16:21 +02:00
Alvise de Faveri 7e72fc4be1 DLA: Add RemoveConflictingEdges step
Add a DLA step that removes all instance-at-offset-0 edges between nodes
that already have an inheritance edge between them.
2021-10-05 18:16:21 +02:00
Pietro Fezzardi f057441ce8 Fix linking 2021-08-20 11:21:04 +02:00
Alvise de Faveri a0f95e0370 Modify CollapseSingleChild to allow single members
* Inheritance straight lines are now collapsed by CollapseSingleChild
* Don't collapse if parent has more than one parent or if the child has
more than one parent
* Allow the possibility to construct single-member struct: if this
struct is inherited by many other structs, "flattening" the struct is not
the most sensible thing to do, since inheritance information is something
we want to preserve in these cases.
2021-07-27 11:59:48 +02:00
Pietro Fezzardi ae0095e90a DLA: handle Values with unknown Layouts 2021-07-20 15:20:53 +02:00
Alvise de Faveri 4eb50d0bb5 Add Unit Test for DLACollapseSingleChild 2021-06-30 17:50:12 +02:00
Alvise de Faveri c1e4b940d0 Add CollapseSingleChild step to DLA 2021-06-30 17:50:12 +02:00