In computing, binary translation (or (binary) recompilation) is the emulation of one instruction set by another through translation of binary code. Sequences of instructions are translated from the source to the target instruction set. In some cases such as instruction set simulation, the target instruction set may be the same as the source instruction set, providing testing and debugging features such as instruction trace, conditional breakpoints and hot spot detection.
Contents
- Motivation
- Static binary translation
- Examples for static binary translations
- Dynamic binary translation
- Examples for dynamic binary translations in software
- Examples for dynamic binary translations in hardware
- References
The two main types are static and dynamic binary translation. Translation can be done in hardware (for example, by circuits in a CPU) or in software (e.g. run-time engines, statical recompiler, emulators).
The smart microprocessor consists of a hardware VLIW core as its engine and a software layer called Code Morphing software. The Code Morphing software acts as a shell ... morphing or translating x86 instructions to native Crusoe instructions. In addition, the Code Morphing software contains a dynamic compiler and code optimizer ... The result is increased performance at the least amount of power. ... [This] allows Transmeta to evolve the VLIW hardware and Code Morphing software separately without affecting the huge base of software applications.
Motivation
Motivation for using the complex process of binary translation is either that a compilation of the source code to the destination platform or instruction set is not available (or technically problematic) or when the source code is plainly not available anymore (Abandonware).
Performance-wise static recompilations have the potential to achieve a better performance than real emulation approaches as in optimal case one overhead introducing interface is removed.
Static binary translation
A translator using static binary translation aims to convert all of the code of an executable file into code that runs on the target architecture without having to run the code first, as is done in dynamic binary translation. This is very difficult to do correctly, since not all the code can be discovered by the translator. For example, some parts of the executable may be reachable only through indirect branches, whose value is known only at run-time.
One such static binary translator uses universal superoptimizer peephole technology (developed by Sorav Bansal, and Alex Aiken from Stanford University) to perform efficient translation between possibly many source and target pairs, with considerably low development costs and high performance of the target binary. In experiments of PowerPC-to-x86 translations, some binaries even outperformed native versions, but on average they ran at two-thirds of native speed.
Examples for static binary translations
In 2014, an ARM architecture version of the 1998 video game StarCraft was generated by static recompilation and additional reverse engineering of the original x86 version. The Pandora handheld community was capable of developing the required tools on their own and achieving such translations successfully several times.
For instance, a successful x86-to-x64 static recompilation was generated for the procedural terrain generator of the video game Cube World in 2014.
Another example is the NES-to-x86 statically recompiled version of the videogame Super Mario Bros. which was generated under usage of LLVM in 2013.
In 2004 Scott Elliott and Phillip R. Hutchinson at Nintendo developed a tool to generate "C" code from Game Boy binary that could then be compiled for a new platform and linked against a hardware library for use in airline entertainment systems.
In 1995 Norman Ramsey at Bell Communications Research and Mary F. Fernandez at Department of Computer Science, Princeton University developed The New Jersey Machine-Code Toolkit that had the basic tools for static assembly translation.
Dynamic binary translation
Dynamic binary translation looks at a short sequence of code—typically on the order of a single basic block—then translates it and caches the resulting sequence. Code is only translated as it is discovered and when possible, and branch instructions are made to point to already translated and saved code (memoization).
Dynamic binary translation differs from simple emulation (eliminating the emulator's main read-decode-execute loop—a major performance bottleneck), paying for this by large overhead during translation time. This overhead is hopefully amortized as translated code sequences are executed multiple times.
More advanced dynamic translators employ dynamic recompilation where the translated code is instrumented to find out what portions are executed a large number of times, and these portions are optimized aggressively. This technique is reminiscent of a JIT compiler, and in fact such compilers (e.g. Sun's HotSpot technology) can be viewed as dynamic translators from a virtual instruction set (the bytecode) to a real one.
Examples for dynamic binary translations in software
The smart microprocessor consists of a hardware VLIW core as its engine and a software layer called Code Morphing software. The Code Morphing software acts as a shell ... morphing or translating x86 instructions to native Crusoe instructions. In addition, the Code Morphing software contains a dynamic compiler and code optimizer ... The result is increased performance at the least amount of power. ... [This] allows Transmeta to evolve the VLIW hardware and Code Morphing software separately without affecting the huge base of software applications.