Commit Graph

267 Commits

Author SHA1 Message Date
Alessandro Di Federico 6bb7f4e8f1 Declare prototype of non-static functions
Certain non-`static` functions were missing prototype declarations,
triggering a compiler warning.

This was due to a missing header or due to a bug in boost.

This commit resolves this situation.
2018-09-29 13:05:16 +02:00
Alessandro Di Federico 047ae0d4d8 Apply clang-format globally
This commit applies our `clang-format` rules globally. From now on, all
commits should respect our configuration file.

Pretty large change.
2018-09-21 20:08:45 +02:00
Alessandro Di Federico 960286f419 Reorder Boost includes
Include directives are groups by library, the groups should be sorted
from the most general (i.e., the STL) to the most specific (the local
includes).

This commit ensures that Boost includes are before LLVM includes.
2018-09-21 20:08:23 +02:00
Alessandro Di Federico 31e5d1c96f Add braces around else
Sometimes the true-branch of an `if` statement was using braces but the
false-branch was not. This commit fixes this.
2018-09-21 20:05:18 +02:00
Alessandro Di Federico 5513ae606c Force the text segment at 0x20000 on ARM
For a long time we had an issue on ARM: the linker would use as the
first page 0x10000. However, on many distros, that matches the first
page that can be mapped (see `/proc/sys/vm/mmap_min_addr`). Therefore,
this shouldn't be a problem, except the fact that the translated program
also needs the preceeding page for the (outer) ELF header.

We used to suggest users to run:

    echo 4096 | sudo tee /proc/sys/vm/mmap_min_addr

Now in our tests, we force the text segment page to be at 0x20000,
therefore, this will no longer be necessary.
2018-09-21 17:27:22 +02:00
Andrea Gussoni 500d77f43e Register and add among JT reasons FunctionSymbol
The symbol handling has been extended to register whether a symbol
represents a function or not. This information is then used to register,
during the global data harvesting phase, all the function symbols and
explicitly mark them through the "FunctionSymbol" `JTReason`.

We use this information during the CFEP harvesting phase to integrate
the information produced by the function boundaries detection with
potential unidentified CFEPs.

This option can be enabled with the `--use-debug-symbols`, which
supersedes `--use-sections`.
2018-09-20 17:52:10 +02:00
Alessandro Di Federico 1aa65aa211 Fix trivial bug in test_stackanalysis 2018-09-19 19:59:10 +02:00
Alessandro Di Federico 7fe00c08dd Rewrite the stack and introduce the ABI analyses
This is a very large commit importing the reviewed (and heavily
simplified) stack analysis and the new ABI analysis, which provides
information on the calling convention of each function and so on.

For an overview of the new analyses please consult OVERVIEW.md.
2018-09-18 15:58:20 +02:00
Alessandro Di Federico fb7ad64070 CMake: one argument per line
This commit simply reduces the length of lines in CMake by splitting the
statements over multiple lines. This is particularly useful when listing
the translation units composing a program/library. In fact, it makes
merge much easier.
2018-08-31 09:00:33 +02:00
Alessandro Di Federico 6b39f031e1 Generate as much debug info as possible in tests 2018-08-31 08:42:31 +02:00
Alessandro Di Federico a0f4e0bb41 Introduce new assertion framework
A set of assertion-related functions has been introduced:

* `revng_abort(message)`: aborts, in release builds too.
* `revng_check(what, message)`: asserts `what`, in release builds
  too. Also emits a `__builtin_assume`, that can lead to additional
  optimizations in clang.
* `revng_unreahcable(message)`: identical to `revng_abort`, but in
  release builds emits `__built_unreachable`.
* `revng_assert(what, message)`: asserts in debug builds, otherwise
  emits `sizeof(what)` (to suppress unused variable warnings) and
  `__builtin_assume`.

The adoption of these function has the following benefits:

* Nice stack traces.
* The developer can choose to enforce an `assert` (or an `unreachable`)
  at release-time too by using `check`/`abort`.
* Most warnings about unused variables in release mode should be gone.
* When using clang, the `assert`s become `assume`s, which might enable
  additional optimizations (with no run-time costs).
