Commit Graph

158 Commits

Author SHA1 Message Date
Pietro Fezzardi e052dee40f Drop isCandidateForInline 2024-06-07 17:59:06 +02:00
Pietro Fezzardi 44a4a77d53 Backend: prevent emission of const variables
At the moment in C we can't emit variable declarations with inline
initialization. Not for some substantial problem, but we haven't
implemented it yet. As a result if TypeMap.at(VarDeclCall) returns a
const-qualified type we will end up generating C code that doesn't
compile, when it tries to assign a value to the variable for
initializing it separately from the declaration.
To work around this, until we don't support emission of variable
declarations with inline initialization, we have to strip away
constness.
2024-06-06 11:27:48 +02:00
Pietro Fezzardi 4106617f6c Backend: better const-correctness for inline types 2024-05-29 15:34:26 +02:00
Pietro Fezzardi 196a15685f Rename TypeInlineHelper::findStackTypesPerFunction
to TypeInlineHelper::findTypesToInlineInStacks, which is more
descriptive of what the method actually does.
2024-05-29 15:34:26 +02:00
Pietro Fezzardi 93a821a64a Backend: assert that the stack is defined once 2024-05-29 15:34:26 +02:00
Djordje Todorovic c58fec45e3 Add ImplicitModelCastPass
We introduce a new LLVM Pass that should detect implicit
casts, by marking the 3rd argument of ModelCast as `true`.
The backend will omit printing a cast expression if the
ModelCast is implicit one.
2024-05-16 17:57:22 +02:00
Djordje Todorovic dd68f7d810 Move casts to MakeModelCastPass
Production of casts in backend should be indicated by
call to ModelCast only. This patch implements that.
2024-05-16 17:57:22 +02:00
Ivan Krysak a88b03aef8 Backend: fix an assertion on a lost typedef 2024-03-15 19:05:10 +01:00
Andrea Gussoni 6c8d963f69 RestructureCFG: Reorganize debug graphs
Various improvements to the debug graphs for `restructure-cfg` and
`beautify`:
- Normalize casing and syntax of debug graphs.
- Improve the graph folders name and layout.
- Implement `CFGDumper` and `ASTDumper` for when we need a serialization
  with incremental indexes.
- Remove old and stale graph serializations.
2024-03-11 19:08:34 +01:00
Alessandro Di Federico 0c212b66d9 Relicense to MIT 2024-02-29 17:03:36 +01:00
Andrea Gussoni e1a49e417f ALAPVariableDeclaration: introduce ALAP Var Decl
Perform the ALAP Variable Declaration process.
The process is structured in the following stages:
- We start by collecting all the `Variable`s that need to be assigned in
  a `ASTNode`.
- We build a `GenericGraph` where each `ASTNode` is connected with its
  child nodes, and also its immediate successor.
- We perform a walk in post order over this graph, and for each
  `ASTNode` we decide if the current node could be the ALAP location
  where we can declare the `Variable`, i.e., where we dominate all its
  uses.
