Blame libipt/src/pt_decoder_function.c

Packit b1f7ae
/*
Packit b1f7ae
 * Copyright (c) 2013-2017, Intel Corporation
Packit b1f7ae
 *
Packit b1f7ae
 * Redistribution and use in source and binary forms, with or without
Packit b1f7ae
 * modification, are permitted provided that the following conditions are met:
Packit b1f7ae
 *
Packit b1f7ae
 *  * Redistributions of source code must retain the above copyright notice,
Packit b1f7ae
 *    this list of conditions and the following disclaimer.
Packit b1f7ae
 *  * Redistributions in binary form must reproduce the above copyright notice,
Packit b1f7ae
 *    this list of conditions and the following disclaimer in the documentation
Packit b1f7ae
 *    and/or other materials provided with the distribution.
Packit b1f7ae
 *  * Neither the name of Intel Corporation nor the names of its contributors
Packit b1f7ae
 *    may be used to endorse or promote products derived from this software
Packit b1f7ae
 *    without specific prior written permission.
Packit b1f7ae
 *
Packit b1f7ae
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
Packit b1f7ae
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
Packit b1f7ae
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
Packit b1f7ae
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
Packit b1f7ae
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
Packit b1f7ae
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
Packit b1f7ae
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
Packit b1f7ae
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
Packit b1f7ae
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
Packit b1f7ae
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
Packit b1f7ae
 * POSSIBILITY OF SUCH DAMAGE.
Packit b1f7ae
 */
