Import Intel Processor Trace library.

Git ID 24982c1a6fce48f1e416461d42899805f74fbb26

Sponsored by:	DARPA, AFRL
Differential Revision:	https://reviews.freebsd.org/D12815
This commit is contained in:
Ruslan Bukin 2018-03-19 18:34:08 +00:00
commit 766f5c51c3
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/vendor/processor-trace/24982c1a6fce48f1e416461d42899805f74fbb26/; revision=331218; tag=vendor/processor-trace/24982c1a6fce48f1e416461d42899805f74fbb26
370 changed files with 82916 additions and 0 deletions

7
.gitignore vendored Normal file
View File

@ -0,0 +1,7 @@
*.lst
*.bin
*.pt
*.sb
*.exp
*.out
*.diff

304
CMakeLists.txt Normal file
View File

@ -0,0 +1,304 @@
# Copyright (c) 2013-2018, 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.
cmake_minimum_required(VERSION 2.8.6)
project(PT C)
# versioning
#
# the major and the minor number define the supported Intel PT set.
#
# a build number and a version extension can be optionally specified.
#
set(PT_VERSION_MAJOR 1)
set(PT_VERSION_MINOR 6)
set(PT_VERSION_BUILD "0" CACHE STRING "")
set(PT_VERSION_EXT "" CACHE STRING "")
set(PT_VERSION "${PT_VERSION_MAJOR}.${PT_VERSION_MINOR}.${PT_VERSION_BUILD}")
add_definitions(
-DPT_VERSION_MAJOR=${PT_VERSION_MAJOR}
-DPT_VERSION_MINOR=${PT_VERSION_MINOR}
-DPT_VERSION_BUILD=${PT_VERSION_BUILD}
-DPT_VERSION_EXT=\"${PT_VERSION_EXT}\"
)
include(GNUInstallDirs)
include(FindUnixCommands)
include(CheckCCompilerFlag)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)
set(MAN_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/man)
set(CMAKE_COLOR_MAKEFILE OFF)
set(CMAKE_VERBOSE_MAKEFILE ON)
set(CMAKE_MACOSX_RPATH ON)
option(FEATURE_THREADS "A small amount of multi-threading support." ON)
if (FEATURE_THREADS)
add_definitions(-DFEATURE_THREADS)
endif (FEATURE_THREADS)
option(DEVBUILD "Enable compiler warnings and turn them into errors." OFF)
option(PTDUMP "Enable ptdump, a packet dumper")
option(PTXED "Enable ptxed, an instruction flow dumper")
option(PTTC "Enable pttc, a test compiler")
option(PTUNIT "Enable ptunit, a unit test system and libipt unit tests")
option(MAN "Enable man pages (requires pandoc)." OFF)
option(SIDEBAND "Enable libipt-sb, a sideband correlation library")
if (SIDEBAND)
option(PEVENT "Enable perf_event sideband support." OFF)
endif (SIDEBAND)
if (PTXED OR PEVENT)
option(FEATURE_ELF "Support ELF files." OFF)
endif (PTXED OR PEVENT)
set(PTT OFF)
if (BASH AND PTDUMP AND PTXED AND PTTC)
set(PTT ON)
endif ()
if (PTUNIT OR PTT)
ENABLE_TESTING()
endif()
if (PTUNIT)
enable_language(CXX)
endif()
include_directories(
include
${CMAKE_CURRENT_BINARY_DIR}/libipt/include
)
if (PTUNIT)
include_directories(
ptunit/include
)
endif (PTUNIT)
if (FEATURE_ELF)
add_definitions(
-DFEATURE_ELF
)
endif (FEATURE_ELF)
if (SIDEBAND)
add_definitions(
-DFEATURE_SIDEBAND
)
include_directories(
${CMAKE_CURRENT_BINARY_DIR}/sideband/include
)
endif (SIDEBAND)
if (PEVENT)
add_definitions(
-DFEATURE_PEVENT
)
include_directories(
pevent/include
)
endif (PEVENT)
function(add_cflag_if_available option)
check_c_compiler_flag(${option} ${option}_supported)
if (${option}_supported)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${option}" PARENT_SCOPE)
endif (${option}_supported)
endfunction(add_cflag_if_available)
if (CMAKE_HOST_WIN32)
include_directories(
include/windows
)
add_definitions(
# cl spells inline __inline in C
#
/Dinline=__inline
# cl spells strtoll _strtoi64
#
/Dstrtoll=_strtoi64
# cl spells strtoull _strtoui64
#
/Dstrtoull=_strtoui64
# avoid annoying warnings about unsecure standard functions
#
/D_CRT_SECURE_NO_WARNINGS
)
# enable parallel build
#
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /MP")
if (DEVBUILD)
# compiler warnings
#
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /W4")
# warnings are errors
#
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /WX")
endif (DEVBUILD)
if (CMAKE_C_COMPILER_ID MATCHES "MSVC")
# prevent complaints on:
# - do {} while(0) constructs
# - int arr[] constructs
#
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /wd4127")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /wd4200")
endif (CMAKE_C_COMPILER_ID MATCHES "MSVC")
endif (CMAKE_HOST_WIN32)
if (CMAKE_HOST_UNIX)
include_directories(
include/posix
)
add_definitions(
-D_POSIX_C_SOURCE=200809L
)
option(GCOV "Compile for GNU code coverage analysis." OFF)
if (GCOV)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fprofile-arcs")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -ftest-coverage")
link_libraries(gcov)
endif (GCOV)
if (FEATURE_THREADS)
link_libraries(pthread)
endif (FEATURE_THREADS)
# set the language
#
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=c99")
# windows-like dll export model
#
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fvisibility=hidden")
if (DEVBUILD)
# compiler warnings
#
if (CMAKE_C_COMPILER_ID MATCHES "[Cc]lang")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Weverything")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-disabled-macro-expansion")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-covered-switch-default")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-sign-conversion")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-switch-enum")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-cast-align")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-padded")
else (CMAKE_C_COMPILER_ID MATCHES "[Cc]lang")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wextra")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -pedantic")
add_cflag_if_available("-Wimplicit-fallthrough=5")
endif (CMAKE_C_COMPILER_ID MATCHES "[Cc]lang")
# warnings are errors
#
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Werror")
endif (DEVBUILD)
endif (CMAKE_HOST_UNIX)
function(add_ptunit_test_base name)
if (PTUNIT)
add_executable(${name} ${ARGN})
target_link_libraries(${name} ptunit)
add_test(NAME ${name} COMMAND ${name})
endif (PTUNIT)
endfunction(add_ptunit_test_base)
function(add_ptunit_c_test name)
add_ptunit_test_base(ptunit-${name} test/src/ptunit-${name}.c ${ARGN})
endfunction(add_ptunit_c_test)
function(add_ptunit_cpp_test name)
add_ptunit_test_base(ptunit-${name} test/src/ptunit-${name}.cpp ${ARGN})
endfunction(add_ptunit_cpp_test)
function(add_ptunit_libraries name)
if (PTUNIT)
target_link_libraries(ptunit-${name} ${ARGN})
endif (PTUNIT)
endfunction(add_ptunit_libraries)
add_subdirectory(libipt)
if (PTDUMP)
add_subdirectory(ptdump)
endif (PTDUMP)
if (PTXED)
add_subdirectory(ptxed)
endif (PTXED)
if (PTTC)
add_subdirectory(pttc)
endif (PTTC)
if (PTUNIT)
add_subdirectory(ptunit)
endif (PTUNIT)
if (PTT)
add_subdirectory(test)
endif (PTT)
if (MAN)
add_subdirectory(doc/man)
endif (MAN)
if (SIDEBAND)
add_subdirectory(sideband)
endif (SIDEBAND)
if (PEVENT)
add_subdirectory(pevent)
endif (PEVENT)

107
CONTRIBUTING Executable file
View File