* The `assert(Condition && "Reason")` trick is no longer needed, we now
  have a proper argument.
2018-08-18 16:25:40 +02:00
Alessandro Di Federico 2d32074075 Remove cross-compiler autodetection 2018-05-31 17:04:16 +02:00
Alessandro Di Federico 0dc77e104f Introduce statistics
This class introduces the `RunningStatistics` class, which allows to
compute the mean and standard deviation of a set of numbers. These
values are computed incrementally and can be associated to a name. The
values computed by `RunningStatistics` can be dumped upon regular
program termination, `SIGABRT` and `SIGINT`. In practice they are
printed at the end of the program execution, even in case of asserts and
`Ctrl + C`. Moreover, `SIGUSR1` is used to trigger printing the
statistics without crashing the program.
2018-05-30 12:45:45 +02:00
Alessandro Di Federico 8c148607d3 Introduce ClassSentinel
Sometimes, dealing with move-semantics in C++ can be challenging. To
mitigate this problem, this commit introduces `ClassSentinel`, a simple
class that can be added as a member of a class and that will allow the
user to easily monitor if an instance of a class is used after being
moved in an unwanted way. To do so, simply call the
`ClassSentinel::check` method on the class member.

`ClassSentinel` performs similar (but less reliable) checks on usage of
destroyed objects.

`ClassSentinel` can also (optionally, though the `SENTINEL_STACKTRACES`
macro) collect stack traces of the points where the object was moved or
destroyed.

This commit also includes some basic testing for the class.
2018-05-30 12:45:45 +02:00
Alessandro Di Federico e407fc11a1 Various minor cleanups 2018-05-30 12:45:45 +02:00
Alessandro Di Federico 4eaa6f76e4 Force CMake to link libraries using full path
If CMake detects `libhello` correctly and it is present in the system
paths, it passes it to the linker as `-lhello`. However, sometimes, in
particular when linking Boost, the compiler detects a different version.

Forcing the CMake policy `CMP0060` to the new approach solves the
problem, since CMake now always uses the full path of the required
library, even if it's already available in the system paths.
2018-05-30 12:45:45 +02:00
Alessandro Di Federico 61cfbdfc56 Introduce support for dynamic binaries
This commit introduces support for dynamic programs. The current
implementation translate the main binary and uses native libraries. This
works only if the target architecture is the same as the source
one. Currently we only handle x86-64.

* The `ExternalJumpsHandler` class has been introduced. It basically
  takes care of extending the dispatcher handling the case in which the
  program counter is an address outside the range of executable
  addresses of the input program. In this case, a `setjmp` is perfomed,
  the CPU state is serialized to physical registers and jump to the
  value of the program counter is performed.

  Once the target code will try to return to the translated program, a
  segmentation fault will be triggered, a `longjmp` is performed and the
  CPU state is deserialized so that the execution can resume (from the
  dispatcher).

* `early-linked.c` has been introduced. Its purposes is to provide
  declarations of variables and functions defined in `support.c`. In the
  past, we had to manually create these definitions, a cumbersome and
  error prone we now avoid by letting `clang` compile `early-linked.c`
  and then linking it in.

* The old `support.h` is now known as `commonconstants.h`. `support.h`
  now contains declarations that have to be consumed by
  `early-linked.c`.

* Each architecture now provides additional information:

  1. Which registers are part of the ABI and have to be preserved. If
     necessary the QEMU name can be provided. For each register it's
     also possible to provide their position within the `mcontext_t`
     structure, provided by the signal handler.
  2. Three assembly snippets, one to write a register, one to read it
     and one perform an indirect jump.

  Some of this information is also exposed in the output module as
  metadata.

* `support.c` now installs a SIGSEGV signal handler. Since pages that
  were originally executable are no longer executable, jumping there
  (typically, from a library) will trigger a SIGSEGV that we will
  handle. This allows us to properly deserialize the CPU state and
  resume execution of the translate code.

* Now also a dynamic version of each test program is translated and
  tested.

* The `merge-dynamic.py` script has been introduced: it takes case of
  rewriting the translated binary so to tell the linker to performe both
  the relocations of the translate program and the relocations of the
  original program. It does so by rewriting a large portion of the
  sections employed by the dynamic linker such as `.dynamic`, `.dynsym`
  and so on.

