Commit Graph

1005 Commits

Author SHA1 Message Date
Pietro Fezzardi 53c39d32f2 DecompileFunction.cpp: drop support for allocas
Since when we added the -exit-ssa pass, allocas are never supposed to
reach the C backend anymore.
This commit drops the code that supports them, that was effectively dead
code since a quite long time.
2023-04-04 09:33:22 +02:00
Kacper Kołodziej 9decc1fe51 DLA Frontend: Create nodes for StringLiterals
For segmentRef type of the segment and type returned by segmentRef
function are the same.

For cstringLiteral every call returns pointer to 1-byte type. Pointer is
offsetted by value of strlen+1. strlen is fetched from metadata.

Additionally, all uses of cstringLiteral function has same type as the
type of cstringLiteral (pointer to 1-byte).
2023-04-04 09:31:10 +02:00
Kacper Kołodziej 3776c9a382 Add case for StringLiteral in getExpectedModelType
Use Signed instead of Generic Int8 for StringLiteral return type
2023-04-04 09:31:10 +02:00
Kacper Kołodziej 3dd647cb28 Handle StringLiteral tag in InitModelTypes
InitModelTypes: use argument type as return type for cstringLiteral
2023-04-04 09:31:10 +02:00
Kacper Kołodziej c61c59c474 Handle StringLiteral tag in DecompileFunction 2023-04-04 09:31:10 +02:00
Kacper Kołodziej 2445c5e740 MakeSegmentRefPass: emit cstringLiteral
This commit changes MakeSegmentRefPass so that it's now a ModulePass and
it uses the binary to detect integer constants that represent the
address of strings.
When it detects address of constant strings, instead of injecting calls
to SegmentRef, we now inject calls to cstringLiteral, so that we can
later emit them as inline string literals in C.

In segmentRef we use integer type meaning address in memory, so we
generate segmentRef function with non-pointer type. For cstringLiteral
function we need real pointer type of operand.

Save MetaAddress, size, offset and original type for every
cstringLiteral call in metadata as we do for segmentRef calls.

For cstringLiteral "revng.cstring_literal" metadata name is used.

StringLiteralPool needs tuple of address, size, offset and type to
keep distinct string decorator functions for each string. This tuple is
represented by StringLiteralPoolKey struct.

Pipe for MakeSegmentRefPass needs to be defined explicitly, because
additional wrapper passes are required in MakeSegmentRef:

 1. LoadModelWrapperPass
 2. LoadBinaryWrapperPass

MakeSegmentRefPass requires access to RawBinaryView to detect cstring
literals in binary.

Fix printed command in MakeSegmentRefPipe

This printed command might not work. @ale commented it will be replaced
with `revng pipe run-pipe` once we will have it.

Update IRHelpers to new revng API

Switch String and Namespace arguments in getUniqueString
2023-04-04 09:31:10 +02:00
Kacper Kołodziej f83cb94e1f Add StringLiteral tag and corresponding f. pool
StringLiteral tag will be used to mark cstring decorators in generated
IR.
2023-04-04 09:31:10 +02:00
Ivan Krysak 47213e1669 Backend: remove an obsolete log file 2023-03-15 10:28:24 +01:00
Alessandro Di Federico b0024a302f Fixes for SPTAR passed on the stack 2023-03-15 10:28:24 +01:00
Ivan Krysak 4e2159d9b5 MakeModelGEP: fix aggregate return value support 2023-03-15 10:28:24 +01:00
Ivan Krysak d08c9387d2 DLA: stop updating aggregate return value types 2023-03-15 10:28:24 +01:00
Ivan Krysak 89774a1789 RemoveStackAlignmentPass: Add empty input support 2023-03-15 10:28:24 +01:00
Alessandro Di Federico d325e3b64a SSA: support shadow arguments on stack 2023-03-15 10:28:24 +01:00
Ivan Krysak 85fcd92f0e Backend: reword a comment 2023-03-15 10:28:24 +01:00
Ivan Krysak 56cdd8f876 Model: make model::Type::size() stricter 2023-03-15 10:28:24 +01:00
Ivan Krysak c2f0fc19e5 ABI: FunctionType.h -> FunctionType/Layout.h 2023-03-15 10:28:24 +01:00
Alessandro Di Federico 77ea6c6db6 Fix serialization of Segment key 2023-03-13 13:42:33 +01:00
Alessandro Di Federico e73bd95493 Improve handling of declarations
SegregateStackAccesses and PromoteStackPointer were not handling
functions declarated (but not defined) properly.

This commit fixes this, in part by adopting `TaggedFunctionPass`.
2023-03-13 13:42:33 +01:00
Alessandro Di Federico f6cdd8ad6d s/revng.register/revng.abi_register/ 2023-03-13 13:42:33 +01:00
Alessandro Di Federico f5a5990a30 Drop buildStringPtr in favor of getUniqueString 2023-03-13 13:42:33 +01:00
Djordje Todorovic 5482083e79 DecompileFunction.cpp: print debug info in PTML 2023-03-08 09:57:48 +01:00
Pietro Fezzardi f3e466c989 DecompileFunction.cpp: fix format for int literals 2023-03-01 12:22:35 +01:00
Alessandro Di Federico deddd8ebd1 PromoteInitCSVToUndef: only preserved registers
Do not promote registers to `undef` initializers of registers not marked
as being preserved by the current function.