@ -0,0 +1,107 @@
Contributing to this Project
============================
## License
This project is licensed under the terms and conditions of the 3-Clause BSD
[LICENSE](LICENSE). By contributing to this project, you agree that you are
providing your contribution under the terms and conditions of that license.
## Patches
We accept patches to this project as pull requests on GitHub. When submitting
patches, please keep each patch self-contained and as small as possible. Please
address one topic per patch series. Intermediate patches must build without
errors (with DEVBUILD=ON) and not introduce test fails. Please describe what
each patch is doing in its commit message.
If you are contributing a patch series that addresses a GitHub Issue, the last
patch in the series should have 'fixes #<issue>' in its commit-message.
If the patch series addresses a bug that is not tracked, please provide a
detailed description of the issue in the commit-message, ideally with a
description of the 'before' and 'after' behavior.
The patch series should contain regression tests either as PTT tests or as
ptunit tests. Please make sure that all tests are passing. This may require
re-ordering patches to introduce the regression test after the issue was fixed.
If the patch series adds a new feature, please make sure to add documentation.
Prior to submitting this type of contribution, it may be a good idea to first
discuss the feature as a GitHub issue or via email before implementing it.
This project is using the Linux coding style.
## Sign Your Patch
Please use the sign-off line at the end of each patch. Your signature
certifies that you wrote the patch or otherwise have the right to pass
it on as an open-source patch. The rules are pretty simple: if you can
certify the below (from
[developercertificate.org](http://developercertificate.org/)):
```
Developer Certificate of Origin
Version 1.1
Copyright (C) 2004, 2006 The Linux Foundation and its contributors.
660 York Street, Suite 102,
San Francisco, CA 94110 USA
Everyone is permitted to copy and distribute verbatim copies of this
license document, but changing it is not allowed.
Developer's Certificate of Origin 1.1
By making a contribution to this project, I certify that:
(a) The contribution was created in whole or in part by me and I
have the right to submit it under the open source license
indicated in the file; or
(b) The contribution is based upon previous work that, to the best
of my knowledge, is covered under an appropriate open source
license and I have the right under that license to submit that
work with modifications, whether created in whole or in part
by me, under the same open source license (unless I am
permitted to submit under a different license), as indicated
in the file; or
(c) The contribution was provided directly to me by some other
person who certified (a), (b) or (c) and I have not modified
it.
(d) I understand and agree that this project and the contribution
are public and that a record of the contribution (including all
personal information I submit with it, including my sign-off) is
maintained indefinitely and may be redistributed consistent with
this project or the open source license(s) involved.
```
Then you just add a line to every git commit message:
Signed-off-by: Joe Smith <joe.smith@email.com>
Use your real name (sorry, no pseudonyms or anonymous contributions.)
If you set your `user.name` and `user.email` git configs, you can sign your
commit automatically with `git commit -s`.
## Reporting Issues
If you want to report an issue or bug, please report them via the GitHub Issues
tracker.
When reporting a bug, please provide the steps to reproduce it with the ptdump
and ptxed tools contained in the tree. Please include the command-line that was
used and the exact error message. You may also attach a trace file and the
binaries necessary for reproducing the issue or write a small PTT test to
demonstrate the issue.
When providing trace snippets, please provide a few extra packets of context.
Please also provide the processor family and model on which the trace was
recorded and the version of the decoder that was used to decode the trace.

24
LICENSE Normal file
View File

@ -0,0 +1,24 @@
Copyright (c) 2013-2018, 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.

79
README Normal file
View File

@ -0,0 +1,79 @@
Intel(R) Processor Trace Decoder Library
========================================
The Intel Processor Trace (Intel PT) Decoder Library is Intel's reference
implementation for decoding Intel PT. It can be used as a standalone library or
it can be partially or fully integrated into your tool.
The library comes with a set of sample tools built on top of it and a test
system built on top of the sample tools. The samples demonstrate how to use the
library and may serve as a starting point for integrating the library into your
tool.
Go to https://software.intel.com/en-us/intel-platform-analysis-library for
support of upcoming (non-public) processors (NDA required).
Contents
--------
README this file
libipt A packet encoder/decoder library
Optional Contents and Samples
-----------------------------
ptdump Example implementation of a packet dumper
ptxed Example implementation of a trace disassembler
pttc A trace test generator
ptunit A simple unit test system
sideband A sideband correlation library
pevent A library for reading/writing Linux perf event records
script A collection of scripts
test A collection of tests
include A collection of substitute headers
doc A document describing the build
A document describing how to get started
A document describing the usage of the decoder library
A document describing how to capture trace
A document describing pttc
doc/man Man pages for the encoder/decoder library
Dependencies
------------
We use cmake for building.
cmake The cross-platform open-source build system.
http://www.cmake.org
Other packages you need for some of the above optional components.
xed The Intel x86 instruction encoder and decoder.
https://github.com/intelxed/xed
This is needed to build and run ptxed.
yasm The Yasm Modular Assembler
http://github.com/yasm
This is needed to run pttc.
pandoc A universal document converter
http://pandoc.org
This is needed for man pages.

93
doc/getting_started.md Executable file
View File

@ -0,0 +1,93 @@
Getting Started {#start}
========================
<!---
! Copyright (c) 2013-2018, 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.
!-->
This chapter gives a brief introduction into the sample tools using one of the
tests as example. It assumes that you are already familiar with Intel(R)
Processor Trace (Intel PT) and that you already built the decoder library and
the sample tools. For detailed information about Intel PT, please refer to
chapter 11 of the Intel Architecture Instruction Set Extensions Programming
Reference at http://www.intel.com/products/processor/manuals/.
Start by compiling the loop-tnt test. It consists of a small assembly program
with interleaved Intel PT directives:
$ pttc test/src/loop-tnt.ptt
loop-tnt-ptxed.exp
loop-tnt-ptdump.exp
This produces the following output files:
loop-tnt.lst a yasm assembly listing file
loop-tnt.bin a raw binary file
loop-tnt.pt a Intel PT file
loop-tnt-ptxed.exp the expected ptxed output
loop-tnt-ptdump.exp the expected ptdump output
The latter two files are generated based on the `@pt .exp(<tool>)` directives
found in the `.ptt` file. They are used for automated testing. See
script/test.bash for details on that.
Use `ptdump` to dump the Intel PT packets:
$ ptdump loop-tnt.pt
0000000000000000 psb
0000000000000010 fup 3: 0x0000000000100000, ip=0x0000000000100000
0000000000000017 mode.exec cs.d=0, cs.l=1 (64-bit mode)
0000000000000019 psbend
000000000000001b tnt8 !!.
000000000000001c tip.pgd 3: 0x0000000000100013, ip=0x0000000000100013
The ptdump tool takes an Intel PT file as input and dumps the packets in
human-readable form. The number on the very left is the offset into the Intel
PT packet stream in hex. This is followed by the packet opcode and payload.
Use `ptxed` for reconstructing the execution flow. For this, you need the Intel
PT file as well as the corresponding binary image. You need to specify the load
address given by the org directive in the .ptt file when using a raw binary
file.
$ ptxed --pt loop-tnt.pt --raw loop-tnt.bin:0x100000
0x0000000000100000 mov rax, 0x0
0x0000000000100007 jmp 0x10000d
0x000000000010000d cmp rax, 0x1
0x0000000000100011 jle 0x100009
0x0000000000100009 add rax, 0x1
0x000000000010000d cmp rax, 0x1
0x0000000000100011 jle 0x100009
0x0000000000100009 add rax, 0x1
0x000000000010000d cmp rax, 0x1
0x0000000000100011 jle 0x100009
[disabled]
Ptxed prints disassembled instructions in execution order as well as status
messages enclosed in brackets.

197
doc/howto_build.md Executable file
View File

@ -0,0 +1,197 @@
Building the Intel(R) Processor Trace (Intel PT) Decoder Library and Samples {#build}
============================================================================
<!---
! Copyright (c) 2013-2018, 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.
!-->
This chapter gives step-by-step instructions for building the library and the
sample tools using cmake. For detailed information on cmake, see
http://www.cmake.org.
## Configuration
Besides the standard cmake options of build type and install directory, you will
find project-specific options for enabling optional features, optional
components, or optional build variants.
### Optional Components
By default, only the decoder library is built. Other components can be enabled
by setting the respective cmake variable to ON.
The following optional components are availble:
PTUNIT A simple unit test framework.
A collection of unit tests for libipt.
PTDUMP A packet dumper example.
PTXED A trace disassembler example.
PTTC A trace test generator.
SIDEBAND A sideband correlation library
PEVENT Support for the Linux perf_event sideband format.
This feature requires the linux/perf_event.h header.
### Optional Features
Features are enabled by setting the respective FEATURE_<name> cmake variable.
This causes the FEATURE_<name> pre-processor macro to be defined and may also
cause additional source files to be compiled and additional libraries to be
linked.
Features are enabled globally and will be used by all components that support
the feature. The following features are supported:
FEATURE_ELF Support for the ELF object format.
This feature requires the elf.h header.
FEATURE_THREADS Support some amount of multi-threading.
This feature makes image functions thread-safe.
### Build Variants
Some build variants depend on libraries or header files that may not be
available on all supported platforms.
GCOV Support for code coverage using libgcov.
This build variant requires libgcov and is not availble
on Windows.
DEVBUILD Enable compiler warnings and turn them into errors.
### Version Settings
The major and minor version numbers are set in the sources and must be changed
there. You can set the build number and an arbitrary extension string.
build.
PT_VERSION_BUILD The build number.
Defaults to zero.
PT_VERSION_EXT An arbitrary version extension string.
Defaults to the empty string.
### Dependencies
In order to build ptxed, the location of the XED library and the XED header
files must be specified.
XED_INCLUDE Path to the directory containing the XED header files.
XED_LIBDIR Path to the directory containing the XED library.
When using XED from a PIN distribution, the respective directories are located
in `extras/xed2-<arch>/`.
## Building on Linux``*`` and OS X``*``
We recommend out-of-tree builds. Start by creating the destination directory
and navigating into it:
$ mkdir -p /path/to/dest
$ cd /path/to/dest
From here, call cmake with the top-level source directory as argument. You may
already pass some or all of the cmake variables as arguments to cmake. Without
arguments, cmake uses default values.
$ cmake /path/to/src
If you have not passed values for XED_INCLUDE or XED_LIBDIR, you need to
configure them now if you want to build ptxed. You may also use this command to
change the configuration at any time later on.
$ make edit_cache
After configuring the cmake cache, you can build either specific targets or
everything using one of:
$ make <target>
$ make
Use the help make target to learn about available make targets:
$ make help
## Building on Windows``*``
We recommend using the cmake GUI. After starting the cmake GUI, fill in the
following fields:
Where is the source code: Path to the top-level source directory.
Where to build the binaries: Path to the destination directory.
We recommend out-of-tree builds, so the build directory should not be the same
as or below the source directory. After this first configuration step, press
the
Configure
button and select the builder you want to use.
Cmake will now populate the remainder of the window with configuration options.
Please make sure to specify at least XED_INCLUDE and XED_LIBDIR if you want to
build ptxed. After completing the configuration, press the
Generate
button. If you selected a Visual Studio generator in the first step, cmake will
now generate a Visual Studio solution. You can repeat this step if you want to
change the configuration later on. Beware that you always need to press the
Generate button after changing the configuration.
In the case of a Visual Studio generator, you may now open the generated Visual
Studio solution and build the library and samples.

628
doc/howto_capture.md Normal file
View File

@ -0,0 +1,628 @@
Capturing Intel(R) Processor Trace (Intel PT) {#capture}
=============================================
<!---
! Copyright (c) 2015-2018, 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.
!-->
This chapter describes how to capture Intel PT for processing with libipt. For
illustration, we use the sample tools ptdump and ptxed. We assume that they are
configured with:
* PEVENT=ON
* FEATURE_ELF=ON
## Capturing Intel PT on Linux
Starting with version 4.1, the Linux kernel supports Intel PT via the perf_event
kernel interface. Starting with version 4.3, the perf user-space tool will
support Intel PT as well.
### Capturing Intel PT via Linux perf_event
We start with setting up a perf_event_attr object for capturing Intel PT. The
structure is declared in `/usr/include/linux/perf_event.h`.
The Intel PT PMU type is dynamic. Its value can be read from
`/sys/bus/event_source/devices/intel_pt/type`.
~~~{.c}
struct perf_event_attr attr;
memset(&attr, 0, sizeof(attr));
attr.size = sizeof(attr);
attr.type = <read type>();
attr.exclude_kernel = 1;
...
~~~
Once all desired fields have been set, we can open a perf_event counter for
Intel PT. See `perf_event_open(2)` for details. In our example, we configure
it for tracing a single thread.
The system call returns a file descriptor on success, `-1` otherwise.
~~~{.c}
int fd;
fd = syscall(SYS_perf_event_open, &attr, <pid>, -1, -1, 0);
~~~
The Intel PT trace is captured in the AUX area, which has been introduced with
kernel 4.1. The DATA area contains sideband information such as image changes
that are necessary for decoding the trace.
In theory, both areas can be configured as circular buffers or as linear buffers
by mapping them read-only or read-write, respectively. When configured as
circular buffer, new data will overwrite older data. When configured as linear
buffer, the user is expected to continuously read out the data and update the
buffer's tail pointer. New data that do not fit into the buffer will be
dropped.
When using the AUX area, its size and offset have to be filled into the
`perf_event_mmap_page`, which is mapped together with the DATA area. This
requires the DATA area to be mapped read-write and hence configured as linear
buffer. In our example, we configure the AUX area as circular buffer.
Note that the size of both the AUX and the DATA area has to be a power of two
pages. The DATA area needs one additional page to contain the
`perf_event_mmap_page`.
~~~{.c}
struct perf_event_mmap_page *header;
void *base, *data, *aux;
base = mmap(NULL, (1+2**n) * PAGE_SIZE, PROT_WRITE, MAP_SHARED, fd, 0);
if (base == MAP_FAILED)
return <handle data mmap error>();
header = base;
data = base + header->data_offset;
header->aux_offset = header->data_offset + header->data_size;
header->aux_size = (2**m) * PAGE_SIZE;
aux = mmap(NULL, header->aux_size, PROT_READ, MAP_SHARED, fd,
header->aux_offset);
if (aux == MAP_FAILED)
return <handle aux mmap error>();
~~~
### Capturing Intel PT via the perf user-space tool
Starting with kernel 4.3, the perf user-space tool can be used to capture Intel
PT with the `intel_pt` event. See tools/perf/Documentation in the Linux kernel
tree for further information. In this text, we describe how to use the captured
trace with the ptdump and ptxed sample tools.
We start with capturing some Intel PT trace using the `intel_pt` event. Note
that when collecting system-wide (`-a`) trace, we need context switch events
(`--switch-events`) to decode the trace. See `perf-record(1)` for details.
~~~{.sh}
$ perf record -e intel_pt//[uk] [--per-thread] [-a --switch-events] -T -- ls
[ perf record: Woken up 1 times to write data ]
[ perf record: Captured and wrote 0.384 MB perf.data ]
~~~
This generates a file called `perf.data` that contains the Intel PT trace, the
sideband information, and some metadata. To process the trace with ptxed, we
extract the Intel PT trace into one file per thread or cpu.
Looking at the raw trace dump of `perf script -D`, we notice
`PERF_RECORD_AUXTRACE` records. The raw Intel PT trace is contained directly
after such records. We can extract it with the `dd` command. The arguments to
`dd` can be computed from the record's fields. This can be done automatically,
for example with an AWK script.
~~~{.awk}
/PERF_RECORD_AUXTRACE / {
offset = strtonum($1)
hsize = strtonum(substr($2, 2))
size = strtonum($5)
idx = strtonum($11)
ofile = sprintf("perf.data-aux-idx%d.bin", idx)
begin = offset + hsize
cmd = sprintf("dd if=perf.data of=%s conv=notrunc oflag=append ibs=1 \
skip=%d count=%d status=none", ofile, begin, size)
system(cmd)
}
~~~
The libipt tree contains such a script in `script/perf-read-aux.bash`.
If we recorded in snapshot mode (perf record -S), we need to extract the Intel
PT trace into one file per `PERF_RECORD_AUXTRACE` record. This can be done with
an AWK script similar to the one above. Use `script/perf-read-aux.bash -S` when
using the script from the libipt tree.
In addition to the Intel PT trace, we need sideband information that describes
process creation and termination, context switches, and memory image changes.
This sideband information needs to be processed together with the trace. We
therefore extract the sideband information from `perf.data`. This can again be
done automatically with an AWK script:
~~~{.awk}
function handle_record(ofile, offset, size) {
cmd = sprintf("dd if=%s of=%s conv=notrunc oflag=append ibs=1 skip=%d " \
"count=%d status=none", file, ofile, offset, size)
if (dry_run != 0) {
print cmd
}
else {
system(cmd)
}
next
}
function handle_global_record(offset, size) {
ofile = sprintf("%s-sideband.pevent", file)
handle_record(ofile, offset, size)
}
function handle_cpu_record(cpu, offset, size) {
# (uint32_t) -1 = 4294967295
#
if (cpu == -1 || cpu == 4294967295) {
handle_global_record(offset, size);
}
else {
ofile = sprintf("%s-sideband-cpu%d.pevent", file, cpu)
handle_record(ofile, offset, size)
}
}
/PERF_RECORD_AUXTRACE_INFO/ { next }
/PERF_RECORD_AUXTRACE/ { next }
/PERF_RECORD_FINISHED_ROUND/ { next }
/^[0-9]+ [0-9]+ 0x[0-9a-f]+ \[0x[0-9a-f]+\]: PERF_RECORD_/ {
cpu = strtonum($1)
begin = strtonum($3)
size = strtonum(substr($4, 2))
handle_cpu_record(cpu, begin, size)
}
/^[0-9]+ 0x[0-9a-f]+ \[0x[0-9a-f]+\]: PERF_RECORD_/ {
begin = strtonum($2)
size = strtonum(substr($3, 2))
handle_global_record(begin, size)
}
/^0x[0-9a-f]+ \[0x[0-9a-f]+\]: PERF_RECORD_/ {
begin = strtonum($1)
size = strtonum(substr($2, 2))
handle_global_record(begin, size)
}
~~~
The libipt tree contains such a script in `script/perf-read-sideband.bash`.
In Linux, sideband is implemented as a sequence of perf_event records. Each
record can optionally be followed by one or more samples that specify the cpu on
which the record was created or a timestamp that specifies when the record was
created. We use the timestamp sample to correlate sideband and trace.
To process those samples, we need to know exactly what was sampled so that we
can find the timestamp sample we are interested in. This information can be
found in the `sample_type` field of `struct perf_event_attr`. We can extract
this information from `perf.data` using the `perf evlist` command:
~~~{.sh}
$ perf evlist -v
intel_pt//u: [...] sample_type: IP|TID|TIME|CPU|IDENTIFIER [...]
dummy:u: [...] sample_type: IP|TID|TIME|IDENTIFIER [...]
~~~
The command lists two items, one for the `intel_pt` perf_event counter and one
for a `dummy` counter that is used for capturing context switch events.
We translate the sample_type string using `PERF_EVENT_SAMPLE_*` enumeration
constants defined in `/usr/include/linux/perf_event.h` into a single 64-bit
integer constant. For example, `IP|TID|TIME|CPU|IDENTIFIER` translates into
`0x10086`. Note that the `IP` sample type is reported but will not be attached
to perf_event records. The resulting constant is then supplied as argument to
the ptdump and ptxed option:
* --pevent:sample-type
The translation can be done automatically using an AWK script, assuming that we
already extracted the samle_type string:
~~~{.awk}
BEGIN { RS = "[|\n]" }
/^TID$/ { config += 0x00002 }
/^TIME$/ { config += 0x00004 }
/^ID$/ { config += 0x00040 }
/^CPU$/ { config += 0x00080 }
/^STREAM$/ { config += 0x00200 }
/^IDENTIFIER$/ { config += 0x10000 }
END {
if (config != 0) {
printf(" --pevent:sample_type 0x%x", config)
}
}
~~~
Sideband and trace are time-correlated. Since Intel PT and perf use different
time domains, we need a few parameters to translate between the two domains.
The parameters can be found in `struct perf_event_mmap_page`, which is declared
in `/usr/include/linux/perf_event.h`:
* time_shift
* time_mult
* time_zero
The header also documents how to calculate TSC from perf_event timestamps.
The ptdump and ptxed sample tools do this translation but we need to supply the
parameters via corresponding options:
* --pevent:time-shift
* --pevent:time-mult
* --pevent:time-zero
We can extract this information from the PERF_RECORD_AUXTRACE_INFO record. This
is an artificial record that the perf tool synthesizes when capturing the trace.
We can view it using the `perf script` command:
~~~{.sh}
$ perf script --no-itrace -D | grep -A14 PERF_RECORD_AUXTRACE_INFO
0x1a8 [0x88]: PERF_RECORD_AUXTRACE_INFO type: 1
PMU Type 6
Time Shift 10
Time Muliplier 642
Time Zero 18446744056970350213
Cap Time Zero 1
TSC bit 0x400
NoRETComp bit 0x800
Have sched_switch 0
Snapshot mode 0
Per-cpu maps 1
MTC bit 0x200
TSC:CTC numerator 0
TSC:CTC denominator 0
CYC bit 0x2
~~~
This will also give us the values for `cpuid[0x15].eax` and `cpuid[0x15].ebx`
that we need for tracking time with `MTC` and `CYC` packets in `TSC:CTC
denominator` and `TSC:CTC numerator` respectively. On processors that do not
support `MTC` and `CYC`, the values are reported as zero.
When decoding system-wide trace, we need to correlate context switch sideband
events with decoded instructions from the trace to find a suitable location for
switching the traced memory image for the scheduled-in process. The heuristics
we use rely on sufficiently precise timing information. If timing information
is too coarse, we might map the contex switch to the wrong location.
When tracing ring-0, we use any code in kernel space. Since the kernel is
mapped into every process, this is good enough as long as we are not interested
in identifying processes and threads in the trace. To allow ptxed to
distinguish kernel from user addresses, we provide the start address of the
kernel via the option:
* --pevent:kernel-start
We can find the address in `kallsyms` and we can extract it automatically using
an AWK script:
~~~{.awk}
function update_kernel_start(vaddr) {
if (vaddr < kernel_start) {
kernel_start = vaddr
}
}
BEGIN { kernel_start = 0xffffffffffffffff }
/^[0-9a-f]+ T _text$/ { update_kernel_start(strtonum("0x" $1)) }
/^[0-9a-f]+ T _stext$/ { update_kernel_start(strtonum("0x" $1)) }
END {
if (kernel_start < 0xffffffffffffffff) {
printf(" --pevent:kernel-start 0x%x", kernel_start)
}
}
~~~
When not tracing ring-0, we use a region where tracing has been disabled
assuming that tracing is disabled due to a ring transition.
To apply processor errata we need to know on which processor the trace was
collected and provide this information to ptxed using the
* --cpu
option. We can find this information in the `perf.data` header using the `perf
script --header-only` command:
~~~{.sh}
$ perf script --header-only | grep cpuid
# cpuid : GenuineIntel,6,61,4
~~~
The libipt tree contains a script in `script/perf-get-opts.bash` that computes
all the perf_event related options from `perf.data` and from previously
extracted sideband information.
The kernel uses special filenames in `PERF_RECORD_MMAP` and `PERF_RECORD_MMAP2`
records to indicate pseudo-files that can not be found directly on disk. One
such special filename is
* [vdso]
which corresponds to the virtual dynamic shared object that is mapped into every
process. See `vdso(7)` for details. Depending on the installation there may be
different vdso flavors. We need to specify the location of each flavor that is
referenced in the trace via corresponding options:
* --pevent:vdso-x64
* --pevent:vdso-x32
* --pevent:vdso-ia32
The perf tool installation may provide utilities called:
* perf-read-vdso32
* perf-read-vdsox32
for reading the ia32 and the x32 vdso flavors. If the native flavor is not
specified or the specified file does not exist, ptxed will copy its own vdso
into a temporary file and use that. This may not work for remote decode, nor
can ptxed provide other vdso flavors.
Let's put it all together. Note that we use the `-m` option of
`script/perf-get-opts.bash` to specify the master sideband file for the cpu on
which we want to decode the trace. We further enable tick events for finer
grain sideband correlation.
~~~{.sh}
$ perf record -e intel_pt//u -T --switch-events -- grep -r foo /usr/include
[ perf record: Woken up 18 times to write data ]
[ perf record: Captured and wrote 30.240 MB perf.data ]
$ script/perf-read-aux.bash
$ script/perf-read-sideband.bash
$ ptdump $(script/perf-get-opts.bash) perf.data-aux-idx0.bin
[...]
$ ptxed $(script/perf-get-opts.bash -m perf.data-sideband-cpu0.pevent)
--pevent:vdso... --event:tick --pt perf.data-aux-idx0.bin
[...]
~~~
When tracing ring-0 code, we need to use `perf-with-kcore` for recording and
supply the `perf.data` directory as additional argument after the `record` perf
sub-command. When `perf-with-kcore` completes, the `perf.data` directory
contains `perf.data` as well as a directory `kcore_dir` that contains copies of
`/proc/kcore` and `/proc/kallsyms`. We need to supply the path to `kcore_dir`
to `script/perf-get-opts.bash` using the `-k` option.
~~~{.sh}
$ perf-with-kcore record dir -e intel_pt// -T -a --switch-events -- sleep 10
[ perf record: Woken up 26 times to write data ]
[ perf record: Captured and wrote 54.238 MB perf.data ]
Copying kcore
Done
$ cd dir
$ script/perf-read-aux.bash
$ script/perf-read-sideband.bash
$ ptdump $(script/perf-get-opts.bash) perf.data-aux-idx0.bin
[...]
$ ptxed $(script/perf-get-opts.bash -k kcore_dir
-m perf.data-sideband-cpu0.pevent)
--pevent:vdso... --event:tick --pt perf.data-aux-idx0.bin
[...]
~~~
#### Remote decode
To decode the recorded trace on a different system, we copy all the files
referenced in the trace to the system on which the trace is being decoded and
point ptxed to the respective root directory using the option:
* --pevent:sysroot
Ptxed will prepend the sysroot directory to every filename referenced in
`PERF_RECORD_MMAP` and `PERF_RECORD_MMAP2` records.
Note that like most configuration options, the `--pevent.sysroot` option needs
to precede `--pevent:primary` and `-pevent:secondary` options.
We can extract the referenced file names from `PERF_RECORD_MMAP` and
`PERF_RECORD_MMAP2` records in the output of `perf script -D` and we can
automatically copy the files using an AWK script:
~~~{.awk}
function dirname(file) {
items = split(file, parts, "/", seps)
delete parts[items]
dname = ""
for (part in parts) {
dname = dname seps[part-1] parts[part]
}
return dname
}
function handle_mmap(file) {
# ignore any non-absolute filename
#
# this covers pseudo-files like [kallsyms] or [vdso]
#
if (substr(file, 0, 1) != "/") {
return
}
# ignore kernel modules
#
# we rely on kcore
#
if (match(file, /\.ko$/) != 0) {
return
}
# ignore //anon
#
if (file == "//anon") {
return
}
dst = outdir file
dir = dirname(dst)
system("mkdir -p " dir)
system("cp " file " " dst)
}
/PERF_RECORD_MMAP/ { handle_mmap($NF) }
~~~
The libipt tree contains such a script in `script/perf-copy-mapped-files.bash`.
It will also read the vdso flavors for which the perf installation provides
readers.
We use the `-s` option of `script/perf-get-opts.bash` to have it generate
options for the sysroot directory and for the vdso flavors found in that
sysroot.
For the remote decode case, we thus get (assuming kernel and user tracing on a
64-bit system):
~~~{.sh}
[record]
$ perf-with-kcore record dir -e intel_pt// -T -a --switch-events -- sleep 10
[ perf record: Woken up 26 times to write data ]
[ perf record: Captured and wrote 54.238 MB perf.data ]
Copying kcore
Done
$ cd dir
$ script/perf-copy-mapped-files.bash -o sysroot
[copy dir to remote system]
[decode]
$ script/perf-read-aux.bash
$ script/perf-read-sideband.bash
$ ptdump $(script/perf-get-opts.bash -s sysroot) perf.data-aux-idx0.bin
[...]
$ ptxed $(script/perf-get-opts.bash -s sysroot -k kcore_dir
-m perf.data-sideband-cpu0.pevent)
--event:tick --pt perf.data-aux-idx0.bin
[...]
~~~
#### Troubleshooting
##### Sideband correlation and `no memory mapped at this address` errors
If timing information in the trace is too coarse, we may end up applying
sideband events too late. This typically results in `no memory mapped at this
address` errors.
Try to increase timing precision by increasing the MTC frequency or by enabling
cycle-accurate tracing. If this does not help or is not an option, ptxed can
process sideband events earlier than timing information indicates. Supply a
suitable value to ptxed's option:
* --pevent:tsc-offset
This option adds its argument to the timing information in the trace and so
causes sideband events to be processed earlier. There is logic in ptxed to
determine a suitable location in the trace for applying some sideband events.
For example, a context switch event is postponed until tracing is disabled or
enters the kernel.
Those heuristics have their limits, of course. If the tsc offset is chosen too
big, ptxed may end up mapping a sideband event to the wrong kernel entry.
##### Sideband and trace losses leading to decode errors
The perf tool reads trace and sideband while it is being collected and stores it
in `perf.data`. If it fails to keep up, perf_event records or trace may be
lost. The losses are indicated in the sideband:
* `PERF_RECORD_LOST` indicates sideband losses
* `PERF_RECORD_AUX.TRUNCATED` indicates trace losses
Sideband losses may go unnoticed or may lead to decode errors. Typical errors
are:
* `no memory mapped at this address`
* `decoder out of sync`
* `trace stream does not match query`
Ptxed diagnoses sideband losses as warning both to stderr and to stdout
interleaved with the normal output.
Trace losses may go unnoticed or may lead to all kinds of errors. Ptxed
diagnoses trace losses as warning to stderr.
### Capturing Intel PT via Simple-PT
The Simple-PT project on github supports capturing Intel PT on Linux with an
alternative kernel driver. The spt decoder supports sideband information.
See the project's page at https://github.com/andikleen/simple-pt for more
information including examples.

1271
doc/howto_libipt.md Normal file

File diff suppressed because it is too large Load Diff

482
doc/howto_pttc.md Executable file
View File

@ -0,0 +1,482 @@
Testing the Intel(R) Processor Trace (Intel PT) Decoder Library and Samples {#pttc}
===========================================================================
<!---
! Copyright (c) 2013-2018, 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.
!-->
This chapter documents how to use the pttc tool to generate and run tests.
Pttc takes a yasm assembly file and creates a Processor Trace stream from
special directives in its input.
Usage
-----
$ pttc path/to/file.ptt
If no error occurs, the following files will be generated in the current working
directory:
file.lst
file.bin
file.pt
file-<tool>.exp
file-<src>.sb
The `.lst` and `.bin` files are generated by a call to yasm. The `.pt` file
contains the Processor Trace and the `.exp` files contain the content of the
comments after the `.exp` directive for tool `<tool>` (see below). The `.sb`
files contain sideband infomrmation from source `<src>` (see below).
Pttc prints the filenames of the generated `.exp` and `.sb` files to stdout.
Syntax
------
Pttc allows annotations in the comments of yasm assembler source files. The
parser recognizes all comments that contain the `@pt` directive marker.
Every pt directive can be preceded by a label name followed by a colon (`:`).
Refer to the description of the `.exp()` and `.sb()` directives below on how to
use these labels.
The general syntax for pt directives is as follows:
@pt [label:]directive([arguments])
### Intel PT directives
This section lists the directives that are understood by pttc.
#### psb, psbend, pad, ovf, stop
@pt psb()
@pt psbend()
@pt pad()
@pt ovf()
@pt stop()
These packets do not have any arguments and correspond to the packets from the
specification.
#### tnt, tnt64
@pt tnt(args)
@pt tnt64(args)
The arguments of the tnt and tnt64 packets is a list of Takens `t` and
Not-Takens `n`. For better readability an arbitrary number of blanks and dots
can be intervened.
It is an error if no characters, only blanks or dots, or other characters are in
the payload. Additionally for the TNT packet and the TNT64 packet it is an error
to have more than 6 and more than 47 t's or n's in the payload, respectively.
#### tip, tip.pge, tip.pgd, fup
@pt tip(ipc: addr)
@pt tip.pge(ipc: addr)
@pt tip.pgd(ipc: addr)
@pt fup(ipc: addr)
These packets accept arbitrary addresses. `Addr` must be a parsable integer or a
valid label name. `Ipc` specifies the IP compression bits as integer number.
If `addr` is given as a label, the address is truncated according to the IP
bytes value given in `ipc`. Otherwise the address needs to be a zero-extended
integer no bigger than specified in `ipc`.
#### mode.exec, mode.tsx
@pt mode.exec(mode)
@pt mode.tsx(state)
`Mode` must be either `16bit` or `32bit` or `64bit`; `state` must be `begin` or
`abort` or `commit`.
#### pip
@pt pip(addr[, nr])
Addr is the value that was written to CR3.
If nr is specified after addr, the non-root bit is set.
#### tsc
@pt tsc(value)
Value is the timestamp.
#### cbr
@pt cbr(value)
Value is the core/bus ratio.
#### tma
@pt tma(ctc, fc)
Ctc is the 16bit crystal clock component.
Fc is the 9bit fast counter component.
#### mtc
@pt mtc(value)
Value is the 8bit crystal clock component.
#### cyc
@pt cyc(value)
Value is the cycle count.
#### vmcs
@pt vmcs(value)
Value is the VMCS base address. Beware that only bits 12 to 51 will be used.
The rest will be silently ignored.
#### mnt
@pt mnt(value)
Value is the 8-byte packet payload represented as 64-bit little-endian number.
#### exstop
@pt exstop([ip])
If ip is specified, the IP bit in the packet opcode is set, it is clear
otherwise.
#### mwait
@pt mwait(hints, ext)
Hints is the 4-byte mwait hints argument in eax. Ext is the 4-byte extensions
argument in ecx.
#### pwre
@pt pwre(c-state[, hw])
C-state is a thread C-state with optional sub C-state in the format
`c<state>[.<sub>]` where both `<state>` and `<sub>` are decimal integer values
between 0 and 15. If the sub C-state is not specified, it defaults to c0.
If hw is specified, the C-state entry was initiated by hardware.
#### pwrx
@pt pwrx(wr: last, deepest)
Wr is the wake reason. It must be `int`, `st`, or `hw`.
Last and deepest are the last and deepest achieved core C-state in the format
`c<state>` where `<state>` is a decimal integer value between 0 and 15.
#### ptw
@pt ptw(size: payload[, ip])
Size is the payload size; it must be 0 or 1. Payload is the unsigned integer
payload. If ip is specified, the IP bit in the packet opcode is set, it is
clear otherwise.
#### .exp
@pt .exp([tool])
Every occurrence of this directive prints all the lines, following this
directive, to a `file[-tool].exp`.
The first occurrence of this directive stops processing of other directives.
In order to have a valid yasm file, it is necessary to put the expected output
into yasm comments (with the semi-colon character (`;`)). Any character up to
(and including) the semi-colon is not printed to the `.exp` file. Trailing white
space is removed from each line.
Comments are made with the `#` character and go to the end of line. Comments
and whitespace before comments are not printed in the `.exp` file.
Each line that contains no yasm comment at all is not printed to the exp file.
Empty lines can be used to structure the expected output text.
In `.exp` files and in sideband directives, the address of a yasm label can be
substituted using:
%[?0]label[.<number>].
Labels are prefixed with `%`, for example, `%%label`. A label name can consist
of alphanumeric characters and underscores. Labels must be unique. The address
of label will be substituted with a hex number including leading `0x`.
Prefixing the label with `0`, for example `%0label`, prints the address with
leading zeroes using 16 hex digits plus the leading `0x`.
The least significant `n` bytes of an address can be masked by appending `.n` to
the label. For example, `%%label.2` with `label` = `0xffffff004c` is printed as
`0x4c`.
Prefixing the label with `?` in combination with masking replaces the masked out
parts with `?` using 16 digits for the address plus the leading `0x`. The
remaining number is zero extended. For example, `%?label.2` with `label` =
`0xc0001` is printed as `0x????????????0001`.
The packet number of pt directives can also be substituted in the output. These
numbers are printed in decimal. The syntax is as follows:
%label
### Special Labels
There is a special label for the byte offset after the last packet: `%%eos`.
Labels in sections are relative to the section's vstart address. PTTC also adds
the following special section labels:
* *section_<name>_start* gives the section's offset in the binary file
* *section_<name>_vstart* gives the virtual base address of the mapped section
* *section_<name>_length* gives the size of the section in bytes
Beware that PTTC does not support switching back and forth between sections.
### Sideband Directives
This section lists the sideband directives that are understood by pttc.
#### primary/secondary [requires SIDEBAND]
@sb primary(format [,src])
@sb secondary(format [,src])
Every occurrence of this directive switches the current sideband file to
`file[-src]-format-primary.sb` or `file[-src]-format-secondary.sb` respectively.
Every subsequent sideband directive will write to the current sideband file.
A primary sideband file is directly related to the trace. For example, it may
contain the sideband information for the traced cpu. A secondary sideband file
is indirectly related to the trace. For example, it may contain the sideband
information for other cpus on the system.
Sideband directive and Intel PT directives can be mixed.
#### raw [requires SIDEBAND]
@sb raw-8(value)
@sb raw-16(value)
@sb raw-32(value)
@sb raw-64(value)
Writes a raw unsigned 8, 16, 32, or 64 bit value into the current sideband
stream.
#### pevent-sample_type [requires SIDEBAND, PEVENT]
@sb pevent-sample_type(t1[, t2[, t3[...]]])
Sets the perf_event sample_type for subsequent pevent sideband directives for
the current sideband file to the bit-wise or '|' of all arguments. Each
argument can be:
* *tid* representing PERF_SAMPLE_TID
* *time* representing PERF_SAMPLE_TIME
* *id* representing PERF_SAMPLE_ID
* *cpu* representing PERF_SAMPLE_CPU
* *stream* representing PERF_SAMPLE_STREAM_ID
* *identifier* representing PERF_SAMPLE_IDENTIFIER
* a 64bit unsigned integer representing a bit-mask of
enum perf_event_sample_format values
Subsequent perf event record generating directives must provide the specified
number of sample arguments in the above order order. The `tid` sample type
takes two arguments: a pid followed by a tid.
This directive may only be used before the first perf event record generating
directive.
#### pevent-mmap [requires SIDEBAND, PEVENT]
@sb pevent-mmap(pid, tid, addr, len, pgoff, filename[, samples])
Writes a PERF_RECORD_MMAP event into the current sideband stream describing the
mapping of filename.
The `samples` argument is a comma-separated list of samples corresponding to the
pevent-sample_type configuration.
#### pevent-mmap-section [requires SIDEBAND, PEVENT]
@sb pevent-mmap-section(name, pid, tid[, samples])
Writes a PERF_RECORD_MMAP event into the current sideband stream describing the
mapping of section `name` to its vstart address from its start address in the
test binary.
The `samples` argument is a comma-separated list of samples corresponding to the
pevent-sample_type configuration.
#### pevent-lost [requires SIDEBAND, PEVENT]
@sb pevent-lost(id, lost[, samples])
Writes a PERF_RECORD_LOST event into the current sideband stream describing the
loss of perf_event records.
The `samples` argument is a comma-separated list of samples corresponding to the
pevent-sample_type configuration.
#### pevent-comm [requires SIDEBAND, PEVENT]
@sb pevent-comm(pid, tid, comm[, samples])
@sb pevent-comm.exec(pid, tid, comm[, samples])
Writes a PERF_RECORD_COMM event into the current sideband stream describing the
command that is being traced.
The `samples` argument is a comma-separated list of samples corresponding to the
pevent-sample_type configuration.
#### pevent-exit [requires SIDEBAND, PEVENT]
@sb pevent-exit(pid, ppid, tid, ptid, time[, samples])
Writes a PERF_RECORD_EXIT event into the current sideband stream describing the
exiting of the current thread. The thread is still running in kernel space but
won't return to user space.
The `samples` argument is a comma-separated list of samples corresponding to the
pevent-sample_type configuration.
#### pevent-fork [requires SIDEBAND, PEVENT]
@sb pevent-fork(pid, ppid, tid, ptid, time[, samples])
Writes a PERF_RECORD_FORK event into the current sideband stream describing the
creation of a new thread or process. The event occurs in the context of the
parent thread.
The `samples` argument is a comma-separated list of samples corresponding to the
pevent-sample_type configuration.
#### pevent-aux [requires SIDEBAND, PEVENT]
@sb pevent-aux(offset, size, flags[, samples])
Writes a PERF_RECORD_AUX event into the current sideband stream describing that
new data landed in the aux buffer.
The `samples` argument is a comma-separated list of samples corresponding to the
pevent-sample_type configuration.
#### pevent-itrace-start [requires SIDEBAND, PEVENT]
@sb pevent-itrace-start(pid, tid[, samples])
Writes a PERF_RECORD_ITRACE_START event into the current sideband stream
describing that instruction tracing has started.
The `samples` argument is a comma-separated list of samples corresponding to the
pevent-sample_type configuration.
#### pevent-lost-samples [requires SIDEBAND, PEVENT]
@sb pevent-lost-samples(lost[, samples])
Writes a PERF_RECORD_LOST_SAMPLES event into the current sideband stream
describing a loss of sample records.
The `samples` argument is a comma-separated list of samples corresponding to the
pevent-sample_type configuration.
#### pevent-switch [requires SIDEBAND, PEVENT]
@sb pevent-switch.in([samples])
@sb pevent-switch.out([samples])
Writes a PERF_RECORD_SWITCH event into the current sideband stream describing a
switch into or out of context.
The `samples` argument is a comma-separated list of samples corresponding to the
pevent-sample_type configuration.
#### pevent-switch-cpu-wide [requires SIDEBAND, PEVENT]
@sb pevent-switch-cpu-wide.in(pid, tid[, samples])
@sb pevent-switch-cpu-wide.out(pid, tid[, samples])
Writes a PERF_RECORD_SWITCH_CPU_WIDE event into the current sideband stream
describing a switch into or out of context. The `pid` and `tid` arguments give
the process and thread id of the previous task.
The `samples` argument is a comma-separated list of samples corresponding to the
pevent-sample_type configuration.

147
doc/man/CMakeLists.txt Normal file
View File

@ -0,0 +1,147 @@
# Copyright (c) 2015-2018, 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.
file(MAKE_DIRECTORY ${MAN_OUTPUT_DIRECTORY}/man3)
find_program(PANDOC pandoc
DOC "Path to pandoc; used for building man pages."
)
function(add_man_page filename section function)
set(input ${CMAKE_CURRENT_SOURCE_DIR}/${filename})
set(output ${MAN_OUTPUT_DIRECTORY}/man${section}/${function}.${section})
add_custom_command(
OUTPUT ${output}
COMMAND ${PANDOC} -s -f markdown -t man -o ${output} ${input}
MAIN_DEPENDENCY ${filename}
)
endfunction(add_man_page)
function(install_man_page section function)
install(
FILES ${MAN_OUTPUT_DIRECTORY}/man${section}/${function}.${section}
DESTINATION ${CMAKE_INSTALL_MANDIR}/man${section}
)
endfunction(install_man_page)
function(add_man_page_alias section function alias)
set(output ${MAN_OUTPUT_DIRECTORY}/man${section}/${alias}.${section})
file(WRITE ${output} ".so man${section}/${function}.${section}\n")
install_man_page(${section} ${alias})
endfunction(add_man_page_alias)
set(MAN3_FUNCTIONS
pt_library_version
pt_config
pt_packet
pt_alloc_encoder
pt_enc_get_offset
pt_enc_get_config
pt_pkt_alloc_decoder
pt_pkt_sync_forward
pt_pkt_get_offset
pt_qry_alloc_decoder
pt_qry_sync_forward
pt_qry_get_offset
pt_qry_cond_branch
pt_qry_event
pt_qry_time
pt_image_alloc
pt_image_add_file
pt_image_remove_by_filename
pt_image_set_callback
pt_insn_alloc_decoder
pt_insn_sync_forward
pt_insn_get_offset
pt_insn_get_image
pt_insn_next
pt_iscache_alloc
pt_iscache_add_file
pt_iscache_read
pt_iscache_set_limit
pt_blk_alloc_decoder
pt_blk_sync_forward
pt_blk_get_offset
pt_blk_next
)
foreach (function ${MAN3_FUNCTIONS})
set(MAN_PAGES ${MAN_PAGES} ${MAN_OUTPUT_DIRECTORY}/man3/${function}.3)
add_man_page(${function}.3.md 3 ${function})
install_man_page(3 ${function})
endforeach ()
add_man_page_alias(3 pt_config pt_cpu_errata)
add_man_page_alias(3 pt_packet pt_enc_next)
add_man_page_alias(3 pt_packet pt_pkt_next)
add_man_page_alias(3 pt_alloc_encoder pt_free_encoder)
add_man_page_alias(3 pt_enc_get_offset pt_enc_sync_set)
add_man_page_alias(3 pt_enc_get_config pt_pkt_get_config)
add_man_page_alias(3 pt_enc_get_config pt_qry_get_config)
add_man_page_alias(3 pt_enc_get_config pt_insn_get_config)
add_man_page_alias(3 pt_enc_get_config pt_blk_get_config)
add_man_page_alias(3 pt_pkt_alloc_decoder pt_pkt_free_decoder)
add_man_page_alias(3 pt_pkt_sync_forward pt_pkt_sync_backward)
add_man_page_alias(3 pt_pkt_sync_forward pt_pkt_sync_set)
add_man_page_alias(3 pt_pkt_get_offset pt_pkt_get_sync_offset)
add_man_page_alias(3 pt_qry_alloc_decoder pt_qry_free_decoder)
add_man_page_alias(3 pt_qry_sync_forward pt_qry_sync_backward)
add_man_page_alias(3 pt_qry_sync_forward pt_qry_sync_set)
add_man_page_alias(3 pt_qry_get_offset pt_qry_get_sync_offset)
add_man_page_alias(3 pt_qry_cond_branch pt_qry_indirect_branch)
add_man_page_alias(3 pt_qry_time pt_qry_core_bus_ratio)
add_man_page_alias(3 pt_qry_time pt_insn_time)
add_man_page_alias(3 pt_qry_time pt_insn_core_bus_ratio)
add_man_page_alias(3 pt_qry_time pt_blk_time)
add_man_page_alias(3 pt_qry_time pt_blk_core_bus_ratio)
add_man_page_alias(3 pt_qry_event pt_insn_event)
add_man_page_alias(3 pt_qry_event pt_blk_event)
add_man_page_alias(3 pt_image_alloc pt_image_free)
add_man_page_alias(3 pt_image_alloc pt_image_name)
add_man_page_alias(3 pt_image_add_file pt_image_copy)
add_man_page_alias(3 pt_image_add_file pt_image_add_cached)
add_man_page_alias(3 pt_image_remove_by_filename pt_image_remove_by_asid)
add_man_page_alias(3 pt_insn_alloc_decoder pt_insn_free_decoder)
add_man_page_alias(3 pt_insn_sync_forward pt_insn_sync_backward)
add_man_page_alias(3 pt_insn_sync_forward pt_insn_sync_set)
add_man_page_alias(3 pt_insn_get_offset pt_insn_get_sync_offset)
add_man_page_alias(3 pt_insn_get_image pt_insn_set_image)
add_man_page_alias(3 pt_insn_get_image pt_blk_get_image)
add_man_page_alias(3 pt_insn_get_image pt_blk_set_image)
add_man_page_alias(3 pt_insn_next pt_insn)
add_man_page_alias(3 pt_iscache_alloc pt_iscache_free)
add_man_page_alias(3 pt_iscache_alloc pt_iscache_name)
add_man_page_alias(3 pt_blk_alloc_decoder pt_blk_free_decoder)
add_man_page_alias(3 pt_blk_sync_forward pt_blk_sync_backward)
add_man_page_alias(3 pt_blk_sync_forward pt_blk_sync_set)
add_man_page_alias(3 pt_blk_get_offset pt_blk_get_sync_offset)
add_man_page_alias(3 pt_blk_next pt_block)
add_custom_target(man ALL DEPENDS ${MAN_PAGES})

View File

@ -0,0 +1,96 @@
% PT_ALLOC_ENCODER(3)
<!---
! Copyright (c) 2015-2018, 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.
!-->
# NAME
pt_alloc_encoder, pt_free_encoder - allocate/free an Intel(R) Processor Trace
packet encoder
# SYNOPSIS
| **\#include `<intel-pt.h>`**
|
| **struct pt_packet_encoder \***
| **pt_alloc_encoder(const struct pt_config \**config*);**
|
| **void pt_free_encoder(struct pt_packet_encoder \**encoder*);**
Link with *-lipt*.
# DESCRIPTION
**pt_alloc_encoder**() allocates a new Intel Processor Trace (Intel PT) packet
encoder and returns a pointer to it. The packet encoder generates Intel PT
trace from *pt_packet* objects. See **pt_enc_next**(3).
The *config* argument points to a *pt_config* object. See **pt_config**(3).
The *config* argument will not be referenced by the returned encoder but the
trace buffer defined by the *config* argument's *begin* and *end* fields will.
The returned packet encoder is initially synchronized onto the beginning of the
trace buffer specified in its *config* argument. Use **pt_enc_sync_set**(3) to
move it to any other position inside the trace buffer.
**pt_free_encoder**() frees the Intel PT packet encoder pointed to by encoder*.
*The *encoder* argument must be NULL or point to an encoder that has been
*allocated by a call to **pt_alloc_encoder**().
# RETURN VALUE
**pt_alloc_encoder**() returns a pointer to a *pt_packet_encoder* object on
success or NULL in case of an error.
# EXAMPLE
~~~{.c}
int foo(const struct pt_config *config) {
struct pt_packet_encoder *encoder;
errcode;
encoder = pt_alloc_encoder(config);
if (!encoder)
return pte_nomem;
errcode = bar(encoder);
pt_free_encoder(encoder);
return errcode;
}
~~~
# SEE ALSO
**pt_config**(3), **pt_enc_sync_set**(3), **pt_enc_get_offset**(3),
**pt_enc_get_config**(3), **pt_enc_next**(3)

View File

@ -0,0 +1,98 @@
% PT_BLK_ALLOC_DECODER(3)
<!---
! Copyright (c) 2016-2018, 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.
!-->
# NAME
pt_blk_alloc_decoder, pt_blk_free_decoder - allocate/free an Intel(R) Processor
Trace block decoder
# SYNOPSIS
| **\#include `<intel-pt.h>`**
|
| **struct pt_block_decoder \***
| **pt_blk_alloc_decoder(const struct pt_config \**config*);**
|
| **void pt_blk_free_decoder(struct pt_block_decoder \**decoder*);**
Link with *-lipt*.
# DESCRIPTION
A block decoder decodes raw Intel Processor Trace (Intel PT) into a sequence of
blocks of instructions described by the *pt_block* structure. See
**pt_blk_next**(3).
**pt_blk_alloc_decoder**() allocates a new block decoder and returns a pointer
to it. The *config* argument points to a *pt_config* object. See
**pt_config**(3). The *config* argument will not be referenced by the returned
decoder but the trace buffer defined by the *config* argument's *begin* and
*end* fields will.
The returned block decoder needs to be synchronized onto the trace stream before
it can be used. To synchronize the decoder, use **pt_blk_sync_forward**(3),
**pt_blk_sync_backward**(3), or **pt_blk_sync_set**(3).
**pt_blk_free_decoder**() frees the Intel PT block decoder pointed to by
*decoder*. The *decoder* argument must be NULL or point to a decoder that has
been allocated by a call to **pt_blk_alloc_decoder**().
# RETURN VALUE
**pt_blk_alloc_decoder**() returns a pointer to a *pt_block_decoder* object on
success or NULL in case of an error.
# EXAMPLE
~~~{.c}
struct pt_block_decoder *decoder;
int errcode;
decoder = pt_blk_alloc_decoder(config);
if (!decoder)
return pte_nomem;
errcode = decode(decoder);
pt_blk_free_decoder(decoder);
return errcode;
~~~
# SEE ALSO
**pt_config**(3), **pt_blk_sync_forward**(3), **pt_blk_sync_backward**(3),
**pt_blk_sync_set**(3), **pt_blk_get_offset**(3), **pt_blk_get_sync_offset**(3),
**pt_blk_get_image**(3), **pt_blk_set_image**(3), **pt_blk_get_config**(3),
**pt_blk_time**(3), **pt_blk_core_bus_ratio**(3), **pt_blk_next**(3)

View File

@ -0,0 +1,82 @@
% PT_BLK_GET_OFFSET(3)
<!---
! Copyright (c) 2016-2018, 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.
!-->
# NAME
pt_blk_get_offset, pt_blk_get_sync_offset - get an Intel(R) Processor Trace
block decoder's current/synchronization trace buffer offset
# SYNOPSIS
| **\#include `<intel-pt.h>`**
|
| **int pt_blk_get_offset(const struct pt_block_decoder \**decoder*,**
| **uint64_t \**offset*);**
| **int pt_blk_get_sync_offset(const struct pt_block_decoder \**decoder*,**
| **uint64_t \**offset*);**
Link with *-lipt*.
# DESCRIPTION
**pt_blk_get_offset**() provides *decoder*'s current position as offset in
bytes from the beginning of *decoder*'s trace buffer in the unsigned integer
variable pointed to by *offset*.
**pt_blk_get_sync_offset**() provides *decoder*'s last synchronization point as
offset in bytes from the beginning of *decoder*'s trace buffer in the unsigned
integer variable pointed to by *offset*.
# RETURN VALUE
Both functions return zero on success or a negative *pt_error_code* enumeration
constant in case of an error.
# ERRORS
pte_invalid
: The *decoder* or *offset* argument is NULL.
pte_nosync
: *decoder* has not been synchronized onto the trace stream. Use
**pt_blk_sync_forward**(3), **pt_blk_sync_backward**(3), or
**pt_blk_sync_set**(3) to synchronize *decoder*.
# SEE ALSO
**pt_blk_alloc_decoder**(3), **pt_blk_free_decoder**(3),
**pt_blk_sync_forward**(3), **pt_blk_sync_backward**(3),
**pt_blk_sync_set**(3), **pt_blk_get_config**(3), **pt_blk_time**(3),
**pt_blk_core_bus_ratio**(3), **pt_blk_next**(3)

285
doc/man/pt_blk_next.3.md Normal file
View File

@ -0,0 +1,285 @@
% PT_BLK_NEXT(3)
<!---
! Copyright (c) 2016-2018, 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 NEXT 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.
!-->
# NAME
pt_blk_next, pt_block - iterate over blocks of traced instructions
# SYNOPSIS
| **\#include `<intel-pt.h>`**
|
| **struct pt_block;**
|
| **int pt_blk_next(struct pt_blk_decoder \**decoder*,**
| **struct pt_blk \**blk*, size_t *size*);**
|
| **int pt_blk_next(struct pt_block_decoder \**decoder*,**
| **struct pt_block \**block*, size_t *size*);**
Link with *-lipt*.
# DESCRIPTION
**pt_blk_next**() provides the next block of instructions in execution order,
which is described by the *pt_block* structure.
The *size* argument must be set to *sizeof(struct pt_block)*. The function will
provide at most *size* bytes of the *pt_block* structure. A newer decoder
library may truncate an extended *pt_block* object to *size* bytes.
An older decoder library may provide less *pt_block* fields. Fields that are
not provided will be zero-initialized. For fields where zero is a valid value
(e.g. for bit-fields), check the decoder library version to determine which
fields are valid. See **pt_library_version**(3).
On success, the next block of instructions is provided in the *pt_block* object
pointed to by the *block* argument. The *pt_block* structure is declared as:
~~~{.c}
/** A block of instructions.
*
* Instructions in this block are executed sequentially but are not necessarily
* contiguous in memory. Users are expected to follow direct branches.
*/
struct pt_block {
/** The IP of the first instruction in this block. */
uint64_t ip;
/** The IP of the last instruction in this block.
*
* This can be used for error-detection.
*/
uint64_t end_ip;
/** The image section that contains the instructions in this block.
*
* A value of zero means that the section did not have an identifier.
* The section was not added via an image section cache or the memory
* was read via the read memory callback.
*/
int isid;
/** The execution mode for all instructions in this block. */
enum pt_exec_mode mode;
/** The instruction class for the last instruction in this block.
*
* This field may be set to ptic_error to indicate that the instruction
* class is not available. The block decoder may choose to not provide
* the instruction class in some cases for performance reasons.
*/
enum pt_insn_class iclass;
/** The number of instructions in this block. */
uint16_t ninsn;
/** The raw bytes of the last instruction in this block in case the
* instruction does not fit entirely into this block's section.
*
* This field is only valid if \@truncated is set.
*/
uint8_t raw[pt_max_insn_size];
/** The size of the last instruction in this block in bytes.
*
* This field is only valid if \@truncated is set.
*/
uint8_t size;
/** A collection of flags giving additional information about the
* instructions in this block.
*
* - all instructions in this block were executed speculatively.
*/
uint32_t speculative:1;
/** - the last instruction in this block is truncated.
*
* It starts in this block's section but continues in one or more
* other sections depending on how fragmented the memory image is.
*
* The raw bytes for the last instruction are provided in \@raw and
* its size in \@size in this case.
*/
uint32_t truncated:1;
};
~~~
The fields of the *pt_block* structure are described in more detail below:
ip
: The virtual address of the first instruction in the block. The address
should be interpreted in the current address space context.
end_ip
: The virtual address of the last instruction in the block. The address
should be interpreted in the current address space context.
This can be used for error detection. Reconstruction of the instructions in
a block should end with the last instruction at *end_ip*.
isid
: The image section identifier of the section from which the block of
instructions originated. This will be zero unless the instructions came
from a section that was added via an image section cache. See
**pt_image_add_cached**(3).
The image section identifier can be used for reading the memory containing
an instruction in order to decode it and for tracing an instruction back to
its binary file and from there to source code.
mode
: The execution mode at which the instructions in the block were executed.
The *pt_exec_mode* enumeration is declared as:
~~~{.c}
/** An execution mode. */
enum pt_exec_mode {
ptem_unknown,
ptem_16bit,
ptem_32bit,
ptem_64bit
};
~~~
iclass
: A coarse classification of the last instruction in the block. This may be
*ptic_error* to indicate that the classification is not available.
The block decoder knows the instruction class of the instruction that ended
the block most of the time. If it does, it provides this information to
save the caller the effort of decoding the instruction in some cases.
ninsn
: The number of instructions contained in this block.
The instructions are sequential in the sense that no trace is required for
reconstructing them. They are not necessarily contiguous in memory.
The IP of the first instruction is given in the *ip* field and the IP of
other instructions can be determined by decoding and examining the previous
instruction.
raw
: If the last instruction of this block can not be read entirely from this
block's section, this field provides the instruction's raw bytes.
It is only valid if the *truncated* flag is set.
size
: If the last instruction of this block can not be read entirely from this
block's section, this field provides the instruction's size in bytes.
It is only valid if the *truncated* flag is set.
speculative
: A flag giving the speculative execution status of all instructions in the
block. If set, the instructions were executed speculatively. Otherwise,
the instructions were executed normally.
truncated
: A flag saying whether the last instruction in this block can not be read
entirely from this block's section. Some bytes need to be read from one or
more other sections. This can happen when an image section is partially
overwritten by another image section.
If set, the last instruction's memory is provided in *raw* and its size in
*size*.
# RETURN VALUE
**pt_blk_next**() returns zero or a positive value on success or a negative
*pt_error_code* enumeration constant in case of an error.
On success, a bit-vector of *pt_status_flag* enumeration constants is returned.
The *pt_status_flag* enumeration is declared as:
~~~{.c}
/** Decoder status flags. */
enum pt_status_flag {
/** There is an event pending. */
pts_event_pending = 1 << 0,
/** The address has been suppressed. */
pts_ip_suppressed = 1 << 1,
/** There is no more trace data available. */
pts_eos = 1 << 2
};
~~~
The *pts_event_pending* flag indicates that one or more events are pending. Use
**pt_blk_event**(3) to process pending events before calling **pt_blk_next**()
again.
The *pt_eos* flag indicates that the information contained in the Intel PT
stream has been consumed. Further calls to **pt_blk_next**() will continue to
provide blocks for instructions as long as the instruction's addresses can be
determined without further trace.
# ERRORS
pte_invalid
: The *decoder* or *block* argument is NULL or the *size* argument is too
small.
pte_eos
: Decode reached the end of the trace stream.
pte_nosync
: The decoder has not been synchronized onto the trace stream. Use
**pt_blk_sync_forward**(3), **pt_blk_sync_backward**(3), or
**pt_blk_sync_set**(3) to synchronize *decoder*.
pte_bad_opc
: The decoder encountered an unsupported Intel PT packet opcode.
pte_bad_packet
: The decoder encountered an unsupported Intel PT packet payload.
pte_bad_query
: Execution flow reconstruction and trace got out of sync.
This typically means that, on its way to the virtual address of the next
event, the decoder encountered a conditional or indirect branch for which it
did not find guidance in the trace.
# SEE ALSO
**pt_blk_alloc_decoder**(3), **pt_blk_free_decoder**(3),
**pt_blk_sync_forward**(3), **pt_blk_sync_backward**(3),
**pt_blk_sync_set**(3), **pt_blk_time**(3), **pt_blk_core_bus_ratio**(3),
**pt_blk_event**(3)

View File

@ -0,0 +1,152 @@
% PT_BLK_SYNC_FORWARD(3)
<!---
! Copyright (c) 2016-2018, 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.
!-->
# NAME
pt_blk_sync_forward, pt_blk_sync_backward, pt_blk_sync_set - synchronize an
Intel(R) Processor Trace block decoder
# SYNOPSIS
| **\#include `<intel-pt.h>`**
|
| **int pt_blk_sync_forward(struct pt_block_decoder \**decoder*);**
| **int pt_blk_sync_backward(struct pt_block_decoder \**decoder*);**
| **int pt_blk_sync_set(struct pt_block_decoder \**decoder*,**
| **uint64_t *offset*);**
Link with *-lipt*.
# DESCRIPTION
These functions synchronize an Intel Processor Trace (Intel PT) block decoder
pointed to by *decoder* onto the trace stream in *decoder*'s trace buffer.
They search for a Packet Stream Boundary (PSB) packet in the trace stream and,
if successful, set *decoder*'s current position and synchronization position to
that packet and start processing packets. For synchronization to be
successfull, there must be a full PSB+ header in the trace stream.
**pt_blk_sync_forward**() searches in forward direction from *decoder*'s
current position towards the end of the trace buffer. If *decoder* has been
newly allocated and has not been synchronized yet, the search starts from the
beginning of the trace.
**pt_blk_sync_backward**() searches in backward direction from *decoder*'s
current position towards the beginning of the trace buffer. If *decoder* has
been newly allocated and has not been synchronized yet, the search starts from
the end of the trace.
**pt_blk_sync_set**() searches at *offset* bytes from the beginning of its
trace buffer.
# RETURN VALUE
All synchronization functions return zero or a positive value on success or a
negative *pt_error_code* enumeration constant in case of an error.
On success, a bit-vector of *pt_status_flag* enumeration constants is returned.
The *pt_status_flag* enumeration is declared as:
~~~{.c}
/** Decoder status flags. */
enum pt_status_flag {
/** There is an event pending. */
pts_event_pending = 1 << 0,
/** The address has been suppressed. */
pts_ip_suppressed = 1 << 1,
/** There is no more trace data available. */
pts_eos = 1 << 2
};
~~~
The *pts_event_pending* flag indicates that one or more events are pending. Use
**pt_blk_event**(3) to process pending events before calling **pt_blk_next**(3).
The *pt_eos* flag indicates that the information contained in the Intel PT
stream has been consumed. Calls to **pt_blk_next**() will provide blocks for
instructions as long as the instruction's addresses can be determined without
further trace.
# ERRORS
pte_invalid
: The *decoder* argument is NULL.
pte_eos
: There is no (further) PSB+ header in the trace stream
(**pt_blk_sync_forward**() and **pt_blk_sync_backward**()) or at *offset*
bytes into the trace buffer (**pt_blk_sync_set**()).
pte_nosync
: There is no PSB packet at *offset* bytes from the beginning of the trace
(**pt_blk_sync_set**() only).
pte_bad_opc
: The decoder encountered an unsupported Intel PT packet opcode.
pte_bad_packet
: The decoder encountered an unsupported Intel PT packet payload.
# EXAMPLE
The following example re-synchronizes an Intel PT block decoder after decode
errors:
~~~{.c}
int foo(struct pt_block_decoder *decoder) {
for (;;) {
int errcode;
errcode = pt_blk_sync_forward(decoder);
if (errcode < 0)
return errcode;
do {
errcode = decode(decoder);
} while (errcode >= 0);
}
}
~~~
# SEE ALSO
**pt_blk_alloc_decoder**(3), **pt_blk_free_decoder**(3),
**pt_blk_get_offset**(3), **pt_blk_get_sync_offset**(3),
**pt_blk_get_config**(3), **pt_blk_time**(3), **pt_blk_core_bus_ratio**(3),
**pt_blk_next**(3), **pt_blk_event**(3)

359
doc/man/pt_config.3.md Normal file
View File

@ -0,0 +1,359 @@
% PT_CONFIG(3)
<!---
! Copyright (c) 2015-2018, 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.
!-->
# NAME
pt_config, pt_config_init, pt_cpu_errata - Intel(R) Processor Trace
encoder/decoder configuration
# SYNOPSIS
| **\#include `<intel-pt.h>`**
|
| **struct pt_config;**
|
| **void pt_config_init(struct pt_config \**config*);**
|
| **int pt_cpu_errata(struct pt_errata \**errata*, const struct pt_cpu \**cpu*);**
Link with *-lipt*.
# DESCRIPTION
The *pt_config* structure defines an Intel Processor Trace (Intel PT) encoder or
decoder configuration. It is required for allocating a trace packet encoder
(see **pt_alloc_encoder**(3)), a trace packet decoder (see
**pt_pkt_alloc_decoder**(3)), a query decoder (see **pt_qry_alloc_decoder**(3)),
or an instruction flow decoder (see **pt_insn_alloc_decoder**(3)).
**pt_config_init**() zero-initializes its *config* argument and sets *config*'s
*size* field to *sizeof(struct pt_config)*.
**pt_cpu_errata**() enables workarounds for known errata in its *errata*
argument for the processor defined by its family/model/stepping in its *cpu*
argument.
The *pt_config* structure is declared as:
~~~{.c}
/** An Intel PT decoder configuration. */
struct pt_config {
/** The size of the config structure in bytes. */
size_t size;
/** The trace buffer begin address. */
uint8_t *begin;
/** The trace buffer end address. */
uint8_t *end;
/** An optional callback for handling unknown packets.
*
* If \@callback is not NULL, it is called for any unknown
* opcode.
*/
struct {
/** The callback function.
*
* It shall decode the packet at \@pos into \@unknown.
* It shall return the number of bytes read upon success.
* It shall return a negative pt_error_code otherwise.
* The below context is passed as \@context.
*/
int (*callback)(struct pt_packet_unknown *unknown,
const struct pt_config *config,
const uint8_t *pos, void *context);
/** The user-defined context for this configuration. */
void *context;
} decode;
/** The cpu on which Intel PT has been recorded. */
struct pt_cpu cpu;
/** The errata to apply when encoding or decoding Intel PT. */
struct pt_errata errata;
/** The CTC frequency.
*
* This is only required if MTC packets have been enabled in
* IA32_RTIT_CTRL.MTCEn.
*/
uint32_t cpuid_0x15_eax, cpuid_0x15_ebx;
/** The MTC frequency as defined in IA32_RTIT_CTL.MTCFreq.
*
* This is only required if MTC packets have been enabled in
* IA32_RTIT_CTRL.MTCEn.
*/
uint8_t mtc_freq;
/** The nominal frequency as defined in
* MSR_PLATFORM_INFO[15:8].
*
* This is only required if CYC packets have been enabled in
* IA32_RTIT_CTRL.CYCEn.
*
* If zero, timing calibration will only be able to use MTC
* and CYC packets.
*
* If not zero, timing calibration will also be able to use
* CBR packets.
*/
uint8_t nom_freq;
/** A collection of decoder-specific flags. */
struct pt_conf_flags flags;
/** The address filter configuration. */
struct pt_conf_addr_filter addr_filter;
};
~~~
The fields of the *pt_config* structure are described in more detail below:
size
: The size of the *pt_config* structure for backward and forward
compatibility. Set it to *sizeof(struct pt_config)*.
begin, end
: The begin and end of a user-allocated memory buffer; *begin* points to
the first byte of the buffer, *end* points to one past the last byte in the
buffer.
The packet encoder will generate Intel PT packets into the memory buffer.
The decoders expect the buffer to contain raw Intel PT packets. They decode
directly from the buffer and expect the buffer to remain valid until the
decoder has been freed.
decode
: An optional packet decode callback function. If *decode.callback* is not
NULL, it will be called for any unknown packet with the decoder
configuration, the current decoder position and with a user-defined context
provided in *callback.context* as arguments.
If the callback function is able to decode the packet, it shall return the
size of the decoded packet and provide details in a *pt_packet_unknown*
object.
If the packet cannot be decoded, the callback function shall return a
negative *pt_error_code* enumeration constant.
The *pt_packet_unknown* object can be used to provide user-defined
information back to the user when using the packet decoder to iterate over
Intel PT packets. Other decoders ignore this information but will skip
the packet if a non-zero size is returned by the callback function.
cpu
: The processor on which the trace has been collected or for which the trace
should be generated. The processor is identified by its family, model, and
stepping.
~~~{.c}
/** A cpu vendor. */
enum pt_cpu_vendor {
pcv_unknown,
pcv_intel
};
/** A cpu identifier. */
struct pt_cpu {
/** The cpu vendor. */
enum pt_cpu_vendor vendor;
/** The cpu family. */
uint16_t family;
/** The cpu model. */
uint8_t model;
/** The stepping. */
uint8_t stepping;
};
~~~
errata
: The errata workarounds to be applied by the trace encoder or decoder that
is created using this configuration.
The *pt_errata* structure is a collection of one-bit-fields, one for each
supported erratum. Duplicate errata are indicated by comments for the
erratum for which the workaround was first implemented. Set the field of an
erratum to enable the correspondig workaround.
The *pt_errata* structure is declared as:
~~~{.c}
/** A collection of Intel PT errata. */
struct pt_errata {
/** BDM70: Intel(R) Processor Trace PSB+ Packets May Contain
* Unexpected Packets.
*
* Same as: SKD024.
*
* Some Intel Processor Trace packets should be issued only
* between TIP.PGE and TIP.PGD packets. Due to this erratum,
* when a TIP.PGE packet is generated it may be preceded by a
* PSB+ that incorrectly includes FUP and MODE.Exec packets.
*/
uint32_t bdm70:1;
/** BDM64: An Incorrect LBR or Intel(R) Processor Trace Packet
* May Be Recorded Following a Transactional Abort.
*
* Use of Intel(R) Transactional Synchronization Extensions
* (Intel(R) TSX) may result in a transactional abort. If an
* abort occurs immediately following a branch instruction,
* an incorrect branch target may be logged in an LBR (Last
* Branch Record) or in an Intel(R) Processor Trace (Intel(R)
* PT) packet before the LBR or Intel PT packet produced by
* the abort.
*/
uint32_t bdm64:1;
[...]
};
~~~
cpuid_0x15_eax, cpuid_0x15_ebx
: The values of *eax* and *ebx* on a *cpuid* call for leaf *0x15*.
The value *ebx/eax* gives the ratio of the Core Crystal Clock (CTC) to
Timestamp Counter (TSC) frequency.
This field is ignored by the packet encoder and packet decoder. It is
required for other decoders if Mini Time Counter (MTC) packets are enabled
in the collected trace.
mtc_freq
: The Mini Time Counter (MTC) frequency as defined in *IA32_RTIT_CTL.MTCFreq*.
This field is ignored by the packet encoder and packet decoder. It is
required for other decoders if Mini Time Counter (MTC) packets are enabled
in the collected trace.
nom_freq
: The nominal or max non-turbo frequency.
This field is ignored by the packet encoder and packet decoder. It is
used by other decoders if Cycle Count (CYC) packets are enabled to improve
timing calibration for cycle-accurate tracing.
If the field is zero, the time tracking algorithm will use Mini Time
Counter (MTC) and Cycle Count (CYC) packets for calibration.
If the field is non-zero, the time tracking algorithm will additionally be
able to calibrate at Core:Bus Ratio (CBR) packets.
flags
: A collection of decoder-specific configuration flags.
addr_filter
: The address filter configuration. It is declared as:
~~~{.c}
/** The address filter configuration. */
struct pt_conf_addr_filter {
/** The address filter configuration.
*
* This corresponds to the respective fields in IA32_RTIT_CTL MSR.
*/
union {
uint64_t addr_cfg;
struct {
uint32_t addr0_cfg:4;
uint32_t addr1_cfg:4;
uint32_t addr2_cfg:4;
uint32_t addr3_cfg:4;
} ctl;
} config;
/** The address ranges configuration.
*
* This corresponds to the IA32_RTIT_ADDRn_A/B MSRs.
*/
uint64_t addr0_a;
uint64_t addr0_b;
uint64_t addr1_a;
uint64_t addr1_b;
uint64_t addr2_a;
uint64_t addr2_b;
uint64_t addr3_a;
uint64_t addr3_b;
/* Reserve some space. */
uint64_t reserved[8];
};
~~~
# RETURN VALUE
**pt_cpu_errata**() returns zero on success or a negative *pt_error_code*
enumeration constant otherwise.
# ERRORS
**pt_cpu_errata**() may return the following errors:
pte_invalid
: The *errata* or *cpu* argument is NULL.
# EXAMPLE
~~~{.c}
int foo(uint8_t *trace_buffer, size_t size, struct pt_cpu cpu) {
struct pt_config config;
int errcode;
pt_config_init(&config);
config.begin = trace_buffer;
config.end = trace_buffer + size;
config.cpu = cpu;
errcode = pt_cpu_errata(&config.errata, &config.cpu);
if (errcode < 0)
return errcode;
[...]
}
~~~
# SEE ALSO
**pt_alloc_encoder**(3), **pt_pkt_alloc_decoder**(3),
**pt_qry_alloc_decoder**(3), **pt_insn_alloc_decoder**(3)

View File

@ -0,0 +1,77 @@
% PT_ENC_GET_CONFIG(3)
<!---
! Copyright (c) 2015-2018, 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.
!-->
# NAME
pt_enc_get_config, pt_pkt_get_config, pt_qry_get_config, pt_insn_get_config,
pt_blk_get_config - get an Intel(R) Processor Trace encoder/decoder's
configuration
# SYNOPSIS
| **\#include `<intel-pt.h>`**
|
| **const struct pt_config \***
| **pt_enc_get_config(const struct pt_encoder \**encoder*);**
|
| **const struct pt_config \***
| **pt_pkt_get_config(const struct pt_packet_decoder \**decoder*);**
|
| **const struct pt_config \***
| **pt_qry_get_config(const struct pt_query_decoder \**decoder*);**
|
| **const struct pt_config \***
| **pt_insn_get_config(const struct pt_insn_decoder \**decoder*);**
|
| **const struct pt_config \***
| **pt_blk_get_config(const struct pt_block_decoder \**decoder*);**
Link with *-lipt*.
# DESCRIPTION
These functions return a pointer to their argument's configuration. The
returned configuration object must not be freed. It is valid as long as their
argument is not freed.
# RETURN VALUE
These functions returns a pointer to a *pt_config* object. The returned pointer
is NULL if their argument is NULL.
# SEE ALSO
**pt_config**(3), **pt_alloc_encoder**(3), **pt_pkt_alloc_decoder**(3),
**pt_qry_alloc_decoder**(3), **pt_insn_alloc_decoder**(3),
**pt_blk_alloc_decoder**(3)

View File

@ -0,0 +1,77 @@
% PT_ENC_GET_OFFSET(3)
<!---
! Copyright (c) 2015-2018, 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.
!-->
# NAME
pt_enc_get_offset, pt_enc_sync_set - get/set an Intel(R) Processor Trace packet
encoder's current trace buffer offset
# SYNOPSIS
| **\#include `<intel-pt.h>`**
|
| **int pt_enc_get_offset(const struct pt_packet_encoder \**encoder*,**
| **uint64_t \**offset*);**
| **int pt_enc_sync_set(const struct pt_packet_encoder \**encoder*,**
| **uint64_t *offset*);**
Link with *-lipt*.
# DESCRIPTION
**pt_enc_get_offset**() provides *encoder*'s current position as offset in bytes
from the beginning of *encoder*'s trace buffer in the unsigned integer variable
pointed to by *offset*.
**pt_enc_sync_set**() sets *encoder*'s current position to *offset* bytes from
the beginning of its trace buffer.
# RETURN VALUE
Both functions return zero on success or a negative *pt_error_code* enumeration
constant in case of an error.
# ERRORS
pte_invalid
: The *encoder* or *offset* (for **pt_enc_sync_set**()) argument is NULL.
pte_eos
: The *offset* argument is too big and the resulting position would be outside
of *encoder*'s trace buffer (**pt_enc_sync_set**() only).
# SEE ALSO
**pt_enc_alloc_encoder**(3), **pt_enc_free_encoder**(3), **pt_enc_next**(3)

View File

@ -0,0 +1,135 @@
% PT_IMAGE_ADD_FILE(3)
<!---
! Copyright (c) 2015-2018, 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.
!-->
# NAME
pt_image_add_file, pt_image_add_cached, pt_image_copy - add file sections to a
traced memory image descriptor
# SYNOPSIS
| **\#include `<intel-pt.h>`**
|
| **int pt_image_add_file(struct pt_image \**image*, const char \**filename*,**
| **uint64_t *offset*, uint64_t *size*,**
| **const struct pt_asid \**asid*, uint64_t *vaddr*);**
| **int pt_image_add_cached(struct pt_image \**image*,**
| **struct pt_image_section_cache \**iscache*,**
| **int *isid*, const struct pt_asid \**asid*);**
| **int pt_image_copy(struct pt_image \**image*,**
| **const struct pt_image \**src*);**
Link with *-lipt*.
# DESCRIPTION
**pt_image_add_file**() adds a new section to a *pt_image* object. The *image*
argument points to the *pt_image* object to which the new section is added. The
*filename* argument gives the absolute or relative path to the file on disk that
contains the section. The *offset* and *size* arguments define the section
within the file. The *size* argument is silently truncated to end the section
with the end of the underlying file. The *vaddr* argument gives the virtual
address at which the section is being loaded.
**pt_image_add_cached**() adds a new section from an image section cache. See
**pt_iscache_add_file**(3). The *iscache* argument points to the
*pt_image_section_cache* object containing the section. The *isid* argument
gives the image section identifier for the desired section in that cache.
The *asid* argument gives an optional address space identifier. If it is not
NULL, it points to a *pt_asid* structure, which is declared as:
~~~{.c}
/** An Intel PT address space identifier.
*
* This identifies a particular address space when adding file
* sections or when reading memory.
*/
struct pt_asid {
/** The size of this object - set to sizeof(struct pt_asid).
*/
size_t size;
/** The CR3 value. */
uint64_t cr3;
/** The VMCS Base address. */
uint64_t vmcs;
};
~~~
The *asid* argument can be used to prepare a collection of process, guest, and
hypervisor images to an Intel(R) Processor Trace (Intel PT) instruction flow
decoder. The decoder will select the current image based on CR3 and VMCS
information in the Intel PT trace.
If only the CR3 or only the VMCS field should be considered by the decoder,
supply *pt_asid_no_cr3* and *pt_asid_no_vmcs* to the other field respectively.
If the *asid* argument is NULL, the file section will be added for all
processes, guests, and hypervisor images.
If the new section overlaps with an existing section, the existing section is
truncated or split to make room for the new section.
**pt_image_copy**() adds file sections from the *pt_image* pointed to by the
*src* argument to the *pt_image* pointed to by the *dst* argument.
# RETURN VALUE
**pt_image_add_file**() and **pt_image_add_cached**() return zero on success or
a negative *pt_error_code* enumeration constant in case of an error.
**pt_image_copy**() returns the number of ignored sections on success or a
negative *pt_error_code* enumeration constant in case of an error.
# ERRORS
pte_invalid
: The *image* or *filename* argument is NULL or the *offset* argument is too
big such that the section would start past the end of the file
(**pt_image_add_file**()).
The *image* or *iscache* argument is NULL (**pt_image_add_cached**()).
The *src* or *dst* argument is NULL (**pt_image_copy**()).
pte_bad_image
: The *iscache* does not contain *isid* (**pt_image_add_cached**()).
# SEE ALSO
**pt_image_alloc**(3), **pt_image_free**(3),
**pt_image_remove_by_filename**(3), **pt_image_remove_by_asid**(3),
**pt_image_set_callback**(3), **pt_insn_set_image**(3),
**pt_insn_get_image**(3), **pt_iscache_alloc**(3), **pt_iscache_add_file**(3)

View File

@ -0,0 +1,99 @@
% PT_IMAGE_ALLOC(3)
<!---
! Copyright (c) 2015-2018, 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.
!-->
# NAME
pt_image_alloc, pt_image_free, pt_image_name - allocate/free a traced memory
image descriptor
# SYNOPSIS
| **\#include `<intel-pt.h>`**
|
| **struct pt_image \*pt_image_alloc(const char \**name*);**
| **const char \*pt_image_name(const struct pt_image \**image*);**
| **void pt_image_free(struct pt_image \**image*);**
Link with *-lipt*.
# DESCRIPTION
**pt_image_alloc**() allocates a new *pt_image* and returns a pointer to it. A
*pt_image* object defines the memory image that was traced as a collection of
file sections and the virtual addresses at which those sections were loaded.
The *name* argument points to an optional zero-terminated name string. If the
*name* argument is NULL, it will be ignored and the returned *pt_image* object
will not have a name. Otherwise, the returned *pt_image* object will have a
copy of the string pointed to by the *name* argument as name.
**pt_image_name**() returns the name of the *pt_image* object the *image*
argument points to.
**pt_image_free**() frees the *pt_image* object pointed to by *image*. The
*image* argument must be NULL or point to an image that has been allocated by a
call to **pt_image_alloc**().
# RETURN VALUE
**pt_image_alloc**() returns a pointer to a *pt_image* object on success or NULL
in case of an error.
**pt_image_name**() returns a pointer to a zero-terminated string of NULL if the
image does not have a name.
# EXAMPLE
~~~{.c}
int foo(const char *name) {
struct pt_image *image;
errcode;
image = pt_image_alloc(name);
if (!image)
return pte_nomem;
errcode = bar(image);
pt_image_free(image);
return errcode;
}
~~~
# SEE ALSO
**pt_image_add_file**(3), **pt_image_add_cached**(3), **pt_image_copy**(3),
**pt_image_remove_by_filename**(3), **pt_image_remove_by_asid**(3),
**pt_image_set_callback**(3), **pt_insn_set_image**(3), **pt_insn_get_image**(3)

View File

@ -0,0 +1,150 @@
% PT_IMAGE_REMOVE_BY_FILENAME(3)
<!---
! Copyright (c) 2015-2018, 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.
!-->
# NAME
pt_image_remove_by_filename, pt_image_remove_by_asid - remove sections from a
traced memory image descriptor
# SYNOPSIS
| **\#include `<intel-pt.h>`**
|
| **int pt_image_remove_by_filename(struct pt_image \**image*,**
| **const char \**filename*,**
| **const struct pt_asid \**asid*);**
| **int pt_image_remove_by_asid(struct pt_image \**image*,**
| **const struct pt_asid \**asid*);**
Link with *-lipt*.
# DESCRIPTION
**pt_image_remove_by_filename**() removes all sections from *image* that were
added by a call to **pt_image_add_file**(3) with an identical *filename*
argument or by a call to **pt_image_copy**(3) from such a section. Sections
that are based on the same underlying file but that were added using a different
*filename* argument are not removed.
If the *asid* argument is not NULL, it removes only sections that were added
with a matching address-space identifier. See **pt_image_add_file**(3).
**pt_image_remove_by_asid**(3) removes all sections from *image* that were added
by a call to **pt_image_add_file**(3) with a matching *asid* argument or by a
call to **pt_image_copy**(3) from such a section. See **pt_image_add_file**(3).
Two *pt_asid* objects match in their "cr3* or *vmcs* field if one of them does
not provide the field (i.e. sets it to *pt_asid_no_cr3* or *pt_asid_no_vmcs*
respectively) or if the provided values are identical. Two *pt_asid* objects
match if they match in all fields.
# RETURN VALUE
Both functions return the number of sections removed on success or a negative
*pt_error_code* enumeration constant in case of an error.
# ERRORS
pte_invalid
: The *image* argument is NULL or the *filename* argument is NULL
(**pt_image_remove_by_filename**() only).
# EXAMPLE
~~~{.c}
int foo(struct pt_image *image, uint64_t cr3) {
struct pt_asid asid1, asid2;
int errcode;
pt_asid_init(&asid1);
asid1.cr3 = cr3;
pt_asid_init(&asid2);
asid2.cr3 = ~cr3;
errcode = pt_image_add_file(image, "/path/to/libfoo.so",
0xa000, 0x100, &asid1, 0xb000);
if (errcode < 0)
return errcode;
errcode = pt_image_add_file(image, "rel/path/to/libfoo.so",
0xa000, 0x100, &asid1, 0xc000);
if (errcode < 0)
return errcode;
/* This call would only remove the section added first:
*
* - filename matches only the first section's filename
* - NULL matches every asid
*/
(void) pt_image_remove_by_filename(image,
"/path/to/libfoo.so",
NULL);
/* This call would not remove any of the above sections:
*
* - filename matches the first section's filename
* - asid2 does not match asid1
*/
(void) pt_image_remove_by_filename(image,
"/path/to/libfoo.so",
&asid2);
/* This call would not remove any of the above sections:
*
* - asid2 does not match asid1
*/
(void) pt_image_remove_by_asid(image, &asid2);
/* This call would remove both sections:
*
* - asid1 matches itself
*/
(void) pt_image_remove_by_asid(image, &asid1);
/* This call would remove both sections:
*
* - NULL matches every asid
*/
(void) pt_image_remove_by_asid(image, NULL);
}
~~~
# SEE ALSO
**pt_image_alloc**(3), **pt_image_free**(3), **pt_image_add_file**(3),
**pt_image_add_cached**(3), **pt_image_copy**(3), **pt_insn_set_image**(3),
**pt_insn_get_image**(3)

View File

@ -0,0 +1,103 @@
% PT_IMAGE_SET_CALLBACK(3)
<!---
! Copyright (c) 2015-2018, 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.
!-->
# NAME
pt_image_set_callback - set a traced memory image read memory callback
# SYNOPSIS
| **\#include `<intel-pt.h>`**
|
| **typedef int (read_memory_callback_t)(uint8_t \**buffer*, size_t *size*,**
| **const struct pt_asid \**asid*,**
| **uint64_t *ip*, void \**context*);**
|
| **int pt_image_set_callback(struct pt_image \**image*,**
| **read_memory_callback_t \**callback*,**
| **void \**context*);**
Link with *-lipt*.
# DESCRIPTION
**pt_image_set_callback**() sets the function pointed to by *callback* as the
read-memory callback function in the *pt_image* object pointed to by *image*.
Any previous read-memory callback function is replaced. The read-memory
callback function can be removed by passing NULL as *callback* argument.
When the Intel(R) Processor Trace (Intel PT) instruction flow decoder that is
using *image* tries to read memory from a location that is not contained in any
of the file sections in *image*, it calls the read-memory callback function with
the following arguments:
buffer
: A pre-allocated memory buffer to hold the to-be-read memory. The callback
function shall provide the read memory in that buffer.
size
: The size of the memory buffer pointed to by the *buffer* argument.
asid
: The address-space identifier specifying the process, guest, or hypervisor,
in which context the *ip* argument is to be interpreted. See
**pt_image_add_file**(3).
ip
: The virtual address from which *size* bytes of memory shall be read.
context
: The *context* argument passed to **pt_image_set_callback**().
The callback function shall return the number of bytes read on success (no more
than *size*) or a negative *pt_error_code* enumeration constant in case of an
error.
# RETURN VALUE
**pt_image_set_callback**() returns zero on success or a negative
*pt_error_code* enumeration constant in case of an error.
# ERRORS
pte_invalid
: If the *image* argument is NULL.
# SEE ALSO
**pt_image_alloc**(3), **pt_image_free**(3), **pt_image_add_file**(3),
**pt_image_add_cached**(3), pt_image_copy**(3),
**pt_image_remove_by_filename**(3), pt_image_remove_by_asid**(3),
**pt_insn_set_image**(3), pt_insn_get_image**(3)

View File

@ -0,0 +1,101 @@
% PT_INSN_ALLOC_DECODER(3)
<!---
! Copyright (c) 2015-2018, 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.
!-->
# NAME
pt_insn_alloc_decoder, pt_insn_free_decoder - allocate/free an Intel(R)
Processor Trace instruction flow decoder
# SYNOPSIS
| **\#include `<intel-pt.h>`**
|
| **struct pt_insn_decoder \***
| **pt_insn_alloc_decoder(const struct pt_config \**config*);**
|
| **void pt_insn_free_decoder(struct pt_insn_decoder \**decoder*);**
Link with *-lipt*.
# DESCRIPTION
An instruction flow decoder decodes raw Intel Processor Trace (Intel PT) into a
sequence of instructions described by the *pt_insn* structure. See
**pt_insn_next**(3).
**pt_insn_alloc_decoder**() allocates a new instruction flow decoder and returns
a pointer to it. The *config* argument points to a *pt_config* object. See
**pt_config**(3). The *config* argument will not be referenced by the returned
decoder but the trace buffer defined by the *config* argument's *begin* and
*end* fields will.
The returned instruction flow decoder needs to be synchronized onto the trace
stream before it can be used. To synchronize the instruction flow decoder, use
**pt_insn_sync_forward**(3), **pt_insn_sync_backward**(3), or
**pt_insn_sync_set**(3).
**pt_insn_free_decoder**() frees the Intel PT instruction flow decoder pointed
to by *decoder*. The *decoder* argument must be NULL or point to a decoder that
has been allocated by a call to **pt_insn_alloc_decoder**().
# RETURN VALUE
**pt_insn_alloc_decoder**() returns a pointer to a *pt_insn_decoder* object on
success or NULL in case of an error.
# EXAMPLE
~~~{.c}
int foo(const struct pt_config *config) {
struct pt_insn_decoder *decoder;
errcode;
decoder = pt_insn_alloc_decoder(config);
if (!decoder)
return pte_nomem;
errcode = bar(decoder);
pt_insn_free_decoder(decoder);
return errcode;
}
~~~
# SEE ALSO
**pt_config**(3), **pt_insn_sync_forward**(3), **pt_insn_sync_backward**(3),
**pt_insn_sync_set**(3), **pt_insn_get_offset**(3), **pt_insn_get_sync_offset**(3),
**pt_insn_get_image**(3), **pt_insn_set_image**(3), **pt_insn_get_config**(3),
**pt_insn_time**(3), **pt_insn_core_bus_ratio**(3), **pt_insn_next**(3)

View File

@ -0,0 +1,93 @@
% PT_INSN_GET_IMAGE(3)
<!---
! Copyright (c) 2015-2018, 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.
!-->
# NAME
pt_insn_get_image, pt_insn_set_image, pt_blk_get_image, pt_blk_set_image -
get/set an Intel(R) Processor Trace instruction flow or block decoder's traced
memory image descriptor
# SYNOPSIS
| **\#include `<intel-pt.h>`**
|
| **struct pt_image \*pt_insn_get_image(struct pt_insn_decoder \**decoder*);**
| **struct pt_image \*pt_blk_get_image(struct pt_block_decoder \**decoder*);**
|
| **int pt_insn_set_image(struct pt_insn_decoder \**decoder*,**
| **struct pt_image \**image*);**
| **int pt_blk_set_image(struct pt_block_decoder \**decoder*,**
| **struct pt_image \**image*);**
Link with *-lipt*.
# DESCRIPTION
**pt_insn_get_image**() and **pt_blk_get_image**() return the traced memory
*image descriptor that decoder* uses for reading instruction memory. See
***pt_image_alloc**(3). Every decoder comes with a default *pt_image* object
*that is initially empty and that will automatically be destroyed when the
*decoder is freed.
**pt_insn_set_image**() and **pt_blk_set_image**() set the traced memory image
descriptor that *decoder* uses for reading instruction memory. If the *image*
argument is NULL, sets *decoder*'s image to be its default image. The user is
responsible for freeing the *pt_image* object that *image* points to when it is
no longer needed.
# RETURN VALUE
**pt_insn_get_image**() and **pt_blk_get_image**() return a pointer to
*decoder*'s *pt_image* object. The returned pointer is NULL if the *decoder*
argument is NULL.
**pt_insn_set_image**() and **pt_blk_set_image**() return zero on success or a
negative *pt_error_code* enumeration constant in case of an error.
# ERRORS
pte_invalid
: The *decoder* argument is NULL.
# NOTES
One *pt_image* object must not be shared between multiple decoders. Use
**pt_image_copy**(3) to copy a common image.
# SEE ALSO
**pt_insn_alloc_decoder**(3), **pt_insn_free_decoder**(3), **pt_insn_next**(3),
**pt_blk_alloc_decoder**(3), **pt_blk_free_decoder**(3), **pt_blk_next**(3)

View File

@ -0,0 +1,82 @@
% PT_INSN_GET_OFFSET(3)
<!---
! Copyright (c) 2015-2018, 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.
!-->
# NAME
pt_insn_get_offset, pt_insn_get_sync_offset - get an Intel(R) Processor Trace
instruction flow decoder's current/synchronization trace buffer offset
# SYNOPSIS
| **\#include `<intel-pt.h>`**
|
| **int pt_insn_get_offset(const struct pt_insn_decoder \**decoder*,**
| **uint64_t \**offset*);**
| **int pt_insn_get_sync_offset(const struct pt_insn_decoder \**decoder*,**
| **uint64_t \**offset*);**
Link with *-lipt*.
# DESCRIPTION
**pt_insn_get_offset**() provides *decoder*'s current position as offset in
bytes from the beginning of *decoder*'s trace buffer in the unsigned integer
variable pointed to by *offset*.
**pt_insn_get_sync_offset**() provides *decoder*'s last synchronization point as
offset in bytes from the beginning of *decoder*'s trace buffer in the unsigned
integer variable pointed to by *offset*.
# RETURN VALUE
Both functions return zero on success or a negative *pt_error_code* enumeration
constant in case of an error.
# ERRORS
pte_invalid
: The *decoder* or *offset* argument is NULL.
pte_nosync
: *decoder* has not been synchronized onto the trace stream. Use
**pt_insn_sync_forward**(3), **pt_insn_sync_backward**(3), or
**pt_insn_sync_set**(3) to synchronize *decoder*.
# SEE ALSO
**pt_insn_alloc_decoder**(3), **pt_insn_free_decoder**(3),
**pt_insn_sync_forward**(3), **pt_insn_sync_backward**(3),
**pt_insn_sync_set**(3), **pt_insn_get_config**(3), **pt_insn_time**(3),
**pt_insn_core_bus_ratio**(3), **pt_insn_next**(3)

264
doc/man/pt_insn_next.3.md Normal file
View File

@ -0,0 +1,264 @@
% PT_INSN_NEXT(3)
<!---
! Copyright (c) 2015-2018, 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 NEXT 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.
!-->
# NAME
pt_insn_next, pt_insn - iterate over traced instructions
# SYNOPSIS
| **\#include `<intel-pt.h>`**
|
| **struct pt_insn;**
|
| **int pt_insn_next(struct pt_insn_decoder \**decoder*,**
| **struct pt_insn \**insn*, size_t *size*);**
Link with *-lipt*.
# DESCRIPTION
**pt_insn_next**() provides the next instruction in execution order, which is
described by the *pt_insn* structure.
The *size* argument must be set to *sizeof(struct pt_insn)*. The function will
provide at most *size* bytes of the *pt_insn* structure. A newer decoder
library may truncate an extended *pt_insn* object to *size* bytes.
An older decoder library may provide less *pt_insn* fields. Fields that are not
provided will be zero-initialized. For fields where zero is a valid value
(e.g. for bit-fields), check the decoder library version to determine which
fields are valid. See **pt_library_version**(3).
On success, the next instruction is provided in the *pt_insn* object pointed to
by the *insn* argument. The *pt_insn* structure is declared as:
~~~{.c}
/** A single traced instruction. */
struct pt_insn {
/** The virtual address in its process. */
uint64_t ip;
/** The image section identifier for the section containing this
* instruction.
*
* A value of zero means that the section did not have an identifier.
* The section was not added via an image section cache or the memory
* was read via the read memory callback.
*/
int isid;
/** The execution mode. */
enum pt_exec_mode mode;
/** A coarse classification. */
enum pt_insn_class iclass;
/** The raw bytes. */
uint8_t raw[pt_max_insn_size];
/** The size in bytes. */
uint8_t size;
/** A collection of flags giving additional information:
*
* - the instruction was executed speculatively.
*/
uint32_t speculative:1;
/** - this instruction is truncated in its image section.
*
* It starts in the image section identified by \@isid and continues
* in one or more other sections.
*/
uint32_t truncated:1;
};
~~~
The fields of the *pt_insn* structure are described in more detail below:
ip
: The virtual address of the instruction. The address should be interpreted
in the current address space context.
isid
: The image section identifier of the section from which the instruction
originated. This will be zero unless the instruction came from a section
that was added via an image section cache. See **pt_image_add_cached**(3).
The image section identifier can be used to trace an instruction back to
its binary file and from there to source code.
mode
: The execution mode at which the instruction was executed. The
*pt_exec_mode* enumeration is declared as:
~~~{.c}
/** An execution mode. */
enum pt_exec_mode {
ptem_unknown,
ptem_16bit,
ptem_32bit,
ptem_64bit
};
~~~
iclass
: A coarse classification of the instruction suitable for constructing a call
back trace. The *pt_insn_class* enumeration is declared as:
~~~{.c}
/** The instruction class.
*
* We provide only a very coarse classification suitable for
* reconstructing the execution flow.
*/
enum pt_insn_class {
/* The instruction could not be classified. */
ptic_error,
/* The instruction is something not listed below. */
ptic_other,
/* The instruction is a near (function) call. */
ptic_call,
/* The instruction is a near (function) return. */
ptic_return,
/* The instruction is a near unconditional jump. */
ptic_jump,
/* The instruction is a near conditional jump. */
ptic_cond_jump,
/* The instruction is a call-like far transfer.
* E.g. SYSCALL, SYSENTER, or FAR CALL.
*/
ptic_far_call,
/* The instruction is a return-like far transfer.
* E.g. SYSRET, SYSEXIT, IRET, or FAR RET.
*/
ptic_far_return,
/* The instruction is a jump-like far transfer.
* E.g. FAR JMP.
*/
ptic_far_jump
};
~~~
raw
: The memory containing the instruction.
size
: The size of the instruction in bytes.
speculative
: A flag giving the speculative execution status of the instruction. If set,
the instruction was executed speculatively. Otherwise, the instruction was
executed normally.
truncated
: A flag saying whether this instruction spans more than one image section.
If clear, this instruction originates from a single section identified by
*isid*. If set, the instruction overlaps two or more image sections. In
this case, *isid* identifies the section that contains the first byte.
# RETURN VALUE
**pt_insn_next**() returns zero or a positive value on success or a negative
*pt_error_code* enumeration constant in case of an error.
On success, a bit-vector of *pt_status_flag* enumeration constants is returned.
The *pt_status_flag* enumeration is declared as:
~~~{.c}
/** Decoder status flags. */
enum pt_status_flag {
/** There is an event pending. */
pts_event_pending = 1 << 0,
/** The address has been suppressed. */
pts_ip_suppressed = 1 << 1,
/** There is no more trace data available. */
pts_eos = 1 << 2
};
~~~
The *pts_event_pending* flag indicates that one or more events are pending. Use
**pt_insn_event**(3) to process pending events before calling **pt_insn_next**()
again.
The *pt_eos* flag indicates that the information contained in the Intel PT
stream has been consumed. Further calls to **pt_insn_next**() will continue to
provide instructions as long as the instruction's address can be determined
without further trace.
# ERRORS
pte_invalid
: The *decoder* or *insn* argument is NULL or the *size* argument is too
small.
pte_eos
: Decode reached the end of the trace stream.
pte_nosync
: The decoder has not been synchronized onto the trace stream. Use
**pt_insn_sync_forward**(3), **pt_insn_sync_backward**(3), or
**pt_insn_sync_set**(3) to synchronize *decoder*.
pte_bad_opc
: The decoder encountered an unsupported Intel PT packet opcode.
pte_bad_packet
: The decoder encountered an unsupported Intel PT packet payload.
pte_bad_query
: Execution flow reconstruction and trace got out of sync.
This typically means that, on its way to the virtual address of the next
event, the decoder encountered a conditional or indirect branch for which it
did not find guidance in the trace.
# SEE ALSO
**pt_insn_alloc_decoder**(3), **pt_insn_free_decoder**(3),
**pt_insn_sync_forward**(3), **pt_insn_sync_backward**(3),
**pt_insn_sync_set**(3), **pt_insn_time**(3), **pt_insn_core_bus_ratio**(3),
**pt_insn_event**(3)

View File

@ -0,0 +1,153 @@
% PT_INSN_SYNC_FORWARD(3)
<!---
! Copyright (c) 2015-2018, 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.
!-->
# NAME
pt_insn_sync_forward, pt_insn_sync_backward, pt_insn_sync_set - synchronize an
Intel(R) Processor Trace instruction flow decoder
# SYNOPSIS
| **\#include `<intel-pt.h>`**
|
| **int pt_insn_sync_forward(struct pt_insn_decoder \**decoder*);**
| **int pt_insn_sync_backward(struct pt_insn_decoder \**decoder*);**
| **int pt_insn_sync_set(struct pt_insn_decoder \**decoder*,**
| **uint64_t *offset*);**
Link with *-lipt*.
# DESCRIPTION
These functions synchronize an Intel Processor Trace (Intel PT) instruction flow
decoder pointed to by *decoder* onto the trace stream in *decoder*'s trace
buffer.
They search for a Packet Stream Boundary (PSB) packet in the trace stream and,
if successful, set *decoder*'s current position and synchronization position to
that packet and start processing packets. For synchronization to be
successfull, there must be a full PSB+ header in the trace stream.
**pt_insn_sync_forward**() searches in forward direction from *decoder*'s
current position towards the end of the trace buffer. If *decoder* has been
newly allocated and has not been synchronized yet, the search starts from the
beginning of the trace.
**pt_insn_sync_backward**() searches in backward direction from *decoder*'s
current position towards the beginning of the trace buffer. If *decoder* has
been newly allocated and has not been synchronized yet, the search starts from
the end of the trace.
**pt_insn_sync_set**() searches at *offset* bytes from the beginning of its
trace buffer.
# RETURN VALUE
All synchronization functions return zero or a positive value on success or a
negative *pt_error_code* enumeration constant in case of an error.
On success, a bit-vector of *pt_status_flag* enumeration constants is returned.
The *pt_status_flag* enumeration is declared as:
~~~{.c}
/** Decoder status flags. */
enum pt_status_flag {
/** There is an event pending. */
pts_event_pending = 1 << 0,
/** The address has been suppressed. */
pts_ip_suppressed = 1 << 1,
/** There is no more trace data available. */
pts_eos = 1 << 2
};
~~~
The *pts_event_pending* flag indicates that one or more events are pending. Use
**pt_insn_event**(3) to process pending events before calling
**pt_insn_next**(3).
The *pt_eos* flag indicates that the information contained in the Intel PT
stream has been consumed. Calls to **pt_insn_next**() will provide instructions
as long as the instruction's address can be determined without trace.
# ERRORS
pte_invalid
: The *decoder* argument is NULL.
pte_eos
: There is no (further) PSB+ header in the trace stream
(**pt_insn_sync_forward**() and **pt_insn_sync_backward**()) or at *offset*
bytes into the trace buffer (**pt_insn_sync_set**()).
pte_nosync
: There is no PSB packet at *offset* bytes from the beginning of the trace
(**pt_insn_sync_set**() only).
pte_bad_opc
: The decoder encountered an unsupported Intel PT packet opcode.
pte_bad_packet
: The decoder encountered an unsupported Intel PT packet payload.
# EXAMPLE
The following example re-synchronizes an Intel PT instruction flow decoder after
decode errors:
~~~{.c}
int foo(struct pt_insn_decoder *decoder) {
for (;;) {
int status;
status = pt_insn_sync_forward(decoder);
if (status < 0)
return status;
do {
status = decode(decoder, status);
} while (status >= 0);
}
}
~~~
# SEE ALSO
**pt_insn_alloc_decoder**(3), **pt_insn_free_decoder**(3),
**pt_insn_get_offset**(3), **pt_insn_get_sync_offset**(3),
**pt_insn_get_config**(3), **pt_insn_time**(3), **pt_insn_core_bus_ratio**(3),
**pt_insn_next**(3), **pt_insn_event**(3)

View File

@ -0,0 +1,98 @@
% PT_ISCACHE_ADD_FILE(3)
<!---
! Copyright (c) 2015-2018, 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.
!-->
# NAME
pt_iscache_add_file - add file sections to a traced memory image section cache
# SYNOPSIS
| **\#include `<intel-pt.h>`**
|
| **int pt_iscache_add_file(struct pt_image_section_cache \**iscache*,**
| **const char \**filename*, uint64_t *offset*,**
| **uint64_t *size*, uint64_t *vaddr*);**
Link with *-lipt*.
# DESCRIPTION
**pt_iscache_add_file**() adds a new section consisting of *size* bytes starting
at *offset* in *filename* loaded at *vaddr* to *iscache*.
On success, **pt_iscache_add_file**() returns a positive integer identifier that
uniquely identifies the added section in that cache. This identifier can be
used to add sections from an image section cache to one or more traced memory
images. See **pt_image_add_cached**(3). Sections added from an image section
cache will be shared across images. It can also be used to read memory from the
cached section. See **pt_iscache_read**(3).
If the cache already contains a suitable section, no section is added and the
identifier for the existing section is returned. If the cache already contains
a section that only differs in the load address, a new section is added that
shares the underlying file section.
# RETURN VALUE
**pt_iscache_add_file**() returns a positive image section identifier on success
or a negative *pt_error_code* enumeration constant in case of an error.
# ERRORS
pte_invalid
: The *iscache* or *filename* argument is NULL or the *offset* argument is too
big such that the section would start past the end of the file.
# EXAMPLE
~~~{.c}
int add_file(struct pt_image_section_cache *iscache, struct pt_image *image,
const char *filename, uint64_t offset, uint64_t size,
uint64_t vaddr, const struct pt_asid *asid) {
int isid;
isid = pt_iscache_add_file(iscache, filename, offset, size, vaddr);
if (isid < 0)
return isid;
return pt_image_add_cached(image, iscache, isid, asid);
}
~~~
# SEE ALSO
**pt_iscache_alloc**(3), **pt_iscache_free**(3), **pt_iscache_read**(3),
**pt_image_add_cached**(3)

View File

@ -0,0 +1,102 @@
% PT_ISCACHE_ALLOC(3)
<!---
! Copyright (c) 2015-2018, 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.
!-->
# NAME
pt_iscache_alloc, pt_iscache_free, pt_iscache_name - allocate/free a traced memory
image section cache
# SYNOPSIS
| **\#include `<intel-pt.h>`**
|
| **struct pt_image_section_cache \*pt_iscache_alloc(const char \**name*);**
| **const char \*pt_iscache_name(const struct pt_image_section_cache \**iscache*);**
| **void pt_iscache_free(struct pt_image_section_cache \**iscache*);**
Link with *-lipt*.
# DESCRIPTION
**pt_iscache_alloc**() allocates a new *pt_image_section_cache* and returns a
pointer to it. A *pt_image_section_cache* object contains a collection of file
sections and the virtual addresses at which those sections were loaded.
The image sections can be added to one or more *pt_image* objects. The
underlying file sections will be mapped once and their content will be shared
across images.
The *name* argument points to an optional zero-terminated name string. If the
*name* argument is NULL, it will be ignored and the returned
*pt_image_section_cache* object will not have a name. Otherwise, the returned
*pt_image_section_object* object will have a copy of the string pointed to by
the *name* argument as name.
**pt_iscache_name**() returns the name of the *pt_image_section_cache* object
the *iscache* argument points to.
**pt_iscache_free**() frees the *pt_image_section_cache* object pointed to by
*iscache*. The *iscache* argument must be NULL or point to an image section
cache that has been allocated by a call to **pt_iscache_alloc**().
# RETURN VALUE
**pt_iscache_alloc**() returns a pointer to a *pt_image_section_cache* object
on success or NULL in case of an error.
**pt_iscache_name**() returns a pointer to a zero-terminated string of NULL if the
image section cache does not have a name.
# EXAMPLE
~~~{.c}
int foo(const char *name) {
struct pt_image_section_cache *iscache;
errcode;
image = pt_iscache_alloc(name);
if (!iscache)
return pte_nomem;
errcode = bar(iscache);
pt_iscache_free(iscache);
return errcode;
}
~~~
# SEE ALSO
**pt_iscache_add_file**(3), **pt_image_add_cached**(3)

View File

@ -0,0 +1,89 @@
% PT_ISCACHE_READ(3)
<!---
! Copyright (c) 2015-2018, 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.
!-->
# NAME
pt_iscache_read - read memory from a cached file section
# SYNOPSIS
| **\#include `<intel-pt.h>`**
|
| **int pt_iscache_read(struct pt_image_section_cache \**iscache*,**
| **uint8_t \**buffer*, uint64_t *size*, int *isid*,**
| **uint64_t *vaddr*);**
Link with *-lipt*.
# DESCRIPTION
**pt_iscache_read**() reads memory from a cached file section. The file section
must have previously been added by a call to **pt_iscache_add**(3). The
*iscache* argument points to the *pt_image_section_cache* object. It must be
the same that was used in the corresponding **pt_iscache_add**(3) call. The
*buffer* argument must point to a memory buffer of at least *size* bytes. The
*isid* argument identifies the file section from which memory is read. It must
be the same identifier that was returned from the corresponding
**pt_iscache_add**(3) call that added the file section to the cache. The *vaddr*
argument gives the virtual address from which *size* bytes of memory shall be
read.
On success, **pt_iscache_read**() copies at most *size* bytes of memory from the
cached file section identified by *isid* in *iscache* starting at virtual
address *vaddr* into *buffer* and returns the number of bytes that were copied.
Multiple calls to **pt_iscache_read**() may be necessary if *size* is bigger
than 4Kbyte or if the read crosses a section boundary.
# RETURN VALUE
**pt_iscache_read**() returns the number of bytes that were read on success
or a negative *pt_error_code* enumeration constant in case of an error.
# ERRORS
pte_invalid
: The *iscache* or *buffer* argument is NULL or the *size* argument is zero.
pte_bad_image
: The *iscache* does not contain a section identified by *isid*.
pte_nomap
: The *vaddr* argument lies outside of the virtual address range of the cached
section.
# SEE ALSO
**pt_iscache_alloc**(3), **pt_iscache_free**(3), **pt_iscache_add**(3)

View File

@ -0,0 +1,73 @@
% PT_ISCACHE_SET_LIMIT(3)
<!---
! Copyright (c) 2017-2018, 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.
!-->
# NAME
pt_iscache_set_limit - set the mapped image section cache limit
# SYNOPSIS
| **\#include `<intel-pt.h>`**
|
| **int pt_iscache_set_limit(struct pt_image_section_cache \**iscache*,**
| **uint64_t *limit*);**
Link with *-lipt*.
# DESCRIPTION
**pt_iscache_set_limit**() sets the mapped image section cache limit. The
*iscache* argument points to the *pt_image_section_cache* object. The *limit*
argument gives the limit in bytes.
The image section cache will spend at most *limit* bytes to keep image sections
mapped as opposed to mapping and unmapping them when reading from them. This
includes the memory for any caches associated with the mapped section.
A *limit* of zero disables caching and clears the cache.
# RETURN VALUE
**pt_iscache_set_limit**() returns zero on success or a negative *pt_error_code*
enumeration constant in case of an error.
# ERRORS
pte_invalid
: The *iscache* argument is NULL.
# SEE ALSO
**pt_iscache_alloc**(3), **pt_iscache_free**(3), **pt_iscache_read**(3)

View File

@ -0,0 +1,72 @@
% PT_LIBRARY_VERSION(3)
<!---
! Copyright (c) 2015-2018, 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.
!-->
# NAME
pt_library_version - version information
# SYNOPSIS
| **\#include `<intel-pt.h>`**
|
| **struct pt_version pt_library_version();**
Link with *-lipt*.
# DESCRIPTION
**pt_library_version**() returns the decoder library version.
# RETURN VALUE
**pt_library_version**() returns a *pt_version* structure which is declared as:
~~~{.c}
/** The library version. */
struct pt_version {
/** Major version number. */
uint8_t major;
/** Minor version number. */
uint8_t minor;
/** Reserved bits. */
uint16_t reserved;
/** Build number. */
uint32_t build;
/** Version extension. */
const char *ext;
};
~~~

197
doc/man/pt_packet.3.md Normal file
View File

@ -0,0 +1,197 @@
% PT_PACKET(3)
<!---
! Copyright (c) 2015-2018, 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.
!-->
# NAME
pt_packet, pt_enc_next, pt_pkt_next - encode/decode an Intel(R) Processor Trace
packet
# SYNOPSIS
| **\#include `<intel-pt.h>`**
|
| **struct pt_packet;**
|
| **int pt_enc_next(struct pt_packet_encoder \**encoder*,**
| **const struct pt_packet \**packet*);**
|
| **int pt_pkt_next(struct pt_packet_decoder \**decoder*,**
| **struct pt_packet \**packet*, size_t *size*);**
Link with *-lipt*.
# DESCRIPTION
**pt_enc_next**() encodes its *packet* argument as Intel Processor Trace (Intel
PT) packet at *encoder*'s current position. On success, sets *encoder*'s
current position to point to the first byte after the encoded packet.
**pt_pkt_next**() decodes the Intel PT packet at decoder*'s current position
into *packet*. On success, sets *decoder*'s current position to point to the
first byte after the decoded packet.
The caller is responsible for allocating and freeing the *pt_packet* object
pointed to be the *packet* argument.
The *size* argument of **pt_pkt_next**() must be set to *sizeof(struct
pt_packet)*. The function will provide at most *size* bytes of packet data. A
newer decoder library may provide packet types that are not yet defined. Those
packets may be truncated. Unknown packet types should be ignored.
If the packet decoder does not know the packet opcode at *decoder*'s current
position and if *decoder*'s configuration contains a packet decode callback
function, **pt_pkt_next**() will call that callback function to decode the
unknown packet. On success, a *ppt_unknown* packet type is provided with the
information provided by the decode callback function.
An Intel PT packet is described by the *pt_packet* structure, which is declared
as:
~~~{.c}
/** An Intel PT packet. */
struct pt_packet {
/** The type of the packet.
*
* This also determines the \@variant field.
*/
enum pt_packet_type type;
/** The size of the packet including opcode and payload. */
uint8_t size;
/** Packet specific data. */
union {
/** Packets: pad, ovf, psb, psbend, stop - no payload. */
/** Packet: tnt-8, tnt-64. */
struct pt_packet_tnt tnt;
/** Packet: tip, fup, tip.pge, tip.pgd. */
struct pt_packet_ip ip;
/** Packet: mode. */
struct pt_packet_mode mode;
/** Packet: pip. */
struct pt_packet_pip pip;
/** Packet: tsc. */
struct pt_packet_tsc tsc;
/** Packet: cbr. */
struct pt_packet_cbr cbr;
/** Packet: tma. */
struct pt_packet_tma tma;
/** Packet: mtc. */
struct pt_packet_mtc mtc;
/** Packet: cyc. */
struct pt_packet_cyc cyc;
/** Packet: vmcs. */
struct pt_packet_vmcs vmcs;
/** Packet: mnt. */
struct pt_packet_mnt mnt;
/** Packet: unknown. */
struct pt_packet_unknown unknown;
} payload;
};
~~~
See the *intel-pt.h* header file for more detail.
# RETURN VALUE
**pt_enc_next**() returns the number of bytes written on success or a negative
*pt_error_code* enumeration constant in case of an error.
**pt_pkt_next**() returns the number of bytes consumed on success or a negative
*pt_error_code* enumeration constant in case of an error.
# ERRORS
pte_invalid
: The *encoder*/*decoder* or *packet* argument is NULL or the *size* argument
is zero (**pt_pkt_next**() only).
pte_nosync
: *decoder* has not been synchronized onto the trace stream (**pt_pkt_next**()
only). Use **pt_pkt_sync_forward**(3), **pt_pkt_sync_backward**(3), or
**pt_pkt_sync_set**(3) to synchronize *decoder*.
pte_eos
: Encode/decode has reached the end of the trace buffer. There is not enough
space in the trace buffer to generate *packet* (**pt_enc_next**()) or the
trace buffer does not contain a full Intel PT packet (**pt_pkt_next**()).
pte_bad_opc
: The type of the *packet* argument is not supported (**pt_enc_next**()) or
the packet at *decoder*'s current position is not supported
(**pt_pkt_next**()).
pte_bad_packet
: The payload or parts of the payload of the *packet* argument is not
supported (**pt_enc_next**()) or the packet at *decoder*'s current position
contains unsupported payload (**pt_pkt_next**()).
# EXAMPLE
The example shows a typical Intel PT packet decode loop.
~~~{.c}
int foo(struct pt_packet_decoder *decoder) {
for (;;) {
struct pt_packet packet;
int errcode;
errcode = pt_pkt_next(decoder, &packet, sizeof(packet));
if (errcode < 0)
return errcode;
[...]
}
}
~~~
# SEE ALSO
**pt_alloc_encoder**(3), **pt_pkt_alloc_decoder**(3),
**pt_pkt_sync_forward**(3), **pt_pkt_sync_backward**(3), **pt_pkt_sync_set**(3)

View File

@ -0,0 +1,98 @@
% PT_PKT_ALLOC_DECODER(3)
<!---
! Copyright (c) 2015-2018, 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.
!-->
# NAME
pt_pkt_alloc_decoder, pt_pkt_free_decoder - allocate/free an Intel(R) Processor
Trace packet decoder
# SYNOPSIS
| **\#include `<intel-pt.h>`**
|
| **struct pt_packet_decoder \***
| **pt_pkt_alloc_decoder(const struct pt_config \**config*);**
|
| **void pt_pkt_free_decoder(struct pt_packet_decoder \**decoder*);**
Link with *-lipt*.
# DESCRIPTION
**pt_pkt_alloc_decoder**() allocates a new Intel Processor Trace (Intel PT)
packet decoder and returns a pointer to it. The packet decoder decodes raw
Intel PT trace into a stream of *pt_packet* objects. See **pt_pkt_next**(3).
The *config* argument points to a *pt_config* object. See **pt_config**(3).
The *config* argument will not be referenced by the returned decoder but the
trace buffer defined by the *config* argument's *begin* and *end* fields will.
The returned packet decoder needs to be synchronized onto the trace stream
before it can be used. To synchronize the packet decoder, use
**pt_pkt_sync_forward**(3), **pt_pkt_sync_backward**(3), or
**pt_pkt_sync_set**(3).
**pt_pkt_free_decoder**() frees the Intel PT packet decoder pointed to by
*decoder*. The *decoder* argument must be NULL or point to a decoder that has
been allocated by a call to **pt_pkt_alloc_decoder**().
# RETURN VALUE
**pt_pkt_alloc_decoder**() returns a pointer to a *pt_packet_decoder* object on
success or NULL in case of an error.
# EXAMPLE
~~~{.c}
int foo(const struct pt_config *config) {
struct pt_packet_decoder *decoder;
errcode;
decoder = pt_pkt_alloc_decoder(config);
if (!decoder)
return pte_nomem;
errcode = bar(decoder);
pt_pkt_free_decoder(decoder);
return errcode;
}
~~~
# SEE ALSO
**pt_config**(3), **pt_pkt_sync_forward**(3), **pt_pkt_sync_backward**(3),
**pt_pkt_sync_set**(3), **pt_pkt_get_offset**(3), **pt_pkt_get_sync_offset**(3),
**pt_pkt_get_config**(3), **pt_pkt_next**(3)

View File

@ -0,0 +1,81 @@
% PT_PKT_GET_OFFSET(3)
<!---
! Copyright (c) 2015-2018, 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.
!-->
# NAME
pt_pkt_get_offset, pt_pkt_get_sync_offset - get an Intel(R) Processor Trace
packet decoder's current/synchronization trace buffer offset
# SYNOPSIS
| **\#include `<intel-pt.h>`**
|
| **int pt_pkt_get_offset(const struct pt_packet_decoder \**decoder*,**
| **uint64_t \**offset*);**
| **int pt_pkt_get_sync_offset(const struct pt_packet_decoder \**decoder*,**
| **uint64_t \**offset*);**
Link with *-lipt*.
# DESCRIPTION
**pt_pkt_get_offset**() provides *decoder*'s current position as offset in bytes
from the beginning of *decoder*'s trace buffer in the unsigned integer variable
pointed to by *offset*.
**pt_pkt_get_sync_offset**() provides *decoder*'s last synchronization point as
offset in bytes from the beginning of *decoder*'s trace buffer in the unsigned
integer variable pointed to by *offset*.
# RETURN VALUE
Both functions return zero on success or a negative *pt_error_code* enumeration
constant in case of an error.
# ERRORS
pte_invalid
: The *decoder* or *offset* argument is NULL.
pte_nosync
: *decoder* has not been synchronized onto the trace stream. Use
**pt_pkt_sync_forward**(3), **pt_pkt_sync_backward**(3), or
**pt_pkt_sync_set**(3) to synchronize *decoder*.
# SEE ALSO
**pt_pkt_alloc_decoder**(3), **pt_pkt_free_decoder**(3),
**pt_pkt_sync_forward**(3), **pt_pkt_sync_backward**(3),
**pt_pkt_sync_set**(3), **pt_pkt_next**(3)

View File

@ -0,0 +1,115 @@
% PT_PKT_SYNC_FORWARD(3)
<!---
! Copyright (c) 2015-2018, 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.
!-->
# NAME
pt_pkt_sync_forward, pt_pkt_sync_backward, pt_pkt_sync_set - synchronize an
Intel(R) Processor Trace packet decoder
# SYNOPSIS
| **\#include `<intel-pt.h>`**
|
| **int pt_pkt_sync_forward(struct pt_packet_decoder \**decoder*);**
| **int pt_pkt_sync_backward(struct pt_packet_decoder \**decoder*);**
| **int pt_pkt_sync_set(struct pt_packet_decoder \**decoder*,**
| **uint64_t *offset*);**
Link with *-lipt*.
# DESCRIPTION
**pt_pkt_sync_forward**() and **pt_pkt_sync_backward**() synchronize an Intel
Processor Trace (Intel PT) packet decoder pointed to by *decoder* onto the trace
stream in *decoder*'s trace buffer. They search for a Packet Stream Boundary
(PSB) packet in the trace stream and, if successful, set *decoder*'s current
position to that packet.
**pt_pkt_sync_forward**() searches in forward direction from *decoder*'s current
position towards the end of the trace buffer. If *decoder* has been newly
allocated and has not been synchronized yet, the search starts from the
beginning of the trace.
**pt_pkt_sync_backward**() searches in backward direction from *decoder*'s
current position towards the beginning of the trace buffer. If *decoder* has
been newly allocated and has not been synchronized yet, the search starts from
the end of the trace.
**pt_pkt_sync_set**() sets *decoder*'s current position to *offset* bytes from
the beginning of its trace buffer.
# RETURN VALUE
All synchronization functions return zero or a positive value on success or a
negative *pt_error_code* enumeration constant in case of an error.
# ERRORS
pte_invalid
: The *decoder* argument is NULL.
pte_eos
: There is no (further) PSB packet in the trace stream
(**pt_pkt_sync_forward**() and **pt_pkt_sync_backward**()) or the *offset*
argument is too big and the resulting position would be outside of
*decoder*'s trace buffer (**pt_pkt_sync_set**()).
# EXAMPLE
The following example re-synchronizes an Intel PT packet decoder after decode
errors:
~~~{.c}
int foo(struct pt_packet_decoder *decoder) {
for (;;) {
int errcode;
errcode = pt_pkt_sync_forward(decoder);
if (errcode < 0)
return errcode;
do {
errcode = decode(decoder);
} while (errcode >= 0);
}
}
~~~
# SEE ALSO
**pt_pkt_alloc_decoder**(3), **pt_pkt_free_decoder**(3),
**pt_pkt_get_offset**(3), **pt_pkt_get_sync_offset**(3),
**pt_pkt_get_config**(3), **pt_pkt_next**(3)

View File

@ -0,0 +1,113 @@
% PT_QRY_ALLOC_DECODER(3)
<!---
! Copyright (c) 2015-2018, 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.
!-->
# NAME
pt_qry_alloc_decoder, pt_qry_free_decoder - allocate/free an Intel(R) Processor
Trace query decoder
# SYNOPSIS
| **\#include `<intel-pt.h>`**
|
| **struct pt_query_decoder \***
| **pt_qry_alloc_decoder(const struct pt_config \**config*);**
|
| **void pt_qry_free_decoder(struct pt_query_decoder \**decoder*);**
Link with *-lipt*.
# DESCRIPTION
A query decoder decodes raw Intel Processor Trace (Intel PT) and provides
functions for querying the decoder about:
- whether the next conditional branch was taken (or not taken)
- the destination of the next indirect branch
This information can be used to reconstruct the execution flow of the traced
code. As long as the flow is clear, follow the flow. If the flow cannot be
determined by examining the current instruction, ask the query decoder.
In addition, the query decoder indicates asynchronous events via the return
value of its query functions and provides an additional function to query for
such asynchronous events. See **pt_qry_cond_branch**(3),
**pt_qry_indirect_branch**(3), and **pt_qry_event**(3).
**pt_qry_alloc_decoder**() allocates a new query decoder and returns a pointer
to it. The *config* argument points to a *pt_config* object. See
**pt_config**(3). The *config* argument will not be referenced by the returned
decoder but the trace buffer defined by the *config* argument's *begin* and
*end* fields will.
The returned query decoder needs to be synchronized onto the trace stream
before it can be used. To synchronize the query decoder, use
**pt_qry_sync_forward**(3), **pt_qry_sync_backward**(3), or
**pt_qry_sync_set**(3).
**pt_qry_free_decoder**() frees the Intel PT query decoder pointed to by
*decoder*. The *decoder* argument must be NULL or point to a decoder that has
been allocated by a call to **pt_qry_alloc_decoder**().
# RETURN VALUE
**pt_qry_alloc_decoder**() returns a pointer to a *pt_query_decoder* object on
success or NULL in case of an error.
# EXAMPLE
~~~{.c}
int foo(const struct pt_config *config) {
struct pt_query_decoder *decoder;
errcode;
decoder = pt_qry_alloc_decoder(config);
if (!decoder)
return pte_nomem;
errcode = bar(decoder);
pt_qry_free_decoder(decoder);
return errcode;
}
~~~
# SEE ALSO
**pt_config**(3), **pt_qry_sync_forward**(3), **pt_qry_sync_backward**(3),
**pt_qry_sync_set**(3), **pt_qry_get_offset**(3), **pt_qry_get_sync_offset**(3),
**pt_qry_get_config**(3), **pt_qry_cond_branch**(3),
**pt_qry_indirect_branch**(3), **pt_qry_event**(3), **pt_qry_time**(3),
**pt_qry_core_bus_ratio**(3)

View File

@ -0,0 +1,152 @@
% PT_QRY_COND_BRANCH(3)
<!---
! Copyright (c) 2015-2018, 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.
!-->
# NAME
pt_qry_cond_branch, pt_qry_indirect_branch - query an Intel(R) Processor Trace
query decoder
# SYNOPSIS
| **\#include `<intel-pt.h>`**
|
| **int pt_qry_cond_branch(struct pt_query_decoder \**decoder*,**
| **int \**taken*);**
| **int pt_qry_indirect_branch(struct pt_query_decoder \**decoder*,**
| **uint64_t \**ip*);
Link with *-lipt*.
# DESCRIPTION
**pt_qry_cond_branch**() uses Intel Processor Trace (Intel PT) to determine
whether the next conditional branch in the traced code was taken or was not
taken. The *decoder* argument must point to an Intel PT query decoder.
On success, sets the variable the *taken* argument points to a non-zero value
if the next condition branch is taken and to zero if it is not taken.
**pt_qry_indirect_branch**() uses Intel Processor Trace (Intel PT) to determine
the destination virtual address of the next indirect branch in the traced code.
On success, provides the destination address in the integer variable pointed to
be the *ip* argument. If the destination address has been suppressed in the
Intel PT trace, the lack of an IP is indicated in the return value by setting
the *pts_ip_suppressed* bit.
# RETURN VALUE
Both functions return zero or a positive value on success or a negative
*pt_error_code* enumeration constant in case of an error.
On success, a bit-vector of *pt_status_flag* enumeration constants is returned.
The *pt_status_flag* enumeration is declared as:
~~~{.c}
/** Decoder status flags. */
enum pt_status_flag {
/** There is an event pending. */
pts_event_pending = 1 << 0,
/** The address has been suppressed. */
pts_ip_suppressed = 1 << 1,
/** There is no more trace data available. */
pts_eos = 1 << 2
};
~~~
# ERRORS
pte_invalid
: The *decoder* argument or the *taken* (**pt_qry_cond_branch**()) or *ip*
(**pt_qry_indirect_branch**()) argument is NULL.
pte_eos
: Decode reached the end of the trace stream.
pte_nosync
: The decoder has not been synchronized onto the trace stream. Use
**pt_qry_sync_forward**(3), **pt_qry_sync_backward**(3), or
**pt_qry_sync_set**(3) to synchronize *decoder*.
pte_bad_opc
: The decoder encountered an unsupported Intel PT packet opcode.
pte_bad_packet
: The decoder encountered an unsupported Intel PT packet payload.
pte_bad_query
: The query does not match the data provided in the Intel PT stream. Based on
the trace, the decoder expected a call to the other query function or a call
to **pt_qry_event**(3). This usually means that execution flow
reconstruction and trace got out of sync.
# EXAMPLE
The following example sketches an execution flow reconstruction loop.
Asynchronous events have been omitted.
~~~{.c}
int foo(struct pt_query_decoder *decoder, uint64_t ip) {
for (;;) {
if (insn_is_cond_branch(ip)) {
int errcode, taken;
errcode = pt_qry_cond_branch(decoder, &taken);
if (errcode < 0)
return errcode;
if (taken)
ip = insn_destination(ip);
else
ip = insn_next_ip(ip);
} else if (insn_is_indirect_branch(ip)) {
int errcode;
errcode = pt_qry_indirect_branch(decoder, &ip);
if (errcode < 0)
return errcode;
} else
ip = insn_next_ip(ip);
}
}
~~~
# SEE ALSO
**pt_qry_alloc_decoder**(3), **pt_qry_free_decoder**(3),
**pt_qry_event**(3), **pt_qry_time**(3), **pt_qry_core_bus_ratio**(3)

291
doc/man/pt_qry_event.3.md Normal file
View File

@ -0,0 +1,291 @@
% PT_QRY_EVENT(3)
<!---
! Copyright (c) 2015-2018, 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.
!-->
# NAME
pt_qry_event, pt_insn_event, pt_blk_event - query an Intel(R) Processor Trace
decoder for an asynchronous event
# SYNOPSIS
| **\#include `<intel-pt.h>`**
|
| **int pt_qry_event(struct pt_query_decoder \**decoder*,**
| **struct pt_event \**event*, size_t *size*);**
|
| **int pt_insn_event(struct pt_insn_decoder \**decoder*,**
| **struct pt_event \**event*, size_t *size*);**
|
| **int pt_blk_event(struct pt_block_decoder \**decoder*,**
| **struct pt_event \**event*, size_t *size*);**
Link with *-lipt*.
# DESCRIPTION
**pt_qry_event**(), **pt_insn_event**(), and **pt_blk_event**() provide the next
pending asynchronous event in *decoder*'s Intel Processor Trace (Intel PT)
decode in the *pt_event* object pointed to by the *event* argument.
The *size* argument must be set to *sizeof(struct pt_event)*. The function will
provide at most *size* bytes of the *pt_event* structure. A newer decoder
library may provide event types that are not yet defined. Those events may be
truncated.
On success, detailed information about the event is provided in the *pt_event*
object pointed to by the *event* argument. The *pt_event* structure is declared
as:
~~~{.c}
/** An event. */
struct pt_event {
/** The type of the event. */
enum pt_event_type type;
/** A flag indicating that the event IP has been
* suppressed.
*/
uint32_t ip_suppressed:1;
/** A flag indicating that the event is for status update. */
uint32_t status_update:1;
/** A flag indicating that the event has timing
* information.
*/
uint32_t has_tsc:1;
/** The time stamp count of the event.
*
* This field is only valid if \@has_tsc is set.
*/
uint64_t tsc;
/** The number of lost mtc and cyc packets.
*
* This gives an idea about the quality of the \@tsc. The
* more packets were dropped, the less precise timing is.
*/
uint32_t lost_mtc;
uint32_t lost_cyc;
/* Reserved space for future extensions. */
uint64_t reserved[2];
/** Event specific data. */
union {
/** Event: enabled. */
struct {
/** The address at which tracing resumes. */
uint64_t ip;
/** A flag indicating that tracing resumes from the IP
* at which tracing had been disabled before.
*/
uint32_t resumed:1;
} enabled;
/** Event: disabled. */
struct {
/** The destination of the first branch inside a
* filtered area.
*
* This field is not valid if \@ip_suppressed is set.
*/
uint64_t ip;
/* The exact source ip needs to be determined using
* disassembly and the filter configuration.
*/
} disabled;
[...]
} variant;
};
~~~
See the *intel-pt.h* header file for more detail. The common fields of the
*pt_event* structure are described in more detail below:
type
: The type of the event as a *pt_event_type* enumeration, which is declared
as:
~~~{.c}
/** Event types. */
enum pt_event_type {
/* Tracing has been enabled/disabled. */
ptev_enabled,
ptev_disabled,
/* Tracing has been disabled asynchronously. */
ptev_async_disabled,
/* An asynchronous branch, e.g. interrupt. */
ptev_async_branch,
/* A synchronous paging event. */
ptev_paging,
/* An asynchronous paging event. */
ptev_async_paging,
/* Trace overflow. */
ptev_overflow,
/* An execution mode change. */
ptev_exec_mode,
/* A transactional execution state change. */
ptev_tsx,
/* Trace Stop. */
ptev_stop,
/* A synchronous vmcs event. */
ptev_vmcs,
/* An asynchronous vmcs event. */
ptev_async_vmcs,
/* Execution has stopped. */
ptev_exstop,
/* An MWAIT operation completed. */
ptev_mwait,
/* A power state was entered. */
ptev_pwre,
/* A power state was exited. */
ptev_pwrx,
/* A PTWRITE event. */
ptev_ptwrite,
/* A timing event. */
ptev_tick,
/* A core:bus ratio event. */
ptev_cbr,
/* A maintenance event. */
ptev_mnt
};
~~~
ip_suppressed
: A flag indicating whether the *ip* field in the event-dependent part is not
valid because the value has been suppressed in the trace.
status_update
: A flag indicating whether the event is for updating the decoder's status.
Status update events originate from Intel PT packets in PSB+.
has_tsc
: A flag indicating that the event's timing-related fields *tsc*, *lost_mtc*,
and *lost_cyc* are valid.
tsc
: The last time stamp count before the event. Depending on the timing
configuration, the timestamp can be more or less precise. For
cycle-accurate tracing, event packets are typically CYC-eligible so the
timestamp should be cycle-accurate.
lost_mtc, lost_cyc
: The number of lost MTC and CYC updates. An update is lost if the decoder
was not able to process an MTC or CYC packet due to missing information.
This can be either missing calibration or missing configuration information.
The number of lost MTC and CYC updates gives a rough idea about the quality
of the *tsc* field.
variant
: This field contains event-specific information. See the *intel-pt.h* header
file for details.
# RETURN VALUE
**pt_qry_event**(), **pt_insn_event**(), and **pt_blk_event**() return zero or a
*positive value on success or a negative pt_error_code* enumeration constant in
*case of an error.
On success, a bit-vector of *pt_status_flag* enumeration constants is returned.
The *pt_status_flag* enumeration is declared as:
~~~{.c}
/** Decoder status flags. */
enum pt_status_flag {
/** There is an event pending. */
pts_event_pending = 1 << 0,
/** The address has been suppressed. */
pts_ip_suppressed = 1 << 1,
/** There is no more trace data available. */
pts_eos = 1 << 2
};
~~~
# ERRORS
pte_invalid
: The *decoder* or *event* argument is NULL or the *size* argument is too
small.
pte_eos
: Decode reached the end of the trace stream.
pte_nosync
: The decoder has not been synchronized onto the trace stream. Use
**pt_qry_sync_forward**(3), **pt_qry_sync_backward**(3), or
**pt_qry_sync_set**(3) to synchronize *decoder*.
pte_bad_opc
: The decoder encountered an unsupported Intel PT packet opcode.
pte_bad_packet
: The decoder encountered an unsupported Intel PT packet payload.
pte_bad_query
: The query does not match the data provided in the Intel PT stream. Based on
the trace, the decoder expected a call to **pt_qry_cond_branch**(3) or
**pt_qry_indirect_branch**(3). This usually means that execution flow
reconstruction and trace got out of sync.
# SEE ALSO
**pt_qry_alloc_decoder**(3), **pt_qry_free_decoder**(3),
**pt_qry_cond_branch**(3), **pt_qry_indirect_branch**(3), **pt_qry_time**(3),
**pt_qry_core_bus_ratio**(3), **pt_insn_next**(3), **pt_blk_next**(3)

View File

@ -0,0 +1,83 @@
% PT_QRY_GET_OFFSET(3)
<!---
! Copyright (c) 2015-2018, 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.
!-->
# NAME
pt_qry_get_offset, pt_qry_get_sync_offset - get an Intel(R) Processor Trace
query decoder's current/synchronization trace buffer offset
# SYNOPSIS
| **\#include `<intel-pt.h>`**
|
| **int pt_qry_get_offset(const struct pt_query_decoder \**decoder*,**
| **uint64_t \**offset*);**
| **int pt_qry_get_sync_offset(const struct pt_query_decoder \**decoder*,**
| **uint64_t \**offset*);**
Link with *-lipt*.
# DESCRIPTION
**pt_qry_get_offset**() provides *decoder*'s current position as offset in bytes
from the beginning of *decoder*'s trace buffer in the unsigned integer variable
pointed to by *offset*.
**pt_qry_get_sync_offset**() provides *decoder*'s last synchronization point as
offset in bytes from the beginning of *decoder*'s trace buffer in the unsigned
integer variable pointed to by *offset*.
# RETURN VALUE
Both functions return zero on success or a negative *pt_error_code* enumeration
constant in case of an error.
# ERRORS
pte_invalid
: The *decoder* or *offset* argument is NULL.
pte_nosync
: *decoder* has not been synchronized onto the trace stream. Use
**pt_qry_sync_forward**(3), **pt_qry_sync_backward**(3), or
**pt_qry_sync_set**(3) to synchronize *decoder*.
# SEE ALSO
**pt_qry_alloc_decoder**(3), **pt_qry_free_decoder**(3),
**pt_qry_sync_forward**(3), **pt_qry_sync_backward**(3),
**pt_qry_sync_set**(3), **pt_qry_get_config**(3), **pt_qry_cond_branch**(3),
**pt_qry_indirect_branch**(3), **pt_qry_event**(3), **pt_qry_time**(3),
**pt_qry_core_bus_ratio**(3)

View File

@ -0,0 +1,152 @@
% PT_QRY_SYNC_FORWARD(3)
<!---
! Copyright (c) 2015-2018, 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.
!-->
# NAME
pt_qry_sync_forward, pt_qry_sync_backward, pt_qry_sync_set - synchronize an
Intel(R) Processor Trace query decoder
# SYNOPSIS
| **\#include `<intel-pt.h>`**
|
| **int pt_qry_sync_forward(struct pt_query_decoder \**decoder*,**
| **uint64_t \**ip*);**
| **int pt_qry_sync_backward(struct pt_query_decoder \**decoder*,**
| **uint64_t \**ip*);**
| **int pt_qry_sync_set(struct pt_query_decoder \**decoder*,**
| **uint64_t \**ip*, uint64_t *offset*);**
Link with *-lipt*.
# DESCRIPTION
These functions synchronize an Intel Processor Trace (Intel PT) query decoder
pointed to by *decoder* onto the trace stream in *decoder*'s trace buffer.
They search for a Packet Stream Boundary (PSB) packet in the trace stream and,
if successful, set *decoder*'s current position and synchronization position to
that packet and start processing packets. For synchronization to be
successfull, there must be a full PSB+ header in the trace stream.
If the *ip* argument is not NULL, these functions provide the code memory
address at which tracing starts in the variable pointed to by *ip*. If tracing
is disabled at the synchronization point, the lack of an IP is indicated in the
return value by setting the *pts_ip_suppressed* bit.
**pt_qry_sync_forward**() searches in forward direction from *decoder*'s current
position towards the end of the trace buffer. If *decoder* has been newly
allocated and has not been synchronized yet, the search starts from the
beginning of the trace.
**pt_qry_sync_backward**() searches in backward direction from *decoder*'s
current position towards the beginning of the trace buffer. If *decoder* has
been newly allocated and has not been synchronized yet, the search starts from
the end of the trace.
**pt_qry_sync_set**() searches at *offset* bytes from the beginning of its trace
buffer.
# RETURN VALUE
All synchronization functions return zero or a positive value on success or a
negative *pt_error_code* enumeration constant in case of an error.
On success, a bit-vector of *pt_status_flag* enumeration constants is returned.
The *pt_status_flag* enumeration is declared as:
~~~{.c}
/** Decoder status flags. */
enum pt_status_flag {
/** There is an event pending. */
pts_event_pending = 1 << 0,
/** The address has been suppressed. */
pts_ip_suppressed = 1 << 1,
/** There is no more trace data available. */
pts_eos = 1 << 2
};
~~~
# ERRORS
pte_invalid
: The *decoder* argument is NULL.
pte_eos
: There is no (further) PSB+ header in the trace stream
(**pt_qry_sync_forward**() and **pt_qry_sync_backward**()) or at *offset*
bytes into the trace buffer (**pt_qry_sync_set**()).
pte_nosync
: There is no PSB packet at *offset* bytes from the beginning of the trace
(**pt_qry_sync_set**() only).
pte_bad_opc
: The decoder encountered an unsupported Intel PT packet opcode.
pte_bad_packet
: The decoder encountered an unsupported Intel PT packet payload.
# EXAMPLE
The following example re-synchronizes an Intel PT query decoder after decode
errors:
~~~{.c}
int foo(struct pt_query_decoder *decoder) {
for (;;) {
int errcode;
errcode = pt_qry_sync_forward(decoder);
if (errcode < 0)
return errcode;
do {
errcode = decode(decoder);
} while (errcode >= 0);
}
}
~~~
# SEE ALSO
**pt_qry_alloc_decoder**(3), **pt_qry_free_decoder**(3),
**pt_qry_get_offset**(3), **pt_qry_get_sync_offset**(3),
**pt_qry_get_config**(3), **pt_qry_cond_branch**(3),
**pt_qry_indirect_branch**(3), **pt_qry_event**(3), **pt_qry_time**(3),
**pt_qry_core_bus_ratio**(3)

128
doc/man/pt_qry_time.3.md Normal file
View File

@ -0,0 +1,128 @@
% PT_QRY_TIME(3)
<!---
! Copyright (c) 2015-2018, 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.
!-->
# NAME
pt_qry_time, pt_qry_core_bus_ratio, pt_insn_time, pt_insn_core_bus_ratio,
pt_blk_time, pt_blk_core_bus_ratio - query an Intel(R) Processor Trace decoder
for timing information
# SYNOPSIS
| **\#include `<intel-pt.h>`**
|
| **int pt_qry_time(struct pt_query_decoder \**decoder*, uint64_t \**time*,**
| **uint32_t \**lost_mtc*, uint32_t \**lost_cyc*);**
| **int pt_qry_core_bus_ratio(struct pt_query_decoder \**decoder*,**
| **uint32_t \**cbr*);**
|
| **int pt_insn_time(struct pt_insn_decoder \**decoder*, uint64_t \**time*,**
| **uint32_t \**lost_mtc*, uint32_t \**lost_cyc*);**
| **int pt_insn_core_bus_ratio(struct pt_insn_decoder \**decoder*,**
| **uint32_t \**cbr*);**
|
| **int pt_blk_time(struct pt_block_decoder \**decoder*, uint64_t \**time*,**
| **uint32_t \**lost_mtc*, uint32_t \**lost_cyc*);**
| **int pt_blk_core_bus_ratio(struct pt_block_decoder \**decoder*,**
| **uint32_t \**cbr*);**
Link with *-lipt*.
# DESCRIPTION
**pt_qry_time**(), **pt_insn_time**(), and **pt_blk_time**() provide the current
estimated timestamp count (TSC) value in the unsigned integer variable pointed
to by the *time* argument. The returned value corresponds to what an **rdtsc**
instruction would have returned.
At configurable intervals, Intel PT contains the full, accurate TSC value.
Between those intervals, the timestamp count is estimated using a collection of
lower-bandwidth packets, the Mini Time Counter (MTC) packet and the Cycle Count
Packet (CYC). Depending on the Intel PT configuration, timing can be very
precise at the cost of increased bandwidth or less precise but requiring lower
bandwidth.
The decoder needs to be calibrated in order to translate Cycle Counter ticks
into Core Crystal Clock ticks. Without calibration, CYC packets need to be
dropped. The decoder calibrates itself using MTC, CYC, and CBR packets.
To interpret MTC and CYC packets, the decoder needs additional information
provided in respective fields in the *pt_config* structure. Lacking this
information, MTC packets may need to be dropped. This will impact the precision
of the estimated timestamp count by losing periodic updates and it will impact
calibration, which may result in reduced precision for cycle-accurate timing.
The number of dropped MTC and CYC packets gives a rough idea about the quality
of the estimated timestamp count. The value of dropped MTC and CYC packets is
given in the unsigned integer variables pointed to by the *lost_mtc* and
*lost_cyc* arguments respectively. If one or both of the arguments is NULL, no
information on lost packets is provided for the respective packet type.
**pt_qry_core_bus_ratio**(), **pt_insn_core_bus_ratio**(), and
**pt_blk_core_bus_ratio**() give the last known core:bus ratio as provided by
the Core Bus Ratio (CBR) Intel PT packet.
# RETURN VALUE
All functions return zero on success or a negative *pt_error_code* enumeration
constant in case of an error.
# ERRORS
pte_invalid
: The *decoder* or *time* (**pt_qry_time**(), **pt_insn_time**(), and
**pt_blk_time**()) or *cbr* (**pt_qry_core_bus_ratio**(),
**pt_insn_core_bus_ratio**(), and **pt_blk_core_bus_ratio**()) argument is
NULL.
pte_no_time
: There has not been a TSC packet to provide the full, accurate Time Stamp
Count. There may have been MTC or CYC packets, so the provided *time* may
be non-zero. It is zero if there has not been any timing packet yet.
Depending on the Intel PT configuration, TSC packets may not have been
enabled. In this case, the *time* value provides the relative time based on
other timing packets.
pte_no_cbr
: There has not been a CBR packet to provide the core:bus ratio. The *cbr*
value is undefined in this case.
# SEE ALSO
**pt_qry_alloc_decoder**(3), **pt_qry_free_decoder**(3),
**pt_qry_cond_branch**(3), **pt_qry_indirect_branch**(3), **pt_qry_event**(3),
**pt_insn_alloc_decoder**(3), **pt_insn_free_decoder**(3), **pt_insn_next**(3),
**pt_blk_alloc_decoder**(3), **pt_blk_free_decoder**(3), **pt_blk_next**(3)

259
include/posix/threads.h Normal file
View File

@ -0,0 +1,259 @@
/*
* Copyright (c) 2014-2018, 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.
*
*
* It looks like there is still no support for C11's threads.h.
*
* We implement the few features we actually need hoping that this file will
* soon go away.
*/
#ifndef THREADS_H
#define THREADS_H
#include <pthread.h>
#ifndef PTHREAD_MUTEX_NORMAL
# define PTHREAD_MUTEX_NORMAL PTHREAD_MUTEX_TIMED_NP
#endif
#include <stdint.h>
#include <stdlib.h>
enum {
thrd_success = 1,
thrd_error
};
struct pt_thread {
pthread_t thread;
};
typedef struct pt_thread thrd_t;
typedef int (*thrd_start_t)(void *);
struct thrd_args {
thrd_start_t fun;
void *arg;
};
static void *thrd_routine(void *arg)
{
struct thrd_args *args;
int result;
args = arg;
if (!args)
return (void *) (intptr_t) -1;
result = -1;
if (args->fun)
result = args->fun(args->arg);
free(args);
return (void *) (intptr_t) result;
}
static inline int thrd_create(thrd_t *thrd, thrd_start_t fun, void *arg)
{
struct thrd_args *args;
int errcode;
if (!thrd || !fun)
return thrd_error;
args = malloc(sizeof(*args));
if (!args)
return thrd_error;
args->fun = fun;
args->arg = arg;
errcode = pthread_create(&thrd->thread, NULL, thrd_routine, args);
if (errcode) {
free(args);
return thrd_error;
}
return thrd_success;
}
static inline int thrd_join(thrd_t *thrd, int *res)
{
void *result;
int errcode;
if (!thrd)
return thrd_error;
errcode = pthread_join(thrd->thread, &result);
if (errcode)
return thrd_error;
if (res)
*res = (int) (intptr_t) result;
return thrd_success;
}
struct pt_mutex {
pthread_mutex_t mutex;
};
typedef struct pt_mutex mtx_t;
enum {
mtx_plain = PTHREAD_MUTEX_NORMAL
};
static inline int mtx_init(mtx_t *mtx, int type)
{
int errcode;
if (!mtx || type != mtx_plain)
return thrd_error;
errcode = pthread_mutex_init(&mtx->mutex, NULL);
if (errcode)
return thrd_error;
return thrd_success;
}
static inline void mtx_destroy(mtx_t *mtx)
{
if (mtx)
(void) pthread_mutex_destroy(&mtx->mutex);
}
static inline int mtx_lock(mtx_t *mtx)
{
int errcode;
if (!mtx)
return thrd_error;
errcode = pthread_mutex_lock(&mtx->mutex);
if (errcode)
return thrd_error;
return thrd_success;
}
static inline int mtx_unlock(mtx_t *mtx)
{
int errcode;
if (!mtx)
return thrd_error;
errcode = pthread_mutex_unlock(&mtx->mutex);
if (errcode)
return thrd_error;
return thrd_success;
}
struct pt_cond {
pthread_cond_t cond;
};
typedef struct pt_cond cnd_t;
static inline int cnd_init(cnd_t *cnd)
{
int errcode;
if (!cnd)
return thrd_error;
errcode = pthread_cond_init(&cnd->cond, NULL);
if (errcode)
return thrd_error;
return thrd_success;
}
static inline int cnd_destroy(cnd_t *cnd)
{
int errcode;
if (!cnd)
return thrd_error;
errcode = pthread_cond_destroy(&cnd->cond);
if (errcode)
return thrd_error;
return thrd_success;
}
static inline int cnd_signal(cnd_t *cnd)
{
int errcode;
if (!cnd)
return thrd_error;
errcode = pthread_cond_signal(&cnd->cond);
if (errcode)
return thrd_error;
return thrd_success;
}
static inline int cnd_broadcast(cnd_t *cnd)
{
int errcode;
if (!cnd)
return thrd_error;
errcode = pthread_cond_broadcast(&cnd->cond);
if (errcode)
return thrd_error;
return thrd_success;
}
static inline int cnd_wait(cnd_t *cnd, mtx_t *mtx)
{
int errcode;
if (!cnd || !mtx)
return thrd_error;
errcode = pthread_cond_wait(&cnd->cond, &mtx->mutex);
if (errcode)
return thrd_error;
return thrd_success;
}
#endif /* THREADS_H */

47
include/pt_compiler.h Normal file
View File

@ -0,0 +1,47 @@
/*
* Copyright (c) 2017-2018, 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_COMPILER_H
#define PT_COMPILER_H
/* Both the relevant Clang and GCC versions support this. */
#if !defined(__has_attribute)
# define __has_attribute(attr) 0
#endif
#if !defined(fallthrough)
# if (__has_attribute(fallthrough))
# define fallthrough __attribute__((fallthrough))
# else
# define fallthrough /* Fall through. */
# endif
#endif /* !defined(fallthrough) */
#endif /* PT_COMPILER_H */

View File

@ -0,0 +1,65 @@
/*
* Copyright (c) 2013-2018, 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 <stddef.h>
#include <stdint.h>
#ifndef PRId64
# define PRId64 "lld"
#endif
#ifndef PRIu64
# define PRIu64 "llu"
#endif
#ifndef PRIx64
# define PRIx64 "llx"
#endif
#ifndef PRId32
# define PRId32 "d"
#endif
#ifndef PRIu32
# define PRIu32 "u"
#endif
#ifndef PRIx32
# define PRIx32 "x"
#endif
#ifndef PRIu16
# define PRIu16 "u"
#endif
#ifndef PRIu8
# define PRIu8 "u"
#endif
#ifndef PRIx8
# define PRIx8 "x"
#endif
#ifndef SCNx64
# define SCNx64 "llx"
#endif

239
include/windows/threads.h Normal file
View File

@ -0,0 +1,239 @@
/*
* Copyright (c) 2014-2018, 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.
*
*
* It looks like there is still no support for C11's threads.h.
*
* We implement the few features we actually need hoping that this file will
* soon go away.
*/
#ifndef THREADS_H
#define THREADS_H
#include "windows.h"
enum {
thrd_success = 1,
thrd_error
};
struct pt_thread {
HANDLE handle;
};
typedef struct pt_thread thrd_t;
typedef int (*thrd_start_t)(void *);
struct thrd_args {
thrd_start_t fun;
void *arg;
};
static DWORD WINAPI thrd_routine(void *arg)
{
struct thrd_args *args;
int result;
args = (struct thrd_args *) arg;
if (!args)
return (DWORD) -1;
result = -1;
if (args->fun)
result = args->fun(args->arg);
free(args);
return (DWORD) result;
}
static inline int thrd_create(thrd_t *thrd, thrd_start_t fun, void *arg)
{
struct thrd_args *args;
HANDLE handle;
if (!thrd || !fun)
return thrd_error;
args = malloc(sizeof(*args));
if (!args)
return thrd_error;
args->fun = fun;
args->arg = arg;
handle = CreateThread(NULL, 0, thrd_routine, args, 0, NULL);
if (!handle) {
free(args);
return thrd_error;
}
thrd->handle = handle;
return thrd_success;
}
static inline int thrd_join(thrd_t *thrd, int *res)
{
DWORD status;
BOOL success;
if (!thrd)
return thrd_error;
status = WaitForSingleObject(thrd->handle, INFINITE);
if (status)
return thrd_error;
if (res) {
DWORD result;
success = GetExitCodeThread(thrd->handle, &result);
if (!success) {
(void) CloseHandle(thrd->handle);
return thrd_error;
}
*res = (int) result;
}
success = CloseHandle(thrd->handle);
if (!success)
return thrd_error;
return thrd_success;
}
struct pt_mutex {
CRITICAL_SECTION cs;
};
typedef struct pt_mutex mtx_t;
enum {
mtx_plain
};
static inline int mtx_init(mtx_t *mtx, int type)
{
if (!mtx || type != mtx_plain)
return thrd_error;
InitializeCriticalSection(&mtx->cs);
return thrd_success;
}
static inline void mtx_destroy(mtx_t *mtx)
{
if (mtx)
DeleteCriticalSection(&mtx->cs);
}
static inline int mtx_lock(mtx_t *mtx)
{
if (!mtx)
return thrd_error;
EnterCriticalSection(&mtx->cs);
return thrd_success;
}
static inline int mtx_unlock(mtx_t *mtx)
{
if (!mtx)
return thrd_error;
LeaveCriticalSection(&mtx->cs);
return thrd_success;
}
struct pt_cond {
CONDITION_VARIABLE cond;
};
typedef struct pt_cond cnd_t;
static inline int cnd_init(cnd_t *cnd)
{
if (!cnd)
return thrd_error;
InitializeConditionVariable(&cnd->cond);
return thrd_success;
}
static inline int cnd_destroy(cnd_t *cnd)
{
if (!cnd)
return thrd_error;
/* Nothing to do. */
return thrd_success;
}
static inline int cnd_signal(cnd_t *cnd)
{
if (!cnd)
return thrd_error;
WakeConditionVariable(&cnd->cond);
return thrd_success;
}
static inline int cnd_broadcast(cnd_t *cnd)
{
if (!cnd)
return thrd_error;
WakeAllConditionVariable(&cnd->cond);
return thrd_success;
}
static inline int cnd_wait(cnd_t *cnd, mtx_t *mtx)
{
BOOL success;
if (!cnd || !mtx)
return thrd_error;
success = SleepConditionVariableCS(&cnd->cond, &mtx->cs, INFINITE);
if (!success)
return thrd_error;
return thrd_success;
}
#endif /* THREADS_H */

172
libipt/CMakeLists.txt Normal file
View File

@ -0,0 +1,172 @@
# Copyright (c) 2013-2018, 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_directories(
internal/include
)
set(LIBIPT_SECTION_FILES
src/pt_section.c
src/pt_section_file.c
)
set(LIBIPT_FILES
src/pt_error.c
src/pt_packet_decoder.c
src/pt_query_decoder.c
src/pt_encoder.c
src/pt_sync.c
src/pt_version.c
src/pt_last_ip.c
src/pt_tnt_cache.c
src/pt_ild.c
src/pt_image.c
src/pt_image_section_cache.c
src/pt_retstack.c
src/pt_insn_decoder.c
src/pt_time.c
src/pt_asid.c
src/pt_event_queue.c
src/pt_packet.c
src/pt_decoder_function.c
src/pt_config.c
src/pt_insn.c
src/pt_block_decoder.c
src/pt_block_cache.c
src/pt_msec_cache.c
)
if (CMAKE_HOST_UNIX)
include_directories(
internal/include/posix
)
set(LIBIPT_FILES ${LIBIPT_FILES} src/posix/init.c)
set(LIBIPT_SECTION_FILES ${LIBIPT_SECTION_FILES} src/posix/pt_section_posix.c)
endif (CMAKE_HOST_UNIX)
if (CMAKE_HOST_WIN32)
add_definitions(
# export libipt symbols
#
/Dpt_export=__declspec\(dllexport\)
)
include_directories(
internal/include/windows
)
set(LIBIPT_FILES ${LIBIPT_FILES} src/windows/init.c)
set(LIBIPT_SECTION_FILES ${LIBIPT_SECTION_FILES} src/windows/pt_section_windows.c)
endif (CMAKE_HOST_WIN32)
set(LIBIPT_FILES ${LIBIPT_FILES} ${LIBIPT_SECTION_FILES})
add_library(libipt SHARED
${LIBIPT_FILES}
)
# put the version into the intel-pt header
#
configure_file(
${CMAKE_CURRENT_SOURCE_DIR}/include/intel-pt.h.in
${CMAKE_CURRENT_BINARY_DIR}/include/intel-pt.h
)
set_target_properties(libipt PROPERTIES
PREFIX ""
PUBLIC_HEADER ${CMAKE_CURRENT_BINARY_DIR}/include/intel-pt.h
VERSION ${PT_VERSION}
SOVERSION ${PT_VERSION_MAJOR}
)
install(TARGETS libipt
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
)
function(add_ptunit_std_test name)
add_ptunit_c_test(${name} src/pt_${name}.c ${ARGN})
endfunction(add_ptunit_std_test)
add_ptunit_std_test(last_ip)
add_ptunit_std_test(tnt_cache)
add_ptunit_std_test(retstack)
add_ptunit_std_test(ild)
add_ptunit_std_test(cpu)
add_ptunit_std_test(time)
add_ptunit_std_test(asid)
add_ptunit_std_test(event_queue)
add_ptunit_std_test(image src/pt_asid.c)
add_ptunit_std_test(sync src/pt_packet.c)
add_ptunit_std_test(config)
add_ptunit_std_test(image_section_cache)
add_ptunit_std_test(block_cache)
add_ptunit_std_test(msec_cache)
add_ptunit_c_test(mapped_section src/pt_asid.c)
add_ptunit_c_test(query
src/pt_encoder.c
src/pt_last_ip.c
src/pt_packet_decoder.c
src/pt_sync.c
src/pt_tnt_cache.c
src/pt_time.c
src/pt_event_queue.c
src/pt_query_decoder.c
src/pt_packet.c
src/pt_decoder_function.c
src/pt_packet_decoder.c
src/pt_config.c
src/pt_time.c
src/pt_block_cache.c
)
add_ptunit_c_test(section ${LIBIPT_SECTION_FILES})
add_ptunit_c_test(section-file
test/src/ptunit-section.c
src/pt_section.c
src/pt_section_file.c
)
add_ptunit_c_test(packet
src/pt_encoder.c
src/pt_packet_decoder.c
src/pt_sync.c
src/pt_packet.c
src/pt_decoder_function.c
src/pt_config.c
)
add_ptunit_c_test(fetch
src/pt_decoder_function.c
src/pt_encoder.c
src/pt_config.c
)
add_ptunit_cpp_test(cpp)
add_ptunit_libraries(cpp libipt)

2463
libipt/include/intel-pt.h.in Executable file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,100 @@
/*
* Copyright (c) 2015-2018, 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 */

View File

@ -0,0 +1,74 @@
/*
* Copyright (c) 2014-2018, 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 */

View File

@ -0,0 +1,225 @@
/*
* Copyright (c) 2016-2018, 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 */

View File

@ -0,0 +1,143 @@
/*
* Copyright (c) 2016-2018, 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 */

View File

@ -0,0 +1,82 @@
/*
* Copyright (c) 2015-2018, 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);

View File

@ -0,0 +1,54 @@
/*
* Copyright (c) 2013-2018, 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 */

View File

@ -0,0 +1,40 @@
/*
* Copyright (c) 2013-2018, 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 */

View File

@ -0,0 +1,129 @@
/*
* Copyright (c) 2013-2018, 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 */

View File

@ -0,0 +1,125 @@
/*
* Copyright (c) 2014-2018, 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 */

View File

@ -0,0 +1,143 @@
/*
* Copyright (c) 2013-2018, 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 */

View File

@ -0,0 +1,128 @@
/*
* Copyright (c) 2013-2018, 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;
}
/* MAIN ENTRANCE POINTS */
/* one time call. not thread safe init. call when single threaded. */
extern void pt_ild_init(void);
/* 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 */

View File

@ -0,0 +1,140 @@
/*
* Copyright (c) 2013-2018, 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 */

View File

@ -0,0 +1,206 @@
/*
* Copyright (c) 2016-2018, 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 */

View File

@ -0,0 +1,212 @@
/*
* Copyright (c) 2016-2018, 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 */

View File

@ -0,0 +1,139 @@
/*
* Copyright (c) 2013-2018, 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 */

View File

@ -0,0 +1,79 @@
/*
* Copyright (c) 2013-2018, 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 */

View File

@ -0,0 +1,199 @@
/*
* Copyright (c) 2014-2018, 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 */

View File

@ -0,0 +1,95 @@
/*
* Copyright (c) 2017-2018, 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 */

View File

@ -0,0 +1,397 @@
/*
* Copyright (c) 2013-2018, 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 */

View File

@ -0,0 +1,111 @@
/*
* Copyright (c) 2014-2018, 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 */

View File

@ -0,0 +1,92 @@
/*
* Copyright (c) 2014-2018, 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 */

View File

@ -0,0 +1,134 @@
/*
* Copyright (c) 2014-2018, 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 */

View File

@ -0,0 +1,87 @@
/*
* Copyright (c) 2013-2018, 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 */

View File

@ -0,0 +1,392 @@
/*
* Copyright (c) 2013-2018, 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 a new section on success, NULL otherwise.
*/
extern struct pt_section *pt_mk_section(const char *file, 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 */

View File

@ -0,0 +1,106 @@
/*
* Copyright (c) 2013-2018, 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 */

View File

@ -0,0 +1,71 @@
/*
* Copyright (c) 2014-2018, 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 */

View File

@ -0,0 +1,232 @@
/*
* Copyright (c) 2014-2018, 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;
};
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 *);
#endif /* PT_TIME_H */

View File

@ -0,0 +1,88 @@
/*
* Copyright (c) 2013-2018, 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 */

View File

@ -0,0 +1,39 @@
/*
* Copyright (c) 2013-2018, 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

View File

@ -0,0 +1,544 @@
/*
* Copyright (c) 2013-2018, 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,
};

View File

@ -0,0 +1,46 @@
/*
* Copyright (c) 2013-2018, 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

View File

@ -0,0 +1,544 @@
/*
* Copyright (c) 2013-2018, 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,
};

View File

@ -0,0 +1,38 @@
/*
* Copyright (c) 2013-2018, 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

View File

@ -0,0 +1,544 @@
/*
* Copyright (c) 2013-2018, 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,
};

View File

@ -0,0 +1,111 @@
/*
* Copyright (c) 2015-2018, 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 */

36
libipt/src/posix/init.c Normal file
View File

@ -0,0 +1,36 @@
/*
* Copyright (c) 2013-2018, 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 "pt_ild.h"
static void __attribute__((constructor)) init(void)
{
/* Initialize the Intel(R) Processor Trace instruction decoder. */
pt_ild_init();
}

View File

@ -0,0 +1,37 @@
/*
* Copyright (c) 2013-2018, 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 "pt_cpuid.h"
#include <cpuid.h>
extern void pt_cpuid(uint32_t leaf, uint32_t *eax, uint32_t *ebx,
uint32_t *ecx, uint32_t *edx)
{
__get_cpuid(leaf, eax, ebx, ecx, edx);
}

View File

@ -0,0 +1,326 @@
/*
* Copyright (c) 2013-2018, 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 "pt_section.h"
#include "pt_section_posix.h"
#include "pt_section_file.h"
#include "intel-pt.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <limits.h>
#include <sys/types.h>
#include <sys/mman.h>
#include <fcntl.h>
#include <unistd.h>
int pt_section_mk_status(void **pstatus, uint64_t *psize, const char *filename)
{
struct pt_sec_posix_status *status;
struct stat buffer;
int errcode;
if (!pstatus || !psize)
return -pte_internal;
errcode = stat(filename, &buffer);
if (errcode < 0)
return errcode;
if (buffer.st_size < 0)
return -pte_bad_image;
status = malloc(sizeof(*status));
if (!status)
return -pte_nomem;
status->stat = buffer;
*pstatus = status;
*psize = buffer.st_size;
return 0;
}
static int check_file_status(struct pt_section *section, int fd)
{
struct pt_sec_posix_status *status;
struct stat stat;
int errcode;
if (!section)
return -pte_internal;
errcode = fstat(fd, &stat);
if (errcode)
return -pte_bad_image;
status = section->status;
if (!status)
return -pte_internal;
if (stat.st_size != status->stat.st_size)
return -pte_bad_image;
if (stat.st_mtime != status->stat.st_mtime)
return -pte_bad_image;
return 0;
}
int pt_sec_posix_map(struct pt_section *section, int fd)
{
struct pt_sec_posix_mapping *mapping;
uint64_t offset, size, adjustment;
uint8_t *base;
int errcode;
if (!section)
return -pte_internal;
offset = section->offset;
size = section->size;
adjustment = offset % sysconf(_SC_PAGESIZE);
offset -= adjustment;
size += adjustment;
/* The section is supposed to fit into the file so we shouldn't
* see any overflows, here.
*/
if (size < section->size)
return -pte_internal;
if (SIZE_MAX < size)
return -pte_nomem;
if (INT_MAX < offset)
return -pte_nomem;
base = mmap(NULL, (size_t) size, PROT_READ, MAP_SHARED, fd,
(off_t) offset);
if (base == MAP_FAILED)
return -pte_nomem;
mapping = malloc(sizeof(*mapping));
if (!mapping) {
errcode = -pte_nomem;
goto out_map;
}
mapping->base = base;
mapping->size = size;
mapping->begin = base + adjustment;
mapping->end = base + size;
section->mapping = mapping;
section->unmap = pt_sec_posix_unmap;
section->read = pt_sec_posix_read;
section->memsize = pt_sec_posix_memsize;
return 0;
out_map:
munmap(base, (size_t) size);
return errcode;
}
static int pt_sec_posix_map_success(struct pt_section *section)
{
uint16_t mcount;
int errcode, status;
if (!section)
return -pte_internal;
mcount = section->mcount + 1;
if (!mcount) {
(void) pt_section_unlock(section);
return -pte_overflow;
}
section->mcount = mcount;
errcode = pt_section_unlock(section);
if (errcode < 0)
return errcode;
status = pt_section_on_map(section);
if (status < 0) {
/* We had to release the section lock for pt_section_on_map() so
* @section may have meanwhile been mapped by other threads.
*
* We still want to return the error so we release our mapping.
* Our caller does not yet know whether pt_section_map()
* succeeded.
*/
(void) pt_section_unmap(section);
return status;
}
return 0;
}
int pt_section_map(struct pt_section *section)
{
const char *filename;
FILE *file;
int fd, errcode;
if (!section)
return -pte_internal;
errcode = pt_section_lock(section);
if (errcode < 0)
return errcode;
if (section->mcount)
return pt_sec_posix_map_success(section);
if (section->mapping)
goto out_unlock;
filename = section->filename;
if (!filename)
goto out_unlock;
errcode = -pte_bad_image;
fd = open(filename, O_RDONLY);
if (fd == -1)
goto out_unlock;
errcode = check_file_status(section, fd);
if (errcode < 0)
goto out_fd;
/* We close the file on success. This does not unmap the section. */
errcode = pt_sec_posix_map(section, fd);
if (!errcode) {
close(fd);
return pt_sec_posix_map_success(section);
}
/* Fall back to file based sections - report the original error
* if we fail to convert the file descriptor.
*/
file = fdopen(fd, "rb");
if (!file)
goto out_fd;
/* We need to keep the file open on success. It will be closed when
* the section is unmapped.
*/
errcode = pt_sec_file_map(section, file);
if (!errcode)
return pt_sec_posix_map_success(section);
fclose(file);
goto out_unlock;
out_fd:
close(fd);
out_unlock:
(void) pt_section_unlock(section);
return errcode;
}
int pt_sec_posix_unmap(struct pt_section *section)
{
struct pt_sec_posix_mapping *mapping;
if (!section)
return -pte_internal;
mapping = section->mapping;
if (!mapping || !section->unmap || !section->read || !section->memsize)
return -pte_internal;
section->mapping = NULL;
section->unmap = NULL;
section->read = NULL;
section->memsize = NULL;
munmap(mapping->base, (size_t) mapping->size);
free(mapping);
return 0;
}
int pt_sec_posix_read(const struct pt_section *section, uint8_t *buffer,
uint16_t size, uint64_t offset)
{
struct pt_sec_posix_mapping *mapping;
const uint8_t *begin;
if (!buffer || !section)
return -pte_internal;
mapping = section->mapping;
if (!mapping)
return -pte_internal;
/* We already checked in pt_section_read() that the requested memory
* lies within the section's boundaries.
*
* And we checked that the entire section was mapped. There's no need
* to check for overflows, again.
*/
begin = mapping->begin + offset;
memcpy(buffer, begin, size);
return (int) size;
}
int pt_sec_posix_memsize(const struct pt_section *section, uint64_t *size)
{
struct pt_sec_posix_mapping *mapping;
const uint8_t *begin, *end;
if (!section || !size)
return -pte_internal;
mapping = section->mapping;
if (!mapping)
return -pte_internal;
begin = mapping->base;
end = mapping->end;
if (!begin || !end || end < begin)
return -pte_internal;
*size = (uint64_t) (end - begin);
return 0;
}

106
libipt/src/pt_asid.c Normal file
View File

@ -0,0 +1,106 @@
/*
* Copyright (c) 2014-2018, 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 "pt_asid.h"
#include "intel-pt.h"
#include <string.h>
int pt_asid_from_user(struct pt_asid *asid, const struct pt_asid *user)
{
if (!asid)
return -pte_internal;
pt_asid_init(asid);
if (user) {
size_t size;
size = user->size;
/* Ignore fields in the user's asid we don't know. */
if (sizeof(*asid) < size)
size = sizeof(*asid);
/* Copy (portions of) the user's asid. */
memcpy(asid, user, size);
/* We copied user's size - fix it. */
asid->size = sizeof(*asid);
}
return 0;
}
int pt_asid_to_user(struct pt_asid *user, const struct pt_asid *asid,
size_t size)
{
if (!user || !asid)
return -pte_internal;
/* We need at least space for the size field. */
if (size < sizeof(asid->size))
return -pte_invalid;
/* Only provide the fields we actually have. */
if (sizeof(*asid) < size)
size = sizeof(*asid);
/* Copy (portions of) our asid to the user's. */
memcpy(user, asid, size);
/* We copied our size - fix it. */
user->size = size;
return 0;
}
int pt_asid_match(const struct pt_asid *lhs, const struct pt_asid *rhs)
{
uint64_t lcr3, rcr3, lvmcs, rvmcs;
if (!lhs || !rhs)
return -pte_internal;
lcr3 = lhs->cr3;
rcr3 = rhs->cr3;
if (lcr3 != rcr3 && lcr3 != pt_asid_no_cr3 && rcr3 != pt_asid_no_cr3)
return 0;
lvmcs = lhs->vmcs;
rvmcs = rhs->vmcs;
if (lvmcs != rvmcs && lvmcs != pt_asid_no_vmcs &&
rvmcs != pt_asid_no_vmcs)
return 0;
return 1;
}

View File

@ -0,0 +1,96 @@
/*
* Copyright (c) 2016-2018, 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 "pt_block_cache.h"
#include <stdlib.h>
#include <string.h>
struct pt_block_cache *pt_bcache_alloc(uint64_t nentries)
{
struct pt_block_cache *bcache;
uint64_t size;
if (!nentries || (UINT32_MAX < nentries))
return NULL;
size = sizeof(*bcache) + (nentries * sizeof(struct pt_bcache_entry));
if (SIZE_MAX < size)
return NULL;
bcache = malloc((size_t) size);
if (!bcache)
return NULL;
memset(bcache, 0, (size_t) size);
bcache->nentries = (uint32_t) nentries;
return bcache;
}
void pt_bcache_free(struct pt_block_cache *bcache)
{
free(bcache);
}
int pt_bcache_add(struct pt_block_cache *bcache, uint64_t index,
struct pt_bcache_entry bce)
{
if (!bcache)
return -pte_internal;
if (bcache->nentries <= index)
return -pte_internal;
/* 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.
*/
bcache->entry[(uint32_t) index] = bce;
return 0;
}
int pt_bcache_lookup(struct pt_bcache_entry *bce,
const struct pt_block_cache *bcache, uint64_t index)
{
if (!bce || !bcache)
return -pte_internal;
if (bcache->nentries <= index)
return -pte_internal;
/* 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.
*/
*bce = bcache->entry[(uint32_t) index];
return 0;
}

File diff suppressed because it is too large Load Diff

251
libipt/src/pt_config.c Normal file
View File

@ -0,0 +1,251 @@
/*
* Copyright (c) 2013-2018, 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 "pt_config.h"
#include "pt_opcodes.h"
#include "intel-pt.h"
#include <string.h>
#include <stddef.h>
int pt_cpu_errata(struct pt_errata *errata, const struct pt_cpu *cpu)
{
if (!errata || !cpu)
return -pte_invalid;
memset(errata, 0, sizeof(*errata));
/* We don't know about others. */
if (cpu->vendor != pcv_intel)
return -pte_bad_cpu;
switch (cpu->family) {
case 0x6:
switch (cpu->model) {
case 0x3d:
case 0x47:
case 0x4f:
case 0x56:
errata->bdm70 = 1;
errata->bdm64 = 1;
return 0;
case 0x4e:
case 0x5e:
errata->bdm70 = 1;
errata->skd007 = 1;
errata->skd022 = 1;
errata->skd010 = 1;
errata->skl014 = 1;
return 0;
case 0x8e:
case 0x9e:
errata->bdm70 = 1;
errata->skl014 = 1;
errata->skd022 = 1;
errata->skd010 = 1;
errata->skd007 = 1;
return 0;
case 0x5c:
case 0x5f:
errata->apl12 = 1;
errata->apl11 = 1;
return 0;
}
break;
}
return -pte_bad_cpu;
}
int pt_config_from_user(struct pt_config *config,
const struct pt_config *uconfig)
{
uint8_t *begin, *end;
size_t size;
if (!config)
return -pte_internal;
if (!uconfig)
return -pte_invalid;
size = uconfig->size;
if (size < offsetof(struct pt_config, decode))
return -pte_bad_config;
begin = uconfig->begin;
end = uconfig->end;
if (!begin || !end || end < begin)
return -pte_bad_config;
/* Ignore fields in the user's configuration we don't know; zero out
* fields the user didn't know about.
*/
if (sizeof(*config) <= size)
size = sizeof(*config);
else
memset(((uint8_t *) config) + size, 0, sizeof(*config) - size);
/* Copy (portions of) the user's configuration. */
memcpy(config, uconfig, size);
/* We copied user's size - fix it. */
config->size = size;
return 0;
}
/* The maximum number of filter addresses that fit into the configuration. */
static inline size_t pt_filter_addr_ncfg(void)
{
return (sizeof(struct pt_conf_addr_filter) -
offsetof(struct pt_conf_addr_filter, addr0_a)) /
(2 * sizeof(uint64_t));
}
uint32_t pt_filter_addr_cfg(const struct pt_conf_addr_filter *filter, uint8_t n)
{
if (!filter)
return 0u;
if (pt_filter_addr_ncfg() <= n)
return 0u;
return (filter->config.addr_cfg >> (4 * n)) & 0xf;
}
uint64_t pt_filter_addr_a(const struct pt_conf_addr_filter *filter, uint8_t n)
{
const uint64_t *addr;
if (!filter)
return 0ull;
if (pt_filter_addr_ncfg() <= n)
return 0ull;
addr = &filter->addr0_a;
return addr[2 * n];
}
uint64_t pt_filter_addr_b(const struct pt_conf_addr_filter *filter, uint8_t n)
{
const uint64_t *addr;
if (!filter)
return 0ull;
if (pt_filter_addr_ncfg() <= n)
return 0ull;
addr = &filter->addr0_a;
return addr[(2 * n) + 1];
}
static int pt_filter_check_cfg_filter(const struct pt_conf_addr_filter *filter,
uint64_t addr)
{
uint8_t n;
if (!filter)
return -pte_internal;
for (n = 0; n < pt_filter_addr_ncfg(); ++n) {
uint64_t addr_a, addr_b;
uint32_t addr_cfg;
addr_cfg = pt_filter_addr_cfg(filter, n);
if (addr_cfg != pt_addr_cfg_filter)
continue;
addr_a = pt_filter_addr_a(filter, n);
addr_b = pt_filter_addr_b(filter, n);
/* Note that both A and B are inclusive. */
if ((addr_a <= addr) && (addr <= addr_b))
return 1;
}
/* No filter hit. If we have at least one FilterEn filter, this means
* that tracing is disabled; otherwise, tracing is enabled.
*/
for (n = 0; n < pt_filter_addr_ncfg(); ++n) {
uint32_t addr_cfg;
addr_cfg = pt_filter_addr_cfg(filter, n);
if (addr_cfg == pt_addr_cfg_filter)
return 0;
}
return 1;
}
static int pt_filter_check_cfg_stop(const struct pt_conf_addr_filter *filter,
uint64_t addr)
{
uint8_t n;
if (!filter)
return -pte_internal;
for (n = 0; n < pt_filter_addr_ncfg(); ++n) {
uint64_t addr_a, addr_b;
uint32_t addr_cfg;
addr_cfg = pt_filter_addr_cfg(filter, n);
if (addr_cfg != pt_addr_cfg_stop)
continue;
addr_a = pt_filter_addr_a(filter, n);
addr_b = pt_filter_addr_b(filter, n);
/* Note that both A and B are inclusive. */
if ((addr_a <= addr) && (addr <= addr_b))
return 0;
}
return 1;
}
int pt_filter_addr_check(const struct pt_conf_addr_filter *filter,
uint64_t addr)
{
int status;
status = pt_filter_check_cfg_stop(filter, addr);
if (status <= 0)
return status;
return pt_filter_check_cfg_filter(filter, addr);
}