Packit b1f7ae
Packit b1f7ae
#include "pt_decoder_function.h"
Packit b1f7ae
#include "pt_packet_decoder.h"
Packit b1f7ae
#include "pt_query_decoder.h"
Packit b1f7ae
Packit b1f7ae
#include "intel-pt.h"
Packit b1f7ae
Packit b1f7ae
Packit b1f7ae
const struct pt_decoder_function pt_decode_unknown = {
Packit b1f7ae
	/* .packet = */ pt_pkt_decode_unknown,
Packit b1f7ae
	/* .decode = */ pt_qry_decode_unknown,
Packit b1f7ae
	/* .header = */ pt_qry_decode_unknown,
Packit b1f7ae
	/* .flags =  */ pdff_unknown
Packit b1f7ae
};
Packit b1f7ae
Packit b1f7ae
const struct pt_decoder_function pt_decode_pad = {
Packit b1f7ae
	/* .packet = */ pt_pkt_decode_pad,
Packit b1f7ae
	/* .decode = */ pt_qry_decode_pad,
Packit b1f7ae
	/* .header = */ pt_qry_decode_pad,
Packit b1f7ae
	/* .flags =  */ pdff_pad
Packit b1f7ae
};
Packit b1f7ae
Packit b1f7ae
const struct pt_decoder_function pt_decode_psb = {
Packit b1f7ae
	/* .packet = */ pt_pkt_decode_psb,
Packit b1f7ae
	/* .decode = */ pt_qry_decode_psb,
Packit b1f7ae
	/* .header = */ NULL,
Packit b1f7ae
	/* .flags =  */ 0
Packit b1f7ae
};
Packit b1f7ae
Packit b1f7ae
const struct pt_decoder_function pt_decode_tip = {
Packit b1f7ae
	/* .packet = */ pt_pkt_decode_tip,
Packit b1f7ae
	/* .decode = */ pt_qry_decode_tip,
Packit b1f7ae
	/* .header = */ NULL,
Packit b1f7ae
	/* .flags =  */ pdff_tip
Packit b1f7ae
};
Packit b1f7ae
Packit b1f7ae
const struct pt_decoder_function pt_decode_tnt_8 = {
Packit b1f7ae
	/* .packet = */ pt_pkt_decode_tnt_8,
Packit b1f7ae
	/* .decode = */ pt_qry_decode_tnt_8,
Packit b1f7ae
	/* .header = */ NULL,
Packit b1f7ae
	/* .flags =  */ pdff_tnt
Packit b1f7ae
};
Packit b1f7ae
Packit b1f7ae
const struct pt_decoder_function pt_decode_tnt_64 = {
Packit b1f7ae
	/* .packet = */ pt_pkt_decode_tnt_64,
Packit b1f7ae
	/* .decode = */ pt_qry_decode_tnt_64,
Packit b1f7ae
	/* .header = */ NULL,
Packit b1f7ae
	/* .flags =  */ pdff_tnt
Packit b1f7ae
};
Packit b1f7ae
Packit b1f7ae
const struct pt_decoder_function pt_decode_tip_pge = {
Packit b1f7ae
	/* .packet = */ pt_pkt_decode_tip_pge,
Packit b1f7ae
	/* .decode = */ pt_qry_decode_tip_pge,
Packit b1f7ae
	/* .header = */ NULL,
Packit b1f7ae
	/* .flags =  */ pdff_event
Packit b1f7ae
};
Packit b1f7ae
Packit b1f7ae
const struct pt_decoder_function pt_decode_tip_pgd = {
Packit b1f7ae
	/* .packet = */ pt_pkt_decode_tip_pgd,
Packit b1f7ae
	/* .decode = */ pt_qry_decode_tip_pgd,
Packit b1f7ae
	/* .header = */ NULL,
Packit b1f7ae
	/* .flags =  */ pdff_event
Packit b1f7ae
};
Packit b1f7ae
Packit b1f7ae
const struct pt_decoder_function pt_decode_fup = {
Packit b1f7ae
	/* .packet = */ pt_pkt_decode_fup,
Packit b1f7ae
	/* .decode = */ pt_qry_decode_fup,
Packit b1f7ae
	/* .header = */ pt_qry_header_fup,
Packit b1f7ae
	/* .flags =  */ pdff_fup
Packit b1f7ae
};
Packit b1f7ae
Packit b1f7ae
const struct pt_decoder_function pt_decode_pip = {
Packit b1f7ae
	/* .packet = */ pt_pkt_decode_pip,
Packit b1f7ae
	/* .decode = */ pt_qry_decode_pip,
Packit b1f7ae
	/* .header = */ pt_qry_header_pip,
Packit b1f7ae
	/* .flags =  */ pdff_event
Packit b1f7ae
};
Packit b1f7ae
Packit b1f7ae
const struct pt_decoder_function pt_decode_ovf = {
Packit b1f7ae
	/* .packet = */ pt_pkt_decode_ovf,
Packit b1f7ae
	/* .decode = */ pt_qry_decode_ovf,
Packit b1f7ae
	/* .header = */ NULL,
Packit b1f7ae
	/* .flags =  */ pdff_psbend | pdff_event
Packit b1f7ae
};
Packit b1f7ae
Packit b1f7ae
const struct pt_decoder_function pt_decode_mode = {
Packit b1f7ae
	/* .packet = */ pt_pkt_decode_mode,
Packit b1f7ae
	/* .decode = */ pt_qry_decode_mode,
Packit b1f7ae
	/* .header = */ pt_qry_header_mode,
Packit b1f7ae
	/* .flags =  */ pdff_event
Packit b1f7ae
};
Packit b1f7ae
Packit b1f7ae
const struct pt_decoder_function pt_decode_psbend = {
Packit b1f7ae
	/* .packet = */ pt_pkt_decode_psbend,
Packit b1f7ae
	/* .decode = */ pt_qry_decode_psbend,
Packit b1f7ae
	/* .header = */ NULL,
Packit b1f7ae
	/* .flags =  */ pdff_psbend
Packit b1f7ae
};
Packit b1f7ae
Packit b1f7ae
const struct pt_decoder_function pt_decode_tsc = {
Packit b1f7ae
	/* .packet = */ pt_pkt_decode_tsc,
Packit b1f7ae
	/* .decode = */ pt_qry_decode_tsc,
Packit b1f7ae
	/* .header = */ pt_qry_header_tsc,
Packit b1f7ae
	/* .flags =  */ pdff_timing
Packit b1f7ae
};
Packit b1f7ae
Packit b1f7ae
const struct pt_decoder_function pt_decode_cbr = {
Packit b1f7ae
	/* .packet = */ pt_pkt_decode_cbr,
Packit b1f7ae
	/* .decode = */ pt_qry_decode_cbr,
Packit b1f7ae
	/* .header = */ pt_qry_header_cbr,
Packit b1f7ae
	/* .flags =  */ pdff_timing
Packit b1f7ae
};
Packit b1f7ae
Packit b1f7ae
const struct pt_decoder_function pt_decode_tma = {
Packit b1f7ae
	/* .packet = */ pt_pkt_decode_tma,
Packit b1f7ae
	/* .decode = */ pt_qry_decode_tma,
Packit b1f7ae
	/* .header = */ pt_qry_decode_tma,
Packit b1f7ae
	/* .flags =  */ pdff_timing
Packit b1f7ae
};
Packit b1f7ae
Packit b1f7ae
const struct pt_decoder_function pt_decode_mtc = {
Packit b1f7ae
	/* .packet = */ pt_pkt_decode_mtc,
Packit b1f7ae
	/* .decode = */ pt_qry_decode_mtc,
Packit b1f7ae
	/* .header = */ pt_qry_decode_mtc,
Packit b1f7ae
	/* .flags =  */ pdff_timing
Packit b1f7ae
};
Packit b1f7ae
Packit b1f7ae
const struct pt_decoder_function pt_decode_cyc = {
Packit b1f7ae
	/* .packet = */ pt_pkt_decode_cyc,
Packit b1f7ae
	/* .decode = */ pt_qry_decode_cyc,
Packit b1f7ae
	/* .header = */ pt_qry_decode_cyc,
Packit b1f7ae
	/* .flags =  */ pdff_timing
Packit b1f7ae
};
Packit b1f7ae
Packit b1f7ae
const struct pt_decoder_function pt_decode_stop = {
Packit b1f7ae
	/* .packet = */ pt_pkt_decode_stop,
Packit b1f7ae
	/* .decode = */ pt_qry_decode_stop,
Packit b1f7ae
	/* .header = */ NULL,
Packit b1f7ae
	/* .flags =  */ pdff_event
Packit b1f7ae
};
Packit b1f7ae
Packit b1f7ae
const struct pt_decoder_function pt_decode_vmcs = {
Packit b1f7ae
	/* .packet = */ pt_pkt_decode_vmcs,
Packit b1f7ae
	/* .decode = */ pt_qry_decode_vmcs,
Packit b1f7ae
	/* .header = */ pt_qry_header_vmcs,
Packit b1f7ae
	/* .flags =  */ pdff_event
Packit b1f7ae
};
Packit b1f7ae
Packit b1f7ae
const struct pt_decoder_function pt_decode_mnt = {
Packit b1f7ae
	/* .packet = */ pt_pkt_decode_mnt,
Packit b1f7ae
	/* .decode = */ pt_qry_decode_mnt,
Packit b1f7ae
	/* .header = */ pt_qry_decode_mnt,
Packit b1f7ae
	/* .flags =  */ pdff_pad
Packit b1f7ae
};
Packit b1f7ae
Packit b1f7ae
Packit b1f7ae
int pt_df_fetch(const struct pt_decoder_function **dfun, const uint8_t *pos,
Packit b1f7ae
		const struct pt_config *config)
