Commit Graph

35 Commits

Author SHA1 Message Date
Alessandro Di Federico cc87ad607d Introduce NoreturnAnalysis
This commit introduces the `noreturn` analysis, whose aim is to detect
all the basic blocks the are doomed to lead to a `noreturn` syscall such
as `execve` or `exit`.

* Implement `NoreturnAnalysis`.
* Include and initialize in the `Architecture` data structure all the
  necessary information to detect `noreturn` syscalls. Specifically, the
  name of the QEMU helper for syscalls, the name of the register holding
  the syscall number and the syscall numbers representing `noreturn`
  syscalls.
* `ReachingDefinitionsPass`: make reaching definitions available both in
  reaching definitions mode and reached loads mode. This part needs
  further cleanup. We also might be willing to implement this with a
  `Boost.Bimap`.
* Use `SET` to collect information useful for the
  `NoreturnAnalysis`. Also restructure how the `OperationsStack` works
  to be more streamlined and keep track of multiple information about
  the instruction currently being tracked.
2016-09-17 15:33:57 +02:00
Alessandro Di Federico e9834e25b9 Exploit the power of unsigned comparisons
An unsigned comparison such as `x - 3 < 5` carries two information: the
first is the obvious one (`x < 8`), but the other one is even more
interesting. In fact any unsigned comparison implies that the LHS is not
negative, therefore we also can state that `x >= 3`. This commit
implements the usage of this information.
2016-09-17 15:33:56 +02:00
Alessandro Di Federico 621095c31a Create OSRs also for trunc and zext instructions 2016-09-17 15:33:56 +02:00
Alessandro Di Federico 65190dc20e OSRA: bugfixes about constant bounded values
* When creating a new `BoundedValue`, check if the value associated to
  it is a `ConstantInt` and if so, initialize the boundaries and the the
  signedness as appropriate.
* Add various checks for the presence of the signedness information
  before using functions that might require it.
2016-09-17 15:33:56 +02:00
Alessandro Di Federico 51d73d6b18 Register analysis passes as such 2016-09-17 15:33:56 +02:00
Alessandro Di Federico 46fe86225b Free memory after analyses
* Clear all the data that's not part of the analysis results at the end
  of the `runOnFunction` method
* Clear all the data that's part of the analysis results when the
  `PassManager` tells us so (`Pass::releaseMemory`)
* Do not use the `clear()` method, since it doesn't release memory
* Add some debugging information
2016-09-17 15:33:56 +02:00
Alessandro Di Federico 7e8ac596b5 Minimize pathSensitiveMerge usage
Record amount of reaching definitions for each load, even in
`ReachedLoads` mode, so that we can run the `pathSensitiveMerge` only
when we're sure we've collected all of them.
2016-09-17 15:33:55 +02:00
Alessandro Di Federico 168bac9079 Merge of BV: handle the [0,1] | [2,3] case 2016-09-17 15:33:55 +02:00
Alessandro Di Federico c1742184e7 OSRA: subscription for the update of load reachers
An instruction can now subscribe for the change of the list of reachers
of a certain load. This is particularly useful in the case of `ICmp`
instructions, which might hold constraints about the reachers of a
certain load without actually being a its user.
2016-09-17 15:33:55 +02:00
Alessandro Di Federico f4d71cf926 OSRA: improve handling of multi-defined loads
Before this commit, loads with multiple definitions were handled by
simply checking if all the definitions agreed. Now we also implement
some logic to put constraints on the new OSR, in case they don't agree.

To do this we implement a path-sensitive algorithm to collect
constraints about the reaching definitions.

This commit also introduce a set of methods to, if possible, apply an
OSR to a BoundedValue, e.g. [1 + 1 * x] will produce a new BoundedValue
whose bounds are shifted of 1 unit.
2016-09-17 15:33:54 +02:00
Alessandro Di Federico 37f54ffc8d Handle some undef cases building ConstantExprs
Some undefined behaviors, which result in `undef` values, are now
handled in `OSR::solveEquation`.
2016-09-17 15:33:54 +02:00
Alessandro Di Federico a372b878bd OSRA constraints: handle reaching definitions
In OSRA, when producing constraints associated to a `ICmpInst`
associated to a load instruction, consider also all of its reaching
definitions.

Moreover, when propagating constraints due to a `Br` instruction, look
for loads which might be affected by the constraints being propagated,
and, if necessary, update them.
2016-09-17 15:33:53 +02:00
Alessandro Di Federico 00a1e49f81 OSRA: handle load/store using reaching definitions
Use information from (`Conditional`)`ReachingDefinitionsPass` to
propagate OSRs and constraints when a load/store instruction is met.
2016-09-17 15:33:53 +02:00
Alessandro Di Federico deae1f841e SimplifyComparisonsPass: transform in analysis
* Add an "s" in the name
* Transform the pass in analysis and let OSRA use it
2016-09-17 15:33:53 +02:00
Alessandro Di Federico fcf9603456 Improve and isolate MemoryAccess
Isolate in its own file so that multiple class can benefit from it and
improve its potential performance.
2016-08-20 03:10:49 +02:00
Alessandro Di Federico ce5aa5507d Remove argument from OSRAPass::identifyOperands
Remove an useless argument from `OSRAPass::identifyOperands` and apply
some whitespace changes.
2016-08-20 03:10:49 +02:00
Alessandro Di Federico e3952732f0 OSRA: add proper support for constant - x
OSRA can now properly handle subtractions whose *first* operand is
constant.
2016-08-20 03:10:49 +02:00
Alessandro Di Federico 850fbf1bbe OSRA: represent constants as BV constraint
Constant OSR are now represented through an OSR such as
[0 + 1 * x with x = (*, c, c)]. Since equality doesn't hold any
signedness information we introduce a new signedness type (available
only in `BoundedValue`), `AnySignedness`, which is similar to
`UnknownSignedness` but does not trigger `isUninitialized() == true`.

