18dffb485Schristos /* Branch trace support for GDB, the GNU debugger. 28dffb485Schristos 3*5ba1f45fSchristos Copyright (C) 2013-2024 Free Software Foundation, Inc. 48dffb485Schristos 58dffb485Schristos Contributed by Intel Corp. <markus.t.metzger@intel.com>. 68dffb485Schristos 78dffb485Schristos This file is part of GDB. 88dffb485Schristos 98dffb485Schristos This program is free software; you can redistribute it and/or modify 108dffb485Schristos it under the terms of the GNU General Public License as published by 118dffb485Schristos the Free Software Foundation; either version 3 of the License, or 128dffb485Schristos (at your option) any later version. 138dffb485Schristos 148dffb485Schristos This program is distributed in the hope that it will be useful, 158dffb485Schristos but WITHOUT ANY WARRANTY; without even the implied warranty of 168dffb485Schristos MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 178dffb485Schristos GNU General Public License for more details. 188dffb485Schristos 198dffb485Schristos You should have received a copy of the GNU General Public License 208dffb485Schristos along with this program. If not, see <http://www.gnu.org/licenses/>. */ 218dffb485Schristos 228dffb485Schristos #ifndef COMMON_BTRACE_COMMON_H 238dffb485Schristos #define COMMON_BTRACE_COMMON_H 248dffb485Schristos 258dffb485Schristos /* Branch tracing (btrace) is a per-thread control-flow execution trace of the 268dffb485Schristos inferior. For presentation purposes, the branch trace is represented as a 278dffb485Schristos list of sequential control-flow blocks, one such list per thread. */ 288dffb485Schristos 298dffb485Schristos /* A branch trace block. 308dffb485Schristos 318dffb485Schristos This represents a block of sequential control-flow. Adjacent blocks will be 328dffb485Schristos connected via calls, returns, or jumps. The latter can be direct or 338dffb485Schristos indirect, conditional or unconditional. Branches can further be 348dffb485Schristos asynchronous, e.g. interrupts. */ 358dffb485Schristos struct btrace_block 368dffb485Schristos { 378dffb485Schristos /* The address of the first byte of the first instruction in the block. 388dffb485Schristos The address may be zero if we do not know the beginning of this block, 398dffb485Schristos such as for the first block in a delta trace. */ 408dffb485Schristos CORE_ADDR begin; 418dffb485Schristos 428dffb485Schristos /* The address of the first byte of the last instruction in the block. */ 438dffb485Schristos CORE_ADDR end; 448dffb485Schristos 458dffb485Schristos /* Simple constructor. */ 468dffb485Schristos btrace_block (CORE_ADDR begin, CORE_ADDR end) 478dffb485Schristos : begin (begin), 488dffb485Schristos end (end) 498dffb485Schristos { 508dffb485Schristos /* Nothing. */ 518dffb485Schristos } 528dffb485Schristos }; 538dffb485Schristos 548dffb485Schristos /* Enumeration of btrace formats. */ 558dffb485Schristos 568dffb485Schristos enum btrace_format 578dffb485Schristos { 588dffb485Schristos /* No branch trace format. */ 598dffb485Schristos BTRACE_FORMAT_NONE, 608dffb485Schristos 618dffb485Schristos /* Branch trace is in Branch Trace Store (BTS) format. 628dffb485Schristos Actually, the format is a sequence of blocks derived from BTS. */ 638dffb485Schristos BTRACE_FORMAT_BTS, 648dffb485Schristos 658dffb485Schristos /* Branch trace is in Intel Processor Trace format. */ 668dffb485Schristos BTRACE_FORMAT_PT 678dffb485Schristos }; 688dffb485Schristos 698dffb485Schristos /* An enumeration of cpu vendors. */ 708dffb485Schristos 718dffb485Schristos enum btrace_cpu_vendor 728dffb485Schristos { 738dffb485Schristos /* We do not know this vendor. */ 748dffb485Schristos CV_UNKNOWN, 758dffb485Schristos 768dffb485Schristos /* Intel. */ 778dffb485Schristos CV_INTEL, 788dffb485Schristos 798dffb485Schristos /* AMD. */ 808dffb485Schristos CV_AMD 818dffb485Schristos }; 828dffb485Schristos 838dffb485Schristos /* A cpu identifier. */ 848dffb485Schristos 858dffb485Schristos struct btrace_cpu 868dffb485Schristos { 878dffb485Schristos /* The processor vendor. */ 888dffb485Schristos enum btrace_cpu_vendor vendor; 898dffb485Schristos 908dffb485Schristos /* The cpu family. */ 918dffb485Schristos unsigned short family; 928dffb485Schristos 938dffb485Schristos /* The cpu model. */ 948dffb485Schristos unsigned char model; 958dffb485Schristos 968dffb485Schristos /* The cpu stepping. */ 978dffb485Schristos unsigned char stepping; 988dffb485Schristos }; 998dffb485Schristos 1008dffb485Schristos /* A BTS configuration. */ 1018dffb485Schristos 1028dffb485Schristos struct btrace_config_bts 1038dffb485Schristos { 1048dffb485Schristos /* The size of the branch trace buffer in bytes. 1058dffb485Schristos 1068dffb485Schristos This is unsigned int and not size_t since it is registered as 1078dffb485Schristos control variable for "set record btrace bts buffer-size". */ 1088dffb485Schristos unsigned int size; 1098dffb485Schristos }; 1108dffb485Schristos 1118dffb485Schristos /* An Intel Processor Trace configuration. */ 1128dffb485Schristos 1138dffb485Schristos struct btrace_config_pt 1148dffb485Schristos { 1158dffb485Schristos /* The size of the branch trace buffer in bytes. 1168dffb485Schristos 1178dffb485Schristos This is unsigned int and not size_t since it is registered as 1188dffb485Schristos control variable for "set record btrace pt buffer-size". */ 1198dffb485Schristos unsigned int size; 1208dffb485Schristos }; 1218dffb485Schristos 1228dffb485Schristos /* A branch tracing configuration. 1238dffb485Schristos 1248dffb485Schristos This describes the requested configuration as well as the actually 1258dffb485Schristos obtained configuration. 1268dffb485Schristos We describe the configuration for all different formats so we can 1278dffb485Schristos easily switch between formats. */ 1288dffb485Schristos 1298dffb485Schristos struct btrace_config 1308dffb485Schristos { 1318dffb485Schristos /* The branch tracing format. */ 1328dffb485Schristos enum btrace_format format; 1338dffb485Schristos 1348dffb485Schristos /* The BTS format configuration. */ 1358dffb485Schristos struct btrace_config_bts bts; 1368dffb485Schristos 1378dffb485Schristos /* The Intel Processor Trace format configuration. */ 1388dffb485Schristos struct btrace_config_pt pt; 1398dffb485Schristos }; 1408dffb485Schristos 1418dffb485Schristos /* Branch trace in BTS format. */ 1428dffb485Schristos struct btrace_data_bts 1438dffb485Schristos { 1448dffb485Schristos /* Branch trace is represented as a vector of branch trace blocks starting 1458dffb485Schristos with the most recent block. This needs to be a pointer as we place 1468dffb485Schristos btrace_data_bts into a union. */ 1478dffb485Schristos std::vector<btrace_block> *blocks; 1488dffb485Schristos }; 1498dffb485Schristos 1508dffb485Schristos /* Configuration information to go with the trace data. */ 1518dffb485Schristos struct btrace_data_pt_config 1528dffb485Schristos { 1538dffb485Schristos /* The processor on which the trace has been collected. */ 1548dffb485Schristos struct btrace_cpu cpu; 1558dffb485Schristos }; 1568dffb485Schristos 1578dffb485Schristos /* Branch trace in Intel Processor Trace format. */ 1588dffb485Schristos struct btrace_data_pt 1598dffb485Schristos { 1608dffb485Schristos /* Some configuration information to go with the data. */ 1618dffb485Schristos struct btrace_data_pt_config config; 1628dffb485Schristos 1638dffb485Schristos /* The trace data. */ 1648dffb485Schristos gdb_byte *data; 1658dffb485Schristos 1668dffb485Schristos /* The size of DATA in bytes. */ 1678dffb485Schristos size_t size; 1688dffb485Schristos }; 1698dffb485Schristos 1708dffb485Schristos /* The branch trace data. */ 1718dffb485Schristos struct btrace_data 1728dffb485Schristos { 1738dffb485Schristos btrace_data () = default; 1748dffb485Schristos 1758dffb485Schristos ~btrace_data () 1768dffb485Schristos { 1778dffb485Schristos fini (); 1788dffb485Schristos } 1798dffb485Schristos 1808dffb485Schristos btrace_data &operator= (btrace_data &&other) 1818dffb485Schristos { 1828dffb485Schristos if (this != &other) 1838dffb485Schristos { 1848dffb485Schristos fini (); 1858dffb485Schristos format = other.format; 1868dffb485Schristos variant = other.variant; 1878dffb485Schristos other.format = BTRACE_FORMAT_NONE; 1888dffb485Schristos } 1898dffb485Schristos return *this; 1908dffb485Schristos } 1918dffb485Schristos 1928dffb485Schristos /* Return true if this is empty; false otherwise. */ 1938dffb485Schristos bool empty () const; 1948dffb485Schristos 1958dffb485Schristos /* Clear this object. */ 1968dffb485Schristos void clear (); 1978dffb485Schristos 1988dffb485Schristos enum btrace_format format = BTRACE_FORMAT_NONE; 1998dffb485Schristos 2008dffb485Schristos union 2018dffb485Schristos { 2028dffb485Schristos /* Format == BTRACE_FORMAT_BTS. */ 2038dffb485Schristos struct btrace_data_bts bts; 2048dffb485Schristos 2058dffb485Schristos /* Format == BTRACE_FORMAT_PT. */ 2068dffb485Schristos struct btrace_data_pt pt; 2078dffb485Schristos } variant; 2088dffb485Schristos 2098dffb485Schristos private: 2108dffb485Schristos 2118dffb485Schristos DISABLE_COPY_AND_ASSIGN (btrace_data); 2128dffb485Schristos 2138dffb485Schristos void fini (); 2148dffb485Schristos }; 2158dffb485Schristos 2168dffb485Schristos /* Target specific branch trace information. */ 217*5ba1f45fSchristos struct btrace_target_info 218*5ba1f45fSchristos { 219*5ba1f45fSchristos btrace_target_info (ptid_t ptid) : ptid (ptid) 220*5ba1f45fSchristos {} 221*5ba1f45fSchristos 222*5ba1f45fSchristos btrace_target_info (ptid_t ptid, btrace_config conf) 223*5ba1f45fSchristos : ptid (ptid), conf (conf) 224*5ba1f45fSchristos {} 225*5ba1f45fSchristos 226*5ba1f45fSchristos virtual ~btrace_target_info () = default; 227*5ba1f45fSchristos 228*5ba1f45fSchristos /* The ptid of this thread. */ 229*5ba1f45fSchristos ptid_t ptid {}; 230*5ba1f45fSchristos 231*5ba1f45fSchristos /* The obtained branch trace configuration. */ 232*5ba1f45fSchristos btrace_config conf {}; 233*5ba1f45fSchristos }; 2348dffb485Schristos 2358dffb485Schristos /* Enumeration of btrace read types. */ 2368dffb485Schristos 2378dffb485Schristos enum btrace_read_type 2388dffb485Schristos { 2398dffb485Schristos /* Send all available trace. */ 2408dffb485Schristos BTRACE_READ_ALL, 2418dffb485Schristos 2428dffb485Schristos /* Send all available trace, if it changed. */ 2438dffb485Schristos BTRACE_READ_NEW, 2448dffb485Schristos 2458dffb485Schristos /* Send the trace since the last request. This will fail if the trace 2468dffb485Schristos buffer overflowed. */ 2478dffb485Schristos BTRACE_READ_DELTA 2488dffb485Schristos }; 2498dffb485Schristos 2508dffb485Schristos /* Enumeration of btrace errors. */ 2518dffb485Schristos 2528dffb485Schristos enum btrace_error 2538dffb485Schristos { 2548dffb485Schristos /* No error. Everything is OK. */ 2558dffb485Schristos BTRACE_ERR_NONE, 2568dffb485Schristos 2578dffb485Schristos /* An unknown error. */ 2588dffb485Schristos BTRACE_ERR_UNKNOWN, 2598dffb485Schristos 2608dffb485Schristos /* Branch tracing is not supported on this system. */ 2618dffb485Schristos BTRACE_ERR_NOT_SUPPORTED, 2628dffb485Schristos 2638dffb485Schristos /* The branch trace buffer overflowed; no delta read possible. */ 2648dffb485Schristos BTRACE_ERR_OVERFLOW 2658dffb485Schristos }; 2668dffb485Schristos 2678dffb485Schristos /* Return a string representation of FORMAT. */ 2688dffb485Schristos extern const char *btrace_format_string (enum btrace_format format); 2698dffb485Schristos 2708dffb485Schristos /* Return an abbreviation string representation of FORMAT. */ 2718dffb485Schristos extern const char *btrace_format_short_string (enum btrace_format format); 2728dffb485Schristos 2738dffb485Schristos /* Append the branch trace data from SRC to the end of DST. 2748dffb485Schristos Both SRC and DST must use the same format. 2758dffb485Schristos Returns zero on success; a negative number otherwise. */ 2768dffb485Schristos extern int btrace_data_append (struct btrace_data *dst, 2778dffb485Schristos const struct btrace_data *src); 2788dffb485Schristos 2798dffb485Schristos #endif /* COMMON_BTRACE_COMMON_H */ 280