Commit Graph

3168 Commits

Author SHA1 Message Date
Ivan Krysak bc98e0079f Formatting: change PenaltyReturnTypeOnItsOwnLine
The new value is 21.
2023-07-02 13:20:49 +02:00
Ivan Krysak 01b4ec36c9 Formatting: set AllowShortEnumsOnASingleLine
The new value is `false`.
2023-07-02 13:15:08 +02:00
Ivan Krysak 7ed14ca65c Minor improvements 2023-07-02 11:06:55 +00:00
Alessandro Di Federico 5885e4f9c8 ValueMaterializer: fix handling of ptr 2023-06-30 16:57:33 +02:00
Alessandro Di Federico 56d43ff089 Isolate/Enforce: add nomerge to calls
Isolated functions already have the `nomerge` attribute, but calls do
not.  This is important in presence of indirect calls.
2023-06-30 16:54:01 +02:00
Alessandro Di Federico a65ccc3413 Introduce ValueMaterializer
`ValueMaterializer` is a rewrite of what was called `AdvancedValueInfo`
which follows the same principles.

The main benefits over the old version is:

* We materialize the data-flow graph and the CFG of the relevant part of
  root. This makes debugging significantly easier.
* We drop the old MonotoneFramework infrastructure in favor of
  getMaximalFixedPoint.
* We significantly reduce the amount of queries we make to
  AdvancedValueInfo.
2023-06-30 13:39:22 +02:00
Alessandro Di Federico 4edcb6dd49 MetaAddress::decomposeIntegerPC: accept APInt 2023-06-30 13:35:04 +02:00
Alessandro Di Federico 466871e866 Introduce RegisterClobberer 2023-06-30 13:28:36 +02:00
Alessandro Di Federico f120ad334c Statistics.h: rework 2023-06-30 13:06:58 +02:00
Alessandro Di Federico 6ca6692d1e getUniqueJumpTarget: do not abort if PC unwritten
Sometimes code performs an indirect jump without changing the value of
the PC.  In most cases this is due to non-code or some other faulty
situation, but it is in principle possible that an instruction performs
an indirect branch to its own address.

This commit ensures that this situation does not end up in an hard
failure.
2023-06-30 12:35:18 +02:00
Alessandro Di Federico 3706f77960 LDDTree: mark Logger static 2023-06-30 12:35:18 +02: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
Pietro Fezzardi 01a985632f OperatorPrecedence: support OpaqueExtractValue 2023-06-30 10:48:59 +02:00
Pietro Fezzardi e2791443fb Remove extractvalue instructions in decompilation
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.
2023-06-30 10:48:59 +02:00
Pietro Fezzardi e4315c2cf0 FoldModelGEP: update transparent opcodes 2023-06-30 10:48:59 +02:00
Pietro Fezzardi cb02af692a FunctionTags::OpaqueExtractValue: add attributes
This commit adds the following attributes to OpaqueExtractValue:
- nounwind
- willreturn
- inaccessiblememonly
2023-06-30 10:48:59 +02:00
Pietro Fezzardi ce576870a5 FunctionTags: drop old unused FunctionTags::Marker 2023-06-30 10:48:59 +02:00
Pietro Fezzardi c3d7125dd5 Drop old unused RestoreExtractValuesPass
Now we don't restore the extractvalue instructions anymore, so this
whole pass is dead code.
2023-06-30 10:48:59 +02:00
Pietro Fezzardi 220a7718e8 Fix getModelGEPToken 2023-06-30 10:48:59 +02:00
Pietro Fezzardi 56a340bcb1 MakeModelGEPPass.cpp: improve debug prints 2023-06-30 10:48:59 +02:00
Pietro Fezzardi 0dd6e75800 Fix flattenTypedefsIgnoringConst 2023-06-30 10:48:59 +02:00
Pietro Fezzardi 386a6cc8aa MakeModelGEPPass.cpp: remove old dead classes 2023-06-30 10:48:59 +02:00
Pietro Fezzardi d1c1a79553 MakeModelGEPPass: drop old too stric assertions
It's actually legal to have a void PointeeType on LLVM IR, so the
removed assertions were just too strict and wrong.
2023-06-30 10:48:59 +02:00
Pietro Fezzardi a9128fb72b InitModelTypes: improve const-correctness 2023-06-30 10:48:59 +02:00
Alessandro Di Federico a660c83b49 Segregate: fix handling of return values
We were not properly handling functions with a `CABIFunctionType` whose
return value covered multiple registers (e.g., a `uint64_t` being
returned through two registers in i386).

Also, we were not correctly handling `CABIFunctionType` returning a
integer type that is smaller than the register containing it (e.g., a
`uint32_t` being returned through `rax` in x86-64).

This commit fixes both situations.
2023-06-30 10:48:59 +02:00
Alessandro Di Federico 559cc7d699 HoistStructPhis: various improvements
HoistStructPhis now:

1. Ignores calls to isolated functions
2. Works only on isolated functions
3. Drop the old calls which were otherwise surviving
2023-06-30 10:48:59 +02:00
Andrea Gussoni 2162bd6f4a BeautifyGHAST: change Standard to WhileTrue
Rename the `LoopType` enum element `Standard` to `WhileTrue`, to better
convey the information that in that stage the loop as not been promoted.
2023-06-26 15:23:00 +02:00
Andrea Gussoni 3b07a6fba6 BeautifyGHAST: Introduce the hybrid not simplify
Introduce the hybrid beautifier aiming to simplify double `not`s (one on
the IR side (e.g., a `icmp ne`), and one on the `ExprNode` side on the
`GHAST` in the form of a `NotNode`.

To do this hybrid beautifier, we basically need to do the following:
- Implement a preliminary collection phase which computes which
  `ExprNode`s are affected by which `BasicBlock`.
- Compute the so-called consesus, i.e., verify that for all the
  `ExprNode`s affected by a certain `BasicBlock`, the transformation
  would be beneficial in terms of output. Basically:
    1) That the number of `!(!=)` transformed into `(==)` outscores the
       number of correlated `(!=)` which are transformed into `!(==)`.
    2) That the number of `!(==)` transformed into `(!=)` outscores the
       number of correlated `(==)` which are transformed into `!(!=)`.