In `BVMap` we also introduce the concept of "forced" constraint, i.e. a
constraint that is fixed, cannot be changed or update. Constant stores
will produce this type of constraints.
2016-08-20 03:10:49 +02:00
Alessandro Di Federico bfcb58bade Debug info: replace pointers with sensible names
This commit introduces the `getName` function, which, given a
BasicBlock, an Instruction or a Value, outputs a sensible name. In
particular instructions are now identified as [basic block]:[instruction
index].

`getName` is now used in the various `describe` methods in OSRA.
2016-08-20 03:10:48 +02:00
Alessandro Di Federico 8e589238bf Various bugfixes in merging BVs 2016-08-20 03:10:48 +02:00
Alessandro Di Federico ecdfab70a9 OSRA: don't propagate dead stores
Sometimes QEMU writes to register that are never used afterwards,
typically the `cmp` instruction sets several CPU flags which might be
ignored.

This becomes a problem when comparison are performed since they affect
the signedness of a BoundedValue. With this patch, we ignore their
effect if we can prove it's a dead store.
2016-08-20 03:10:48 +02:00
Alessandro Di Federico 7d55f3dd6b Handle multiple stores reaching a load
With this patch we basically handle a load as a sort of phi-node, since
we keep track of all the store/loads reaching a certain load, along with
their OSR, so that we can come up with smarter merging policies and
obtain more precise information.

This commit also introduce a change that leads to consider loads as
stores during propagation.  This heavily simplifies the store
propagation logic by considering load instruction as aliasing, and by,
consequently, propagating load (along with stores). This removes
completely the need for the concept of "conflicts".
2016-08-20 03:10:48 +02:00
Alessandro Di Federico d0f5944133 Factor out reusable data structures 2016-08-20 03:10:48 +02:00
Alessandro Di Federico 23818e9da4 OSRA: handle register-relative memory accesses
Introduce the `MemoryAccess` class which represents the source of a
`LoadInst` or the destination of a `StoreInst` for which we want to
propagate an OSR.

This patch handles more elegantly the propagation and introduces support
for propagating OSRs through register + offset memory accesses, in
particular stack pointer- (or base pointer-)relative memory accesses,
which are common in unoptimized code and that led to miss some cases
that we otherwise handle correctly.
2016-08-20 03:10:47 +02:00
Alessandro Di Federico 7d4e95b45e Associate BoundedValue to constant OSRs
The current modeling of constant OSRs prevent their merging on basic
blocks. This was due to the fact they had no `BoundedValue`
associated. This patch fixes this by representing them as:

    [120 + 0 * x, with x = (null, ?)]

instead of:

    [120 + 0 * x, with x = null]
2016-08-20 03:10:47 +02:00
Alessandro Di Federico 08be097123 Fix typos, add an assert, spread some const-ness 2016-08-20 03:10:47 +02:00
Alessandro Di Federico 4547b4731f Drop leftovers from weakness 2016-08-20 03:10:47 +02:00
Alessandro Di Federico 041ea8726d Introduce predecessors and successors 2016-08-20 03:10:47 +02:00
Alessandro Di Federico b3fb106d41 Handle change of an OSR's associated value
Enqueue users of an instruction if the value associated to its OSR
changes.
2016-08-20 03:10:46 +02:00
Alessandro Di Federico e39ae91a37 Improve OSRA's handling of overtaken values
Keep a map to associate overtaken and overtaker load/store values, and
keep it valid for the whole analysis.
2016-08-20 03:10:46 +02:00
Alessandro Di Federico 1a5fc0f519 Introduce collection of basic block statistics
Let revamb produce a CSV file containing statistics about the translated
input basic blocks for further analysis (e.g., identify false
positives).
2016-08-20 03:10:46 +02:00
Alessandro Di Federico 8d34cecb90 Catch undefined behavior due to excessive shift 2016-08-20 03:10:46 +02:00
Alessandro Di Federico eb8e589a4d Don't access boundedValue if it's not available 2016-08-20 03:10:46 +02:00
Alessandro Di Federico 6acc701b54 Documentation and some refactoring 2016-08-20 03:10:45 +02:00
Alessandro Di Federico fbca5bba2e Import OSRA and update SET
* Import OSRA
* Improve the SET (aka `JumpTargetFromConstants`) by introducing the
  `OperationsStack` class.
* Review `harvest` logic
* Allow to disable OSRA (along with the sumjump heuristic)
* Take the core of `getNextPC` out of it and move it to `getPC`, a
  function returning both the current and the next PC. Also, fix a bug
  when reaching the beginning of a basic block.
* Detect "reliable" jump targets: a "reliable" jump target is a jump
  target obtained from a store to a PC but it's not a fallthrough jump.
2016-08-20 03:10:39 +02:00