* The `compile-time-constants.py` script has been introduced: it a
  user-specified compiler on a source file producing an object
  file. This object file is inspected and the value of global read-only
  variables is produced in a CSV.
2018-05-29 15:10:51 +02:00
Alessandro Di Federico 9c2bb85f30 Introduce printf test using %f
This test will be useful to test that calls to external libraries using
float arguments work as appropriate.
2018-05-29 08:43:17 +02:00
Alessandro Di Federico 0bd4204e07 In tests, use the translate script 2018-05-29 08:35:24 +02:00
Andrea Gussoni cf42e497aa Introduce the Function Isolation Pass
This commit introduces the Function Isolation Pass. We use the
information provided by the Function Boundaries Detection Pass to
organize the code that `revamb` places inside the `root` function in
different LLVM functions. To do this we obviously need to introduce some
changes and tricks to handle the execution of the translated program.

The main idea is to have two different realms (one where the isolated
functions live, one in which we have basically the old root function).
We start the execution from the realm of the *non isolated* functions,
and we transfer, as soon as possible, the execution to the *isolated
functions* realm. We then have a fallback mechanism to restore the
execution in the right place in the *non isolated* functions realm, and
so on.

The largest change, besides the re-organization of the code in different
functions, is the use of the exception handling mechanism provided by
the LLVM framework in order to be able to manage the switch between the
two realms.

We also introduce the `support.h` header file, which contains a couple
of definitions used by `support.c` and that need to be shared with some
of the components involved in the translation process. We have defined
some helper functions, directly in C, that we use both for handling the
exception mechanism and for giving extra debug informations when an
exception is raised.

The `revamb-dump` utility now supports the `-i` option to specify the
path were to save the new LLVM module.

The `translate` utility now supports the `-i` option that produces a
binary in which the function isolation has been applied.

We also introduced some tests that apply the function isolation pass to
the `Runtime/` tests already present. In this way we can verify that the
translation and the following function isolation preserve the behavior
of the program.

When serializing the new LLVM module we regenerate the metadata used for
debug purposes, and for doing this, since we not longer have only the
`root` function, we have changed some details in the `DebugHelper` class
in order to be able to emit the metadata for all the functions of our
interest in a single shot.
2018-04-22 15:19:36 +02:00
Alessandro Di Federico bbd3471266 Suppress signedness comparison warnings in tests 2018-01-28 14:08:45 +01:00
Thorbjörn Schulz 2f55d4ba76 Added i386 support
Added the necessary information for i386 support and a call to a helper
function initializing the global descriptor table at runtime.
2018-01-28 14:07:31 +01:00
Andrea Gussoni 0735acd2a0 Add checks for no-pie flag for cross-compilers
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.
2018-01-17 21:11:41 +01:00
Alessandro Di Federico cb8b34013e Enable -no-pie only if the compiler supports it
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.
2017-10-28 17:59:57 +02:00
Pietro Fezzardi 55eb769aae Add -no-pie to compiler flags
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.
2017-08-29 00:34:26 +02:00
Alessandro Di Federico a5af28621b Introducing the stack analysis
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.
2017-08-12 16:56:23 +02:00
Alessandro Di Federico d409390084 Unit testing for LazySmallBitVector
This commit introduces the unit test infrastructure, and a first unit
test suite for `LazySmallBitVector`.
2017-08-12 16:56:23 +02:00
Alessandro Di Federico b3ba517c8b Minor whitespace fixes and cleanups 2017-08-12 16:56:23 +02:00
Alessandro Di Federico d8f13c799d Detect try/catch landing pads
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.
2017-03-31 10:10:16 +02:00
Alessandro Di Federico 815c72a417 OSRA: introduce a new test for disjoint ranges
Since we now support disjoint ranges in ORSA, let's test it. This commit
also introduces some license disclaimers in tests assembly files.
2017-03-29 14:04:35 +02:00
Alessandro Di Federico c4221f1a4c Add a label to Analysis/check-* tests 2016-12-08 21:56:11 +01:00
Alessandro Di Federico f6b6138408 Introduce tests for the analyses
So far we only had end-to-end functionality testing. This commit
introduces a new part of the testsuite which allows to verify quickly if
the results that a certain analysis should give are changed or not. This
is vital to be able to make larger changes.