164
libipt/src/pt_cpu.c Normal file
View File

@ -0,0 +1,164 @@
/*
* Copyright (c) 2013-2018, 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 "pt_cpu.h"
#include "pt_cpuid.h"
#include "intel-pt.h"
#include <limits.h>
#include <stdlib.h>
static const char * const cpu_vendors[] = {
"",
"GenuineIntel"
};
enum {
pt_cpuid_vendor_size = 12
};
union cpu_vendor {
/* The raw data returned from cpuid. */
struct {
uint32_t ebx;
uint32_t edx;
uint32_t ecx;
} cpuid;
/* The resulting vendor string. */
char vendor_string[pt_cpuid_vendor_size];
};
static enum pt_cpu_vendor cpu_vendor(void)
{
union cpu_vendor vendor;
uint32_t eax;
size_t i;
memset(&vendor, 0, sizeof(vendor));
eax = 0;
pt_cpuid(0u, &eax, &vendor.cpuid.ebx, &vendor.cpuid.ecx,
&vendor.cpuid.edx);
for (i = 0; i < sizeof(cpu_vendors)/sizeof(*cpu_vendors); i++)
if (strncmp(vendor.vendor_string,
cpu_vendors[i], pt_cpuid_vendor_size) == 0)
return (enum pt_cpu_vendor) i;
return pcv_unknown;
}
static uint32_t cpu_info(void)
{
uint32_t eax, ebx, ecx, edx;
eax = 0;
ebx = 0;
ecx = 0;
edx = 0;
pt_cpuid(1u, &eax, &ebx, &ecx, &edx);
return eax;
}
int pt_cpu_parse(struct pt_cpu *cpu, const char *s)
{
const char sep = '/';
char *endptr;
long family, model, stepping;
if (!cpu || !s)
return -pte_invalid;
family = strtol(s, &endptr, 0);
if (s == endptr || *endptr == '\0' || *endptr != sep)
return -pte_invalid;
if (family < 0 || family > USHRT_MAX)
return -pte_invalid;
/* skip separator */
s = endptr + 1;
model = strtol(s, &endptr, 0);
if (s == endptr || (*endptr != '\0' && *endptr != sep))
return -pte_invalid;
if (model < 0 || model > UCHAR_MAX)
return -pte_invalid;
if (*endptr == '\0')
/* stepping was omitted, it defaults to 0 */
stepping = 0;
else {
/* skip separator */
s = endptr + 1;
stepping = strtol(s, &endptr, 0);
if (*endptr != '\0')
return -pte_invalid;
if (stepping < 0 || stepping > UCHAR_MAX)
return -pte_invalid;
}
cpu->vendor = pcv_intel;
cpu->family = (uint16_t) family;
cpu->model = (uint8_t) model;
cpu->stepping = (uint8_t) stepping;
return 0;
}
int pt_cpu_read(struct pt_cpu *cpu)
{
uint32_t info;
uint16_t family;
if (!cpu)
return -pte_invalid;
cpu->vendor = cpu_vendor();
info = cpu_info();
cpu->family = family = (info>>8) & 0xf;
if (family == 0xf)
cpu->family += (info>>20) & 0xf;
cpu->model = (info>>4) & 0xf;
if (family == 0x6 || family == 0xf)
cpu->model += (info>>12) & 0xf0;
cpu->stepping = (info>>0) & 0xf;
return 0;
}

