Reverse-Engineering Instruction Encodings (2001)
A 2001 USENIX paper on DERIVE, which reverse-engineers bit-level instruction encodings by feeding permutations of instructions to an assembler, covering MIPS, SPARC, Alpha, PowerPC and most of ARM and x86.
Extract
USENIX 2001 Paper [USENIX '01 Tech Program Index] Pp. 133–146 of the Proceedings A short version of this paper that only described the DERIVE solver appeared in the proceedings of the DYNAMO 2000 workshop [6]. Abstract Binary tools such as disassemblers, just-in-time compilers, and executable code rewriters need to have an explicit representation of how machine instructions are encoded. Unfortunately, writing encodings for an entire instruction set by hand is both tedious and error-prone. We describe DERIVE, a tool that extracts bit-level instruction encoding information from assemblers. The user provides DERIVE with assembly-level information about various instructions. DERIVE automatically reverse-engineers the encodings for those instructions from an assembler by feeding it permutations of instructions and analyzing the resulting machine code. DERIVE solves the entire MIPS, SPARC, Alpha, and PowerPC instruction sets, and almost all of the ARM and x86 instruction sets. Its output consists of C declarations that can be used by binary tools. To demonstrate the utility of DERIVE, we have built a code emitter generator that takes DERIVE’s output and produces C macros for code emission, which we have then used to rewrite a Java JIT backend. 1 Introduction Binary tools such as assemblers, debuggers, disassemblers, dynamic code generation systems [3, 8, 10, 15, 18], just-in-time compilers [4, 7, 12], and executable code rewriters [14, 21, 24] need to contain a representation of how machine instructions are encoded. For example, a JIT needs to know that the x86 instruction addl %ecx, %ebx corresponds to the bits 0x01cb (formed by a bitwise OR of the addl opcode 0x01c0 with 0x8 for the %ecx argument and 0x3 for the %ebx argument). Unfortunately, specifying instruction encodings with current tools requires looking up and detailing the offsets, sizes, and values of many instruction fields. Unsurprisingly, this process is both error-prone and tedious, especially for CISC machines such as the x86. Currently, system builders must transcribe instruction encodings from an architecture reference manual. We have built a tool called DERIVE that eliminates the need to specify many of the bit-level details of instruction layout. The user supplies DERIVE with an assembly-level description of an instruction set: instruction names and operand types (registers, immediates, or labels). DERIVE outputs a description of how each instruction is encoded, which is given in the …