Module type Backend.S

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.

type t

an abs

val delete : t -> unit

delete d is called when the disassembler is no longer needed.

It is safe now to free any data related with the disassembler.

val set_memory : t -> int64 -> Core_kernel.Bigstring.t -> off:int -> len:int -> unit

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.

val store_predicates : t -> bool -> unit

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.

val store_asm_string : t -> bool -> unit

store_asm_string dis on_off turns assembly string storage on or off.

When it is off it is not required to store assembly strings for each instruction in the queue, only for the last disassembled one.

It is off by default.

val insn_table : t -> Core_kernel.Bigstring.t

insn_table dis returns a string table for opcodes.

The table contains a sequence of null-terminated strings.

val reg_table : t -> Core_kernel.Bigstring.t

reg_table dis returns a string table for register names.

The table contains a sequence of null-terminated strings.

val predicates_clear : t -> unit

predicates_clear dis clears the set of predicates.

val predicates_push : t -> predicate -> unit

predicates_push dis p adds p to the set of predicates.

precondition: is_supported dis p.

val is_supported : t -> predicate -> bool

is_supported dis p is true if dis supports p.

val set_offset : t -> int -> unit

set_offset dis off sets the current offset to off.

val offset : t -> int

offset dis is the current offset.

val run : t -> unit

run dis runs the disassembler.

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.

val insns_clear : t -> unit

insns_clear dis clears the disassembler instructions queue.

val insns_size : t -> int

insns_size dis the length of the instruction queue.

val insn_size : t -> insn:int -> int

insn_size dis ~insn:n the nth instruction length.

val insn_name : t -> insn:int -> int

insn_name dis ~insn:n the nth instruction name.

val insn_code : t -> insn:int -> int

insn_name dis ~insn:n the nth instruction opcode.

The opcode name is represented as an offset to the insn_table dis string table in which each element is a null-terminated string.

val insn_offset : t -> insn:int -> int

insn_offset dis ~insn:n the offset of nth instruction.

val insn_asm_size : t -> insn:int -> int

insn_offset dis ~insn:n the nth instruction assembly string length.

val insn_asm_copy : t -> insn:int -> Regular.Std.Bytes.t -> unit

insn_asm_copy dis ~insn:n data copies the assembly string of the nth instruction.

val insn_satisfies : t -> insn:int -> predicate -> bool

insn_satisfies dis ~insn:n p is true if the nth instruction satisfies the predicate p.

val insn_ops_size : t -> insn:int -> int

insn_ops_size dis ~insn:n the number of operands.

val insn_op_type : t -> insn:int -> oper:int -> op

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.

Precondition: insn_op_type dis ~insn:n ~oper:m = Reg

val insn_op_reg_code : t -> insn:int -> oper:int -> int

insn_op_reg_name dis ~insn:n ~oper:m the register code.

Returns the register code of the operand m. The code is a unique number identifying the register (could be the same as insn_op_reg_name.

Precondition: insn_op_type dis ~insn:n ~oper:m = Reg

val insn_op_imm_value : t -> insn:int -> oper:int -> int64

insn_op_imm_value dis ~insn:n ~oper:m the immediate value.

Returns the value of the operand m.

Precondition: insn_op_type dis ~insn:n ~oper:m = Imm

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.

Precondition: insn_op_type dis ~insn:n ~oper:m = Imm

val insn_op_fmm_value : t -> insn:int -> oper:int -> float

insn_op_fmm_value the floating-point immediate value.

Returns the value of the operand m.

Precondition: insn_op_type dis ~insn:n ~oper:m = Fmm