`cpu_loop_exit` is used by QEMU to get back control from the translated
code while running an helper. Here we complete the inversion of the
hierarchy by transforming calls to `cpu_loop_exit` into calls to our
customized `cpu_loop`, which will handle syscalls and the like.
Since originally `cpu_loop_exit` was a noreturn function, we also need to
ensure that the semantic of its usage is preserved. We do this by setting
a global variable (`cpu_loop_exiting`) right after the call to
`cpu_loop_exit` and forcing the whole call stack to return immediately
if it's true.
* Introduce `CpuLoopExitPass`: replace all the calls to
`cpu_loop_exit` with a call to `cpu_loop`, a store true to
`cpu_loop_exiting` and a return. Then take all the callers and make
them return if `cpu_loop_exiting` is set. Once we get to the translated
function just reset `cpu_loop_exiting` to false.
* Introduce `VariableManager::computeEnvAddress`: generate code to
compute the offset of env . This computation is useful when
reference to the CPU state must be arificially introduced. This code
will be flattened by `CorrectCPUStateUsagePass` later.
`cpu_loop` is the main program loop used by QEMU during emulation. Here
we are interested in transforming it in a simple handler of exceptions
(e.g. signals and syscalls).
* Introduce `CpuLoopFunctionPass`: remove the outermost backedge in
`cpu_loop` and replace the call to cpu_*_exec with the exception index.
* Implement the support function `find_unique` which returns the only
element in a range satisfying a predicate, or, otherwise, asserts.
* Expand the function to replace with no-op or abort
* Factor out the code to replace function bodies (replaceFunction and
replaceFunctionWithRet)
* Replace functions before linking, directly in the helper module
In certain cases we have a call to `exitTB` right after an helper, in
particular in x86, after a syscall. We cannot know what the target
address will be, so we have to handle this as an indirect jump.
* `JumpTargetManager::getPrevPCWrite`: clean up.
* `JumpTargetManager::getPrevPCWrite`: while searching for stores to the
PC, also check for call instructions. If one is met, return nullptr.
* `TranslateDirectBranchesPass::runOnFunction` and
`JumpTargetManager::translateIndirectJumps`: insert new code before
`exitTB`, not the write to the PC.
Currently we do not support access to pointer data types in the CPU state
structure. Now, since their usage is marginal, instead of failing at
compile-time we put an abort instruction when the code reaches that
point.
The same is done in case an access to an array member using a
non-constant index is performed.
* Move initialization and management of the structure describing the CPU
state (CPUStateType) into variablemanager.cpp.
* Support parts of CPU state outside "env" (e.g. the MIPSCPU
structure). Now "env" has an offset into the possibly larger CPU state
which we have to take into account where appropriate (see
VariableManager::envOffset).
* Link the helpers module into the generated module, including only what
is needed.
* Create some "no-op" or "abort" function corresponding to QEMU functions
not included in the helper module (e.g. logging and abort functions).
* Implement the CorrectCPUStateUsagePass pass, which starts from the
"env" global variable and looks for all its usages recursively, keeping
track of where pointers are pointing into the CPU state data structure,
and replaces all the load/stores with the global variable corresponding
to that specific field of the CPU state.
* After the linking phase, run SROA, the pass to adjust the CPU usage and
DCE.
* Let global variables have common linkage.
* Emit a call to an helper function (ExitTB) corresponding to each
exit_tb PTC instruction.
* Update TranslateDirectBranchesPass and
JumpTargetManager::translateIndirectJumps to look for the last write
to the PC before calls to ExitTB.
* Exposing the PC with JumpTargetManager::PC is not needed anymore. Users
from outside should only be interested in finding the the previous
write to the PC (using JumpTargetManager::getPrevPCWrite).
The main aim of these changes is to support `ret` instructions (that are
indirect jumps), so that function calls can now work properly.
* Emit a dummy call to a `@newPC` function to record where a new
instruction in the original assembly started, what is its PC and its
size. The `Size` parameter for these function call is initially zero,
and it's updated later when a new instruction is met or the current
basic block is terminated. All these calls, before the final emission
of the IR are removed `InstructionTranslator::removeNewPCMarkers`.
* Transform translateMoveToPC into an LLVM pass
(`TranslateDirectBranchesPass`).
* Implement `getNextPC`, which returns the next program counter by
looking for a call to `@newpc` in the current basic block, and,
recursively, in all the basic blocks dominating the current one. This
function is used to force exploration of the basic block coming after
a direct jump, which is paritcularly useful in case of a function call.
* Introduce `translateIndirectJumps`, which translates all the leftover
writes to the PC, i.e. all the indirect ones, by diverting execution
to a large switch statement mapping addresses in the original program
to the corresponding basic blocks in the translated program.
* Introduce `function_call`, a simple test for function calls.
* Other minor changes and whitespace fixes.
* mmap on the PTC side before doing any translation
* Update usages of virtual addresses
* Refactor options to have --load-at and --entry
* Update tests according to the changes
* Implement an handler for PTC_INSTRUCTION_op_debug_insn_start
* Implement an handler for calls to helpers
* Implement an handler for all the remaining instructions
* Discover automatically path of the helpers module
* Import the IRReader module
* Remove support for predefined global variables
* Implement getByCPUStateOffset which returns or creates a global
variable from an offset in the CPUState structure
* Remove the VariableManager::createGlobal function
* Implement getTypeAtOffset which searches for the data type at the
specified offset, recursively exploring sub-structs
* Autodetect the CPUState structure by election on the struct parameters
of the helper functions
* CodeGenerator::translate returns void
* Multiplication should sign-extend, not zero-extend
* Fix wrong update of alloca insertion point
* Implement PTC_INSTRUCTION_op_mul{u,s}2_i{32,64} instructions
* Don't output a source line if it's identical to the last printed one
* Invoke DIBuilder::finalize as appropriate
* Fix off-by-one in line number computation
* Create the CodeGenerator class from most of the logic that was in the
Translate function.
* Extract debug information handling logic from the Translate function and move
it into the DebugManager class.
* Add include guards.
* Remove some dead code and add and fix documentation.
* Add support to specify a path for debug source
* Annotate generated LLVM with original assembly and PTC
* As debug source, use the same .ll as the compiled one