This is useful to highlight usages of registers that are not an
argument, nor a callee saved register. Mainly this has been introduced
to preserved reads from x86-64 `fs` register.
2023-02-21 16:48:35 +01:00
Alessandro Di Federico dfb18bd1cf RemoveLiftingArtifacts: drop makeInitRegsUndef
Redundant w.r.t. PromoteInitCSVToUndef.
2023-02-21 16:48:35 +01:00
Alessandro Di Federico 098b9b3aa4 PromoteStackPointer: prevent DCE of init_local_sp
We need to prevent DCE from killing `revng_init_local_sp`, since certain
passes downstream might want to introduce new uses of it, and they might
be the first.

`SegregateStackAccesses` will take care of removing it by hand.
2023-02-21 16:48:35 +01:00
Alessandro Di Federico e9b9ba50d1 MakeModelGEP: ignore negative strides 2023-02-21 16:48:35 +01:00
Alessandro Di Federico c18dca0031 Adopt new approach for MetaAddress serialization 2023-02-21 16:48:35 +01:00
Pietro Fezzardi 7edfffbbf8 DuplicateReferences: fix for chains of IsRef ops
The previous implementation was iterating on the instructions in order.
This caused problems when we had two instructions, A and B, both tagged
IsRef, and B was using A and B had 2 or more uses.
In this case the pass was looking at A before looking at B, so A was not
duplicated because it only had one use (B).
Then B was analyzed and it had 2 uses so it was duplicated, causing the
number of uses of A to increase accordingly.

This commit fixes the problem iterating on the BasicBlocks in post
order, and on the instruction list in reverse order.

It also fixes MarkAssignments.cpp not to erroneously mark instructions
that are marked IsRef.
2023-02-08 18:12:53 +01:00
Pietro Fezzardi 66434db5f9 Don't use named metadata revng.segment_ref
Using a named metadata is simply wrong, because we need to have many of
these metadata alive at the same time with different values.
Using a named metadata has the unpleasant side effect of making all the
`SegmentRef` functions to refer to the same segment.
2023-02-07 18:03:34 +01:00
Kacper Kołodziej 5b94a5a649 HelpersToHeaders: skip unnecessary helpers 2023-02-07 17:43:05 +01:00
Pietro Fezzardi 72b32dafa2 MakeModelGEP: array accesses jumping many elements
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.
2023-02-07 08:12:42 +01:00
Andrea Gussoni ca540399d4 Ensure that no backedges are left
Ensure that no backedges are left after the restructuring of all the
metaregions.

This additional assertion should help ensuring that no entries in the
`Backedges` set are left after the restructuring process, in turn making
it easier to spot bugs if backedges references are not handled correctly
during the steps of the restructuring.
2023-01-31 11:55:52 +01:00
Pietro Fezzardi f0573995ba MakeModelGEP: use branch-and-bound approach
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.
2023-01-31 11:39:28 +01:00
Pietro Fezzardi 4e1fb3a854 DLA: fix CompactCompatibleArrays
Before this commit, the dla::Step CompactCompatibleArrays was
occasionally generating artificial nodes that were larger than the inner
data, forcing their size to Stride - AvailableSlack.
This commit fixes the problem keeping track of the actual size that is
consumed in the array element, and forcing the size of the artificial
nodes to that.
2023-01-24 16:50:42 +01:00
Andrea Gussoni db48424629 Handle Code and Collapsed node in shortest path
Assign a value to cloned and collapsed nodes in terms of shortest path
from entry, which is a criterion we use to elect region entry.
The shortest path is computed at the beginning for the nodes present in
the CFG, but needs to keep updated for additional nodes that we insert
that may become loop entry candidates.
2023-01-20 17:03:24 +00:00
Andrea Gussoni febd4a2777 Remove from Backedges set retreating edges
During the creation of the exit dispatcher, take care of removing from
the `Backedges` set the additional backedge that is collapsed in case
two exiting backedges do target the same destination.

When this is not done, a ghost backedge is left inside the set, making
it not coherent with the state of the graph.

In addition, we add an assertion which ensures that during this phase of
the restructuring dummy nodes are present only as source of retreating
edges, and have one and only one successor.
2023-01-20 17:02:18 +00:00
Pietro Fezzardi 3fe74cdb0d DLA: single-step ArrangeAccessesHierarchically
The dla::Step ArrangeAccessesHierarchically looks throught the DLA graph
and for each node with many outgoing instance edges tries to see if some
of them are hierachically contained within each other.