2024-02-20 16:35:36 +01:00
Andrea Gussoni 3966d57cfd DecompileFunction.cpp: move helpers to header file
Move some helper functions to the `DecompilationHelpers.h` file in order
to use them from other `.cpp` files.
2024-02-20 16:35:36 +01:00
Alessandro Di Federico 911ab00107 s/CDecompilation/Decompile/g 2024-02-09 09:03:34 +01:00
Pietro Fezzardi 04bb1d0fb3 Backend: avoid casting to uint8_t in conditions
Explicitly casting to uint8_t has the semantics of truncating, in case
the value being casted is larger than 8 bits.
Avoiding the cast default to regular C behavior, where every non-zero
integer is considered true.
2024-01-26 16:49:47 +01:00
Alessandro Di Federico bb0a8cd495 CCodeGenerator: fix nullptr dereference 2023-12-12 12:04:19 +01:00
Giacomo Vercesi 194bcecc41 Drop getReturnField
Drop the `getReturnField` helper, the cases in which it was used are now
covered by the `NamedTypeRegister::name` method.
2023-12-11 10:21:40 +01:00
Giacomo Vercesi fd24487666 C code: fix location for RawFunction return struct
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`.
2023-12-11 10:21:40 +01:00
Pietro Fezzardi 24cb43ce9c Make RawFunctionType::StackArgumentsType a TTR
This is homogeneous with all other nullable references to types in the
model, such as the StackFrameType in model::Function, and others.
2023-12-05 16:56:52 +01:00
Andrea Gussoni 078cc1222a InlineDispatcherSwitch: introduce beautify pass
We introduce the `InlineDispatcherSwitch` beautify pass. Its goal is to
try and inline the body of some of the `case`s of a exit dispatcher, in
place of the `SetNode` corresponding to that `case`, if this doesn't
introduce duplication in the code (i.e., a single `SetNode` for that
specific case value is present).

Additionally, if the inlining procedure is able to completely remove the
necessity of an exit dispatcher altogether, the pass removes it.

The pass is able to handle chains of weaved dispatcher `switch`es
referring to the same original dispatcher `switch`, by handling the
inline operation and the possible simplification level-wise.

The inlining procedure, cannot take place if a `SetNode` is contained in
the body of the case we are trying to inline, since this can possibly
break the semantics of the state variable of a loop, by placing a
`SetNode` in a more internal loop.
2023-11-28 16:19:08 +01:00
Pietro Fezzardi 24c9fbe3fb Fix emission of do-while loops 2023-11-28 15:46:19 +01:00
Pietro Fezzardi 3e49213b43 Drop needsTopScopeDeclaration hack
This commit drops `needsTopScopeDeclaration`.
Now all the LocalVariables are declared at the top of the function.
In DecompileFunction.cpp, the emission of LocalVariables if handled at
the scope of GHAST `ASTNode`s instead of being LLVM BasicBlock-based.
This enables in the future to design and implement an analysis that for
each LocalVariable decides the C scope (represented by an `ASTNode`)
where it's declaration should be emitted to always be visible in all its
uses.
2023-11-28 15:46:19 +01:00
Pietro Fezzardi 0572b8f972 Relax assertion on mismatching size of binary ops
This fixes a crash due to the fact that pointers on the model may have
different size than pointer on LLVM IR, due to revng always using
64-bits DataLayout, even when decompiling 32-bits architecture.

The assertion did not take this into account.
In principle the assertion could be removed, but it might become a
source of broken semantics, so it's better to keep an advanced verions
of the assertion in place, to make sure we only allow situations that we
fully understand, and that we can guarantee don't break semantics.
2023-11-20 22:36:59 +01:00
Pietro Fezzardi dd8049abcc Add LiteralPrintDecorator Tag
This Tag is used to tag all the funcitons that we use to decorate
integer literals to decide how to print them.
Using a single Tag shared among all the decorators enables more concise
code to handle it.
2023-11-20 22:36:39 +01:00
Giacomo Vercesi 68f71c3b39 Adopt new PTML tags
Change the emitted decompile code to include the
`data-action-context-location` and `data-name-of` tags.
2023-11-03 16:31:06 +01:00
Andrea Gussoni 3e13765267 BeautifyGHAST: handle noreturn calls in beautify
Improve the `fallThroughScope` computation, in order to handle calls to
`NoReturn` functions in the analysis, representing the fact that they
induce a `noFallthrough` scope (i.e., execution will not ever resume
after the call, and therefore we can later improve the nesting of the
code with the `promoteNoFallthrough` pass).
2023-10-23 18:16:20 +02:00
Andrea Gussoni 733f5008b3 BeautifyGHAST: implement DualSwitch simplify
We introduce a simplification step, which looks for `switch`es that can
be reduced to simpler `if` statements.

Specifically, the logic is the following:
1) When we identify a `switch` statement composed by a single `case` and
   a possible default, we transform it into an `if` with the `case` now
   corresponding to the `then`, and the `default` corresponding to the
   `else`, if present.
2) When we identify a `switch` statement composed by two `case`s, and no
   `default` is present, we can promote it to an `if` with `then` `else`
   branches.

Other key details:
- The promotion happens only if we can identify at least one of the
  `case`s that have a single element in the `case` label. If this is not
  the case, we do not promote one to RHS of the `if` condition.
- A new `CompareNode` class, inheriting from `ExprNode`, is created, in
  order to represent the equality or inequality condition of an `IfNode`
  instance that is the result of the promotion. This `CompareNode` can
  represent for the LHS both an `llvm::Value` or the `loop_state_var`,
  while it embeds the RHS constant which completes the comparison.
- We remove `SwitchBreak` AST nodes that may now appear as children of
  an `if` node promoted from a `switch`.
- We introduce in the `CompareNode` the `weaved` concept. Indeed, if a
  promotion of a weaved `switch` happens, we should avoid the
  serialization of the instructions leading to the computation of the
  condition of the original `switch`, because they have been already
  emitted by the main related dominating `switch`.

We also introduce an additional simplification step, which takes care
of:
- Promoting `!(==)` to `(!=)` and `!(!=)` to `(==)`, if the inner
  equal/not equal is represented via a `CompareNode`.
- Promoting `x == 0` to `!x` and `x != 0` to `x`.

To be able to correctly emit (or not) the instructions computing a
condition of an `IfNode`, we need to add the `EmittBB` flag, an
additional parameter to the `buildGHASTCondition` function, which
controls the emission of the statements of a basic block computing a
condition.

Consequently, the `IfNode` acquires a `IsWeaved` field, which is used to
mirror the property having the same name on `SwitchNode`. Being now
possible a promotion from a dual `SwitchNode` to an `IfNode`, we need to
represent this property on the `IfNode` too.
2023-10-23 18:16:20 +02:00
Andrea Gussoni 2cef075697 ASTNode: refactor default in SwitchNode
The `default` `case` is now a standard `case`, and it is identified only
by having the `label` set empty.

Therefore, a list of beautify and transformation actions now do not need
special casing in order to handle the `default` `case`, which is reached
during the standard iteration over the `case`s.

A special accessor is still necessary, in order to correctly emit the
`default` `case` in the backend.
2023-10-23 18:16:20 +02:00
Andrea Gussoni 061bc52bc2 BeautifyGHAST: implicit statements simplification
Introduce implicit statements simplification phase, specifically:
- A implicit `return` simplification: `return` statements in `void`
  type functions, which are not followed by any other scope, can be
  omitted.
- A implicit `continue` simplification: `continue` statements whose
  fallthrough leads directly to the end of the cycle scope (i.e., to
  execute another iteration of the enclosing loop), can be omitted.

In order to avoid the printing of the implicit `return`, we need an
additional `emitReturn` parameter in the `emitBasicBlock` method of the
`CCodeGenerator` class.
2023-10-23 18:16:20 +02:00
Giacomo Vercesi df877d4aec Drop unused statements
Drop `using`s that were unused.
2023-10-23 10:20:49 +02:00
Pietro Fezzardi 48a708c07c Support printing NULL in decompiled C code 2023-10-19 16:18:41 +02:00
Pietro Fezzardi a97287cef3 ModelToPTMLTypeHelpers: refactor APIs
This commit reorders the argument passed to various `printDeclaration`
and `printDefinition` helper functions, to make them more uniform across
each other, and to accept the same arguments in the same order.
2023-10-18 15:19:53 +02:00
Alessandro Di Federico 4fe4d05895 CCodeGenerator::ParentPrototype: drop Parent 2023-10-06 17:14:29 +02:00
Alessandro Di Federico 2a7e06df1f printFunctionPrototype: add newline after ABI
This commit forces getLocationAttribute's argument to be false.
2023-10-06 17:14:29 +02:00
Alessandro Di Federico 6141717440 CCodeGenerator: emit comment after noreturn calls 2023-10-06 17:14:27 +02:00
Alessandro Di Federico 9f3b832009 CCodeGenerator: add space in struct initializers 2023-10-05 19:18:38 +02:00
Alessandro Di Federico cb8aa3d929 Adopt .prototype()
Also adopt `QualifiedType::getFunctionType` where appropriate in order
to unwrap typedefs.
2023-10-05 19:18:38 +02:00
Pietro Fezzardi 8d9f07d7a7 Change indentation of all decompiled C code
This commit changes the indentation of all the C code we emit, from 4
whitespaces to only 2 whitespaces.
2023-09-21 15:17:44 +02:00
Pietro Fezzardi 01f338be29 Add progress bars to DecompileFunction.cpp 2023-09-20 16:36:21 +02:00
Alessandro Di Federico f3d6bbb047 s/ThePTMLCBuilder/B/g 2023-08-23 16:40:54 +02:00
Alessandro Di Federico 489dddd0e7 TupleTreeReference::isValid is for assertions only 2023-08-23 16:37:39 +02:00
Alessandro Di Federico 330d2b6cc7 Model: rework how we name things
This commit:

* Introduces `_` as a prefix for all non-user entities we emit in
  decompiled code.
  Also, some names have been changed to be more concise.
  Specifically, the following entities have changed:
  `_ENUM_UNDERLYING`, `_ABI`, `_REG`, `_padding_at_`,
  `_artificial_struct_`, `_artificial_wrapper_`, `_stack`,
  `_break_from_loop_`, `_var_`, `_stack_arguments`,
  `_artificial_struct_returned_`, `_enum_max_value_`.
* Introduce _PACKED for `__attribute__((packed))`.
* `EnumEntry` name: drop the `EnumType` name prefix.
2023-08-23 16:37:39 +02:00
Pietro Fezzardi dfbb9a15b2 Backend: declare local variables for aggregates 2023-08-18 15:48:55 +02:00
Giacomo Vercesi 2d8e11fe74 DecompileFunction: use scope-location
Change debug locations to use the new `scope-location` tag to allow
switching between C and ASM code.
2023-07-31 11:25:45 +02:00
Ivan Krysak 4a32781868 Backend: emit function comment 2023-07-21 04:58:51 +00:00
Ivan Krysak e0b956b1c2 Model: rework edit path helpers from the ground up 2023-07-21 04:58:50 +00:00
Ivan Krysak fe0531868c Use Container::contains() where appropriate 2023-07-05 06:07:09 +00:00
Pietro Fezzardi 1b4079b496 DecompileFunction.cpp: HTML-escape strings in PTML 2023-06-30 10:48:59 +02:00
Pietro Fezzardi dd3836112d DecompileFunction.cpp: handle enum comparisons 2023-06-30 10:48:59 +02:00
Pietro Fezzardi 6acd265c5a Add revng helpers to decompile llvm::UndefValue
Before this commit, we used to decomple UndefValue to the literal 0.

This was causing problems in some cases, such as switch(0 /*undef*/)
where clang was issuing a warning that was impossible do disable without
turning off -Wall alltogether, which is undesirable.

This commit introduces a set of helper functions in
revng-primitive-types.h, that are now used to avoid emitting undef as
constant.
This is more semantically meaningful when looking at the decompiled
code, and it has the nice side effect that it silences the clang
warnings mentioned above.
2023-06-30 10:48:59 +02:00
Pietro Fezzardi e988932442 DecompileFunction.cpp: fix 128 bit literals 2023-06-30 10:48:59 +02:00