So far the test suite is composed by the most difficult case we support
(the uClibc ARM memset) and the typical lowering of switch statements
for ARM, MIPS and x86-64.

I'm so happy now.
2016-12-08 21:50:49 +01:00
Alessandro Di Federico a7f1097988 Improve testsuite
* Add a label for runtime and analysis tests
* Add support for per-test custom compile flags
2016-12-04 00:28:57 +01:00
Alessandro Di Federico f67f7aef77 Reorganize testsuite
So far the only tests we had were end to end tests to assess the
functionality of simple programs and, in particular, certain helper
functions. In the perspective of being able to test individual features,
and in particular check that we have no regressions in our analyses, we
isolated these end to end tests in the Runtime directory. We kept in the
root test directory the mechanism to compile a binary for a certain
architecture so that all the test types can use it.
2016-12-04 00:28:57 +01:00
Alessandro Di Federico bc6a732ad7 Don't compute function boundaries by default 2016-12-03 08:46:12 +01:00
Alessandro Di Federico 83ea2caacd Isolate ELF code and remove architecture parameter
This commit removes all the ELF-specific code from the `CodeGenerator`
class by creating a new class, `BinaryFile` which contains all the
information about the program that might be needed in an image format
independent way. However, `BinaryFile` has some fields which are
specific to ELF, we might want to address this when additional file
formats are supported.

A key benefit of isolating this code is that we can anticipate the
parsing of the input file, so that we have its architecture available
earlier than when `CodeGenerator` is instantiated, therefore we can drop
the `--architecture` parameter.
2016-12-03 08:46:12 +01:00
Alessandro Di Federico d48715494d Improve installation
* Use "$ORIGIN/../lib/" as RPATH when linking the installed binary
* Install also support material such as "support.c"
* Import the `translate` script for easy end-to-end translation
2016-09-22 22:44:16 +02:00
Alessandro Di Federico 59c871afc5 Make revamb portable
Add different search paths for QEMU components, in paritcular relative
to the program's path.
Also, install the revamb.
2016-09-22 18:45:59 +02:00
Alessandro Di Federico d01ee1f437 Copyright notices, license and credits 2016-09-21 01:45:26 +02:00
Alessandro Di Federico 53b1dfbb5d Improve autodetection of QEMU's location 2016-09-21 01:45:26 +02:00
Alessandro Di Federico b98c163c3e Implement the path function in support.c
The `path` function allows support.c to decide how to modify the path
opened by the translated program.
2016-09-21 01:45:26 +02:00
Alessandro Di Federico f0c12bfac4 Fixes to the testing infrastructure
* Disable PIE if enabled by default
* Link librt.so to compiled binaries (sometimes the QEMU runtime needs
  it)
* Replace `strtonum` with `int` in `awk` script
* Specify the compiler, not the triple
2016-09-21 01:45:26 +02:00
Alessandro Di Federico c7990ae60c Autodetect the compiler to use
Check in PATH if there's a compiler compatible with the supported ones
(i.e., using uclibc or musl) and use that triple.
2016-09-21 01:45:19 +02:00
Alessandro Di Federico 6c5c0ad8f7 Add support for using section information 2016-09-17 15:33:54 +02:00
Alessandro Di Federico 9487f0e400 Assign labels to tests 2016-09-17 15:33:54 +02:00
Alessandro Di Federico 994f518e14 Use ld.bfd linker as linker by default 2016-08-20 03:10:46 +02:00
Alessandro Di Federico 4e04f0eed5 Copy run-time files to build directory 2016-08-20 03:10:46 +02:00
Alessandro Di Federico db030d6757 Downgrade to CMake 2.8 2016-08-20 03:10:45 +02:00
Alessandro Di Federico 329fcb3707 Introduce tracing support 2016-08-20 03:10:45 +02:00
Alessandro Di Federico 0d035a93e1 Introduce clang support: fixes and cleanup 2016-08-20 03:10:45 +02:00