diff options
Diffstat (limited to 'libipt/internal')
37 files changed, 6314 insertions, 0 deletions
diff --git a/libipt/internal/include/posix/pt_section_posix.h b/libipt/internal/include/posix/pt_section_posix.h new file mode 100644 index 000000000000..b1ed5b1236eb --- /dev/null +++ b/libipt/internal/include/posix/pt_section_posix.h @@ -0,0 +1,100 @@ +/* + * Copyright (c) 2015-2019, 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_SECTION_POSIX_H +#define PT_SECTION_POSIX_H + +#include <stdint.h> +#include <sys/stat.h> + +struct pt_section; + + +/* Fstat-based file status. */ +struct pt_sec_posix_status { + /* The file status. */ + struct stat stat; +}; + +/* MMAP-based section mapping information. */ +struct pt_sec_posix_mapping { + /* The mmap base address. */ + uint8_t *base; + + /* The mapped memory size. */ + uint64_t size; + + /* The begin and end of the mapped memory. */ + const uint8_t *begin, *end; +}; + + +/* Map a section. + * + * On success, sets @section's mapping, unmap, and read pointers. + * + * Returns zero on success, a negative error code otherwise. + * Returns -pte_internal if @section or @file are NULL. + * Returns -pte_invalid if @section can't be mapped. + */ +extern int pt_sec_posix_map(struct pt_section *section, int fd); + +/* Unmap a section. + * + * On success, clears @section's mapping, unmap, and read pointers. + * + * Returns zero on success, a negative error code otherwise. + * Returns -pte_internal if @section is NULL. + * Returns -pte_internal if @section has not been mapped. + */ +extern int pt_sec_posix_unmap(struct pt_section *section); + +/* Read memory from an mmaped section. + * + * Reads at most @size bytes from @section at @offset into @buffer. + * + * Returns the number of bytes read on success, a negative error code otherwise. + * Returns -pte_invalid if @section or @buffer are NULL. + * Returns -pte_nomap if @offset is beyond the end of the section. + */ +extern int pt_sec_posix_read(const struct pt_section *section, uint8_t *buffer, + uint16_t size, uint64_t offset); + +/* Compute the memory size of a section. + * + * On success, provides the amount of memory used for mapping @section in bytes + * in @size. + * + * Returns zero on success, a negative error code otherwise. + * Returns -pte_internal if @section or @size is NULL. + * Returns -pte_internal if @section has not been mapped. + */ +extern int pt_sec_posix_memsize(const struct pt_section *section, + uint64_t *size); + +#endif /* PT_SECTION_POSIX_H */ diff --git a/libipt/internal/include/pt_asid.h b/libipt/internal/include/pt_asid.h new file mode 100644 index 000000000000..a97a4814ba7c --- /dev/null +++ b/libipt/internal/include/pt_asid.h @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2014-2019, 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_ASID_H +#define PT_ASID_H + +#include <stddef.h> + +struct pt_asid; + + +/* Read an asid provided by our user. + * + * Translate a user-provided asid in @user into @asid. This uses default values + * for fields that are not provided by the user and for all fields, if @user is + * NULL. + * + * Fields set in @user that are not known (i.e. from a newer version of this + * library) will be ignored. + * + * Returns zero on success, a negative error code otherwise. + * Returns -pte_internal, if @asid is NULL. + */ +extern int pt_asid_from_user(struct pt_asid *asid, const struct pt_asid *user); + +/* Provide an asid to the user. + * + * Translate @asid into a potentially older or newer version in @user. + * + * Returns zero on success, a negative error code otherwise. + * Returns -pte_internal, if @user or @asid is NULL. + * Returns -pte_invalid, if @size is too small. + */ +extern int pt_asid_to_user(struct pt_asid *user, const struct pt_asid *asid, + size_t size); + +/* Match two asids. + * + * Asids match if all fields provide either default values or are identical. + * + * Returns a positive number if @lhs matches @rhs. + * Returns zero if @lhs does not match @rhs. + * Returns a negative error code otherwise. + * + * Returns -pte_internal if @lhs or @rhs are NULL. + */ +extern int pt_asid_match(const struct pt_asid *lhs, const struct pt_asid *rhs); + +#endif /* PT_ASID_H */ diff --git a/libipt/internal/include/pt_block_cache.h b/libipt/internal/include/pt_block_cache.h new file mode 100644 index 000000000000..8745e787350b --- /dev/null +++ b/libipt/internal/include/pt_block_cache.h @@ -0,0 +1,225 @@ +/* + * Copyright (c) 2016-2019, 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_BLOCK_CACHE_H +#define PT_BLOCK_CACHE_H + +#include "intel-pt.h" + +#include <stdint.h> + + +/* A block cache entry qualifier. + * + * This describes what to do at the decision point determined by a block cache + * entry. + */ +enum pt_bcache_qualifier { + /* This is not a decision point. + * + * The next decision point is too far away and one or more fields + * threatened to overflow so we had to stop somewhere on our way. + * + * Apply the displacement and number of instructions and continue from + * the resulting IP. + */ + ptbq_again, + + /* The decision point is a conditional branch. + * + * This requires a conditional branch query. + * + * The isize field should provide the size of the branch instruction so + * only taken branches require the instruction to be decoded. + */ + ptbq_cond, + + /* The decision point is a near indirect call. + * + * This requires a return-address stack update and an indirect branch + * query. + * + * The isize field should provide the size of the call instruction so + * the return address can be computed by adding it to the displacement + * that brings us to the call instruction. + * + * No instruction decode is required. + */ + ptbq_ind_call, + + /* The decision point is a near return. + * + * The return may be compressed so this requires a conditional branch + * query to determine the compression state and either a return-address + * stack lookup or an indirect branch query. + * + * No instruction decode is required. + */ + ptbq_return, + + /* The decision point is an indirect jump or far branch. + * + * This requires an indirect branch query. + * + * No instruction decode is required. + */ + ptbq_indirect, + + /* The decision point requires the instruction at the decision point IP + * to be decoded to determine the next step. + * + * This is used for + * + * - near direct calls that need to maintain the return-address stack. + * + * - near direct jumps that are too far away to be handled with a + * block cache entry as they would overflow the displacement field. + */ + ptbq_decode +}; + +/* A block cache entry. + * + * There will be one such entry per byte of decoded memory image. Each entry + * corresponds to an IP in the traced memory image. The cache is initialized + * with invalid entries for all IPs. + * + * Only entries for the first byte of each instruction will be used; other + * entries are ignored and will remain invalid. + * + * Each valid entry gives the distance from the entry's IP to the next decision + * point both in bytes and in the number of instructions. + */ +struct pt_bcache_entry { + /* The displacement to the next decision point in bytes. + * + * This is zero if we are at a decision point except for ptbq_again + * where it gives the displacement to the next block cache entry to be + * used. + */ + int32_t displacement:16; + + /* The number of instructions to the next decision point. + * + * This is typically one at a decision point since we are already + * accounting for the instruction at the decision point. + * + * Note that this field must be smaller than the respective struct + * pt_block field so we can fit one block cache entry into an empty + * block. + */ + uint32_t ninsn:8; + + /* The execution mode for all instruction between here and the next + * decision point. + * + * This is enum pt_exec_mode. + * + * This is ptem_unknown if the entry is not valid. + */ + uint32_t mode:2; + + /* The decision point qualifier. + * + * This is enum pt_bcache_qualifier. + */ + uint32_t qualifier:3; + + /* The size of the instruction at the decision point. + * + * This is zero if the size is too big to fit into the field. In this + * case, the instruction needs to be decoded to determine its size. + */ + uint32_t isize:3; +}; + +/* Get the execution mode of a block cache entry. */ +static inline enum pt_exec_mode pt_bce_exec_mode(struct pt_bcache_entry bce) +{ + return (enum pt_exec_mode) bce.mode; +} + +/* Get the block cache qualifier of a block cache entry. */ +static inline enum pt_bcache_qualifier +pt_bce_qualifier(struct pt_bcache_entry bce) +{ + return (enum pt_bcache_qualifier) bce.qualifier; +} + +/* Check if a block cache entry is valid. */ +static inline int pt_bce_is_valid(struct pt_bcache_entry bce) +{ + return pt_bce_exec_mode(bce) != ptem_unknown; +} + + + +/* A block cache. */ +struct pt_block_cache { + /* The number of cache entries. */ + uint32_t nentries; + + /* A variable-length array of @nentries entries. */ + struct pt_bcache_entry entry[]; +}; + +/* Create a block cache. + * + * @nentries is the number of entries in the cache and should match the size of + * the to-be-cached section in bytes. + */ +extern struct pt_block_cache *pt_bcache_alloc(uint64_t nentries); + +/* Destroy a block cache. */ +extern void pt_bcache_free(struct pt_block_cache *bcache); + +/* Cache a block. + * + * It is expected that all calls for the same @index write the same @bce. + * + * Returns zero on success, a negative error code otherwise. + * Returns -pte_internal if @bcache is NULL. + * Returns -pte_internal if @index is outside of @bcache. + */ +extern int pt_bcache_add(struct pt_block_cache *bcache, uint64_t index, + struct pt_bcache_entry bce); + +/* Lookup a cached block. + * + * The returned cache entry need not be valid. The caller is expected to check + * for validity using pt_bce_is_valid(*@bce). + * + * Returns zero on success, a negative error code otherwise. + * Returns -pte_internal if @bcache or @bce is NULL. + * Returns -pte_internal if @index is outside of @bcache. + */ +extern int pt_bcache_lookup(struct pt_bcache_entry *bce, + const struct pt_block_cache *bcache, + uint64_t index); + +#endif /* PT_BLOCK_CACHE_H */ diff --git a/libipt/internal/include/pt_block_decoder.h b/libipt/internal/include/pt_block_decoder.h new file mode 100644 index 000000000000..e84259ca4f08 --- /dev/null +++ b/libipt/internal/include/pt_block_decoder.h @@ -0,0 +1,143 @@ +/* + * Copyright (c) 2016-2019, 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_BLOCK_DECODER_H +#define PT_BLOCK_DECODER_H + +#include "pt_query_decoder.h" +#include "pt_image.h" +#include "pt_retstack.h" +#include "pt_ild.h" +#include "pt_msec_cache.h" + + +/* A block decoder. + * + * It decodes Intel(R) Processor Trace into a sequence of instruction blocks + * such that the instructions in each block can be decoded without further need + * of trace. + */ +struct pt_block_decoder { + /* The Intel(R) Processor Trace query decoder. */ + struct pt_query_decoder query; + + /* The configuration flags. + * + * Those are our flags set by the user. In @query.config.flags, we set + * the flags we need for the query decoder. + */ + struct pt_conf_flags flags; + + /* The default image. */ + struct pt_image default_image; + + /* The image. */ + struct pt_image *image; + + /* The current cached section. */ + struct pt_msec_cache scache; + + /* The current address space. */ + struct pt_asid asid; + + /* The current Intel(R) Processor Trace event. */ + struct pt_event event; + + /* The call/return stack for ret compression. */ + struct pt_retstack retstack; + + /* The current instruction. + * + * This is only valid if @process_insn is set. + */ + struct pt_insn insn; + struct pt_insn_ext iext; + + /* The start IP of the next block. + * + * If tracing is disabled, this is the IP at which we assume tracing to + * be resumed. + */ + uint64_t ip; + + /* The current execution mode. */ + enum pt_exec_mode mode; + + /* The status of the last successful decoder query. + * + * Errors are reported directly; the status is always a non-negative + * pt_status_flag bit-vector. + */ + int status; + + /* A collection of flags defining how to proceed flow reconstruction: + * + * - tracing is enabled. + */ + uint32_t enabled:1; + + /* - process @event. */ + uint32_t process_event:1; + + /* - instructions are executed speculatively. */ + uint32_t speculative:1; + + /* - process @insn/@iext. + * + * We have started processing events binding to @insn/@iext. The + * instruction has been accounted for in the previous block, but we + * have not yet proceeded past it. + * + * We will do so in pt_blk_event() after processing all events that + * bind to it. + */ + uint32_t process_insn:1; + + /* - a paging event has already been bound to @insn/@iext. */ + uint32_t bound_paging:1; + + /* - a vmcs event has already been bound to @insn/@iext. */ + uint32_t bound_vmcs:1; + + /* - a ptwrite event has already been bound to @insn/@iext. */ + uint32_t bound_ptwrite:1; +}; + + +/* Initialize a block decoder. + * + * Returns zero on success; a negative error code otherwise. + * Returns -pte_internal, if @decoder or @config is NULL. + */ +extern int pt_blk_decoder_init(struct pt_block_decoder *decoder, + const struct pt_config *config); + +/* Finalize a block decoder. */ +extern void pt_blk_decoder_fini(struct pt_block_decoder *decoder); + +#endif /* PT_BLOCK_DECODER_H */ diff --git a/libipt/internal/include/pt_config.h b/libipt/internal/include/pt_config.h new file mode 100644 index 000000000000..5d18ca42485a --- /dev/null +++ b/libipt/internal/include/pt_config.h @@ -0,0 +1,82 @@ +/* + * Copyright (c) 2015-2019, 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. + */ + +#include "intel-pt.h" + + +/* Read the configuration provided by a library user and zero-initialize + * missing fields. + * + * We keep the user's size value if it is smaller than sizeof(*@config) to + * allow decoders to detect missing configuration bits. + * + * Returns zero on success, a negative error code otherwise. + * Returns -pte_internal if @config is NULL. + * Returns -pte_invalid if @uconfig is NULL. + * Returns -pte_bad_config if @config is too small to be useful. + */ +extern int pt_config_from_user(struct pt_config *config, + const struct pt_config *uconfig); + +/* Get the configuration for the n'th address filter. + * + * Returns zero if @filter is NULL or @n is out of bounds. + * + * This corresponds to IA32_RTIT_CTL.ADDRn_CFG. + */ +extern uint32_t pt_filter_addr_cfg(const struct pt_conf_addr_filter *filter, + uint8_t n); + +/* Get the lower bound (inclusive) of the n'th address filter. + * + * Returns zero if @filter is NULL or @n is out of bounds. + * + * This corresponds to IA32_RTIT_ADDRn_A. + */ +extern uint64_t pt_filter_addr_a(const struct pt_conf_addr_filter *filter, + uint8_t n); + +/* Get the upper bound (inclusive) of the n'th address filter. + * + * Returns zero if @filter is NULL or @n is out of bounds. + * + * This corresponds to IA32_RTIT_ADDRn_B. + */ +extern uint64_t pt_filter_addr_b(const struct pt_conf_addr_filter *filter, + uint8_t n); + +/* Check address filters. + * + * Checks @addr against @filter. + * + * Returns a positive number if @addr lies in a tracing-enabled region. + * Returns zero if @addr lies in a tracing-disabled region. + * Returns a negative pt_error_code otherwise. + */ +extern int pt_filter_addr_check(const struct pt_conf_addr_filter *filter, + uint64_t addr); diff --git a/libipt/internal/include/pt_cpu.h b/libipt/internal/include/pt_cpu.h new file mode 100644 index 000000000000..3a1da3a4dba7 --- /dev/null +++ b/libipt/internal/include/pt_cpu.h @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2013-2019, 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_CPU_H +#define PT_CPU_H + +struct pt_cpu; + +/* Parses @s which should be of format family/model[/stepping] and + * stores the value in @cpu on success. + * The optional stepping defaults to 0 if omitted. + * + * Returns 0 on success. + * Returns -pte_invalid if @cpu or @s is NULL. + * Returns -pte_invalid if @s could not be parsed. + */ +extern int pt_cpu_parse(struct pt_cpu *cpu, const char *s); + +/* Get the cpu we're running on. + * + * Reads the family/model/stepping of the processor on which this function + * is executed and stores the value in @cpu. + * + * Returns zero on success, a negative error code otherwise. + * Returns -pte_invalid if @cpu is NULL. + */ +extern int pt_cpu_read(struct pt_cpu *cpu); + +#endif /* PT_CPU_H */ diff --git a/libipt/internal/include/pt_cpuid.h b/libipt/internal/include/pt_cpuid.h new file mode 100644 index 000000000000..995ad80abbe0 --- /dev/null +++ b/libipt/internal/include/pt_cpuid.h @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2013-2019, 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_CPUID_H +#define PT_CPUID_H + +#include <inttypes.h> + +/* Execute cpuid with @leaf set in the eax register. + * The result is stored in @eax, @ebx, @ecx and @edx. + */ +extern void pt_cpuid(uint32_t leaf, uint32_t *eax, uint32_t *ebx, + uint32_t *ecx, uint32_t *edx); + +#endif /* PT_CPUID_H */ diff --git a/libipt/internal/include/pt_decoder_function.h b/libipt/internal/include/pt_decoder_function.h new file mode 100644 index 000000000000..0b59dc695fa7 --- /dev/null +++ b/libipt/internal/include/pt_decoder_function.h @@ -0,0 +1,129 @@ +/* + * Copyright (c) 2013-2019, 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_DECODER_FUNCTION_H +#define PT_DECODER_FUNCTION_H + +#include <stdint.h> + +struct pt_query_decoder; +struct pt_packet_decoder; +struct pt_packet; +struct pt_config; + + +/* Intel(R) Processor Trace decoder function flags. */ +enum pt_decoder_function_flag { + /* The decoded packet contains an unconditional branch destination. */ + pdff_tip = 1 << 0, + + /* The decode packet contains unconditional branch destinations. */ + pdff_tnt = 1 << 1, + + /* The decoded packet contains an event. */ + pdff_event = 1 << 2, + + /* The decoded packet marks the end of a PSB header. */ + pdff_psbend = 1 << 3, + + /* The decoded packet contains a non-branch IP update. */ + pdff_fup = 1 << 4, + + /* The decoded packet is unknown to the decoder. */ + pdff_unknown = 1 << 5, + + /* The decoded packet contains timing information. */ + pdff_timing = 1 << 6, + + /* The decoded packet contains padding. */ + pdff_pad = 1 << 7 +}; + +/* An Intel(R) Processor Trace decoder function. */ +struct pt_decoder_function { + /* The function to analyze the next packet. */ + int (*packet)(struct pt_packet_decoder *, struct pt_packet *); + + /* The function to decode the next packet. */ + int (*decode)(struct pt_query_decoder *); + + /* The function to decode the next packet in segment header + * context, i.e. between PSB and ENDPSB. + */ + int (*header)(struct pt_query_decoder *); + + /* Decoder function flags. */ + int flags; +}; + + +/* Fetch the decoder function. + * + * Sets @dfun to the decoder function for decoding the packet at @pos. + * + * Returns 0 on success. + * Returns -pte_internal if @dfun or @config is NULL. + * Returns -pte_nosync if @pos is NULL or outside @config's trace buffer. + * Returns -pte_eos if the opcode is incomplete or missing. + */ +extern int pt_df_fetch(const struct pt_decoder_function **dfun, + const uint8_t *pos, const struct pt_config *config); + + +/* Decoder functions for the various packet types. + * + * Do not call those functions directly! + */ +extern const struct pt_decoder_function pt_decode_unknown; +extern const struct pt_decoder_function pt_decode_pad; +extern const struct pt_decoder_function pt_decode_psb; +extern const struct pt_decoder_function pt_decode_tip; +extern const struct pt_decoder_function pt_decode_tnt_8; +extern const struct pt_decoder_function pt_decode_tnt_64; +extern const struct pt_decoder_function pt_decode_tip_pge; +extern const struct pt_decoder_function pt_decode_tip_pgd; +extern const struct pt_decoder_function pt_decode_fup; +extern const struct pt_decoder_function pt_decode_pip; +extern const struct pt_decoder_function pt_decode_ovf; +extern const struct pt_decoder_function pt_decode_mode; +extern const struct pt_decoder_function pt_decode_psbend; +extern const struct pt_decoder_function pt_decode_tsc; +extern const struct pt_decoder_function pt_decode_cbr; +extern const struct pt_decoder_function pt_decode_tma; +extern const struct pt_decoder_function pt_decode_mtc; +extern const struct pt_decoder_function pt_decode_cyc; +extern const struct pt_decoder_function pt_decode_stop; +extern const struct pt_decoder_function pt_decode_vmcs; +extern const struct pt_decoder_function pt_decode_mnt; +extern const struct pt_decoder_function pt_decode_exstop; +extern const struct pt_decoder_function pt_decode_mwait; +extern const struct pt_decoder_function pt_decode_pwre; +extern const struct pt_decoder_function pt_decode_pwrx; +extern const struct pt_decoder_function pt_decode_ptw; + +#endif /* PT_DECODER_FUNCTION_H */ diff --git a/libipt/internal/include/pt_encoder.h b/libipt/internal/include/pt_encoder.h new file mode 100644 index 000000000000..f1b338e80848 --- /dev/null +++ b/libipt/internal/include/pt_encoder.h @@ -0,0 +1,125 @@ +/* + * Copyright (c) 2014-2019, 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_ENCODER_H +#define PT_ENCODER_H + +#include "intel-pt.h" + + +/* An Intel PT packet encoder. */ +struct pt_encoder { + /* The encoder configuration. */ + struct pt_config config; + + /** The current position in the trace buffer. */ + uint8_t *pos; +}; + + +/* Initialize the packet encoder. + * + * Returns zero on success, a negative error code otherwise. + */ +extern int pt_encoder_init(struct pt_encoder *, const struct pt_config *); + +/* Finalize the packet encoder. */ +extern void pt_encoder_fini(struct pt_encoder *); + + +/* The below functions are convenience wrappers around pt_enc_next(). */ + +/* Encode a Padding (pad) packet. */ +extern int pt_encode_pad(struct pt_encoder *); + +/* Encode a Packet Stream Boundary (psb) packet. */ +extern int pt_encode_psb(struct pt_encoder *); + +/* Encode an End PSB (psbend) packet. */ +extern int pt_encode_psbend(struct pt_encoder *); + +/* Encode a Target Instruction Pointer (tip) packet. */ +extern int pt_encode_tip(struct pt_encoder *, uint64_t ip, + enum pt_ip_compression ipc); + +/* Encode a Taken Not Taken (tnt) packet - 8-bit version. */ +extern int pt_encode_tnt_8(struct pt_encoder *, uint8_t tnt, int size); + +/* Encode a Taken Not Taken (tnt) packet - 64-bit version. */ +extern int pt_encode_tnt_64(struct pt_encoder *, uint64_t tnt, int size); + +/* Encode a Packet Generation Enable (tip.pge) packet. */ +extern int pt_encode_tip_pge(struct pt_encoder *, uint64_t ip, + enum pt_ip_compression ipc); + +/* Encode a Packet Generation Disable (tip.pgd) packet. */ +extern int pt_encode_tip_pgd(struct pt_encoder *, uint64_t ip, + enum pt_ip_compression ipc); + +/* Encode a Flow Update Packet (fup). */ +extern int pt_encode_fup(struct pt_encoder *, uint64_t ip, + enum pt_ip_compression ipc); + +/* Encode a Paging Information Packet (pip). */ +extern int pt_encode_pip(struct pt_encoder *, uint64_t cr3, uint8_t flags); + +/* Encode a Overflow Packet (ovf). */ +extern int pt_encode_ovf(struct pt_encoder *); + +/* Encode a Mode Exec Packet (mode.exec). */ +extern int pt_encode_mode_exec(struct pt_encoder *, enum pt_exec_mode); + +/* Encode a Mode Tsx Packet (mode.tsx). */ +extern int pt_encode_mode_tsx(struct pt_encoder *, uint8_t); + +/* Encode a Time Stamp Counter (tsc) packet. */ +extern int pt_encode_tsc(struct pt_encoder *, uint64_t); + +/* Encode a Core Bus Ratio (cbr) packet. */ +extern int pt_encode_cbr(struct pt_encoder *, uint8_t); + +/* Encode a TSC/MTC Alignment (tma) packet. */ +extern int pt_encode_tma(struct pt_encoder *, uint16_t ctc, + uint16_t fc); + +/* Encode a Mini Time Counter (mtc) packet. */ +extern int pt_encode_mtc(struct pt_encoder *, uint8_t ctc); + +/* Encode a Cycle Count (cyc) packet. */ +extern int pt_encode_cyc(struct pt_encoder *, uint32_t cyc); + +/* Encode a TraceStop Packet (stop). */ +extern int pt_encode_stop(struct pt_encoder *); + +/* Encode a VMCS packet. */ +extern int pt_encode_vmcs(struct pt_encoder *, uint64_t); + +/* Encode a Maintenance (mnt) packet. */ +extern int pt_encode_mnt(struct pt_encoder *, uint64_t); + +#endif /* PT_ENCODER_H */ diff --git a/libipt/internal/include/pt_event_queue.h b/libipt/internal/include/pt_event_queue.h new file mode 100644 index 000000000000..a6df4ca32468 --- /dev/null +++ b/libipt/internal/include/pt_event_queue.h @@ -0,0 +1,143 @@ +/* + * Copyright (c) 2013-2019, 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_EVENT_QUEUE_H +#define PT_EVENT_QUEUE_H + +#include "intel-pt.h" + +#include <stdint.h> + + +/* Events are grouped by the packet the event binds to. */ +enum pt_event_binding { + evb_psbend, + evb_tip, + evb_fup, + + evb_max +}; + +enum { + /* The maximal number of pending events - should be a power of two. */ + evq_max = 8 +}; + +/* A queue of events. */ +struct pt_event_queue { + /* A collection of event queues, one per binding. */ + struct pt_event queue[evb_max][evq_max]; + + /* The begin and end indices for the above event queues. */ + uint8_t begin[evb_max]; + uint8_t end[evb_max]; + + /* A standalone event to be published immediately. */ + struct pt_event standalone; +}; + + +/* Initialize (or reset) an event queue. */ +extern void pt_evq_init(struct pt_event_queue *); + +/* Get a standalone event. + * + * Returns a pointer to the standalone event on success. + * Returns NULL if @evq is NULL. + */ +extern struct pt_event *pt_evq_standalone(struct pt_event_queue *evq); + +/* Enqueue an event. + * + * Adds a new event to @evq for binding @evb. + * + * Returns a pointer to the new event on success. + * Returns NULL if @evq is NULL or @evb is invalid. + * Returns NULL if @evq is full. + */ +extern struct pt_event *pt_evq_enqueue(struct pt_event_queue *evq, + enum pt_event_binding evb); + + +/* Dequeue an event. + * + * Removes the first event for binding @evb from @evq. + * + * Returns a pointer to the dequeued event on success. + * Returns NULL if @evq is NULL or @evb is invalid. + * Returns NULL if @evq is empty. + */ +extern struct pt_event *pt_evq_dequeue(struct pt_event_queue *evq, + enum pt_event_binding evb); + +/* Clear a queue and discard events. + * + * Removes all events for binding @evb from @evq. + * + * Returns zero on success, a negative error code otherwise. + * Returns -pte_internal if @evq is NULL or @evb is invalid. + */ +extern int pt_evq_clear(struct pt_event_queue *evq, + enum pt_event_binding evb); + +/* Check for emptiness. + * + * Check if @evq for binding @evb is empty. + * + * Returns a positive number if @evq is empty. + * Returns zero if @evq is not empty. + * Returns -pte_internal if @evq is NULL or @evb is invalid. + */ +extern int pt_evq_empty(const struct pt_event_queue *evq, + enum pt_event_binding evb); + +/* Check for non-emptiness. + * + * Check if @evq for binding @evb contains pending events. + * + * Returns a positive number if @evq is not empty. + * Returns zero if @evq is empty. + * Returns -pte_internal if @evq is NULL or @evb is invalid. + */ +extern int pt_evq_pending(const struct pt_event_queue *evq, + enum pt_event_binding evb); + +/* Find an event by type. + * + * Searches @evq for binding @evb for an event of type @evt. + * + * Returns a pointer to the first matching event on success. + * Returns NULL if there is no such event. + * Returns NULL if @evq is NULL. + * Returns NULL if @evb or @evt is invalid. + */ +extern struct pt_event *pt_evq_find(struct pt_event_queue *evq, + enum pt_event_binding evb, + enum pt_event_type evt); + +#endif /* PT_EVENT_QUEUE_H */ diff --git a/libipt/internal/include/pt_ild.h b/libipt/internal/include/pt_ild.h new file mode 100644 index 000000000000..ebc41f575299 --- /dev/null +++ b/libipt/internal/include/pt_ild.h @@ -0,0 +1,123 @@ +/* + * Copyright (c) 2013-2019, 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. + */ + +#if !defined(PT_ILD_H) +#define PT_ILD_H + +#include "pt_insn.h" + +#include "intel-pt.h" + + +typedef enum { + PTI_MAP_0, /* 1-byte opcodes. may have modrm */ + PTI_MAP_1, /* 2-byte opcodes (0x0f). may have modrm */ + PTI_MAP_2, /* 3-byte opcodes (0x0f38). has modrm */ + PTI_MAP_3, /* 3-byte opcodes (0x0f3a). has modrm */ + PTI_MAP_AMD3DNOW, /* 3d-now opcodes (0x0f0f). has modrm */ + PTI_MAP_INVALID +} pti_map_enum_t; + +struct pt_ild { + /* inputs */ + uint8_t const *itext; + uint8_t max_bytes; /*1..15 bytes */ + enum pt_exec_mode mode; + + union { + struct { + uint32_t osz:1; + uint32_t asz:1; + uint32_t lock:1; + uint32_t f3:1; + uint32_t f2:1; + uint32_t last_f2f3:2; /* 2 or 3 */ + /* The vex bit is set for c4/c5 VEX and EVEX. */ + uint32_t vex:1; + /* The REX.R and REX.W bits in REX, VEX, or EVEX. */ + uint32_t rex_r:1; + uint32_t rex_w:1; + } s; + uint32_t i; + } u; + uint8_t imm1_bytes; /* # of bytes in 1st immediate */ + uint8_t imm2_bytes; /* # of bytes in 2nd immediate */ + uint8_t disp_bytes; /* # of displacement bytes */ + uint8_t modrm_byte; + /* 5b but valid values= 0,1,2,3 could be in bit union */ + uint8_t map; + uint8_t rex; /* 0b0100wrxb */ + uint8_t nominal_opcode; + uint8_t disp_pos; + /* imm_pos can be derived from disp_pos + disp_bytes. */ +}; + +static inline pti_map_enum_t pti_get_map(const struct pt_ild *ild) +{ + return (pti_map_enum_t) ild->map; +} + +static inline uint8_t pti_get_modrm_mod(const struct pt_ild *ild) +{ + return ild->modrm_byte >> 6; +} + +static inline uint8_t pti_get_modrm_reg(const struct pt_ild *ild) +{ + return (ild->modrm_byte >> 3) & 7; +} + +static inline uint8_t pti_get_modrm_rm(const struct pt_ild *ild) +{ + return ild->modrm_byte & 7; +} + +/* all decoding is multithread safe. */ + +/* Decode one instruction. + * + * Input: + * + * @insn->ip: the virtual address of the instruction + * @insn->raw: the memory at that virtual address + * @insn->size: the maximal size of the instruction + * @insn->mode: the execution mode + * + * Output: + * + * @insn->size: the actual size of the instruction + * @insn->iclass: a coarse classification + * + * @iext->iclass: a finer grain classification + * @iext->variant: instruction class dependent information + * + * Returns zero on success, a negative error code otherwise. + */ +extern int pt_ild_decode(struct pt_insn *insn, struct pt_insn_ext *iext); + +#endif /* PT_ILD_H */ diff --git a/libipt/internal/include/pt_image.h b/libipt/internal/include/pt_image.h new file mode 100644 index 000000000000..8b05b480ce2b --- /dev/null +++ b/libipt/internal/include/pt_image.h @@ -0,0 +1,140 @@ +/* + * Copyright (c) 2013-2019, 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_IMAGE_H +#define PT_IMAGE_H + +#include "pt_mapped_section.h" + +#include "intel-pt.h" + +#include <stdint.h> + + +/* A list of sections. */ +struct pt_section_list { + /* The next list element. */ + struct pt_section_list *next; + + /* The mapped section. */ + struct pt_mapped_section section; + + /* The image section identifier. */ + int isid; +}; + +/* A traced image consisting of a collection of sections. */ +struct pt_image { + /* The optional image name. */ + char *name; + + /* The list of sections. */ + struct pt_section_list *sections; + + /* An optional read memory callback. */ + struct { + /* The callback function. */ + read_memory_callback_t *callback; + + /* The callback context. */ + void *context; + } readmem; +}; + +/* Initialize an image with an optional @name. */ +extern void pt_image_init(struct pt_image *image, const char *name); + +/* Finalize an image. + * + * This removes all sections and frees the name. + */ +extern void pt_image_fini(struct pt_image *image); + +/* Add a section to an image. + * + * Add @section identified by @isid to @image at @vaddr in @asid. If @section + * overlaps with existing sections, the existing sections are shrunk, split, or + * removed to accomodate @section. Absence of a section identifier is indicated + * by an @isid of zero. + * + * Returns zero on success. + * Returns -pte_internal if @image, @section, or @asid is NULL. + */ +extern int pt_image_add(struct pt_image *image, struct pt_section *section, + const struct pt_asid *asid, uint64_t vaddr, int isid); + +/* Remove a section from an image. + * + * Returns zero on success. + * Returns -pte_internal if @image, @section, or @asid is NULL. + * Returns -pte_bad_image if @image does not contain @section at @vaddr. + */ +extern int pt_image_remove(struct pt_image *image, struct pt_section *section, + const struct pt_asid *asid, uint64_t vaddr); + +/* Read memory from an image. + * + * Reads at most @size bytes from @image at @addr in @asid into @buffer. + * + * Returns the number of bytes read on success, a negative error code otherwise. + * Returns -pte_internal if @image, @isid, @buffer, or @asid is NULL. + * Returns -pte_nomap if the section does not contain @addr. + */ +extern int pt_image_read(struct pt_image *image, int *isid, uint8_t *buffer, + uint16_t size, const struct pt_asid *asid, + uint64_t addr); + +/* Find an image section. + * + * Find the section containing @vaddr in @asid and provide it in @msec. On + * success, takes a reference of @msec->section that the caller needs to put + * after use. + * + * Returns the section's identifier on success, a negative error code otherwise. + * Returns -pte_internal if @image, @msec, or @asid is NULL. + * Returns -pte_nomap if there is no such section in @image. + */ +extern int pt_image_find(struct pt_image *image, struct pt_mapped_section *msec, + const struct pt_asid *asid, uint64_t vaddr); + +/* Validate an image section. + * + * Validate that a lookup of @vaddr in @msec->asid in @image would result in + * @msec identified by @isid. + * + * Validation may fail sporadically. + * + * Returns zero on success, a negative error code otherwise. + * Returns -pte_invalid if @image or @msec is NULL. + * Returns -pte_nomap if validation failed. + */ +extern int pt_image_validate(const struct pt_image *image, + const struct pt_mapped_section *msec, + uint64_t vaddr, int isid); + +#endif /* PT_IMAGE_H */ diff --git a/libipt/internal/include/pt_image_section_cache.h b/libipt/internal/include/pt_image_section_cache.h new file mode 100644 index 000000000000..9e70c13de1c6 --- /dev/null +++ b/libipt/internal/include/pt_image_section_cache.h @@ -0,0 +1,206 @@ +/* + * Copyright (c) 2016-2019, 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_IMAGE_SECTION_CACHE_H +#define PT_IMAGE_SECTION_CACHE_H + +#include <stdint.h> + +#if defined(FEATURE_THREADS) +# include <threads.h> +#endif /* defined(FEATURE_THREADS) */ + +struct pt_section; + + +/* An image section cache entry. */ +struct pt_iscache_entry { + /* The section object. + * + * We hold a reference to the section - put it when the section is + * removed from the cache. + */ + struct pt_section *section; + + /* The base address at which @section has been loaded. */ + uint64_t laddr; +}; + +/* An image section cache least recently used cache entry. */ +struct pt_iscache_lru_entry { + /* The next entry in a list ordered by recent use. */ + struct pt_iscache_lru_entry *next; + + /* The section mapped by the image section cache. */ + struct pt_section *section; + + /* The amount of memory used by mapping @section in bytes. */ + uint64_t size; +}; + +/* A cache of image sections and their load addresses. + * + * We combine the section with its load address to reduce the amount of + * information we need to store in order to read from a cached section by + * virtual address. + * + * Internally, the section object will be shared if it is loaded at different + * addresses in the cache. + * + * The cache does not consider the address-space the section is mapped into. + * This is not relevant for reading from the section. + */ +struct pt_image_section_cache { + /* The optional name of the cache; NULL if not named. */ + char *name; + + /* An array of @nentries cached sections. */ + struct pt_iscache_entry *entries; + + /* A list of mapped sections ordered by time of last access. */ + struct pt_iscache_lru_entry *lru; + + /* The memory limit for our LRU cache. */ + uint64_t limit; + + /* The current size of our LRU cache. */ + uint64_t used; + +#if defined(FEATURE_THREADS) + /* A lock protecting this image section cache. */ + mtx_t lock; +#endif /* defined(FEATURE_THREADS) */ + + /* The capacity of the @entries array. + * + * Cached sections are identified by a positive integer, the image + * section identifier (isid), which is derived from their index into the + * @entries array. + * + * We can't expand the section cache capacity beyond INT_MAX. + */ + uint16_t capacity; + + /* The current size of the cache in number of entries. + * + * This is smaller than @capacity if there is still room in the @entries + * array; equal to @capacity if the @entries array is full and needs to + * be reallocated. + */ + uint16_t size; +}; + + +/* Initialize an image section cache. */ +extern int pt_iscache_init(struct pt_image_section_cache *iscache, + const char *name); + +/* Finalize an image section cache. */ +extern void pt_iscache_fini(struct pt_image_section_cache *iscache); + +/* Add a section to the cache. + * + * Adds @section at @laddr to @iscache and returns its isid. If a similar + * section is already cached, returns that section's isid, instead. + * + * We take a full section rather than its filename and range in that file to + * avoid the dependency to pt_section.h. Callers are expected to query the + * cache before creating the section, so we should only see unnecessary section + * creation/destruction on insertion races. + * + * Returns zero on success, a negative error code otherwise. + * Returns -pte_internal if @iscache or @section is NULL. + * Returns -pte_internal if @section's filename is NULL. + */ +extern int pt_iscache_add(struct pt_image_section_cache *iscache, + struct pt_section *section, uint64_t laddr); + +/* Find a section in the cache. + * + * Returns a positive isid if a section matching @filename, @offset, @size + * loaded at @laddr is found in @iscache. + * Returns zero if no such section is found. + * Returns a negative error code otherwise. + * Returns -pte_internal if @iscache or @filename is NULL. + */ +extern int pt_iscache_find(struct pt_image_section_cache *iscache, + const char *filename, uint64_t offset, + uint64_t size, uint64_t laddr); + +/* Lookup the section identified by its isid. + * + * Provides a reference to the section in @section and its load address in + * @laddr on success. The caller is expected to put the returned section after + * use. + * + * Returns zero on success, a negative error code otherwise. + * Returns -pte_internal if @iscache, @section, or @laddr is NULL. + * Returns -pte_bad_image if @iscache does not contain @isid. + */ +extern int pt_iscache_lookup(struct pt_image_section_cache *iscache, + struct pt_section **section, uint64_t *laddr, + int isid); + +/* Clear an image section cache. */ +extern int pt_iscache_clear(struct pt_image_section_cache *iscache); + +/* Notify about the mapping of a cached section. + * + * Notifies @iscache that @section has been mapped. + * + * The caller guarantees that @iscache contains @section (by using @section's + * iscache pointer) and prevents @iscache from detaching. + * + * The caller must not lock @section to allow @iscache to map it. This function + * must not try to detach from @section. + * + * Returns zero on success, a negative pt_error_code otherwise. + * Returns -pte_internal if @iscache or @section is NULL. + * Returns -pte_bad_lock on any locking error. + */ +extern int pt_iscache_notify_map(struct pt_image_section_cache *iscache, + struct pt_section *section); + +/* Notify about a size change of a mapped section. + * + * Notifies @iscache that @section's size has changed while it was mapped. + * + * The caller guarantees that @iscache contains @section (by using @section's + * iscache pointer) and prevents @iscache from detaching. + * + * The caller must not lock @section to allow @iscache to map it. This function + * must not try to detach from @section. + * + * Returns zero on success, a negative pt_error_code otherwise. + * Returns -pte_internal if @iscache or @section is NULL. + * Returns -pte_bad_lock on any locking error. + */ +extern int pt_iscache_notify_resize(struct pt_image_section_cache *iscache, + struct pt_section *section, uint64_t size); + +#endif /* PT_IMAGE_SECTION_CACHE_H */ diff --git a/libipt/internal/include/pt_insn.h b/libipt/internal/include/pt_insn.h new file mode 100644 index 000000000000..56e1c9b65b7d --- /dev/null +++ b/libipt/internal/include/pt_insn.h @@ -0,0 +1,212 @@ +/* + * Copyright (c) 2016-2019, 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_PTWRITE, + + 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); + +/* Check if the instruction @insn/@iext is a ptwrite instruction. + * + * Returns non-zero if it is, zero if it isn't (or @insn/@iext is NULL). + */ +extern int pt_insn_is_ptwrite(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 */ diff --git a/libipt/internal/include/pt_insn_decoder.h b/libipt/internal/include/pt_insn_decoder.h new file mode 100644 index 000000000000..eef1dc8bb5cd --- /dev/null +++ b/libipt/internal/include/pt_insn_decoder.h @@ -0,0 +1,139 @@ +/* + * Copyright (c) 2013-2019, 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_DECODER_H +#define PT_INSN_DECODER_H + +#include "pt_query_decoder.h" +#include "pt_image.h" +#include "pt_retstack.h" +#include "pt_ild.h" +#include "pt_msec_cache.h" + +#include <inttypes.h> + + +struct pt_insn_decoder { + /* The Intel(R) Processor Trace query decoder. */ + struct pt_query_decoder query; + + /* The configuration flags. + * + * Those are our flags set by the user. In @query.config.flags, we set + * the flags we need for the query decoder. + */ + struct pt_conf_flags flags; + + /* The default image. */ + struct pt_image default_image; + + /* The image. */ + struct pt_image *image; + + /* The current cached section. */ + struct pt_msec_cache scache; + + /* The current address space. */ + struct pt_asid asid; + + /* The current Intel(R) Processor Trace event. */ + struct pt_event event; + + /* The call/return stack for ret compression. */ + struct pt_retstack retstack; + + /* The current instruction. + * + * This is only valid if @process_insn is set. + */ + struct pt_insn insn; + struct pt_insn_ext iext; + + /* The current IP. + * + * If tracing is disabled, this is the IP at which we assume tracing to + * be resumed. + */ + uint64_t ip; + + /* The current execution mode. */ + enum pt_exec_mode mode; + + /* The status of the last successful decoder query. + * + * Errors are reported directly; the status is always a non-negative + * pt_status_flag bit-vector. + */ + int status; + + /* A collection of flags defining how to proceed flow reconstruction: + * + * - tracing is enabled. + */ + uint32_t enabled:1; + + /* - process @event. */ + uint32_t process_event:1; + + /* - instructions are executed speculatively. */ + uint32_t speculative:1; + + /* - process @insn/@iext. + * + * We have started processing events binding to @insn/@iext. We have + * not yet proceeded past it. + * + * We will do so in pt_insn_event() after processing all events that + * bind to it. + */ + uint32_t process_insn:1; + + /* - a paging event has already been bound to @insn/@iext. */ + uint32_t bound_paging:1; + + /* - a vmcs event has already been bound to @insn/@iext. */ + uint32_t bound_vmcs:1; + + /* - a ptwrite event has already been bound to @insn/@iext. */ + uint32_t bound_ptwrite:1; +}; + + +/* Initialize an instruction flow decoder. + * + * Returns zero on success; a negative error code otherwise. + * Returns -pte_internal, if @decoder is NULL. + * Returns -pte_invalid, if @config is NULL. + */ +extern int pt_insn_decoder_init(struct pt_insn_decoder *decoder, + const struct pt_config *config); + +/* Finalize an instruction flow decoder. */ +extern void pt_insn_decoder_fini(struct pt_insn_decoder *decoder); + +#endif /* PT_INSN_DECODER_H */ diff --git a/libipt/internal/include/pt_last_ip.h b/libipt/internal/include/pt_last_ip.h new file mode 100644 index 000000000000..aaf068f2fd1f --- /dev/null +++ b/libipt/internal/include/pt_last_ip.h @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2013-2019, 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_LAST_IP_H +#define PT_LAST_IP_H + +#include <stdint.h> + +struct pt_packet_ip; +struct pt_config; + + +/* Keeping track of the last-ip in Intel PT packets. */ +struct pt_last_ip { + /* The last IP. */ + uint64_t ip; + + /* Flags governing the handling of IP updates and queries: + * + * - we have seen an IP update. + */ + uint32_t have_ip:1; + /* - the IP has been suppressed in the last update. */ + uint32_t suppressed:1; +}; + + +/* Initialize (or reset) the last-ip. */ +extern void pt_last_ip_init(struct pt_last_ip *last_ip); + +/* Query the last-ip. + * + * If @ip is not NULL, provides the last-ip in @ip on success. + * + * Returns zero on success. + * Returns -pte_internal if @last_ip is NULL. + * Returns -pte_noip if there is no last-ip. + * Returns -pte_ip_suppressed if the last-ip has been suppressed. + */ +extern int pt_last_ip_query(uint64_t *ip, const struct pt_last_ip *last_ip); + +/* Update last-ip. + * + * Updates @last_ip based on @packet and, if non-null, @config. + * + * Returns zero on success. + * Returns -pte_internal if @last_ip or @packet is NULL. + * Returns -pte_bad_packet if @packet appears to be corrupted. + */ +extern int pt_last_ip_update_ip(struct pt_last_ip *last_ip, + const struct pt_packet_ip *packet, + const struct pt_config *config); + +#endif /* PT_LAST_IP_H */ diff --git a/libipt/internal/include/pt_mapped_section.h b/libipt/internal/include/pt_mapped_section.h new file mode 100644 index 000000000000..322f928d1ae3 --- /dev/null +++ b/libipt/internal/include/pt_mapped_section.h @@ -0,0 +1,199 @@ +/* + * Copyright (c) 2014-2019, 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_MAPPED_SECTION_H +#define PT_MAPPED_SECTION_H + +#include "intel-pt.h" +#include "pt_section.h" + +#include <stdint.h> + + +/* A section mapped into memory. */ +struct pt_mapped_section { + /* The section that is mapped. */ + struct pt_section *section; + + /* The address space into which the section is mapped. */ + struct pt_asid asid; + + /* The virtual address at which the section is mapped. */ + uint64_t vaddr; + + /* The offset into the section. + * + * This is normally zero but when @section is split, @offset is added to + * the section/file offset when accessing @section. + */ + uint64_t offset; + + /* The size of the section. + * + * This is normally @section->size but when @section is split, this is + * used to determine the size of the sub-section. + */ + uint64_t size; +}; + + +static inline void pt_msec_init(struct pt_mapped_section *msec, + struct pt_section *section, + const struct pt_asid *asid, + uint64_t vaddr, uint64_t offset, uint64_t size) +{ + if (!msec) + return; + + msec->section = section; + msec->vaddr = vaddr; + msec->offset = offset; + msec->size = size; + + if (asid) + msec->asid = *asid; + else + pt_asid_init(&msec->asid); +} + +/* Destroy a mapped section - does not free @msec->section. */ +static inline void pt_msec_fini(struct pt_mapped_section *msec) +{ + (void) msec; + + /* Nothing to do. */ +} + +/* Return the virtual address of the beginning of the memory region. */ +static inline uint64_t pt_msec_begin(const struct pt_mapped_section *msec) +{ + if (!msec) + return 0ull; + + return msec->vaddr; +} + +/* Return the virtual address one byte past the end of the memory region. */ +static inline uint64_t pt_msec_end(const struct pt_mapped_section *msec) +{ + if (!msec) + return 0ull; + + return msec->vaddr + msec->size; +} + +/* Return the section/file offset. */ +static inline uint64_t pt_msec_offset(const struct pt_mapped_section *msec) +{ + if (!msec) + return 0ull; + + return msec->offset; +} + +/* Return the section size. */ +static inline uint64_t pt_msec_size(const struct pt_mapped_section *msec) +{ + if (!msec) + return 0ull; + + return msec->size; +} + +/* Return the underlying section. */ +static inline struct pt_section * +pt_msec_section(const struct pt_mapped_section *msec) +{ + return msec->section; +} + +/* Return an identifier for the address-space the section is mapped into. */ +static inline const struct pt_asid * +pt_msec_asid(const struct pt_mapped_section *msec) +{ + if (!msec) + return NULL; + + return &msec->asid; +} + +/* Translate a section/file offset into a virtual address. */ +static inline uint64_t pt_msec_map(const struct pt_mapped_section *msec, + uint64_t offset) +{ + return (offset - msec->offset) + msec->vaddr; +} + +/* Translate a virtual address into a section/file offset. */ +static inline uint64_t pt_msec_unmap(const struct pt_mapped_section *msec, + uint64_t vaddr) +{ + return (vaddr - msec->vaddr) + msec->offset; +} + +/* Read memory from a mapped section. + * + * The caller must check @msec->asid. + * The caller must ensure that @msec->section is mapped. + * + * Returns the number of bytes read on success. + * Returns a negative error code otherwise. + */ +static inline int pt_msec_read(const struct pt_mapped_section *msec, + uint8_t *buffer, uint16_t size, + uint64_t vaddr) +{ + struct pt_section *section; + uint64_t begin, end, mbegin, mend, offset; + + if (!msec) + return -pte_internal; + + begin = vaddr; + end = begin + size; + if (end < begin) + end = UINT64_MAX; + + mbegin = pt_msec_begin(msec); + mend = pt_msec_end(msec); + + if (begin < mbegin || mend <= begin) + return -pte_nomap; + + if (mend < end) + end = mend; + + size = (uint16_t) (end - begin); + + section = pt_msec_section(msec); + offset = pt_msec_unmap(msec, begin); + + return pt_section_read(section, buffer, size, offset); +} + +#endif /* PT_MAPPED_SECTION_H */ diff --git a/libipt/internal/include/pt_msec_cache.h b/libipt/internal/include/pt_msec_cache.h new file mode 100644 index 000000000000..6a52d09267d2 --- /dev/null +++ b/libipt/internal/include/pt_msec_cache.h @@ -0,0 +1,95 @@ +/* + * Copyright (c) 2017-2019, 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_MSEC_CACHE_H +#define PT_MSEC_CACHE_H + +#include "pt_mapped_section.h" + +#include "intel-pt.h" + + +/* A single-entry mapped section cache. + * + * The cached section is implicitly mapped and unmapped. The cache is not + * thread-safe. + */ +struct pt_msec_cache { + /* The cached section. + * + * The cache is valid if and only if @msec.section is not NULL. + * + * It needs to be unmapped and put. Use pt_blk_scache_invalidate() to + * release the cached section and to invalidate the cache. + */ + struct pt_mapped_section msec; + + /* The section identifier. */ + int isid; +}; + +/* Initialize the cache. */ +extern int pt_msec_cache_init(struct pt_msec_cache *cache); + +/* Finalize the cache. */ +extern void pt_msec_cache_fini(struct pt_msec_cache *cache); + +/* Invalidate the cache. */ +extern int pt_msec_cache_invalidate(struct pt_msec_cache *cache); + +/* Read the cached section. + * + * If @cache is not empty and @image would find it when looking up @vaddr in + * @*pmsec->asid, provide a pointer to the cached section in @pmsec and return + * its image section identifier. + * + * The provided pointer remains valid until @cache is invalidated. + * + * Returns @*pmsec's isid on success, a negative pt_error_code otherwise. + */ +extern int pt_msec_cache_read(struct pt_msec_cache *cache, + const struct pt_mapped_section **pmsec, + struct pt_image *image, uint64_t vaddr); + +/* Fill the cache. + * + * Look up @vaddr in @asid in @image and cache as well as provide the found + * section in @pmsec and return its image section identifier. + * + * Invalidates @cache. + * + * The provided pointer remains valid until @cache is invalidated. + * + * Returns @*pmsec's isid on success, a negative pt_error_code otherwise. + */ +extern int pt_msec_cache_fill(struct pt_msec_cache *cache, + const struct pt_mapped_section **pmsec, + struct pt_image *image, + const struct pt_asid *asid, uint64_t vaddr); + +#endif /* PT_MSEC_CACHE_H */ diff --git a/libipt/internal/include/pt_opcodes.h b/libipt/internal/include/pt_opcodes.h new file mode 100644 index 000000000000..945445ea735e --- /dev/null +++ b/libipt/internal/include/pt_opcodes.h @@ -0,0 +1,397 @@ +/* + * Copyright (c) 2013-2019, 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_OPCODES_H +#define PT_OPCODES_H + + +/* A one byte opcode. */ +enum pt_opcode { + pt_opc_pad = 0x00, + pt_opc_ext = 0x02, + pt_opc_psb = pt_opc_ext, + pt_opc_tip = 0x0d, + pt_opc_tnt_8 = 0x00, + pt_opc_tip_pge = 0x11, + pt_opc_tip_pgd = 0x01, + pt_opc_fup = 0x1d, + pt_opc_mode = 0x99, + pt_opc_tsc = 0x19, + pt_opc_mtc = 0x59, + pt_opc_cyc = 0x03, + + /* A free opcode to trigger a decode fault. */ + pt_opc_bad = 0xd9 +}; + +/* A one byte extension code for ext opcodes. */ +enum pt_ext_code { + pt_ext_psb = 0x82, + pt_ext_tnt_64 = 0xa3, + pt_ext_pip = 0x43, + pt_ext_ovf = 0xf3, + pt_ext_psbend = 0x23, + pt_ext_cbr = 0x03, + pt_ext_tma = 0x73, + pt_ext_stop = 0x83, + pt_ext_vmcs = 0xc8, + pt_ext_ext2 = 0xc3, + pt_ext_exstop = 0x62, + pt_ext_exstop_ip = 0xe2, + pt_ext_mwait = 0xc2, + pt_ext_pwre = 0x22, + pt_ext_pwrx = 0xa2, + pt_ext_ptw = 0x12, + + pt_ext_bad = 0x04 +}; + +/* A one byte extension 2 code for ext2 extension opcodes. */ +enum pt_ext2_code { + pt_ext2_mnt = 0x88, + + pt_ext2_bad = 0x00 +}; + +/* A one byte opcode mask. */ +enum pt_opcode_mask { + pt_opm_tip = 0x1f, + pt_opm_tnt_8 = 0x01, + pt_opm_tnt_8_shr = 1, + pt_opm_fup = pt_opm_tip, + + /* The bit mask for the compression bits in the opcode. */ + pt_opm_ipc = 0xe0, + + /* The shift right value for ipc bits. */ + pt_opm_ipc_shr = 5, + + /* The bit mask for the compression bits after shifting. */ + pt_opm_ipc_shr_mask = 0x7, + + /* Shift counts and masks for decoding the cyc packet. */ + pt_opm_cyc = 0x03, + pt_opm_cyc_ext = 0x04, + pt_opm_cyc_bits = 0xf8, + pt_opm_cyc_shr = 3, + pt_opm_cycx_ext = 0x01, + pt_opm_cycx_shr = 1, + + /* The bit mask for the IP bit in the exstop packet. */ + pt_opm_exstop_ip = 0x80, + + /* The PTW opcode. */ + pt_opm_ptw = 0x1f, + + /* The bit mask for the IP bit in the ptw packet. */ + pt_opm_ptw_ip = 0x80, + + /* The bit mask and shr value for the payload bytes field in ptw. */ + pt_opm_ptw_pb = 0x60, + pt_opm_ptw_pb_shr = 5, + + /* The bit mask for the payload bytes field in ptw after shifting. */ + pt_opm_ptw_pb_shr_mask = 0x3 +}; + +/* The size of the various opcodes in bytes. */ +enum pt_opcode_size { + pt_opcs_pad = 1, + pt_opcs_tip = 1, + pt_opcs_tip_pge = 1, + pt_opcs_tip_pgd = 1, + pt_opcs_fup = 1, + pt_opcs_tnt_8 = 1, + pt_opcs_mode = 1, + pt_opcs_tsc = 1, + pt_opcs_mtc = 1, + pt_opcs_cyc = 1, + pt_opcs_psb = 2, + pt_opcs_psbend = 2, + pt_opcs_ovf = 2, + pt_opcs_pip = 2, + pt_opcs_tnt_64 = 2, + pt_opcs_cbr = 2, + pt_opcs_tma = 2, + pt_opcs_stop = 2, + pt_opcs_vmcs = 2, + pt_opcs_mnt = 3, + pt_opcs_exstop = 2, + pt_opcs_mwait = 2, + pt_opcs_pwre = 2, + pt_opcs_pwrx = 2, + pt_opcs_ptw = 2 +}; + +/* The psb magic payload. + * + * The payload is a repeating 2-byte pattern. + */ +enum pt_psb_pattern { + /* The high and low bytes in the pattern. */ + pt_psb_hi = pt_opc_psb, + pt_psb_lo = pt_ext_psb, + + /* Various combinations of the above parts. */ + pt_psb_lohi = pt_psb_lo | pt_psb_hi << 8, + pt_psb_hilo = pt_psb_hi | pt_psb_lo << 8, + + /* The repeat count of the payload, not including opc and ext. */ + pt_psb_repeat_count = 7, + + /* The size of the repeated pattern in bytes. */ + pt_psb_repeat_size = 2 +}; + +/* The payload details. */ +enum pt_payload { + /* The shift counts for post-processing the PIP payload. */ + pt_pl_pip_shr = 1, + pt_pl_pip_shl = 5, + + /* The size of a PIP payload in bytes. */ + pt_pl_pip_size = 6, + + /* The non-root bit in the first byte of the PIP payload. */ + pt_pl_pip_nr = 0x01, + + /* The size of a 8bit TNT packet's payload in bits. */ + pt_pl_tnt_8_bits = 8 - pt_opm_tnt_8_shr, + + /* The size of a 64bit TNT packet's payload in bytes. */ + pt_pl_tnt_64_size = 6, + + /* The size of a 64bit TNT packet's payload in bits. */ + pt_pl_tnt_64_bits = 48, + + /* The size of a TSC packet's payload in bytes and in bits. */ + pt_pl_tsc_size = 7, + pt_pl_tsc_bit_size = pt_pl_tsc_size * 8, + + /* The size of a CBR packet's payload in bytes. */ + pt_pl_cbr_size = 2, + + /* The size of a PSB packet's payload in bytes. */ + pt_pl_psb_size = pt_psb_repeat_count * pt_psb_repeat_size, + + /* The size of a MODE packet's payload in bytes. */ + pt_pl_mode_size = 1, + + /* The size of an IP packet's payload with update-16 compression. */ + pt_pl_ip_upd16_size = 2, + + /* The size of an IP packet's payload with update-32 compression. */ + pt_pl_ip_upd32_size = 4, + + /* The size of an IP packet's payload with update-48 compression. */ + pt_pl_ip_upd48_size = 6, + + /* The size of an IP packet's payload with sext-48 compression. */ + pt_pl_ip_sext48_size = 6, + + /* The size of an IP packet's payload with full-ip compression. */ + pt_pl_ip_full_size = 8, + + /* Byte locations, sizes, and masks for processing TMA packets. */ + pt_pl_tma_size = 5, + pt_pl_tma_ctc_size = 2, + pt_pl_tma_ctc_bit_size = pt_pl_tma_ctc_size * 8, + pt_pl_tma_ctc_0 = 2, + pt_pl_tma_ctc_1 = 3, + pt_pl_tma_ctc_mask = (1 << pt_pl_tma_ctc_bit_size) - 1, + pt_pl_tma_fc_size = 2, + pt_pl_tma_fc_bit_size = 9, + pt_pl_tma_fc_0 = 5, + pt_pl_tma_fc_1 = 6, + pt_pl_tma_fc_mask = (1 << pt_pl_tma_fc_bit_size) - 1, + + /* The size of a MTC packet's payload in bytes and in bits. */ + pt_pl_mtc_size = 1, + pt_pl_mtc_bit_size = pt_pl_mtc_size * 8, + + /* A mask for the MTC payload bits. */ + pt_pl_mtc_mask = (1 << pt_pl_mtc_bit_size) - 1, + + /* The maximal payload size in bytes of a CYC packet. */ + pt_pl_cyc_max_size = 15, + + /* The size of a VMCS packet's payload in bytes. */ + pt_pl_vmcs_size = 5, + + /* The shift counts for post-processing the VMCS payload. */ + pt_pl_vmcs_shl = 12, + + /* The size of a MNT packet's payload in bytes. */ + pt_pl_mnt_size = 8, + + /* The bit-mask for the IP bit in the EXSTOP opcode extension. */ + pt_pl_exstop_ip_mask = 0x80, + + /* The size of the hints field in the MWAIT payload in bytes. */ + pt_pl_mwait_hints_size = 4, + + /* The size of the extensions field in the MWAIT payload in bytes. */ + pt_pl_mwait_ext_size = 4, + + /* The size of the MWAIT payload in bytes. */ + pt_pl_mwait_size = pt_pl_mwait_hints_size + pt_pl_mwait_ext_size, + + /* The size of the PWRE payload in bytes. */ + pt_pl_pwre_size = 2, + + /* The bit-mask for the h/w bit in the PWRE payload. */ + pt_pl_pwre_hw_mask = 0x8, + + /* The bit-mask for the resolved thread sub C-state in the PWRE + * payload. + */ + pt_pl_pwre_sub_state_mask = 0xf00, + + /* The shift right value for the resolved thread sub C-state in the + * PWRE payload. + */ + pt_pl_pwre_sub_state_shr = 8, + + /* The bit-mask for the resolved thread C-state in the PWRE payload. */ + pt_pl_pwre_state_mask = 0xf000, + + /* The shift right value for the resolved thread C-state in the + * PWRE payload. + */ + pt_pl_pwre_state_shr = 12, + + /* The size of the PWRX payload in bytes. */ + pt_pl_pwrx_size = 5, + + /* The bit-mask for the deepest core C-state in the PWRX payload. */ + pt_pl_pwrx_deepest_mask = 0xf, + + /* The shift right value for the deepest core C-state in the PWRX + * payload. + */ + pt_pl_pwrx_deepest_shr = 0, + + /* The bit-mask for the last core C-state in the PWRX payload. */ + pt_pl_pwrx_last_mask = 0xf0, + + /* The shift right value for the last core C-state in the PWRX + * payload. + */ + pt_pl_pwrx_last_shr = 4, + + /* The bit-mask for the wake reason in the PWRX payload. */ + pt_pl_pwrx_wr_mask = 0xf00, + + /* The shift right value for the wake reason in the PWRX payload. */ + pt_pl_pwrx_wr_shr = 8, + + /* The bit-mask for the interrupt wake reason in the PWRX payload. */ + pt_pl_pwrx_wr_int = 0x100, + + /* The bit-mask for the store wake reason in the PWRX payload. */ + pt_pl_pwrx_wr_store = 0x400, + + /* The bit-mask for the autonomous wake reason in the PWRX payload. */ + pt_pl_pwrx_wr_hw = 0x800 +}; + +/* Mode packet masks. */ +enum pt_mode_mask { + pt_mom_leaf = 0xe0, + pt_mom_leaf_shr = 5, + pt_mom_bits = 0x1f +}; + +/* Mode packet bits. */ +enum pt_mode_bit { + /* mode.exec */ + pt_mob_exec_csl = 0x01, + pt_mob_exec_csd = 0x02, + + /* mode.tsx */ + pt_mob_tsx_intx = 0x01, + pt_mob_tsx_abrt = 0x02 +}; + +/* The size of the various packets in bytes. */ +enum pt_packet_size { + ptps_pad = pt_opcs_pad, + ptps_tnt_8 = pt_opcs_tnt_8, + ptps_mode = pt_opcs_mode + pt_pl_mode_size, + ptps_tsc = pt_opcs_tsc + pt_pl_tsc_size, + ptps_mtc = pt_opcs_mtc + pt_pl_mtc_size, + ptps_psb = pt_opcs_psb + pt_pl_psb_size, + ptps_psbend = pt_opcs_psbend, + ptps_ovf = pt_opcs_ovf, + ptps_pip = pt_opcs_pip + pt_pl_pip_size, + ptps_tnt_64 = pt_opcs_tnt_64 + pt_pl_tnt_64_size, + ptps_cbr = pt_opcs_cbr + pt_pl_cbr_size, + ptps_tip_supp = pt_opcs_tip, + ptps_tip_upd16 = pt_opcs_tip + pt_pl_ip_upd16_size, + ptps_tip_upd32 = pt_opcs_tip + pt_pl_ip_upd32_size, + ptps_tip_upd48 = pt_opcs_tip + pt_pl_ip_upd48_size, + ptps_tip_sext48 = pt_opcs_tip + pt_pl_ip_sext48_size, + ptps_tip_full = pt_opcs_tip + pt_pl_ip_full_size, + ptps_tip_pge_supp = pt_opcs_tip_pge, + ptps_tip_pge_upd16 = pt_opcs_tip_pge + pt_pl_ip_upd16_size, + ptps_tip_pge_upd32 = pt_opcs_tip_pge + pt_pl_ip_upd32_size, + ptps_tip_pge_upd48 = pt_opcs_tip_pge + pt_pl_ip_upd48_size, + ptps_tip_pge_sext48 = pt_opcs_tip_pge + pt_pl_ip_sext48_size, + ptps_tip_pge_full = pt_opcs_tip_pge + pt_pl_ip_full_size, + ptps_tip_pgd_supp = pt_opcs_tip_pgd, + ptps_tip_pgd_upd16 = pt_opcs_tip_pgd + pt_pl_ip_upd16_size, + ptps_tip_pgd_upd32 = pt_opcs_tip_pgd + pt_pl_ip_upd32_size, + ptps_tip_pgd_upd48 = pt_opcs_tip_pgd + pt_pl_ip_upd48_size, + ptps_tip_pgd_sext48 = pt_opcs_tip_pgd + pt_pl_ip_sext48_size, + ptps_tip_pgd_full = pt_opcs_tip_pgd + pt_pl_ip_full_size, + ptps_fup_supp = pt_opcs_fup, + ptps_fup_upd16 = pt_opcs_fup + pt_pl_ip_upd16_size, + ptps_fup_upd32 = pt_opcs_fup + pt_pl_ip_upd32_size, + ptps_fup_upd48 = pt_opcs_fup + pt_pl_ip_upd48_size, + ptps_fup_sext48 = pt_opcs_fup + pt_pl_ip_sext48_size, + ptps_fup_full = pt_opcs_fup + pt_pl_ip_full_size, + ptps_tma = pt_opcs_tma + pt_pl_tma_size, + ptps_stop = pt_opcs_stop, + ptps_vmcs = pt_opcs_vmcs + pt_pl_vmcs_size, + ptps_mnt = pt_opcs_mnt + pt_pl_mnt_size, + ptps_exstop = pt_opcs_exstop, + ptps_mwait = pt_opcs_mwait + pt_pl_mwait_size, + ptps_pwre = pt_opcs_pwre + pt_pl_pwre_size, + ptps_pwrx = pt_opcs_pwrx + pt_pl_pwrx_size, + ptps_ptw_32 = pt_opcs_ptw + 4, + ptps_ptw_64 = pt_opcs_ptw + 8 +}; + +/* Supported address range configurations. */ +enum pt_addr_cfg { + pt_addr_cfg_disabled = 0, + pt_addr_cfg_filter = 1, + pt_addr_cfg_stop = 2 +}; + +#endif /* PT_OPCODES_H */ diff --git a/libipt/internal/include/pt_packet.h b/libipt/internal/include/pt_packet.h new file mode 100644 index 000000000000..ae1357ff29cb --- /dev/null +++ b/libipt/internal/include/pt_packet.h @@ -0,0 +1,111 @@ +/* + * Copyright (c) 2014-2019, 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_PACKET_H +#define PT_PACKET_H + +#include <stdint.h> + +struct pt_config; +struct pt_packet; +struct pt_packet_ip; +struct pt_packet_tnt; +struct pt_packet_pip; +struct pt_packet_mode; +struct pt_packet_tsc; +struct pt_packet_cbr; +struct pt_packet_tma; +struct pt_packet_mtc; +struct pt_packet_cyc; +struct pt_packet_vmcs; +struct pt_packet_mnt; +struct pt_packet_exstop; +struct pt_packet_mwait; +struct pt_packet_pwre; +struct pt_packet_pwrx; +struct pt_packet_ptw; + + +/* Read the payload of an Intel PT packet. + * + * Reads the payload of the packet starting at @pos into @packet. + * + * For pt_pkt_read_psb(), the @packet parameter is omitted; the function + * validates that the payload matches the expected PSB pattern. + * + * Decoding an unknown packet uses @config's decode callback. If the callback + * is NULL, pt_pkt_read_unknown() returns -pte_bad_opc. + * + * Beware that the packet opcode is not checked. The caller is responsible + * for checking the opcode and calling the correct packet read function. + * + * Returns the packet size on success, a negative error code otherwise. + * Returns -pte_bad_packet if the packet payload is corrupt. + * Returns -pte_eos if the packet does not fit into the trace buffer. + * Returns -pte_internal if @packet, @pos, or @config is NULL. + */ +extern int pt_pkt_read_unknown(struct pt_packet *packet, const uint8_t *pos, + const struct pt_config *config); +extern int pt_pkt_read_psb(const uint8_t *pos, const struct pt_config *config); +extern int pt_pkt_read_ip(struct pt_packet_ip *packet, const uint8_t *pos, + const struct pt_config *config); +extern int pt_pkt_read_tnt_8(struct pt_packet_tnt *packet, const uint8_t *pos, + const struct pt_config *config); +extern int pt_pkt_read_tnt_64(struct pt_packet_tnt *packet, const uint8_t *pos, + const struct pt_config *config); +extern int pt_pkt_read_pip(struct pt_packet_pip *packet, const uint8_t *pos, + const struct pt_config *config); +extern int pt_pkt_read_mode(struct pt_packet_mode *packet, const uint8_t *pos, + const struct pt_config *config); +extern int pt_pkt_read_tsc(struct pt_packet_tsc *packet, const uint8_t *pos, + const struct pt_config *config); +extern int pt_pkt_read_cbr(struct pt_packet_cbr *packet, const uint8_t *pos, + const struct pt_config *config); +extern int pt_pkt_read_tma(struct pt_packet_tma *packet, const uint8_t *pos, + const struct pt_config *config); +extern int pt_pkt_read_mtc(struct pt_packet_mtc *packet, const uint8_t *pos, + const struct pt_config *config); +extern int pt_pkt_read_cyc(struct pt_packet_cyc *packet, const uint8_t *pos, + const struct pt_config *config); +extern int pt_pkt_read_vmcs(struct pt_packet_vmcs *packet, const uint8_t *pos, + const struct pt_config *config); +extern int pt_pkt_read_mnt(struct pt_packet_mnt *packet, const uint8_t *pos, + const struct pt_config *config); +extern int pt_pkt_read_exstop(struct pt_packet_exstop *packet, + const uint8_t *pos, + const struct pt_config *config); +extern int pt_pkt_read_mwait(struct pt_packet_mwait *packet, const uint8_t *pos, + const struct pt_config *config); +extern int pt_pkt_read_pwre(struct pt_packet_pwre *packet, const uint8_t *pos, + const struct pt_config *config); +extern int pt_pkt_read_pwrx(struct pt_packet_pwrx *packet, const uint8_t *pos, + const struct pt_config *config); +extern int pt_pkt_read_ptw(struct pt_packet_ptw *packet, const uint8_t *pos, + const struct pt_config *config); + +#endif /* PT_PACKET_H */ diff --git a/libipt/internal/include/pt_packet_decoder.h b/libipt/internal/include/pt_packet_decoder.h new file mode 100644 index 000000000000..0ea30db13386 --- /dev/null +++ b/libipt/internal/include/pt_packet_decoder.h @@ -0,0 +1,92 @@ +/* + * Copyright (c) 2014-2019, 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_PACKET_DECODER_H +#define PT_PACKET_DECODER_H + +#include "intel-pt.h" + + +/* An Intel PT packet decoder. */ +struct pt_packet_decoder { + /* The decoder configuration. */ + struct pt_config config; + + /* The current position in the trace buffer. */ + const uint8_t *pos; + + /* The position of the last PSB packet. */ + const uint8_t *sync; +}; + + +/* Initialize the packet decoder. + * + * Returns zero on success, a negative error code otherwise. + */ +extern int pt_pkt_decoder_init(struct pt_packet_decoder *, + const struct pt_config *); + +/* Finalize the packet decoder. */ +extern void pt_pkt_decoder_fini(struct pt_packet_decoder *); + + +/* Decoder functions for the packet decoder. */ +extern int pt_pkt_decode_unknown(struct pt_packet_decoder *, + struct pt_packet *); +extern int pt_pkt_decode_pad(struct pt_packet_decoder *, struct pt_packet *); +extern int pt_pkt_decode_psb(struct pt_packet_decoder *, struct pt_packet *); +extern int pt_pkt_decode_tip(struct pt_packet_decoder *, struct pt_packet *); +extern int pt_pkt_decode_tnt_8(struct pt_packet_decoder *, struct pt_packet *); +extern int pt_pkt_decode_tnt_64(struct pt_packet_decoder *, + struct pt_packet *); +extern int pt_pkt_decode_tip_pge(struct pt_packet_decoder *, + struct pt_packet *); +extern int pt_pkt_decode_tip_pgd(struct pt_packet_decoder *, + struct pt_packet *); +extern int pt_pkt_decode_fup(struct pt_packet_decoder *, struct pt_packet *); +extern int pt_pkt_decode_pip(struct pt_packet_decoder *, struct pt_packet *); +extern int pt_pkt_decode_ovf(struct pt_packet_decoder *, struct pt_packet *); +extern int pt_pkt_decode_mode(struct pt_packet_decoder *, struct pt_packet *); +extern int pt_pkt_decode_psbend(struct pt_packet_decoder *, + struct pt_packet *); +extern int pt_pkt_decode_tsc(struct pt_packet_decoder *, struct pt_packet *); +extern int pt_pkt_decode_cbr(struct pt_packet_decoder *, struct pt_packet *); +extern int pt_pkt_decode_tma(struct pt_packet_decoder *, struct pt_packet *); +extern int pt_pkt_decode_mtc(struct pt_packet_decoder *, struct pt_packet *); +extern int pt_pkt_decode_cyc(struct pt_packet_decoder *, struct pt_packet *); +extern int pt_pkt_decode_stop(struct pt_packet_decoder *, struct pt_packet *); +extern int pt_pkt_decode_vmcs(struct pt_packet_decoder *, struct pt_packet *); +extern int pt_pkt_decode_mnt(struct pt_packet_decoder *, struct pt_packet *); +extern int pt_pkt_decode_exstop(struct pt_packet_decoder *, struct pt_packet *); +extern int pt_pkt_decode_mwait(struct pt_packet_decoder *, struct pt_packet *); +extern int pt_pkt_decode_pwre(struct pt_packet_decoder *, struct pt_packet *); +extern int pt_pkt_decode_pwrx(struct pt_packet_decoder *, struct pt_packet *); +extern int pt_pkt_decode_ptw(struct pt_packet_decoder *, struct pt_packet *); + +#endif /* PT_PACKET_DECODER_H */ diff --git a/libipt/internal/include/pt_query_decoder.h b/libipt/internal/include/pt_query_decoder.h new file mode 100644 index 000000000000..40194ec766dc --- /dev/null +++ b/libipt/internal/include/pt_query_decoder.h @@ -0,0 +1,134 @@ +/* + * Copyright (c) 2014-2019, 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_QUERY_DECODER_H +#define PT_QUERY_DECODER_H + +#include "pt_last_ip.h" +#include "pt_tnt_cache.h" +#include "pt_time.h" +#include "pt_event_queue.h" + +#include "intel-pt.h" + +struct pt_decoder_function; + + +/* An Intel PT query decoder. */ +struct pt_query_decoder { + /* The decoder configuration. */ + struct pt_config config; + + /* The current position in the trace buffer. */ + const uint8_t *pos; + + /* The position of the last PSB packet. */ + const uint8_t *sync; + + /* The decoding function for the next packet. */ + const struct pt_decoder_function *next; + + /* The last-ip. */ + struct pt_last_ip ip; + + /* The cached tnt indicators. */ + struct pt_tnt_cache tnt; + + /* Timing information. */ + struct pt_time time; + + /* The time at the last query (before reading ahead). */ + struct pt_time last_time; + + /* Timing calibration. */ + struct pt_time_cal tcal; + + /* Pending (incomplete) events. */ + struct pt_event_queue evq; + + /* The current event. */ + struct pt_event *event; + + /* A collection of flags relevant for decoding: + * + * - tracing is enabled. + */ + uint32_t enabled:1; + + /* - consume the current packet. */ + uint32_t consume_packet:1; +}; + +/* Initialize the query decoder. + * + * Returns zero on success, a negative error code otherwise. + */ +extern int pt_qry_decoder_init(struct pt_query_decoder *, + const struct pt_config *); + +/* Finalize the query decoder. */ +extern void pt_qry_decoder_fini(struct pt_query_decoder *); + +/* Decoder functions (tracing context). */ +extern int pt_qry_decode_unknown(struct pt_query_decoder *); +extern int pt_qry_decode_pad(struct pt_query_decoder *); +extern int pt_qry_decode_psb(struct pt_query_decoder *); +extern int pt_qry_decode_tip(struct pt_query_decoder *); +extern int pt_qry_decode_tnt_8(struct pt_query_decoder *); +extern int pt_qry_decode_tnt_64(struct pt_query_decoder *); +extern int pt_qry_decode_tip_pge(struct pt_query_decoder *); +extern int pt_qry_decode_tip_pgd(struct pt_query_decoder *); +extern int pt_qry_decode_fup(struct pt_query_decoder *); +extern int pt_qry_decode_pip(struct pt_query_decoder *); +extern int pt_qry_decode_ovf(struct pt_query_decoder *); +extern int pt_qry_decode_mode(struct pt_query_decoder *); +extern int pt_qry_decode_psbend(struct pt_query_decoder *); +extern int pt_qry_decode_tsc(struct pt_query_decoder *); +extern int pt_qry_header_tsc(struct pt_query_decoder *); +extern int pt_qry_decode_cbr(struct pt_query_decoder *); +extern int pt_qry_header_cbr(struct pt_query_decoder *); +extern int pt_qry_decode_tma(struct pt_query_decoder *); +extern int pt_qry_decode_mtc(struct pt_query_decoder *); +extern int pt_qry_decode_cyc(struct pt_query_decoder *); +extern int pt_qry_decode_stop(struct pt_query_decoder *); +extern int pt_qry_decode_vmcs(struct pt_query_decoder *); +extern int pt_qry_decode_mnt(struct pt_query_decoder *); +extern int pt_qry_decode_exstop(struct pt_query_decoder *); +extern int pt_qry_decode_mwait(struct pt_query_decoder *); +extern int pt_qry_decode_pwre(struct pt_query_decoder *); +extern int pt_qry_decode_pwrx(struct pt_query_decoder *); +extern int pt_qry_decode_ptw(struct pt_query_decoder *); + +/* Decoder functions (header context). */ +extern int pt_qry_header_fup(struct pt_query_decoder *); +extern int pt_qry_header_pip(struct pt_query_decoder *); +extern int pt_qry_header_mode(struct pt_query_decoder *); +extern int pt_qry_header_vmcs(struct pt_query_decoder *); +extern int pt_qry_header_mnt(struct pt_query_decoder *); + +#endif /* PT_QUERY_DECODER_H */ diff --git a/libipt/internal/include/pt_retstack.h b/libipt/internal/include/pt_retstack.h new file mode 100644 index 000000000000..e619ee602b2c --- /dev/null +++ b/libipt/internal/include/pt_retstack.h @@ -0,0 +1,87 @@ +/* + * Copyright (c) 2013-2019, 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_RETSTACK_H +#define PT_RETSTACK_H + +#include <stdint.h> + + +/* The size of the call/return stack in number of entries. */ +enum { + pt_retstack_size = 64 +}; + +/* A stack of return addresses used for return compression. */ +struct pt_retstack { + /* The stack of return addresses. + * + * We use one additional entry in order to distinguish a full from + * an empty stack. + */ + uint64_t stack[pt_retstack_size + 1]; + + /* The top of the stack. */ + uint8_t top; + + /* The bottom of the stack. */ + uint8_t bottom; +}; + +/* Initialize (or reset) a call/return stack. */ +extern void pt_retstack_init(struct pt_retstack *); + +/* Test a call/return stack for emptiness. + * + * Returns zero if @retstack contains at least one element. + * Returns a positive integer if @retstack is empty. + * Returns -pte_invalid if @retstack is NULL. + */ +extern int pt_retstack_is_empty(const struct pt_retstack *retstack); + +/* Pop and return the topmost IP. + * + * If @ip is not NULL, provides the topmost return address on success. + * If @retstack is not empty, pops the topmost return address on success. + * + * Returns zero on success. + * Returns -pte_invalid if @retstack is NULL. + * Returns -pte_noip if @retstack is empty. + */ +extern int pt_retstack_pop(struct pt_retstack *retstack, uint64_t *ip); + +/* Push a return address onto the stack. + * + * Pushes @ip onto @retstack. + * If @retstack is full, drops the oldest return address. + * + * Returns zero on success. + */ +extern int pt_retstack_push(struct pt_retstack *retstack, uint64_t ip); + +#endif /* PT_RETSTACK_H */ diff --git a/libipt/internal/include/pt_section.h b/libipt/internal/include/pt_section.h new file mode 100644 index 000000000000..f0a80c5e5b0a --- /dev/null +++ b/libipt/internal/include/pt_section.h @@ -0,0 +1,397 @@ +/* + * Copyright (c) 2013-2019, 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_SECTION_H +#define PT_SECTION_H + +#include <stdint.h> +#include <stddef.h> + +#if defined(FEATURE_THREADS) +# include <threads.h> +#endif /* defined(FEATURE_THREADS) */ + +#include "intel-pt.h" + +struct pt_block_cache; + + +/* A section of contiguous memory loaded from a file. */ +struct pt_section { + /* The name of the file. */ + char *filename; + + /* The offset into the file. */ + uint64_t offset; + + /* The (adjusted) size in bytes. The size is truncated to match the + * actual file size. + */ + uint64_t size; + + /* A pointer to OS-specific file status for detecting changes. + * + * The status is initialized on first pt_section_map() and will be + * left in the section until the section is destroyed. This field + * is owned by the OS-specific mmap-based section implementation. + */ + void *status; + + /* A pointer to implementation-specific mapping information - NULL if + * the section is currently not mapped. + * + * This field is set in pt_section_map() and owned by the mapping + * implementation. + */ + void *mapping; + + /* A pointer to an optional block cache. + * + * The cache is created on request and destroyed implicitly when the + * section is unmapped. + * + * We read this field without locking and only lock the section in order + * to install the block cache. + * + * We rely on guaranteed atomic operations as specified in section 8.1.1 + * in Volume 3A of the Intel(R) Software Developer's Manual at + * http://www.intel.com/sdm. + */ + struct pt_block_cache *bcache; + + /* A pointer to the iscache attached to this section. + * + * The pointer is initialized when the iscache attaches and cleared when + * it detaches again. There can be at most one iscache attached to this + * section at any time. + * + * In addition to attaching, the iscache will need to obtain a reference + * to the section, which it needs to drop again after detaching. + */ + struct pt_image_section_cache *iscache; + + /* A pointer to the unmap function - NULL if the section is currently + * not mapped. + * + * This field is set in pt_section_map() and owned by the mapping + * implementation. + */ + int (*unmap)(struct pt_section *sec); + + /* A pointer to the read function - NULL if the section is currently + * not mapped. + * + * This field is set in pt_section_map() and owned by the mapping + * implementation. + */ + int (*read)(const struct pt_section *sec, uint8_t *buffer, + uint16_t size, uint64_t offset); + + /* A pointer to the memsize function - NULL if the section is currently + * not mapped. + * + * This field is set in pt_section_map() and owned by the mapping + * implementation. + */ + int (*memsize)(const struct pt_section *section, uint64_t *size); + +#if defined(FEATURE_THREADS) + /* A lock protecting this section. + * + * Most operations do not require the section to be locked. All + * actual locking should be handled by pt_section_* functions. + */ + mtx_t lock; + + /* A lock protecting the @iscache and @acount fields. + * + * We need separate locks to protect against a deadlock scenario when + * the iscache is mapping or unmapping this section. + * + * The attach lock must not be taken while holding the section lock; the + * other way round is OK. + */ + mtx_t alock; +#endif /* defined(FEATURE_THREADS) */ + + /* The number of current users. The last user destroys the section. */ + uint16_t ucount; + + /* The number of attaches. This must be <= @ucount. */ + uint16_t acount; + + /* The number of current mappers. The last unmaps the section. */ + uint16_t mcount; +}; + +/* Create a section. + * + * The returned section describes the contents of @file starting at @offset + * for @size bytes. + * + * If @file is shorter than the requested @size, the section is silently + * truncated to the size of @file. + * + * If @offset lies beyond the end of @file, no section is created. + * + * The returned section is not mapped and starts with a user count of one and + * instruction caching enabled. + * + * Returns zero on success, a negative pt_error_code otherwise. + * Returns -pte_internal if @psection is NULL. + * Returns -pte_nomem when running out of memory. + * Returns -pte_bad_file if @filename cannot be opened. + * Returns -pte_invalid if @offset lies beyond @file. + * Returns -pte_invalid if @filename is too long. + */ +extern int pt_mk_section(struct pt_section **psection, const char *filename, + uint64_t offset, uint64_t size); + +/* Lock a section. + * + * Locks @section. The section must not be locked. + * + * Returns a new section on success, NULL otherwise. + * Returns -pte_bad_lock on any locking error. + */ +extern int pt_section_lock(struct pt_section *section); + +/* Unlock a section. + * + * Unlocks @section. The section must be locked. + * + * Returns a new section on success, NULL otherwise. + * Returns -pte_bad_lock on any locking error. + */ +extern int pt_section_unlock(struct pt_section *section); + +/* Add another user. + * + * Increments the user count of @section. + * + * Returns zero on success, a negative error code otherwise. + * Returns -pte_internal if @section is NULL. + * Returns -pte_overflow if the user count would overflow. + * Returns -pte_bad_lock on any locking error. + */ +extern int pt_section_get(struct pt_section *section); + +/* Remove a user. + * + * Decrements the user count of @section. Destroys the section if the + * count reaches zero. + * + * Returns zero on success, a negative error code otherwise. + * Returns -pte_internal if @section is NULL. + * Returns -pte_internal if the user count is already zero. + * Returns -pte_bad_lock on any locking error. + */ +extern int pt_section_put(struct pt_section *section); + +/* Attaches the image section cache user. + * + * Similar to pt_section_get() but sets @section->iscache to @iscache. + * + * Returns zero on success, a negative error code otherwise. + * Returns -pte_internal if @section or @iscache is NULL. + * Returns -pte_internal if a different cache is already attached. + * Returns -pte_overflow if the attach count would overflow. + * Returns -pte_bad_lock on any locking error. + */ +extern int pt_section_attach(struct pt_section *section, + struct pt_image_section_cache *iscache); + +/* Detaches the image section cache user. + * + * Similar to pt_section_put() but clears @section->iscache. + * + * Returns zero on success, a negative error code otherwise. + * Returns -pte_internal if @section or @iscache is NULL. + * Returns -pte_internal if the attach count is already zero. + * Returns -pte_internal if @section->iscache is not equal to @iscache. + * Returns -pte_bad_lock on any locking error. + */ +extern int pt_section_detach(struct pt_section *section, + struct pt_image_section_cache *iscache); + +/* Return the filename of @section. */ +extern const char *pt_section_filename(const struct pt_section *section); + +/* Return the offset of the section in bytes. */ +extern uint64_t pt_section_offset(const struct pt_section *section); + +/* Return the size of the section in bytes. */ +extern uint64_t pt_section_size(const struct pt_section *section); + +/* Return the amount of memory currently used by the section in bytes. + * + * We only consider the amount of memory required for mapping @section; we + * ignore the size of the section object itself and the size of the status + * object. + * + * If @section is currently not mapped, the size is zero. + * + * Returns zero on success, a negative pt_error_code otherwise. + * Returns -pte_internal if @size of @section is NULL. + */ +extern int pt_section_memsize(struct pt_section *section, uint64_t *size); + +/* Allocate a block cache. + * + * Returns zero on success, a negative error code otherwise. + * Returns -pte_internal if @section is NULL. + * Returns -pte_nomem if the block cache can't be allocated. + * Returns -pte_bad_lock on any locking error. + */ +extern int pt_section_alloc_bcache(struct pt_section *section); + +/* Request block caching. + * + * The caller must ensure that @section is mapped. + */ +static inline int pt_section_request_bcache(struct pt_section *section) +{ + if (!section) + return -pte_internal; + + if (section->bcache) + return 0; + + return pt_section_alloc_bcache(section); +} + +/* Return @section's block cache, if available. + * + * The caller must ensure that @section is mapped. + * + * The cache is not use-counted. It is only valid as long as the caller keeps + * @section mapped. + */ +static inline struct pt_block_cache * +pt_section_bcache(const struct pt_section *section) +{ + if (!section) + return NULL; + + return section->bcache; +} + +/* Create the OS-specific file status. + * + * On success, allocates a status object, provides a pointer to it in @pstatus + * and provides the file size in @psize. + * + * The status object will be free()'ed when its section is. + * + * This function is implemented in the OS-specific section implementation. + * + * Returns zero on success, a negative error code otherwise. + * Returns -pte_internal if @pstatus, @psize, or @filename is NULL. + * Returns -pte_bad_image if @filename can't be opened. + * Returns -pte_nomem if the status object can't be allocated. + */ +extern int pt_section_mk_status(void **pstatus, uint64_t *psize, + const char *filename); + +/* Perform on-map maintenance work. + * + * Notifies an attached image section cache about the mapping of @section. + * + * This function is called by the OS-specific pt_section_map() implementation + * after @section has been successfully mapped and @section has been unlocked. + * + * Returns zero on success, a negative error code otherwise. + * Returns -pte_internal if @section is NULL. + * Returns -pte_bad_lock on any locking error. + */ +extern int pt_section_on_map_lock(struct pt_section *section); + +static inline int pt_section_on_map(struct pt_section *section) +{ + if (section && !section->iscache) + return 0; + + return pt_section_on_map_lock(section); +} + +/* Map a section. + * + * Maps @section into memory. Mappings are use-counted. The number of + * pt_section_map() calls must match the number of pt_section_unmap() + * calls. + * + * This function is implemented in the OS-specific section implementation. + * + * Returns zero on success, a negative error code otherwise. + * Returns -pte_internal if @section is NULL. + * Returns -pte_bad_image if @section changed or can't be opened. + * Returns -pte_bad_lock on any locking error. + * Returns -pte_nomem if @section can't be mapped into memory. + * Returns -pte_overflow if the map count would overflow. + */ +extern int pt_section_map(struct pt_section *section); + +/* Share a section mapping. + * + * Increases the map count for @section without notifying an attached image + * section cache. + * + * This function should only be used by the attached image section cache to + * resolve a deadlock scenario when mapping a section it intends to cache. + * + * Returns zero on success, a negative error code otherwise. + * Returns -pte_internal if @section is NULL. + * Returns -pte_internal if @section->mcount is zero. + * Returns -pte_bad_lock on any locking error. + */ +extern int pt_section_map_share(struct pt_section *section); + +/* Unmap a section. + * + * Unmaps @section from memory. + * + * Returns zero on success, a negative error code otherwise. + * Returns -pte_internal if @section is NULL. + * Returns -pte_bad_lock on any locking error. + * Returns -pte_internal if @section has not been mapped. + */ +extern int pt_section_unmap(struct pt_section *section); + +/* Read memory from a section. + * + * Reads at most @size bytes from @section at @offset into @buffer. @section + * must be mapped. + * + * Returns the number of bytes read on success, a negative error code otherwise. + * Returns -pte_internal if @section or @buffer are NULL. + * Returns -pte_nomap if @offset is beyond the end of the section. + */ +extern int pt_section_read(const struct pt_section *section, uint8_t *buffer, + uint16_t size, uint64_t offset); + +#endif /* PT_SECTION_H */ diff --git a/libipt/internal/include/pt_section_file.h b/libipt/internal/include/pt_section_file.h new file mode 100644 index 000000000000..1f3c6cb2a72a --- /dev/null +++ b/libipt/internal/include/pt_section_file.h @@ -0,0 +1,106 @@ +/* + * Copyright (c) 2013-2019, 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_SECTION_FILE_H +#define PT_SECTION_FILE_H + +#include <stdio.h> +#include <stdint.h> + +#if defined(FEATURE_THREADS) +# include <threads.h> +#endif /* defined(FEATURE_THREADS) */ + +struct pt_section; + + +/* File-based section mapping information. */ +struct pt_sec_file_mapping { + /* The FILE pointer. */ + FILE *file; + + /* The begin and end of the section as offset into @file. */ + long begin, end; + +#if defined(FEATURE_THREADS) + /* A lock protecting read access to this file. + * + * Since we need to first set the file position indication before + * we can read, there's a race on the file position. + */ + mtx_t lock; +#endif /* defined(FEATURE_THREADS) */ +}; + + +/* Map a section based on file operations. + * + * The caller has already opened the file for reading. + * + * On success, sets @section's mapping, unmap, and read pointers. + * + * Returns zero on success, a negative error code otherwise. + * Returns -pte_internal if @section or @file are NULL. + * Returns -pte_invalid if @section can't be mapped. + */ +extern int pt_sec_file_map(struct pt_section *section, FILE *file); + +/* Unmap a section based on file operations. + * + * On success, clears @section's mapping, unmap, and read pointers. + * + * Returns zero on success, a negative error code otherwise. + * Returns -pte_internal if @section is NULL. + * Returns -pte_internal if @section has not been mapped. + */ +extern int pt_sec_file_unmap(struct pt_section *section); + +/* Read memory from a file based section. + * + * Reads at most @size bytes from @section at @offset into @buffer. + * + * Returns the number of bytes read on success, a negative error code otherwise. + * Returns -pte_invalid if @section or @buffer are NULL. + * Returns -pte_nomap if @offset is beyond the end of the section. + */ +extern int pt_sec_file_read(const struct pt_section *section, uint8_t *buffer, + uint16_t size, uint64_t offset); + +/* Compute the memory size of a section based on file operations. + * + * On success, provides the amount of memory used for mapping @section in bytes + * in @size. + * + * Returns zero on success, a negative error code otherwise. + * Returns -pte_internal if @section or @size is NULL. + * Returns -pte_internal if @section has not been mapped. + */ +extern int pt_sec_file_memsize(const struct pt_section *section, + uint64_t *size); + +#endif /* PT_SECTION_FILE_H */ diff --git a/libipt/internal/include/pt_sync.h b/libipt/internal/include/pt_sync.h new file mode 100644 index 000000000000..24d654cef979 --- /dev/null +++ b/libipt/internal/include/pt_sync.h @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2014-2019, 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_SYNC_H +#define PT_SYNC_H + +#include <stdint.h> + +struct pt_config; + + +/* Synchronize onto the trace stream. + * + * Search for the next synchronization point in forward or backward direction + * starting at @pos using the trace configuration @config. + * + * On success, stores a pointer to the next synchronization point in @sync. + * + * Returns zero on success, a negative error code otherwise. + * + * Returns -pte_internal if @sync, @pos, or @config is NULL. + * Returns -pte_nosync if @pos lies outside of @config's buffer. + * Returns -pte_eos if no further synchronization point is found. + */ +extern int pt_sync_forward(const uint8_t **sync, const uint8_t *pos, + const struct pt_config *config); +extern int pt_sync_backward(const uint8_t **sync, const uint8_t *pos, + const struct pt_config *config); + +/* Manually synchronize onto the trace stream. + * + * Validate that @pos is within the bounds of @config's trace buffer and that + * there is a synchronization point at @pos. + * + * On success, stores @pos in @sync. + * + * Returns zero on success, a negative error code otherwise. + * + * Returns -pte_eos if @pos is outside of @config's trace buffer. + * Returns -pte_internal if @sync, @pos, or @config is NULL. + * Returns -pte_bad_packet if there is no PSB at @pos. + */ +extern int pt_sync_set(const uint8_t **sync, const uint8_t *pos, + const struct pt_config *config); + +#endif /* PT_SYNC_H */ diff --git a/libipt/internal/include/pt_time.h b/libipt/internal/include/pt_time.h new file mode 100644 index 000000000000..61079c372141 --- /dev/null +++ b/libipt/internal/include/pt_time.h @@ -0,0 +1,239 @@ +/* + * Copyright (c) 2014-2019, 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_TIME_H +#define PT_TIME_H + +#include <stdint.h> + +struct pt_config; +struct pt_packet_tsc; +struct pt_packet_cbr; +struct pt_packet_tma; +struct pt_packet_mtc; +struct pt_packet_cyc; + + +/* Intel(R) Processor Trace timing. */ +struct pt_time { + /* The estimated Time Stamp Count. */ + uint64_t tsc; + + /* The base Time Stamp Count (from TSC and MTC). */ + uint64_t base; + + /* The estimated Fast Counter. */ + uint64_t fc; + + /* The adjusted last CTC value (from MTC and TMA). */ + uint32_t ctc; + + /* The adjusted CTC value when @fc was cleared (from MTC and TMA). */ + uint32_t ctc_cyc; + + /* The number of lost MTC updates. */ + uint32_t lost_mtc; + + /* The number of lost CYC updates. */ + uint32_t lost_cyc; + + /* The core:bus ratio. */ + uint8_t cbr; + + /* A flag saying whether we have seen a TSC packet. */ + uint32_t have_tsc:1; + + /* A flag saying whether we have seen a CBR packet. */ + uint32_t have_cbr:1; + + /* A flag saying whether we have seen a TMA packet. */ + uint32_t have_tma:1; + + /* A flag saying whether we have seen a MTC packet. */ + uint32_t have_mtc:1; +}; + +/* Initialize (or reset) the time. */ +extern void pt_time_init(struct pt_time *time); + +/* Query the current time. + * + * Provides the estimated Time Stamp Count value in @tsc. + * + * If @lost_mtc is not NULL, provides the number of lost MTC packets. + * If @lost_cyc is not NULL, provides the number of lost CYC packets. + * + * Returns zero on success; a negative error code, otherwise. + * Returns -pte_internal if @tsc or @time is NULL. + * Returns -pte_no_time if there has not been a TSC packet. + */ +extern int pt_time_query_tsc(uint64_t *tsc, uint32_t *lost_mtc, + uint32_t *lost_cyc, const struct pt_time *time); + +/* Query the current core:bus ratio. + * + * Provides the core:bus ratio in @cbr. + * + * Returns zero on success; a negative error code, otherwise. + * Returns -pte_internal if @cbr or @time is NULL. + * Returns -pte_no_cbr if there has not been a CBR packet. + */ +extern int pt_time_query_cbr(uint32_t *cbr, const struct pt_time *time); + +/* Update the time based on an Intel PT packet. + * + * Returns zero on success. + * Returns a negative error code, otherwise. + */ +extern int pt_time_update_tsc(struct pt_time *, const struct pt_packet_tsc *, + const struct pt_config *); +extern int pt_time_update_cbr(struct pt_time *, const struct pt_packet_cbr *, + const struct pt_config *); +extern int pt_time_update_tma(struct pt_time *, const struct pt_packet_tma *, + const struct pt_config *); +extern int pt_time_update_mtc(struct pt_time *, const struct pt_packet_mtc *, + const struct pt_config *); +/* @fcr is the fast-counter:cycles ratio obtained by calibration. */ +extern int pt_time_update_cyc(struct pt_time *, const struct pt_packet_cyc *, + const struct pt_config *, uint64_t fcr); + + +/* Timing calibration. + * + * Used for estimating the Fast-Counter:Cycles ratio. + * + * Ideally, we calibrate by counting CYCs between MTCs. Lacking MTCs, we + * use TSC, instead. + */ +struct pt_time_cal { + /* The estimated fast-counter:cycles ratio. */ + uint64_t fcr; + + /* The minimal and maximal @fcr values. */ + uint64_t min_fcr, max_fcr; + + /* The last TSC value. + * + * Used for calibrating at TSC. + */ + uint64_t tsc; + + /* The number of cycles since the last TSC (from CYC). + * + * Used for calibrating at TSC. + */ + uint64_t cyc_tsc; + + /* The number of cycles since the last MTC (from CYC). + * + * Used for calibrating at MTC. + */ + uint64_t cyc_mtc; + + /* The adjusted last CTC value (from MTC). + * + * Used for calibrating at MTC. + */ + uint32_t ctc; + + /* The number of lost MTC updates since the last successful update. */ + uint32_t lost_mtc; + + /* A flag saying whether we have seen a MTC packet. */ + uint32_t have_mtc:1; + + /* A flag saying whether we need to check for erratum SKL168. */ + uint32_t check_skl168:1; +}; + +enum { + /* The amount by which the fcr value is right-shifted. + * + * Do not shift the value obtained by pt_tcal_fcr() when passing it to + * pt_time_update_cyc(). + * Do shift the value passed to pt_tcal_set_fcr(). + */ + pt_tcal_fcr_shr = 8 +}; + +/* Initialize of reset timing calibration. */ +extern void pt_tcal_init(struct pt_time_cal *tcal); + +/* Query the estimated fast-counter:cycles ratio. + * + * Provides the estimated ratio in @fcr unless -pte_internal or + * -pte_no_time is returned. + * + * Returns zero on success, a negative error code otherwise. + * Returns -pte_internal if @fcr or @tcal is NULL. + * Returns -pte_no_time if no information is available. + */ +extern int pt_tcal_fcr(uint64_t *fcr, const struct pt_time_cal *tcal); + +/* Set the fast-counter:cycles ratio. + * + * Timing calibration takes one CBR or two MTC packets before it can provide + * first estimations. Use this to supply an initial value to be used in the + * meantime. + * + * Returns zero on success, a negative error code otherwise. + * Returns -pte_internal if @cal is NULL. + */ +extern int pt_tcal_set_fcr(struct pt_time_cal *tcal, uint64_t fcr); + +/* Update calibration based on an Intel PT packet. + * + * Returns zero on success, a negative error code otherwise. + */ +extern int pt_tcal_update_tsc(struct pt_time_cal *, + const struct pt_packet_tsc *, + const struct pt_config *); +extern int pt_tcal_header_tsc(struct pt_time_cal *, + const struct pt_packet_tsc *, + const struct pt_config *); +extern int pt_tcal_update_cbr(struct pt_time_cal *, + const struct pt_packet_cbr *, + const struct pt_config *); +extern int pt_tcal_header_cbr(struct pt_time_cal *, + const struct pt_packet_cbr *, + const struct pt_config *); +extern int pt_tcal_update_tma(struct pt_time_cal *, + const struct pt_packet_tma *, + const struct pt_config *); +extern int pt_tcal_update_mtc(struct pt_time_cal *, + const struct pt_packet_mtc *, + const struct pt_config *); +extern int pt_tcal_update_cyc(struct pt_time_cal *, + const struct pt_packet_cyc *, + const struct pt_config *); +extern int pt_tcal_update_psb(struct pt_time_cal *, + const struct pt_config *); +extern int pt_tcal_update_ovf(struct pt_time_cal *, + const struct pt_config *); + +#endif /* PT_TIME_H */ diff --git a/libipt/internal/include/pt_tnt_cache.h b/libipt/internal/include/pt_tnt_cache.h new file mode 100644 index 000000000000..1d0d0da4bd53 --- /dev/null +++ b/libipt/internal/include/pt_tnt_cache.h @@ -0,0 +1,88 @@ +/* + * Copyright (c) 2013-2019, 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_TNT_CACHE_H +#define PT_TNT_CACHE_H + +#include <stdint.h> + +struct pt_packet_tnt; +struct pt_config; + + +/* Keeping track of tnt indicators. */ +struct pt_tnt_cache { + /* The last tnt. */ + uint64_t tnt; + + /* The index into the above tnt. + * + * (tnt & index) gives the current tnt entry. + * (index >>= 1) moves the index to the next tnt entry. + * (index == 0) means that the current tnt is empty. + */ + uint64_t index; +}; + + +/* Initialize (or reset) the tnt cache. */ +extern void pt_tnt_cache_init(struct pt_tnt_cache *cache); + +/* Check if the tnt cache is empty. + * + * Returns 0 if the tnt cache is not empty. + * Returns > 0 if the tnt cache is empty. + * Returns -pte_invalid if @cache is NULL. + */ +extern int pt_tnt_cache_is_empty(const struct pt_tnt_cache *cache); + +/* Query the next tnt indicator. + * + * This consumes the returned tnt indicator in the cache. + * + * Returns 0 if the next branch is not taken. + * Returns > 0 if the next branch is taken. + * Returns -pte_invalid if @cache is NULL. + * Returns -pte_bad_query if there is no tnt cached. + */ +extern int pt_tnt_cache_query(struct pt_tnt_cache *cache); + +/* Update the tnt cache based on Intel PT packets. + * + * Updates @cache based on @packet and, if non-null, @config. + * + * Returns zero on success. + * Returns -pte_invalid if @cache or @packet is NULL. + * Returns -pte_bad_packet if @packet appears to be corrupted. + * Returns -pte_bad_context if the tnt cache is not empty. + */ +extern int pt_tnt_cache_update_tnt(struct pt_tnt_cache *cache, + const struct pt_packet_tnt *packet, + const struct pt_config *config); + +#endif /* PT_TNT_CACHE_H */ diff --git a/libipt/internal/include/pti-disp-defs.h b/libipt/internal/include/pti-disp-defs.h new file mode 100644 index 000000000000..0f1077cacc8e --- /dev/null +++ b/libipt/internal/include/pti-disp-defs.h @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2013-2019, 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. + */ + +#if !defined(PTI_DISP_DEFS_H) +#define PTI_DISP_DEFS_H + +#define PTI_DISP_NONE 0 +#define PTI_PRESERVE_DEFAULT 1 +#define PTI_BRDISP8 2 +#define PTI_DISP_BUCKET_0_l1 3 +#define PTI_MEMDISPv_DISP_WIDTH_ASZ_NONTERM_EASZ_l2 4 +#define PTI_BRDISPz_BRDISP_WIDTH_OSZ_NONTERM_EOSZ_l2 5 +#define PTI_RESOLVE_BYREG_DISP_map0x0_op0xc7_l1 6 +#endif diff --git a/libipt/internal/include/pti-disp.h b/libipt/internal/include/pti-disp.h new file mode 100644 index 000000000000..a82f381d4e24 --- /dev/null +++ b/libipt/internal/include/pti-disp.h @@ -0,0 +1,544 @@ +/* + * Copyright (c) 2013-2019, 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. + */ + +static uint8_t disp_bytes_map_0x0[256] = { +/*opcode 0x0*/ PTI_PRESERVE_DEFAULT, +/*opcode 0x1*/ PTI_PRESERVE_DEFAULT, +/*opcode 0x2*/ PTI_PRESERVE_DEFAULT, +/*opcode 0x3*/ PTI_PRESERVE_DEFAULT, +/*opcode 0x4*/ PTI_PRESERVE_DEFAULT, +/*opcode 0x5*/ PTI_PRESERVE_DEFAULT, +/*opcode 0x6*/ PTI_PRESERVE_DEFAULT, +/*opcode 0x7*/ PTI_PRESERVE_DEFAULT, +/*opcode 0x8*/ PTI_PRESERVE_DEFAULT, +/*opcode 0x9*/ PTI_PRESERVE_DEFAULT, +/*opcode 0xa*/ PTI_PRESERVE_DEFAULT, +/*opcode 0xb*/ PTI_PRESERVE_DEFAULT, +/*opcode 0xc*/ PTI_PRESERVE_DEFAULT, +/*opcode 0xd*/ PTI_PRESERVE_DEFAULT, +/*opcode 0xe*/ PTI_PRESERVE_DEFAULT, +/*opcode 0xf*/ 0, +/*opcode 0x10*/ PTI_PRESERVE_DEFAULT, +/*opcode 0x11*/ PTI_PRESERVE_DEFAULT, +/*opcode 0x12*/ PTI_PRESERVE_DEFAULT, +/*opcode 0x13*/ PTI_PRESERVE_DEFAULT, +/*opcode 0x14*/ PTI_PRESERVE_DEFAULT, +/*opcode 0x15*/ PTI_PRESERVE_DEFAULT, +/*opcode 0x16*/ PTI_PRESERVE_DEFAULT, +/*opcode 0x17*/ PTI_PRESERVE_DEFAULT, +/*opcode 0x18*/ PTI_PRESERVE_DEFAULT, +/*opcode 0x19*/ PTI_PRESERVE_DEFAULT, +/*opcode 0x1a*/ PTI_PRESERVE_DEFAULT, +/*opcode 0x1b*/ PTI_PRESERVE_DEFAULT, +/*opcode 0x1c*/ PTI_PRESERVE_DEFAULT, +/*opcode 0x1d*/ PTI_PRESERVE_DEFAULT, +/*opcode 0x1e*/ PTI_PRESERVE_DEFAULT, +/*opcode 0x1f*/ PTI_PRESERVE_DEFAULT, +/*opcode 0x20*/ PTI_PRESERVE_DEFAULT, +/*opcode 0x21*/ PTI_PRESERVE_DEFAULT, +/*opcode 0x22*/ PTI_PRESERVE_DEFAULT, +/*opcode 0x23*/ PTI_PRESERVE_DEFAULT, +/*opcode 0x24*/ PTI_PRESERVE_DEFAULT, +/*opcode 0x25*/ PTI_PRESERVE_DEFAULT, +/*opcode 0x26*/ 0, +/*opcode 0x27*/ PTI_PRESERVE_DEFAULT, +/*opcode 0x28*/ PTI_PRESERVE_DEFAULT, +/*opcode 0x29*/ PTI_PRESERVE_DEFAULT, +/*opcode 0x2a*/ PTI_PRESERVE_DEFAULT, +/*opcode 0x2b*/ PTI_PRESERVE_DEFAULT, +/*opcode 0x2c*/ PTI_PRESERVE_DEFAULT, +/*opcode 0x2d*/ PTI_PRESERVE_DEFAULT, +/*opcode 0x2e*/ 0, +/*opcode 0x2f*/ PTI_PRESERVE_DEFAULT, +/*opcode 0x30*/ PTI_PRESERVE_DEFAULT, +/*opcode 0x31*/ PTI_PRESERVE_DEFAULT, +/*opcode 0x32*/ PTI_PRESERVE_DEFAULT, +/*opcode 0x33*/ PTI_PRESERVE_DEFAULT, +/*opcode 0x34*/ PTI_PRESERVE_DEFAULT, +/*opcode 0x35*/ PTI_PRESERVE_DEFAULT, +/*opcode 0x36*/ 0, +/*opcode 0x37*/ PTI_PRESERVE_DEFAULT, +/*opcode 0x38*/ PTI_PRESERVE_DEFAULT, +/*opcode 0x39*/ PTI_PRESERVE_DEFAULT, +/*opcode 0x3a*/ PTI_PRESERVE_DEFAULT, +/*opcode 0x3b*/ PTI_PRESERVE_DEFAULT, +/*opcode 0x3c*/ PTI_PRESERVE_DEFAULT, +/*opcode 0x3d*/ PTI_PRESERVE_DEFAULT, +/*opcode 0x3e*/ 0, +/*opcode 0x3f*/ PTI_PRESERVE_DEFAULT, +/*opcode 0x40*/ PTI_PRESERVE_DEFAULT, +/*opcode 0x41*/ PTI_PRESERVE_DEFAULT, +/*opcode 0x42*/ PTI_PRESERVE_DEFAULT, +/*opcode 0x43*/ PTI_PRESERVE_DEFAULT, +/*opcode 0x44*/ PTI_PRESERVE_DEFAULT, +/*opcode 0x45*/ PTI_PRESERVE_DEFAULT, +/*opcode 0x46*/ PTI_PRESERVE_DEFAULT, +/*opcode 0x47*/ PTI_PRESERVE_DEFAULT, +/*opcode 0x48*/ PTI_PRESERVE_DEFAULT, +/*opcode 0x49*/ PTI_PRESERVE_DEFAULT, +/*opcode 0x4a*/ PTI_PRESERVE_DEFAULT, +/*opcode 0x4b*/ PTI_PRESERVE_DEFAULT, +/*opcode 0x4c*/ PTI_PRESERVE_DEFAULT, +/*opcode 0x4d*/ PTI_PRESERVE_DEFAULT, +/*opcode 0x4e*/ PTI_PRESERVE_DEFAULT, +/*opcode 0x4f*/ PTI_PRESERVE_DEFAULT, +/*opcode 0x50*/ PTI_PRESERVE_DEFAULT, +/*opcode 0x51*/ PTI_PRESERVE_DEFAULT, +/*opcode 0x52*/ PTI_PRESERVE_DEFAULT, +/*opcode 0x53*/ PTI_PRESERVE_DEFAULT, +/*opcode 0x54*/ PTI_PRESERVE_DEFAULT, +/*opcode 0x55*/ PTI_PRESERVE_DEFAULT, +/*opcode 0x56*/ PTI_PRESERVE_DEFAULT, +/*opcode 0x57*/ PTI_PRESERVE_DEFAULT, +/*opcode 0x58*/ PTI_PRESERVE_DEFAULT, +/*opcode 0x59*/ PTI_PRESERVE_DEFAULT, +/*opcode 0x5a*/ PTI_PRESERVE_DEFAULT, +/*opcode 0x5b*/ PTI_PRESERVE_DEFAULT, +/*opcode 0x5c*/ PTI_PRESERVE_DEFAULT, +/*opcode 0x5d*/ PTI_PRESERVE_DEFAULT, +/*opcode 0x5e*/ PTI_PRESERVE_DEFAULT, +/*opcode 0x5f*/ PTI_PRESERVE_DEFAULT, +/*opcode 0x60*/ PTI_PRESERVE_DEFAULT, +/*opcode 0x61*/ PTI_PRESERVE_DEFAULT, +/*opcode 0x62*/ PTI_PRESERVE_DEFAULT, +/*opcode 0x63*/ PTI_PRESERVE_DEFAULT, +/*opcode 0x64*/ 0, +/*opcode 0x65*/ 0, +/*opcode 0x66*/ 0, +/*opcode 0x67*/ 0, +/*opcode 0x68*/ PTI_PRESERVE_DEFAULT, +/*opcode 0x69*/ PTI_PRESERVE_DEFAULT, +/*opcode 0x6a*/ PTI_PRESERVE_DEFAULT, +/*opcode 0x6b*/ PTI_PRESERVE_DEFAULT, +/*opcode 0x6c*/ PTI_PRESERVE_DEFAULT, +/*opcode 0x6d*/ PTI_PRESERVE_DEFAULT, +/*opcode 0x6e*/ PTI_PRESERVE_DEFAULT, +/*opcode 0x6f*/ PTI_PRESERVE_DEFAULT, +/*opcode 0x70*/ PTI_BRDISP8, +/*opcode 0x71*/ PTI_BRDISP8, +/*opcode 0x72*/ PTI_BRDISP8, +/*opcode 0x73*/ PTI_BRDISP8, +/*opcode 0x74*/ PTI_BRDISP8, +/*opcode 0x75*/ PTI_BRDISP8, +/*opcode 0x76*/ PTI_BRDISP8, +/*opcode 0x77*/ PTI_BRDISP8, +/*opcode 0x78*/ PTI_BRDISP8, +/*opcode 0x79*/ PTI_BRDISP8, +/*opcode 0x7a*/ PTI_BRDISP8, +/*opcode 0x7b*/ PTI_BRDISP8, +/*opcode 0x7c*/ PTI_BRDISP8, +/*opcode 0x7d*/ PTI_BRDISP8, +/*opcode 0x7e*/ PTI_BRDISP8, +/*opcode 0x7f*/ PTI_BRDISP8, +/*opcode 0x80*/ PTI_PRESERVE_DEFAULT, +/*opcode 0x81*/ PTI_PRESERVE_DEFAULT, +/*opcode 0x82*/ PTI_PRESERVE_DEFAULT, +/*opcode 0x83*/ PTI_PRESERVE_DEFAULT, +/*opcode 0x84*/ PTI_PRESERVE_DEFAULT, +/*opcode 0x85*/ PTI_PRESERVE_DEFAULT, +/*opcode 0x86*/ PTI_PRESERVE_DEFAULT, +/*opcode 0x87*/ PTI_PRESERVE_DEFAULT, +/*opcode 0x88*/ PTI_PRESERVE_DEFAULT, +/*opcode 0x89*/ PTI_PRESERVE_DEFAULT, +/*opcode 0x8a*/ PTI_PRESERVE_DEFAULT, +/*opcode 0x8b*/ PTI_PRESERVE_DEFAULT, +/*opcode 0x8c*/ PTI_PRESERVE_DEFAULT, +/*opcode 0x8d*/ PTI_PRESERVE_DEFAULT, +/*opcode 0x8e*/ PTI_PRESERVE_DEFAULT, +/*opcode 0x8f*/ PTI_PRESERVE_DEFAULT, +/*opcode 0x90*/ PTI_PRESERVE_DEFAULT, +/*opcode 0x91*/ PTI_PRESERVE_DEFAULT, +/*opcode 0x92*/ PTI_PRESERVE_DEFAULT, +/*opcode 0x93*/ PTI_PRESERVE_DEFAULT, +/*opcode 0x94*/ PTI_PRESERVE_DEFAULT, +/*opcode 0x95*/ PTI_PRESERVE_DEFAULT, +/*opcode 0x96*/ PTI_PRESERVE_DEFAULT, +/*opcode 0x97*/ PTI_PRESERVE_DEFAULT, +/*opcode 0x98*/ PTI_PRESERVE_DEFAULT, +/*opcode 0x99*/ PTI_PRESERVE_DEFAULT, +/*opcode 0x9a*/ PTI_BRDISPz_BRDISP_WIDTH_OSZ_NONTERM_EOSZ_l2, +/*opcode 0x9b*/ PTI_PRESERVE_DEFAULT, +/*opcode 0x9c*/ PTI_PRESERVE_DEFAULT, +/*opcode 0x9d*/ PTI_PRESERVE_DEFAULT, +/*opcode 0x9e*/ PTI_PRESERVE_DEFAULT, +/*opcode 0x9f*/ PTI_PRESERVE_DEFAULT, +/*opcode 0xa0*/ PTI_MEMDISPv_DISP_WIDTH_ASZ_NONTERM_EASZ_l2, +/*opcode 0xa1*/ PTI_MEMDISPv_DISP_WIDTH_ASZ_NONTERM_EASZ_l2, +/*opcode 0xa2*/ PTI_MEMDISPv_DISP_WIDTH_ASZ_NONTERM_EASZ_l2, +/*opcode 0xa3*/ PTI_MEMDISPv_DISP_WIDTH_ASZ_NONTERM_EASZ_l2, +/*opcode 0xa4*/ PTI_PRESERVE_DEFAULT, +/*opcode 0xa5*/ PTI_PRESERVE_DEFAULT, +/*opcode 0xa6*/ PTI_PRESERVE_DEFAULT, +/*opcode 0xa7*/ PTI_PRESERVE_DEFAULT, +/*opcode 0xa8*/ PTI_PRESERVE_DEFAULT, +/*opcode 0xa9*/ PTI_PRESERVE_DEFAULT, +/*opcode 0xaa*/ PTI_PRESERVE_DEFAULT, +/*opcode 0xab*/ PTI_PRESERVE_DEFAULT, +/*opcode 0xac*/ PTI_PRESERVE_DEFAULT, +/*opcode 0xad*/ PTI_PRESERVE_DEFAULT, +/*opcode 0xae*/ PTI_PRESERVE_DEFAULT, +/*opcode 0xaf*/ PTI_PRESERVE_DEFAULT, +/*opcode 0xb0*/ PTI_PRESERVE_DEFAULT, +/*opcode 0xb1*/ PTI_PRESERVE_DEFAULT, +/*opcode 0xb2*/ PTI_PRESERVE_DEFAULT, +/*opcode 0xb3*/ PTI_PRESERVE_DEFAULT, +/*opcode 0xb4*/ PTI_PRESERVE_DEFAULT, +/*opcode 0xb5*/ PTI_PRESERVE_DEFAULT, +/*opcode 0xb6*/ PTI_PRESERVE_DEFAULT, +/*opcode 0xb7*/ PTI_PRESERVE_DEFAULT, +/*opcode 0xb8*/ PTI_PRESERVE_DEFAULT, +/*opcode 0xb9*/ PTI_PRESERVE_DEFAULT, +/*opcode 0xba*/ PTI_PRESERVE_DEFAULT, +/*opcode 0xbb*/ PTI_PRESERVE_DEFAULT, +/*opcode 0xbc*/ PTI_PRESERVE_DEFAULT, +/*opcode 0xbd*/ PTI_PRESERVE_DEFAULT, +/*opcode 0xbe*/ PTI_PRESERVE_DEFAULT, +/*opcode 0xbf*/ PTI_PRESERVE_DEFAULT, +/*opcode 0xc0*/ PTI_PRESERVE_DEFAULT, +/*opcode 0xc1*/ PTI_PRESERVE_DEFAULT, +/*opcode 0xc2*/ PTI_PRESERVE_DEFAULT, +/*opcode 0xc3*/ PTI_PRESERVE_DEFAULT, +/*opcode 0xc4*/ PTI_PRESERVE_DEFAULT, +/*opcode 0xc5*/ PTI_PRESERVE_DEFAULT, +/*opcode 0xc6*/ PTI_PRESERVE_DEFAULT, +/*opcode 0xc7*/ PTI_RESOLVE_BYREG_DISP_map0x0_op0xc7_l1, +/*opcode 0xc8*/ PTI_PRESERVE_DEFAULT, +/*opcode 0xc9*/ PTI_PRESERVE_DEFAULT, +/*opcode 0xca*/ PTI_PRESERVE_DEFAULT, +/*opcode 0xcb*/ PTI_PRESERVE_DEFAULT, +/*opcode 0xcc*/ PTI_PRESERVE_DEFAULT, +/*opcode 0xcd*/ PTI_PRESERVE_DEFAULT, +/*opcode 0xce*/ PTI_PRESERVE_DEFAULT, +/*opcode 0xcf*/ PTI_PRESERVE_DEFAULT, +/*opcode 0xd0*/ PTI_PRESERVE_DEFAULT, +/*opcode 0xd1*/ PTI_PRESERVE_DEFAULT, +/*opcode 0xd2*/ PTI_PRESERVE_DEFAULT, +/*opcode 0xd3*/ PTI_PRESERVE_DEFAULT, +/*opcode 0xd4*/ PTI_PRESERVE_DEFAULT, +/*opcode 0xd5*/ PTI_PRESERVE_DEFAULT, +/*opcode 0xd6*/ PTI_PRESERVE_DEFAULT, +/*opcode 0xd7*/ PTI_PRESERVE_DEFAULT, +/*opcode 0xd8*/ PTI_PRESERVE_DEFAULT, +/*opcode 0xd9*/ PTI_PRESERVE_DEFAULT, +/*opcode 0xda*/ PTI_PRESERVE_DEFAULT, +/*opcode 0xdb*/ PTI_PRESERVE_DEFAULT, +/*opcode 0xdc*/ PTI_PRESERVE_DEFAULT, +/*opcode 0xdd*/ PTI_PRESERVE_DEFAULT, +/*opcode 0xde*/ PTI_PRESERVE_DEFAULT, +/*opcode 0xdf*/ PTI_PRESERVE_DEFAULT, +/*opcode 0xe0*/ PTI_BRDISP8, +/*opcode 0xe1*/ PTI_BRDISP8, +/*opcode 0xe2*/ PTI_BRDISP8, +/*opcode 0xe3*/ PTI_BRDISP8, +/*opcode 0xe4*/ PTI_PRESERVE_DEFAULT, +/*opcode 0xe5*/ PTI_PRESERVE_DEFAULT, +/*opcode 0xe6*/ PTI_PRESERVE_DEFAULT, +/*opcode 0xe7*/ PTI_PRESERVE_DEFAULT, +/*opcode 0xe8*/ PTI_DISP_BUCKET_0_l1, +/*opcode 0xe9*/ PTI_DISP_BUCKET_0_l1, +/*opcode 0xea*/ PTI_BRDISPz_BRDISP_WIDTH_OSZ_NONTERM_EOSZ_l2, +/*opcode 0xeb*/ PTI_BRDISP8, +/*opcode 0xec*/ PTI_PRESERVE_DEFAULT, +/*opcode 0xed*/ PTI_PRESERVE_DEFAULT, +/*opcode 0xee*/ PTI_PRESERVE_DEFAULT, +/*opcode 0xef*/ PTI_PRESERVE_DEFAULT, +/*opcode 0xf0*/ 0, +/*opcode 0xf1*/ PTI_PRESERVE_DEFAULT, +/*opcode 0xf2*/ 0, +/*opcode 0xf3*/ 0, +/*opcode 0xf4*/ PTI_PRESERVE_DEFAULT, +/*opcode 0xf5*/ PTI_PRESERVE_DEFAULT, +/*opcode 0xf6*/ PTI_PRESERVE_DEFAULT, +/*opcode 0xf7*/ PTI_PRESERVE_DEFAULT, +/*opcode 0xf8*/ PTI_PRESERVE_DEFAULT, +/*opcode 0xf9*/ PTI_PRESERVE_DEFAULT, +/*opcode 0xfa*/ PTI_PRESERVE_DEFAULT, +/*opcode 0xfb*/ PTI_PRESERVE_DEFAULT, +/*opcode 0xfc*/ PTI_PRESERVE_DEFAULT, +/*opcode 0xfd*/ PTI_PRESERVE_DEFAULT, +/*opcode 0xfe*/ PTI_PRESERVE_DEFAULT, +/*opcode 0xff*/ PTI_PRESERVE_DEFAULT, +}; +static uint8_t disp_bytes_map_0x0F[256] = { +/*opcode 0x0*/ PTI_PRESERVE_DEFAULT, +/*opcode 0x1*/ PTI_PRESERVE_DEFAULT, +/*opcode 0x2*/ PTI_PRESERVE_DEFAULT, +/*opcode 0x3*/ PTI_PRESERVE_DEFAULT, +/*opcode 0x4*/ 0, +/*opcode 0x5*/ PTI_PRESERVE_DEFAULT, +/*opcode 0x6*/ PTI_PRESERVE_DEFAULT, +/*opcode 0x7*/ PTI_PRESERVE_DEFAULT, +/*opcode 0x8*/ PTI_PRESERVE_DEFAULT, +/*opcode 0x9*/ PTI_PRESERVE_DEFAULT, +/*opcode 0xa*/ 0, +/*opcode 0xb*/ PTI_PRESERVE_DEFAULT, +/*opcode 0xc*/ 0, +/*opcode 0xd*/ PTI_PRESERVE_DEFAULT, +/*opcode 0xe*/ PTI_PRESERVE_DEFAULT, +/*opcode 0xf*/ 0, +/*opcode 0x10*/ PTI_PRESERVE_DEFAULT, +/*opcode 0x11*/ PTI_PRESERVE_DEFAULT, +/*opcode 0x12*/ PTI_PRESERVE_DEFAULT, +/*opcode 0x13*/ PTI_PRESERVE_DEFAULT, +/*opcode 0x14*/ PTI_PRESERVE_DEFAULT, +/*opcode 0x15*/ PTI_PRESERVE_DEFAULT, +/*opcode 0x16*/ PTI_PRESERVE_DEFAULT, +/*opcode 0x17*/ PTI_PRESERVE_DEFAULT, +/*opcode 0x18*/ PTI_PRESERVE_DEFAULT, +/*opcode 0x19*/ PTI_PRESERVE_DEFAULT, +/*opcode 0x1a*/ PTI_PRESERVE_DEFAULT, +/*opcode 0x1b*/ PTI_PRESERVE_DEFAULT, +/*opcode 0x1c*/ PTI_PRESERVE_DEFAULT, +/*opcode 0x1d*/ PTI_PRESERVE_DEFAULT, +/*opcode 0x1e*/ PTI_PRESERVE_DEFAULT, +/*opcode 0x1f*/ PTI_PRESERVE_DEFAULT, +/*opcode 0x20*/ PTI_PRESERVE_DEFAULT, +/*opcode 0x21*/ PTI_PRESERVE_DEFAULT, +/*opcode 0x22*/ PTI_PRESERVE_DEFAULT, +/*opcode 0x23*/ PTI_PRESERVE_DEFAULT, +/*opcode 0x24*/ 0, +/*opcode 0x25*/ 0, +/*opcode 0x26*/ 0, +/*opcode 0x27*/ 0, +/*opcode 0x28*/ PTI_PRESERVE_DEFAULT, +/*opcode 0x29*/ PTI_PRESERVE_DEFAULT, +/*opcode 0x2a*/ PTI_PRESERVE_DEFAULT, +/*opcode 0x2b*/ PTI_PRESERVE_DEFAULT, +/*opcode 0x2c*/ PTI_PRESERVE_DEFAULT, +/*opcode 0x2d*/ PTI_PRESERVE_DEFAULT, +/*opcode 0x2e*/ PTI_PRESERVE_DEFAULT, +/*opcode 0x2f*/ PTI_PRESERVE_DEFAULT, +/*opcode 0x30*/ PTI_PRESERVE_DEFAULT, +/*opcode 0x31*/ PTI_PRESERVE_DEFAULT, +/*opcode 0x32*/ PTI_PRESERVE_DEFAULT, +/*opcode 0x33*/ PTI_PRESERVE_DEFAULT, +/*opcode 0x34*/ PTI_PRESERVE_DEFAULT, +/*opcode 0x35*/ PTI_PRESERVE_DEFAULT, +/*opcode 0x36*/ 0, +/*opcode 0x37*/ PTI_PRESERVE_DEFAULT, +/*opcode 0x38*/ 0, +/*opcode 0x39*/ 0, +/*opcode 0x3a*/ 0, +/*opcode 0x3b*/ 0, +/*opcode 0x3c*/ 0, +/*opcode 0x3d*/ 0, +/*opcode 0x3e*/ 0, +/*opcode 0x3f*/ 0, +/*opcode 0x40*/ PTI_PRESERVE_DEFAULT, +/*opcode 0x41*/ PTI_PRESERVE_DEFAULT, +/*opcode 0x42*/ PTI_PRESERVE_DEFAULT, +/*opcode 0x43*/ PTI_PRESERVE_DEFAULT, +/*opcode 0x44*/ PTI_PRESERVE_DEFAULT, +/*opcode 0x45*/ PTI_PRESERVE_DEFAULT, +/*opcode 0x46*/ PTI_PRESERVE_DEFAULT, +/*opcode 0x47*/ PTI_PRESERVE_DEFAULT, +/*opcode 0x48*/ PTI_PRESERVE_DEFAULT, +/*opcode 0x49*/ PTI_PRESERVE_DEFAULT, +/*opcode 0x4a*/ PTI_PRESERVE_DEFAULT, +/*opcode 0x4b*/ PTI_PRESERVE_DEFAULT, +/*opcode 0x4c*/ PTI_PRESERVE_DEFAULT, +/*opcode 0x4d*/ PTI_PRESERVE_DEFAULT, +/*opcode 0x4e*/ PTI_PRESERVE_DEFAULT, +/*opcode 0x4f*/ PTI_PRESERVE_DEFAULT, +/*opcode 0x50*/ PTI_PRESERVE_DEFAULT, +/*opcode 0x51*/ PTI_PRESERVE_DEFAULT, +/*opcode 0x52*/ PTI_PRESERVE_DEFAULT, +/*opcode 0x53*/ PTI_PRESERVE_DEFAULT, +/*opcode 0x54*/ PTI_PRESERVE_DEFAULT, +/*opcode 0x55*/ PTI_PRESERVE_DEFAULT, +/*opcode 0x56*/ PTI_PRESERVE_DEFAULT, +/*opcode 0x57*/ PTI_PRESERVE_DEFAULT, +/*opcode 0x58*/ PTI_PRESERVE_DEFAULT, +/*opcode 0x59*/ PTI_PRESERVE_DEFAULT, +/*opcode 0x5a*/ PTI_PRESERVE_DEFAULT, +/*opcode 0x5b*/ PTI_PRESERVE_DEFAULT, +/*opcode 0x5c*/ PTI_PRESERVE_DEFAULT, +/*opcode 0x5d*/ PTI_PRESERVE_DEFAULT, +/*opcode 0x5e*/ PTI_PRESERVE_DEFAULT, +/*opcode 0x5f*/ PTI_PRESERVE_DEFAULT, +/*opcode 0x60*/ PTI_PRESERVE_DEFAULT, +/*opcode 0x61*/ PTI_PRESERVE_DEFAULT, +/*opcode 0x62*/ PTI_PRESERVE_DEFAULT, +/*opcode 0x63*/ PTI_PRESERVE_DEFAULT, +/*opcode 0x64*/ PTI_PRESERVE_DEFAULT, +/*opcode 0x65*/ PTI_PRESERVE_DEFAULT, +/*opcode 0x66*/ PTI_PRESERVE_DEFAULT, +/*opcode 0x67*/ PTI_PRESERVE_DEFAULT, +/*opcode 0x68*/ PTI_PRESERVE_DEFAULT, +/*opcode 0x69*/ PTI_PRESERVE_DEFAULT, +/*opcode 0x6a*/ PTI_PRESERVE_DEFAULT, +/*opcode 0x6b*/ PTI_PRESERVE_DEFAULT, +/*opcode 0x6c*/ PTI_PRESERVE_DEFAULT, +/*opcode 0x6d*/ PTI_PRESERVE_DEFAULT, +/*opcode 0x6e*/ PTI_PRESERVE_DEFAULT, +/*opcode 0x6f*/ PTI_PRESERVE_DEFAULT, +/*opcode 0x70*/ PTI_PRESERVE_DEFAULT, +/*opcode 0x71*/ PTI_PRESERVE_DEFAULT, +/*opcode 0x72*/ PTI_PRESERVE_DEFAULT, +/*opcode 0x73*/ PTI_PRESERVE_DEFAULT, +/*opcode 0x74*/ PTI_PRESERVE_DEFAULT, +/*opcode 0x75*/ PTI_PRESERVE_DEFAULT, +/*opcode 0x76*/ PTI_PRESERVE_DEFAULT, +/*opcode 0x77*/ PTI_PRESERVE_DEFAULT, +/*opcode 0x78*/ PTI_PRESERVE_DEFAULT, +/*opcode 0x79*/ PTI_PRESERVE_DEFAULT, +/*opcode 0x7a*/ PTI_PRESERVE_DEFAULT, +/*opcode 0x7b*/ PTI_PRESERVE_DEFAULT, +/*opcode 0x7c*/ PTI_PRESERVE_DEFAULT, +/*opcode 0x7d*/ PTI_PRESERVE_DEFAULT, +/*opcode 0x7e*/ PTI_PRESERVE_DEFAULT, +/*opcode 0x7f*/ PTI_PRESERVE_DEFAULT, +/*opcode 0x80*/ PTI_DISP_BUCKET_0_l1, +/*opcode 0x81*/ PTI_DISP_BUCKET_0_l1, +/*opcode 0x82*/ PTI_DISP_BUCKET_0_l1, +/*opcode 0x83*/ PTI_DISP_BUCKET_0_l1, +/*opcode 0x84*/ PTI_DISP_BUCKET_0_l1, +/*opcode 0x85*/ PTI_DISP_BUCKET_0_l1, +/*opcode 0x86*/ PTI_DISP_BUCKET_0_l1, +/*opcode 0x87*/ PTI_DISP_BUCKET_0_l1, +/*opcode 0x88*/ PTI_DISP_BUCKET_0_l1, +/*opcode 0x89*/ PTI_DISP_BUCKET_0_l1, +/*opcode 0x8a*/ PTI_DISP_BUCKET_0_l1, +/*opcode 0x8b*/ PTI_DISP_BUCKET_0_l1, +/*opcode 0x8c*/ PTI_DISP_BUCKET_0_l1, +/*opcode 0x8d*/ PTI_DISP_BUCKET_0_l1, +/*opcode 0x8e*/ PTI_DISP_BUCKET_0_l1, +/*opcode 0x8f*/ PTI_DISP_BUCKET_0_l1, +/*opcode 0x90*/ PTI_PRESERVE_DEFAULT, +/*opcode 0x91*/ PTI_PRESERVE_DEFAULT, +/*opcode 0x92*/ PTI_PRESERVE_DEFAULT, +/*opcode 0x93*/ PTI_PRESERVE_DEFAULT, +/*opcode 0x94*/ PTI_PRESERVE_DEFAULT, +/*opcode 0x95*/ PTI_PRESERVE_DEFAULT, +/*opcode 0x96*/ PTI_PRESERVE_DEFAULT, +/*opcode 0x97*/ PTI_PRESERVE_DEFAULT, +/*opcode 0x98*/ PTI_PRESERVE_DEFAULT, +/*opcode 0x99*/ PTI_PRESERVE_DEFAULT, +/*opcode 0x9a*/ PTI_PRESERVE_DEFAULT, +/*opcode 0x9b*/ PTI_PRESERVE_DEFAULT, +/*opcode 0x9c*/ PTI_PRESERVE_DEFAULT, +/*opcode 0x9d*/ PTI_PRESERVE_DEFAULT, +/*opcode 0x9e*/ PTI_PRESERVE_DEFAULT, +/*opcode 0x9f*/ PTI_PRESERVE_DEFAULT, +/*opcode 0xa0*/ PTI_PRESERVE_DEFAULT, +/*opcode 0xa1*/ PTI_PRESERVE_DEFAULT, +/*opcode 0xa2*/ PTI_PRESERVE_DEFAULT, +/*opcode 0xa3*/ PTI_PRESERVE_DEFAULT, +/*opcode 0xa4*/ PTI_PRESERVE_DEFAULT, +/*opcode 0xa5*/ PTI_PRESERVE_DEFAULT, +/*opcode 0xa6*/ 0, +/*opcode 0xa7*/ 0, +/*opcode 0xa8*/ PTI_PRESERVE_DEFAULT, +/*opcode 0xa9*/ PTI_PRESERVE_DEFAULT, +/*opcode 0xaa*/ PTI_PRESERVE_DEFAULT, +/*opcode 0xab*/ PTI_PRESERVE_DEFAULT, +/*opcode 0xac*/ PTI_PRESERVE_DEFAULT, +/*opcode 0xad*/ PTI_PRESERVE_DEFAULT, +/*opcode 0xae*/ PTI_PRESERVE_DEFAULT, +/*opcode 0xaf*/ PTI_PRESERVE_DEFAULT, +/*opcode 0xb0*/ PTI_PRESERVE_DEFAULT, +/*opcode 0xb1*/ PTI_PRESERVE_DEFAULT, +/*opcode 0xb2*/ PTI_PRESERVE_DEFAULT, +/*opcode 0xb3*/ PTI_PRESERVE_DEFAULT, +/*opcode 0xb4*/ PTI_PRESERVE_DEFAULT, +/*opcode 0xb5*/ PTI_PRESERVE_DEFAULT, +/*opcode 0xb6*/ PTI_PRESERVE_DEFAULT, +/*opcode 0xb7*/ PTI_PRESERVE_DEFAULT, +/*opcode 0xb8*/ PTI_PRESERVE_DEFAULT, +/*opcode 0xb9*/ 0, +/*opcode 0xba*/ PTI_PRESERVE_DEFAULT, +/*opcode 0xbb*/ PTI_PRESERVE_DEFAULT, +/*opcode 0xbc*/ PTI_PRESERVE_DEFAULT, +/*opcode 0xbd*/ PTI_PRESERVE_DEFAULT, +/*opcode 0xbe*/ PTI_PRESERVE_DEFAULT, +/*opcode 0xbf*/ PTI_PRESERVE_DEFAULT, +/*opcode 0xc0*/ PTI_PRESERVE_DEFAULT, +/*opcode 0xc1*/ PTI_PRESERVE_DEFAULT, +/*opcode 0xc2*/ PTI_PRESERVE_DEFAULT, +/*opcode 0xc3*/ PTI_PRESERVE_DEFAULT, +/*opcode 0xc4*/ PTI_PRESERVE_DEFAULT, +/*opcode 0xc5*/ PTI_PRESERVE_DEFAULT, +/*opcode 0xc6*/ PTI_PRESERVE_DEFAULT, +/*opcode 0xc7*/ PTI_PRESERVE_DEFAULT, +/*opcode 0xc8*/ PTI_PRESERVE_DEFAULT, +/*opcode 0xc9*/ PTI_PRESERVE_DEFAULT, +/*opcode 0xca*/ PTI_PRESERVE_DEFAULT, +/*opcode 0xcb*/ PTI_PRESERVE_DEFAULT, +/*opcode 0xcc*/ PTI_PRESERVE_DEFAULT, +/*opcode 0xcd*/ PTI_PRESERVE_DEFAULT, +/*opcode 0xce*/ PTI_PRESERVE_DEFAULT, +/*opcode 0xcf*/ PTI_PRESERVE_DEFAULT, +/*opcode 0xd0*/ PTI_PRESERVE_DEFAULT, +/*opcode 0xd1*/ PTI_PRESERVE_DEFAULT, +/*opcode 0xd2*/ PTI_PRESERVE_DEFAULT, +/*opcode 0xd3*/ PTI_PRESERVE_DEFAULT, +/*opcode 0xd4*/ PTI_PRESERVE_DEFAULT, +/*opcode 0xd5*/ PTI_PRESERVE_DEFAULT, +/*opcode 0xd6*/ PTI_PRESERVE_DEFAULT, +/*opcode 0xd7*/ PTI_PRESERVE_DEFAULT, +/*opcode 0xd8*/ PTI_PRESERVE_DEFAULT, +/*opcode 0xd9*/ PTI_PRESERVE_DEFAULT, +/*opcode 0xda*/ PTI_PRESERVE_DEFAULT, +/*opcode 0xdb*/ PTI_PRESERVE_DEFAULT, +/*opcode 0xdc*/ PTI_PRESERVE_DEFAULT, +/*opcode 0xdd*/ PTI_PRESERVE_DEFAULT, +/*opcode 0xde*/ PTI_PRESERVE_DEFAULT, +/*opcode 0xdf*/ PTI_PRESERVE_DEFAULT, +/*opcode 0xe0*/ PTI_PRESERVE_DEFAULT, +/*opcode 0xe1*/ PTI_PRESERVE_DEFAULT, +/*opcode 0xe2*/ PTI_PRESERVE_DEFAULT, +/*opcode 0xe3*/ PTI_PRESERVE_DEFAULT, +/*opcode 0xe4*/ PTI_PRESERVE_DEFAULT, +/*opcode 0xe5*/ PTI_PRESERVE_DEFAULT, +/*opcode 0xe6*/ PTI_PRESERVE_DEFAULT, +/*opcode 0xe7*/ PTI_PRESERVE_DEFAULT, +/*opcode 0xe8*/ PTI_PRESERVE_DEFAULT, +/*opcode 0xe9*/ PTI_PRESERVE_DEFAULT, +/*opcode 0xea*/ PTI_PRESERVE_DEFAULT, +/*opcode 0xeb*/ PTI_PRESERVE_DEFAULT, +/*opcode 0xec*/ PTI_PRESERVE_DEFAULT, +/*opcode 0xed*/ PTI_PRESERVE_DEFAULT, +/*opcode 0xee*/ PTI_PRESERVE_DEFAULT, +/*opcode 0xef*/ PTI_PRESERVE_DEFAULT, +/*opcode 0xf0*/ PTI_PRESERVE_DEFAULT, +/*opcode 0xf1*/ PTI_PRESERVE_DEFAULT, +/*opcode 0xf2*/ PTI_PRESERVE_DEFAULT, +/*opcode 0xf3*/ PTI_PRESERVE_DEFAULT, +/*opcode 0xf4*/ PTI_PRESERVE_DEFAULT, +/*opcode 0xf5*/ PTI_PRESERVE_DEFAULT, +/*opcode 0xf6*/ PTI_PRESERVE_DEFAULT, +/*opcode 0xf7*/ PTI_PRESERVE_DEFAULT, +/*opcode 0xf8*/ PTI_PRESERVE_DEFAULT, +/*opcode 0xf9*/ PTI_PRESERVE_DEFAULT, +/*opcode 0xfa*/ PTI_PRESERVE_DEFAULT, +/*opcode 0xfb*/ PTI_PRESERVE_DEFAULT, +/*opcode 0xfc*/ PTI_PRESERVE_DEFAULT, +/*opcode 0xfd*/ PTI_PRESERVE_DEFAULT, +/*opcode 0xfe*/ PTI_PRESERVE_DEFAULT, +/*opcode 0xff*/ 0, +}; diff --git a/libipt/internal/include/pti-disp_default.h b/libipt/internal/include/pti-disp_default.h new file mode 100644 index 000000000000..7b454baefd1e --- /dev/null +++ b/libipt/internal/include/pti-disp_default.h @@ -0,0 +1,209 @@ +/* + * Copyright (c) 2017-2019, 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 PTI_DISP_DEFAULT_H +#define PTI_DISP_DEFAULT_H + +#include <stdint.h> + + +static const uint8_t disp_default[4][4][8] = { + /* Effective Addressing Mode: ptem_unknown. */ { + /* MOD: 0 */ { + /* RM: 0 */ 0, + /* RM: 1 */ 0, + /* RM: 2 */ 0, + /* RM: 3 */ 0, + /* RM: 4 */ 0, + /* RM: 5 */ 0, + /* RM: 6 */ 0, + /* RM: 7 */ 0 + }, + /* MOD: 1 */ { + /* RM: 0 */ 0, + /* RM: 1 */ 0, + /* RM: 2 */ 0, + /* RM: 3 */ 0, + /* RM: 4 */ 0, + /* RM: 5 */ 0, + /* RM: 6 */ 0, + /* RM: 7 */ 0 + }, + /* MOD: 2 */ { + /* RM: 0 */ 0, + /* RM: 1 */ 0, + /* RM: 2 */ 0, + /* RM: 3 */ 0, + /* RM: 4 */ 0, + /* RM: 5 */ 0, + /* RM: 6 */ 0, + /* RM: 7 */ 0 + }, + /* MOD: 3 */ { + /* RM: 0 */ 0, + /* RM: 1 */ 0, + /* RM: 2 */ 0, + /* RM: 3 */ 0, + /* RM: 4 */ 0, + /* RM: 5 */ 0, + /* RM: 6 */ 0, + /* RM: 7 */ 0 + } + }, + + /* Effective Addressing Mode: ptem_16bit. */ { + /* MOD: 0 */ { + /* RM: 0 */ 0, + /* RM: 1 */ 0, + /* RM: 2 */ 0, + /* RM: 3 */ 0, + /* RM: 4 */ 0, + /* RM: 5 */ 0, + /* RM: 6 */ 2, + /* RM: 7 */ 0 + }, + /* MOD: 1 */ { + /* RM: 0 */ 1, + /* RM: 1 */ 1, + /* RM: 2 */ 1, + /* RM: 3 */ 1, + /* RM: 4 */ 1, + /* RM: 5 */ 1, + /* RM: 6 */ 1, + /* RM: 7 */ 1 + }, + /* MOD: 2 */ { + /* RM: 0 */ 2, + /* RM: 1 */ 2, + /* RM: 2 */ 2, + /* RM: 3 */ 2, + /* RM: 4 */ 2, + /* RM: 5 */ 2, + /* RM: 6 */ 2, + /* RM: 7 */ 2 + }, + /* MOD: 3 */ { + /* RM: 0 */ 0, + /* RM: 1 */ 0, + /* RM: 2 */ 0, + /* RM: 3 */ 0, + /* RM: 4 */ 0, + /* RM: 5 */ 0, + /* RM: 6 */ 0, + /* RM: 7 */ 0 + } + }, + + /* Effective Addressing Mode: ptem_32bit. */ { + /* MOD: 0 */ { + /* RM: 0 */ 0, + /* RM: 1 */ 0, + /* RM: 2 */ 0, + /* RM: 3 */ 0, + /* RM: 4 */ 0, + /* RM: 5 */ 4, + /* RM: 6 */ 0, + /* RM: 7 */ 0 + }, + /* MOD: 1 */ { + /* RM: 0 */ 1, + /* RM: 1 */ 1, + /* RM: 2 */ 1, + /* RM: 3 */ 1, + /* RM: 4 */ 1, + /* RM: 5 */ 1, + /* RM: 6 */ 1, + /* RM: 7 */ 1 + }, + /* MOD: 2 */ { + /* RM: 0 */ 4, + /* RM: 1 */ 4, + /* RM: 2 */ 4, + /* RM: 3 */ 4, + /* RM: 4 */ 4, + /* RM: 5 */ 4, + /* RM: 6 */ 4, + /* RM: 7 */ 4 + }, + /* MOD: 3 */ { + /* RM: 0 */ 0, + /* RM: 1 */ 0, + /* RM: 2 */ 0, + /* RM: 3 */ 0, + /* RM: 4 */ 0, + /* RM: 5 */ 0, + /* RM: 6 */ 0, + /* RM: 7 */ 0 + } + }, + + /* Effective Addressing Mode: ptem_64bit. */ { + /* MOD: 0 */ { + /* RM: 0 */ 0, + /* RM: 1 */ 0, + /* RM: 2 */ 0, + /* RM: 3 */ 0, + /* RM: 4 */ 0, + /* RM: 5 */ 4, + /* RM: 6 */ 0, + /* RM: 7 */ 0 + }, + /* MOD: 1 */ { + /* RM: 0 */ 1, + /* RM: 1 */ 1, + /* RM: 2 */ 1, + /* RM: 3 */ 1, + /* RM: 4 */ 1, + /* RM: 5 */ 1, + /* RM: 6 */ 1, + /* RM: 7 */ 1 + }, + /* MOD: 2 */ { + /* RM: 0 */ 4, + /* RM: 1 */ 4, + /* RM: 2 */ 4, + /* RM: 3 */ 4, + /* RM: 4 */ 4, + /* RM: 5 */ 4, + /* RM: 6 */ 4, + /* RM: 7 */ 4 + }, + /* MOD: 3 */ { + /* RM: 0 */ 0, + /* RM: 1 */ 0, + /* RM: 2 */ 0, + /* RM: 3 */ 0, + /* RM: 4 */ 0, + /* RM: 5 */ 0, + /* RM: 6 */ 0, + /* RM: 7 */ 0 + } + } +}; + +#endif /* PTI_DISP_DEFAULT_H */ diff --git a/libipt/internal/include/pti-imm-defs.h b/libipt/internal/include/pti-imm-defs.h new file mode 100644 index 000000000000..c26ea4e02e87 --- /dev/null +++ b/libipt/internal/include/pti-imm-defs.h @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2013-2019, 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. + */ + +#if !defined(PTI_IMM_DEFS_H) +#define PTI_IMM_DEFS_H + +#define PTI_IMM_NONE 0 +#define PTI_0_IMM_WIDTH_CONST_l2 1 +#define PTI_UIMM8_IMM_WIDTH_CONST_l2 2 +#define PTI_SIMM8_IMM_WIDTH_CONST_l2 3 +#define PTI_SIMMz_IMM_WIDTH_OSZ_NONTERM_EOSZ_l2 4 +#define PTI_UIMMv_IMM_WIDTH_OSZ_NONTERM_EOSZ_l2 5 +#define PTI_UIMM16_IMM_WIDTH_CONST_l2 6 +#define PTI_RESOLVE_BYREG_IMM_WIDTH_map0x0_op0xf7_l1 7 +#define PTI_RESOLVE_BYREG_IMM_WIDTH_map0x0_op0xc7_l1 8 +#define PTI_SIMMz_IMM_WIDTH_OSZ_NONTERM_DF64_EOSZ_l2 9 +#define PTI_RESOLVE_BYREG_IMM_WIDTH_map0x0_op0xf6_l1 10 +#define PTI_IMM_hasimm_map0x0_op0xc8_l1 11 +#define PTI_IMM_hasimm_map0x0F_op0x78_l1 12 + +#endif diff --git a/libipt/internal/include/pti-imm.h b/libipt/internal/include/pti-imm.h new file mode 100644 index 000000000000..fbbfbbb5c693 --- /dev/null +++ b/libipt/internal/include/pti-imm.h @@ -0,0 +1,544 @@ +/* + * Copyright (c) 2013-2019, 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. + */ + +static uint8_t imm_bytes_map_0x0[256] = { +/*opcode 0x0*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0x1*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0x2*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0x3*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0x4*/ PTI_SIMM8_IMM_WIDTH_CONST_l2, +/*opcode 0x5*/ PTI_SIMMz_IMM_WIDTH_OSZ_NONTERM_EOSZ_l2, +/*opcode 0x6*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0x7*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0x8*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0x9*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0xa*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0xb*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0xc*/ PTI_UIMM8_IMM_WIDTH_CONST_l2, +/*opcode 0xd*/ PTI_SIMMz_IMM_WIDTH_OSZ_NONTERM_EOSZ_l2, +/*opcode 0xe*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0xf*/ 0, +/*opcode 0x10*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0x11*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0x12*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0x13*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0x14*/ PTI_SIMM8_IMM_WIDTH_CONST_l2, +/*opcode 0x15*/ PTI_SIMMz_IMM_WIDTH_OSZ_NONTERM_EOSZ_l2, +/*opcode 0x16*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0x17*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0x18*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0x19*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0x1a*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0x1b*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0x1c*/ PTI_SIMM8_IMM_WIDTH_CONST_l2, +/*opcode 0x1d*/ PTI_SIMMz_IMM_WIDTH_OSZ_NONTERM_EOSZ_l2, +/*opcode 0x1e*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0x1f*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0x20*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0x21*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0x22*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0x23*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0x24*/ PTI_SIMM8_IMM_WIDTH_CONST_l2, +/*opcode 0x25*/ PTI_SIMMz_IMM_WIDTH_OSZ_NONTERM_EOSZ_l2, +/*opcode 0x26*/ 0, +/*opcode 0x27*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0x28*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0x29*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0x2a*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0x2b*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0x2c*/ PTI_SIMM8_IMM_WIDTH_CONST_l2, +/*opcode 0x2d*/ PTI_SIMMz_IMM_WIDTH_OSZ_NONTERM_EOSZ_l2, +/*opcode 0x2e*/ 0, +/*opcode 0x2f*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0x30*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0x31*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0x32*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0x33*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0x34*/ PTI_UIMM8_IMM_WIDTH_CONST_l2, +/*opcode 0x35*/ PTI_SIMMz_IMM_WIDTH_OSZ_NONTERM_EOSZ_l2, +/*opcode 0x36*/ 0, +/*opcode 0x37*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0x38*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0x39*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0x3a*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0x3b*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0x3c*/ PTI_SIMM8_IMM_WIDTH_CONST_l2, +/*opcode 0x3d*/ PTI_SIMMz_IMM_WIDTH_OSZ_NONTERM_EOSZ_l2, +/*opcode 0x3e*/ 0, +/*opcode 0x3f*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0x40*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0x41*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0x42*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0x43*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0x44*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0x45*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0x46*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0x47*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0x48*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0x49*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0x4a*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0x4b*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0x4c*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0x4d*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0x4e*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0x4f*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0x50*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0x51*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0x52*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0x53*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0x54*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0x55*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0x56*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0x57*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0x58*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0x59*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0x5a*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0x5b*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0x5c*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0x5d*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0x5e*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0x5f*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0x60*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0x61*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0x62*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0x63*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0x64*/ 0, +/*opcode 0x65*/ 0, +/*opcode 0x66*/ 0, +/*opcode 0x67*/ 0, +/*opcode 0x68*/ PTI_SIMMz_IMM_WIDTH_OSZ_NONTERM_DF64_EOSZ_l2, +/*opcode 0x69*/ PTI_SIMMz_IMM_WIDTH_OSZ_NONTERM_EOSZ_l2, +/*opcode 0x6a*/ PTI_SIMM8_IMM_WIDTH_CONST_l2, +/*opcode 0x6b*/ PTI_SIMM8_IMM_WIDTH_CONST_l2, +/*opcode 0x6c*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0x6d*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0x6e*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0x6f*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0x70*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0x71*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0x72*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0x73*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0x74*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0x75*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0x76*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0x77*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0x78*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0x79*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0x7a*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0x7b*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0x7c*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0x7d*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0x7e*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0x7f*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0x80*/ PTI_SIMM8_IMM_WIDTH_CONST_l2, +/*opcode 0x81*/ PTI_SIMMz_IMM_WIDTH_OSZ_NONTERM_EOSZ_l2, +/*opcode 0x82*/ PTI_SIMM8_IMM_WIDTH_CONST_l2, +/*opcode 0x83*/ PTI_SIMM8_IMM_WIDTH_CONST_l2, +/*opcode 0x84*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0x85*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0x86*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0x87*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0x88*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0x89*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0x8a*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0x8b*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0x8c*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0x8d*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0x8e*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0x8f*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0x90*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0x91*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0x92*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0x93*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0x94*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0x95*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0x96*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0x97*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0x98*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0x99*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0x9a*/ PTI_UIMM16_IMM_WIDTH_CONST_l2, +/*opcode 0x9b*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0x9c*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0x9d*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0x9e*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0x9f*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0xa0*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0xa1*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0xa2*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0xa3*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0xa4*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0xa5*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0xa6*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0xa7*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0xa8*/ PTI_SIMM8_IMM_WIDTH_CONST_l2, +/*opcode 0xa9*/ PTI_SIMMz_IMM_WIDTH_OSZ_NONTERM_EOSZ_l2, +/*opcode 0xaa*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0xab*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0xac*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0xad*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0xae*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0xaf*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0xb0*/ PTI_UIMM8_IMM_WIDTH_CONST_l2, +/*opcode 0xb1*/ PTI_UIMM8_IMM_WIDTH_CONST_l2, +/*opcode 0xb2*/ PTI_UIMM8_IMM_WIDTH_CONST_l2, +/*opcode 0xb3*/ PTI_UIMM8_IMM_WIDTH_CONST_l2, +/*opcode 0xb4*/ PTI_UIMM8_IMM_WIDTH_CONST_l2, +/*opcode 0xb5*/ PTI_UIMM8_IMM_WIDTH_CONST_l2, +/*opcode 0xb6*/ PTI_UIMM8_IMM_WIDTH_CONST_l2, +/*opcode 0xb7*/ PTI_UIMM8_IMM_WIDTH_CONST_l2, +/*opcode 0xb8*/ PTI_UIMMv_IMM_WIDTH_OSZ_NONTERM_EOSZ_l2, +/*opcode 0xb9*/ PTI_UIMMv_IMM_WIDTH_OSZ_NONTERM_EOSZ_l2, +/*opcode 0xba*/ PTI_UIMMv_IMM_WIDTH_OSZ_NONTERM_EOSZ_l2, +/*opcode 0xbb*/ PTI_UIMMv_IMM_WIDTH_OSZ_NONTERM_EOSZ_l2, +/*opcode 0xbc*/ PTI_UIMMv_IMM_WIDTH_OSZ_NONTERM_EOSZ_l2, +/*opcode 0xbd*/ PTI_UIMMv_IMM_WIDTH_OSZ_NONTERM_EOSZ_l2, +/*opcode 0xbe*/ PTI_UIMMv_IMM_WIDTH_OSZ_NONTERM_EOSZ_l2, +/*opcode 0xbf*/ PTI_UIMMv_IMM_WIDTH_OSZ_NONTERM_EOSZ_l2, +/*opcode 0xc0*/ PTI_UIMM8_IMM_WIDTH_CONST_l2, +/*opcode 0xc1*/ PTI_UIMM8_IMM_WIDTH_CONST_l2, +/*opcode 0xc2*/ PTI_UIMM16_IMM_WIDTH_CONST_l2, +/*opcode 0xc3*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0xc4*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0xc5*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0xc6*/ PTI_UIMM8_IMM_WIDTH_CONST_l2, +/*opcode 0xc7*/ PTI_RESOLVE_BYREG_IMM_WIDTH_map0x0_op0xc7_l1, +/*opcode 0xc8*/ PTI_IMM_hasimm_map0x0_op0xc8_l1, +/*opcode 0xc9*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0xca*/ PTI_UIMM16_IMM_WIDTH_CONST_l2, +/*opcode 0xcb*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0xcc*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0xcd*/ PTI_UIMM8_IMM_WIDTH_CONST_l2, +/*opcode 0xce*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0xcf*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0xd0*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0xd1*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0xd2*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0xd3*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0xd4*/ PTI_SIMM8_IMM_WIDTH_CONST_l2, +/*opcode 0xd5*/ PTI_SIMM8_IMM_WIDTH_CONST_l2, +/*opcode 0xd6*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0xd7*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0xd8*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0xd9*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0xda*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0xdb*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0xdc*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0xdd*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0xde*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0xdf*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0xe0*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0xe1*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0xe2*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0xe3*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0xe4*/ PTI_UIMM8_IMM_WIDTH_CONST_l2, +/*opcode 0xe5*/ PTI_UIMM8_IMM_WIDTH_CONST_l2, +/*opcode 0xe6*/ PTI_UIMM8_IMM_WIDTH_CONST_l2, +/*opcode 0xe7*/ PTI_UIMM8_IMM_WIDTH_CONST_l2, +/*opcode 0xe8*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0xe9*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0xea*/ PTI_UIMM16_IMM_WIDTH_CONST_l2, +/*opcode 0xeb*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0xec*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0xed*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0xee*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0xef*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0xf0*/ 0, +/*opcode 0xf1*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0xf2*/ 0, +/*opcode 0xf3*/ 0, +/*opcode 0xf4*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0xf5*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0xf6*/ PTI_RESOLVE_BYREG_IMM_WIDTH_map0x0_op0xf6_l1, +/*opcode 0xf7*/ PTI_RESOLVE_BYREG_IMM_WIDTH_map0x0_op0xf7_l1, +/*opcode 0xf8*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0xf9*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0xfa*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0xfb*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0xfc*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0xfd*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0xfe*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0xff*/ PTI_0_IMM_WIDTH_CONST_l2, +}; +static uint8_t imm_bytes_map_0x0F[256] = { +/*opcode 0x0*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0x1*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0x2*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0x3*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0x4*/ 0, +/*opcode 0x5*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0x6*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0x7*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0x8*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0x9*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0xa*/ 0, +/*opcode 0xb*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0xc*/ 0, +/*opcode 0xd*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0xe*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0xf*/ 0, +/*opcode 0x10*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0x11*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0x12*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0x13*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0x14*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0x15*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0x16*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0x17*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0x18*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0x19*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0x1a*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0x1b*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0x1c*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0x1d*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0x1e*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0x1f*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0x20*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0x21*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0x22*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0x23*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0x24*/ 0, +/*opcode 0x25*/ 0, +/*opcode 0x26*/ 0, +/*opcode 0x27*/ 0, +/*opcode 0x28*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0x29*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0x2a*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0x2b*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0x2c*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0x2d*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0x2e*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0x2f*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0x30*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0x31*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0x32*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0x33*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0x34*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0x35*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0x36*/ 0, +/*opcode 0x37*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0x38*/ 0, +/*opcode 0x39*/ 0, +/*opcode 0x3a*/ 0, +/*opcode 0x3b*/ 0, +/*opcode 0x3c*/ 0, +/*opcode 0x3d*/ 0, +/*opcode 0x3e*/ 0, +/*opcode 0x3f*/ 0, +/*opcode 0x40*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0x41*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0x42*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0x43*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0x44*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0x45*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0x46*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0x47*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0x48*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0x49*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0x4a*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0x4b*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0x4c*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0x4d*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0x4e*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0x4f*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0x50*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0x51*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0x52*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0x53*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0x54*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0x55*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0x56*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0x57*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0x58*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0x59*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0x5a*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0x5b*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0x5c*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0x5d*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0x5e*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0x5f*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0x60*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0x61*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0x62*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0x63*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0x64*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0x65*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0x66*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0x67*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0x68*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0x69*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0x6a*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0x6b*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0x6c*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0x6d*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0x6e*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0x6f*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0x70*/ PTI_UIMM8_IMM_WIDTH_CONST_l2, +/*opcode 0x71*/ PTI_UIMM8_IMM_WIDTH_CONST_l2, +/*opcode 0x72*/ PTI_UIMM8_IMM_WIDTH_CONST_l2, +/*opcode 0x73*/ PTI_UIMM8_IMM_WIDTH_CONST_l2, +/*opcode 0x74*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0x75*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0x76*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0x77*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0x78*/ PTI_IMM_hasimm_map0x0F_op0x78_l1, +/*opcode 0x79*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0x7a*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0x7b*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0x7c*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0x7d*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0x7e*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0x7f*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0x80*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0x81*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0x82*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0x83*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0x84*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0x85*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0x86*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0x87*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0x88*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0x89*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0x8a*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0x8b*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0x8c*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0x8d*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0x8e*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0x8f*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0x90*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0x91*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0x92*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0x93*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0x94*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0x95*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0x96*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0x97*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0x98*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0x99*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0x9a*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0x9b*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0x9c*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0x9d*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0x9e*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0x9f*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0xa0*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0xa1*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0xa2*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0xa3*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0xa4*/ PTI_UIMM8_IMM_WIDTH_CONST_l2, +/*opcode 0xa5*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0xa6*/ 0, +/*opcode 0xa7*/ 0, +/*opcode 0xa8*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0xa9*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0xaa*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0xab*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0xac*/ PTI_UIMM8_IMM_WIDTH_CONST_l2, +/*opcode 0xad*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0xae*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0xaf*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0xb0*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0xb1*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0xb2*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0xb3*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0xb4*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0xb5*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0xb6*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0xb7*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0xb8*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0xb9*/ 0, +/*opcode 0xba*/ PTI_UIMM8_IMM_WIDTH_CONST_l2, +/*opcode 0xbb*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0xbc*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0xbd*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0xbe*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0xbf*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0xc0*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0xc1*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0xc2*/ PTI_UIMM8_IMM_WIDTH_CONST_l2, +/*opcode 0xc3*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0xc4*/ PTI_UIMM8_IMM_WIDTH_CONST_l2, +/*opcode 0xc5*/ PTI_UIMM8_IMM_WIDTH_CONST_l2, +/*opcode 0xc6*/ PTI_UIMM8_IMM_WIDTH_CONST_l2, +/*opcode 0xc7*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0xc8*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0xc9*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0xca*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0xcb*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0xcc*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0xcd*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0xce*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0xcf*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0xd0*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0xd1*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0xd2*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0xd3*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0xd4*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0xd5*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0xd6*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0xd7*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0xd8*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0xd9*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0xda*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0xdb*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0xdc*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0xdd*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0xde*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0xdf*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0xe0*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0xe1*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0xe2*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0xe3*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0xe4*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0xe5*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0xe6*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0xe7*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0xe8*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0xe9*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0xea*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0xeb*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0xec*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0xed*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0xee*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0xef*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0xf0*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0xf1*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0xf2*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0xf3*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0xf4*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0xf5*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0xf6*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0xf7*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0xf8*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0xf9*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0xfa*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0xfb*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0xfc*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0xfd*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0xfe*/ PTI_0_IMM_WIDTH_CONST_l2, +/*opcode 0xff*/ 0, +}; diff --git a/libipt/internal/include/pti-modrm-defs.h b/libipt/internal/include/pti-modrm-defs.h new file mode 100644 index 000000000000..cb67c4be49ec --- /dev/null +++ b/libipt/internal/include/pti-modrm-defs.h @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2013-2019, 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. + */ + +#if !defined(PTI_MODRM_DEFS_H) +#define PTI_MODRM_DEFS_H + + +#define PTI_MODRM_FALSE 0 +#define PTI_MODRM_TRUE 1 +#define PTI_MODRM_IGNORE_MOD 2 +#define PTI_MODRM_UNDEF 3 + +#endif diff --git a/libipt/internal/include/pti-modrm.h b/libipt/internal/include/pti-modrm.h new file mode 100644 index 000000000000..72bdec8a37b5 --- /dev/null +++ b/libipt/internal/include/pti-modrm.h @@ -0,0 +1,544 @@ +/* + * Copyright (c) 2013-2019, 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. + */ + +static uint8_t has_modrm_map_0x0[256] = { +/*opcode 0x0*/ PTI_MODRM_TRUE, +/*opcode 0x1*/ PTI_MODRM_TRUE, +/*opcode 0x2*/ PTI_MODRM_TRUE, +/*opcode 0x3*/ PTI_MODRM_TRUE, +/*opcode 0x4*/ PTI_MODRM_FALSE, +/*opcode 0x5*/ PTI_MODRM_FALSE, +/*opcode 0x6*/ PTI_MODRM_FALSE, +/*opcode 0x7*/ PTI_MODRM_FALSE, +/*opcode 0x8*/ PTI_MODRM_TRUE, +/*opcode 0x9*/ PTI_MODRM_TRUE, +/*opcode 0xa*/ PTI_MODRM_TRUE, +/*opcode 0xb*/ PTI_MODRM_TRUE, +/*opcode 0xc*/ PTI_MODRM_FALSE, +/*opcode 0xd*/ PTI_MODRM_FALSE, +/*opcode 0xe*/ PTI_MODRM_FALSE, +/*opcode 0xf*/ PTI_MODRM_UNDEF, +/*opcode 0x10*/ PTI_MODRM_TRUE, +/*opcode 0x11*/ PTI_MODRM_TRUE, +/*opcode 0x12*/ PTI_MODRM_TRUE, +/*opcode 0x13*/ PTI_MODRM_TRUE, +/*opcode 0x14*/ PTI_MODRM_FALSE, +/*opcode 0x15*/ PTI_MODRM_FALSE, +/*opcode 0x16*/ PTI_MODRM_FALSE, +/*opcode 0x17*/ PTI_MODRM_FALSE, +/*opcode 0x18*/ PTI_MODRM_TRUE, +/*opcode 0x19*/ PTI_MODRM_TRUE, +/*opcode 0x1a*/ PTI_MODRM_TRUE, +/*opcode 0x1b*/ PTI_MODRM_TRUE, +/*opcode 0x1c*/ PTI_MODRM_FALSE, +/*opcode 0x1d*/ PTI_MODRM_FALSE, +/*opcode 0x1e*/ PTI_MODRM_FALSE, +/*opcode 0x1f*/ PTI_MODRM_FALSE, +/*opcode 0x20*/ PTI_MODRM_TRUE, +/*opcode 0x21*/ PTI_MODRM_TRUE, +/*opcode 0x22*/ PTI_MODRM_TRUE, +/*opcode 0x23*/ PTI_MODRM_TRUE, +/*opcode 0x24*/ PTI_MODRM_FALSE, +/*opcode 0x25*/ PTI_MODRM_FALSE, +/*opcode 0x26*/ PTI_MODRM_UNDEF, +/*opcode 0x27*/ PTI_MODRM_FALSE, +/*opcode 0x28*/ PTI_MODRM_TRUE, +/*opcode 0x29*/ PTI_MODRM_TRUE, +/*opcode 0x2a*/ PTI_MODRM_TRUE, +/*opcode 0x2b*/ PTI_MODRM_TRUE, +/*opcode 0x2c*/ PTI_MODRM_FALSE, +/*opcode 0x2d*/ PTI_MODRM_FALSE, +/*opcode 0x2e*/ PTI_MODRM_UNDEF, +/*opcode 0x2f*/ PTI_MODRM_FALSE, +/*opcode 0x30*/ PTI_MODRM_TRUE, +/*opcode 0x31*/ PTI_MODRM_TRUE, +/*opcode 0x32*/ PTI_MODRM_TRUE, +/*opcode 0x33*/ PTI_MODRM_TRUE, +/*opcode 0x34*/ PTI_MODRM_FALSE, +/*opcode 0x35*/ PTI_MODRM_FALSE, +/*opcode 0x36*/ PTI_MODRM_UNDEF, +/*opcode 0x37*/ PTI_MODRM_FALSE, +/*opcode 0x38*/ PTI_MODRM_TRUE, +/*opcode 0x39*/ PTI_MODRM_TRUE, +/*opcode 0x3a*/ PTI_MODRM_TRUE, +/*opcode 0x3b*/ PTI_MODRM_TRUE, +/*opcode 0x3c*/ PTI_MODRM_FALSE, +/*opcode 0x3d*/ PTI_MODRM_FALSE, +/*opcode 0x3e*/ PTI_MODRM_UNDEF, +/*opcode 0x3f*/ PTI_MODRM_FALSE, +/*opcode 0x40*/ PTI_MODRM_FALSE, +/*opcode 0x41*/ PTI_MODRM_FALSE, +/*opcode 0x42*/ PTI_MODRM_FALSE, +/*opcode 0x43*/ PTI_MODRM_FALSE, +/*opcode 0x44*/ PTI_MODRM_FALSE, +/*opcode 0x45*/ PTI_MODRM_FALSE, +/*opcode 0x46*/ PTI_MODRM_FALSE, +/*opcode 0x47*/ PTI_MODRM_FALSE, +/*opcode 0x48*/ PTI_MODRM_FALSE, +/*opcode 0x49*/ PTI_MODRM_FALSE, +/*opcode 0x4a*/ PTI_MODRM_FALSE, +/*opcode 0x4b*/ PTI_MODRM_FALSE, +/*opcode 0x4c*/ PTI_MODRM_FALSE, +/*opcode 0x4d*/ PTI_MODRM_FALSE, +/*opcode 0x4e*/ PTI_MODRM_FALSE, +/*opcode 0x4f*/ PTI_MODRM_FALSE, +/*opcode 0x50*/ PTI_MODRM_FALSE, +/*opcode 0x51*/ PTI_MODRM_FALSE, +/*opcode 0x52*/ PTI_MODRM_FALSE, +/*opcode 0x53*/ PTI_MODRM_FALSE, +/*opcode 0x54*/ PTI_MODRM_FALSE, +/*opcode 0x55*/ PTI_MODRM_FALSE, +/*opcode 0x56*/ PTI_MODRM_FALSE, +/*opcode 0x57*/ PTI_MODRM_FALSE, +/*opcode 0x58*/ PTI_MODRM_FALSE, +/*opcode 0x59*/ PTI_MODRM_FALSE, +/*opcode 0x5a*/ PTI_MODRM_FALSE, +/*opcode 0x5b*/ PTI_MODRM_FALSE, +/*opcode 0x5c*/ PTI_MODRM_FALSE, +/*opcode 0x5d*/ PTI_MODRM_FALSE, +/*opcode 0x5e*/ PTI_MODRM_FALSE, +/*opcode 0x5f*/ PTI_MODRM_FALSE, +/*opcode 0x60*/ PTI_MODRM_FALSE, +/*opcode 0x61*/ PTI_MODRM_FALSE, +/*opcode 0x62*/ PTI_MODRM_TRUE, +/*opcode 0x63*/ PTI_MODRM_TRUE, +/*opcode 0x64*/ PTI_MODRM_UNDEF, +/*opcode 0x65*/ PTI_MODRM_UNDEF, +/*opcode 0x66*/ PTI_MODRM_UNDEF, +/*opcode 0x67*/ PTI_MODRM_UNDEF, +/*opcode 0x68*/ PTI_MODRM_FALSE, +/*opcode 0x69*/ PTI_MODRM_TRUE, +/*opcode 0x6a*/ PTI_MODRM_FALSE, +/*opcode 0x6b*/ PTI_MODRM_TRUE, +/*opcode 0x6c*/ PTI_MODRM_FALSE, +/*opcode 0x6d*/ PTI_MODRM_FALSE, +/*opcode 0x6e*/ PTI_MODRM_FALSE, +/*opcode 0x6f*/ PTI_MODRM_FALSE, +/*opcode 0x70*/ PTI_MODRM_FALSE, +/*opcode 0x71*/ PTI_MODRM_FALSE, +/*opcode 0x72*/ PTI_MODRM_FALSE, +/*opcode 0x73*/ PTI_MODRM_FALSE, +/*opcode 0x74*/ PTI_MODRM_FALSE, +/*opcode 0x75*/ PTI_MODRM_FALSE, +/*opcode 0x76*/ PTI_MODRM_FALSE, +/*opcode 0x77*/ PTI_MODRM_FALSE, +/*opcode 0x78*/ PTI_MODRM_FALSE, +/*opcode 0x79*/ PTI_MODRM_FALSE, +/*opcode 0x7a*/ PTI_MODRM_FALSE, +/*opcode 0x7b*/ PTI_MODRM_FALSE, +/*opcode 0x7c*/ PTI_MODRM_FALSE, +/*opcode 0x7d*/ PTI_MODRM_FALSE, +/*opcode 0x7e*/ PTI_MODRM_FALSE, +/*opcode 0x7f*/ PTI_MODRM_FALSE, +/*opcode 0x80*/ PTI_MODRM_TRUE, +/*opcode 0x81*/ PTI_MODRM_TRUE, +/*opcode 0x82*/ PTI_MODRM_TRUE, +/*opcode 0x83*/ PTI_MODRM_TRUE, +/*opcode 0x84*/ PTI_MODRM_TRUE, +/*opcode 0x85*/ PTI_MODRM_TRUE, +/*opcode 0x86*/ PTI_MODRM_TRUE, +/*opcode 0x87*/ PTI_MODRM_TRUE, +/*opcode 0x88*/ PTI_MODRM_TRUE, +/*opcode 0x89*/ PTI_MODRM_TRUE, +/*opcode 0x8a*/ PTI_MODRM_TRUE, +/*opcode 0x8b*/ PTI_MODRM_TRUE, +/*opcode 0x8c*/ PTI_MODRM_TRUE, +/*opcode 0x8d*/ PTI_MODRM_TRUE, +/*opcode 0x8e*/ PTI_MODRM_TRUE, +/*opcode 0x8f*/ PTI_MODRM_TRUE, +/*opcode 0x90*/ PTI_MODRM_FALSE, +/*opcode 0x91*/ PTI_MODRM_FALSE, +/*opcode 0x92*/ PTI_MODRM_FALSE, +/*opcode 0x93*/ PTI_MODRM_FALSE, +/*opcode 0x94*/ PTI_MODRM_FALSE, +/*opcode 0x95*/ PTI_MODRM_FALSE, +/*opcode 0x96*/ PTI_MODRM_FALSE, +/*opcode 0x97*/ PTI_MODRM_FALSE, +/*opcode 0x98*/ PTI_MODRM_FALSE, +/*opcode 0x99*/ PTI_MODRM_FALSE, +/*opcode 0x9a*/ PTI_MODRM_FALSE, +/*opcode 0x9b*/ PTI_MODRM_FALSE, +/*opcode 0x9c*/ PTI_MODRM_FALSE, +/*opcode 0x9d*/ PTI_MODRM_FALSE, +/*opcode 0x9e*/ PTI_MODRM_FALSE, +/*opcode 0x9f*/ PTI_MODRM_FALSE, +/*opcode 0xa0*/ PTI_MODRM_FALSE, +/*opcode 0xa1*/ PTI_MODRM_FALSE, +/*opcode 0xa2*/ PTI_MODRM_FALSE, +/*opcode 0xa3*/ PTI_MODRM_FALSE, +/*opcode 0xa4*/ PTI_MODRM_FALSE, +/*opcode 0xa5*/ PTI_MODRM_FALSE, +/*opcode 0xa6*/ PTI_MODRM_FALSE, +/*opcode 0xa7*/ PTI_MODRM_FALSE, +/*opcode 0xa8*/ PTI_MODRM_FALSE, +/*opcode 0xa9*/ PTI_MODRM_FALSE, +/*opcode 0xaa*/ PTI_MODRM_FALSE, +/*opcode 0xab*/ PTI_MODRM_FALSE, +/*opcode 0xac*/ PTI_MODRM_FALSE, +/*opcode 0xad*/ PTI_MODRM_FALSE, +/*opcode 0xae*/ PTI_MODRM_FALSE, +/*opcode 0xaf*/ PTI_MODRM_FALSE, +/*opcode 0xb0*/ PTI_MODRM_FALSE, +/*opcode 0xb1*/ PTI_MODRM_FALSE, +/*opcode 0xb2*/ PTI_MODRM_FALSE, +/*opcode 0xb3*/ PTI_MODRM_FALSE, +/*opcode 0xb4*/ PTI_MODRM_FALSE, +/*opcode 0xb5*/ PTI_MODRM_FALSE, +/*opcode 0xb6*/ PTI_MODRM_FALSE, +/*opcode 0xb7*/ PTI_MODRM_FALSE, +/*opcode 0xb8*/ PTI_MODRM_FALSE, +/*opcode 0xb9*/ PTI_MODRM_FALSE, +/*opcode 0xba*/ PTI_MODRM_FALSE, +/*opcode 0xbb*/ PTI_MODRM_FALSE, +/*opcode 0xbc*/ PTI_MODRM_FALSE, +/*opcode 0xbd*/ PTI_MODRM_FALSE, +/*opcode 0xbe*/ PTI_MODRM_FALSE, +/*opcode 0xbf*/ PTI_MODRM_FALSE, +/*opcode 0xc0*/ PTI_MODRM_TRUE, +/*opcode 0xc1*/ PTI_MODRM_TRUE, +/*opcode 0xc2*/ PTI_MODRM_FALSE, +/*opcode 0xc3*/ PTI_MODRM_FALSE, +/*opcode 0xc4*/ PTI_MODRM_TRUE, +/*opcode 0xc5*/ PTI_MODRM_TRUE, +/*opcode 0xc6*/ PTI_MODRM_TRUE, +/*opcode 0xc7*/ PTI_MODRM_TRUE, +/*opcode 0xc8*/ PTI_MODRM_FALSE, +/*opcode 0xc9*/ PTI_MODRM_FALSE, +/*opcode 0xca*/ PTI_MODRM_FALSE, +/*opcode 0xcb*/ PTI_MODRM_FALSE, +/*opcode 0xcc*/ PTI_MODRM_FALSE, +/*opcode 0xcd*/ PTI_MODRM_FALSE, +/*opcode 0xce*/ PTI_MODRM_FALSE, +/*opcode 0xcf*/ PTI_MODRM_FALSE, +/*opcode 0xd0*/ PTI_MODRM_TRUE, +/*opcode 0xd1*/ PTI_MODRM_TRUE, +/*opcode 0xd2*/ PTI_MODRM_TRUE, +/*opcode 0xd3*/ PTI_MODRM_TRUE, +/*opcode 0xd4*/ PTI_MODRM_FALSE, +/*opcode 0xd5*/ PTI_MODRM_FALSE, +/*opcode 0xd6*/ PTI_MODRM_FALSE, +/*opcode 0xd7*/ PTI_MODRM_FALSE, +/*opcode 0xd8*/ PTI_MODRM_TRUE, +/*opcode 0xd9*/ PTI_MODRM_TRUE, +/*opcode 0xda*/ PTI_MODRM_TRUE, +/*opcode 0xdb*/ PTI_MODRM_TRUE, +/*opcode 0xdc*/ PTI_MODRM_TRUE, +/*opcode 0xdd*/ PTI_MODRM_TRUE, +/*opcode 0xde*/ PTI_MODRM_TRUE, +/*opcode 0xdf*/ PTI_MODRM_TRUE, +/*opcode 0xe0*/ PTI_MODRM_FALSE, +/*opcode 0xe1*/ PTI_MODRM_FALSE, +/*opcode 0xe2*/ PTI_MODRM_FALSE, +/*opcode 0xe3*/ PTI_MODRM_FALSE, +/*opcode 0xe4*/ PTI_MODRM_FALSE, +/*opcode 0xe5*/ PTI_MODRM_FALSE, +/*opcode 0xe6*/ PTI_MODRM_FALSE, +/*opcode 0xe7*/ PTI_MODRM_FALSE, +/*opcode 0xe8*/ PTI_MODRM_FALSE, +/*opcode 0xe9*/ PTI_MODRM_FALSE, +/*opcode 0xea*/ PTI_MODRM_FALSE, +/*opcode 0xeb*/ PTI_MODRM_FALSE, +/*opcode 0xec*/ PTI_MODRM_FALSE, +/*opcode 0xed*/ PTI_MODRM_FALSE, +/*opcode 0xee*/ PTI_MODRM_FALSE, +/*opcode 0xef*/ PTI_MODRM_FALSE, +/*opcode 0xf0*/ PTI_MODRM_UNDEF, +/*opcode 0xf1*/ PTI_MODRM_FALSE, +/*opcode 0xf2*/ PTI_MODRM_UNDEF, +/*opcode 0xf3*/ PTI_MODRM_UNDEF, +/*opcode 0xf4*/ PTI_MODRM_FALSE, +/*opcode 0xf5*/ PTI_MODRM_FALSE, +/*opcode 0xf6*/ PTI_MODRM_TRUE, +/*opcode 0xf7*/ PTI_MODRM_TRUE, +/*opcode 0xf8*/ PTI_MODRM_FALSE, +/*opcode 0xf9*/ PTI_MODRM_FALSE, +/*opcode 0xfa*/ PTI_MODRM_FALSE, +/*opcode 0xfb*/ PTI_MODRM_FALSE, +/*opcode 0xfc*/ PTI_MODRM_FALSE, +/*opcode 0xfd*/ PTI_MODRM_FALSE, +/*opcode 0xfe*/ PTI_MODRM_TRUE, +/*opcode 0xff*/ PTI_MODRM_TRUE, +}; +static uint8_t has_modrm_map_0x0F[256] = { +/*opcode 0x0*/ PTI_MODRM_TRUE, +/*opcode 0x1*/ PTI_MODRM_TRUE, +/*opcode 0x2*/ PTI_MODRM_TRUE, +/*opcode 0x3*/ PTI_MODRM_TRUE, +/*opcode 0x4*/ PTI_MODRM_UNDEF, +/*opcode 0x5*/ PTI_MODRM_FALSE, +/*opcode 0x6*/ PTI_MODRM_FALSE, +/*opcode 0x7*/ PTI_MODRM_FALSE, +/*opcode 0x8*/ PTI_MODRM_FALSE, +/*opcode 0x9*/ PTI_MODRM_FALSE, +/*opcode 0xa*/ PTI_MODRM_UNDEF, +/*opcode 0xb*/ PTI_MODRM_FALSE, +/*opcode 0xc*/ PTI_MODRM_UNDEF, +/*opcode 0xd*/ PTI_MODRM_TRUE, +/*opcode 0xe*/ PTI_MODRM_FALSE, +/*opcode 0xf*/ PTI_MODRM_UNDEF, +/*opcode 0x10*/ PTI_MODRM_TRUE, +/*opcode 0x11*/ PTI_MODRM_TRUE, +/*opcode 0x12*/ PTI_MODRM_TRUE, +/*opcode 0x13*/ PTI_MODRM_TRUE, +/*opcode 0x14*/ PTI_MODRM_TRUE, +/*opcode 0x15*/ PTI_MODRM_TRUE, +/*opcode 0x16*/ PTI_MODRM_TRUE, +/*opcode 0x17*/ PTI_MODRM_TRUE, +/*opcode 0x18*/ PTI_MODRM_TRUE, +/*opcode 0x19*/ PTI_MODRM_TRUE, +/*opcode 0x1a*/ PTI_MODRM_TRUE, +/*opcode 0x1b*/ PTI_MODRM_TRUE, +/*opcode 0x1c*/ PTI_MODRM_TRUE, +/*opcode 0x1d*/ PTI_MODRM_TRUE, +/*opcode 0x1e*/ PTI_MODRM_TRUE, +/*opcode 0x1f*/ PTI_MODRM_TRUE, +/*opcode 0x20*/ PTI_MODRM_IGNORE_MOD, +/*opcode 0x21*/ PTI_MODRM_IGNORE_MOD, +/*opcode 0x22*/ PTI_MODRM_IGNORE_MOD, +/*opcode 0x23*/ PTI_MODRM_IGNORE_MOD, +/*opcode 0x24*/ PTI_MODRM_UNDEF, +/*opcode 0x25*/ PTI_MODRM_UNDEF, +/*opcode 0x26*/ PTI_MODRM_UNDEF, +/*opcode 0x27*/ PTI_MODRM_UNDEF, +/*opcode 0x28*/ PTI_MODRM_TRUE, +/*opcode 0x29*/ PTI_MODRM_TRUE, +/*opcode 0x2a*/ PTI_MODRM_TRUE, +/*opcode 0x2b*/ PTI_MODRM_TRUE, +/*opcode 0x2c*/ PTI_MODRM_TRUE, +/*opcode 0x2d*/ PTI_MODRM_TRUE, +/*opcode 0x2e*/ PTI_MODRM_TRUE, +/*opcode 0x2f*/ PTI_MODRM_TRUE, +/*opcode 0x30*/ PTI_MODRM_FALSE, +/*opcode 0x31*/ PTI_MODRM_FALSE, +/*opcode 0x32*/ PTI_MODRM_FALSE, +/*opcode 0x33*/ PTI_MODRM_FALSE, +/*opcode 0x34*/ PTI_MODRM_FALSE, +/*opcode 0x35*/ PTI_MODRM_FALSE, +/*opcode 0x36*/ PTI_MODRM_UNDEF, +/*opcode 0x37*/ PTI_MODRM_FALSE, +/*opcode 0x38*/ PTI_MODRM_UNDEF, +/*opcode 0x39*/ PTI_MODRM_UNDEF, +/*opcode 0x3a*/ PTI_MODRM_UNDEF, +/*opcode 0x3b*/ PTI_MODRM_UNDEF, +/*opcode 0x3c*/ PTI_MODRM_UNDEF, +/*opcode 0x3d*/ PTI_MODRM_UNDEF, +/*opcode 0x3e*/ PTI_MODRM_UNDEF, +/*opcode 0x3f*/ PTI_MODRM_UNDEF, +/*opcode 0x40*/ PTI_MODRM_TRUE, +/*opcode 0x41*/ PTI_MODRM_TRUE, +/*opcode 0x42*/ PTI_MODRM_TRUE, +/*opcode 0x43*/ PTI_MODRM_TRUE, +/*opcode 0x44*/ PTI_MODRM_TRUE, +/*opcode 0x45*/ PTI_MODRM_TRUE, +/*opcode 0x46*/ PTI_MODRM_TRUE, +/*opcode 0x47*/ PTI_MODRM_TRUE, +/*opcode 0x48*/ PTI_MODRM_TRUE, +/*opcode 0x49*/ PTI_MODRM_TRUE, +/*opcode 0x4a*/ PTI_MODRM_TRUE, +/*opcode 0x4b*/ PTI_MODRM_TRUE, +/*opcode 0x4c*/ PTI_MODRM_TRUE, +/*opcode 0x4d*/ PTI_MODRM_TRUE, +/*opcode 0x4e*/ PTI_MODRM_TRUE, +/*opcode 0x4f*/ PTI_MODRM_TRUE, +/*opcode 0x50*/ PTI_MODRM_TRUE, +/*opcode 0x51*/ PTI_MODRM_TRUE, +/*opcode 0x52*/ PTI_MODRM_TRUE, +/*opcode 0x53*/ PTI_MODRM_TRUE, +/*opcode 0x54*/ PTI_MODRM_TRUE, +/*opcode 0x55*/ PTI_MODRM_TRUE, +/*opcode 0x56*/ PTI_MODRM_TRUE, +/*opcode 0x57*/ PTI_MODRM_TRUE, +/*opcode 0x58*/ PTI_MODRM_TRUE, +/*opcode 0x59*/ PTI_MODRM_TRUE, +/*opcode 0x5a*/ PTI_MODRM_TRUE, +/*opcode 0x5b*/ PTI_MODRM_TRUE, +/*opcode 0x5c*/ PTI_MODRM_TRUE, +/*opcode 0x5d*/ PTI_MODRM_TRUE, +/*opcode 0x5e*/ PTI_MODRM_TRUE, +/*opcode 0x5f*/ PTI_MODRM_TRUE, +/*opcode 0x60*/ PTI_MODRM_TRUE, +/*opcode 0x61*/ PTI_MODRM_TRUE, +/*opcode 0x62*/ PTI_MODRM_TRUE, +/*opcode 0x63*/ PTI_MODRM_TRUE, +/*opcode 0x64*/ PTI_MODRM_TRUE, +/*opcode 0x65*/ PTI_MODRM_TRUE, +/*opcode 0x66*/ PTI_MODRM_TRUE, +/*opcode 0x67*/ PTI_MODRM_TRUE, +/*opcode 0x68*/ PTI_MODRM_TRUE, +/*opcode 0x69*/ PTI_MODRM_TRUE, +/*opcode 0x6a*/ PTI_MODRM_TRUE, +/*opcode 0x6b*/ PTI_MODRM_TRUE, +/*opcode 0x6c*/ PTI_MODRM_TRUE, +/*opcode 0x6d*/ PTI_MODRM_TRUE, +/*opcode 0x6e*/ PTI_MODRM_TRUE, +/*opcode 0x6f*/ PTI_MODRM_TRUE, +/*opcode 0x70*/ PTI_MODRM_TRUE, +/*opcode 0x71*/ PTI_MODRM_TRUE, +/*opcode 0x72*/ PTI_MODRM_TRUE, +/*opcode 0x73*/ PTI_MODRM_TRUE, +/*opcode 0x74*/ PTI_MODRM_TRUE, +/*opcode 0x75*/ PTI_MODRM_TRUE, +/*opcode 0x76*/ PTI_MODRM_TRUE, +/*opcode 0x77*/ PTI_MODRM_FALSE, +/*opcode 0x78*/ PTI_MODRM_TRUE, +/*opcode 0x79*/ PTI_MODRM_TRUE, +/*opcode 0x7a*/ PTI_MODRM_TRUE, +/*opcode 0x7b*/ PTI_MODRM_TRUE, +/*opcode 0x7c*/ PTI_MODRM_TRUE, +/*opcode 0x7d*/ PTI_MODRM_TRUE, +/*opcode 0x7e*/ PTI_MODRM_TRUE, +/*opcode 0x7f*/ PTI_MODRM_TRUE, +/*opcode 0x80*/ PTI_MODRM_FALSE, +/*opcode 0x81*/ PTI_MODRM_FALSE, +/*opcode 0x82*/ PTI_MODRM_FALSE, +/*opcode 0x83*/ PTI_MODRM_FALSE, +/*opcode 0x84*/ PTI_MODRM_FALSE, +/*opcode 0x85*/ PTI_MODRM_FALSE, +/*opcode 0x86*/ PTI_MODRM_FALSE, +/*opcode 0x87*/ PTI_MODRM_FALSE, +/*opcode 0x88*/ PTI_MODRM_FALSE, +/*opcode 0x89*/ PTI_MODRM_FALSE, +/*opcode 0x8a*/ PTI_MODRM_FALSE, +/*opcode 0x8b*/ PTI_MODRM_FALSE, +/*opcode 0x8c*/ PTI_MODRM_FALSE, +/*opcode 0x8d*/ PTI_MODRM_FALSE, +/*opcode 0x8e*/ PTI_MODRM_FALSE, +/*opcode 0x8f*/ PTI_MODRM_FALSE, +/*opcode 0x90*/ PTI_MODRM_TRUE, +/*opcode 0x91*/ PTI_MODRM_TRUE, +/*opcode 0x92*/ PTI_MODRM_TRUE, +/*opcode 0x93*/ PTI_MODRM_TRUE, +/*opcode 0x94*/ PTI_MODRM_TRUE, +/*opcode 0x95*/ PTI_MODRM_TRUE, +/*opcode 0x96*/ PTI_MODRM_TRUE, +/*opcode 0x97*/ PTI_MODRM_TRUE, +/*opcode 0x98*/ PTI_MODRM_TRUE, +/*opcode 0x99*/ PTI_MODRM_TRUE, +/*opcode 0x9a*/ PTI_MODRM_TRUE, +/*opcode 0x9b*/ PTI_MODRM_TRUE, +/*opcode 0x9c*/ PTI_MODRM_TRUE, +/*opcode 0x9d*/ PTI_MODRM_TRUE, +/*opcode 0x9e*/ PTI_MODRM_TRUE, +/*opcode 0x9f*/ PTI_MODRM_TRUE, +/*opcode 0xa0*/ PTI_MODRM_FALSE, +/*opcode 0xa1*/ PTI_MODRM_FALSE, +/*opcode 0xa2*/ PTI_MODRM_FALSE, +/*opcode 0xa3*/ PTI_MODRM_TRUE, +/*opcode 0xa4*/ PTI_MODRM_TRUE, +/*opcode 0xa5*/ PTI_MODRM_TRUE, +/*opcode 0xa6*/ PTI_MODRM_UNDEF, +/*opcode 0xa7*/ PTI_MODRM_UNDEF, +/*opcode 0xa8*/ PTI_MODRM_FALSE, +/*opcode 0xa9*/ PTI_MODRM_FALSE, +/*opcode 0xaa*/ PTI_MODRM_FALSE, +/*opcode 0xab*/ PTI_MODRM_TRUE, +/*opcode 0xac*/ PTI_MODRM_TRUE, +/*opcode 0xad*/ PTI_MODRM_TRUE, +/*opcode 0xae*/ PTI_MODRM_TRUE, +/*opcode 0xaf*/ PTI_MODRM_TRUE, +/*opcode 0xb0*/ PTI_MODRM_TRUE, +/*opcode 0xb1*/ PTI_MODRM_TRUE, +/*opcode 0xb2*/ PTI_MODRM_TRUE, +/*opcode 0xb3*/ PTI_MODRM_TRUE, +/*opcode 0xb4*/ PTI_MODRM_TRUE, +/*opcode 0xb5*/ PTI_MODRM_TRUE, +/*opcode 0xb6*/ PTI_MODRM_TRUE, +/*opcode 0xb7*/ PTI_MODRM_TRUE, +/*opcode 0xb8*/ PTI_MODRM_TRUE, +/*opcode 0xb9*/ PTI_MODRM_UNDEF, +/*opcode 0xba*/ PTI_MODRM_TRUE, +/*opcode 0xbb*/ PTI_MODRM_TRUE, +/*opcode 0xbc*/ PTI_MODRM_TRUE, +/*opcode 0xbd*/ PTI_MODRM_TRUE, +/*opcode 0xbe*/ PTI_MODRM_TRUE, +/*opcode 0xbf*/ PTI_MODRM_TRUE, +/*opcode 0xc0*/ PTI_MODRM_TRUE, +/*opcode 0xc1*/ PTI_MODRM_TRUE, +/*opcode 0xc2*/ PTI_MODRM_TRUE, +/*opcode 0xc3*/ PTI_MODRM_TRUE, +/*opcode 0xc4*/ PTI_MODRM_TRUE, +/*opcode 0xc5*/ PTI_MODRM_TRUE, +/*opcode 0xc6*/ PTI_MODRM_TRUE, +/*opcode 0xc7*/ PTI_MODRM_TRUE, +/*opcode 0xc8*/ PTI_MODRM_FALSE, +/*opcode 0xc9*/ PTI_MODRM_FALSE, +/*opcode 0xca*/ PTI_MODRM_FALSE, +/*opcode 0xcb*/ PTI_MODRM_FALSE, +/*opcode 0xcc*/ PTI_MODRM_FALSE, +/*opcode 0xcd*/ PTI_MODRM_FALSE, +/*opcode 0xce*/ PTI_MODRM_FALSE, +/*opcode 0xcf*/ PTI_MODRM_FALSE, +/*opcode 0xd0*/ PTI_MODRM_TRUE, +/*opcode 0xd1*/ PTI_MODRM_TRUE, +/*opcode 0xd2*/ PTI_MODRM_TRUE, +/*opcode 0xd3*/ PTI_MODRM_TRUE, +/*opcode 0xd4*/ PTI_MODRM_TRUE, +/*opcode 0xd5*/ PTI_MODRM_TRUE, +/*opcode 0xd6*/ PTI_MODRM_TRUE, +/*opcode 0xd7*/ PTI_MODRM_TRUE, +/*opcode 0xd8*/ PTI_MODRM_TRUE, +/*opcode 0xd9*/ PTI_MODRM_TRUE, +/*opcode 0xda*/ PTI_MODRM_TRUE, +/*opcode 0xdb*/ PTI_MODRM_TRUE, +/*opcode 0xdc*/ PTI_MODRM_TRUE, +/*opcode 0xdd*/ PTI_MODRM_TRUE, +/*opcode 0xde*/ PTI_MODRM_TRUE, +/*opcode 0xdf*/ PTI_MODRM_TRUE, +/*opcode 0xe0*/ PTI_MODRM_TRUE, +/*opcode 0xe1*/ PTI_MODRM_TRUE, +/*opcode 0xe2*/ PTI_MODRM_TRUE, +/*opcode 0xe3*/ PTI_MODRM_TRUE, +/*opcode 0xe4*/ PTI_MODRM_TRUE, +/*opcode 0xe5*/ PTI_MODRM_TRUE, +/*opcode 0xe6*/ PTI_MODRM_TRUE, +/*opcode 0xe7*/ PTI_MODRM_TRUE, +/*opcode 0xe8*/ PTI_MODRM_TRUE, +/*opcode 0xe9*/ PTI_MODRM_TRUE, +/*opcode 0xea*/ PTI_MODRM_TRUE, +/*opcode 0xeb*/ PTI_MODRM_TRUE, +/*opcode 0xec*/ PTI_MODRM_TRUE, +/*opcode 0xed*/ PTI_MODRM_TRUE, +/*opcode 0xee*/ PTI_MODRM_TRUE, +/*opcode 0xef*/ PTI_MODRM_TRUE, +/*opcode 0xf0*/ PTI_MODRM_TRUE, +/*opcode 0xf1*/ PTI_MODRM_TRUE, +/*opcode 0xf2*/ PTI_MODRM_TRUE, +/*opcode 0xf3*/ PTI_MODRM_TRUE, +/*opcode 0xf4*/ PTI_MODRM_TRUE, +/*opcode 0xf5*/ PTI_MODRM_TRUE, +/*opcode 0xf6*/ PTI_MODRM_TRUE, +/*opcode 0xf7*/ PTI_MODRM_TRUE, +/*opcode 0xf8*/ PTI_MODRM_TRUE, +/*opcode 0xf9*/ PTI_MODRM_TRUE, +/*opcode 0xfa*/ PTI_MODRM_TRUE, +/*opcode 0xfb*/ PTI_MODRM_TRUE, +/*opcode 0xfc*/ PTI_MODRM_TRUE, +/*opcode 0xfd*/ PTI_MODRM_TRUE, +/*opcode 0xfe*/ PTI_MODRM_TRUE, +/*opcode 0xff*/ PTI_MODRM_UNDEF, +}; diff --git a/libipt/internal/include/pti-sib.h b/libipt/internal/include/pti-sib.h new file mode 100644 index 000000000000..d57670f47571 --- /dev/null +++ b/libipt/internal/include/pti-sib.h @@ -0,0 +1,209 @@ +/* + * Copyright (c) 2017-2019, 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 PTI_SIB_H +#define PTI_SIB_H + +#include <stdint.h> + + +static const uint8_t has_sib[4][4][8] = { + /* Effective Addressing Mode: ptem_unknown. */ { + /* MOD: 0 */ { + /* RM: 0 */ 0, + /* RM: 1 */ 0, + /* RM: 2 */ 0, + /* RM: 3 */ 0, + /* RM: 4 */ 0, + /* RM: 5 */ 0, + /* RM: 6 */ 0, + /* RM: 7 */ 0 + }, + /* MOD: 1 */ { + /* RM: 0 */ 0, + /* RM: 1 */ 0, + /* RM: 2 */ 0, + /* RM: 3 */ 0, + /* RM: 4 */ 0, + /* RM: 5 */ 0, + /* RM: 6 */ 0, + /* RM: 7 */ 0 + }, + /* MOD: 2 */ { + /* RM: 0 */ 0, + /* RM: 1 */ 0, + /* RM: 2 */ 0, + /* RM: 3 */ 0, + /* RM: 4 */ 0, + /* RM: 5 */ 0, + /* RM: 6 */ 0, + /* RM: 7 */ 0 + }, + /* MOD: 3 */ { + /* RM: 0 */ 0, + /* RM: 1 */ 0, + /* RM: 2 */ 0, + /* RM: 3 */ 0, + /* RM: 4 */ 0, + /* RM: 5 */ 0, + /* RM: 6 */ 0, + /* RM: 7 */ 0 + } + }, + + /* Effective Addressing Mode: ptem_16bit. */ { + /* MOD: 0 */ { + /* RM: 0 */ 0, + /* RM: 1 */ 0, + /* RM: 2 */ 0, + /* RM: 3 */ 0, + /* RM: 4 */ 0, + /* RM: 5 */ 0, + /* RM: 6 */ 0, + /* RM: 7 */ 0 + }, + /* MOD: 1 */ { + /* RM: 0 */ 0, + /* RM: 1 */ 0, + /* RM: 2 */ 0, + /* RM: 3 */ 0, + /* RM: 4 */ 0, + /* RM: 5 */ 0, + /* RM: 6 */ 0, + /* RM: 7 */ 0 + }, + /* MOD: 2 */ { + /* RM: 0 */ 0, + /* RM: 1 */ 0, + /* RM: 2 */ 0, + /* RM: 3 */ 0, + /* RM: 4 */ 0, + /* RM: 5 */ 0, + /* RM: 6 */ 0, + /* RM: 7 */ 0 + }, + /* MOD: 3 */ { + /* RM: 0 */ 0, + /* RM: 1 */ 0, + /* RM: 2 */ 0, + /* RM: 3 */ 0, + /* RM: 4 */ 0, + /* RM: 5 */ 0, + /* RM: 6 */ 0, + /* RM: 7 */ 0 + } + }, + + /* Effective Addressing Mode: ptem_32bit. */ { + /* MOD: 0 */ { + /* RM: 0 */ 0, + /* RM: 1 */ 0, + /* RM: 2 */ 0, + /* RM: 3 */ 0, + /* RM: 4 */ 1, + /* RM: 5 */ 0, + /* RM: 6 */ 0, + /* RM: 7 */ 0 + }, + /* MOD: 1 */ { + /* RM: 0 */ 0, + /* RM: 1 */ 0, + /* RM: 2 */ 0, + /* RM: 3 */ 0, + /* RM: 4 */ 1, + /* RM: 5 */ 0, + /* RM: 6 */ 0, + /* RM: 7 */ 0 + }, + /* MOD: 2 */ { + /* RM: 0 */ 0, + /* RM: 1 */ 0, + /* RM: 2 */ 0, + /* RM: 3 */ 0, + /* RM: 4 */ 1, + /* RM: 5 */ 0, + /* RM: 6 */ 0, + /* RM: 7 */ 0 + }, + /* MOD: 3 */ { + /* RM: 0 */ 0, + /* RM: 1 */ 0, + /* RM: 2 */ 0, + /* RM: 3 */ 0, + /* RM: 4 */ 0, + /* RM: 5 */ 0, + /* RM: 6 */ 0, + /* RM: 7 */ 0 + } + }, + + /* Effective Addressing Mode: ptem_64bit. */ { + /* MOD: 0 */ { + /* RM: 0 */ 0, + /* RM: 1 */ 0, + /* RM: 2 */ 0, + /* RM: 3 */ 0, + /* RM: 4 */ 1, + /* RM: 5 */ 0, + /* RM: 6 */ 0, + /* RM: 7 */ 0 + }, + /* MOD: 1 */ { + /* RM: 0 */ 0, + /* RM: 1 */ 0, + /* RM: 2 */ 0, + /* RM: 3 */ 0, + /* RM: 4 */ 1, + /* RM: 5 */ 0, + /* RM: 6 */ 0, + /* RM: 7 */ 0 + }, + /* MOD: 2 */ { + /* RM: 0 */ 0, + /* RM: 1 */ 0, + /* RM: 2 */ 0, + /* RM: 3 */ 0, + /* RM: 4 */ 1, + /* RM: 5 */ 0, + /* RM: 6 */ 0, + /* RM: 7 */ 0 + }, + /* MOD: 3 */ { + /* RM: 0 */ 0, + /* RM: 1 */ 0, + /* RM: 2 */ 0, + /* RM: 3 */ 0, + /* RM: 4 */ 0, + /* RM: 5 */ 0, + /* RM: 6 */ 0, + /* RM: 7 */ 0 + } + } +}; + +#endif /* PTI_SIB_H */ diff --git a/libipt/internal/include/windows/pt_section_windows.h b/libipt/internal/include/windows/pt_section_windows.h new file mode 100644 index 000000000000..0fcce2dffefe --- /dev/null +++ b/libipt/internal/include/windows/pt_section_windows.h @@ -0,0 +1,111 @@ +/* + * Copyright (c) 2015-2019, 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_SECTION_WINDOWS_H +#define PT_SECTION_WINDOWS_H + +#include <windows.h> +#include <sys/types.h> +#include <sys/stat.h> + +struct pt_section; + + +/* Fstat-based file status. */ +struct pt_sec_windows_status { + /* The file status. */ + struct _stat stat; +}; + +/* FileView-based section mapping information. */ +struct pt_sec_windows_mapping { + /* The file descriptor. */ + int fd; + + /* The FileMapping handle. */ + HANDLE mh; + + /* The mmap base address. */ + uint8_t *base; + + /* The begin and end of the mapped memory. */ + const uint8_t *begin, *end; +}; + + +/* Map a section. + * + * The caller has already opened the file for reading. + * + * On success, sets @section's mapping, unmap, and read pointers. + * + * Returns zero on success, a negative error code otherwise. + * Returns -pte_internal if @section is NULL. + * Returns -pte_invalid if @section can't be mapped. + */ +extern int pt_sec_windows_map(struct pt_section *section, int fd); + +/* Unmap a section. + * + * On success, clears @section's mapping, unmap, and read pointers. + * + * This function should not be called directly; call @section->unmap() instead. + * + * Returns zero on success, a negative error code otherwise. + * Returns -pte_internal if @section is NULL. + * Returns -pte_internal if @section has not been mapped. + */ +extern int pt_sec_windows_unmap(struct pt_section *section); + +/* Read memory from an mmaped section. + * + * Reads at most @size bytes from @section at @offset into @buffer. + * + * This function should not be called directly; call @section->read() instead. + * + * Returns the number of bytes read on success, a negative error code otherwise. + * Returns -pte_invalid if @section or @buffer are NULL. + * Returns -pte_nomap if @offset is beyond the end of the section. + */ +extern int pt_sec_windows_read(const struct pt_section *section, + uint8_t *buffer, uint16_t size, + uint64_t offset); + +/* Compute the memory size of a section. + * + * On success, provides the amount of memory used for mapping @section in bytes + * in @size. + * + * Returns zero on success, a negative error code otherwise. + * Returns -pte_internal if @section or @size is NULL. + * Returns -pte_internal if @section has not been mapped. + */ +extern int pt_sec_windows_memsize(const struct pt_section *section, + uint64_t *size); + +#endif /* PT_SECTION_WINDOWS_H */ |