diff options
author | Ruslan Bukin <br@FreeBSD.org> | 2019-10-10 12:20:25 +0000 |
---|---|---|
committer | Ruslan Bukin <br@FreeBSD.org> | 2019-10-10 12:20:25 +0000 |
commit | ebacdab3d4e774ca6dd5a0904e43fd209e8abd3f (patch) | |
tree | 5b4cc6e151764817b6b99465bfe6de8670ebcf34 /doc |
Import Intel Processor Trace library.vendor/processor-trace/892e12c5a27bda5806d1e63269986bb4171b5a8b
Git ID 892e12c5a27bda5806d1e63269986bb4171b5a8b
Sponsored by: DARPA, AFRL
Notes
Notes:
svn path=/vendor/processor-trace/892e12c5a27bda5806d1e63269986bb4171b5a8b/; revision=353389; tag=vendor/processor-trace/892e12c5a27bda5806d1e63269986bb4171b5a8b
Diffstat (limited to 'doc')
38 files changed, 7085 insertions, 0 deletions
diff --git a/doc/getting_started.md b/doc/getting_started.md new file mode 100644 index 000000000000..b8cbbccbf400 --- /dev/null +++ b/doc/getting_started.md @@ -0,0 +1,95 @@ +Getting Started {#start} +======================== + +<!--- + ! Copyright (c) 2013-2019, Intel Corporation + ! + ! Redistribution and use in source and binary forms, with or without + ! modification, are permitted provided that the following conditions are met: + ! + ! * Redistributions of source code must retain the above copyright notice, + ! this list of conditions and the following disclaimer. + ! * Redistributions in binary form must reproduce the above copyright notice, + ! this list of conditions and the following disclaimer in the documentation + ! and/or other materials provided with the distribution. + ! * Neither the name of Intel Corporation nor the names of its contributors + ! may be used to endorse or promote products derived from this software + ! without specific prior written permission. + ! + ! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + ! AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + ! IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ! ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + ! LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + ! CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + ! SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + ! INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + ! CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ! ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + ! POSSIBILITY OF SUCH DAMAGE. + !--> + +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 the respective +chapter in Volume 3 of the Intel Software Developer's Manual at +https://www.intel.com/sdm. + +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. diff --git a/doc/howto_build.md b/doc/howto_build.md new file mode 100644 index 000000000000..f94095d5902d --- /dev/null +++ b/doc/howto_build.md @@ -0,0 +1,202 @@ +Building the Intel(R) Processor Trace (Intel PT) Decoder Library and Samples {#build} +============================================================================ + +<!--- + ! Copyright (c) 2013-2019, Intel Corporation + ! + ! Redistribution and use in source and binary forms, with or without + ! modification, are permitted provided that the following conditions are met: + ! + ! * Redistributions of source code must retain the above copyright notice, + ! this list of conditions and the following disclaimer. + ! * Redistributions in binary form must reproduce the above copyright notice, + ! this list of conditions and the following disclaimer in the documentation + ! and/or other materials provided with the distribution. + ! * Neither the name of Intel Corporation nor the names of its contributors + ! may be used to endorse or promote products derived from this software + ! without specific prior written permission. + ! + ! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + ! AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + ! IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ! ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + ! LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + ! CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + ! SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + ! INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + ! CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ! ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + ! POSSIBILITY OF SUCH DAMAGE. + !--> + +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, minor, and patch version numbers are set in the sources and +must be changed there. You can set the optional build number and an +arbitrary extension string. + + PT_VERSION_BUILD The optional build number. + + Defaults to zero (no build number). + + + PT_VERSION_EXT An arbitrary version extension string. + + Defaults to the empty string (no extension 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>/`. + +When using XED from github, the respective directories are located in the +install directory (default: kits/xed-install-date-os-cpu) and the header +files are located in include/xed. Please refer to the README in the XED +tree on how to build XED. + + +## 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. diff --git a/doc/howto_capture.md b/doc/howto_capture.md new file mode 100644 index 000000000000..bec0099aa165 --- /dev/null +++ b/doc/howto_capture.md @@ -0,0 +1,628 @@ +Capturing Intel(R) Processor Trace (Intel PT) {#capture} +============================================= + +<!--- + ! Copyright (c) 2015-2019, Intel Corporation + ! + ! Redistribution and use in source and binary forms, with or without + ! modification, are permitted provided that the following conditions are met: + ! + ! * Redistributions of source code must retain the above copyright notice, + ! this list of conditions and the following disclaimer. + ! * Redistributions in binary form must reproduce the above copyright notice, + ! this list of conditions and the following disclaimer in the documentation + ! and/or other materials provided with the distribution. + ! * Neither the name of Intel Corporation nor the names of its contributors + ! may be used to endorse or promote products derived from this software + ! without specific prior written permission. + ! + ! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + ! AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + ! IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ! ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + ! LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + ! CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + ! SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + ! INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + ! CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ! ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + ! POSSIBILITY OF SUCH DAMAGE. + !--> + +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. diff --git a/doc/howto_libipt.md b/doc/howto_libipt.md new file mode 100644 index 000000000000..3d3c12f0bb16 --- /dev/null +++ b/doc/howto_libipt.md @@ -0,0 +1,1271 @@ +Decoding Intel(R) Processor Trace Using libipt {#libipt} +======================================================== + +<!--- + ! Copyright (c) 2013-2019, Intel Corporation + ! + ! Redistribution and use in source and binary forms, with or without + ! modification, are permitted provided that the following conditions are met: + ! + ! * Redistributions of source code must retain the above copyright notice, + ! this list of conditions and the following disclaimer. + ! * Redistributions in binary form must reproduce the above copyright notice, + ! this list of conditions and the following disclaimer in the documentation + ! and/or other materials provided with the distribution. + ! * Neither the name of Intel Corporation nor the names of its contributors + ! may be used to endorse or promote products derived from this software + ! without specific prior written permission. + ! + ! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + ! AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + ! IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ! ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + ! LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + ! CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + ! SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + ! INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + ! CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ! ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + ! POSSIBILITY OF SUCH DAMAGE. + !--> + +This chapter describes how to use libipt for various tasks around Intel +Processor Trace (Intel PT). For code examples, refer to the sample tools that +are contained in the source tree: + + * *ptdump* A packet dumper example. + * *ptxed* A control-flow reconstruction example. + * *pttc* A packet encoder example. + + +For detailed information about Intel PT, please refer to the respective chapter +in Volume 3 of the Intel Software Developer's Manual at +http://www.intel.com/sdm. + + +## Introduction + +The libipt decoder library provides multiple layers of abstraction ranging from +packet encoding and decoding to full execution flow reconstruction. The layers +are organized as follows: + + * *packets* This layer deals with raw Intel PT packets. + + * *events* This layer deals with packet combinations that + encode higher-level events. + + * *instruction flow* This layer deals with the execution flow on the + instruction level. + + * *block* This layer deals with the execution flow on the + instruction level. + + It is faster than the instruction flow decoder but + requires a small amount of post-processing. + + +Each layer provides its own encoder or decoder struct plus a set of functions +for allocating and freeing encoder or decoder objects and for synchronizing +decoders onto the Intel PT packet stream. Function names are prefixed with +`pt_<lyr>_` where `<lyr>` is an abbreviation of the layer name. The following +abbreviations are used: + + * *enc* Packet encoding (packet layer). + * *pkt* Packet decoding (packet layer). + * *qry* Event (or query) layer. + * *insn* Instruction flow layer. + * *blk* Block layer. + + +Here is some generic example code for working with decoders: + +~~~{.c} + struct pt_<layer>_decoder *decoder; + struct pt_config config; + int errcode; + + memset(&config, 0, sizeof(config)); + config.size = sizeof(config); + config.begin = <pt buffer begin>; + config.end = <pt buffer end>; + config.cpu = <cpu identifier>; + config... + + decoder = pt_<lyr>_alloc_decoder(&config); + if (!decoder) + <handle error>(errcode); + + errcode = pt_<lyr>_sync_<where>(decoder); + if (errcode < 0) + <handle error>(errcode); + + <use decoder>(decoder); + + pt_<lyr>_free_decoder(decoder); +~~~ + +First, configure the decoder. As a minimum, the size of the config struct and +the `begin` and `end` of the buffer containing the Intel PT data need to be set. +Configuration options details will be discussed later in this chapter. In the +case of packet encoding, this is the begin and end address of the pre-allocated +buffer, into which Intel PT packets shall be written. + +Next, allocate a decoder object for the layer you are interested in. A return +value of NULL indicates an error. There is no further information available on +the exact error condition. Most of the time, however, the error is the result +of an incomplete or inconsistent configuration. + +Before the decoder can be used, it needs to be synchronized onto the Intel PT +packet stream specified in the configuration. The only exception to this is the +packet encoder, which is implicitly synchronized onto the beginning of the Intel +PT buffer. + +Depending on the type of decoder, one or more synchronization options are +available. + + * `pt_<lyr>_sync_forward()` Synchronize onto the next PSB in forward + direction (or the first PSB if not yet + synchronized). + + * `pt_<lyr>_sync_backward()` Synchronize onto the next PSB in backward + direction (or the last PSB if not yet + synchronized). + + * `pt_<lyr>_sync_set()` Set the synchronization position to a + user-defined location in the Intel PT packet + stream. + There is no check whether the specified + location makes sense or is valid. + + +After synchronizing, the decoder can be used. While decoding, the decoder +stores the location of the last PSB it encountered during normal decode. +Subsequent calls to pt_<lyr>_sync_forward() will start searching from that +location. This is useful for re-synchronizing onto the Intel PT packet stream +in case of errors. An example of a typical decode loop is given below: + +~~~{.c} + for (;;) { + int errcode; + + errcode = <use decoder>(decoder); + if (errcode >= 0) + continue; + + if (errcode == -pte_eos) + return; + + <report error>(errcode); + + do { + errcode = pt_<lyr>_sync_forward(decoder); + + if (errcode == -pte_eos) + return; + } while (errcode < 0); + } +~~~ + +You can get the current decoder position as offset into the Intel PT buffer via: + + pt_<lyr>_get_offset() + + +You can get the position of the last synchronization point as offset into the +Intel PT buffer via: + + pt_<lyr>_get_sync_offset() + + +Each layer will be discussed in detail below. In the remainder of this section, +general functionality will be considered. + + +### Version + +You can query the library version using: + + * `pt_library_version()` + + +This function returns a version structure that can be used for compatibility +checks or simply for reporting the version of the decoder library. + + +### Errors + +The library uses a single error enum for all layers. + + * `enum pt_error_code` An enumeration of encode and decode errors. + + +Errors are typically represented as negative pt_error_code enumeration constants +and returned as an int. The library provides two functions for dealing with +errors: + + * `pt_errcode()` Translate an int return value into a pt_error_code + enumeration constant. + + * `pt_errstr()` Returns a human-readable error string. + + +Not all errors may occur on every layer. Every API function specifies the +errors it may return. + + +### Configuration + +Every encoder or decoder allocation function requires a configuration argument. +Some of its fields have already been discussed in the example above. Refer to +the `intel-pt.h` header for detailed and up-to-date documentation of each field. + +As a minimum, the `size` field needs to be set to `sizeof(struct pt_config)` and +`begin` and `end` need to be set to the Intel PT buffer to use. + +The size is used for detecting library version mismatches and to provide +backwards compatibility. Without the proper `size`, decoder allocation will +fail. + +Although not strictly required, it is recommended to also set the `cpu` field to +the processor, on which Intel PT has been collected (for decoders), or for which +Intel PT shall be generated (for encoders). This allows implementing +processor-specific behavior such as erratum workarounds. + + +## The Packet Layer + +This layer deals with Intel PT packet encoding and decoding. It can further be +split into three sub-layers: opcodes, encoding, and decoding. + + +### Opcodes + +The opcodes layer provides enumerations for all the bits necessary for Intel PT +encoding and decoding. The enumeration constants can be used without linking to +the decoder library. There is no encoder or decoder struct associated with this +layer. See the intel-pt.h header file for details. + + +### Packet Encoding + +The packet encoding layer provides support for encoding Intel PT +packet-by-packet. Start by configuring and allocating a `pt_packet_encoder` as +shown below: + +~~~{.c} + struct pt_encoder *encoder; + struct pt_config config; + int errcode; + + memset(&config, 0, sizeof(config)); + config.size = sizeof(config); + config.begin = <pt buffer begin>; + config.end = <pt buffer end>; + config.cpu = <cpu identifier>; + + encoder = pt_alloc_encoder(&config); + if (!encoder) + <handle error>(errcode); +~~~ + +For packet encoding, only the mandatory config fields need to be filled in. + +The allocated encoder object will be implicitly synchronized onto the beginning +of the Intel PT buffer. You may change the encoder's position at any time by +calling `pt_enc_sync_set()` with the desired buffer offset. + +Next, fill in a `pt_packet` object with details about the packet to be encoded. +You do not need to fill in the `size` field. The needed size is computed by the +encoder. There is no consistency check with the size specified in the packet +object. The following example encodes a TIP packet: + +~~~{.c} + struct pt_packet_encoder *encoder = ...; + struct pt_packet packet; + int errcode; + + packet.type = ppt_tip; + packet.payload.ip.ipc = pt_ipc_update_16; + packet.payload.ip.ip = <ip>; +~~~ + +For IP packets, for example FUP or TIP.PGE, there is no need to mask out bits in +the `ip` field that will not be encoded in the packet due to the specified IP +compression in the `ipc` field. The encoder will ignore them. + +There are no consistency checks whether the specified IP compression in the +`ipc` field is allowed in the current context or whether decode will result in +the full IP specified in the `ip` field. + +Once the packet object has been filled, it can be handed over to the encoder as +shown here: + +~~~{.c} + errcode = pt_enc_next(encoder, &packet); + if (errcode < 0) + <handle error>(errcode); +~~~ + +The encoder will encode the packet, write it into the Intel PT buffer, and +advance its position to the next byte after the packet. On a successful encode, +it will return the number of bytes that have been written. In case of errors, +nothing will be written and the encoder returns a negative error code. + + +### Packet Decoding + +The packet decoding layer provides support for decoding Intel PT +packet-by-packet. Start by configuring and allocating a `pt_packet_decoder` as +shown here: + +~~~{.c} + struct pt_packet_decoder *decoder; + struct pt_config config; + int errcode; + + memset(&config, 0, sizeof(config)); + config.size = sizeof(config); + config.begin = <pt buffer begin>; + config.end = <pt buffer end>; + config.cpu = <cpu identifier>; + config.decode.callback = <decode function>; + config.decode.context = <decode context>; + + decoder = pt_pkt_alloc_decoder(&config); + if (!decoder) + <handle error>(errcode); +~~~ + +For packet decoding, an optional decode callback function may be specified in +addition to the mandatory config fields. If specified, the callback function +will be called for packets the decoder does not know about. If there is no +decode callback specified, the decoder will return `-pte_bad_opc`. In addition +to the callback function pointer, an optional pointer to user-defined context +information can be specified. This context will be passed to the decode +callback function. + +Before the decoder can be used, it needs to be synchronized onto the Intel PT +packet stream. Packet decoders offer three synchronization functions. To +iterate over synchronization points in the Intel PT packet stream in forward or +backward direction, use one of the following two functions respectively: + + pt_pkt_sync_forward() + pt_pkt_sync_backward() + + +To manually synchronize the decoder at a particular offset into the Intel PT +packet stream, use the following function: + + pt_pkt_sync_set() + + +There are no checks to ensure that the specified offset is at the beginning of a +packet. The example below shows synchronization to the first synchronization +point: + +~~~{.c} + struct pt_packet_decoder *decoder; + int errcode; + + errcode = pt_pkt_sync_forward(decoder); + if (errcode < 0) + <handle error>(errcode); +~~~ + +The decoder will remember the last synchronization packet it decoded. +Subsequent calls to `pt_pkt_sync_forward` and `pt_pkt_sync_backward` will use +this as their starting point. + +You can get the current decoder position as offset into the Intel PT buffer via: + + pt_pkt_get_offset() + + +You can get the position of the last synchronization point as offset into the +Intel PT buffer via: + + pt_pkt_get_sync_offset() + + +Once the decoder is synchronized, you can iterate over packets by repeated calls +to `pt_pkt_next()` as shown in the following example: + +~~~{.c} + struct pt_packet_decoder *decoder; + int errcode; + + for (;;) { + struct pt_packet packet; + + errcode = pt_pkt_next(decoder, &packet, sizeof(packet)); + if (errcode < 0) + break; + + <process packet>(&packet); + } +~~~ + + +## The Event Layer + +The event layer deals with packet combinations that encode higher-level events. +It is used for reconstructing execution flow for users who need finer-grain +control not available via the instruction flow layer or for users who want to +integrate execution flow reconstruction with other functionality more tightly +than it would be possible otherwise. + +This section describes how to use the query decoder for reconstructing execution +flow. See the instruction flow decoder as an example. Start by configuring and +allocating a `pt_query_decoder` as shown below: + +~~~{.c} + struct pt_query_decoder *decoder; + struct pt_config config; + int errcode; + + memset(&config, 0, sizeof(config)); + config.size = sizeof(config); + config.begin = <pt buffer begin>; + config.end = <pt buffer end>; + config.cpu = <cpu identifier>; + config.decode.callback = <decode function>; + config.decode.context = <decode context>; + + decoder = pt_qry_alloc_decoder(&config); + if (!decoder) + <handle error>(errcode); +~~~ + +An optional packet decode callback function may be specified in addition to the +mandatory config fields. If specified, the callback function will be called for +packets the decoder does not know about. The query decoder will ignore the +unknown packet except for its size in order to skip it. If there is no decode +callback specified, the decoder will abort with `-pte_bad_opc`. In addition to +the callback function pointer, an optional pointer to user-defined context +information can be specified. This context will be passed to the decode +callback function. + +Before the decoder can be used, it needs to be synchronized onto the Intel PT +packet stream. To iterate over synchronization points in the Intel PT packet +stream in forward or backward direction, the query decoders offer the following +two synchronization functions respectively: + + pt_qry_sync_forward() + pt_qry_sync_backward() + + +To manually synchronize the decoder at a synchronization point (i.e. PSB packet) +in the Intel PT packet stream, use the following function: + + pt_qry_sync_set() + + +After successfully synchronizing, the query decoder will start reading the PSB+ +header to initialize its internal state. If tracing is enabled at this +synchronization point, the IP of the instruction, at which decoding should be +started, is returned. If tracing is disabled at this synchronization point, it +will be indicated in the returned status bits (see below). In this example, +synchronization to the first synchronization point is shown: + +~~~{.c} + struct pt_query_decoder *decoder; + uint64_t ip; + int status; + + status = pt_qry_sync_forward(decoder, &ip); + if (status < 0) + <handle error>(status); +~~~ + +In addition to a query decoder, you will need an instruction decoder for +decoding and classifying instructions. + + +#### In A Nutshell + +After synchronizing, you begin decoding instructions starting at the returned +IP. As long as you can determine the next instruction in execution order, you +continue on your own. Only when the next instruction cannot be determined by +examining the current instruction, you would ask the query decoder for guidance: + + * If the current instruction is a conditional branch, the + `pt_qry_cond_branch()` function will tell whether it was taken. + + * If the current instruction is an indirect branch, the + `pt_qry_indirect_branch()` function will provide the IP of its destination. + + +~~~{.c} + struct pt_query_decoder *decoder; + uint64_t ip; + + for (;;) { + struct <instruction> insn; + + insn = <decode instruction>(ip); + + ip += <instruction size>(insn); + + if (<is cond branch>(insn)) { + int status, taken; + + status = pt_qry_cond_branch(decoder, &taken); + if (status < 0) + <handle error>(status); + + if (taken) + ip += <branch displacement>(insn); + } else if (<is indirect branch>(insn)) { + int status; + + status = pt_qry_indirect_branch(decoder, &ip); + if (status < 0) + <handle error>(status); + } + } +~~~ + + +Certain aspects such as, for example, asynchronous events or synchronizing at a +location where tracing is disabled, have been ignored so far. Let us consider +them now. + + +#### Queries + +The query decoder provides four query functions: + + * `pt_qry_cond_branch()` Query whether the next conditional branch was + taken. + + * `pt_qry_indirect_branch()` Query for the destination IP of the next + indirect branch. + + * `pt_qry_event()` Query for the next event. + + * `pt_qry_time()` Query for the current time. + + +Each function returns either a positive vector of status bits or a negative +error code. For details on status bits and error conditions, please refer to +the `pt_status_flag` and `pt_error_code` enumerations in the intel-pt.h header. + +The `pts_ip_suppressed` status bit is used to indicate that no IP is available +at functions that are supposed to return an IP. Examples are the indirect +branch query function and both synchronization functions. + +The `pts_event_pending` status bit is used to indicate that there is an event +pending. You should query for this event before continuing execution flow +reconstruction. + +The `pts_eos` status bit is used to indicate the end of the trace. Any +subsequent query will return -pte_eos. + + +#### Events + +Events are signaled ahead of time. When you query for pending events as soon as +they are indicated, you will be aware of asynchronous events before you reach +the instruction associated with the event. + +For example, if tracing is disabled at the synchronization point, the IP will be +suppressed. In this case, it is very likely that a tracing enabled event is +signaled. You will also get events for initializing the decoder state after +synchronizing onto the Intel PT packet stream. For example, paging or execution +mode events. + +See the `enum pt_event_type` and `struct pt_event` in the intel-pt.h header for +details on possible events. This document does not give an example of event +processing. Refer to the implementation of the instruction flow decoder in +pt_insn.c for details. + + +#### Timing + +To be able to signal events, the decoder reads ahead until it arrives at a query +relevant packet. Errors encountered during that time will be postponed until +the respective query call. This reading ahead affects timing. The decoder will +always be a few packets ahead. When querying for the current time, the query +will return the time at the decoder's current packet. This corresponds to the +time at our next query. + + +#### Return Compression + +If Intel PT has been configured to compress returns, a successfully compressed +return is represented as a conditional branch instead of an indirect branch. +For a RET instruction, you first query for a conditional branch. If the query +succeeds, it should indicate that the branch was taken. In that case, the +return has been compressed. A not taken branch indicates an error. If the +query fails, the return has not been compressed and you query for an indirect +branch. + +There is no guarantee that returns will be compressed. Even though return +compression has been enabled, returns may still be represented as indirect +branches. + +To reconstruct the execution flow for compressed returns, you would maintain a +stack of return addresses. For each call instruction, push the IP of the +instruction following the call onto the stack. For compressed returns, pop the +topmost IP from the stack. See pt_retstack.h and pt_retstack.c for a sample +implementation. + + +## The Instruction Flow Layer + +The instruction flow layer provides a simple API for iterating over instructions +in execution order. Start by configuring and allocating a `pt_insn_decoder` as +shown below: + +~~~{.c} + struct pt_insn_decoder *decoder; + struct pt_config config; + int errcode; + + memset(&config, 0, sizeof(config)); + config.size = sizeof(config); + config.begin = <pt buffer begin>; + config.end = <pt buffer end>; + config.cpu = <cpu identifier>; + config.decode.callback = <decode function>; + config.decode.context = <decode context>; + + decoder = pt_insn_alloc_decoder(&config); + if (!decoder) + <handle error>(errcode); +~~~ + +An optional packet decode callback function may be specified in addition to the +mandatory config fields. If specified, the callback function will be called for +packets the decoder does not know about. The decoder will ignore the unknown +packet except for its size in order to skip it. If there is no decode callback +specified, the decoder will abort with `-pte_bad_opc`. In addition to the +callback function pointer, an optional pointer to user-defined context +information can be specified. This context will be passed to the decode +callback function. + +The image argument is optional. If no image is given, the decoder will use an +empty default image that can be populated later on and that is implicitly +destroyed when the decoder is freed. See below for more information on this. + + +#### The Traced Image + +In addition to the Intel PT configuration, the instruction flow decoder needs to +know the memory image for which Intel PT has been recorded. This memory image +is represented by a `pt_image` object. If decoding failed due to an IP lying +outside of the traced memory image, `pt_insn_next()` will return `-pte_nomap`. + +Use `pt_image_alloc()` to allocate and `pt_image_free()` to free an image. +Images may not be shared. Every decoder must use a different image. Use this +to prepare the image in advance or if you want to switch between images. + +Every decoder provides an empty default image that is used if no image is +specified during allocation. The default image is implicitly destroyed when the +decoder is freed. It can be obtained by calling `pt_insn_get_image()`. Use +this if you only use one decoder and one image. + +An image is a collection of contiguous, non-overlapping memory regions called +`sections`. Starting with an empty image, it may be populated with repeated +calls to `pt_image_add_file()` or `pt_image_add_cached()`, one for each section, +or with a call to `pt_image_copy()` to add all sections from another image. If +a newly added section overlaps with an existing section, the existing section +will be truncated or split to make room for the new section. + +In some cases, the memory image may change during the execution. You can use +the `pt_image_remove_by_filename()` function to remove previously added sections +by their file name and `pt_image_remove_by_asid()` to remove all sections for an +address-space. + +In addition to adding sections, you can register a callback function for reading +memory using `pt_image_set_callback()`. The `context` parameter you pass +together with the callback function pointer will be passed to your callback +function every time it is called. There can only be one callback at any time. +Adding a new callback will remove any previously added callback. To remove the +callback function, pass `NULL` to `pt_image_set_callback()`. + +Callback and files may be combined. The callback function is used whenever +the memory cannot be found in any of the image's sections. + +If more than one process is traced, the memory image may change when the process +context is switched. To simplify handling this case, an address-space +identifier may be passed to each of the above functions to define separate +images for different processes at the same time. The decoder will select the +correct image based on context switch information in the Intel PT trace. If +you want to manage this on your own, you can use `pt_insn_set_image()` to +replace the image a decoder uses. + + +#### The Traced Image Section Cache + +When using multiple decoders that work on related memory images it is desirable +to share image sections between decoders. The underlying file sections will be +mapped only once per image section cache. + +Use `pt_iscache_alloc()` to allocate and `pt_iscache_free()` to free an image +section cache. Freeing the cache does not destroy sections added to the cache. +They remain valid until they are no longer used. + +Use `pt_iscache_add_file()` to add a file section to an image section cache. +The function returns an image section identifier (ISID) that uniquely identifies +the section in this cache. Use `pt_image_add_cached()` to add a file section +from an image section cache to an image. + +Multiple image section caches may be used at the same time but it is recommended +not to mix sections from different image section caches in one image. + +A traced image section cache can also be used for reading an instruction's +memory via its IP and ISID as provided in `struct pt_insn`. + +The image section cache provides a cache of recently mapped sections and keeps +them mapped when they are unmapped by the images that used them. This avoid +repeated unmapping and re-mapping of image sections in some parallel debug +scenarios or when reading memory from the image section cache. + +Use `pt_iscache_set_limit()` to set the limit of this cache in bytes. This +accounts for the extra memory that will be used for keeping image sections +mapped including any block caches associated with image sections. To disable +caching, set the limit to zero. + + +#### Synchronizing + +Before the decoder can be used, it needs to be synchronized onto the Intel PT +packet stream. To iterate over synchronization points in the Intel PT packet +stream in forward or backward directions, the instruction flow decoders offer +the following two synchronization functions respectively: + + pt_insn_sync_forward() + pt_insn_sync_backward() + + +To manually synchronize the decoder at a synchronization point (i.e. PSB packet) +in the Intel PT packet stream, use the following function: + + pt_insn_sync_set() + + +The example below shows synchronization to the first synchronization point: + +~~~{.c} + struct pt_insn_decoder *decoder; + int errcode; + + errcode = pt_insn_sync_forward(decoder); + if (errcode < 0) + <handle error>(errcode); +~~~ + +The decoder will remember the last synchronization packet it decoded. +Subsequent calls to `pt_insn_sync_forward` and `pt_insn_sync_backward` will use +this as their starting point. + +You can get the current decoder position as offset into the Intel PT buffer via: + + pt_insn_get_offset() + + +You can get the position of the last synchronization point as offset into the +Intel PT buffer via: + + pt_insn_get_sync_offset() + + +#### Iterating + +Once the decoder is synchronized, you can iterate over instructions in execution +flow order by repeated calls to `pt_insn_next()` as shown in the following +example: + +~~~{.c} + struct pt_insn_decoder *decoder; + int status; + + for (;;) { + struct pt_insn insn; + + status = pt_insn_next(decoder, &insn, sizeof(insn)); + + if (insn.iclass != ptic_error) + <process instruction>(&insn); + + if (status < 0) + break; + + ... + } +~~~ + +Note that the example ignores non-error status returns. + +For each instruction, you get its IP, its size in bytes, the raw memory, an +identifier for the image section that contained it, the current execution mode, +and the speculation state, that is whether the instruction has been executed +speculatively. In addition, you get a coarse classification that can be used +for further processing without the need for a full instruction decode. + +If a traced image section cache is used the image section identifier can be used +to trace an instruction back to the binary file that contained it. This allows +mapping the instruction back to source code using the debug information +contained in or reachable via the binary file. + +Beware that `pt_insn_next()` may indicate errors that occur after the returned +instruction. The returned instruction is valid if its `iclass` field is set. + + +#### Events + +The instruction flow decoder uses an event system similar to the query +decoder's. Pending events are indicated by the `pts_event_pending` flag in the +status flag bit-vector returned from `pt_insn_sync_<where>()`, `pt_insn_next()` +and `pt_insn_event()`. + +When the `pts_event_pending` flag is set on return from `pt_insn_next()`, use +repeated calls to `pt_insn_event()` to drain all queued events. Then switch +back to calling `pt_insn_next()` to resume with instruction flow decode as +shown in the following example: + +~~~{.c} + struct pt_insn_decoder *decoder; + int status; + + for (;;) { + struct pt_insn insn; + + status = pt_insn_next(decoder, &insn, sizeof(insn)); + if (status < 0) + break; + + <process instruction>(&insn); + + while (status & pts_event_pending) { + struct pt_event event; + + status = pt_insn_event(decoder, &event, sizeof(event)); + if (status < 0) + <handle error>(status); + + <process event>(&event); + } + } +~~~ + + +#### The Instruction Flow Decode Loop + +If we put all of the above examples together, we end up with a decode loop as +shown below: + +~~~{.c} + int handle_events(struct pt_insn_decoder *decoder, int status) + { + while (status & pts_event_pending) { + struct pt_event event; + + status = pt_insn_event(decoder, &event, sizeof(event)); + if (status < 0) + break; + + <process event>(&event); + } + + return status; + } + + int decode(struct pt_insn_decoder *decoder) + { + int status; + + for (;;) { + status = pt_insn_sync_forward(decoder); + if (status < 0) + break; + + for (;;) { + struct pt_insn insn; + + status = handle_events(decoder, status); + if (status < 0) + break; + + status = pt_insn_next(decoder, &insn, sizeof(insn)); + + if (insn.iclass != ptic_error) + <process instruction>(&insn); + + if (status < 0) + break; + } + + <handle error>(status); + } + + <handle error>(status); + + return status; + } +~~~ + + +## The Block Layer + +The block layer provides a simple API for iterating over blocks of sequential +instructions in execution order. The instructions in a block are sequential in +the sense that no trace is required for reconstructing the instructions. The IP +of the first instruction is given in `struct pt_block` and the IP of other +instructions in the block can be determined by decoding and examining the +previous instruction. + +Start by configuring and allocating a `pt_block_decoder` as shown below: + +~~~{.c} + struct pt_block_decoder *decoder; + struct pt_config config; + + memset(&config, 0, sizeof(config)); + config.size = sizeof(config); + config.begin = <pt buffer begin>; + config.end = <pt buffer end>; + config.cpu = <cpu identifier>; + config.decode.callback = <decode function>; + config.decode.context = <decode context>; + + decoder = pt_blk_alloc_decoder(&config); +~~~ + +An optional packet decode callback function may be specified in addition to the +mandatory config fields. If specified, the callback function will be called for +packets the decoder does not know about. The decoder will ignore the unknown +packet except for its size in order to skip it. If there is no decode callback +specified, the decoder will abort with `-pte_bad_opc`. In addition to the +callback function pointer, an optional pointer to user-defined context +information can be specified. This context will be passed to the decode +callback function. + + +#### Synchronizing + +Before the decoder can be used, it needs to be synchronized onto the Intel PT +packet stream. To iterate over synchronization points in the Intel PT packet +stream in forward or backward directions, the block decoder offers the following +two synchronization functions respectively: + + pt_blk_sync_forward() + pt_blk_sync_backward() + + +To manually synchronize the decoder at a synchronization point (i.e. PSB packet) +in the Intel PT packet stream, use the following function: + + pt_blk_sync_set() + + +The example below shows synchronization to the first synchronization point: + +~~~{.c} + struct pt_block_decoder *decoder; + int errcode; + + errcode = pt_blk_sync_forward(decoder); + if (errcode < 0) + <handle error>(errcode); +~~~ + +The decoder will remember the last synchronization packet it decoded. +Subsequent calls to `pt_blk_sync_forward` and `pt_blk_sync_backward` will use +this as their starting point. + +You can get the current decoder position as offset into the Intel PT buffer via: + + pt_blk_get_offset() + + +You can get the position of the last synchronization point as offset into the +Intel PT buffer via: + + pt_blk_get_sync_offset() + + +#### Iterating + +Once the decoder is synchronized, it can be used to iterate over blocks of +instructions in execution flow order by repeated calls to `pt_blk_next()` as +shown in the following example: + +~~~{.c} + struct pt_block_decoder *decoder; + int status; + + for (;;) { + struct pt_block block; + + status = pt_blk_next(decoder, &block, sizeof(block)); + + if (block.ninsn > 0) + <process block>(&block); + + if (status < 0) + break; + + ... + } +~~~ + +Note that the example ignores non-error status returns. + +A block contains enough information to reconstruct the instructions. See +`struct pt_block` in `intel-pt.h` for details. Note that errors returned by +`pt_blk_next()` apply after the last instruction in the provided block. + +It is recommended to use a traced image section cache so the image section +identifier contained in a block can be used for reading the memory containing +the instructions in the block. This also allows mapping the instructions back +to source code using the debug information contained in or reachable via the +binary file. + +In some cases, the last instruction in a block may cross image section +boundaries. This can happen when a code segment is split into more than one +image section. The block is marked truncated in this case and provides the raw +bytes of the last instruction. + +The following example shows how instructions can be reconstructed from a block: + +~~~{.c} + struct pt_image_section_cache *iscache; + struct pt_block *block; + uint16_t ninsn; + uint64_t ip; + + ip = block->ip; + for (ninsn = 0; ninsn < block->ninsn; ++ninsn) { + uint8_t raw[pt_max_insn_size]; + <struct insn> insn; + int size; + + if (block->truncated && ((ninsn +1) == block->ninsn)) { + memcpy(raw, block->raw, block->size); + size = block->size; + } else { + size = pt_iscache_read(iscache, raw, sizeof(raw), block->isid, ip); + if (size < 0) + break; + } + + errcode = <decode instruction>(&insn, raw, size, block->mode); + if (errcode < 0) + break; + + <process instruction>(&insn); + + ip = <determine next ip>(&insn); + } +~~~ + + +#### Events + +The block decoder uses an event system similar to the query decoder's. Pending +events are indicated by the `pts_event_pending` flag in the status flag +bit-vector returned from `pt_blk_sync_<where>()`, `pt_blk_next()` and +`pt_blk_event()`. + +When the `pts_event_pending` flag is set on return from `pt_blk_sync_<where>()` +or `pt_blk_next()`, use repeated calls to `pt_blk_event()` to drain all queued +events. Then switch back to calling `pt_blk_next()` to resume with block decode +as shown in the following example: + +~~~{.c} + struct pt_block_decoder *decoder; + int status; + + for (;;) { + struct pt_block block; + + status = pt_blk_next(decoder, &block, sizeof(block)); + if (status < 0) + break; + + <process block>(&block); + + while (status & pts_event_pending) { + struct pt_event event; + + status = pt_blk_event(decoder, &event, sizeof(event)); + if (status < 0) + <handle error>(status); + + <process event>(&event); + } + } +~~~ + + +#### The Block Decode Loop + +If we put all of the above examples together, we end up with a decode loop as +shown below: + +~~~{.c} + int process_block(struct pt_block *block, + struct pt_image_section_cache *iscache) + { + uint16_t ninsn; + uint64_t ip; + + ip = block->ip; + for (ninsn = 0; ninsn < block->ninsn; ++ninsn) { + struct pt_insn insn; + + memset(&insn, 0, sizeof(insn)); + insn->speculative = block->speculative; + insn->isid = block->isid; + insn->mode = block->mode; + insn->ip = ip; + + if (block->truncated && ((ninsn +1) == block->ninsn)) { + insn.truncated = 1; + insn.size = block->size; + + memcpy(insn.raw, block->raw, insn.size); + } else { + int size; + + size = pt_iscache_read(iscache, insn.raw, sizeof(insn.raw), + insn.isid, insn.ip); + if (size < 0) + return size; + + insn.size = (uint8_t) size; + } + + <decode instruction>(&insn); + <process instruction>(&insn); + + ip = <determine next ip>(&insn); + } + + return 0; + } + + int handle_events(struct pt_blk_decoder *decoder, int status) + { + while (status & pts_event_pending) { + struct pt_event event; + + status = pt_blk_event(decoder, &event, sizeof(event)); + if (status < 0) + break; + + <process event>(&event); + } + + return status; + } + + int decode(struct pt_blk_decoder *decoder, + struct pt_image_section_cache *iscache) + { + int status; + + for (;;) { + status = pt_blk_sync_forward(decoder); + if (status < 0) + break; + + for (;;) { + struct pt_block block; + int errcode; + + status = handle_events(decoder, status); + if (status < 0) + break; + + status = pt_blk_next(decoder, &block, sizeof(block)); + + errcode = process_block(&block, iscache); + if (errcode < 0) + status = errcode; + + if (status < 0) + break; + } + + <handle error>(status); + } + + <handle error>(status); + + return status; + } +~~~ + + +## Parallel Decode + +Intel PT splits naturally into self-contained PSB segments that can be decoded +independently. Use the packet or query decoder to search for PSB's using +repeated calls to `pt_pkt_sync_forward()` and `pt_pkt_get_sync_offset()` (or +`pt_qry_sync_forward()` and `pt_qry_get_sync_offset()`). The following example +shows this using the query decoder, which will already give the IP needed in +the next step. + +~~~{.c} + struct pt_query_decoder *decoder; + uint64_t offset, ip; + int status, errcode; + + for (;;) { + status = pt_qry_sync_forward(decoder, &ip); + if (status < 0) + break; + + errcode = pt_qry_get_sync_offset(decoder, &offset); + if (errcode < 0) + <handle error>(errcode); + + <split trace>(offset, ip, status); + } +~~~ + +The individual trace segments can then be decoded using the query, instruction +flow, or block decoder as shown above in the previous examples. + +When stitching decoded trace segments together, a sequence of linear (in the +sense that it can be decoded without Intel PT) code has to be filled in. Use +the `pts_eos` status indication to stop decoding early enough. Then proceed +until the IP at the start of the succeeding trace segment is reached. When +using the instruction flow decoder, `pt_insn_next()` may be used for that as +shown in the following example: + +~~~{.c} + struct pt_insn_decoder *decoder; + struct pt_insn insn; + int status; + + for (;;) { + status = pt_insn_next(decoder, &insn, sizeof(insn)); + if (status < 0) + <handle error>(status); + + if (status & pts_eos) + break; + + <process instruction>(&insn); + } + + while (insn.ip != <next segment's start IP>) { + <process instruction>(&insn); + + status = pt_insn_next(decoder, &insn, sizeof(insn)); + if (status < 0) + <handle error>(status); + } +~~~ + + +## Threading + +The decoder library API is not thread-safe. Different threads may allocate and +use different decoder objects at the same time. Different decoders must not use +the same image object. Use `pt_image_copy()` to give each decoder its own copy +of a shared master image. diff --git a/doc/howto_pttc.md b/doc/howto_pttc.md new file mode 100644 index 000000000000..240a73121933 --- /dev/null +++ b/doc/howto_pttc.md @@ -0,0 +1,492 @@ +Testing the Intel(R) Processor Trace (Intel PT) Decoder Library and Samples {#pttc} +=========================================================================== + +<!--- + ! Copyright (c) 2013-2019, Intel Corporation + ! + ! Redistribution and use in source and binary forms, with or without + ! modification, are permitted provided that the following conditions are met: + ! + ! * Redistributions of source code must retain the above copyright notice, + ! this list of conditions and the following disclaimer. + ! * Redistributions in binary form must reproduce the above copyright notice, + ! this list of conditions and the following disclaimer in the documentation + ! and/or other materials provided with the distribution. + ! * Neither the name of Intel Corporation nor the names of its contributors + ! may be used to endorse or promote products derived from this software + ! without specific prior written permission. + ! + ! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + ! AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + ! IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ! ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + ! LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + ! CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + ! SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + ! INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + ! CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ! ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + ! POSSIBILITY OF SUCH DAMAGE. + !--> + +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. + + +#### raw + + @pt raw-8(value) + @pt raw-16(value) + @pt raw-32(value) + @pt raw-64(value) + +Writes a raw unsigned 8, 16, 32, or 64 bit value. + + +#### 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. diff --git a/doc/man/CMakeLists.txt b/doc/man/CMakeLists.txt new file mode 100644 index 000000000000..101581051959 --- /dev/null +++ b/doc/man/CMakeLists.txt @@ -0,0 +1,147 @@ +# Copyright (c) 2015-2019, Intel Corporation +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# * Redistributions of source code must retain the above copyright notice, +# this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright notice, +# this list of conditions and the following disclaimer in the documentation +# and/or other materials provided with the distribution. +# * Neither the name of Intel Corporation nor the names of its contributors +# may be used to endorse or promote products derived from this software +# without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. + +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}) diff --git a/doc/man/pt_alloc_encoder.3.md b/doc/man/pt_alloc_encoder.3.md new file mode 100644 index 000000000000..f5e8e0ea5ae8 --- /dev/null +++ b/doc/man/pt_alloc_encoder.3.md @@ -0,0 +1,96 @@ +% PT_ALLOC_ENCODER(3) + +<!--- + ! Copyright (c) 2015-2019, Intel Corporation + ! + ! Redistribution and use in source and binary forms, with or without + ! modification, are permitted provided that the following conditions are met: + ! + ! * Redistributions of source code must retain the above copyright notice, + ! this list of conditions and the following disclaimer. + ! * Redistributions in binary form must reproduce the above copyright notice, + ! this list of conditions and the following disclaimer in the documentation + ! and/or other materials provided with the distribution. + ! * Neither the name of Intel Corporation nor the names of its contributors + ! may be used to endorse or promote products derived from this software + ! without specific prior written permission. + ! + ! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + ! AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + ! IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ! ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + ! LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + ! CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + ! SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + ! INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + ! CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ! ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + ! POSSIBILITY OF SUCH DAMAGE. + !--> + +# 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) diff --git a/doc/man/pt_blk_alloc_decoder.3.md b/doc/man/pt_blk_alloc_decoder.3.md new file mode 100644 index 000000000000..aa6db3c536e6 --- /dev/null +++ b/doc/man/pt_blk_alloc_decoder.3.md @@ -0,0 +1,98 @@ +% PT_BLK_ALLOC_DECODER(3) + +<!--- + ! Copyright (c) 2016-2019, Intel Corporation + ! + ! Redistribution and use in source and binary forms, with or without + ! modification, are permitted provided that the following conditions are met: + ! + ! * Redistributions of source code must retain the above copyright notice, + ! this list of conditions and the following disclaimer. + ! * Redistributions in binary form must reproduce the above copyright notice, + ! this list of conditions and the following disclaimer in the documentation + ! and/or other materials provided with the distribution. + ! * Neither the name of Intel Corporation nor the names of its contributors + ! may be used to endorse or promote products derived from this software + ! without specific prior written permission. + ! + ! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + ! AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + ! IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ! ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + ! LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + ! CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + ! SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + ! INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + ! CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ! ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + ! POSSIBILITY OF SUCH DAMAGE. + !--> + +# 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) diff --git a/doc/man/pt_blk_get_offset.3.md b/doc/man/pt_blk_get_offset.3.md new file mode 100644 index 000000000000..da705c97fd31 --- /dev/null +++ b/doc/man/pt_blk_get_offset.3.md @@ -0,0 +1,82 @@ +% PT_BLK_GET_OFFSET(3) + +<!--- + ! Copyright (c) 2016-2019, Intel Corporation + ! + ! Redistribution and use in source and binary forms, with or without + ! modification, are permitted provided that the following conditions are met: + ! + ! * Redistributions of source code must retain the above copyright notice, + ! this list of conditions and the following disclaimer. + ! * Redistributions in binary form must reproduce the above copyright notice, + ! this list of conditions and the following disclaimer in the documentation + ! and/or other materials provided with the distribution. + ! * Neither the name of Intel Corporation nor the names of its contributors + ! may be used to endorse or promote products derived from this software + ! without specific prior written permission. + ! + ! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + ! AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + ! IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ! ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + ! LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + ! CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + ! SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + ! INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + ! CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ! ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + ! POSSIBILITY OF SUCH DAMAGE. + !--> + +# 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) diff --git a/doc/man/pt_blk_next.3.md b/doc/man/pt_blk_next.3.md new file mode 100644 index 000000000000..ff576ef01d3e --- /dev/null +++ b/doc/man/pt_blk_next.3.md @@ -0,0 +1,285 @@ +% PT_BLK_NEXT(3) + +<!--- + ! Copyright (c) 2016-2019, Intel Corporation + ! + ! Redistribution and use in source and binary forms, with or without + ! modification, are permitted provided that the following conditions are met: + ! + ! * Redistributions of source code must retain the above copyright notice, + ! this list of conditions and the following disclaimer. + ! * Redistributions in binary form must reproduce the above copyright notice, + ! this list of conditions and the following disclaimer in the documentation + ! and/or other materials provided with the distribution. + ! * Neither the name of Intel Corporation nor the names of its contributors + ! may be used to endorse or promote products derived from this software + ! without specific prior written permission. + ! + ! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + ! AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + ! IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ! ARE DISCLAIMED. IN NO 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) diff --git a/doc/man/pt_blk_sync_forward.3.md b/doc/man/pt_blk_sync_forward.3.md new file mode 100644 index 000000000000..e5602f6545b9 --- /dev/null +++ b/doc/man/pt_blk_sync_forward.3.md @@ -0,0 +1,152 @@ +% PT_BLK_SYNC_FORWARD(3) + +<!--- + ! Copyright (c) 2016-2019, Intel Corporation + ! + ! Redistribution and use in source and binary forms, with or without + ! modification, are permitted provided that the following conditions are met: + ! + ! * Redistributions of source code must retain the above copyright notice, + ! this list of conditions and the following disclaimer. + ! * Redistributions in binary form must reproduce the above copyright notice, + ! this list of conditions and the following disclaimer in the documentation + ! and/or other materials provided with the distribution. + ! * Neither the name of Intel Corporation nor the names of its contributors + ! may be used to endorse or promote products derived from this software + ! without specific prior written permission. + ! + ! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + ! AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + ! IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ! ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + ! LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + ! CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + ! SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + ! INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + ! CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ! ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + ! POSSIBILITY OF SUCH DAMAGE. + !--> + +# 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) diff --git a/doc/man/pt_config.3.md b/doc/man/pt_config.3.md new file mode 100644 index 000000000000..94b1ca329833 --- /dev/null +++ b/doc/man/pt_config.3.md @@ -0,0 +1,359 @@ +% PT_CONFIG(3) + +<!--- + ! Copyright (c) 2015-2019, Intel Corporation + ! + ! Redistribution and use in source and binary forms, with or without + ! modification, are permitted provided that the following conditions are met: + ! + ! * Redistributions of source code must retain the above copyright notice, + ! this list of conditions and the following disclaimer. + ! * Redistributions in binary form must reproduce the above copyright notice, + ! this list of conditions and the following disclaimer in the documentation + ! and/or other materials provided with the distribution. + ! * Neither the name of Intel Corporation nor the names of its contributors + ! may be used to endorse or promote products derived from this software + ! without specific prior written permission. + ! + ! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + ! AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + ! IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ! ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + ! LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + ! CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + ! SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + ! INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + ! CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ! ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + ! POSSIBILITY OF SUCH DAMAGE. + !--> + +# 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) diff --git a/doc/man/pt_enc_get_config.3.md b/doc/man/pt_enc_get_config.3.md new file mode 100644 index 000000000000..fcba6e397ba3 --- /dev/null +++ b/doc/man/pt_enc_get_config.3.md @@ -0,0 +1,77 @@ +% PT_ENC_GET_CONFIG(3) + +<!--- + ! Copyright (c) 2015-2019, Intel Corporation + ! + ! Redistribution and use in source and binary forms, with or without + ! modification, are permitted provided that the following conditions are met: + ! + ! * Redistributions of source code must retain the above copyright notice, + ! this list of conditions and the following disclaimer. + ! * Redistributions in binary form must reproduce the above copyright notice, + ! this list of conditions and the following disclaimer in the documentation + ! and/or other materials provided with the distribution. + ! * Neither the name of Intel Corporation nor the names of its contributors + ! may be used to endorse or promote products derived from this software + ! without specific prior written permission. + ! + ! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + ! AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + ! IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ! ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + ! LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + ! CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + ! SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + ! INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + ! CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ! ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + ! POSSIBILITY OF SUCH DAMAGE. + !--> + +# 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) diff --git a/doc/man/pt_enc_get_offset.3.md b/doc/man/pt_enc_get_offset.3.md new file mode 100644 index 000000000000..528a5e1f451d --- /dev/null +++ b/doc/man/pt_enc_get_offset.3.md @@ -0,0 +1,77 @@ +% PT_ENC_GET_OFFSET(3) + +<!--- + ! Copyright (c) 2015-2019, Intel Corporation + ! + ! Redistribution and use in source and binary forms, with or without + ! modification, are permitted provided that the following conditions are met: + ! + ! * Redistributions of source code must retain the above copyright notice, + ! this list of conditions and the following disclaimer. + ! * Redistributions in binary form must reproduce the above copyright notice, + ! this list of conditions and the following disclaimer in the documentation + ! and/or other materials provided with the distribution. + ! * Neither the name of Intel Corporation nor the names of its contributors + ! may be used to endorse or promote products derived from this software + ! without specific prior written permission. + ! + ! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + ! AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + ! IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ! ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + ! LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + ! CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + ! SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + ! INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + ! CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ! ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + ! POSSIBILITY OF SUCH DAMAGE. + !--> + +# 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) diff --git a/doc/man/pt_image_add_file.3.md b/doc/man/pt_image_add_file.3.md new file mode 100644 index 000000000000..9c644b632a76 --- /dev/null +++ b/doc/man/pt_image_add_file.3.md @@ -0,0 +1,135 @@ +% PT_IMAGE_ADD_FILE(3) + +<!--- + ! Copyright (c) 2015-2019, Intel Corporation + ! + ! Redistribution and use in source and binary forms, with or without + ! modification, are permitted provided that the following conditions are met: + ! + ! * Redistributions of source code must retain the above copyright notice, + ! this list of conditions and the following disclaimer. + ! * Redistributions in binary form must reproduce the above copyright notice, + ! this list of conditions and the following disclaimer in the documentation + ! and/or other materials provided with the distribution. + ! * Neither the name of Intel Corporation nor the names of its contributors + ! may be used to endorse or promote products derived from this software + ! without specific prior written permission. + ! + ! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + ! AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + ! IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ! ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + ! LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + ! CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + ! SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + ! INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + ! CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ! ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + ! POSSIBILITY OF SUCH DAMAGE. + !--> + +# 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) diff --git a/doc/man/pt_image_alloc.3.md b/doc/man/pt_image_alloc.3.md new file mode 100644 index 000000000000..ba8b243d8f70 --- /dev/null +++ b/doc/man/pt_image_alloc.3.md @@ -0,0 +1,99 @@ +% PT_IMAGE_ALLOC(3) + +<!--- + ! Copyright (c) 2015-2019, Intel Corporation + ! + ! Redistribution and use in source and binary forms, with or without + ! modification, are permitted provided that the following conditions are met: + ! + ! * Redistributions of source code must retain the above copyright notice, + ! this list of conditions and the following disclaimer. + ! * Redistributions in binary form must reproduce the above copyright notice, + ! this list of conditions and the following disclaimer in the documentation + ! and/or other materials provided with the distribution. + ! * Neither the name of Intel Corporation nor the names of its contributors + ! may be used to endorse or promote products derived from this software + ! without specific prior written permission. + ! + ! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + ! AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + ! IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ! ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + ! LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + ! CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + ! SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + ! INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + ! CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ! ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + ! POSSIBILITY OF SUCH DAMAGE. + !--> + +# 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) diff --git a/doc/man/pt_image_remove_by_filename.3.md b/doc/man/pt_image_remove_by_filename.3.md new file mode 100644 index 000000000000..3561c5d831d8 --- /dev/null +++ b/doc/man/pt_image_remove_by_filename.3.md @@ -0,0 +1,150 @@ +% PT_IMAGE_REMOVE_BY_FILENAME(3) + +<!--- + ! Copyright (c) 2015-2019, Intel Corporation + ! + ! Redistribution and use in source and binary forms, with or without + ! modification, are permitted provided that the following conditions are met: + ! + ! * Redistributions of source code must retain the above copyright notice, + ! this list of conditions and the following disclaimer. + ! * Redistributions in binary form must reproduce the above copyright notice, + ! this list of conditions and the following disclaimer in the documentation + ! and/or other materials provided with the distribution. + ! * Neither the name of Intel Corporation nor the names of its contributors + ! may be used to endorse or promote products derived from this software + ! without specific prior written permission. + ! + ! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + ! AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + ! IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ! ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + ! LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + ! CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + ! SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + ! INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + ! CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ! ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + ! POSSIBILITY OF SUCH DAMAGE. + !--> + +# 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) diff --git a/doc/man/pt_image_set_callback.3.md b/doc/man/pt_image_set_callback.3.md new file mode 100644 index 000000000000..084979a29c62 --- /dev/null +++ b/doc/man/pt_image_set_callback.3.md @@ -0,0 +1,103 @@ +% PT_IMAGE_SET_CALLBACK(3) + +<!--- + ! Copyright (c) 2015-2019, Intel Corporation + ! + ! Redistribution and use in source and binary forms, with or without + ! modification, are permitted provided that the following conditions are met: + ! + ! * Redistributions of source code must retain the above copyright notice, + ! this list of conditions and the following disclaimer. + ! * Redistributions in binary form must reproduce the above copyright notice, + ! this list of conditions and the following disclaimer in the documentation + ! and/or other materials provided with the distribution. + ! * Neither the name of Intel Corporation nor the names of its contributors + ! may be used to endorse or promote products derived from this software + ! without specific prior written permission. + ! + ! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + ! AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + ! IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ! ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + ! LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + ! CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + ! SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + ! INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + ! CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ! ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + ! POSSIBILITY OF SUCH DAMAGE. + !--> + +# 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) diff --git a/doc/man/pt_insn_alloc_decoder.3.md b/doc/man/pt_insn_alloc_decoder.3.md new file mode 100644 index 000000000000..c9a8efba5813 --- /dev/null +++ b/doc/man/pt_insn_alloc_decoder.3.md @@ -0,0 +1,101 @@ +% PT_INSN_ALLOC_DECODER(3) + +<!--- + ! Copyright (c) 2015-2019, Intel Corporation + ! + ! Redistribution and use in source and binary forms, with or without + ! modification, are permitted provided that the following conditions are met: + ! + ! * Redistributions of source code must retain the above copyright notice, + ! this list of conditions and the following disclaimer. + ! * Redistributions in binary form must reproduce the above copyright notice, + ! this list of conditions and the following disclaimer in the documentation + ! and/or other materials provided with the distribution. + ! * Neither the name of Intel Corporation nor the names of its contributors + ! may be used to endorse or promote products derived from this software + ! without specific prior written permission. + ! + ! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + ! AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + ! IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ! ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + ! LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + ! CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + ! SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + ! INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + ! CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ! ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + ! POSSIBILITY OF SUCH DAMAGE. + !--> + +# 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) diff --git a/doc/man/pt_insn_get_image.3.md b/doc/man/pt_insn_get_image.3.md new file mode 100644 index 000000000000..b5a503ea4d2b --- /dev/null +++ b/doc/man/pt_insn_get_image.3.md @@ -0,0 +1,93 @@ +% PT_INSN_GET_IMAGE(3) + +<!--- + ! Copyright (c) 2015-2019, Intel Corporation + ! + ! Redistribution and use in source and binary forms, with or without + ! modification, are permitted provided that the following conditions are met: + ! + ! * Redistributions of source code must retain the above copyright notice, + ! this list of conditions and the following disclaimer. + ! * Redistributions in binary form must reproduce the above copyright notice, + ! this list of conditions and the following disclaimer in the documentation + ! and/or other materials provided with the distribution. + ! * Neither the name of Intel Corporation nor the names of its contributors + ! may be used to endorse or promote products derived from this software + ! without specific prior written permission. + ! + ! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + ! AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + ! IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ! ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + ! LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + ! CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + ! SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + ! INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + ! CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ! ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + ! POSSIBILITY OF SUCH DAMAGE. + !--> + +# 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) diff --git a/doc/man/pt_insn_get_offset.3.md b/doc/man/pt_insn_get_offset.3.md new file mode 100644 index 000000000000..31943f74fdf0 --- /dev/null +++ b/doc/man/pt_insn_get_offset.3.md @@ -0,0 +1,82 @@ +% PT_INSN_GET_OFFSET(3) + +<!--- + ! Copyright (c) 2015-2019, Intel Corporation + ! + ! Redistribution and use in source and binary forms, with or without + ! modification, are permitted provided that the following conditions are met: + ! + ! * Redistributions of source code must retain the above copyright notice, + ! this list of conditions and the following disclaimer. + ! * Redistributions in binary form must reproduce the above copyright notice, + ! this list of conditions and the following disclaimer in the documentation + ! and/or other materials provided with the distribution. + ! * Neither the name of Intel Corporation nor the names of its contributors + ! may be used to endorse or promote products derived from this software + ! without specific prior written permission. + ! + ! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + ! AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + ! IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ! ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + ! LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + ! CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + ! SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + ! INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + ! CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ! ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + ! POSSIBILITY OF SUCH DAMAGE. + !--> + +# 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) diff --git a/doc/man/pt_insn_next.3.md b/doc/man/pt_insn_next.3.md new file mode 100644 index 000000000000..ec57df3f7012 --- /dev/null +++ b/doc/man/pt_insn_next.3.md @@ -0,0 +1,264 @@ +% PT_INSN_NEXT(3) + +<!--- + ! Copyright (c) 2015-2019, Intel Corporation + ! + ! Redistribution and use in source and binary forms, with or without + ! modification, are permitted provided that the following conditions are met: + ! + ! * Redistributions of source code must retain the above copyright notice, + ! this list of conditions and the following disclaimer. + ! * Redistributions in binary form must reproduce the above copyright notice, + ! this list of conditions and the following disclaimer in the documentation + ! and/or other materials provided with the distribution. + ! * Neither the name of Intel Corporation nor the names of its contributors + ! may be used to endorse or promote products derived from this software + ! without specific prior written permission. + ! + ! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + ! AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + ! IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ! ARE DISCLAIMED. IN NO 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) diff --git a/doc/man/pt_insn_sync_forward.3.md b/doc/man/pt_insn_sync_forward.3.md new file mode 100644 index 000000000000..30fb338ac976 --- /dev/null +++ b/doc/man/pt_insn_sync_forward.3.md @@ -0,0 +1,153 @@ +% PT_INSN_SYNC_FORWARD(3) + +<!--- + ! Copyright (c) 2015-2019, Intel Corporation + ! + ! Redistribution and use in source and binary forms, with or without + ! modification, are permitted provided that the following conditions are met: + ! + ! * Redistributions of source code must retain the above copyright notice, + ! this list of conditions and the following disclaimer. + ! * Redistributions in binary form must reproduce the above copyright notice, + ! this list of conditions and the following disclaimer in the documentation + ! and/or other materials provided with the distribution. + ! * Neither the name of Intel Corporation nor the names of its contributors + ! may be used to endorse or promote products derived from this software + ! without specific prior written permission. + ! + ! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + ! AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + ! IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ! ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + ! LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + ! CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + ! SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + ! INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + ! CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ! ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + ! POSSIBILITY OF SUCH DAMAGE. + !--> + +# 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) diff --git a/doc/man/pt_iscache_add_file.3.md b/doc/man/pt_iscache_add_file.3.md new file mode 100644 index 000000000000..cf959299182e --- /dev/null +++ b/doc/man/pt_iscache_add_file.3.md @@ -0,0 +1,98 @@ +% PT_ISCACHE_ADD_FILE(3) + +<!--- + ! Copyright (c) 2015-2019, Intel Corporation + ! + ! Redistribution and use in source and binary forms, with or without + ! modification, are permitted provided that the following conditions are met: + ! + ! * Redistributions of source code must retain the above copyright notice, + ! this list of conditions and the following disclaimer. + ! * Redistributions in binary form must reproduce the above copyright notice, + ! this list of conditions and the following disclaimer in the documentation + ! and/or other materials provided with the distribution. + ! * Neither the name of Intel Corporation nor the names of its contributors + ! may be used to endorse or promote products derived from this software + ! without specific prior written permission. + ! + ! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + ! AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + ! IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ! ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + ! LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + ! CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + ! SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + ! INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + ! CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ! ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + ! POSSIBILITY OF SUCH DAMAGE. + !--> + +# 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) diff --git a/doc/man/pt_iscache_alloc.3.md b/doc/man/pt_iscache_alloc.3.md new file mode 100644 index 000000000000..47f9edfe453c --- /dev/null +++ b/doc/man/pt_iscache_alloc.3.md @@ -0,0 +1,102 @@ +% PT_ISCACHE_ALLOC(3) + +<!--- + ! Copyright (c) 2015-2019, Intel Corporation + ! + ! Redistribution and use in source and binary forms, with or without + ! modification, are permitted provided that the following conditions are met: + ! + ! * Redistributions of source code must retain the above copyright notice, + ! this list of conditions and the following disclaimer. + ! * Redistributions in binary form must reproduce the above copyright notice, + ! this list of conditions and the following disclaimer in the documentation + ! and/or other materials provided with the distribution. + ! * Neither the name of Intel Corporation nor the names of its contributors + ! may be used to endorse or promote products derived from this software + ! without specific prior written permission. + ! + ! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + ! AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + ! IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ! ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + ! LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + ! CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + ! SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + ! INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + ! CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ! ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + ! POSSIBILITY OF SUCH DAMAGE. + !--> + +# 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) diff --git a/doc/man/pt_iscache_read.3.md b/doc/man/pt_iscache_read.3.md new file mode 100644 index 000000000000..0e16b33d6050 --- /dev/null +++ b/doc/man/pt_iscache_read.3.md @@ -0,0 +1,89 @@ +% PT_ISCACHE_READ(3) + +<!--- + ! Copyright (c) 2015-2019, Intel Corporation + ! + ! Redistribution and use in source and binary forms, with or without + ! modification, are permitted provided that the following conditions are met: + ! + ! * Redistributions of source code must retain the above copyright notice, + ! this list of conditions and the following disclaimer. + ! * Redistributions in binary form must reproduce the above copyright notice, + ! this list of conditions and the following disclaimer in the documentation + ! and/or other materials provided with the distribution. + ! * Neither the name of Intel Corporation nor the names of its contributors + ! may be used to endorse or promote products derived from this software + ! without specific prior written permission. + ! + ! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + ! AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + ! IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ! ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + ! LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + ! CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + ! SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + ! INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + ! CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ! ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + ! POSSIBILITY OF SUCH DAMAGE. + !--> + +# 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) diff --git a/doc/man/pt_iscache_set_limit.3.md b/doc/man/pt_iscache_set_limit.3.md new file mode 100644 index 000000000000..c87eb942a6fa --- /dev/null +++ b/doc/man/pt_iscache_set_limit.3.md @@ -0,0 +1,73 @@ +% PT_ISCACHE_SET_LIMIT(3) + +<!--- + ! Copyright (c) 2017-2019, Intel Corporation + ! + ! Redistribution and use in source and binary forms, with or without + ! modification, are permitted provided that the following conditions are met: + ! + ! * Redistributions of source code must retain the above copyright notice, + ! this list of conditions and the following disclaimer. + ! * Redistributions in binary form must reproduce the above copyright notice, + ! this list of conditions and the following disclaimer in the documentation + ! and/or other materials provided with the distribution. + ! * Neither the name of Intel Corporation nor the names of its contributors + ! may be used to endorse or promote products derived from this software + ! without specific prior written permission. + ! + ! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + ! AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + ! IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ! ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + ! LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + ! CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + ! SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + ! INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + ! CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ! ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + ! POSSIBILITY OF SUCH DAMAGE. + !--> + +# 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) diff --git a/doc/man/pt_library_version.3.md b/doc/man/pt_library_version.3.md new file mode 100644 index 000000000000..daeaf0b3e086 --- /dev/null +++ b/doc/man/pt_library_version.3.md @@ -0,0 +1,72 @@ +% PT_LIBRARY_VERSION(3) + +<!--- + ! Copyright (c) 2015-2019, Intel Corporation + ! + ! Redistribution and use in source and binary forms, with or without + ! modification, are permitted provided that the following conditions are met: + ! + ! * Redistributions of source code must retain the above copyright notice, + ! this list of conditions and the following disclaimer. + ! * Redistributions in binary form must reproduce the above copyright notice, + ! this list of conditions and the following disclaimer in the documentation + ! and/or other materials provided with the distribution. + ! * Neither the name of Intel Corporation nor the names of its contributors + ! may be used to endorse or promote products derived from this software + ! without specific prior written permission. + ! + ! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + ! AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + ! IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ! ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + ! LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + ! CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + ! SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + ! INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + ! CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ! ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + ! POSSIBILITY OF SUCH DAMAGE. + !--> + +# 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; + + /** Patch level. */ + uint16_t patch; + + /** Build number. */ + uint32_t build; + + /** Version extension. */ + const char *ext; +}; +~~~ diff --git a/doc/man/pt_packet.3.md b/doc/man/pt_packet.3.md new file mode 100644 index 000000000000..c8d1c806da1b --- /dev/null +++ b/doc/man/pt_packet.3.md @@ -0,0 +1,197 @@ +% PT_PACKET(3) + +<!--- + ! Copyright (c) 2015-2019, Intel Corporation + ! + ! Redistribution and use in source and binary forms, with or without + ! modification, are permitted provided that the following conditions are met: + ! + ! * Redistributions of source code must retain the above copyright notice, + ! this list of conditions and the following disclaimer. + ! * Redistributions in binary form must reproduce the above copyright notice, + ! this list of conditions and the following disclaimer in the documentation + ! and/or other materials provided with the distribution. + ! * Neither the name of Intel Corporation nor the names of its contributors + ! may be used to endorse or promote products derived from this software + ! without specific prior written permission. + ! + ! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + ! AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + ! IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ! ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + ! LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + ! CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + ! SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + ! INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + ! CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ! ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + ! POSSIBILITY OF SUCH DAMAGE. + !--> + +# 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) diff --git a/doc/man/pt_pkt_alloc_decoder.3.md b/doc/man/pt_pkt_alloc_decoder.3.md new file mode 100644 index 000000000000..f7bc28a835bd --- /dev/null +++ b/doc/man/pt_pkt_alloc_decoder.3.md @@ -0,0 +1,98 @@ +% PT_PKT_ALLOC_DECODER(3) + +<!--- + ! Copyright (c) 2015-2019, Intel Corporation + ! + ! Redistribution and use in source and binary forms, with or without + ! modification, are permitted provided that the following conditions are met: + ! + ! * Redistributions of source code must retain the above copyright notice, + ! this list of conditions and the following disclaimer. + ! * Redistributions in binary form must reproduce the above copyright notice, + ! this list of conditions and the following disclaimer in the documentation + ! and/or other materials provided with the distribution. + ! * Neither the name of Intel Corporation nor the names of its contributors + ! may be used to endorse or promote products derived from this software + ! without specific prior written permission. + ! + ! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + ! AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + ! IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ! ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + ! LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + ! CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + ! SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + ! INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + ! CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ! ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + ! POSSIBILITY OF SUCH DAMAGE. + !--> + +# 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) diff --git a/doc/man/pt_pkt_get_offset.3.md b/doc/man/pt_pkt_get_offset.3.md new file mode 100644 index 000000000000..fb723d236f59 --- /dev/null +++ b/doc/man/pt_pkt_get_offset.3.md @@ -0,0 +1,81 @@ +% PT_PKT_GET_OFFSET(3) + +<!--- + ! Copyright (c) 2015-2019, Intel Corporation + ! + ! Redistribution and use in source and binary forms, with or without + ! modification, are permitted provided that the following conditions are met: + ! + ! * Redistributions of source code must retain the above copyright notice, + ! this list of conditions and the following disclaimer. + ! * Redistributions in binary form must reproduce the above copyright notice, + ! this list of conditions and the following disclaimer in the documentation + ! and/or other materials provided with the distribution. + ! * Neither the name of Intel Corporation nor the names of its contributors + ! may be used to endorse or promote products derived from this software + ! without specific prior written permission. + ! + ! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + ! AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + ! IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ! ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + ! LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + ! CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + ! SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + ! INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + ! CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ! ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + ! POSSIBILITY OF SUCH DAMAGE. + !--> + +# 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) diff --git a/doc/man/pt_pkt_sync_forward.3.md b/doc/man/pt_pkt_sync_forward.3.md new file mode 100644 index 000000000000..cf367b863bac --- /dev/null +++ b/doc/man/pt_pkt_sync_forward.3.md @@ -0,0 +1,115 @@ +% PT_PKT_SYNC_FORWARD(3) + +<!--- + ! Copyright (c) 2015-2019, Intel Corporation + ! + ! Redistribution and use in source and binary forms, with or without + ! modification, are permitted provided that the following conditions are met: + ! + ! * Redistributions of source code must retain the above copyright notice, + ! this list of conditions and the following disclaimer. + ! * Redistributions in binary form must reproduce the above copyright notice, + ! this list of conditions and the following disclaimer in the documentation + ! and/or other materials provided with the distribution. + ! * Neither the name of Intel Corporation nor the names of its contributors + ! may be used to endorse or promote products derived from this software + ! without specific prior written permission. + ! + ! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + ! AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + ! IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ! ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + ! LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + ! CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + ! SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + ! INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + ! CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ! ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + ! POSSIBILITY OF SUCH DAMAGE. + !--> + +# 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) diff --git a/doc/man/pt_qry_alloc_decoder.3.md b/doc/man/pt_qry_alloc_decoder.3.md new file mode 100644 index 000000000000..1ec6b16153f5 --- /dev/null +++ b/doc/man/pt_qry_alloc_decoder.3.md @@ -0,0 +1,113 @@ +% PT_QRY_ALLOC_DECODER(3) + +<!--- + ! Copyright (c) 2015-2019, Intel Corporation + ! + ! Redistribution and use in source and binary forms, with or without + ! modification, are permitted provided that the following conditions are met: + ! + ! * Redistributions of source code must retain the above copyright notice, + ! this list of conditions and the following disclaimer. + ! * Redistributions in binary form must reproduce the above copyright notice, + ! this list of conditions and the following disclaimer in the documentation + ! and/or other materials provided with the distribution. + ! * Neither the name of Intel Corporation nor the names of its contributors + ! may be used to endorse or promote products derived from this software + ! without specific prior written permission. + ! + ! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + ! AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + ! IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ! ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + ! LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + ! CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + ! SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + ! INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + ! CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ! ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + ! POSSIBILITY OF SUCH DAMAGE. + !--> + +# 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) diff --git a/doc/man/pt_qry_cond_branch.3.md b/doc/man/pt_qry_cond_branch.3.md new file mode 100644 index 000000000000..b1974761a328 --- /dev/null +++ b/doc/man/pt_qry_cond_branch.3.md @@ -0,0 +1,152 @@ +% PT_QRY_COND_BRANCH(3) + +<!--- + ! Copyright (c) 2015-2019, Intel Corporation + ! + ! Redistribution and use in source and binary forms, with or without + ! modification, are permitted provided that the following conditions are met: + ! + ! * Redistributions of source code must retain the above copyright notice, + ! this list of conditions and the following disclaimer. + ! * Redistributions in binary form must reproduce the above copyright notice, + ! this list of conditions and the following disclaimer in the documentation + ! and/or other materials provided with the distribution. + ! * Neither the name of Intel Corporation nor the names of its contributors + ! may be used to endorse or promote products derived from this software + ! without specific prior written permission. + ! + ! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + ! AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + ! IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ! ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + ! LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + ! CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + ! SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + ! INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + ! CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ! ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + ! POSSIBILITY OF SUCH DAMAGE. + !--> + +# 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) diff --git a/doc/man/pt_qry_event.3.md b/doc/man/pt_qry_event.3.md new file mode 100644 index 000000000000..90e3d0e1cd32 --- /dev/null +++ b/doc/man/pt_qry_event.3.md @@ -0,0 +1,291 @@ +% PT_QRY_EVENT(3) + +<!--- + ! Copyright (c) 2015-2019, Intel Corporation + ! + ! Redistribution and use in source and binary forms, with or without + ! modification, are permitted provided that the following conditions are met: + ! + ! * Redistributions of source code must retain the above copyright notice, + ! this list of conditions and the following disclaimer. + ! * Redistributions in binary form must reproduce the above copyright notice, + ! this list of conditions and the following disclaimer in the documentation + ! and/or other materials provided with the distribution. + ! * Neither the name of Intel Corporation nor the names of its contributors + ! may be used to endorse or promote products derived from this software + ! without specific prior written permission. + ! + ! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + ! AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + ! IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ! ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + ! LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + ! CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + ! SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + ! INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + ! CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ! ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + ! POSSIBILITY OF SUCH DAMAGE. + !--> + +# 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) diff --git a/doc/man/pt_qry_get_offset.3.md b/doc/man/pt_qry_get_offset.3.md new file mode 100644 index 000000000000..8a348c3c1f29 --- /dev/null +++ b/doc/man/pt_qry_get_offset.3.md @@ -0,0 +1,83 @@ +% PT_QRY_GET_OFFSET(3) + +<!--- + ! Copyright (c) 2015-2019, Intel Corporation + ! + ! Redistribution and use in source and binary forms, with or without + ! modification, are permitted provided that the following conditions are met: + ! + ! * Redistributions of source code must retain the above copyright notice, + ! this list of conditions and the following disclaimer. + ! * Redistributions in binary form must reproduce the above copyright notice, + ! this list of conditions and the following disclaimer in the documentation + ! and/or other materials provided with the distribution. + ! * Neither the name of Intel Corporation nor the names of its contributors + ! may be used to endorse or promote products derived from this software + ! without specific prior written permission. + ! + ! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + ! AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + ! IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ! ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + ! LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + ! CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + ! SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + ! INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + ! CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ! ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + ! POSSIBILITY OF SUCH DAMAGE. + !--> + +# 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) diff --git a/doc/man/pt_qry_sync_forward.3.md b/doc/man/pt_qry_sync_forward.3.md new file mode 100644 index 000000000000..b69acbd3831f --- /dev/null +++ b/doc/man/pt_qry_sync_forward.3.md @@ -0,0 +1,152 @@ +% PT_QRY_SYNC_FORWARD(3) + +<!--- + ! Copyright (c) 2015-2019, Intel Corporation + ! + ! Redistribution and use in source and binary forms, with or without + ! modification, are permitted provided that the following conditions are met: + ! + ! * Redistributions of source code must retain the above copyright notice, + ! this list of conditions and the following disclaimer. + ! * Redistributions in binary form must reproduce the above copyright notice, + ! this list of conditions and the following disclaimer in the documentation + ! and/or other materials provided with the distribution. + ! * Neither the name of Intel Corporation nor the names of its contributors + ! may be used to endorse or promote products derived from this software + ! without specific prior written permission. + ! + ! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + ! AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + ! IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ! ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + ! LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + ! CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + ! SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + ! INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + ! CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ! ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + ! POSSIBILITY OF SUCH DAMAGE. + !--> + +# 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) diff --git a/doc/man/pt_qry_time.3.md b/doc/man/pt_qry_time.3.md new file mode 100644 index 000000000000..1dc8a4f691f9 --- /dev/null +++ b/doc/man/pt_qry_time.3.md @@ -0,0 +1,128 @@ +% PT_QRY_TIME(3) + +<!--- + ! Copyright (c) 2015-2019, Intel Corporation + ! + ! Redistribution and use in source and binary forms, with or without + ! modification, are permitted provided that the following conditions are met: + ! + ! * Redistributions of source code must retain the above copyright notice, + ! this list of conditions and the following disclaimer. + ! * Redistributions in binary form must reproduce the above copyright notice, + ! this list of conditions and the following disclaimer in the documentation + ! and/or other materials provided with the distribution. + ! * Neither the name of Intel Corporation nor the names of its contributors + ! may be used to endorse or promote products derived from this software + ! without specific prior written permission. + ! + ! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + ! AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + ! IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ! ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + ! LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + ! CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + ! SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + ! INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + ! CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ! ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + ! POSSIBILITY OF SUCH DAMAGE. + !--> + +# 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) |