View File

@ -0,0 +1,379 @@
/*
* Copyright (c) 2013-2018, 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 "pt_decoder_function.h"
#include "pt_packet_decoder.h"
#include "pt_query_decoder.h"
#include "pt_opcodes.h"
#include "intel-pt.h"
const struct pt_decoder_function pt_decode_unknown = {
/* .packet = */ pt_pkt_decode_unknown,
/* .decode = */ pt_qry_decode_unknown,
/* .header = */ pt_qry_decode_unknown,
/* .flags = */ pdff_unknown
};
const struct pt_decoder_function pt_decode_pad = {
/* .packet = */ pt_pkt_decode_pad,
/* .decode = */ pt_qry_decode_pad,
/* .header = */ pt_qry_decode_pad,
/* .flags = */ pdff_pad
};
const struct pt_decoder_function pt_decode_psb = {
/* .packet = */ pt_pkt_decode_psb,
/* .decode = */ pt_qry_decode_psb,
/* .header = */ NULL,
/* .flags = */ 0
};
const struct pt_decoder_function pt_decode_tip = {
/* .packet = */ pt_pkt_decode_tip,
/* .decode = */ pt_qry_decode_tip,
/* .header = */ NULL,
/* .flags = */ pdff_tip
};
const struct pt_decoder_function pt_decode_tnt_8 = {
/* .packet = */ pt_pkt_decode_tnt_8,
/* .decode = */ pt_qry_decode_tnt_8,
/* .header = */ NULL,
/* .flags = */ pdff_tnt
};
const struct pt_decoder_function pt_decode_tnt_64 = {
/* .packet = */ pt_pkt_decode_tnt_64,
/* .decode = */ pt_qry_decode_tnt_64,
/* .header = */ NULL,
/* .flags = */ pdff_tnt
};
const struct pt_decoder_function pt_decode_tip_pge = {
/* .packet = */ pt_pkt_decode_tip_pge,
/* .decode = */ pt_qry_decode_tip_pge,
/* .header = */ NULL,
/* .flags = */ pdff_event
};
const struct pt_decoder_function pt_decode_tip_pgd = {
/* .packet = */ pt_pkt_decode_tip_pgd,
/* .decode = */ pt_qry_decode_tip_pgd,
/* .header = */ NULL,
/* .flags = */ pdff_event
};
const struct pt_decoder_function pt_decode_fup = {
/* .packet = */ pt_pkt_decode_fup,
/* .decode = */ pt_qry_decode_fup,
/* .header = */ pt_qry_header_fup,
/* .flags = */ pdff_fup
};
const struct pt_decoder_function pt_decode_pip = {
/* .packet = */ pt_pkt_decode_pip,
/* .decode = */ pt_qry_decode_pip,
/* .header = */ pt_qry_header_pip,
/* .flags = */ pdff_event
};
const struct pt_decoder_function pt_decode_ovf = {
/* .packet = */ pt_pkt_decode_ovf,
/* .decode = */ pt_qry_decode_ovf,
/* .header = */ NULL,
/* .flags = */ pdff_psbend | pdff_event
};
const struct pt_decoder_function pt_decode_mode = {
/* .packet = */ pt_pkt_decode_mode,
/* .decode = */ pt_qry_decode_mode,
/* .header = */ pt_qry_header_mode,
/* .flags = */ pdff_event
};
const struct pt_decoder_function pt_decode_psbend = {
/* .packet = */ pt_pkt_decode_psbend,
/* .decode = */ pt_qry_decode_psbend,
/* .header = */ NULL,
/* .flags = */ pdff_psbend
};
const struct pt_decoder_function pt_decode_tsc = {
/* .packet = */ pt_pkt_decode_tsc,
/* .decode = */ pt_qry_decode_tsc,
/* .header = */ pt_qry_header_tsc,
/* .flags = */ pdff_timing
};
const struct pt_decoder_function pt_decode_cbr = {
/* .packet = */ pt_pkt_decode_cbr,
/* .decode = */ pt_qry_decode_cbr,
/* .header = */ pt_qry_header_cbr,
/* .flags = */ pdff_timing | pdff_event
};
const struct pt_decoder_function pt_decode_tma = {
/* .packet = */ pt_pkt_decode_tma,
/* .decode = */ pt_qry_decode_tma,
/* .header = */ pt_qry_decode_tma,
/* .flags = */ pdff_timing
};
const struct pt_decoder_function pt_decode_mtc = {
/* .packet = */ pt_pkt_decode_mtc,
/* .decode = */ pt_qry_decode_mtc,
/* .header = */ pt_qry_decode_mtc,
/* .flags = */ pdff_timing
};
const struct pt_decoder_function pt_decode_cyc = {
/* .packet = */ pt_pkt_decode_cyc,
/* .decode = */ pt_qry_decode_cyc,
/* .header = */ pt_qry_decode_cyc,
/* .flags = */ pdff_timing
};
const struct pt_decoder_function pt_decode_stop = {
/* .packet = */ pt_pkt_decode_stop,
/* .decode = */ pt_qry_decode_stop,
/* .header = */ NULL,
/* .flags = */ pdff_event
};
const struct pt_decoder_function pt_decode_vmcs = {
/* .packet = */ pt_pkt_decode_vmcs,
/* .decode = */ pt_qry_decode_vmcs,
/* .header = */ pt_qry_header_vmcs,
/* .flags = */ pdff_event
};
const struct pt_decoder_function pt_decode_mnt = {
/* .packet = */ pt_pkt_decode_mnt,
/* .decode = */ pt_qry_decode_mnt,
/* .header = */ pt_qry_header_mnt,
/* .flags = */ pdff_event
};
const struct pt_decoder_function pt_decode_exstop = {
/* .packet = */ pt_pkt_decode_exstop,
/* .decode = */ pt_qry_decode_exstop,
/* .header = */ NULL,
/* .flags = */ pdff_event
};
const struct pt_decoder_function pt_decode_mwait = {
/* .packet = */ pt_pkt_decode_mwait,
/* .decode = */ pt_qry_decode_mwait,
/* .header = */ NULL,
/* .flags = */ pdff_event
};
const struct pt_decoder_function pt_decode_pwre = {
/* .packet = */ pt_pkt_decode_pwre,
/* .decode = */ pt_qry_decode_pwre,
/* .header = */ NULL,
/* .flags = */ pdff_event
};
const struct pt_decoder_function pt_decode_pwrx = {
/* .packet = */ pt_pkt_decode_pwrx,
/* .decode = */ pt_qry_decode_pwrx,
/* .header = */ NULL,
/* .flags = */ pdff_event
};
const struct pt_decoder_function pt_decode_ptw = {
/* .packet = */ pt_pkt_decode_ptw,
/* .decode = */ pt_qry_decode_ptw,
/* .header = */ NULL,
/* .flags = */ pdff_event
};
int pt_df_fetch(const struct pt_decoder_function **dfun, const uint8_t *pos,
const struct pt_config *config)
{
const uint8_t *begin, *end;
uint8_t opc, ext, ext2;
if (!dfun || !config)
return -pte_internal;
/* Clear the decode function in case of errors. */
*dfun = NULL;
begin = config->begin;
end = config->end;
if (!pos || (pos < begin) || (end < pos))
return -pte_nosync;
if (pos == end)
return -pte_eos;
opc = *pos++;
switch (opc) {
default:
/* Check opcodes that require masking. */
if ((opc & pt_opm_tnt_8) == pt_opc_tnt_8) {
*dfun = &pt_decode_tnt_8;
return 0;
}
if ((opc & pt_opm_cyc) == pt_opc_cyc) {
*dfun = &pt_decode_cyc;
return 0;
}
if ((opc & pt_opm_tip) == pt_opc_tip) {
*dfun = &pt_decode_tip;
return 0;
}
if ((opc & pt_opm_fup) == pt_opc_fup) {
*dfun = &pt_decode_fup;
return 0;
}
if ((opc & pt_opm_tip) == pt_opc_tip_pge) {
*dfun = &pt_decode_tip_pge;
return 0;
}
if ((opc & pt_opm_tip) == pt_opc_tip_pgd) {
*dfun = &pt_decode_tip_pgd;
return 0;
}
*dfun = &pt_decode_unknown;
return 0;
case pt_opc_pad:
*dfun = &pt_decode_pad;
return 0;
case pt_opc_mode:
*dfun = &pt_decode_mode;
return 0;
case pt_opc_tsc:
*dfun = &pt_decode_tsc;
return 0;
case pt_opc_mtc:
*dfun = &pt_decode_mtc;
return 0;
case pt_opc_ext:
if (pos == end)
return -pte_eos;
ext = *pos++;
switch (ext) {
default:
/* Check opcodes that require masking. */
if ((ext & pt_opm_ptw) == pt_ext_ptw) {
*dfun = &pt_decode_ptw;
return 0;
}
*dfun = &pt_decode_unknown;
return 0;
case pt_ext_psb:
*dfun = &pt_decode_psb;
return 0;
case pt_ext_ovf:
*dfun = &pt_decode_ovf;
return 0;
case pt_ext_tnt_64:
*dfun = &pt_decode_tnt_64;
return 0;
case pt_ext_psbend:
*dfun = &pt_decode_psbend;
return 0;
case pt_ext_cbr:
*dfun = &pt_decode_cbr;
return 0;
case pt_ext_pip:
*dfun = &pt_decode_pip;
return 0;
case pt_ext_tma:
*dfun = &pt_decode_tma;
return 0;
case pt_ext_stop:
*dfun = &pt_decode_stop;
return 0;
case pt_ext_vmcs:
*dfun = &pt_decode_vmcs;
return 0;
case pt_ext_exstop:
case pt_ext_exstop_ip:
*dfun = &pt_decode_exstop;
return 0;
case pt_ext_mwait:
*dfun = &pt_decode_mwait;
return 0;
case pt_ext_pwre:
*dfun = &pt_decode_pwre;
return 0;
case pt_ext_pwrx:
*dfun = &pt_decode_pwrx;
return 0;
case pt_ext_ext2:
if (pos == end)
return -pte_eos;
ext2 = *pos++;
switch (ext2) {
default:
*dfun = &pt_decode_unknown;
return 0;
case pt_ext2_mnt:
*dfun = &pt_decode_mnt;
return 0;
}
}
}
}

