Commit Graph

51 Commits

Author SHA1 Message Date
Antonio Frighetto ebf6ab0be9 Introduce CSVAliasAnalysisPass
A pass that decorates memory accesses with
information about CSV aliasing.
2021-12-10 12:30:11 +01:00
Antonio Frighetto ec629a20b1 JumpTargetManager: move getOption in IRHelpers 2021-12-10 12:30:11 +01:00
Antonio Frighetto adcda3532b AVI: fix error in detection of stores to PC 2021-11-18 15:30:07 +01:00
Alessandro Di Federico 3a3eea0cf5 Introduce support for dynamic functions 2021-10-21 15:01:19 +02:00
Alessandro Di Federico 18cfbdbfe0 Whitespace and other minor changes 2021-10-18 12:39:21 +02:00
Pietro Fezzardi 67eaaab045 JumpTargetManager: enable InstCombine(true)
This fixes the latest failing tests after upgrading to llvm-12.
2021-06-14 23:04:02 +02:00
Pietro Fezzardi 6f7de910a6 Enable warning -Wunused-local-typedefs 2021-06-14 23:04:02 +02:00
Pietro Fezzardi 544b553e5c JumpTargetManger: swap constprop with instsimplify
Constant propagation has been dropped from llvm
2021-06-14 23:04:02 +02:00
Pietro Fezzardi d3d4e1ea5e JumpTargetManager.cpp: include missing header
Before the addition of this include, the file failed to compile with
llvm-12.
2021-06-14 23:04:02 +02:00
Ivan Krysak bc8c8f82d2 Prevent separation of 'main' headers into group 0
The prevention mechanism uses a dummy suffix:
'_THIS_SEQUENCE_IS_NEVER_GOING_TO_HAPPEN'.
2021-06-09 18:05:20 +02:00
Alessandro Di Federico 2e9c2ee275 Introduce FunctionTags
FunctionTags goal is to solve the long-standing problem of identifying
what type of function are we dealing with. Is it a lifted function? An
helper?

Now we have a sane way to determine this using Metadata and a proper
API.
2021-04-22 18:07:24 +02:00
Alessandro Di Federico 2ea5723a53 s/getCalledValue/getCalledOperand/g 2021-04-22 18:06:27 +02:00
Alessandro Di Federico aeb81c4218 Don't implicitly use StringRef as std::string 2021-04-22 18:06:27 +02:00
Alessandro Di Federico fee270b64e Minor changes 2021-04-22 18:06:27 +02:00
Alessandro Di Federico 3ce9acf198 AVI: ignore function calls
This commit further reduces the time spent in AVI by considering all the
function calls as indirect. In fact, we currently don't handle indirect
jumps whose target is affected by computation happening before a
function call.
2021-04-22 18:05:39 +02:00
Alessandro Di Federico 0e21755eb0 Handle more count-leading-zeros helpers 2021-04-22 18:03:53 +02:00
Alessandro Di Federico 2c3df7068e revng-lift: keep harvesting upon new CFG edges
We used to stop the harvesting process when the harvesting process was
no longer able to identify new jump targets, even if new CFG edges have
been identified.

This approach prevented to discover additional parts of the CFG thanks
to the increased accuracy gained by a more accurate CFG. This effect is
particularly visible when we have jump tables that can be reached only
through other jump tables.
2021-03-08 10:15:50 +01:00
Alessandro Di Federico 8b5a462187 AVI: use TypeShrinking
This enables us to handle situations where the comparison against the
switch value is performed on the lower 32 bits, but the address
computations uses the full 64 bits.

    cmp    edi,0x23
    ja     ...
    movsxd rdx,DWORD PTR [rcx+rdi*4]

Note that this does not solve all these situations yet.

