Legend:
Library
Module
Module type
Parameter
Class
Class type
The backend interface.
The backend is a simple automaton that disassembles instructions and pushes them into the queue. It runs until it either hits an instruction that matches with one of the previously set predicates or if it either hits an invalid instruction or runs out of the bounds of the specified memory region. On the high level the algorithm of the run function can be described with the following pseudocode.
1. disassemble instruction 2. push result into the queue 3. update the offset 4. if exists predicate p such that p(insn) or off >= length(data) then stop else goto 1.
If it is impossible to decode the given sequence of bytes, then an invalid instruction is pushed into the queue and disassembling continues on the next offset.
Predicates enables fine control over the behavior of the disassembler. For example, the Is_true predicate is always true disassembler will stop after each instruction. The backend is not required to support all predicates, only Is_true and Is_invalid are required.
The state of the disassembler includes the queue of disassembled instructions, the last disassembled instruction, the set of predicates, and the current offset. At the beginning, the queue and the set of predicates are empty, the offset is zero, and the last disassembled instruction is invalid.
To minimize allocations, opcodes and register names are represented as offsets in the corresponding string tables.
set_memory dis addr data ~off ~len sets the current memory region.
Sets the memory region accessible by disassembler to a substring of data starting at the offset off and having the length len with the first byte at off having the address addr.
Parameters off and len must be non-negative numbers. The offset dis shall be equal to 0 after this function is executed.
store_predicates dis on_off turns predicate storage on or off.
When it is off it is not required to store semantic predicates for each instruction in the queue, only for the last disassembled one. It is off by default.
The disassembler runs until it hits an instruction that matches one of the predicates in the disassemblers current set of predicates or it runs out of the boundaries of the currently specified memory region.
See the module description for the more detailed description of the backend algorithm.
insn_op_type dis ~insn:n ~oper:m the mth operand type.
val insn_op_reg_name : t->insn:int ->oper:int -> int
insn_op_reg_name dis ~insn:n ~oper:m the register name.
Returns the register name of the operand m. The name is represented as an offset to the reg_table dis, which is a string table of null-terminated strings.
val insn_op_imm_small_value : t->insn:int ->oper:int -> int
insn_op_imm_small_value dis ~insn:n ~oper:m the immediate value.
If the value v of the operand m is strictly greater than Int.min_val and is strictly less than Int.max_val then returns v otherwise returns Int.min_val or Int.max_val.