917
libipt/src/pt_encoder.c Normal file
View File

@ -0,0 +1,917 @@
/*
* Copyright (c) 2014-2018, 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 "pt_encoder.h"
#include "pt_config.h"
#include "pt_opcodes.h"
#include <string.h>
#include <stdlib.h>
int pt_encoder_init(struct pt_encoder *encoder, const struct pt_config *config)
{
int errcode;
if (!encoder)
return -pte_invalid;
memset(encoder, 0, sizeof(*encoder));
errcode = pt_config_from_user(&encoder->config, config);
if (errcode < 0)
return errcode;
encoder->pos = encoder->config.begin;
return 0;
}
void pt_encoder_fini(struct pt_encoder *encoder)
{
(void) encoder;
/* Nothing to do. */
}
struct pt_encoder *pt_alloc_encoder(const struct pt_config *config)
{
struct pt_encoder *encoder;
int errcode;
encoder = malloc(sizeof(*encoder));
if (!encoder)
return NULL;
errcode = pt_encoder_init(encoder, config);
if (errcode < 0) {
free(encoder);
return NULL;
}
return encoder;
}
void pt_free_encoder(struct pt_encoder *encoder)
{
pt_encoder_fini(encoder);
free(encoder);
}
int pt_enc_sync_set(struct pt_encoder *encoder, uint64_t offset)
{
uint8_t *begin, *end, *pos;
if (!encoder)
return -pte_invalid;
begin = encoder->config.begin;
end = encoder->config.end;
pos = begin + offset;
if (end < pos || pos < begin)
return -pte_eos;
encoder->pos = pos;
return 0;
}
int pt_enc_get_offset(const struct pt_encoder *encoder, uint64_t *offset)
{
const uint8_t *raw, *begin;
if (!encoder || !offset)
return -pte_invalid;
/* The encoder is synchronized at all times. */
raw = encoder->pos;
if (!raw)
return -pte_internal;
begin = encoder->config.begin;
if (!begin)
return -pte_internal;
*offset = raw - begin;
return 0;
}
const struct pt_config *pt_enc_get_config(const struct pt_encoder *encoder)
{
if (!encoder)
return NULL;
return &encoder->config;
}
/* Check the remaining space.
*
* Returns zero if there are at least \@size bytes of free space available in
* \@encoder's Intel PT buffer.
*
* Returns -pte_eos if not enough space is available.
* Returns -pte_internal if \@encoder is NULL.
* Returns -pte_internal if \@encoder is not synchronized.
*/
static int pt_reserve(const struct pt_encoder *encoder, unsigned int size)
{
const uint8_t *begin, *end, *pos;
if (!encoder)
return -pte_internal;
/* The encoder is synchronized at all times. */
pos = encoder->pos;
if (!pos)
return -pte_internal;
begin = encoder->config.begin;
end = encoder->config.end;
pos += size;
if (pos < begin || end < pos)
return -pte_eos;
return 0;
}
/* Return the size of an IP payload based on its IP compression.
*
* Returns -pte_bad_packet if \@ipc is not a valid IP compression.
*/
static int pt_ipc_size(enum pt_ip_compression ipc)
{
switch (ipc) {
case pt_ipc_suppressed:
return 0;
case pt_ipc_update_16:
return pt_pl_ip_upd16_size;
case pt_ipc_update_32:
return pt_pl_ip_upd32_size;
case pt_ipc_update_48:
return pt_pl_ip_upd48_size;
case pt_ipc_sext_48:
return pt_pl_ip_sext48_size;
case pt_ipc_full:
return pt_pl_ip_full_size;
}
return -pte_invalid;
}
/* Encode an integer value.
*
* Writes the \@size least signifficant bytes of \@value starting from \@pos.
*
* The caller needs to ensure that there is enough space available.
*
* Returns the updated position.
*/
static uint8_t *pt_encode_int(uint8_t *pos, uint64_t val, int size)
{
for (; size; --size, val >>= 8)
*pos++ = (uint8_t) val;
return pos;
}
/* Encode an IP packet.
*
* Write an IP packet with opcode \@opc and payload from \@packet if there is
* enough space in \@encoder's Intel PT buffer.
*
* Returns the number of bytes written on success.
*
* Returns -pte_eos if there is not enough space.
* Returns -pte_internal if \@encoder or \@packet is NULL.
* Returns -pte_invalid if \@packet.ipc is not valid.
*/
static int pt_encode_ip(struct pt_encoder *encoder, enum pt_opcode op,
const struct pt_packet_ip *packet)
{
uint8_t *pos;
uint8_t opc, ipc;
int size, errcode;
if (!encoder || !packet)
return pte_internal;
size = pt_ipc_size(packet->ipc);
if (size < 0)
return size;
errcode = pt_reserve(encoder, /* opc size = */ 1 + size);
if (errcode < 0)
return errcode;
/* We already checked the ipc in pt_ipc_size(). */
ipc = (uint8_t) (packet->ipc << pt_opm_ipc_shr);
opc = (uint8_t) op;
pos = encoder->pos;
*pos++ = opc | ipc;
encoder->pos = pt_encode_int(pos, packet->ip, size);
return /* opc size = */ 1 + size;
}
int pt_enc_next(struct pt_encoder *encoder, const struct pt_packet *packet)
{
uint8_t *pos, *begin;
int errcode;
if (!encoder || !packet)
return -pte_invalid;
pos = begin = encoder->pos;
switch (packet->type) {
case ppt_pad:
errcode = pt_reserve(encoder, ptps_pad);
if (errcode < 0)
return errcode;
*pos++ = pt_opc_pad;
encoder->pos = pos;
return (int) (pos - begin);
case ppt_psb: {
uint64_t psb;
errcode = pt_reserve(encoder, ptps_psb);
if (errcode < 0)
return errcode;
psb = ((uint64_t) pt_psb_hilo << 48 |
(uint64_t) pt_psb_hilo << 32 |
(uint64_t) pt_psb_hilo << 16 |
(uint64_t) pt_psb_hilo);
pos = pt_encode_int(pos, psb, 8);
pos = pt_encode_int(pos, psb, 8);
encoder->pos = pos;
return (int) (pos - begin);
}
case ppt_psbend:
errcode = pt_reserve(encoder, ptps_psbend);
if (errcode < 0)
return errcode;
*pos++ = pt_opc_ext;
*pos++ = pt_ext_psbend;
encoder->pos = pos;
return (int) (pos - begin);
case ppt_ovf:
errcode = pt_reserve(encoder, ptps_ovf);
if (errcode < 0)
return errcode;
*pos++ = pt_opc_ext;
*pos++ = pt_ext_ovf;
encoder->pos = pos;
return (int) (pos - begin);
case ppt_fup:
return pt_encode_ip(encoder, pt_opc_fup, &packet->payload.ip);
case ppt_tip:
return pt_encode_ip(encoder, pt_opc_tip, &packet->payload.ip);
case ppt_tip_pge:
return pt_encode_ip(encoder, pt_opc_tip_pge,
&packet->payload.ip);
case ppt_tip_pgd:
return pt_encode_ip(encoder, pt_opc_tip_pgd,
&packet->payload.ip);
case ppt_tnt_8: {
uint8_t opc, stop;
if (packet->payload.tnt.bit_size >= 7)
return -pte_bad_packet;
errcode = pt_reserve(encoder, ptps_tnt_8);
if (errcode < 0)
return errcode;
stop = packet->payload.tnt.bit_size + pt_opm_tnt_8_shr;
opc = (uint8_t)
(packet->payload.tnt.payload << pt_opm_tnt_8_shr);
*pos++ = (uint8_t) (opc | (1u << stop));
encoder->pos = pos;
return (int) (pos - begin);
}
case ppt_tnt_64: {
uint64_t tnt, stop;
errcode = pt_reserve(encoder, ptps_tnt_64);
if (errcode < 0)
return errcode;
if (packet->payload.tnt.bit_size >= pt_pl_tnt_64_bits)
return -pte_invalid;
stop = 1ull << packet->payload.tnt.bit_size;
tnt = packet->payload.tnt.payload;
if (tnt & ~(stop - 1))
return -pte_invalid;
*pos++ = pt_opc_ext;
*pos++ = pt_ext_tnt_64;
pos = pt_encode_int(pos, tnt | stop, pt_pl_tnt_64_size);
encoder->pos = pos;
return (int) (pos - begin);
}
case ppt_mode: {
uint8_t mode;
errcode = pt_reserve(encoder, ptps_mode);
if (errcode < 0)
return errcode;
switch (packet->payload.mode.leaf) {
default:
return -pte_bad_packet;
case pt_mol_exec:
mode = pt_mol_exec;
if (packet->payload.mode.bits.exec.csl)
mode |= pt_mob_exec_csl;
if (packet->payload.mode.bits.exec.csd)
mode |= pt_mob_exec_csd;
break;
case pt_mol_tsx:
mode = pt_mol_tsx;
if (packet->payload.mode.bits.tsx.intx)
mode |= pt_mob_tsx_intx;
if (packet->payload.mode.bits.tsx.abrt)
mode |= pt_mob_tsx_abrt;
break;
}
*pos++ = pt_opc_mode;
*pos++ = mode;
encoder->pos = pos;
return (int) (pos - begin);
}
case ppt_pip: {
uint64_t cr3;
errcode = pt_reserve(encoder, ptps_pip);
if (errcode < 0)
return errcode;
cr3 = packet->payload.pip.cr3;
cr3 >>= pt_pl_pip_shl;
cr3 <<= pt_pl_pip_shr;
if (packet->payload.pip.nr)
cr3 |= (uint64_t) pt_pl_pip_nr;
*pos++ = pt_opc_ext;
*pos++ = pt_ext_pip;
pos = pt_encode_int(pos, cr3, pt_pl_pip_size);
encoder->pos = pos;
return (int) (pos - begin);
}
case ppt_tsc:
errcode = pt_reserve(encoder, ptps_tsc);
if (errcode < 0)
return errcode;
*pos++ = pt_opc_tsc;
pos = pt_encode_int(pos, packet->payload.tsc.tsc,
pt_pl_tsc_size);
encoder->pos = pos;
return (int) (pos - begin);
case ppt_cbr:
errcode = pt_reserve(encoder, ptps_cbr);
if (errcode < 0)
return errcode;
*pos++ = pt_opc_ext;
*pos++ = pt_ext_cbr;
*pos++ = packet->payload.cbr.ratio;
*pos++ = 0;
encoder->pos = pos;
return (int) (pos - begin);
case ppt_tma: {
uint16_t ctc, fc;
errcode = pt_reserve(encoder, ptps_tma);
if (errcode < 0)
return errcode;
ctc = packet->payload.tma.ctc;
fc = packet->payload.tma.fc;
if (fc & ~pt_pl_tma_fc_mask)
return -pte_bad_packet;
*pos++ = pt_opc_ext;
*pos++ = pt_ext_tma;
pos = pt_encode_int(pos, ctc, pt_pl_tma_ctc_size);
*pos++ = 0;
pos = pt_encode_int(pos, fc, pt_pl_tma_fc_size);
encoder->pos = pos;
return (int) (pos - begin);
}
case ppt_mtc:
errcode = pt_reserve(encoder, ptps_mtc);
if (errcode < 0)
return errcode;
*pos++ = pt_opc_mtc;
*pos++ = packet->payload.mtc.ctc;
encoder->pos = pos;
return (int) (pos - begin);
case ppt_cyc: {
uint8_t byte[pt_pl_cyc_max_size], index, end;
uint64_t ctc;
ctc = (uint8_t) packet->payload.cyc.value;
ctc <<= pt_opm_cyc_shr;
byte[0] = pt_opc_cyc;
byte[0] |= (uint8_t) ctc;
ctc = packet->payload.cyc.value;
ctc >>= (8 - pt_opm_cyc_shr);
if (ctc)
byte[0] |= pt_opm_cyc_ext;
for (end = 1; ctc; ++end) {
/* Check if the CYC payload is too big. */
if (pt_pl_cyc_max_size <= end)
return -pte_bad_packet;
ctc <<= pt_opm_cycx_shr;
byte[end] = (uint8_t) ctc;
ctc >>= 8;
if (ctc)
byte[end] |= pt_opm_cycx_ext;
}
errcode = pt_reserve(encoder, end);
if (errcode < 0)
return errcode;
for (index = 0; index < end; ++index)
*pos++ = byte[index];
encoder->pos = pos;
return (int) (pos - begin);
}
case ppt_stop:
errcode = pt_reserve(encoder, ptps_stop);
if (errcode < 0)
return errcode;
*pos++ = pt_opc_ext;
*pos++ = pt_ext_stop;
encoder->pos = pos;
return (int) (pos - begin);
case ppt_vmcs:
errcode = pt_reserve(encoder, ptps_vmcs);
if (errcode < 0)
return errcode;
*pos++ = pt_opc_ext;
*pos++ = pt_ext_vmcs;
pos = pt_encode_int(pos,
packet->payload.vmcs.base >> pt_pl_vmcs_shl,
pt_pl_vmcs_size);
encoder->pos = pos;
return (int) (pos - begin);
case ppt_mnt:
errcode = pt_reserve(encoder, ptps_mnt);
if (errcode < 0)
return errcode;
*pos++ = pt_opc_ext;
*pos++ = pt_ext_ext2;
*pos++ = pt_ext2_mnt;
pos = pt_encode_int(pos, packet->payload.mnt.payload,
pt_pl_mnt_size);
encoder->pos = pos;
return (int) (pos - begin);
case ppt_exstop: {
uint8_t ext;
errcode = pt_reserve(encoder, ptps_exstop);
if (errcode < 0)
return errcode;
ext = packet->payload.exstop.ip ?
pt_ext_exstop_ip : pt_ext_exstop;
*pos++ = pt_opc_ext;
*pos++ = ext;
encoder->pos = pos;
return (int) (pos - begin);
}
case ppt_mwait:
errcode = pt_reserve(encoder, ptps_mwait);
if (errcode < 0)
return errcode;
*pos++ = pt_opc_ext;
*pos++ = pt_ext_mwait;
pos = pt_encode_int(pos, packet->payload.mwait.hints,
pt_pl_mwait_hints_size);
pos = pt_encode_int(pos, packet->payload.mwait.ext,
pt_pl_mwait_ext_size);
encoder->pos = pos;
return (int) (pos - begin);
case ppt_pwre: {
uint64_t payload;
errcode = pt_reserve(encoder, ptps_pwre);
if (errcode < 0)
return errcode;
payload = 0ull;
payload |= ((uint64_t) packet->payload.pwre.state <<
pt_pl_pwre_state_shr) &
(uint64_t) pt_pl_pwre_state_mask;
payload |= ((uint64_t) packet->payload.pwre.sub_state <<
pt_pl_pwre_sub_state_shr) &
(uint64_t) pt_pl_pwre_sub_state_mask;
if (packet->payload.pwre.hw)
payload |= (uint64_t) pt_pl_pwre_hw_mask;
*pos++ = pt_opc_ext;
*pos++ = pt_ext_pwre;
pos = pt_encode_int(pos, payload, pt_pl_pwre_size);
encoder->pos = pos;
return (int) (pos - begin);
}
case ppt_pwrx: {
uint64_t payload;
errcode = pt_reserve(encoder, ptps_pwrx);
if (errcode < 0)
return errcode;
payload = 0ull;
payload |= ((uint64_t) packet->payload.pwrx.last <<
pt_pl_pwrx_last_shr) &
(uint64_t) pt_pl_pwrx_last_mask;
payload |= ((uint64_t) packet->payload.pwrx.deepest <<
pt_pl_pwrx_deepest_shr) &
(uint64_t) pt_pl_pwrx_deepest_mask;
if (packet->payload.pwrx.interrupt)
payload |= (uint64_t) pt_pl_pwrx_wr_int;
if (packet->payload.pwrx.store)
payload |= (uint64_t) pt_pl_pwrx_wr_store;
if (packet->payload.pwrx.autonomous)
payload |= (uint64_t) pt_pl_pwrx_wr_hw;
*pos++ = pt_opc_ext;
*pos++ = pt_ext_pwrx;
pos = pt_encode_int(pos, payload, pt_pl_pwrx_size);
encoder->pos = pos;
return (int) (pos - begin);
}
case ppt_ptw: {
uint8_t plc, ext;
int size;
plc = packet->payload.ptw.plc;
size = pt_ptw_size(plc);
if (size < 0)
return size;
errcode = pt_reserve(encoder, pt_opcs_ptw + size);
if (errcode < 0)
return errcode;
ext = pt_ext_ptw;
ext |= plc << pt_opm_ptw_pb_shr;
if (packet->payload.ptw.ip)
ext |= (uint8_t) pt_opm_ptw_ip;
*pos++ = pt_opc_ext;
*pos++ = ext;
pos = pt_encode_int(pos, packet->payload.ptw.payload, size);
encoder->pos = pos;
return (int) (pos - begin);
}
case ppt_unknown:
case ppt_invalid:
return -pte_bad_opc;
}
return -pte_bad_opc;
}
int pt_encode_pad(struct pt_encoder *encoder)
{
struct pt_packet packet;
packet.type = ppt_pad;
return pt_enc_next(encoder, &packet);
}
int pt_encode_psb(struct pt_encoder *encoder)
{
struct pt_packet packet;
packet.type = ppt_psb;
return pt_enc_next(encoder, &packet);
}
int pt_encode_psbend(struct pt_encoder *encoder)
{
struct pt_packet packet;
packet.type = ppt_psbend;
return pt_enc_next(encoder, &packet);
}
int pt_encode_tip(struct pt_encoder *encoder, uint64_t ip,
enum pt_ip_compression ipc)
{
struct pt_packet packet;
packet.type = ppt_tip;
packet.payload.ip.ip = ip;
packet.payload.ip.ipc = ipc;
return pt_enc_next(encoder, &packet);
}
int pt_encode_tnt_8(struct pt_encoder *encoder, uint8_t tnt, int size)
{
struct pt_packet packet;
packet.type = ppt_tnt_8;
packet.payload.tnt.bit_size = (uint8_t) size;
packet.payload.tnt.payload = tnt;
return pt_enc_next(encoder, &packet);
}
int pt_encode_tnt_64(struct pt_encoder *encoder, uint64_t tnt, int size)
{
struct pt_packet packet;
packet.type = ppt_tnt_64;
packet.payload.tnt.bit_size = (uint8_t) size;
packet.payload.tnt.payload = tnt;
return pt_enc_next(encoder, &packet);
}
int pt_encode_tip_pge(struct pt_encoder *encoder, uint64_t ip,
enum pt_ip_compression ipc)
{
struct pt_packet packet;
packet.type = ppt_tip_pge;
packet.payload.ip.ip = ip;
packet.payload.ip.ipc = ipc;
return pt_enc_next(encoder, &packet);
}
int pt_encode_tip_pgd(struct pt_encoder *encoder, uint64_t ip,
enum pt_ip_compression ipc)
{
struct pt_packet packet;
packet.type = ppt_tip_pgd;
packet.payload.ip.ip = ip;
packet.payload.ip.ipc = ipc;
return pt_enc_next(encoder, &packet);
}
int pt_encode_fup(struct pt_encoder *encoder, uint64_t ip,
enum pt_ip_compression ipc)
{
struct pt_packet packet;
packet.type = ppt_fup;
packet.payload.ip.ip = ip;
packet.payload.ip.ipc = ipc;
return pt_enc_next(encoder, &packet);
}
int pt_encode_pip(struct pt_encoder *encoder, uint64_t cr3, uint8_t flags)
{
struct pt_packet packet;
packet.type = ppt_pip;
packet.payload.pip.cr3 = cr3;
packet.payload.pip.nr = (flags & pt_pl_pip_nr) != 0;
return pt_enc_next(encoder, &packet);
}
int pt_encode_ovf(struct pt_encoder *encoder)
{
struct pt_packet packet;
packet.type = ppt_ovf;
return pt_enc_next(encoder, &packet);
}
int pt_encode_mode_exec(struct pt_encoder *encoder, enum pt_exec_mode mode)
{
struct pt_packet packet;
packet.type = ppt_mode;
packet.payload.mode.leaf = pt_mol_exec;
packet.payload.mode.bits.exec = pt_set_exec_mode(mode);
return pt_enc_next(encoder, &packet);
}
int pt_encode_mode_tsx(struct pt_encoder *encoder, uint8_t bits)
{
struct pt_packet packet;
packet.type = ppt_mode;
packet.payload.mode.leaf = pt_mol_tsx;
if (bits & pt_mob_tsx_intx)
packet.payload.mode.bits.tsx.intx = 1;
else
packet.payload.mode.bits.tsx.intx = 0;
if (bits & pt_mob_tsx_abrt)
packet.payload.mode.bits.tsx.abrt = 1;
else
packet.payload.mode.bits.tsx.abrt = 0;
return pt_enc_next(encoder, &packet);
}
int pt_encode_tsc(struct pt_encoder *encoder, uint64_t tsc)
{
struct pt_packet packet;
packet.type = ppt_tsc;
packet.payload.tsc.tsc = tsc;
return pt_enc_next(encoder, &packet);
}
int pt_encode_cbr(struct pt_encoder *encoder, uint8_t cbr)
{
struct pt_packet packet;
packet.type = ppt_cbr;
packet.payload.cbr.ratio = cbr;
return pt_enc_next(encoder, &packet);
}
int pt_encode_tma(struct pt_encoder *encoder, uint16_t ctc, uint16_t fc)
{
struct pt_packet packet;
packet.type = ppt_tma;
packet.payload.tma.ctc = ctc;
packet.payload.tma.fc = fc;
return pt_enc_next(encoder, &packet);
}
int pt_encode_mtc(struct pt_encoder *encoder, uint8_t ctc)
{
struct pt_packet packet;
packet.type = ppt_mtc;
packet.payload.mtc.ctc = ctc;
return pt_enc_next(encoder, &packet);
}
int pt_encode_cyc(struct pt_encoder *encoder, uint32_t ctc)
{
struct pt_packet packet;
packet.type = ppt_cyc;
packet.payload.cyc.value = ctc;
return pt_enc_next(encoder, &packet);
}
int pt_encode_stop(struct pt_encoder *encoder)
{
struct pt_packet packet;
packet.type = ppt_stop;
return pt_enc_next(encoder, &packet);
}
int pt_encode_vmcs(struct pt_encoder *encoder, uint64_t payload)
{
struct pt_packet packet;
packet.type = ppt_vmcs;
packet.payload.vmcs.base = payload;
return pt_enc_next(encoder, &packet);
}
int pt_encode_mnt(struct pt_encoder *encoder, uint64_t payload)
{
struct pt_packet packet;
packet.type = ppt_mnt;
packet.payload.mnt.payload = payload;
return pt_enc_next(encoder, &packet);
}