This commit also introduces a reference output for the new
switch-jump-table-32-bit-comparison test case.
2021-03-08 10:15:50 +01:00
Alessandro Di Federico 68e5c6c6ea AVI: drop PC initialization from cloned root
AVI used to work on a cloned root that was initializing the pc to the
program entry point. Under certain conditions, this led to DCE almost
all of the code.
2021-03-08 10:15:50 +01:00
Alessandro Di Federico d0a78a41bf Drop direct branches to the dispatcher
Generated code now either jumps to `anypc` or `unexpectedpc`. The latter
one is to be considered a safety measure and will be populated with an
unreachable instruction on the decompilation pipeline.
2021-02-19 09:39:49 +01:00
Alessandro Di Federico df11232fe1 Improve GCBI
* Introduce GCBI::buildDispatcher
* Introduce GCBI::getJumpTarget{,Block} and GCBI::getBlocksGeneratedByPC
  to easily map `BasicBlock *` to jump targets and viceversa.
* PCH::buildDispatcher now returns a list of the newly created basic
  blocks.
* Other minor changes
2021-02-19 09:39:49 +01:00
Alessandro Di Federico 6cfcd087b7 Introduce ProgramCounterHandler::loadPC 2021-02-18 19:13:06 +01:00
Alessandro Di Federico d3247870f0 Reorganize ProgramCounterHandler construction 2020-12-31 14:37:53 +01:00
Antonio Frighetto 02b3a24463 Jump to dispatcher when location is invalid
Replace a call to `abort` with a branch to `dispatcher` when the
callee is unknown or invalid (namely, it is always treated as an
indirect call).
2020-12-31 14:17:30 +01:00
Alessandro Di Federico 3c58c7441b Whitespace changes 2020-12-29 16:14:49 +01:00
Alessandro Di Federico 0ccc32af08 Performance: destroy AVI PassManager ASAP
It is important to let the pass manager go out of scope ASAP:
LazyValueInfo registers a lot of callbacks to get notified when a Value
is destroyed, slowing down OptimizedFunction->eraseFromParent
enormously.

This commit introduces a speedup of approximately 25% when lifting
`/bin/bash`.
2020-11-22 15:14:44 +01:00
Pietro Fezzardi cd9bc34d9d Enforce new include conventions 2020-11-13 10:00:24 +01:00
Pietro Fezzardi 2fc342d2e4 Add a global public Logger: VerifyLog
Rationale: it is a widespread practice, both in revng and in projects
that depend on it, to write verification functions that check specific
properties hold after different transformations on various data
structures.
Often, these verification function are very useful for debugging and
during development, but they can be very costly and we don't want to
always execute them at runtime.

This patch adds a global public Logger, called VerifyLog, that can be
enabled with the --debug-log=verify command line argument.
This Logger is intended to be used in revng and in projects that depend
on it, as a guard for costly calls to verification functions that do not
need to be performed on a typical execution, but only when debugging.

For now the only user is JumpTargetManager, but other uses are already
envisioned.
2020-06-14 23:34:14 +02:00
Pietro Fezzardi 66873d9c26 Fix legacy::FunctionPassManager initialization and finalization.
This commit adds calls to
`legacy::FunctionPassManager::doInitialization()` and
`legacy::FunctionPassManager::doFinalization()` before and after calls
to `legacy::FunctionPassManager::run()`.

`legacy::FunctionPassManager`s must be explicitly initialized before
running and finalized after running.
Given that we used these managers only in two places and their are the
only ones that need explicit initialization and finalization, we forgot
to do it.

