Import Intel Processor Trace library.
Git ID 24982c1a6fce48f1e416461d42899805f74fbb26 Sponsored by: DARPA, AFRL Differential Revision: https://reviews.freebsd.org/D12815
This commit is contained in:
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
7
.gitignore
vendored
Normal file
7
.gitignore
vendored
Normal file
@ -0,0 +1,7 @@
|
||||
*.lst
|
||||
*.bin
|
||||
*.pt
|
||||
*.sb
|
||||
*.exp
|
||||
*.out
|
||||
*.diff
|
304
CMakeLists.txt
Normal file
304
CMakeLists.txt
Normal 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
107
CONTRIBUTING
Executable 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
24
LICENSE
Normal 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
79
README
Normal 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
93
doc/getting_started.md
Executable 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
197
doc/howto_build.md
Executable 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
628
doc/howto_capture.md
Normal 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
1271
doc/howto_libipt.md
Normal file
File diff suppressed because it is too large
Load Diff
482
doc/howto_pttc.md
Executable file
482
doc/howto_pttc.md
Executable 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
147
doc/man/CMakeLists.txt
Normal 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})
|
96
doc/man/pt_alloc_encoder.3.md
Normal file
96
doc/man/pt_alloc_encoder.3.md
Normal 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)
|
98
doc/man/pt_blk_alloc_decoder.3.md
Normal file
98
doc/man/pt_blk_alloc_decoder.3.md
Normal 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)
|
82
doc/man/pt_blk_get_offset.3.md
Normal file
82
doc/man/pt_blk_get_offset.3.md
Normal 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
285
doc/man/pt_blk_next.3.md
Normal 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)
|
152
doc/man/pt_blk_sync_forward.3.md
Normal file
152
doc/man/pt_blk_sync_forward.3.md
Normal 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
359
doc/man/pt_config.3.md
Normal 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)
|
77
doc/man/pt_enc_get_config.3.md
Normal file
77
doc/man/pt_enc_get_config.3.md
Normal 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)
|
77
doc/man/pt_enc_get_offset.3.md
Normal file
77
doc/man/pt_enc_get_offset.3.md
Normal 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)
|
135
doc/man/pt_image_add_file.3.md
Normal file
135
doc/man/pt_image_add_file.3.md
Normal 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)
|
99
doc/man/pt_image_alloc.3.md
Normal file
99
doc/man/pt_image_alloc.3.md
Normal 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)
|
150
doc/man/pt_image_remove_by_filename.3.md
Normal file
150
doc/man/pt_image_remove_by_filename.3.md
Normal 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)
|
103
doc/man/pt_image_set_callback.3.md
Normal file
103
doc/man/pt_image_set_callback.3.md
Normal 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)
|
101
doc/man/pt_insn_alloc_decoder.3.md
Normal file
101
doc/man/pt_insn_alloc_decoder.3.md
Normal 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)
|
93
doc/man/pt_insn_get_image.3.md
Normal file
93
doc/man/pt_insn_get_image.3.md
Normal 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)
|
82
doc/man/pt_insn_get_offset.3.md
Normal file
82
doc/man/pt_insn_get_offset.3.md
Normal 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
264
doc/man/pt_insn_next.3.md
Normal 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)
|
153
doc/man/pt_insn_sync_forward.3.md
Normal file
153
doc/man/pt_insn_sync_forward.3.md
Normal 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)
|
98
doc/man/pt_iscache_add_file.3.md
Normal file
98
doc/man/pt_iscache_add_file.3.md
Normal 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)
|
102
doc/man/pt_iscache_alloc.3.md
Normal file
102
doc/man/pt_iscache_alloc.3.md
Normal 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)
|
89
doc/man/pt_iscache_read.3.md
Normal file
89
doc/man/pt_iscache_read.3.md
Normal 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)
|
73
doc/man/pt_iscache_set_limit.3.md
Normal file
73
doc/man/pt_iscache_set_limit.3.md
Normal 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)
|
72
doc/man/pt_library_version.3.md
Normal file
72
doc/man/pt_library_version.3.md
Normal 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
197
doc/man/pt_packet.3.md
Normal 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)
|
98
doc/man/pt_pkt_alloc_decoder.3.md
Normal file
98
doc/man/pt_pkt_alloc_decoder.3.md
Normal 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)
|
81
doc/man/pt_pkt_get_offset.3.md
Normal file
81
doc/man/pt_pkt_get_offset.3.md
Normal 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)
|
115
doc/man/pt_pkt_sync_forward.3.md
Normal file
115
doc/man/pt_pkt_sync_forward.3.md
Normal 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)
|
113
doc/man/pt_qry_alloc_decoder.3.md
Normal file
113
doc/man/pt_qry_alloc_decoder.3.md
Normal 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)
|
152
doc/man/pt_qry_cond_branch.3.md
Normal file
152
doc/man/pt_qry_cond_branch.3.md
Normal 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
291
doc/man/pt_qry_event.3.md
Normal 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)
|
83
doc/man/pt_qry_get_offset.3.md
Normal file
83
doc/man/pt_qry_get_offset.3.md
Normal 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)
|
152
doc/man/pt_qry_sync_forward.3.md
Normal file
152
doc/man/pt_qry_sync_forward.3.md
Normal 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
128
doc/man/pt_qry_time.3.md
Normal 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
259
include/posix/threads.h
Normal 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
47
include/pt_compiler.h
Normal 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 */
|
65
include/windows/inttypes.h
Normal file
65
include/windows/inttypes.h
Normal 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
239
include/windows/threads.h
Normal 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
172
libipt/CMakeLists.txt
Normal 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
2463
libipt/include/intel-pt.h.in
Executable file
File diff suppressed because it is too large
Load Diff
100
libipt/internal/include/posix/pt_section_posix.h
Normal file
100
libipt/internal/include/posix/pt_section_posix.h
Normal 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 */
|
74
libipt/internal/include/pt_asid.h
Normal file
74
libipt/internal/include/pt_asid.h
Normal 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 */
|
225
libipt/internal/include/pt_block_cache.h
Normal file
225
libipt/internal/include/pt_block_cache.h
Normal 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 */
|
143
libipt/internal/include/pt_block_decoder.h
Normal file
143
libipt/internal/include/pt_block_decoder.h
Normal 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 */
|
82
libipt/internal/include/pt_config.h
Normal file
82
libipt/internal/include/pt_config.h
Normal 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);
|
54
libipt/internal/include/pt_cpu.h
Normal file
54
libipt/internal/include/pt_cpu.h
Normal 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 */
|
40
libipt/internal/include/pt_cpuid.h
Normal file
40
libipt/internal/include/pt_cpuid.h
Normal 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 */
|
129
libipt/internal/include/pt_decoder_function.h
Normal file
129
libipt/internal/include/pt_decoder_function.h
Normal 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 */
|
125
libipt/internal/include/pt_encoder.h
Normal file
125
libipt/internal/include/pt_encoder.h
Normal 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 */
|
143
libipt/internal/include/pt_event_queue.h
Normal file
143
libipt/internal/include/pt_event_queue.h
Normal 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 */
|
128
libipt/internal/include/pt_ild.h
Normal file
128
libipt/internal/include/pt_ild.h
Normal 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 */
|
140
libipt/internal/include/pt_image.h
Normal file
140
libipt/internal/include/pt_image.h
Normal 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 */
|
206
libipt/internal/include/pt_image_section_cache.h
Normal file
206
libipt/internal/include/pt_image_section_cache.h
Normal 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 */
|
212
libipt/internal/include/pt_insn.h
Normal file
212
libipt/internal/include/pt_insn.h
Normal 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 */
|
139
libipt/internal/include/pt_insn_decoder.h
Normal file
139
libipt/internal/include/pt_insn_decoder.h
Normal 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 */
|
79
libipt/internal/include/pt_last_ip.h
Normal file
79
libipt/internal/include/pt_last_ip.h
Normal 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 */
|
199
libipt/internal/include/pt_mapped_section.h
Normal file
199
libipt/internal/include/pt_mapped_section.h
Normal 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 */
|
95
libipt/internal/include/pt_msec_cache.h
Normal file
95
libipt/internal/include/pt_msec_cache.h
Normal 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 */
|
397
libipt/internal/include/pt_opcodes.h
Normal file
397
libipt/internal/include/pt_opcodes.h
Normal 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 */
|
111
libipt/internal/include/pt_packet.h
Normal file
111
libipt/internal/include/pt_packet.h
Normal 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 */
|
92
libipt/internal/include/pt_packet_decoder.h
Normal file
92
libipt/internal/include/pt_packet_decoder.h
Normal 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 */
|
134
libipt/internal/include/pt_query_decoder.h
Normal file
134
libipt/internal/include/pt_query_decoder.h
Normal 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 */
|
87
libipt/internal/include/pt_retstack.h
Normal file
87
libipt/internal/include/pt_retstack.h
Normal 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 */
|
392
libipt/internal/include/pt_section.h
Normal file
392
libipt/internal/include/pt_section.h
Normal 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 */
|
106
libipt/internal/include/pt_section_file.h
Normal file
106
libipt/internal/include/pt_section_file.h
Normal 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 */
|
71
libipt/internal/include/pt_sync.h
Normal file
71
libipt/internal/include/pt_sync.h
Normal 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 */
|
232
libipt/internal/include/pt_time.h
Normal file
232
libipt/internal/include/pt_time.h
Normal 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 */
|
88
libipt/internal/include/pt_tnt_cache.h
Normal file
88
libipt/internal/include/pt_tnt_cache.h
Normal 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 */
|
39
libipt/internal/include/pti-disp-defs.h
Normal file
39
libipt/internal/include/pti-disp-defs.h
Normal 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
|
544
libipt/internal/include/pti-disp.h
Normal file
544
libipt/internal/include/pti-disp.h
Normal 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,
|
||||
};
|
46
libipt/internal/include/pti-imm-defs.h
Normal file
46
libipt/internal/include/pti-imm-defs.h
Normal 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
|
544
libipt/internal/include/pti-imm.h
Normal file
544
libipt/internal/include/pti-imm.h
Normal 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,
|
||||
};
|
38
libipt/internal/include/pti-modrm-defs.h
Normal file
38
libipt/internal/include/pti-modrm-defs.h
Normal 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
|
544
libipt/internal/include/pti-modrm.h
Normal file
544
libipt/internal/include/pti-modrm.h
Normal 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,
|
||||
};
|
111
libipt/internal/include/windows/pt_section_windows.h
Normal file
111
libipt/internal/include/windows/pt_section_windows.h
Normal 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
36
libipt/src/posix/init.c
Normal 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();
|
||||
}
|
37
libipt/src/posix/pt_cpuid.c
Normal file
37
libipt/src/posix/pt_cpuid.c
Normal 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);
|
||||
}
|
326
libipt/src/posix/pt_section_posix.c
Normal file
326
libipt/src/posix/pt_section_posix.c
Normal 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
106
libipt/src/pt_asid.c
Normal 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;
|
||||
}
|
96
libipt/src/pt_block_cache.c
Normal file
96
libipt/src/pt_block_cache.c
Normal 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;
|
||||
}
|
3469
libipt/src/pt_block_decoder.c
Normal file
3469
libipt/src/pt_block_decoder.c
Normal file
File diff suppressed because it is too large
Load Diff
251
libipt/src/pt_config.c
Normal file
251
libipt/src/pt_config.c
Normal 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
164
libipt/src/pt_cpu.c
Normal 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;
|
||||
}
|
379
libipt/src/pt_decoder_function.c
Normal file
379
libipt/src/pt_decoder_function.c
Normal 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
917
libipt/src/pt_encoder.c
Normal 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
122
libipt/src/pt_error.c
Normal 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
203
libipt/src/pt_event_queue.c
Normal 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
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
718
libipt/src/pt_image.c
Normal 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 = ¤t->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, §ion, &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;
|
||||
}
|
1091
libipt/src/pt_image_section_cache.c
Normal file
1091
libipt/src/pt_image_section_cache.c
Normal file
File diff suppressed because it is too large
Load Diff
372
libipt/src/pt_insn.c
Normal file
372
libipt/src/pt_insn.c
Normal 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
Loading…
Reference in New Issue
Block a user