- Actually perform the transformation for those situations where the
  consensus agrees.
2023-06-26 15:23:00 +02:00
Alessandro Di Federico 942cc1323a revng::verify: dump module upon failure 2023-06-23 17:54:55 +02:00
Pietro Fezzardi 4c9df76673 BeautifyGHAST: fix numbering of debug filenames 2023-06-23 16:39:04 +02:00
Pietro Fezzardi f7dfd1e4ca Backend: drop duplicated do-while condition 2023-06-23 16:39:03 +02:00
Pietro Fezzardi bc76cbe546 AddAssignmentMarkersPass: fix size of ptr locals
Before this commit, we assumed that the size of model types could be
either smaller, equal or larger than IR types.
Hence, the code was designed to take care of all those situations with
various workarounds and assertions.
Thanks to recent developments, the size of Model types can only be equal
to the size of IR types.
There are only 2 exceptions to this rule:
- the size of SPTARs, that can be larger on the Model than on IR, since
  on the IR they are returned as pointers, while on the Model they are
  aggregates;
  these were already handled properly before this commit.
- the size of IR-pointers, since their size in LLVM is target-dependent;
  before this commit they were handled poorly, using LLVM's DataLayout
  but not taking into account that the DataLayout is not necessarily the
  one of the proper target;
  this commit fixes this, just taking the pointer sizes from the Model,
  which effectively represents the proper pointer size for what we're
  handling.
2023-06-21 15:17:28 +02:00
Alessandro Di Federico 2a322dcfeb Segregate: handle small return types
If a function was returning a scalar, we used to forward the return type
from before Segregate. However, this was not OK in case a return value
was in a 64-bit register, but was actually using only the lower 32-bits.

This commit improves handling of such situation.
2023-06-21 15:17:28 +02:00
Pietro Fezzardi dfa279cfec MakeModelGEPPass: ignore zero-size types
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.
2023-06-21 15:17:28 +02:00
Alessandro Di Federico 55d433e020 Layout::verify: be stricter on return values
We now ensure that, if we have multiple return values, each one of them
covers at most one register.
2023-06-21 10:56:27 +02:00
Alessandro Di Federico 0af9b34a0a Layout: make ReturnValues empty in case of void 2023-06-21 10:55:50 +02:00
Pietro Fezzardi 3016c2ad41 MakeModelGEPPass: enable operator [] on pointers
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.
2023-06-20 18:15:24 +02:00
Pietro Fezzardi 35fded0b38 MakeModelGEPPass: handle affine indices in arrays
With this commit we now support emitting array indices in the form:

array[const + coefficient_0 * index_0 + ... + coefficient_n * index_n]
2023-06-14 16:07:20 +02:00
Pietro Fezzardi 63970fb925 MakeModelGEPPass.cpp: use IRSummationin ChildInfo
to represent generalized inputs in the form of:
`constant + sum(coefficient_i * unknown_index_i)`
2023-06-14 16:06:11 +02:00
Pietro Fezzardi 6bf0de84ce Recompile tests with -Wimplicitly-unsigned-literal
This warning was disabled in the past. This commit handles the cas
properly and re-enables the warning in recompilation tests.
2023-06-14 16:06:11 +02:00
Pietro Fezzardi 70eb3e8c4d AddAssignmentMarkersPass: fix size of locals
Before this commit the pass was assuming that the types on the model and
the types on LLVM IR were always of the same size.
This is not always guaranteed, especially if the model is user-provided
or coming from debug info, because in such cases we can have e.g. a
function returning `int` in C, but returning `i64` on LLVM IR.
Another corner-case are CABIFunctionTypes returning big aggregates, that
are represented by pointer-sized integers in LLVM IR.

This commit handles the above mentioned cases.
2023-06-14 12:25:54 +02:00
Pietro Fezzardi ea3c6216ad DecompileFunction.cpp: ban floats only on ICmp
Before this commit we were asserting to never find float types on any
binary operator, which was way too strict.
2023-06-13 17:05:41 +02:00
Valentina Sona 8409c435a6 Add decompilation support for (x != 0) -> (x)
Not equal is handled separatedly during the decompilation process in
order to add the appropriate cast.

Currently, the code only triggers when the not equal is the outermost
operation in the expression - case for which there are no tests in the
test suite.
2023-06-12 14:17:34 +02:00
Valentina Sona 8429c35f2e Insert boolean not on equal to zero comparisons
Implements the transformation (x == 0) -> (!x) via the boolean not
opcode, inside the two's complement arithmetic normalization pass.
2023-06-12 14:17:34 +02:00
Valentina Sona 8dfd7c2d96 Add custom opcode BooleanNot 2023-06-12 14:17:34 +02:00
Pietro Fezzardi aa63ede37b MakeModelGEP: refactor to support partial mismatch
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.
2023-06-12 13:36:18 +02:00
Djordje Todorovic f05c08547d ptml: Introduce PTMLBuilder class
By using this class we can create ptml::Tags without
XML tags. It is useful in the revng-c part when we
want to generate Plain C. All PTML Tags, from now on,
should be created via this class only.

In addition, port `Yield` library to be using this.
2023-06-09 17:15:30 +02:00