xref: /OK3568_Linux_fs/kernel/tools/arch/x86/lib/insn.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun // SPDX-License-Identifier: GPL-2.0-or-later
2*4882a593Smuzhiyun /*
3*4882a593Smuzhiyun  * x86 instruction analysis
4*4882a593Smuzhiyun  *
5*4882a593Smuzhiyun  * Copyright (C) IBM Corporation, 2002, 2004, 2009
6*4882a593Smuzhiyun  */
7*4882a593Smuzhiyun 
8*4882a593Smuzhiyun #ifdef __KERNEL__
9*4882a593Smuzhiyun #include <linux/string.h>
10*4882a593Smuzhiyun #else
11*4882a593Smuzhiyun #include <string.h>
12*4882a593Smuzhiyun #endif
13*4882a593Smuzhiyun #include "../include/asm/inat.h" /* __ignore_sync_check__ */
14*4882a593Smuzhiyun #include "../include/asm/insn.h" /* __ignore_sync_check__ */
15*4882a593Smuzhiyun 
16*4882a593Smuzhiyun #include <linux/errno.h>
17*4882a593Smuzhiyun #include <linux/kconfig.h>
18*4882a593Smuzhiyun 
19*4882a593Smuzhiyun #include "../include/asm/emulate_prefix.h" /* __ignore_sync_check__ */
20*4882a593Smuzhiyun 
21*4882a593Smuzhiyun /* Verify next sizeof(t) bytes can be on the same instruction */
22*4882a593Smuzhiyun #define validate_next(t, insn, n)	\
23*4882a593Smuzhiyun 	((insn)->next_byte + sizeof(t) + n <= (insn)->end_kaddr)
24*4882a593Smuzhiyun 
25*4882a593Smuzhiyun #define __get_next(t, insn)	\
26*4882a593Smuzhiyun 	({ t r = *(t*)insn->next_byte; insn->next_byte += sizeof(t); r; })
27*4882a593Smuzhiyun 
28*4882a593Smuzhiyun #define __peek_nbyte_next(t, insn, n)	\
29*4882a593Smuzhiyun 	({ t r = *(t*)((insn)->next_byte + n); r; })
30*4882a593Smuzhiyun 
31*4882a593Smuzhiyun #define get_next(t, insn)	\
32*4882a593Smuzhiyun 	({ if (unlikely(!validate_next(t, insn, 0))) goto err_out; __get_next(t, insn); })
33*4882a593Smuzhiyun 
34*4882a593Smuzhiyun #define peek_nbyte_next(t, insn, n)	\
35*4882a593Smuzhiyun 	({ if (unlikely(!validate_next(t, insn, n))) goto err_out; __peek_nbyte_next(t, insn, n); })
36*4882a593Smuzhiyun 
37*4882a593Smuzhiyun #define peek_next(t, insn)	peek_nbyte_next(t, insn, 0)
38*4882a593Smuzhiyun 
39*4882a593Smuzhiyun /**
40*4882a593Smuzhiyun  * insn_init() - initialize struct insn
41*4882a593Smuzhiyun  * @insn:	&struct insn to be initialized
42*4882a593Smuzhiyun  * @kaddr:	address (in kernel memory) of instruction (or copy thereof)
43*4882a593Smuzhiyun  * @x86_64:	!0 for 64-bit kernel or 64-bit app
44*4882a593Smuzhiyun  */
insn_init(struct insn * insn,const void * kaddr,int buf_len,int x86_64)45*4882a593Smuzhiyun void insn_init(struct insn *insn, const void *kaddr, int buf_len, int x86_64)
46*4882a593Smuzhiyun {
47*4882a593Smuzhiyun 	/*
48*4882a593Smuzhiyun 	 * Instructions longer than MAX_INSN_SIZE (15 bytes) are invalid
49*4882a593Smuzhiyun 	 * even if the input buffer is long enough to hold them.
50*4882a593Smuzhiyun 	 */
51*4882a593Smuzhiyun 	if (buf_len > MAX_INSN_SIZE)
52*4882a593Smuzhiyun 		buf_len = MAX_INSN_SIZE;
53*4882a593Smuzhiyun 
54*4882a593Smuzhiyun 	memset(insn, 0, sizeof(*insn));
55*4882a593Smuzhiyun 	insn->kaddr = kaddr;
56*4882a593Smuzhiyun 	insn->end_kaddr = kaddr + buf_len;
57*4882a593Smuzhiyun 	insn->next_byte = kaddr;
58*4882a593Smuzhiyun 	insn->x86_64 = x86_64 ? 1 : 0;
59*4882a593Smuzhiyun 	insn->opnd_bytes = 4;
60*4882a593Smuzhiyun 	if (x86_64)
61*4882a593Smuzhiyun 		insn->addr_bytes = 8;
62*4882a593Smuzhiyun 	else
63*4882a593Smuzhiyun 		insn->addr_bytes = 4;
64*4882a593Smuzhiyun }
65*4882a593Smuzhiyun 
66*4882a593Smuzhiyun static const insn_byte_t xen_prefix[] = { __XEN_EMULATE_PREFIX };
67*4882a593Smuzhiyun static const insn_byte_t kvm_prefix[] = { __KVM_EMULATE_PREFIX };
68*4882a593Smuzhiyun 
__insn_get_emulate_prefix(struct insn * insn,const insn_byte_t * prefix,size_t len)69*4882a593Smuzhiyun static int __insn_get_emulate_prefix(struct insn *insn,
70*4882a593Smuzhiyun 				     const insn_byte_t *prefix, size_t len)
71*4882a593Smuzhiyun {
72*4882a593Smuzhiyun 	size_t i;
73*4882a593Smuzhiyun 
74*4882a593Smuzhiyun 	for (i = 0; i < len; i++) {
75*4882a593Smuzhiyun 		if (peek_nbyte_next(insn_byte_t, insn, i) != prefix[i])
76*4882a593Smuzhiyun 			goto err_out;
77*4882a593Smuzhiyun 	}
78*4882a593Smuzhiyun 
79*4882a593Smuzhiyun 	insn->emulate_prefix_size = len;
80*4882a593Smuzhiyun 	insn->next_byte += len;
81*4882a593Smuzhiyun 
82*4882a593Smuzhiyun 	return 1;
83*4882a593Smuzhiyun 
84*4882a593Smuzhiyun err_out:
85*4882a593Smuzhiyun 	return 0;
86*4882a593Smuzhiyun }
87*4882a593Smuzhiyun 
insn_get_emulate_prefix(struct insn * insn)88*4882a593Smuzhiyun static void insn_get_emulate_prefix(struct insn *insn)
89*4882a593Smuzhiyun {
90*4882a593Smuzhiyun 	if (__insn_get_emulate_prefix(insn, xen_prefix, sizeof(xen_prefix)))
91*4882a593Smuzhiyun 		return;
92*4882a593Smuzhiyun 
93*4882a593Smuzhiyun 	__insn_get_emulate_prefix(insn, kvm_prefix, sizeof(kvm_prefix));
94*4882a593Smuzhiyun }
95*4882a593Smuzhiyun 
96*4882a593Smuzhiyun /**
97*4882a593Smuzhiyun  * insn_get_prefixes - scan x86 instruction prefix bytes
98*4882a593Smuzhiyun  * @insn:	&struct insn containing instruction
99*4882a593Smuzhiyun  *
100*4882a593Smuzhiyun  * Populates the @insn->prefixes bitmap, and updates @insn->next_byte
101*4882a593Smuzhiyun  * to point to the (first) opcode.  No effect if @insn->prefixes.got
102*4882a593Smuzhiyun  * is already set.
103*4882a593Smuzhiyun  *
104*4882a593Smuzhiyun  * * Returns:
105*4882a593Smuzhiyun  * 0:  on success
106*4882a593Smuzhiyun  * < 0: on error
107*4882a593Smuzhiyun  */
insn_get_prefixes(struct insn * insn)108*4882a593Smuzhiyun int insn_get_prefixes(struct insn *insn)
109*4882a593Smuzhiyun {
110*4882a593Smuzhiyun 	struct insn_field *prefixes = &insn->prefixes;
111*4882a593Smuzhiyun 	insn_attr_t attr;
112*4882a593Smuzhiyun 	insn_byte_t b, lb;
113*4882a593Smuzhiyun 	int i, nb;
114*4882a593Smuzhiyun 
115*4882a593Smuzhiyun 	if (prefixes->got)
116*4882a593Smuzhiyun 		return 0;
117*4882a593Smuzhiyun 
118*4882a593Smuzhiyun 	insn_get_emulate_prefix(insn);
119*4882a593Smuzhiyun 
120*4882a593Smuzhiyun 	nb = 0;
121*4882a593Smuzhiyun 	lb = 0;
122*4882a593Smuzhiyun 	b = peek_next(insn_byte_t, insn);
123*4882a593Smuzhiyun 	attr = inat_get_opcode_attribute(b);
124*4882a593Smuzhiyun 	while (inat_is_legacy_prefix(attr)) {
125*4882a593Smuzhiyun 		/* Skip if same prefix */
126*4882a593Smuzhiyun 		for (i = 0; i < nb; i++)
127*4882a593Smuzhiyun 			if (prefixes->bytes[i] == b)
128*4882a593Smuzhiyun 				goto found;
129*4882a593Smuzhiyun 		if (nb == 4)
130*4882a593Smuzhiyun 			/* Invalid instruction */
131*4882a593Smuzhiyun 			break;
132*4882a593Smuzhiyun 		prefixes->bytes[nb++] = b;
133*4882a593Smuzhiyun 		if (inat_is_address_size_prefix(attr)) {
134*4882a593Smuzhiyun 			/* address size switches 2/4 or 4/8 */
135*4882a593Smuzhiyun 			if (insn->x86_64)
136*4882a593Smuzhiyun 				insn->addr_bytes ^= 12;
137*4882a593Smuzhiyun 			else
138*4882a593Smuzhiyun 				insn->addr_bytes ^= 6;
139*4882a593Smuzhiyun 		} else if (inat_is_operand_size_prefix(attr)) {
140*4882a593Smuzhiyun 			/* oprand size switches 2/4 */
141*4882a593Smuzhiyun 			insn->opnd_bytes ^= 6;
142*4882a593Smuzhiyun 		}
143*4882a593Smuzhiyun found:
144*4882a593Smuzhiyun 		prefixes->nbytes++;
145*4882a593Smuzhiyun 		insn->next_byte++;
146*4882a593Smuzhiyun 		lb = b;
147*4882a593Smuzhiyun 		b = peek_next(insn_byte_t, insn);
148*4882a593Smuzhiyun 		attr = inat_get_opcode_attribute(b);
149*4882a593Smuzhiyun 	}
150*4882a593Smuzhiyun 	/* Set the last prefix */
151*4882a593Smuzhiyun 	if (lb && lb != insn->prefixes.bytes[3]) {
152*4882a593Smuzhiyun 		if (unlikely(insn->prefixes.bytes[3])) {
153*4882a593Smuzhiyun 			/* Swap the last prefix */
154*4882a593Smuzhiyun 			b = insn->prefixes.bytes[3];
155*4882a593Smuzhiyun 			for (i = 0; i < nb; i++)
156*4882a593Smuzhiyun 				if (prefixes->bytes[i] == lb)
157*4882a593Smuzhiyun 					prefixes->bytes[i] = b;
158*4882a593Smuzhiyun 		}
159*4882a593Smuzhiyun 		insn->prefixes.bytes[3] = lb;
160*4882a593Smuzhiyun 	}
161*4882a593Smuzhiyun 
162*4882a593Smuzhiyun 	/* Decode REX prefix */
163*4882a593Smuzhiyun 	if (insn->x86_64) {
164*4882a593Smuzhiyun 		b = peek_next(insn_byte_t, insn);
165*4882a593Smuzhiyun 		attr = inat_get_opcode_attribute(b);
166*4882a593Smuzhiyun 		if (inat_is_rex_prefix(attr)) {
167*4882a593Smuzhiyun 			insn->rex_prefix.value = b;
168*4882a593Smuzhiyun 			insn->rex_prefix.nbytes = 1;
169*4882a593Smuzhiyun 			insn->next_byte++;
170*4882a593Smuzhiyun 			if (X86_REX_W(b))
171*4882a593Smuzhiyun 				/* REX.W overrides opnd_size */
172*4882a593Smuzhiyun 				insn->opnd_bytes = 8;
173*4882a593Smuzhiyun 		}
174*4882a593Smuzhiyun 	}
175*4882a593Smuzhiyun 	insn->rex_prefix.got = 1;
176*4882a593Smuzhiyun 
177*4882a593Smuzhiyun 	/* Decode VEX prefix */
178*4882a593Smuzhiyun 	b = peek_next(insn_byte_t, insn);
179*4882a593Smuzhiyun 	attr = inat_get_opcode_attribute(b);
180*4882a593Smuzhiyun 	if (inat_is_vex_prefix(attr)) {
181*4882a593Smuzhiyun 		insn_byte_t b2 = peek_nbyte_next(insn_byte_t, insn, 1);
182*4882a593Smuzhiyun 		if (!insn->x86_64) {
183*4882a593Smuzhiyun 			/*
184*4882a593Smuzhiyun 			 * In 32-bits mode, if the [7:6] bits (mod bits of
185*4882a593Smuzhiyun 			 * ModRM) on the second byte are not 11b, it is
186*4882a593Smuzhiyun 			 * LDS or LES or BOUND.
187*4882a593Smuzhiyun 			 */
188*4882a593Smuzhiyun 			if (X86_MODRM_MOD(b2) != 3)
189*4882a593Smuzhiyun 				goto vex_end;
190*4882a593Smuzhiyun 		}
191*4882a593Smuzhiyun 		insn->vex_prefix.bytes[0] = b;
192*4882a593Smuzhiyun 		insn->vex_prefix.bytes[1] = b2;
193*4882a593Smuzhiyun 		if (inat_is_evex_prefix(attr)) {
194*4882a593Smuzhiyun 			b2 = peek_nbyte_next(insn_byte_t, insn, 2);
195*4882a593Smuzhiyun 			insn->vex_prefix.bytes[2] = b2;
196*4882a593Smuzhiyun 			b2 = peek_nbyte_next(insn_byte_t, insn, 3);
197*4882a593Smuzhiyun 			insn->vex_prefix.bytes[3] = b2;
198*4882a593Smuzhiyun 			insn->vex_prefix.nbytes = 4;
199*4882a593Smuzhiyun 			insn->next_byte += 4;
200*4882a593Smuzhiyun 			if (insn->x86_64 && X86_VEX_W(b2))
201*4882a593Smuzhiyun 				/* VEX.W overrides opnd_size */
202*4882a593Smuzhiyun 				insn->opnd_bytes = 8;
203*4882a593Smuzhiyun 		} else if (inat_is_vex3_prefix(attr)) {
204*4882a593Smuzhiyun 			b2 = peek_nbyte_next(insn_byte_t, insn, 2);
205*4882a593Smuzhiyun 			insn->vex_prefix.bytes[2] = b2;
206*4882a593Smuzhiyun 			insn->vex_prefix.nbytes = 3;
207*4882a593Smuzhiyun 			insn->next_byte += 3;
208*4882a593Smuzhiyun 			if (insn->x86_64 && X86_VEX_W(b2))
209*4882a593Smuzhiyun 				/* VEX.W overrides opnd_size */
210*4882a593Smuzhiyun 				insn->opnd_bytes = 8;
211*4882a593Smuzhiyun 		} else {
212*4882a593Smuzhiyun 			/*
213*4882a593Smuzhiyun 			 * For VEX2, fake VEX3-like byte#2.
214*4882a593Smuzhiyun 			 * Makes it easier to decode vex.W, vex.vvvv,
215*4882a593Smuzhiyun 			 * vex.L and vex.pp. Masking with 0x7f sets vex.W == 0.
216*4882a593Smuzhiyun 			 */
217*4882a593Smuzhiyun 			insn->vex_prefix.bytes[2] = b2 & 0x7f;
218*4882a593Smuzhiyun 			insn->vex_prefix.nbytes = 2;
219*4882a593Smuzhiyun 			insn->next_byte += 2;
220*4882a593Smuzhiyun 		}
221*4882a593Smuzhiyun 	}
222*4882a593Smuzhiyun vex_end:
223*4882a593Smuzhiyun 	insn->vex_prefix.got = 1;
224*4882a593Smuzhiyun 
225*4882a593Smuzhiyun 	prefixes->got = 1;
226*4882a593Smuzhiyun 
227*4882a593Smuzhiyun 	return 0;
228*4882a593Smuzhiyun 
229*4882a593Smuzhiyun err_out:
230*4882a593Smuzhiyun 	return -ENODATA;
231*4882a593Smuzhiyun }
232*4882a593Smuzhiyun 
233*4882a593Smuzhiyun /**
234*4882a593Smuzhiyun  * insn_get_opcode - collect opcode(s)
235*4882a593Smuzhiyun  * @insn:	&struct insn containing instruction
236*4882a593Smuzhiyun  *
237*4882a593Smuzhiyun  * Populates @insn->opcode, updates @insn->next_byte to point past the
238*4882a593Smuzhiyun  * opcode byte(s), and set @insn->attr (except for groups).
239*4882a593Smuzhiyun  * If necessary, first collects any preceding (prefix) bytes.
240*4882a593Smuzhiyun  * Sets @insn->opcode.value = opcode1.  No effect if @insn->opcode.got
241*4882a593Smuzhiyun  * is already 1.
242*4882a593Smuzhiyun  *
243*4882a593Smuzhiyun  * Returns:
244*4882a593Smuzhiyun  * 0:  on success
245*4882a593Smuzhiyun  * < 0: on error
246*4882a593Smuzhiyun  */
insn_get_opcode(struct insn * insn)247*4882a593Smuzhiyun int insn_get_opcode(struct insn *insn)
248*4882a593Smuzhiyun {
249*4882a593Smuzhiyun 	struct insn_field *opcode = &insn->opcode;
250*4882a593Smuzhiyun 	int pfx_id, ret;
251*4882a593Smuzhiyun 	insn_byte_t op;
252*4882a593Smuzhiyun 
253*4882a593Smuzhiyun 	if (opcode->got)
254*4882a593Smuzhiyun 		return 0;
255*4882a593Smuzhiyun 
256*4882a593Smuzhiyun 	if (!insn->prefixes.got) {
257*4882a593Smuzhiyun 		ret = insn_get_prefixes(insn);
258*4882a593Smuzhiyun 		if (ret)
259*4882a593Smuzhiyun 			return ret;
260*4882a593Smuzhiyun 	}
261*4882a593Smuzhiyun 
262*4882a593Smuzhiyun 	/* Get first opcode */
263*4882a593Smuzhiyun 	op = get_next(insn_byte_t, insn);
264*4882a593Smuzhiyun 	opcode->bytes[0] = op;
265*4882a593Smuzhiyun 	opcode->nbytes = 1;
266*4882a593Smuzhiyun 
267*4882a593Smuzhiyun 	/* Check if there is VEX prefix or not */
268*4882a593Smuzhiyun 	if (insn_is_avx(insn)) {
269*4882a593Smuzhiyun 		insn_byte_t m, p;
270*4882a593Smuzhiyun 		m = insn_vex_m_bits(insn);
271*4882a593Smuzhiyun 		p = insn_vex_p_bits(insn);
272*4882a593Smuzhiyun 		insn->attr = inat_get_avx_attribute(op, m, p);
273*4882a593Smuzhiyun 		if ((inat_must_evex(insn->attr) && !insn_is_evex(insn)) ||
274*4882a593Smuzhiyun 		    (!inat_accept_vex(insn->attr) &&
275*4882a593Smuzhiyun 		     !inat_is_group(insn->attr))) {
276*4882a593Smuzhiyun 			/* This instruction is bad */
277*4882a593Smuzhiyun 			insn->attr = 0;
278*4882a593Smuzhiyun 			return -EINVAL;
279*4882a593Smuzhiyun 		}
280*4882a593Smuzhiyun 		/* VEX has only 1 byte for opcode */
281*4882a593Smuzhiyun 		goto end;
282*4882a593Smuzhiyun 	}
283*4882a593Smuzhiyun 
284*4882a593Smuzhiyun 	insn->attr = inat_get_opcode_attribute(op);
285*4882a593Smuzhiyun 	while (inat_is_escape(insn->attr)) {
286*4882a593Smuzhiyun 		/* Get escaped opcode */
287*4882a593Smuzhiyun 		op = get_next(insn_byte_t, insn);
288*4882a593Smuzhiyun 		opcode->bytes[opcode->nbytes++] = op;
289*4882a593Smuzhiyun 		pfx_id = insn_last_prefix_id(insn);
290*4882a593Smuzhiyun 		insn->attr = inat_get_escape_attribute(op, pfx_id, insn->attr);
291*4882a593Smuzhiyun 	}
292*4882a593Smuzhiyun 
293*4882a593Smuzhiyun 	if (inat_must_vex(insn->attr)) {
294*4882a593Smuzhiyun 		/* This instruction is bad */
295*4882a593Smuzhiyun 		insn->attr = 0;
296*4882a593Smuzhiyun 		return -EINVAL;
297*4882a593Smuzhiyun 	}
298*4882a593Smuzhiyun end:
299*4882a593Smuzhiyun 	opcode->got = 1;
300*4882a593Smuzhiyun 	return 0;
301*4882a593Smuzhiyun 
302*4882a593Smuzhiyun err_out:
303*4882a593Smuzhiyun 	return -ENODATA;
304*4882a593Smuzhiyun }
305*4882a593Smuzhiyun 
306*4882a593Smuzhiyun /**
307*4882a593Smuzhiyun  * insn_get_modrm - collect ModRM byte, if any
308*4882a593Smuzhiyun  * @insn:	&struct insn containing instruction
309*4882a593Smuzhiyun  *
310*4882a593Smuzhiyun  * Populates @insn->modrm and updates @insn->next_byte to point past the
311*4882a593Smuzhiyun  * ModRM byte, if any.  If necessary, first collects the preceding bytes
312*4882a593Smuzhiyun  * (prefixes and opcode(s)).  No effect if @insn->modrm.got is already 1.
313*4882a593Smuzhiyun  *
314*4882a593Smuzhiyun  * Returns:
315*4882a593Smuzhiyun  * 0:  on success
316*4882a593Smuzhiyun  * < 0: on error
317*4882a593Smuzhiyun  */
insn_get_modrm(struct insn * insn)318*4882a593Smuzhiyun int insn_get_modrm(struct insn *insn)
319*4882a593Smuzhiyun {
320*4882a593Smuzhiyun 	struct insn_field *modrm = &insn->modrm;
321*4882a593Smuzhiyun 	insn_byte_t pfx_id, mod;
322*4882a593Smuzhiyun 	int ret;
323*4882a593Smuzhiyun 
324*4882a593Smuzhiyun 	if (modrm->got)
325*4882a593Smuzhiyun 		return 0;
326*4882a593Smuzhiyun 
327*4882a593Smuzhiyun 	if (!insn->opcode.got) {
328*4882a593Smuzhiyun 		ret = insn_get_opcode(insn);
329*4882a593Smuzhiyun 		if (ret)
330*4882a593Smuzhiyun 			return ret;
331*4882a593Smuzhiyun 	}
332*4882a593Smuzhiyun 
333*4882a593Smuzhiyun 	if (inat_has_modrm(insn->attr)) {
334*4882a593Smuzhiyun 		mod = get_next(insn_byte_t, insn);
335*4882a593Smuzhiyun 		modrm->value = mod;
336*4882a593Smuzhiyun 		modrm->nbytes = 1;
337*4882a593Smuzhiyun 		if (inat_is_group(insn->attr)) {
338*4882a593Smuzhiyun 			pfx_id = insn_last_prefix_id(insn);
339*4882a593Smuzhiyun 			insn->attr = inat_get_group_attribute(mod, pfx_id,
340*4882a593Smuzhiyun 							      insn->attr);
341*4882a593Smuzhiyun 			if (insn_is_avx(insn) && !inat_accept_vex(insn->attr)) {
342*4882a593Smuzhiyun 				/* Bad insn */
343*4882a593Smuzhiyun 				insn->attr = 0;
344*4882a593Smuzhiyun 				return -EINVAL;
345*4882a593Smuzhiyun 			}
346*4882a593Smuzhiyun 		}
347*4882a593Smuzhiyun 	}
348*4882a593Smuzhiyun 
349*4882a593Smuzhiyun 	if (insn->x86_64 && inat_is_force64(insn->attr))
350*4882a593Smuzhiyun 		insn->opnd_bytes = 8;
351*4882a593Smuzhiyun 
352*4882a593Smuzhiyun 	modrm->got = 1;
353*4882a593Smuzhiyun 	return 0;
354*4882a593Smuzhiyun 
355*4882a593Smuzhiyun err_out:
356*4882a593Smuzhiyun 	return -ENODATA;
357*4882a593Smuzhiyun }
358*4882a593Smuzhiyun 
359*4882a593Smuzhiyun 
360*4882a593Smuzhiyun /**
361*4882a593Smuzhiyun  * insn_rip_relative() - Does instruction use RIP-relative addressing mode?
362*4882a593Smuzhiyun  * @insn:	&struct insn containing instruction
363*4882a593Smuzhiyun  *
364*4882a593Smuzhiyun  * If necessary, first collects the instruction up to and including the
365*4882a593Smuzhiyun  * ModRM byte.  No effect if @insn->x86_64 is 0.
366*4882a593Smuzhiyun  */
insn_rip_relative(struct insn * insn)367*4882a593Smuzhiyun int insn_rip_relative(struct insn *insn)
368*4882a593Smuzhiyun {
369*4882a593Smuzhiyun 	struct insn_field *modrm = &insn->modrm;
370*4882a593Smuzhiyun 	int ret;
371*4882a593Smuzhiyun 
372*4882a593Smuzhiyun 	if (!insn->x86_64)
373*4882a593Smuzhiyun 		return 0;
374*4882a593Smuzhiyun 
375*4882a593Smuzhiyun 	if (!modrm->got) {
376*4882a593Smuzhiyun 		ret = insn_get_modrm(insn);
377*4882a593Smuzhiyun 		if (ret)
378*4882a593Smuzhiyun 			return 0;
379*4882a593Smuzhiyun 	}
380*4882a593Smuzhiyun 	/*
381*4882a593Smuzhiyun 	 * For rip-relative instructions, the mod field (top 2 bits)
382*4882a593Smuzhiyun 	 * is zero and the r/m field (bottom 3 bits) is 0x5.
383*4882a593Smuzhiyun 	 */
384*4882a593Smuzhiyun 	return (modrm->nbytes && (modrm->value & 0xc7) == 0x5);
385*4882a593Smuzhiyun }
386*4882a593Smuzhiyun 
387*4882a593Smuzhiyun /**
388*4882a593Smuzhiyun  * insn_get_sib() - Get the SIB byte of instruction
389*4882a593Smuzhiyun  * @insn:	&struct insn containing instruction
390*4882a593Smuzhiyun  *
391*4882a593Smuzhiyun  * If necessary, first collects the instruction up to and including the
392*4882a593Smuzhiyun  * ModRM byte.
393*4882a593Smuzhiyun  *
394*4882a593Smuzhiyun  * Returns:
395*4882a593Smuzhiyun  * 0: if decoding succeeded
396*4882a593Smuzhiyun  * < 0: otherwise.
397*4882a593Smuzhiyun  */
insn_get_sib(struct insn * insn)398*4882a593Smuzhiyun int insn_get_sib(struct insn *insn)
399*4882a593Smuzhiyun {
400*4882a593Smuzhiyun 	insn_byte_t modrm;
401*4882a593Smuzhiyun 	int ret;
402*4882a593Smuzhiyun 
403*4882a593Smuzhiyun 	if (insn->sib.got)
404*4882a593Smuzhiyun 		return 0;
405*4882a593Smuzhiyun 
406*4882a593Smuzhiyun 	if (!insn->modrm.got) {
407*4882a593Smuzhiyun 		ret = insn_get_modrm(insn);
408*4882a593Smuzhiyun 		if (ret)
409*4882a593Smuzhiyun 			return ret;
410*4882a593Smuzhiyun 	}
411*4882a593Smuzhiyun 
412*4882a593Smuzhiyun 	if (insn->modrm.nbytes) {
413*4882a593Smuzhiyun 		modrm = (insn_byte_t)insn->modrm.value;
414*4882a593Smuzhiyun 		if (insn->addr_bytes != 2 &&
415*4882a593Smuzhiyun 		    X86_MODRM_MOD(modrm) != 3 && X86_MODRM_RM(modrm) == 4) {
416*4882a593Smuzhiyun 			insn->sib.value = get_next(insn_byte_t, insn);
417*4882a593Smuzhiyun 			insn->sib.nbytes = 1;
418*4882a593Smuzhiyun 		}
419*4882a593Smuzhiyun 	}
420*4882a593Smuzhiyun 	insn->sib.got = 1;
421*4882a593Smuzhiyun 
422*4882a593Smuzhiyun 	return 0;
423*4882a593Smuzhiyun 
424*4882a593Smuzhiyun err_out:
425*4882a593Smuzhiyun 	return -ENODATA;
426*4882a593Smuzhiyun }
427*4882a593Smuzhiyun 
428*4882a593Smuzhiyun 
429*4882a593Smuzhiyun /**
430*4882a593Smuzhiyun  * insn_get_displacement() - Get the displacement of instruction
431*4882a593Smuzhiyun  * @insn:	&struct insn containing instruction
432*4882a593Smuzhiyun  *
433*4882a593Smuzhiyun  * If necessary, first collects the instruction up to and including the
434*4882a593Smuzhiyun  * SIB byte.
435*4882a593Smuzhiyun  * Displacement value is sign-expanded.
436*4882a593Smuzhiyun  *
437*4882a593Smuzhiyun  * * Returns:
438*4882a593Smuzhiyun  * 0: if decoding succeeded
439*4882a593Smuzhiyun  * < 0: otherwise.
440*4882a593Smuzhiyun  */
insn_get_displacement(struct insn * insn)441*4882a593Smuzhiyun int insn_get_displacement(struct insn *insn)
442*4882a593Smuzhiyun {
443*4882a593Smuzhiyun 	insn_byte_t mod, rm, base;
444*4882a593Smuzhiyun 	int ret;
445*4882a593Smuzhiyun 
446*4882a593Smuzhiyun 	if (insn->displacement.got)
447*4882a593Smuzhiyun 		return 0;
448*4882a593Smuzhiyun 
449*4882a593Smuzhiyun 	if (!insn->sib.got) {
450*4882a593Smuzhiyun 		ret = insn_get_sib(insn);
451*4882a593Smuzhiyun 		if (ret)
452*4882a593Smuzhiyun 			return ret;
453*4882a593Smuzhiyun 	}
454*4882a593Smuzhiyun 
455*4882a593Smuzhiyun 	if (insn->modrm.nbytes) {
456*4882a593Smuzhiyun 		/*
457*4882a593Smuzhiyun 		 * Interpreting the modrm byte:
458*4882a593Smuzhiyun 		 * mod = 00 - no displacement fields (exceptions below)
459*4882a593Smuzhiyun 		 * mod = 01 - 1-byte displacement field
460*4882a593Smuzhiyun 		 * mod = 10 - displacement field is 4 bytes, or 2 bytes if
461*4882a593Smuzhiyun 		 * 	address size = 2 (0x67 prefix in 32-bit mode)
462*4882a593Smuzhiyun 		 * mod = 11 - no memory operand
463*4882a593Smuzhiyun 		 *
464*4882a593Smuzhiyun 		 * If address size = 2...
465*4882a593Smuzhiyun 		 * mod = 00, r/m = 110 - displacement field is 2 bytes
466*4882a593Smuzhiyun 		 *
467*4882a593Smuzhiyun 		 * If address size != 2...
468*4882a593Smuzhiyun 		 * mod != 11, r/m = 100 - SIB byte exists
469*4882a593Smuzhiyun 		 * mod = 00, SIB base = 101 - displacement field is 4 bytes
470*4882a593Smuzhiyun 		 * mod = 00, r/m = 101 - rip-relative addressing, displacement
471*4882a593Smuzhiyun 		 * 	field is 4 bytes
472*4882a593Smuzhiyun 		 */
473*4882a593Smuzhiyun 		mod = X86_MODRM_MOD(insn->modrm.value);
474*4882a593Smuzhiyun 		rm = X86_MODRM_RM(insn->modrm.value);
475*4882a593Smuzhiyun 		base = X86_SIB_BASE(insn->sib.value);
476*4882a593Smuzhiyun 		if (mod == 3)
477*4882a593Smuzhiyun 			goto out;
478*4882a593Smuzhiyun 		if (mod == 1) {
479*4882a593Smuzhiyun 			insn->displacement.value = get_next(signed char, insn);
480*4882a593Smuzhiyun 			insn->displacement.nbytes = 1;
481*4882a593Smuzhiyun 		} else if (insn->addr_bytes == 2) {
482*4882a593Smuzhiyun 			if ((mod == 0 && rm == 6) || mod == 2) {
483*4882a593Smuzhiyun 				insn->displacement.value =
484*4882a593Smuzhiyun 					 get_next(short, insn);
485*4882a593Smuzhiyun 				insn->displacement.nbytes = 2;
486*4882a593Smuzhiyun 			}
487*4882a593Smuzhiyun 		} else {
488*4882a593Smuzhiyun 			if ((mod == 0 && rm == 5) || mod == 2 ||
489*4882a593Smuzhiyun 			    (mod == 0 && base == 5)) {
490*4882a593Smuzhiyun 				insn->displacement.value = get_next(int, insn);
491*4882a593Smuzhiyun 				insn->displacement.nbytes = 4;
492*4882a593Smuzhiyun 			}
493*4882a593Smuzhiyun 		}
494*4882a593Smuzhiyun 	}
495*4882a593Smuzhiyun out:
496*4882a593Smuzhiyun 	insn->displacement.got = 1;
497*4882a593Smuzhiyun 	return 0;
498*4882a593Smuzhiyun 
499*4882a593Smuzhiyun err_out:
500*4882a593Smuzhiyun 	return -ENODATA;
501*4882a593Smuzhiyun }
502*4882a593Smuzhiyun 
503*4882a593Smuzhiyun /* Decode moffset16/32/64. Return 0 if failed */
__get_moffset(struct insn * insn)504*4882a593Smuzhiyun static int __get_moffset(struct insn *insn)
505*4882a593Smuzhiyun {
506*4882a593Smuzhiyun 	switch (insn->addr_bytes) {
507*4882a593Smuzhiyun 	case 2:
508*4882a593Smuzhiyun 		insn->moffset1.value = get_next(short, insn);
509*4882a593Smuzhiyun 		insn->moffset1.nbytes = 2;
510*4882a593Smuzhiyun 		break;
511*4882a593Smuzhiyun 	case 4:
512*4882a593Smuzhiyun 		insn->moffset1.value = get_next(int, insn);
513*4882a593Smuzhiyun 		insn->moffset1.nbytes = 4;
514*4882a593Smuzhiyun 		break;
515*4882a593Smuzhiyun 	case 8:
516*4882a593Smuzhiyun 		insn->moffset1.value = get_next(int, insn);
517*4882a593Smuzhiyun 		insn->moffset1.nbytes = 4;
518*4882a593Smuzhiyun 		insn->moffset2.value = get_next(int, insn);
519*4882a593Smuzhiyun 		insn->moffset2.nbytes = 4;
520*4882a593Smuzhiyun 		break;
521*4882a593Smuzhiyun 	default:	/* opnd_bytes must be modified manually */
522*4882a593Smuzhiyun 		goto err_out;
523*4882a593Smuzhiyun 	}
524*4882a593Smuzhiyun 	insn->moffset1.got = insn->moffset2.got = 1;
525*4882a593Smuzhiyun 
526*4882a593Smuzhiyun 	return 1;
527*4882a593Smuzhiyun 
528*4882a593Smuzhiyun err_out:
529*4882a593Smuzhiyun 	return 0;
530*4882a593Smuzhiyun }
531*4882a593Smuzhiyun 
532*4882a593Smuzhiyun /* Decode imm v32(Iz). Return 0 if failed */
__get_immv32(struct insn * insn)533*4882a593Smuzhiyun static int __get_immv32(struct insn *insn)
534*4882a593Smuzhiyun {
535*4882a593Smuzhiyun 	switch (insn->opnd_bytes) {
536*4882a593Smuzhiyun 	case 2:
537*4882a593Smuzhiyun 		insn->immediate.value = get_next(short, insn);
538*4882a593Smuzhiyun 		insn->immediate.nbytes = 2;
539*4882a593Smuzhiyun 		break;
540*4882a593Smuzhiyun 	case 4:
541*4882a593Smuzhiyun 	case 8:
542*4882a593Smuzhiyun 		insn->immediate.value = get_next(int, insn);
543*4882a593Smuzhiyun 		insn->immediate.nbytes = 4;
544*4882a593Smuzhiyun 		break;
545*4882a593Smuzhiyun 	default:	/* opnd_bytes must be modified manually */
546*4882a593Smuzhiyun 		goto err_out;
547*4882a593Smuzhiyun 	}
548*4882a593Smuzhiyun 
549*4882a593Smuzhiyun 	return 1;
550*4882a593Smuzhiyun 
551*4882a593Smuzhiyun err_out:
552*4882a593Smuzhiyun 	return 0;
553*4882a593Smuzhiyun }
554*4882a593Smuzhiyun 
555*4882a593Smuzhiyun /* Decode imm v64(Iv/Ov), Return 0 if failed */
__get_immv(struct insn * insn)556*4882a593Smuzhiyun static int __get_immv(struct insn *insn)
557*4882a593Smuzhiyun {
558*4882a593Smuzhiyun 	switch (insn->opnd_bytes) {
559*4882a593Smuzhiyun 	case 2:
560*4882a593Smuzhiyun 		insn->immediate1.value = get_next(short, insn);
561*4882a593Smuzhiyun 		insn->immediate1.nbytes = 2;
562*4882a593Smuzhiyun 		break;
563*4882a593Smuzhiyun 	case 4:
564*4882a593Smuzhiyun 		insn->immediate1.value = get_next(int, insn);
565*4882a593Smuzhiyun 		insn->immediate1.nbytes = 4;
566*4882a593Smuzhiyun 		break;
567*4882a593Smuzhiyun 	case 8:
568*4882a593Smuzhiyun 		insn->immediate1.value = get_next(int, insn);
569*4882a593Smuzhiyun 		insn->immediate1.nbytes = 4;
570*4882a593Smuzhiyun 		insn->immediate2.value = get_next(int, insn);
571*4882a593Smuzhiyun 		insn->immediate2.nbytes = 4;
572*4882a593Smuzhiyun 		break;
573*4882a593Smuzhiyun 	default:	/* opnd_bytes must be modified manually */
574*4882a593Smuzhiyun 		goto err_out;
575*4882a593Smuzhiyun 	}
576*4882a593Smuzhiyun 	insn->immediate1.got = insn->immediate2.got = 1;
577*4882a593Smuzhiyun 
578*4882a593Smuzhiyun 	return 1;
579*4882a593Smuzhiyun err_out:
580*4882a593Smuzhiyun 	return 0;
581*4882a593Smuzhiyun }
582*4882a593Smuzhiyun 
583*4882a593Smuzhiyun /* Decode ptr16:16/32(Ap) */
__get_immptr(struct insn * insn)584*4882a593Smuzhiyun static int __get_immptr(struct insn *insn)
585*4882a593Smuzhiyun {
586*4882a593Smuzhiyun 	switch (insn->opnd_bytes) {
587*4882a593Smuzhiyun 	case 2:
588*4882a593Smuzhiyun 		insn->immediate1.value = get_next(short, insn);
589*4882a593Smuzhiyun 		insn->immediate1.nbytes = 2;
590*4882a593Smuzhiyun 		break;
591*4882a593Smuzhiyun 	case 4:
592*4882a593Smuzhiyun 		insn->immediate1.value = get_next(int, insn);
593*4882a593Smuzhiyun 		insn->immediate1.nbytes = 4;
594*4882a593Smuzhiyun 		break;
595*4882a593Smuzhiyun 	case 8:
596*4882a593Smuzhiyun 		/* ptr16:64 is not exist (no segment) */
597*4882a593Smuzhiyun 		return 0;
598*4882a593Smuzhiyun 	default:	/* opnd_bytes must be modified manually */
599*4882a593Smuzhiyun 		goto err_out;
600*4882a593Smuzhiyun 	}
601*4882a593Smuzhiyun 	insn->immediate2.value = get_next(unsigned short, insn);
602*4882a593Smuzhiyun 	insn->immediate2.nbytes = 2;
603*4882a593Smuzhiyun 	insn->immediate1.got = insn->immediate2.got = 1;
604*4882a593Smuzhiyun 
605*4882a593Smuzhiyun 	return 1;
606*4882a593Smuzhiyun err_out:
607*4882a593Smuzhiyun 	return 0;
608*4882a593Smuzhiyun }
609*4882a593Smuzhiyun 
610*4882a593Smuzhiyun /**
611*4882a593Smuzhiyun  * insn_get_immediate() - Get the immediate in an instruction
612*4882a593Smuzhiyun  * @insn:	&struct insn containing instruction
613*4882a593Smuzhiyun  *
614*4882a593Smuzhiyun  * If necessary, first collects the instruction up to and including the
615*4882a593Smuzhiyun  * displacement bytes.
616*4882a593Smuzhiyun  * Basically, most of immediates are sign-expanded. Unsigned-value can be
617*4882a593Smuzhiyun  * computed by bit masking with ((1 << (nbytes * 8)) - 1)
618*4882a593Smuzhiyun  *
619*4882a593Smuzhiyun  * Returns:
620*4882a593Smuzhiyun  * 0:  on success
621*4882a593Smuzhiyun  * < 0: on error
622*4882a593Smuzhiyun  */
insn_get_immediate(struct insn * insn)623*4882a593Smuzhiyun int insn_get_immediate(struct insn *insn)
624*4882a593Smuzhiyun {
625*4882a593Smuzhiyun 	int ret;
626*4882a593Smuzhiyun 
627*4882a593Smuzhiyun 	if (insn->immediate.got)
628*4882a593Smuzhiyun 		return 0;
629*4882a593Smuzhiyun 
630*4882a593Smuzhiyun 	if (!insn->displacement.got) {
631*4882a593Smuzhiyun 		ret = insn_get_displacement(insn);
632*4882a593Smuzhiyun 		if (ret)
633*4882a593Smuzhiyun 			return ret;
634*4882a593Smuzhiyun 	}
635*4882a593Smuzhiyun 
636*4882a593Smuzhiyun 	if (inat_has_moffset(insn->attr)) {
637*4882a593Smuzhiyun 		if (!__get_moffset(insn))
638*4882a593Smuzhiyun 			goto err_out;
639*4882a593Smuzhiyun 		goto done;
640*4882a593Smuzhiyun 	}
641*4882a593Smuzhiyun 
642*4882a593Smuzhiyun 	if (!inat_has_immediate(insn->attr))
643*4882a593Smuzhiyun 		/* no immediates */
644*4882a593Smuzhiyun 		goto done;
645*4882a593Smuzhiyun 
646*4882a593Smuzhiyun 	switch (inat_immediate_size(insn->attr)) {
647*4882a593Smuzhiyun 	case INAT_IMM_BYTE:
648*4882a593Smuzhiyun 		insn->immediate.value = get_next(signed char, insn);
649*4882a593Smuzhiyun 		insn->immediate.nbytes = 1;
650*4882a593Smuzhiyun 		break;
651*4882a593Smuzhiyun 	case INAT_IMM_WORD:
652*4882a593Smuzhiyun 		insn->immediate.value = get_next(short, insn);
653*4882a593Smuzhiyun 		insn->immediate.nbytes = 2;
654*4882a593Smuzhiyun 		break;
655*4882a593Smuzhiyun 	case INAT_IMM_DWORD:
656*4882a593Smuzhiyun 		insn->immediate.value = get_next(int, insn);
657*4882a593Smuzhiyun 		insn->immediate.nbytes = 4;
658*4882a593Smuzhiyun 		break;
659*4882a593Smuzhiyun 	case INAT_IMM_QWORD:
660*4882a593Smuzhiyun 		insn->immediate1.value = get_next(int, insn);
661*4882a593Smuzhiyun 		insn->immediate1.nbytes = 4;
662*4882a593Smuzhiyun 		insn->immediate2.value = get_next(int, insn);
663*4882a593Smuzhiyun 		insn->immediate2.nbytes = 4;
664*4882a593Smuzhiyun 		break;
665*4882a593Smuzhiyun 	case INAT_IMM_PTR:
666*4882a593Smuzhiyun 		if (!__get_immptr(insn))
667*4882a593Smuzhiyun 			goto err_out;
668*4882a593Smuzhiyun 		break;
669*4882a593Smuzhiyun 	case INAT_IMM_VWORD32:
670*4882a593Smuzhiyun 		if (!__get_immv32(insn))
671*4882a593Smuzhiyun 			goto err_out;
672*4882a593Smuzhiyun 		break;
673*4882a593Smuzhiyun 	case INAT_IMM_VWORD:
674*4882a593Smuzhiyun 		if (!__get_immv(insn))
675*4882a593Smuzhiyun 			goto err_out;
676*4882a593Smuzhiyun 		break;
677*4882a593Smuzhiyun 	default:
678*4882a593Smuzhiyun 		/* Here, insn must have an immediate, but failed */
679*4882a593Smuzhiyun 		goto err_out;
680*4882a593Smuzhiyun 	}
681*4882a593Smuzhiyun 	if (inat_has_second_immediate(insn->attr)) {
682*4882a593Smuzhiyun 		insn->immediate2.value = get_next(signed char, insn);
683*4882a593Smuzhiyun 		insn->immediate2.nbytes = 1;
684*4882a593Smuzhiyun 	}
685*4882a593Smuzhiyun done:
686*4882a593Smuzhiyun 	insn->immediate.got = 1;
687*4882a593Smuzhiyun 	return 0;
688*4882a593Smuzhiyun 
689*4882a593Smuzhiyun err_out:
690*4882a593Smuzhiyun 	return -ENODATA;
691*4882a593Smuzhiyun }
692*4882a593Smuzhiyun 
693*4882a593Smuzhiyun /**
694*4882a593Smuzhiyun  * insn_get_length() - Get the length of instruction
695*4882a593Smuzhiyun  * @insn:	&struct insn containing instruction
696*4882a593Smuzhiyun  *
697*4882a593Smuzhiyun  * If necessary, first collects the instruction up to and including the
698*4882a593Smuzhiyun  * immediates bytes.
699*4882a593Smuzhiyun  *
700*4882a593Smuzhiyun  * Returns:
701*4882a593Smuzhiyun  *  - 0 on success
702*4882a593Smuzhiyun  *  - < 0 on error
703*4882a593Smuzhiyun */
insn_get_length(struct insn * insn)704*4882a593Smuzhiyun int insn_get_length(struct insn *insn)
705*4882a593Smuzhiyun {
706*4882a593Smuzhiyun 	int ret;
707*4882a593Smuzhiyun 
708*4882a593Smuzhiyun 	if (insn->length)
709*4882a593Smuzhiyun 		return 0;
710*4882a593Smuzhiyun 
711*4882a593Smuzhiyun 	if (!insn->immediate.got) {
712*4882a593Smuzhiyun 		ret = insn_get_immediate(insn);
713*4882a593Smuzhiyun 		if (ret)
714*4882a593Smuzhiyun 			return ret;
715*4882a593Smuzhiyun 	}
716*4882a593Smuzhiyun 
717*4882a593Smuzhiyun 	insn->length = (unsigned char)((unsigned long)insn->next_byte
718*4882a593Smuzhiyun 				     - (unsigned long)insn->kaddr);
719*4882a593Smuzhiyun 
720*4882a593Smuzhiyun 	return 0;
721*4882a593Smuzhiyun }
722*4882a593Smuzhiyun 
723*4882a593Smuzhiyun /**
724*4882a593Smuzhiyun  * insn_decode() - Decode an x86 instruction
725*4882a593Smuzhiyun  * @insn:	&struct insn to be initialized
726*4882a593Smuzhiyun  * @kaddr:	address (in kernel memory) of instruction (or copy thereof)
727*4882a593Smuzhiyun  * @buf_len:	length of the insn buffer at @kaddr
728*4882a593Smuzhiyun  * @m:		insn mode, see enum insn_mode
729*4882a593Smuzhiyun  *
730*4882a593Smuzhiyun  * Returns:
731*4882a593Smuzhiyun  * 0: if decoding succeeded
732*4882a593Smuzhiyun  * < 0: otherwise.
733*4882a593Smuzhiyun  */
insn_decode(struct insn * insn,const void * kaddr,int buf_len,enum insn_mode m)734*4882a593Smuzhiyun int insn_decode(struct insn *insn, const void *kaddr, int buf_len, enum insn_mode m)
735*4882a593Smuzhiyun {
736*4882a593Smuzhiyun 	int ret;
737*4882a593Smuzhiyun 
738*4882a593Smuzhiyun #define INSN_MODE_KERN (enum insn_mode)-1 /* __ignore_sync_check__ mode is only valid in the kernel */
739*4882a593Smuzhiyun 
740*4882a593Smuzhiyun 	if (m == INSN_MODE_KERN)
741*4882a593Smuzhiyun 		insn_init(insn, kaddr, buf_len, IS_ENABLED(CONFIG_X86_64));
742*4882a593Smuzhiyun 	else
743*4882a593Smuzhiyun 		insn_init(insn, kaddr, buf_len, m == INSN_MODE_64);
744*4882a593Smuzhiyun 
745*4882a593Smuzhiyun 	ret = insn_get_length(insn);
746*4882a593Smuzhiyun 	if (ret)
747*4882a593Smuzhiyun 		return ret;
748*4882a593Smuzhiyun 
749*4882a593Smuzhiyun 	if (insn_complete(insn))
750*4882a593Smuzhiyun 		return 0;
751*4882a593Smuzhiyun 
752*4882a593Smuzhiyun 	return -EINVAL;
753*4882a593Smuzhiyun }
754