Exemple #1
0
/**
 * insn_get_modrm - collect ModRM byte, if any
 * @insn:	&struct insn containing instruction
 *
 * Populates @insn->modrm and updates @insn->next_byte to point past the
 * ModRM byte, if any.  If necessary, first collects the preceding bytes
 * (prefixes and opcode(s)).  No effect if @insn->modrm.got is already 1.
 */
void insn_get_modrm(struct insn *insn)
{
    struct insn_field *modrm = &insn->modrm;
    insn_byte_t pfx_id, mod;
    if (modrm->got)
        return;
    if (!insn->opcode.got)
        insn_get_opcode(insn);

    if (inat_has_modrm(insn->attr)) {
        mod = get_next(insn_byte_t, insn);
        modrm->value = mod;
        modrm->nbytes = 1;
        if (inat_is_group(insn->attr)) {
            pfx_id = insn_last_prefix_id(insn);
            insn->attr = inat_get_group_attribute(mod, pfx_id,
                                                  insn->attr);
            if (insn_is_avx(insn) && !inat_accept_vex(insn->attr))
                insn->attr = 0;	/* This is bad */
        }
    }

    if (insn->x86_64 && inat_is_force64(insn->attr))
        insn->opnd_bytes = 8;
    modrm->got = 1;

err_out:
    return;
}
Exemple #2
0
insn_attr_t inat_get_avx_attribute(insn_byte_t opcode, insn_byte_t vex_m,
				   insn_byte_t vex_p)
{
	const insn_attr_t *table;
	if (vex_m > X86_VEX_M_MAX || vex_p > INAT_LSTPFX_MAX)
		return inat_zero_attrs;
	/* At first, this checks the master table */
	table = inat_avx_tables[vex_m][0];
	if (!table)
		return inat_zero_attrs;
	if (!inat_is_group(table[opcode]) && vex_p) {
		/* If this is not a group, get attribute directly */
		table = inat_avx_tables[vex_m][vex_p];
		if (!table)
			return inat_zero_attrs;
	}
	return table[opcode];
}
Exemple #3
0
/**
 * insn_get_opcode - collect opcode(s)
 * @insn:	&struct insn containing instruction
 *
 * Populates @insn->opcode, updates @insn->next_byte to point past the
 * opcode byte(s), and set @insn->attr (except for groups).
 * If necessary, first collects any preceding (prefix) bytes.
 * Sets @insn->opcode.value = opcode1.  No effect if @insn->opcode.got
 * is already 1.
 */
void insn_get_opcode(struct insn *insn)
{
    struct insn_field *opcode = &insn->opcode;
    insn_byte_t op;
    int pfx_id;
    if (opcode->got)
        return;
    if (!insn->prefixes.got)
        insn_get_prefixes(insn);

    /* Get first opcode */
    op = get_next(insn_byte_t, insn);
    opcode->bytes[0] = op;
    opcode->nbytes = 1;

    /* Check if there is VEX prefix or not */
    if (insn_is_avx(insn)) {
        insn_byte_t m, p;
        m = insn_vex_m_bits(insn);
        p = insn_vex_p_bits(insn);
        insn->attr = inat_get_avx_attribute(op, m, p);
        if (!inat_accept_vex(insn->attr) && !inat_is_group(insn->attr))
            insn->attr = 0;	/* This instruction is bad */
        goto end;	/* VEX has only 1 byte for opcode */
    }

    insn->attr = inat_get_opcode_attribute(op);
    while (inat_is_escape(insn->attr)) {
        /* Get escaped opcode */
        op = get_next(insn_byte_t, insn);
        opcode->bytes[opcode->nbytes++] = op;
        pfx_id = insn_last_prefix_id(insn);
        insn->attr = inat_get_escape_attribute(op, pfx_id, insn->attr);
    }
    if (inat_must_vex(insn->attr))
        insn->attr = 0;	/* This instruction is bad */
end:
    opcode->got = 1;

err_out:
    return;
}
/**
 * insn_get_modrm - collect ModRM byte, if any
 * @insn:	&struct insn containing instruction
 *
 * Populates @insn->modrm and updates @insn->next_byte to point past the
 * ModRM byte, if any.  If necessary, first collects the preceding bytes
 * (prefixes and opcode(s)).  No effect if @insn->modrm.got is already 1.
 */
void insn_get_modrm(struct insn *insn)
{
	struct insn_field *modrm = &insn->modrm;
	insn_byte_t pfx, mod;
	if (modrm->got)
		return;
	if (!insn->opcode.got)
		insn_get_opcode(insn);

	if (inat_has_modrm(insn->attr)) {
		mod = get_next(insn_byte_t, insn);
		modrm->value = mod;
		modrm->nbytes = 1;
		if (inat_is_group(insn->attr)) {
			pfx = insn_last_prefix(insn);
			insn->attr = inat_get_group_attribute(mod, pfx,
							      insn->attr);
		}
	}

	if (insn->x86_64 && inat_is_force64(insn->attr))
		insn->opnd_bytes = 8;
	modrm->got = 1;
}