Sometimes QEMU will emit code that reads a local temporary *before* it
is assigned in the `TranslationBlock`. This usually happens when lifting
non-code, but it's still a problem since it leads to phis around the
dispatcher, which we don't want.
For example, consider the following x86-64 code:
```
0000000140002000 <.text>:
140002000: f0 lock
140002001: 38 00 cmpb %al, (%rax)
```
It leads to:
```
[libtcg] Translation starting from 0x140002000:Generic64
[libtcg] ---- 0000000040002000
[libtcg] mov_i64 loc2,rax
[libtcg] mov_i64 loc1,rax
[libtcg] mov_i64 cc_src,loc1
[libtcg] mov_i64 loc8,loc0
[libtcg] sub_i64 cc_dst,loc0,loc1
[libtcg] discard cc_src2
[libtcg] discard cc_op
```
Note how `loc0` is read before being initialized.
Currently we zero-initialize all the temporaries. It would be in
princple possible to detect those that need the initialization, which
would also enable us to emit a warning.
This commit drops libptc in favor of its new form libtcg.
It brings several improvements, among which:
* The QEMU version we work on has been upgraded.
* CPUStateAccessAnalysis has been reimplemented in a way that makes it
easier to debug and solves some limitations (e.g., tracking leaking
pointers).
* Identification of pieces of the CPU state that are read by each helper
and fixing access to the CPU state is now performed at build-time.
* We no longer mmap the code we need to translate, dropping all the
issues related to code that needed to be mapped where something is
already present.
* We now have two distinct flavors of helper modules: the full one and
the "slim" one. The latter contains the definition only of functions
we intend to inline. It is used in most of the pipeline, a good thing
since we spend less time optimizing code we don't really care about.
The full module is only used on the re-compilation branch of the
pipeline.
* We no longer split the `cpu_loop` function.
* We change MetaAddress to rely on architectures from `model::` as
opposed to the LLVM ones.
* We no longer attach debug info to LLVM IR containing the original
assembly.
* We now verify that the lifted code only contains code we expect.
* Make the following private headers public:
* Lift/CPUStateAccessAnalysisPass.h
* Lift/CSVOffsets.h
* Lift/PTCDump.h
* Lift/VariableManager.h
* Move from revngSupport to revngLift:
* IRAnnotators.{h,cpp}
* SelfReferencingDbgAnnotationWriter.{h,cpp}
* Move from revngSupport to revngModel:
* FunctionTags.{h,cpp}
* ProgramCounterHandler.{h,cpp}
* Move from revngSupport to revngRecompile:
* OriginalAssemblyAnnotationWriter.{h,cpp}
This is a big step to split revng-lift in two parts: one that only
writes the model and one that actually lifts to LLVM IR.
* Introduce `revng import binary`
* Split off `BinaryFile.h`
* Drop `revng.h`
* `GeneratedCodeBasicInfo`: use model
* Reduce role of `GeneratedCodeBasicInfo` in favor of
`model::Architecture` and `model::Register` methods
* `CodeGenerator`: adopt `RawBinaryView` and model
* `JumpTargetManager`: adopt `RawBinaryView` and model
* `ExternalJumpsHandler`: adopt model
* `InstructionTranslator`: discard `Architecture` in favor of
`EndianessMismatch`
* Many other changes