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.
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.
Break node creation is now improved to avoid edge index swapping that
can cause inversion of conditions later on in the decompilation
pipeline.
To do this, the creation and connection of the break nodes is done
during the bulk insertion of nodes in a collapsed region.
* 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.
These may happen in nasty functions like memchr, where you have a loop
pre-header iterating over single bytes, a loop iterating over 4 bytes,
and finally the loop exit iterating over single bytes again.
Now we stop at the first non-decreasing nested AddRec.
While doing thie, also drop `printAccessNode()` from DLA DebugPrinter.
The information about which LLVM instruction originated a given access
node is already available in the csv generated by the `dla-accesses-log`
logger.
Until now, in makeLayout, inheritance edges were ignored when the
children were interfering.
Now the inheritance edges are treated as if they were instance edges at
offset 0.
- Remove `CreateInterProceduralTypes` and `CreateIntraProceduralTypes`
from the StepManager and put them in a separate
`DLATypeSystemLLVMBuilder` object that is in charge of initializing
the DLATypeSystem graph.
- Remove `MakeLayouts` from the StepManager and split into two free
functions: `makeLayouts` and `makeLayoutMap()`
- Remove all LLVM-related stuff (Module, LayoutTypePtrs and mappings
between these and DLATypeSystemNodes) from DLATypeSystem
- Add an IntEqClasses member to DLATypeSystem, to use to map between
LayoutTypePtrs and Layouts
- Add a TSDebugPrinter object inside the DLATypeSystem, which by default
prints only IDs
- Define an LLVMTSDebugPrinter inside DLATypeSystemBuilder which
overrides the default printer's behavior, printing LLVM-related info.
- Add the possibility to dump into a .csv file the bindings between
Nodes in the TypeSystem and `llvm::Value`s
Accessing NextChildPos is not safe if Pushed is true.
This commit switches the conditions so that NextChildPos is never
accessed unsafely thanks to short-circuiting.
This fixes a use-after-free bug, that was activate when calling tryPush
triggered realloc on the Stack.