This caused problems with recent versions of llvm.
In particular, when compiled with aggressive optimizations (at least
`-O2`), missed initialization resulted in null pointers being
dereferenced, causing crashes.
The crashes were caused by the compiler optimizing away `nullptr` checks
on values returned from `getPSI`.
2020-06-06 02:25:45 +02:00
Alessandro Di Federico 2e0266ed05 mv {JumpTargetManager,BinaryFile}::nameForAddress 2020-06-02 21:14:56 +02:00
Alessandro Di Federico 3f79683c18 Drop CFG suffix from CFGForm::Values 2020-06-02 21:14:55 +02:00
Alessandro Di Federico 23f1a7b342 Reduce blocks analyzed by AVI
AVI and InstCombine are the bottleneck of the lifting process.
This commit introduces a whitelist of jump targets that are considered
by AVI during harvesting.
The whitelist is initialized by the jump targets that are new with
respect to the last run of AVI. Then, it's expanded with all the jump
targets that can reach the initial set of jump targets through direct
jumps.
2020-06-02 21:14:50 +02:00
Alessandro Di Federico b27beecc0f Preliminary harvesting: s/InstCombine/ConstProp/ 2020-06-02 10:57:02 +02:00
Alessandro Di Federico c202b989af AVI: drop one InstCombinePass
Preparing for AVI we used to run InstCombine twice in the
pipeline. Apparently, this was not acutally necessary.
2020-06-02 10:57:02 +02:00
Alessandro Di Federico 1f7b23bb5a Introduce harvesting statistics 2020-06-02 10:57:02 +02:00
Alessandro Di Federico d10178483d Introduce the new MetaAddress
Unlike the previous iteration of `MetaAddress`, which tried to stuff all
the parts of `MetaAddress` within the existing `PC` CSV, this
implementation adds a set of new CSVs (or marks some existing ones as) to
represent the four portions of the current PC's `MetaAddress`.

* Introduce `ProgramCounterHandler`: a class responsible to maintain the
  PC-related CSVs. This class is also used to manipulate the new
  dispatcher.
* `AdvancedValueInfo`: update for new MetaAddress.
* External jump handler: do not clobber registers.
  When introducing support for dynamic binaries, we didn't realize that
  in x86-64 we were clobbering `r11`. To avoid this, we have to jump to
  an address stored in memory. However, due to the new `MetaAddress`,
  obtaining a *jumpable* address from the PC-related CSVs might require
  some computations (and it does in ARM). Therefore, we introduce a new
  global variable, `jumpablepc`, whose only role is to contain the
  jumpable version of the program counter and then be the target of the
  memory-indirect jump instruction.
* Labels care only about absolute addresses.
* CSAA: mark call site, even if no accesses.
2020-06-02 10:57:02 +02:00
Alessandro Di Federico dc48188f37 Introduce MetaAddress
`MetaAddress` replaces all the `uint64_t` used to represent a virtual
address. Its main features are:

* It has a non-zero representation of invalid addresses.
* It supports tags to represent code that has different interpretations but
  resides at the same address in memory (namely ARM vs Thumb).
* Arithmetic operations cannot overflow.
* It supports epochs, a way we intend to employ to handle self-modifying code
  (i.e., different code at the same address at different times).
* It supports "address spaces", which enable handling architectures with
  multiple address spaces.
* It fits in two 64-bit registers.
2020-05-14 11:58:18 +02:00
Alessandro Di Federico 72fc95bda9 Purge OriginalInstructionAddresses when deleting
`JumpTargetManager::purgeTranslation` deletes some basic blocks that
need to re-translated, however references to some instructions remained
in `OriginalInstructionAddresses`.
2020-05-14 11:58:18 +02:00
Alessandro Di Federico 8deab9c7ea Whitespace and other minor changes
* Drop unused argument names from function prototypes
* Make `static` some methods
* Disable some copy constructors
* Fix casing of Doxygen `\file` directives
* Add some casts to make the compiler happy
* Initialize `hasRelocationAddend` for AArch64
* Use references in range-for where possible
* Drop default for `switch` statements covering all the entries of an `enum`
* Make some global variables `static`
* Drop dead functions
2020-05-14 11:58:18 +02:00
Andrea Gussoni 2896664cab JTM::readFromPointer: handle ConstantNullPointer 2020-02-27 11:57:34 +01:00
Alessandro Di Federico 7b2744f0ab Register ModuleAnalysisManager in new PassManager 2019-11-21 23:35:42 +01:00
Alessandro Di Federico ae8da14d46 Adopt FunctionCallee
`getOrInsertFunction` in LLVM 9 now returns `FunctionCallee`.
2019-11-21 20:52:55 +01:00
Alessandro Di Federico 0eb1bb583f Remove TerminatorInst
LLVM 9 drops the `TerminatorInst` class. This commit replaces it with
`Instruction` where possible and asserts
`Instruction::isTerminator()`. It also switches from
`TerminatorInst::successors` to `successors(TerminatorInst *)`.
2019-11-21 20:50:55 +01:00
Alessandro Di Federico c7e1c992de DropMarkerCalls: fix dangling pointer refs
`DropMarkerCalls` used to take an `ArrayRef<StringRef>` as an argument,
however the `ArrayRef` was copied in a class field, leading to a
reference to a temporary array.

