fsm
node_overflow(struct x86_decode_fsm *fsm, struct x86_instr *instr)
fsm->fn = NULL;
fsm_read(struct x86_decode_fsm *fsm, uint8_t *bytes, size_t n)
if (fsm->buf + n > fsm->end) {
memcpy(bytes, fsm->buf, n);
fsm_advance(struct x86_decode_fsm *fsm, size_t n,
fsm->buf += n;
if (fsm->buf > fsm->end) {
fsm->fn = node_overflow;
fsm->fn = fn;
node_movs(struct x86_decode_fsm *fsm, struct x86_instr *instr)
fsm_advance(fsm, 0, NULL);
node_cmps(struct x86_decode_fsm *fsm, struct x86_instr *instr)
fsm_advance(fsm, 0, NULL);
node_stlo(struct x86_decode_fsm *fsm, struct x86_instr *instr)
fsm_advance(fsm, 0, NULL);
node_dmo(struct x86_decode_fsm *fsm, struct x86_instr *instr)
if (fsm_read(fsm, (uint8_t *)&stdmo->u.dmo, adrsize) == -1) {
fsm_advance(fsm, adrsize, NULL);
node_immediate(struct x86_decode_fsm *fsm, struct x86_instr *instr)
if (fsm_read(fsm, (uint8_t *)&store->u.imm.data, immsize) == -1) {
fsm_advance(fsm, immsize, NULL);
node_disp(struct x86_decode_fsm *fsm, struct x86_instr *instr)
if (fsm_read(fsm, (uint8_t *)&data, n) == -1) {
if (__predict_true(fsm->is64bit)) {
fsm_advance(fsm, n, node_immediate);
fsm_advance(fsm, n, NULL);
node_dual(struct x86_decode_fsm *fsm, struct x86_instr *instr)
fsm_advance(fsm, 1, node_immediate);
fsm_advance(fsm, 1, NULL);
fsm_advance(fsm, 1, node_disp);
node_sib(struct x86_decode_fsm *fsm, struct x86_instr *instr)
if (fsm_read(fsm, &byte, sizeof(byte)) == -1) {
fsm_advance(fsm, 1, node_disp);
fsm_advance(fsm, 1, node_immediate);
fsm_advance(fsm, 1, NULL);
is_rip_relative(struct x86_decode_fsm *fsm, struct x86_instr *instr)
return (fsm->is64bit && /* RIP-relative only in 64bit mode */
is_disp32_only(struct x86_decode_fsm *fsm, struct x86_instr *instr)
return (!fsm->is64bit && /* no disp32-only in 64bit mode */
is_disp16_only(struct x86_decode_fsm *fsm, struct x86_instr *instr)
is_dual(struct x86_decode_fsm *fsm, struct x86_instr *instr)
node_regmodrm(struct x86_decode_fsm *fsm, struct x86_instr *instr)
if (fsm_read(fsm, &byte, sizeof(byte)) == -1) {
fsm_advance(fsm, 1, node_sib);
if (is_rip_relative(fsm, instr)) {
fsm_advance(fsm, 1, node_disp);
if (is_disp32_only(fsm, instr)) {
fsm_advance(fsm, 1, node_disp);
if (__predict_false(is_disp16_only(fsm, instr))) {
fsm_advance(fsm, 1, node_disp);
if (__predict_false(is_dual(fsm, instr))) {
fsm_advance(fsm, 0, node_dual);
fsm_advance(fsm, 1, node_immediate);
fsm_advance(fsm, 1, NULL);
fsm_advance(fsm, 1, node_immediate);
fsm_advance(fsm, 1, NULL);
fsm_advance(fsm, 1, node_disp);
get_operand_size(struct x86_decode_fsm *fsm, struct x86_instr *instr)
if (!fsm->is16bit) {
get_address_size(struct x86_decode_fsm *fsm, struct x86_instr *instr)
if (fsm->is64bit) {
if (fsm->is32bit) {
node_primary_opcode(struct x86_decode_fsm *fsm, struct x86_instr *instr)
if (fsm_read(fsm, &byte, sizeof(byte)) == -1) {
instr->operand_size = get_operand_size(fsm, instr);
instr->address_size = get_address_size(fsm, instr);
if (fsm->is64bit && (instr->operand_size == 4)) {
fsm_advance(fsm, 1, node_regmodrm);
fsm_advance(fsm, 1, node_dmo);
fsm_advance(fsm, 1, node_stlo);
fsm_advance(fsm, 1, node_movs);
fsm_advance(fsm, 1, node_cmps);
node_secondary_opcode(struct x86_decode_fsm *fsm, struct x86_instr *instr)
if (fsm_read(fsm, &byte, sizeof(byte)) == -1) {
instr->operand_size = get_operand_size(fsm, instr);
instr->address_size = get_address_size(fsm, instr);
if (fsm->is64bit && (instr->operand_size == 4)) {
fsm_advance(fsm, 1, node_regmodrm);
node_main(struct x86_decode_fsm *fsm, struct x86_instr *instr)
if (fsm_read(fsm, &byte, sizeof(byte)) == -1) {
fsm_advance(fsm, 1, node_secondary_opcode);
fsm->fn = node_primary_opcode;
fsm->fn = node_primary_opcode;
node_rex_prefix(struct x86_decode_fsm *fsm, struct x86_instr *instr)
if (fsm_read(fsm, &byte, sizeof(byte)) == -1) {
if (__predict_false(!fsm->is64bit)) {
fsm_advance(fsm, n, node_main);
node_legacy_prefix(struct x86_decode_fsm *fsm, struct x86_instr *instr)
if (fsm_read(fsm, &byte, sizeof(byte)) == -1) {
fsm_advance(fsm, 0, node_rex_prefix);
fsm_advance(fsm, 1, node_legacy_prefix);
struct x86_decode_fsm fsm;
fsm.is64bit = is_64bit(state);
fsm.is32bit = is_32bit(state);
fsm.is16bit = is_16bit(state);
fsm.fn = node_legacy_prefix;
fsm.buf = inst_bytes;
fsm.end = inst_bytes + inst_len;
while (fsm.fn != NULL) {
ret = (*fsm.fn)(&fsm, instr);
instr->len = fsm.buf - inst_bytes;
const struct fsm *fsm;
for (fsm = fs_magics; ; fsm++) {
if (fsm->mask == 0)
v = oldfs[fsm->offset];
if ((v & fsm->mask) == fsm->magic ||
(bswap32(v) & fsm->mask) == fsm->magic)
oldfs[fsm->offset] = 0;
const struct fsm *fsm;
for (fsm = fs_magics;; fsm++) {
if (fsm->mask == 0)
v = oldfs[fsm->offset];
if ((v & fsm->mask) == fsm->magic ||
(bswap32(v) & fsm->mask) == fsm->magic)
oldfs[fsm->offset] = 0;