Sometimes dynamic libraries linked to executables do not end in
`.so`. Previously, we assumed that a version of the library ending in
`.so` was available on the system. However, this is not always the
case. In particular, Ubuntu 16.04 links `ls` to `libselinux.so.1` but no
`libselinux.so` file is available. This can lead to a linking failure.
This commit, correctly handles libraries whose name doesn't end in `.so`
by using the `-l:` linker option (e.g., `-l:libselinux.so.1`).
When installing programs we used to add to `RPATH` the `../lib`
directory. However, this is not enough, since the analysis libraries
reside in `../lib/revng/analyses`. This commit fixes the issue.
Pass to the Global Value Numbering pass the `enable-pre=false` and
`enable-load-pre=false` since they have been identified as a major
source of slowdown with very large binaries.
This commit drops the old FunctionBoundariesDetectionPass and introduces
a new one based on the results provided by the StackAnalysis. A very
similar pass, the ABIDetectionPass, is now available to offer the
results of the ABI analysis too.
These two new passes are a thin shim depending on the appropriate
version of the StackAnalysis (with or withour ABI anlysis) and simply
call `serializeMetadata`, which decorates the LLVM IR with the requested
information.
In addition to drop the old analysis, this commit also isolates the
function boundaries detection pass from `revamb` making it available as
a library only.
This commit does the following:
* It drops `revamb-dump` and transforms all the passes it featured in
passes that can be used directly from `opt`.
* It rename `revamb` to `revng-lift`.
* It introduces a script called `revng` which acts as a driver for the
whole rev.ng project. It replaces `translate`, `revcc`,
`csv-to-ld-options` and `revamb-dump`, since it offers an `opt`
subcommand which allows to easily invoke all the analysis passes.
* It makes the project a CMake package that can be easily used
externally.
* It allows to easily create libraries of analysis to use through
`revng-opt`.
This commit lets the reaching definitions analysis employ results from
the stack analysis to propagate definitions across functions
calls. Specifically, the stack analysis provides a list of registers
that might be clobbered by the callee: definitions concerning those are
not propagated, all the others are propagated.
This change is key to detect jump tables whose address has been
materialized *before* a function call. A test for such situation has
been introduced.
To make this work, the RDA now works over the CFG provided by the
function identification analysis.
The `FunctionCallIdentification` analysis now provides a custom view on
the CFG where 1) dispatcher-related basic blocks are absent, 2) nodes
performing functions calls have an edge to their return address and 3)
nodes ending with a return instruction have no successor.
This CFG is now employed by the reaching definitions analysis and OSRA.
Additionally, the implementation of the `visitSuccessors` and
`visitPredecessors` method has been reviewed. It now consists in a class
that needs to be inherited and for which two methods should be
implemented, one to perform the visit of a block and another one to
enumerate the successors.
In addition, all the users of `visitSuccessors`/`visitPredecessors` have
been updated, a simple set of tests has been introduced and
`GeneratedCodeBasicInfo::visitPredecessors` has been dropped.
This commit fixes a problem that led to use SET to discover very very
simple jump targets: the return addresses of functions call.
Since in this situation, for each call, we needed to run SET, this
commit leads to a *huge* improvements in terms of translation
performance.
This commit also enforces renaming of the translated basic blocks after
they get split and update the ground truth for several analysis tests.
The Reaching Definitions Analysis used to ignore all the memory access
that were not relative to a CSV or an `alloca`. In certain situations,
in particular in x86 which makes heavy use of the stack, this led to
miss certain links that were vital for a correct identification of
certain jump targets.
As an example consider the following example:
cmp DWORD PTR [rbx+0x8],0x5
ja 4bc5c8 <uw_update_context_1+0x148>
mov eax,DWORD PTR [rbx+0x8]
movsxd rax,DWORD PTR [r12+rax*4]
add rax,r12
jmp rax
The constaint on `rbx+0x8` is not propagated to the use after the jump,
due to a missing link.
This commit fixes this by tracking all the memory accesses within the
expressive power of the `MemoryAccess` class, in particular those
expressed as register plus offset.
Additionally, this commit also makes RDA consider as reaching
definitions for a `load` only those definitions that match exactly the
load address, while previously we were considering all the `mayAlias`
definitions. This situation, in combination with the previous change,
led to have paths with multiple reaching definitions, which was
problematic for the path sensitive merge.
Finally, we consider a definition to be clobbered only if there's an
exact store to the esame address, instead of a store on an aliasing
address.
Programs without code (e.g., no executable segment) led to miss the
`env` variable, making the `CpuLoopExitPass` fail. This commit, fixes
the problem by simply populating the `cpu_loop_exit` function with a
`ret`.
In function isolation, every time we met a jump to an unexpected basic
block (i.e., a basic block that is not part of the current function), we
used to throw an exception. However this is unnecessary since oftentimes
it is sufficient to call the `function_dispatcher` or even perform a
regular function call.
The most obvious example is the case of a direct tail call. In this
situation performing a function call to the corresponding isolated
function is the most appopriate thing to do.
We used to black list memory portions target of memory read, so that
they couldn't become function entry points. However, this led to false
positives, in particular with functions that are explicitly called.
This commit ensures that we black list those addresses only if they are
not targets of function calls.
We now optimize `support.c`. We didn't do that since we were optimizing
everything after linking anyway, however, without `-O2`, functions in
`support.c` were getting an `optnone` attribute which inhibited any
optimization. In particular `newpc` and analogous functions were not
inlined. Resolving this issue led to a gigantic improvement in terms of
performance of the output program.
When optimizing a module to which function isolation has been applied the
`prune-eh` pass lead to several issues, specifically:
* `support.c` is now compiled with support for exceptions, to prevent
`raise_exception_helper` from being marked `nounwind` during the
link phase.
* Added a fake `ret` at the end of the `catchblock` to avoid promotion
of `invoke`s to regular `call`s.
* Marked the `invoke` instructions as `noinline`.
`revcc` is a simple script that forwards its arguments to a specified
compiler, except in the case in which the compiler is asked to link the
final program. In such case, the compiler is invoked as appropriate, but
the resulting binary is then translated using rev.ng and replaced by the
translated version.
We used to include `.` and `include/`, but the former is no longer
necessary and the latter has to have the highest priority to avoid that
installed headers take higher precedence, leading to a build employing
outdated headers.
This commit fixes an issue in OSRA with computations on constants. If a
constant was added to another constant, a new constant bounded value
would be created. However, such bounded value wouldn't get propagated
further. This commit fixes the problem by creating an OSRA relative to
the original constant plus an offset.
When going through basic blocks, FCI ignores basic blocks that have
already been identified as function calls. However, this lead to exclude
their fallthrough addresses from the list of fallthrough addresses.
This commit fixes this situation.
`getType` didn't have a `BlockType` to represent the entry basic block
of the `root` function. Therefore, such basic block was erroneously
identified as a translated basic block.
This commit forces the function call identification analysis during
harvesting of new basic blocks. Additionally, the appropriate jump
target reasons are associated to the involved basic blocks.