1/*
2 * Copyright (c) 2016-2018, Intel Corporation
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are met:
6 *
7 *  * Redistributions of source code must retain the above copyright notice,
8 *    this list of conditions and the following disclaimer.
9 *  * Redistributions in binary form must reproduce the above copyright notice,
10 *    this list of conditions and the following disclaimer in the documentation
11 *    and/or other materials provided with the distribution.
12 *  * Neither the name of Intel Corporation nor the names of its contributors
13 *    may be used to endorse or promote products derived from this software
14 *    without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
20 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26 * POSSIBILITY OF SUCH DAMAGE.
27 */
28
29#include "pt_insn.h"
30#include "pt_ild.h"
31#include "pt_image.h"
32#include "pt_compiler.h"
33
34#include "intel-pt.h"
35
36
37int pt_insn_changes_cpl(const struct pt_insn *insn,
38			const struct pt_insn_ext *iext)
39{
40	(void) insn;
41
42	if (!iext)
43		return 0;
44
45	switch (iext->iclass) {
46	default:
47		return 0;
48
49	case PTI_INST_INT:
50	case PTI_INST_INT3:
51	case PTI_INST_INT1:
52	case PTI_INST_INTO:
53	case PTI_INST_IRET:
54	case PTI_INST_SYSCALL:
55	case PTI_INST_SYSENTER:
56	case PTI_INST_SYSEXIT:
57	case PTI_INST_SYSRET:
58		return 1;
59	}
60}
61
62int pt_insn_changes_cr3(const struct pt_insn *insn,
63			const struct pt_insn_ext *iext)
64{
65	(void) insn;
66
67	if (!iext)
68		return 0;
69
70	switch (iext->iclass) {
71	default:
72		return 0;
73
74	case PTI_INST_MOV_CR3:
75		return 1;
76	}
77}
78
79int pt_insn_is_branch(const struct pt_insn *insn,
80		      const struct pt_insn_ext *iext)
81{
82	(void) iext;
83
84	if (!insn)
85		return 0;
86
87	switch (insn->iclass) {
88	default:
89		return 0;
90
91	case ptic_call:
92	case ptic_return:
93	case ptic_jump:
94	case ptic_cond_jump:
95	case ptic_far_call:
96	case ptic_far_return:
97	case ptic_far_jump:
98		return 1;
99	}
100}
101
102int pt_insn_is_far_branch(const struct pt_insn *insn,
103			  const struct pt_insn_ext *iext)
104{
105	(void) iext;
106
107	if (!insn)
108		return 0;
109
110	switch (insn->iclass) {
111	default:
112		return 0;
113
114	case ptic_far_call:
115	case ptic_far_return:
116	case ptic_far_jump:
117		return 1;
118	}
119}
120
121int pt_insn_binds_to_pip(const struct pt_insn *insn,
122			 const struct pt_insn_ext *iext)
123{
124	if (!iext)
125		return 0;
126
127	switch (iext->iclass) {
128	default:
129		return pt_insn_is_far_branch(insn, iext);
130
131	case PTI_INST_MOV_CR3:
132	case PTI_INST_VMLAUNCH:
133	case PTI_INST_VMRESUME:
134		return 1;
135	}
136}
137
138int pt_insn_binds_to_vmcs(const struct pt_insn *insn,
139			  const struct pt_insn_ext *iext)
140{
141	if (!iext)
142		return 0;
143
144	switch (iext->iclass) {
145	default:
146		return pt_insn_is_far_branch(insn, iext);
147
148	case PTI_INST_VMPTRLD:
149	case PTI_INST_VMLAUNCH:
150	case PTI_INST_VMRESUME:
151		return 1;
152	}
153}
154
155int pt_insn_is_ptwrite(const struct pt_insn *insn,
156		       const struct pt_insn_ext *iext)
157{
158	(void) iext;
159
160	if (!insn)
161		return 0;
162
163	switch (insn->iclass) {
164	default:
165		return 0;
166
167	case ptic_ptwrite:
168		return 1;
169	}
170}
171
172int pt_insn_next_ip(uint64_t *pip, const struct pt_insn *insn,
173		    const struct pt_insn_ext *iext)
174{
175	uint64_t ip;
176
177	if (!insn || !iext)
178		return -pte_internal;
179
180	ip = insn->ip + insn->size;
181
182	switch (insn->iclass) {
183	case ptic_ptwrite:
184	case ptic_other:
185		break;
186
187	case ptic_call:
188	case ptic_jump:
189		if (iext->variant.branch.is_direct) {
190			ip += iext->variant.branch.displacement;
191			break;
192		}
193
194		fallthrough;
195	default:
196		return -pte_bad_query;
197
198	case ptic_error:
199		return -pte_bad_insn;
200	}
201
202	if (pip)
203		*pip = ip;
204
205	return 0;
206}
207
208/* Retry decoding an instruction after a preceding decode error.
209 *
210 * Instruction length decode typically fails due to 'not enough
211 * bytes'.
212 *
213 * This may be caused by partial updates of text sections
214 * represented via new image sections overlapping the original
215 * text section's image section.  We stop reading memory at the
216 * end of the section so we do not read the full instruction if
217 * parts of it have been overwritten by the update.
218 *
219 * Try to read the remaining bytes and decode the instruction again.  If we
220 * succeed, set @insn->truncated to indicate that the instruction is truncated
221 * in @insn->isid.
222 *
223 * Returns zero on success, a negative error code otherwise.
224 * Returns -pte_bad_insn if the instruction could not be decoded.
225 */
226static int pt_insn_decode_retry(struct pt_insn *insn, struct pt_insn_ext *iext,
227				struct pt_image *image,
228				const struct pt_asid *asid)
229{
230	int size, errcode, isid;
231	uint8_t isize, remaining;
232
233	if (!insn)
234		return -pte_internal;
235
236	isize = insn->size;
237	remaining = sizeof(insn->raw) - isize;
238
239	/* We failed for real if we already read the maximum number of bytes for
240	 * an instruction.
241	 */
242	if (!remaining)
243		return -pte_bad_insn;
244
245	/* Read the remaining bytes from the image. */
246	size = pt_image_read(image, &isid, &insn->raw[isize], remaining, asid,
247			     insn->ip + isize);
248	if (size <= 0) {
249		/* We should have gotten an error if we were not able to read at
250		 * least one byte.  Check this to guarantee termination.
251		 */
252		if (!size)
253			return -pte_internal;
254
255		/* Preserve the original error if there are no more bytes. */
256		if (size == -pte_nomap)
257			size = -pte_bad_insn;
258
259		return size;
260	}
261
262	/* Add the newly read bytes to the instruction's size. */
263	insn->size += (uint8_t) size;
264
265	/* Store the new size to avoid infinite recursion in case instruction
266	 * decode fails after length decode, which would set @insn->size to the
267	 * actual length.
268	 */
269	size = insn->size;
270
271	/* Try to decode the instruction again.
272	 *
273	 * If we fail again, we recursively retry again until we either fail to
274	 * read more bytes or reach the maximum number of bytes for an
275	 * instruction.
276	 */
277	errcode = pt_ild_decode(insn, iext);
278	if (errcode < 0) {
279		if (errcode != -pte_bad_insn)
280			return errcode;
281
282		/* If instruction length decode already determined the size,
283		 * there's no point in reading more bytes.
284		 */
285		if (insn->size != (uint8_t) size)
286			return errcode;
287
288		return pt_insn_decode_retry(insn, iext, image, asid);
289	}
290
291	/* We succeeded this time, so the instruction crosses image section
292	 * boundaries.
293	 *
294	 * This poses the question which isid to use for the instruction.
295	 *
296	 * To reconstruct exactly this instruction at a later time, we'd need to
297	 * store all isids involved together with the number of bytes read for
298	 * each isid.  Since @insn already provides the exact bytes for this
299	 * instruction, we assume that the isid will be used solely for source
300	 * correlation.  In this case, it should refer to the first byte of the
301	 * instruction - as it already does.
302	 */
303	insn->truncated = 1;
304
305	return errcode;
306}
307
308int pt_insn_decode(struct pt_insn *insn, struct pt_insn_ext *iext,
309		   struct pt_image *image, const struct pt_asid *asid)
310{
311	int size, errcode;
312
313	if (!insn)
314		return -pte_internal;
315
316	/* Read the memory at the current IP in the current address space. */
317	size = pt_image_read(image, &insn->isid, insn->raw, sizeof(insn->raw),
318			     asid, insn->ip);
319	if (size < 0)
320		return size;
321
322	/* We initialize @insn->size to the maximal possible size.  It will be
323	 * set to the actual size during instruction decode.
324	 */
325	insn->size = (uint8_t) size;
326
327	errcode = pt_ild_decode(insn, iext);
328	if (errcode < 0) {
329		if (errcode != -pte_bad_insn)
330			return errcode;
331
332		/* If instruction length decode already determined the size,
333		 * there's no point in reading more bytes.
334		 */
335		if (insn->size != (uint8_t) size)
336			return errcode;
337
338		return pt_insn_decode_retry(insn, iext, image, asid);
339	}
340
341	return errcode;
342}
343
344int pt_insn_range_is_contiguous(uint64_t begin, uint64_t end,
345				enum pt_exec_mode mode, struct pt_image *image,
346				const struct pt_asid *asid, size_t steps)
347{
348	struct pt_insn_ext iext;
349	struct pt_insn insn;
350
351	memset(&insn, 0, sizeof(insn));
352
353	insn.mode = mode;
354	insn.ip = begin;
355
356	while (insn.ip != end) {
357		int errcode;
358
359		if (!steps--)
360			return 0;
361
362		errcode = pt_insn_decode(&insn, &iext, image, asid);
363		if (errcode < 0)
364			return errcode;
365
366		errcode = pt_insn_next_ip(&insn.ip, &insn, &iext);
367		if (errcode < 0)
368			return errcode;
369	}
370
371	return 1;
372}
373