122
libipt/src/pt_error.c Normal file
View File

@ -0,0 +1,122 @@
/*
* Copyright (c) 2013-2018, 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"
const char *pt_errstr(enum pt_error_code errcode)
{
switch (errcode) {
case pte_ok:
return "OK";
case pte_internal:
return "internal error";
case pte_invalid:
return "invalid argument";
case pte_nosync:
return "decoder out of sync";
case pte_bad_opc:
return "unknown opcode";
case pte_bad_packet:
return "unknown packet";
case pte_bad_context:
return "unexpected packet context";
case pte_eos:
return "reached end of trace stream";
case pte_bad_query:
return "trace stream does not match query";
case pte_nomem:
return "out of memory";
case pte_bad_config:
return "bad configuration";
case pte_noip:
return "no ip";
case pte_ip_suppressed:
return "ip has been suppressed";
case pte_nomap:
return "no memory mapped at this address";
case pte_bad_insn:
return "unknown instruction";
case pte_no_time:
return "no timing information";
case pte_no_cbr:
return "no core:bus ratio";
case pte_bad_image:
return "bad image";
case pte_bad_lock:
return "locking error";
case pte_not_supported:
return "not supported";
case pte_retstack_empty:
return "compressed return without call";
case pte_bad_retcomp:
return "bad compressed return";
case pte_bad_status_update:
return "bad status update";
case pte_no_enable:
return "expected tracing enabled event";
case pte_event_ignored:
return "event ignored";
case pte_overflow:
return "overflow";
case pte_bad_file:
return "bad file";
case pte_bad_cpu:
return "unknown cpu";
}
/* Should not reach here. */
return "internal error.";
}