This commit switches from `ArrayRef` to `SmallVector`.
2019-05-27 19:36:12 +02:00
Alessandro Di Federico b9ef70c8dc AdvancedValueInfo: handle pointer types 2019-05-27 19:36:12 +02:00
Alessandro Di Federico 877ba895af Rewrite get{BasicBlockPC,PrevPCWrite}
This commit reimplements `getBasicBlockPC` and `getPrevPCWrite` using
`BackwardBFSVisitor`, making them much more effective.
2019-05-27 19:36:12 +02:00
Alessandro Di Federico 5009074e9e Introduce AdvancedValueInfo for JT discovery
* Introduce `ShrinkInstructionOperandsPass`: a transformation shrinking
  operands and the results of instructions if they are
  zero/sign-extended immediately before and after the instruction.
* Introduce `ConstantRangeSet`: similar to `ConstantRange` but allows
  disjoint ranges.
* Introduce `MaterializedValue`: a class that can represent a constant
  value or a symbol plus offset pair.
* Introduce `DropHelperCallsPass`: a transformation removing calls to
  helpers and replacing them with a function call reading the CSVs that
  the helper reads and writing the CSVs that the helper writes
  (according to CSAA).
* Introduce `DropRangeMetadataPass`: a transformation dropping the
  `range` metadata, which, in certain situations, lowers the quality of
  the results provided by `LazyValueInfo`.
* Introduce `AdvancedValueInfo`: an analysis exploiting results of
  `LazyValueInfo` but collecting them as `ConstantRangeSet` with a
  monotone framework. It produces `MaterializedValue`.
* Anticipate linking of helpers: `AVI` requires `CSAA`, which requires
  helper functions to be linked in.
* Drop `--no-link`.
* Force x86-64 `DataLayout`.
* Reorganize harvesting to either collect simple literals or go with
  (incremental) `AVI`.
* Drop `SET`, `OSRA`, the reaching definition analysis, the
  `SimplifyComparisonsPass` and all the sumjump-related code: e now
  clone `root`, optimize it and analyze it with `AVI`.
* Temporarily drop the `NoReturnAnalysis`.
* Link `libLLVMInstCombine`, `libLLVMCodeGen` and `libLLVMPasses`.
* Introduce tests for `AdvancedValueInfo`,
  `ShrinkInstructionOperandsPass` and `ConstantRangeSet`.
* Fix test results.
* Add `llvm.bswap.i64` and `@pc` to the LLVM template module for unit
  tests.
2019-05-22 21:30:29 +02:00
Alessandro Di Federico 6ae3b6f22f Whitespace and other minor changes
* `GeneratedCodeBasicInfo::getCSVUsedByHelperCall` and
  `GeneratedCodeBasicInfo::extractCSVs`: make the call argument an
  `Instruction`.
* Introduce `blockByName`
* Introduce `getUniqueUser`.
* Fix linking issues.
2019-05-14 16:27:13 +02:00
Alessandro Di Federico 75914742d7 Use BlockType by name in metadata
We used to save the type of a block in the `revng.block.type` metadata
as a number. This commit serializes it as a string.

In order to do this, the `BlockType` enum has been promoted to a
namespace with the usual `getName` and `fromName` functions.
2019-03-06 09:04:58 +01:00
Alessandro Di Federico 53db84f7d6 s/revamb/revng/g 2019-02-11 16:09:23 +01:00