PT_QRY_COND_BRANCH(3)
π PT_QRY_COND_BRANCH β bestie edition π
okay so welcome to pt_qry_cond_branch(3), aka the manual page for pt_qry_cond_branch and pt_qry_indirect_branch, two little functions that query an Intel(R) Processor Trace query decoder. yes that's a lot of "query" in one sentence, we love that for us. β¨
β¨ 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);
and bestie, don't forget to link with -lipt or nothing works, no cap. π
π DESCRIPTION π
pt_qry_cond_branch() π
okay so pt_qry_cond_branch() uses Intel Processor Trace (Intel PT) to figure out whether the next conditional branch in the traced code was taken or not taken. the decoder argument must point to an Intel PT query decoder, like, non-negotiable.
on success, it sets the variable that the taken argument points to: a non-zero value if the next condition branch is taken, and zero if it is not taken. iconic behavior honestly.
pt_qry_indirect_branch() π¦
and then pt_qry_indirect_branch() uses Intel Processor Trace (Intel PT) to figure out the destination virtual address of the next indirect branch in the traced code. main character energy fr fr.
on success, it hands you the destination address in the integer variable pointed to be the ip argument. and listen β if that destination address has been suppressed in the Intel PT trace, the lack of an IP gets indicated in the return value by setting the pts_ip_suppressed bit. so like, check your return value, bestie, i'm begging. π
β 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. periodt.
on success, you get back a bit-vector of pt_status_flag enumeration constants. the pt_status_flag enumeration is declared as:
/** 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
};
look at those little bit flags living their best lives. π
π ERRORS π
pte_invalidβ thedecoderargument, or thetakenargument (forpt_qry_cond_branch()) or theipargument (forpt_qry_indirect_branch()), isNULL. yeah she's null, she's not coming back. πpte_eosβ decode reached the end of the trace stream. that's it, that's the whole stream, we're done here. πpte_nosyncβ the decoder has not been synchronized onto the trace stream. usept_qry_sync_forward(3),pt_qry_sync_backward(3), orpt_qry_sync_set(3)to synchronize the decoder. go sync your decoder bestie, it's giving lost. π§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 topt_qry_event(3). this usually means that execution flow reconstruction and trace got out of sync. π¨ like they broke up. it's messy.
π EXAMPLE π
the following example sketches an execution flow reconstruction loop. asynchronous events have been omitted.
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);
}
}
she loops, she checks, she queries, she slays. π₯ (also note: async events are omitted here, so don't come for me about the events.)
π«Ά 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)
go read those too, they're part of the friend group. β¨
and that's the whole page bestie!! PT_QRY_COND_BRANCH(3) β that's the manual section it lives in, and yes, it's giving legend behavior. π mwah, go reconstruct some execution flow, ily. π
π¦ 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