203
libipt/src/pt_event_queue.c Normal file
View File

@ -0,0 +1,203 @@
/*
* Copyright (c) 2013-2018, 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 "pt_event_queue.h"
#include <string.h>
static inline uint8_t pt_evq_inc(uint8_t idx)
{
idx += 1;
idx %= evq_max;
return idx;
}
static struct pt_event *pt_event_init(struct pt_event *event)
{
if (event)
memset(event, 0, sizeof(*event));
return event;
}
void pt_evq_init(struct pt_event_queue *evq)
{
if (!evq)
return;
memset(evq, 0, sizeof(*evq));
}
struct pt_event *pt_evq_standalone(struct pt_event_queue *evq)
{
if (!evq)
return NULL;
return pt_event_init(&evq->standalone);
}
struct pt_event *pt_evq_enqueue(struct pt_event_queue *evq,
enum pt_event_binding evb)
{
uint8_t begin, end, gap, idx;
if (!evq)
return NULL;
if (evb_max <= evb)
return NULL;
begin = evq->begin[evb];
idx = evq->end[evb];
if (evq_max <= begin)
return NULL;
if (evq_max <= idx)
return NULL;
end = pt_evq_inc(idx);
gap = pt_evq_inc(end);
/* Leave a gap so we don't overwrite the last dequeued event. */
if (begin == gap)
return NULL;
evq->end[evb] = end;
return pt_event_init(&evq->queue[evb][idx]);
}
struct pt_event *pt_evq_dequeue(struct pt_event_queue *evq,
enum pt_event_binding evb)
{
uint8_t begin, end;
if (!evq)
return NULL;
if (evb_max <= evb)
return NULL;
begin = evq->begin[evb];
end = evq->end[evb];
if (evq_max <= begin)
return NULL;
if (evq_max <= end)
return NULL;
if (begin == end)
return NULL;
evq->begin[evb] = pt_evq_inc(begin);
return &evq->queue[evb][begin];
}
int pt_evq_clear(struct pt_event_queue *evq, enum pt_event_binding evb)
{
if (!evq)
return -pte_internal;
if (evb_max <= evb)
return -pte_internal;
evq->begin[evb] = 0;
evq->end[evb] = 0;
return 0;
}
int pt_evq_empty(const struct pt_event_queue *evq, enum pt_event_binding evb)
{
uint8_t begin, end;
if (!evq)
return -pte_internal;
if (evb_max <= evb)
return -pte_internal;
begin = evq->begin[evb];
end = evq->end[evb];
if (evq_max <= begin)
return -pte_internal;
if (evq_max <= end)
return -pte_internal;
return begin == end;
}
int pt_evq_pending(const struct pt_event_queue *evq, enum pt_event_binding evb)
{
int errcode;
errcode = pt_evq_empty(evq, evb);
if (errcode < 0)
return errcode;
return !errcode;
}
struct pt_event *pt_evq_find(struct pt_event_queue *evq,
enum pt_event_binding evb,
enum pt_event_type evt)
{
uint8_t begin, end;
if (!evq)
return NULL;
if (evb_max <= evb)
return NULL;
begin = evq->begin[evb];
end = evq->end[evb];
if (evq_max <= begin)
return NULL;
if (evq_max <= end)
return NULL;
for (; begin != end; begin = pt_evq_inc(begin)) {
struct pt_event *ev;
ev = &evq->queue[evb][begin];
if (ev->type == evt)
return ev;
}
return NULL;
}

