/*
 * Copyright (c) 2016-2017, Intel Corporation
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 *  * Redistributions of source code must retain the above copyright notice,
 *    this list of conditions and the following disclaimer.
 *  * Redistributions in binary form must reproduce the above copyright notice,
 *    this list of conditions and the following disclaimer in the documentation
 *    and/or other materials provided with the distribution.
 *  * Neither the name of Intel Corporation nor the names of its contributors
 *    may be used to endorse or promote products derived from this software
 *    without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */

#ifndef PT_INSN_H
#define PT_INSN_H

#include <inttypes.h>

#include "intel-pt.h"

struct pt_insn_ext;


/* A finer-grain classification of instructions used internally. */
typedef enum {
	PTI_INST_INVALID,

	PTI_INST_CALL_9A,
	PTI_INST_CALL_FFr3,
	PTI_INST_CALL_FFr2,
	PTI_INST_CALL_E8,
	PTI_INST_INT,

	PTI_INST_INT3,
	PTI_INST_INT1,
	PTI_INST_INTO,
	PTI_INST_IRET,	/* includes IRETD and IRETQ (EOSZ determines) */

	PTI_INST_JMP_E9,
	PTI_INST_JMP_EB,
	PTI_INST_JMP_EA,
	PTI_INST_JMP_FFr5,	/* REXW? */
	PTI_INST_JMP_FFr4,
	PTI_INST_JCC,
	PTI_INST_JrCXZ,
	PTI_INST_LOOP,
	PTI_INST_LOOPE,	/* aka Z */
	PTI_INST_LOOPNE,	/* aka NE */

	PTI_INST_MOV_CR3,

	PTI_INST_RET_C3,
	PTI_INST_RET_C2,
	PTI_INST_RET_CB,
	PTI_INST_RET_CA,

	PTI_INST_SYSCALL,
	PTI_INST_SYSENTER,
	PTI_INST_SYSEXIT,
	PTI_INST_SYSRET,

	PTI_INST_VMLAUNCH,
	PTI_INST_VMRESUME,
	PTI_INST_VMCALL,
	PTI_INST_VMPTRLD,

	PTI_INST_LAST
} pti_inst_enum_t;

/* Information about an instruction we need internally in addition to the
 * information provided in struct pt_insn.
 */
struct pt_insn_ext {
	/* A more detailed instruction class. */
	pti_inst_enum_t iclass;

	/* Instruction-specific information. */
	union {
		/* For branch instructions. */
		struct {
			/* The branch displacement.
			 *
			 * This is only valid for direct calls/jumps.
			 *
			 * The displacement is applied to the address of the
			 * instruction following the branch.
			 */
			int32_t displacement;

			/* A flag saying whether the branch is direct.
			 *
			 *   non-zero: direct
			 *   zero:     indirect
			 *
			 * This is expected to go away someday when we extend
			 * enum pt_insn_class to distinguish direct and indirect
			 * branches.
			 */
			uint8_t is_direct;
		} branch;
	} variant;
};


/* Check if the instruction @insn/@iext changes the current privilege level.
 *
 * Returns non-zero if it does, zero if it doesn't (or @insn/@iext is NULL).
 */
extern int pt_insn_changes_cpl(const struct pt_insn *insn,
			       const struct pt_insn_ext *iext);

/* Check if the instruction @insn/@iext changes CR3.
 *
 * Returns non-zero if it does, zero if it doesn't (or @insn/@iext is NULL).
 */
extern int pt_insn_changes_cr3(const struct pt_insn *insn,
			       const struct pt_insn_ext *iext);

/* Check if the instruction @insn/@iext is a (near or far) branch.
 *
 * Returns non-zero if it is, zero if it isn't (or @insn/@iext is NULL).
 */
extern int pt_insn_is_branch(const struct pt_insn *insn,
			     const struct pt_insn_ext *iext);

/* Check if the instruction @insn/@iext is a far branch.
 *
 * Returns non-zero if it is, zero if it isn't (or @insn/@iext is NULL).
 */
extern int pt_insn_is_far_branch(const struct pt_insn *insn,
				 const struct pt_insn_ext *iext);

/* Check if the instruction @insn/@iext binds to a PIP packet.
 *
 * Returns non-zero if it does, zero if it doesn't (or @insn/@iext is NULL).
 */
extern int pt_insn_binds_to_pip(const struct pt_insn *insn,
				const struct pt_insn_ext *iext);

/* Check if the instruction @insn/@iext binds to a VMCS packet.
 *
 * Returns non-zero if it does, zero if it doesn't (or @insn/@iext is NULL).
 */
extern int pt_insn_binds_to_vmcs(const struct pt_insn *insn,
				 const struct pt_insn_ext *iext);

/* Determine the IP of the next instruction.
 *
 * Tries to determine the IP of the next instruction without using trace and
 * provides it in @ip unless @ip is NULL.
 *
 * Returns zero on success, a negative error code otherwise.
 * Returns -pte_bad_query if the IP can't be determined.
 * Returns -pte_internal if @insn or @iext is NULL.
 */
extern int pt_insn_next_ip(uint64_t *ip, const struct pt_insn *insn,
			   const struct pt_insn_ext *iext);

/* Decode and analyze one instruction.
 *
 * Decodes the instructruction at @insn->ip in @insn->mode into @insn and @iext.
 *
 * If the instruction can not be decoded using a single memory read in a single
 * section, sets @insn->truncated and reads the missing bytes from one or more
 * other sections until either the instruction can be decoded or we're sure it
 * is invalid.
 *
 * Returns the size in bytes on success, a negative error code otherwise.
 * Returns -pte_bad_insn if the instruction could not be decoded.
 */
extern int pt_insn_decode(struct pt_insn *insn, struct pt_insn_ext *iext,
			  struct pt_image *image, const struct pt_asid *asid);

/* Determine if a range of instructions is contiguous.
 *
 * Try to proceed from IP @begin to IP @end in @asid without using trace.
 *
 * Returns a positive integer if we reach @end from @begin.
 * Returns zero if we couldn't reach @end within @nsteps steps.
 * Returns a negative error code otherwise.
 */
extern int pt_insn_range_is_contiguous(uint64_t begin, uint64_t end,
				       enum pt_exec_mode mode,
				       struct pt_image *image,
				       const struct pt_asid *asid,
				       size_t nsteps);

#endif /* PT_INSN_H */