In order to do this, before this commit, we were building an auxiliary
graph representing this hierarchy, and in order to build it we had to
perform a number of comparisons between edges that was quadratic with
the number of edges.
Moreover, once all the comparisons were done, we had a deep graph
representing inclusion between edges, but we only cared about the
top-level of this graph, i.e. only the edges that contained other edges
hierarchically, but were not contained in other edges (we'll call them
the root edges).
So we were doing a quadratic number of comparisons but possibly many of
them were useless.
Finally, all the edges that were included in root edges, were pushed
down, but only for a single layer, because they needed to be re-compared
later with the children of the root edges they were being pushed
through. This latter part was responsible for a lot of wasted
computation that just needed to be done over and over at all the layers.
Overall this algorithm was doing a lot of wasted computation.

This commit replaces this logic with a new algorithm.
Now we keep track only of the root edges, and we compare only root edges
with other root edges.
Initially all edges are root edges.
Then we start comparing them.
If a root edge A is included in another one B, then A is not a root edge
anymore, and all the edges that were previously found to be included in
A are not included in B.
This algorithm still does a worst case of quadratic number of
comparisons, but drastically reduces the amount of useless computation
that is redone later. In particular:
- in cases where there are a lot of root edges (meaning that only a few,
  or no edge can be included in others) we do a number of comparison
  close to quadratic, but we're only pushing non-root edges down, so
  we'll never have to redo comparisons in deeper layers
- in cases where there is only a small number of root edges, we're doing
  a number of comparisons close to linear, and we never compare non-root
  edges with each other, so we're saving a lot of computation that would
  be wasted (because it would need to be redone in deeper layers).
2023-01-20 00:45:09 +01:00
Pietro Fezzardi 682cf2067c DLA: ArrangeAccessHierarchically uses RPOT
Before this commit we were manually building a topological ordering,
that resulted in worse overall performance in some scenarios.

This commit changes the dla::Step to temporarily introduce a fake root
node, and computes a RPOT from there, which overall yields better
results.
2023-01-19 14:51:35 +01:00
Pietro Fezzardi 5e12f66ffb Drop old logger, use CombLogger instead 2023-01-18 17:58:09 +01:00
Pietro Fezzardi 6cca34c30d Support array of pointers in getNamedCInstance 2023-01-17 12:31:22 +01:00
Pietro Fezzardi 97b23935de Handle FunctionTags::Exceptional
This is necessary for e.g. the abort function.
2023-01-17 11:14:47 +01:00
Pietro Fezzardi e33f6818cd MakeModelGEPPass: ignore non-pointer-sized Values 2023-01-17 11:11:55 +01:00
Pietro Fezzardi 97883844d3 Fix initialization of FunctionTags 2023-01-17 11:11:46 +01:00
Kacper Kołodziej 568bd24900 Add UnaryMinus and BinaryNot 2023-01-09 15:01:16 +01:00
Andrea Gussoni 80ea234167 Fix ContinueNode emission 2023-01-05 16:33:21 +00:00
Pietro Fezzardi 1a3d752814 MarkAssignments::Flags: drop unused method 2022-12-24 03:03:05 +01:00
Pietro Fezzardi adf0e30081 OperatorPrecedenceResolutionPass: fix QEMU helpers
We always emit a variable for calls to QEMU helpers. For this reason,
for what concerns operator precedence, calls to QEMU helpers should be
considered as references to variables. Hence, they should never be
parenthesized.
2022-12-24 03:01:48 +01:00
Pietro Fezzardi 73507a8d26 SegregateStackAccessesPass: fix pusing calls ALAP
Before this commit, calls were marked to push ALAP in the wrong order,
resulting in preventing to actually push them ALAP.

This commit fixes the ordering, reactivating the code motion.
2022-12-24 03:01:48 +01:00
Pietro Fezzardi e9d84264ff Reduce the number of emitted local variables in C
This commit does various things oriented at reducing the number of local
variables emitted in C:
- MarkAssignments now know that @Copy and @Assign involving
  @LocalVariable only have side effects that affect the local variable
  itself; this enables to reduce the number of times we're forced to
  emit a local variable due to interfering side effects
- Drop the @AssignmentMarker FunctionTag; AddAssignmentMarkerPass now
  doesn't emit @AssignmentMarker anymore; instead it emits groups of
  @LocalVariable, @Copy, and @Assign, which benefit from the previous
  point
- Drop 2 MarkAssignments::Reasons: HasManyUses and HasUsesOutsideOfBB;
  both these have now been aggregated into the AlwaysAssign reason for
  simplicity, representing all reasons non involving side effects
- Update BeautifyGHAST and how it reasons about side effects when
  beautifying; before this commit it used @AssignmentMarker, now it
  looks at @Assign
- Simplify ExitSSA; before this commit it was trying hard to be smart on
  where it emitted the store instructions representing the incoming
  values of the PHI that was being destroyed; this seemed smart when we
  originally did it but it generated C code that was not really better
  to read, so this useless complexity is finally gone
2022-12-24 02:47:10 +01:00
Pietro Fezzardi c201990e5b Print stack variable at beginning of function body 2022-12-24 02:44:38 +01:00