Beispiel #1
0
/* Check that an instruction
 * - can be length-decoded
 * - is correctly length-decoded
 * - can be classified
 * - is corectly diagnosed as interesting/boring
 *
 * Does not check whether the classification is correct.
 * This is left to the calling test.
 */
static struct ptunit_result ptunit_ild_decode(struct pt_ild *ild,
					      int interest, uint8_t size)
{
	int lret, dret;

	lret = pt_instruction_length_decode(ild);
	ptu_int_eq(lret, 1);
	ptu_uint_eq(ild->length, size);

	dret = pt_instruction_decode(ild);
	ptu_int_eq(dret, interest);

	return ptu_passed();
}
Beispiel #2
0
/* Decode and analyze one instruction.
 *
 * Decodes the instructruction at @decoder->ip into @insn and updates
 * @decoder->ip.
 *
 * Returns a negative error code on failure.
 * Returns zero on success if the instruction is not relevant for our purposes.
 * Returns a positive number on success if the instruction is relevant.
 * Returns -pte_bad_insn if the instruction could not be decoded.
 */
static int decode_insn(struct pt_insn *insn, struct pt_insn_decoder *decoder)
{
	struct pt_ild *ild;
	int errcode, relevant;
	int size;

	if (!insn || !decoder)
		return -pte_internal;

	/* Fill in as much as we can as early as we can so we have the
	 * information available in case of errors.
	 */
	if (decoder->speculative)
		insn->speculative = 1;
	insn->ip = decoder->ip;
	insn->mode = decoder->mode;

	/* Read the memory at the current IP in the current address space. */
	size = pt_image_read(decoder->image, insn->raw, sizeof(insn->raw),
			     &decoder->asid, decoder->ip);
	if (size < 0)
		return size;

	/* Decode the instruction. */
	ild = &decoder->ild;
	ild->itext = insn->raw;
	ild->max_bytes = (uint8_t) size;
	ild->mode = decoder->mode;
	ild->runtime_address = decoder->ip;

	errcode = pt_instruction_length_decode(ild);
	if (errcode < 0)
		return errcode;

	insn->size = ild->length;

	relevant = pt_instruction_decode(ild);
	if (!relevant)
		insn->iclass = ptic_other;
	else {
		if (relevant < 0)
			return relevant;

		insn->iclass = pt_insn_classify(ild);
	}

	return relevant;
}
Beispiel #3
0
/* Check whether @ip is ahead of us.
 *
 * Tries to reach @ip from @decoder->ip in @decoder->mode without Intel PT for
 * at most @steps steps.
 *
 * Does not update @decoder except for its image LRU cache.
 *
 * Returns non-zero if @ip can be reached, zero otherwise.
 */
static int pt_ip_is_ahead(struct pt_insn_decoder *decoder, uint64_t ip,
			  size_t steps)
{
	struct pt_ild ild;
	uint8_t raw[pt_max_insn_size];

	if (!decoder)
		return 0;

	/* We do not expect execution mode changes. */
	ild.mode = decoder->mode;
	ild.itext = raw;
	ild.runtime_address = decoder->ip;

	while (ild.runtime_address != ip) {
		int size, errcode;

		if (!steps--)
			return 0;

		/* If we can't read the memory for the instruction, we can't
		 * reach it.
		 */
		size = pt_image_read(decoder->image, raw, sizeof(raw),
				     &decoder->asid, ild.runtime_address);
		if (size < 0)
			return 0;

		ild.max_bytes = (uint8_t) size;

		errcode = pt_instruction_length_decode(&ild);
		if (errcode < 0)
			return 0;

		errcode = pt_instruction_decode(&ild);
		if (errcode < 0)
			return 0;

		errcode = pt_insn_next_ip(&ild.runtime_address, &ild);
		if (errcode < 0)
			return 0;
	}

	return 1;
}
Beispiel #4
0
static int check_erratum_skd022(struct pt_insn_decoder *decoder)
{
	struct pt_ild ild;
	uint8_t raw[pt_max_insn_size];
	int size, errcode;

	if (!decoder)
		return -pte_internal;

	size = pt_image_read(decoder->image, raw, sizeof(raw),
			     &decoder->asid, decoder->ip);
	if (size < 0)
		return 0;

	memset(&ild, 0, sizeof(ild));

	ild.mode = decoder->mode;
	ild.max_bytes = (uint8_t) size;
	ild.itext = raw;
	ild.runtime_address = decoder->ip;

	errcode = pt_instruction_length_decode(&ild);
	if (errcode < 0)
		return 0;

	errcode = pt_instruction_decode(&ild);
	if (errcode < 0)
		return 0;

	switch (ild.iclass) {
	default:
		return 0;

	case PTI_INST_VMLAUNCH:
	case PTI_INST_VMRESUME:
		return 1;
	}
}