1223
libipt/src/pt_ild.c Normal file

File diff suppressed because it is too large Load Diff

718
libipt/src/pt_image.c Normal file
View File

@ -0,0 +1,718 @@
/*
* Copyright (c) 2013-2018, 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 "pt_image.h"
#include "pt_section.h"
#include "pt_asid.h"
#include "pt_image_section_cache.h"
#include <stdlib.h>
#include <string.h>
static char *dupstr(const char *str)
{
char *dup;
size_t len;
if (!str)
return NULL;
len = strlen(str);
dup = malloc(len + 1);
if (!dup)
return NULL;
return strcpy(dup, str);
}
static struct pt_section_list *pt_mk_section_list(struct pt_section *section,
const struct pt_asid *asid,
uint64_t vaddr,
uint64_t offset,
uint64_t size, int isid)
{
struct pt_section_list *list;
int errcode;
list = malloc(sizeof(*list));
if (!list)
return NULL;
memset(list, 0, sizeof(*list));
errcode = pt_section_get(section);
if (errcode < 0)
goto out_mem;
pt_msec_init(&list->section, section, asid, vaddr, offset, size);
list->isid = isid;
return list;
out_mem:
free(list);
return NULL;
}
static void pt_section_list_free(struct pt_section_list *list)
{
if (!list)
return;
pt_section_put(list->section.section);
pt_msec_fini(&list->section);
free(list);
}
static void pt_section_list_free_tail(struct pt_section_list *list)
{
while (list) {
struct pt_section_list *trash;
trash = list;
list = list->next;
pt_section_list_free(trash);
}
}
void pt_image_init(struct pt_image *image, const char *name)
{
if (!image)
return;
memset(image, 0, sizeof(*image));
image->name = dupstr(name);
}
void pt_image_fini(struct pt_image *image)
{
if (!image)
return;
pt_section_list_free_tail(image->sections);
free(image->name);
memset(image, 0, sizeof(*image));
}
struct pt_image *pt_image_alloc(const char *name)
{
struct pt_image *image;
image = malloc(sizeof(*image));
if (image)
pt_image_init(image, name);
return image;
}
void pt_image_free(struct pt_image *image)
{
pt_image_fini(image);
free(image);
}
const char *pt_image_name(const struct pt_image *image)
{
if (!image)
return NULL;
return image->name;
}
int pt_image_add(struct pt_image *image, struct pt_section *section,
const struct pt_asid *asid, uint64_t vaddr, int isid)
{
struct pt_section_list **list, *next, *removed, *new;
uint64_t size, begin, end;
int errcode;
if (!image || !section)
return -pte_internal;
size = pt_section_size(section);
begin = vaddr;
end = begin + size;
next = pt_mk_section_list(section, asid, begin, 0ull, size, isid);
if (!next)
return -pte_nomem;
removed = NULL;
errcode = 0;
/* Check for overlaps while we move to the end of the list. */
list = &(image->sections);
while (*list) {
const struct pt_mapped_section *msec;
const struct pt_asid *masid;
struct pt_section_list *current;
struct pt_section *lsec;
uint64_t lbegin, lend, loff;
current = *list;
msec = &current->section;
masid = pt_msec_asid(msec);
errcode = pt_asid_match(masid, asid);
if (errcode < 0)
break;
if (!errcode) {
list = &((*list)->next);
continue;
}
lbegin = pt_msec_begin(msec);
lend = pt_msec_end(msec);
if ((end <= lbegin) || (lend <= begin)) {
list = &((*list)->next);
continue;
}
/* The new section overlaps with @msec's section. */
lsec = pt_msec_section(msec);
loff = pt_msec_offset(msec);
/* We remove @msec and insert new sections for the remaining
* parts, if any. Those new sections are not mapped initially
* and need to be added to the end of the section list.
*/
*list = current->next;
/* Keep a list of removed sections so we can re-add them in case
* of errors.
*/
current->next = removed;
removed = current;
/* Add a section covering the remaining bytes at the front. */
if (lbegin < begin) {
new = pt_mk_section_list(lsec, masid, lbegin, loff,
begin - lbegin, current->isid);
if (!new) {
errcode = -pte_nomem;
break;
}
new->next = next;
next = new;
}
/* Add a section covering the remaining bytes at the back. */
if (end < lend) {
new = pt_mk_section_list(lsec, masid, end,
loff + (end - lbegin),
lend - end, current->isid);
if (!new) {
errcode = -pte_nomem;
break;
}
new->next = next;
next = new;
}
}
if (errcode < 0) {
pt_section_list_free_tail(next);
/* Re-add removed sections to the tail of the section list. */
for (; *list; list = &((*list)->next))
;
*list = removed;
return errcode;
}
pt_section_list_free_tail(removed);
*list = next;
return 0;
}
int pt_image_remove(struct pt_image *image, struct pt_section *section,
const struct pt_asid *asid, uint64_t vaddr)
{
struct pt_section_list **list;
if (!image || !section)
return -pte_internal;
for (list = &image->sections; *list; list = &((*list)->next)) {
struct pt_mapped_section *msec;
const struct pt_section *sec;
const struct pt_asid *masid;
struct pt_section_list *trash;
uint64_t begin;
int errcode;
trash = *list;
msec = &trash->section;
masid = pt_msec_asid(msec);
errcode = pt_asid_match(masid, asid);
if (errcode < 0)
return errcode;
if (!errcode)
continue;
begin = pt_msec_begin(msec);
sec = pt_msec_section(msec);
if (sec == section && begin == vaddr) {
*list = trash->next;
pt_section_list_free(trash);
return 0;
}
}
return -pte_bad_image;
}
int pt_image_add_file(struct pt_image *image, const char *filename,
uint64_t offset, uint64_t size,
const struct pt_asid *uasid, uint64_t vaddr)
{
struct pt_section *section;
struct pt_asid asid;
int errcode;
if (!image || !filename)
return -pte_invalid;
errcode = pt_asid_from_user(&asid, uasid);
if (errcode < 0)
return errcode;
section = pt_mk_section(filename, offset, size);
if (!section)
return -pte_invalid;
errcode = pt_image_add(image, section, &asid, vaddr, 0);
if (errcode < 0) {
(void) pt_section_put(section);
return errcode;
}
/* The image list got its own reference; let's drop ours. */
errcode = pt_section_put(section);
if (errcode < 0)
return errcode;
return 0;
}
int pt_image_copy(struct pt_image *image, const struct pt_image *src)
{
struct pt_section_list *list;
int ignored;
if (!image || !src)
return -pte_invalid;
/* There is nothing to do if we copy an image to itself.
*
* Besides, pt_image_add() may move sections around, which would
* interfere with our section iteration.
*/
if (image == src)
return 0;
ignored = 0;
for (list = src->sections; list; list = list->next) {
int errcode;
errcode = pt_image_add(image, list->section.section,
&list->section.asid,
list->section.vaddr,
list->isid);
if (errcode < 0)
ignored += 1;
}
return ignored;
}
int pt_image_remove_by_filename(struct pt_image *image, const char *filename,
const struct pt_asid *uasid)
{
struct pt_section_list **list;
struct pt_asid asid;
int errcode, removed;
if (!image || !filename)
return -pte_invalid;
errcode = pt_asid_from_user(&asid, uasid);
if (errcode < 0)
return errcode;
removed = 0;
for (list = &image->sections; *list;) {
struct pt_mapped_section *msec;
const struct pt_section *sec;
const struct pt_asid *masid;
struct pt_section_list *trash;
const char *tname;
trash = *list;
msec = &trash->section;
masid = pt_msec_asid(msec);
errcode = pt_asid_match(masid, &asid);
if (errcode < 0)
return errcode;
if (!errcode) {
list = &trash->next;
continue;
}
sec = pt_msec_section(msec);
tname = pt_section_filename(sec);
if (tname && (strcmp(tname, filename) == 0)) {
*list = trash->next;
pt_section_list_free(trash);
removed += 1;
} else
list = &trash->next;
}
return removed;
}
int pt_image_remove_by_asid(struct pt_image *image,
const struct pt_asid *uasid)
{
struct pt_section_list **list;
struct pt_asid asid;
int errcode, removed;
if (!image)
return -pte_invalid;
errcode = pt_asid_from_user(&asid, uasid);
if (errcode < 0)
return errcode;
removed = 0;
for (list = &image->sections; *list;) {
struct pt_mapped_section *msec;
const struct pt_asid *masid;
struct pt_section_list *trash;
trash = *list;
msec = &trash->section;
masid = pt_msec_asid(msec);
errcode = pt_asid_match(masid, &asid);
if (errcode < 0)
return errcode;
if (!errcode) {
list = &trash->next;
continue;
}
*list = trash->next;
pt_section_list_free(trash);
removed += 1;
}
return removed;
}
int pt_image_set_callback(struct pt_image *image,
read_memory_callback_t *callback, void *context)
{
if (!image)
return -pte_invalid;
image->readmem.callback = callback;
image->readmem.context = context;
return 0;
}
static int pt_image_read_callback(struct pt_image *image, int *isid,
uint8_t *buffer, uint16_t size,
const struct pt_asid *asid, uint64_t addr)
{
read_memory_callback_t *callback;
if (!image || !isid)
return -pte_internal;
callback = image->readmem.callback;
if (!callback)
return -pte_nomap;
*isid = 0;
return callback(buffer, size, asid, addr, image->readmem.context);
}
/* Check whether a mapped section contains an address.
*
* Returns zero if @msec contains @vaddr.
* Returns a negative error code otherwise.
* Returns -pte_nomap if @msec does not contain @vaddr.
*/
static inline int pt_image_check_msec(const struct pt_mapped_section *msec,
const struct pt_asid *asid,
uint64_t vaddr)
{
const struct pt_asid *masid;
uint64_t begin, end;
int errcode;
if (!msec)
return -pte_internal;
begin = pt_msec_begin(msec);
end = pt_msec_end(msec);
if (vaddr < begin || end <= vaddr)
return -pte_nomap;
masid = pt_msec_asid(msec);
errcode = pt_asid_match(masid, asid);
if (errcode <= 0) {
if (!errcode)
errcode = -pte_nomap;
return errcode;
}
return 0;
}
/* Find the section containing a given address in a given address space.
*
* On success, the found section is moved to the front of the section list.
* If caching is enabled, maps the section.
*
* Returns zero on success, a negative error code otherwise.
*/
static int pt_image_fetch_section(struct pt_image *image,
const struct pt_asid *asid, uint64_t vaddr)
{
struct pt_section_list **start, **list;
if (!image)
return -pte_internal;
start = &image->sections;
for (list = start; *list;) {
struct pt_mapped_section *msec;
struct pt_section_list *elem;
int errcode;
elem = *list;
msec = &elem->section;
errcode = pt_image_check_msec(msec, asid, vaddr);
if (errcode < 0) {
if (errcode != -pte_nomap)
return errcode;
list = &elem->next;
continue;
}
/* Move the section to the front if it isn't already. */
if (list != start) {
*list = elem->next;
elem->next = *start;
*start = elem;
}
return 0;
}
return -pte_nomap;
}
int pt_image_read(struct pt_image *image, int *isid, uint8_t *buffer,
uint16_t size, const struct pt_asid *asid, uint64_t addr)
{
struct pt_mapped_section *msec;
struct pt_section_list *slist;
struct pt_section *section;
int errcode, status;
if (!image || !isid)
return -pte_internal;
errcode = pt_image_fetch_section(image, asid, addr);
if (errcode < 0) {
if (errcode != -pte_nomap)
return errcode;
return pt_image_read_callback(image, isid, buffer, size, asid,
addr);
}
slist = image->sections;
if (!slist)
return -pte_internal;
*isid = slist->isid;
msec = &slist->section;
section = pt_msec_section(msec);
errcode = pt_section_map(section);
if (errcode < 0)
return errcode;
status = pt_msec_read(msec, buffer, size, addr);
errcode = pt_section_unmap(section);
if (errcode < 0)
return errcode;
if (status < 0) {
if (status != -pte_nomap)
return status;
return pt_image_read_callback(image, isid, buffer, size, asid,
addr);
}
return status;
}
int pt_image_add_cached(struct pt_image *image,
struct pt_image_section_cache *iscache, int isid,
const struct pt_asid *uasid)
{
struct pt_section *section;
struct pt_asid asid;
uint64_t vaddr;
int errcode, status;
if (!image || !iscache)
return -pte_invalid;
errcode = pt_iscache_lookup(iscache, &section, &vaddr, isid);
if (errcode < 0)
return errcode;
errcode = pt_asid_from_user(&asid, uasid);
if (errcode < 0)
return errcode;
status = pt_image_add(image, section, &asid, vaddr, isid);
/* We grab a reference when we add the section. Drop the one we
* obtained from cache lookup.
*/
errcode = pt_section_put(section);
if (errcode < 0)
return errcode;
return status;
}
int pt_image_find(struct pt_image *image, struct pt_mapped_section *usec,
const struct pt_asid *asid, uint64_t vaddr)
{
struct pt_mapped_section *msec;
struct pt_section_list *slist;
struct pt_section *section;
int errcode;
if (!image || !usec)
return -pte_internal;
errcode = pt_image_fetch_section(image, asid, vaddr);
if (errcode < 0)
return errcode;
slist = image->sections;
if (!slist)
return -pte_internal;
msec = &slist->section;
section = pt_msec_section(msec);
errcode = pt_section_get(section);
if (errcode < 0)
return errcode;
*usec = *msec;
return slist->isid;
}
int pt_image_validate(const struct pt_image *image,
const struct pt_mapped_section *usec, uint64_t vaddr,
int isid)
{
const struct pt_section_list *slist;
uint64_t begin, end;
int status;
if (!image || !usec)
return -pte_internal;
/* Check that @vaddr lies within @usec. */
begin = pt_msec_begin(usec);
end = pt_msec_end(usec);
if (vaddr < begin || end <= vaddr)
return -pte_nomap;
/* We assume that @usec is a copy of the top of our stack and accept
* sporadic validation fails if it isn't, e.g. because it has moved
* down.
*
* A failed validation requires decoders to re-fetch the section so it
* only results in a (relatively small) performance loss.
*/
slist = image->sections;
if (!slist)
return -pte_nomap;
if (slist->isid != isid)
return -pte_nomap;
status = memcmp(&slist->section, usec, sizeof(*usec));
if (status)
return -pte_nomap;
return 0;
}

File diff suppressed because it is too large Load Diff

372
libipt/src/pt_insn.c Normal file
View File

@ -0,0 +1,372 @@
/*
* Copyright (c) 2016-2018, 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 "pt_insn.h"
#include "pt_ild.h"
#include "pt_image.h"
#include "pt_compiler.h"
#include "intel-pt.h"
int pt_insn_changes_cpl(const struct pt_insn *insn,
const struct pt_insn_ext *iext)
{
(void) insn;
if (!iext)
return 0;
switch (iext->iclass) {
default:
return 0;
case PTI_INST_INT:
case PTI_INST_INT3:
case PTI_INST_INT1:
case PTI_INST_INTO:
case PTI_INST_IRET:
case PTI_INST_SYSCALL:
case PTI_INST_SYSENTER:
case PTI_INST_SYSEXIT:
case PTI_INST_SYSRET:
return 1;
}
}
int pt_insn_changes_cr3(const struct pt_insn *insn,
const struct pt_insn_ext *iext)
{
(void) insn;
if (!iext)
return 0;
switch (iext->iclass) {
default:
return 0;
case PTI_INST_MOV_CR3:
return 1;
}
}
int pt_insn_is_branch(const struct pt_insn *insn,
const struct pt_insn_ext *iext)
{
(void) iext;
if (!insn)
return 0;
switch (insn->iclass) {
default:
return 0;
case ptic_call:
case ptic_return:
case ptic_jump:
case ptic_cond_jump:
case ptic_far_call:
case ptic_far_return:
case ptic_far_jump:
return 1;
}
}
int pt_insn_is_far_branch(const struct pt_insn *insn,
const struct pt_insn_ext *iext)
{
(void) iext;
if (!insn)
return 0;
switch (insn->iclass) {
default:
return 0;
case ptic_far_call:
case ptic_far_return:
case ptic_far_jump:
return 1;
}
}
int pt_insn_binds_to_pip(const struct pt_insn *insn,
const struct pt_insn_ext *iext)
{
if (!iext)
return 0;
switch (iext->iclass) {
default:
return pt_insn_is_far_branch(insn, iext);
case PTI_INST_MOV_CR3:
case PTI_INST_VMLAUNCH:
case PTI_INST_VMRESUME:
return 1;
}
}
int pt_insn_binds_to_vmcs(const struct pt_insn *insn,
const struct pt_insn_ext *iext)
{
if (!iext)
return 0;
switch (iext->iclass) {
default:
return pt_insn_is_far_branch(insn, iext);
case PTI_INST_VMPTRLD:
case PTI_INST_VMLAUNCH:
case PTI_INST_VMRESUME:
return 1;
}
}
int pt_insn_is_ptwrite(const struct pt_insn *insn,
const struct pt_insn_ext *iext)
{
(void) iext;
if (!insn)
return 0;
switch (insn->iclass) {
default:
return 0;
case ptic_ptwrite:
return 1;
}
}
int pt_insn_next_ip(uint64_t *pip, const struct pt_insn *insn,
const struct pt_insn_ext *iext)
{
uint64_t ip;
if (!insn || !iext)
return -pte_internal;
ip = insn->ip + insn->size;
switch (insn->iclass) {
case ptic_ptwrite:
case ptic_other:
break;
case ptic_call:
case ptic_jump:
if (iext->variant.branch.is_direct) {
ip += iext->variant.branch.displacement;
break;
}
fallthrough;
default:
return -pte_bad_query;
case ptic_error:
return -pte_bad_insn;
}
if (pip)
*pip = ip;
return 0;
}
/* Retry decoding an instruction after a preceding decode error.
*
* Instruction length decode typically fails due to 'not enough
* bytes'.
*
* This may be caused by partial updates of text sections
* represented via new image sections overlapping the original
* text section's image section. We stop reading memory at the
* end of the section so we do not read the full instruction if
* parts of it have been overwritten by the update.
*
* Try to read the remaining bytes and decode the instruction again. If we
* succeed, set @insn->truncated to indicate that the instruction is truncated
* in @insn->isid.
*
* Returns zero on success, a negative error code otherwise.
* Returns -pte_bad_insn if the instruction could not be decoded.
*/
static int pt_insn_decode_retry(struct pt_insn *insn, struct pt_insn_ext *iext,
struct pt_image *image,
const struct pt_asid *asid)
{
int size, errcode, isid;
uint8_t isize, remaining;
if (!insn)
return -pte_internal;
isize = insn->size;
remaining = sizeof(insn->raw) - isize;
/* We failed for real if we already read the maximum number of bytes for
* an instruction.
*/
if (!remaining)
return -pte_bad_insn;
/* Read the remaining bytes from the image. */
size = pt_image_read(image, &isid, &insn->raw[isize], remaining, asid,
insn->ip + isize);
if (size <= 0) {
/* We should have gotten an error if we were not able to read at
* least one byte. Check this to guarantee termination.
*/
if (!size)
return -pte_internal;
/* Preserve the original error if there are no more bytes. */
if (size == -pte_nomap)
size = -pte_bad_insn;
return size;
}
/* Add the newly read bytes to the instruction's size. */
insn->size += (uint8_t) size;
/* Store the new size to avoid infinite recursion in case instruction
* decode fails after length decode, which would set @insn->size to the
* actual length.
*/
size = insn->size;
/* Try to decode the instruction again.
*
* If we fail again, we recursively retry again until we either fail to
* read more bytes or reach the maximum number of bytes for an
* instruction.
*/
errcode = pt_ild_decode(insn, iext);
if (errcode < 0) {
if (errcode != -pte_bad_insn)
return errcode;
/* If instruction length decode already determined the size,
* there's no point in reading more bytes.
*/
if (insn->size != (uint8_t) size)
return errcode;
return pt_insn_decode_retry(insn, iext, image, asid);
}
/* We succeeded this time, so the instruction crosses image section
* boundaries.
*
* This poses the question which isid to use for the instruction.
*
* To reconstruct exactly this instruction at a later time, we'd need to
* store all isids involved together with the number of bytes read for
* each isid. Since @insn already provides the exact bytes for this
* instruction, we assume that the isid will be used solely for source
* correlation. In this case, it should refer to the first byte of the
* instruction - as it already does.
*/
insn->truncated = 1;
return errcode;
}
int pt_insn_decode(struct pt_insn *insn, struct pt_insn_ext *iext,
struct pt_image *image, const struct pt_asid *asid)
{
int size, errcode;
if (!insn)
return -pte_internal;
/* Read the memory at the current IP in the current address space. */
size = pt_image_read(image, &insn->isid, insn->raw, sizeof(insn->raw),
asid, insn->ip);
if (size < 0)
return size;
/* We initialize @insn->size to the maximal possible size. It will be
* set to the actual size during instruction decode.
*/
insn->size = (uint8_t) size;
errcode = pt_ild_decode(insn, iext);
if (errcode < 0) {
if (errcode != -pte_bad_insn)
return errcode;
/* If instruction length decode already determined the size,
* there's no point in reading more bytes.
*/
if (insn->size != (uint8_t) size)
return errcode;
return pt_insn_decode_retry(insn, iext, image, asid);
}
return errcode;
}
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 steps)
{
struct pt_insn_ext iext;
struct pt_insn insn;
memset(&insn, 0, sizeof(insn));
insn.mode = mode;
insn.ip = begin;
while (insn.ip != end) {
int errcode;
if (!steps--)
return 0;
errcode = pt_insn_decode(&insn, &iext, image, asid);
if (errcode < 0)
return errcode;
errcode = pt_insn_next_ip(&insn.ip, &insn, &iext);
if (errcode < 0)
return errcode;
}
return 1;
}

Some files were not shown because too many files have changed in this diff Show More