We now take advantage of a macro to add a series of compilation flags,
macro that also takes care of checking that the flags are supported by
the compiler.
This patch has been developed by Alessandro Di Federico.
The check to see if a compiler supports the `no-pie` flag was done only
for the main C compiler, and not for the cross-compilers used for
creating the executables for the different supported architectures.
This commit introduces the aforementioned missing checks.
In addition instead of hard-coding the flags to check in the CMakeLists
file we have a list that we pass each time we instantiate a project for
the cross-compilers, and we check for the availability of all the flags.
In order to do this we need to apply a sort of serialization and
deserialization to avoid the "unpack" of the list passed as argument to
the external project (that is implemented as a `;` separated string).
Also implemented a fix suggested in the merge request for a line that
mistakenly added the `TEST_CFLAGS` variable to the `NO_PIE` variable.
Many Linux distributions prevent programs from mapping memory pages at
low addresses. This can lead the translated program to segfault without
any additional explanation. This happens in particular with ARM
binaries, which tend to have the first segment allocated at very low
addresses.
This behavior can be configured through
`/proc/sys/vm/mmap_min_addr`. This commit introduces a warning to the
user in the `li-csv-to-ld-options` script in case a segment with an
address lower than `mmap_min_addr` is requested.
A previous commit introduced `-no-pie` to disable PIE in GCC versions
higher than 5.2. However, earlier versions don't support such an option.
This commit introduces the necessary detection mechanism to enable it or
not.
This commit introduces `value_type` in `LazySmallBitVector` to fix
compilation error on Boost versions newer than 1.65.
The bug was triggered in unit tests.
Add this flag to the flags used for Runtime tests and to the flags used
in the translate script.
Recent GCC versions (`gcc-7` and later) enable PIE by default, and
`-fno-pie` apparently is not enough to disable it.
This warning was introduced with gcc-7 to (quoting the documentation)
"Warn if the C++1z feature making noexcept part of a function type
changes the mangled name of a symbol relative to C++14. Enabled by -Wabi
and -Wc++1z-compat.".
It is triggered from the `GenericFunctor` class template. It can be
safely made not fatal, because this class template is not exposed
outside and the whole project is currently compiled with the same C++
standard compiler flags.
This commit adds machinery to `CMakeLists.txt` to make the warning not
fatal, but only if present. Disabling it when not present would trigger
build errors.
When we have an indirect call (or jump) we are sometimes able to
identify one or more possible targets, therefore, as an optimization,
before performing the indirect jump we check if the target is one of the
expected ones.
This optimization however was creating two issues with the handling of
indirect function calls: 1) the call to the `function_call` marker was
no longer positioned right before the terminator and 2) the function
call was no longer identified as an indirect function call but as call
to `anyPC`. This commit fixes these two issues.
These issues have been identified thanks to a report from Andrea
Gussoni.
The stack analysis is the foundation to obtain accurate information
about the body of a function, which registers are callee-saved,
arguments, return values and so on.
It is implemented as a pass to run in revamb-dump.
This commit also introduces analysis tests specific to what we aim to
obtain from the analysis and also some basic unit tests for data
structures related to the stack analysis.
`LazySmallBitVector` is a bit set data structure which holds up to 31/63
bits in place (depending on the pointer size), and if more than that is
needed, the required space is automatically allocated on the heap.
`LazySmallBitVector` also features lazyness, meaning that any bit index
that has never been set will return `false`, while every time a certain
bit needs to be set the data structure is automatically enlarged, if
necessary.
The `NoReturnAnalysis` now tracks, through metadata, not just the fact
that a basic block is a killer basic block, but also the reason why it
is. This let's the user know whether it's a killer because leads to an
actual killer basic block or because it is a killer syscall/endless
loop.
`GeneratedCodeBasicInfo` now exposes the instruction alignment of the
current architecture, the stack pointer register, the size of the PC
register, a reference to `anyPC` and correctly handles the
`DispatcherFail` basic block.
This commit extendes the FunctionCallIdentification pass to identify,
for each function call, where the return address is stored, i.e., the
link register. If the the return address is stored on the top of the
stack then the link register is `nullptr`.
This information is encoded as an extra argument to the marker
`function_call`.
This commit also makes the pass ignore dispatcher-related basic blocks
and ensures that calls to `function_call` are placed *before* calls to
`exitTB` so that they won't get purged.
Most of the times, when we need to get the next instruction, we actually
want to skip over "marker" function calls (e.g., calls to `newpc` and
`function_call`). `nextNonMarker` does exactly this.
`FunctionCallIdentification::isCall` and `JumpTargetManager::setCFGForm`
have also been extended to correctly handle such situations.
Serialization (in the form of the `revamb.jt.reasons` metadata) of the
reason why a certain address is a jump target has been moved from
`JumpTargetManager::finalizeJumpTargets` to a new function
(`JumpTargetManager::createJTReasonMD`) which is invoked after the
function boundaries detection algorithm has been run.
`JumpTargetManager::translateIndirectJumps` has been pushed into
`JumpTargetManager::finalizeJumpTargets`. Moreover, an safety check
about the removal of `exitTB` has been introduced.
* QuickMetadata has been expanded to get a `MDString` or a `MDTuple`
from a `StringRef`.
* Introducing `skipCasts`, which, given a `Value`, returns the innermost
part of the expression, skipping over casts.
* Introducing `isCallTo`, which, given an `Instruction`, returns whether
it's a call to a specific function or not. `getCallTo` is a sister
function to be used in `if` statements.
* Moving `skip` and `erase_if` in `ir-helpers.h` so that all the
translation unit can benefit from their usage.
`alloca` instruction are passed as variadic arguments to `newpc` to
prevent the optimizer from moving code around them. We used to cast them
all to `i8*`, however these casts where breaking the convention of
having all the `alloca` instructions at the beginning of the function.
Since these casts were not really necessary, they have now been dropped.
This commit introduces a new metadata (`revamb.jt.reasons`) containing a
list of reasons why the initial PC of the current basic block has been
identified as a jump target.
This commit fixes an assertion triggered by the fact that a segment
includes exclusively zero-initialized data (i.e., size on file is 0,
memory size is not). In this case LLVM detects the fact that the global
variable associated to the segment is composed exclusively composed by
0s and uses a `ConstantAggregateZero` as an initializer instead of a
`ConstantDataArray`.
Currently the solution is ignore that data, however, in the future it
might be beneficial to be able to read data from `.bss`, even if we just
have zeros there.
Thanks to Thorbjoern Schulz for reporting this bug.
This commit fixes some warnings given by GCC 6.3.0.
* Some `assert(false)` are not recognized as `noreturn`ing. They have
been replaced with `llvm_unreachable`.
* Added `-Wno-ignored-attributes`: attributes are not part the function
name mangling, and therefore they might create some problems when they
are involved in template arguments. We don't care.
* Specializations of `readPointer` functions in `binaryfile.h` are now
`inline`, so they don't appear as "unused" functions.
QEMU marks each input instruction with a special
pseudo-instruction. This commit makes revamb ignore such instructions
coming after a write to a `btarget` variable, which is an indication
that a delay slot is starting. In this way, the instruction will look
larger and re-translating part of it will not break the branch
instruction.
This simple commit should improve performance of the generated program
sensibly. Basically all the global variables will have internal linkage
from now on (unless the `--external` parameter is specified on the
command line). This way, the compiler will be able to avoid load/store
instructions when leaving code in the current translation unit.
In `translate -O2` we optimize the LLVM IR both with `llc` and
`opt`. However due to a bug in `translate`, `opt` was invoked but its
output was never used.
We used to assert that a `BoundedValue` must not have any entries in the
`Bounds` field before translating a `boost::icl` interval to a
`BoundedValue`. However, if the `Value` associated to the `BoundedValue`
is a `Constant`, we might have an entry in `BoundedValue::Bounds`
immediately after constructing the object. This commit fixes this
problem by simply updating the assertion and clearing the field before
re-populating it.
This commit introduces a docs target which translates `.rst` files into
man pages or HTML documents and installs them in `/usr/share/man/man1`
or `/usr/share/doc/revamb`.
Update `GeneratedIRReference.rst:` to reflect recent changes to the
`root` function. Specifically, the presence of the stack pointer
argument and initialization of the program counter and the stack
pointer.
`FromIRToExecutable.rst` has been updated too, to take into account the
new way we link `support.c`.
Finally, the `--tracing` argument has been removed from
`RevambUsage.rst` and the `-trace` argument is no documented in
`TranslateUsage.rst`.
While materializing values in SET through the `OperationStack` we used
to use as a type the type of the value associate to the currently used
`BoundedValue`. This was wrong, this patch uses the type on the free
operand on the top of the `OperationsStack` to perform the required
computations.
Landing pads are basically the `catch` blocks in C++ `try`/`catch`
statements. So far we were missing them since they are encoded in a
particular way in a way similar to DWARF debugging information in the
`.eh_frame` and, more specifically, in the `.gcc_except_table` sections
of ELF programs.
This commit parses these sections so that the basic blocks associated to
landing pads are correctly identified. Personality functions are
detected too. A test is also introduced to assess the effectiveness of
our code.