diff options
Diffstat (limited to 'tools/arch/x86/lib/insn.c')
| -rw-r--r-- | tools/arch/x86/lib/insn.c | 34 | 
1 files changed, 34 insertions, 0 deletions
diff --git a/tools/arch/x86/lib/insn.c b/tools/arch/x86/lib/insn.c index 79e048f1d902..0151dfc6da61 100644 --- a/tools/arch/x86/lib/insn.c +++ b/tools/arch/x86/lib/insn.c @@ -13,6 +13,8 @@  #include "../include/asm/inat.h"  #include "../include/asm/insn.h" +#include "../include/asm/emulate_prefix.h" +  /* Verify next sizeof(t) bytes can be on the same instruction */  #define validate_next(t, insn, n)	\  	((insn)->next_byte + sizeof(t) + n <= (insn)->end_kaddr) @@ -58,6 +60,36 @@ void insn_init(struct insn *insn, const void *kaddr, int buf_len, int x86_64)  		insn->addr_bytes = 4;  } +static const insn_byte_t xen_prefix[] = { __XEN_EMULATE_PREFIX }; +static const insn_byte_t kvm_prefix[] = { __KVM_EMULATE_PREFIX }; + +static int __insn_get_emulate_prefix(struct insn *insn, +				     const insn_byte_t *prefix, size_t len) +{ +	size_t i; + +	for (i = 0; i < len; i++) { +		if (peek_nbyte_next(insn_byte_t, insn, i) != prefix[i]) +			goto err_out; +	} + +	insn->emulate_prefix_size = len; +	insn->next_byte += len; + +	return 1; + +err_out: +	return 0; +} + +static void insn_get_emulate_prefix(struct insn *insn) +{ +	if (__insn_get_emulate_prefix(insn, xen_prefix, sizeof(xen_prefix))) +		return; + +	__insn_get_emulate_prefix(insn, kvm_prefix, sizeof(kvm_prefix)); +} +  /**   * insn_get_prefixes - scan x86 instruction prefix bytes   * @insn:	&struct insn containing instruction @@ -76,6 +108,8 @@ void insn_get_prefixes(struct insn *insn)  	if (prefixes->got)  		return; +	insn_get_emulate_prefix(insn); +  	nb = 0;  	lb = 0;  	b = peek_next(insn_byte_t, insn);  | 