Packit b1f7ae
{
Packit b1f7ae
	const uint8_t *begin, *end;
Packit b1f7ae
	uint8_t opc, ext, ext2;
Packit b1f7ae
Packit b1f7ae
	if (!dfun || !config)
Packit b1f7ae
		return -pte_internal;
Packit b1f7ae
Packit b1f7ae
	/* Clear the decode function in case of errors. */
Packit b1f7ae
	*dfun = NULL;
Packit b1f7ae
Packit b1f7ae
	begin = config->begin;
Packit b1f7ae
	end = config->end;
Packit b1f7ae
Packit b1f7ae
	if (!pos || (pos < begin) || (end < pos))
Packit b1f7ae
		return -pte_nosync;
Packit b1f7ae
Packit b1f7ae
	if (pos == end)
Packit b1f7ae
		return -pte_eos;
Packit b1f7ae
Packit b1f7ae
	opc = *pos++;
Packit b1f7ae
	switch (opc) {
Packit b1f7ae
	default:
Packit b1f7ae
		/* Check opcodes that require masking. */
Packit b1f7ae
		if ((opc & pt_opm_tnt_8) == pt_opc_tnt_8) {
Packit b1f7ae
			*dfun = &pt_decode_tnt_8;
Packit b1f7ae
			return 0;
Packit b1f7ae
		}
Packit b1f7ae
Packit b1f7ae
		if ((opc & pt_opm_cyc) == pt_opc_cyc) {
Packit b1f7ae
			*dfun = &pt_decode_cyc;
Packit b1f7ae
			return 0;
Packit b1f7ae
		}
Packit b1f7ae
Packit b1f7ae
		if ((opc & pt_opm_tip) == pt_opc_tip) {
Packit b1f7ae
			*dfun = &pt_decode_tip;
Packit b1f7ae
			return 0;
Packit b1f7ae
		}
Packit b1f7ae
Packit b1f7ae
		if ((opc & pt_opm_fup) == pt_opc_fup) {
Packit b1f7ae
			*dfun = &pt_decode_fup;
Packit b1f7ae
			return 0;
Packit b1f7ae
		}
Packit b1f7ae
Packit b1f7ae
		if ((opc & pt_opm_tip) == pt_opc_tip_pge) {
Packit b1f7ae
			*dfun = &pt_decode_tip_pge;
Packit b1f7ae
			return 0;
Packit b1f7ae
		}
Packit b1f7ae
Packit b1f7ae
		if ((opc & pt_opm_tip) == pt_opc_tip_pgd) {
Packit b1f7ae
			*dfun = &pt_decode_tip_pgd;
Packit b1f7ae
			return 0;
Packit b1f7ae
		}
Packit b1f7ae
Packit b1f7ae
		*dfun = &pt_decode_unknown;
Packit b1f7ae
		return 0;
Packit b1f7ae
Packit b1f7ae
	case pt_opc_pad:
Packit b1f7ae
		*dfun = &pt_decode_pad;
Packit b1f7ae
		return 0;
Packit b1f7ae
Packit b1f7ae
	case pt_opc_mode:
Packit b1f7ae
		*dfun = &pt_decode_mode;
Packit b1f7ae
		return 0;
Packit b1f7ae
Packit b1f7ae
	case pt_opc_tsc:
Packit b1f7ae
		*dfun = &pt_decode_tsc;
Packit b1f7ae
		return 0;
Packit b1f7ae
Packit b1f7ae
	case pt_opc_mtc:
Packit b1f7ae
		*dfun = &pt_decode_mtc;
Packit b1f7ae
		return 0;
Packit b1f7ae
Packit b1f7ae
	case pt_opc_ext:
Packit b1f7ae
		if (pos == end)
Packit b1f7ae
			return -pte_eos;
Packit b1f7ae
Packit b1f7ae
		ext = *pos++;
Packit b1f7ae
		switch (ext) {
Packit b1f7ae
		default:
Packit b1f7ae
			*dfun = &pt_decode_unknown;
Packit b1f7ae
			return 0;
Packit b1f7ae
Packit b1f7ae
		case pt_ext_psb:
Packit b1f7ae
			*dfun = &pt_decode_psb;
Packit b1f7ae
			return 0;
Packit b1f7ae
Packit b1f7ae
		case pt_ext_ovf:
Packit b1f7ae
			*dfun = &pt_decode_ovf;
Packit b1f7ae
			return 0;
Packit b1f7ae
Packit b1f7ae
		case pt_ext_tnt_64:
Packit b1f7ae
			*dfun = &pt_decode_tnt_64;
Packit b1f7ae
			return 0;
Packit b1f7ae
Packit b1f7ae
		case pt_ext_psbend:
Packit b1f7ae
			*dfun = &pt_decode_psbend;
Packit b1f7ae
			return 0;
Packit b1f7ae
Packit b1f7ae
		case pt_ext_cbr:
Packit b1f7ae
			*dfun = &pt_decode_cbr;
Packit b1f7ae
			return 0;
Packit b1f7ae
Packit b1f7ae
		case pt_ext_pip:
Packit b1f7ae
			*dfun = &pt_decode_pip;
Packit b1f7ae
			return 0;
Packit b1f7ae
Packit b1f7ae
		case pt_ext_tma:
Packit b1f7ae
			*dfun = &pt_decode_tma;
Packit b1f7ae
			return 0;
Packit b1f7ae
Packit b1f7ae
		case pt_ext_stop:
Packit b1f7ae
			*dfun = &pt_decode_stop;
Packit b1f7ae
			return 0;
Packit b1f7ae
Packit b1f7ae
		case pt_ext_vmcs:
Packit b1f7ae
			*dfun = &pt_decode_vmcs;
Packit b1f7ae
			return 0;
Packit b1f7ae
Packit b1f7ae
		case pt_ext_ext2:
Packit b1f7ae
			if (pos == end)
Packit b1f7ae
				return -pte_eos;
Packit b1f7ae
Packit b1f7ae
			ext2 = *pos++;
Packit b1f7ae
			switch (ext2) {
Packit b1f7ae
			default:
Packit b1f7ae
				*dfun = &pt_decode_unknown;
Packit b1f7ae
				return 0;
Packit b1f7ae
Packit b1f7ae
			case pt_ext2_mnt:
Packit b1f7ae
				*dfun = &pt_decode_mnt;
Packit b1f7ae
				return 0;
Packit b1f7ae
			}
Packit b1f7ae
		}
Packit b1f7ae
	}
Packit b1f7ae
}