PT_PACKET(3)
π PT_PACKET π (the pt_packet manual, section 3, bestie)
okay so bestie, pull up a chair π«Ά today we're decoding Intel(R) Processor Trace packets, and honestly? it's giving main character energy. three functions, one struct, and a whole lot of bytes that go brrr. let's get into it β¨
πΈ 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 β¨
so basically, pt_enc_next() takes your packet argument and encodes it as an Intel Processor Trace (Intel PT) packet, right at encoder's current position. when it works, it slides encoder's current position forward to the first byte after the encoded packet. slay π
pt_pkt_next() is the reverse vibe: it decodes the Intel PT packet sitting at decoder's current position into packet. on success, it moves decoder's current position to the first byte after the decoded packet. no cap. π₯
bestie, heads up: you are responsible for allocating and freeing thept_packetobject that thepacketargument points to. the library is not doing that for you, periodt. π
the size argument of pt_pkt_next() has to be set to sizeof(struct pt_packet). the function will provide at most size bytes of packet data. here's the tea: a newer decoder library might hand you packet types that aren't defined yet. those packets may be truncated. unknown packet types should be ignored. π
now, if the packet decoder doesn't know the packet opcode at decoder's current position, and decoder's configuration contains a packet decode callback function, then pt_pkt_next() will call that callback function to decode the unknown packet. on success, a ppt_unknown packet type is provided, carrying the info the decode callback function gave you. π§
an Intel PT packet is described by the pt_packet structure, which is declared as:
/** 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, iykyk π
π RETURN VALUE π
pt_enc_next()returns the number of bytes written on success, or a negativept_error_codeenumeration constant if something goes wrong πpt_pkt_next()returns the number of bytes consumed on success, or a negativept_error_codeenumeration constant if something goes wrong π
π¦ ERRORS π¦
pte_invalidβ the encoder/decoder orpacketargument isNULL, or thesizeargument is zero (that second one ispt_pkt_next()only). literally just, no. πpte_nosyncβdecoderhas not been synchronized onto the trace stream (pt_pkt_next()only). go usept_pkt_sync_forward(3),pt_pkt_sync_backward(3), orpt_pkt_sync_set(3)to synchronizedecoder, bestie πpte_eosβ encode/decode has reached the end of the trace buffer. either there's not enough space in the trace buffer to generate the packet (pt_enc_next()), or the trace buffer doesn't contain a full Intel PT packet (pt_pkt_next()). we ran out, it's over, pack it up πpte_bad_opcβ the type of thepacketargument is not supported (pt_enc_next()), or the packet atdecoder's current position is not supported (pt_pkt_next()). not a vibe we recognize π«pte_bad_packetβ the payload, or parts of the payload, of thepacketargument is not supported (pt_enc_next()), or the packet atdecoder's current position contains unsupported payload (pt_pkt_next()). the payload said "no thoughts, head empty" π«
π EXAMPLE π
this example shows a typical Intel PT packet decode loop. chef's kiss, honestly π
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)
and that's the whole page, bestie π«Ά the footer's just the page name back at you in section 3 β PT_PACKET(3) β so like, we've gone full circle and it's iconic. now go forth and decode those packets π
β¨π
π¦ where this page comes from
- fedora 43: libipt-devel 2.1.2-3.fc43 Β· BSD-3-Clause
- fedora 43: libipt-devel 2.1.2-3.fc43 Β· BSD-3-Clause
- fedora 44: libipt-devel 2.1.2-4.fc44 Β· BSD-3-Clause
- fedora 44: libipt-devel 2.1.2-4.fc44 Β· BSD-3-Clause
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms