diff options
author | Felix Willgerodt <felix.willgerodt@intel.com> | 2018-05-29 08:44:45 +0200 |
---|---|---|
committer | Felix Willgerodt <felix.willgerodt@intel.com> | 2024-08-14 11:20:56 +0200 |
commit | 77a33bb02413975ccac5ccca315edc72dd6fe25b (patch) | |
tree | 56ae437eea12ff626e3d7e0a8b65425034dec0a5 | |
parent | ccc480801b4779aafe7c27e2b0f472e2e1fab354 (diff) | |
download | binutils-77a33bb02413975ccac5ccca315edc72dd6fe25b.zip binutils-77a33bb02413975ccac5ccca315edc72dd6fe25b.tar.gz binutils-77a33bb02413975ccac5ccca315edc72dd6fe25b.tar.bz2 |
btrace, linux: Enable ptwrite packets.
Enable ptwrite in the PT config, if it is supported by the kernel.
Approved-By: Markus Metzger <markus.t.metzger@intel.com>
-rw-r--r-- | gdb/btrace.c | 8 | ||||
-rw-r--r-- | gdb/nat/linux-btrace.c | 59 | ||||
-rw-r--r-- | gdb/record-btrace.c | 5 |
3 files changed, 72 insertions, 0 deletions
diff --git a/gdb/btrace.c b/gdb/btrace.c index 224341b..d6188c8 100644 --- a/gdb/btrace.c +++ b/gdb/btrace.c @@ -2653,6 +2653,14 @@ pt_print_packet (const struct pt_packet *packet) case ppt_mnt: gdb_printf (("mnt %" PRIx64 ""), packet->payload.mnt.payload); break; + +#if (LIBIPT_VERSION >= 0x200) + case ppt_ptw: + gdb_printf (("ptw %u: 0x%" PRIx64 "%s"), packet->payload.ptw.plc, + packet->payload.ptw.payload, + packet->payload.ptw.ip ? (" ip") : ("")); + break; +#endif /* defined (LIBIPT_VERSION >= 0x200) */ } } diff --git a/gdb/nat/linux-btrace.c b/gdb/nat/linux-btrace.c index 5715168..59e8ae6 100644 --- a/gdb/nat/linux-btrace.c +++ b/gdb/nat/linux-btrace.c @@ -415,6 +415,59 @@ cpu_supports_bts (void) } } +/* Return the Intel PT config bitmask from the linux sysfs for a FEATURE. + The bits can be used in the perf_event configuration when enabling PT. + Callers of this function are expected to check the availability of the + feature first via linux_supports_pt_feature. */ + +static uint64_t +linux_read_pt_config_bitmask (const char *feature) +{ + uint64_t config_bitmask = 0; + std::string filename + = std::string ("/sys/bus/event_source/devices/intel_pt/format/") + + feature; + + gdb_file_up file = gdb_fopen_cloexec (filename.c_str (), "r"); + if (file.get () == nullptr) + error (_("Failed to determine config from %s."), filename.c_str ()); + + uint8_t start, end; + int found = fscanf (file.get (), "config:%hhu-%hhu", &start, &end); + if (found == 1) + end = start; + else if (found != 2) + error (_("Failed to determine config from %s."), filename.c_str ()); + + for (uint8_t i = start; i <= end; ++i) + config_bitmask |= (1ULL << i); + + return config_bitmask; +} + +/* Check whether the linux target supports the Intel PT FEATURE. */ + +static bool +linux_supports_pt_feature (const char *feature) +{ + std::string filename + = std::string ("/sys/bus/event_source/devices/intel_pt/caps/") + feature; + + gdb_file_up file = gdb_fopen_cloexec (filename.c_str (), "r"); + if (file.get () == nullptr) + return false; + + int status, found = fscanf (file.get (), "%d", &status); + if (found != 1) + { + warning (_("Failed to determine %s support from %s."), feature, + filename.c_str ()); + return false; + } + + return (status == 1); +} + /* The perf_event_open syscall failed. Try to print a helpful error message. */ @@ -627,6 +680,12 @@ linux_enable_pt (ptid_t ptid, const struct btrace_config_pt *conf) tinfo->attr.exclude_hv = 1; tinfo->attr.exclude_idle = 1; + if (conf->ptwrite && linux_supports_pt_feature ("ptwrite")) + { + tinfo->attr.config |= linux_read_pt_config_bitmask ("ptw"); + tinfo->conf.pt.ptwrite = true; + } + errno = 0; scoped_fd fd (syscall (SYS_perf_event_open, &tinfo->attr, pid, -1, -1, 0)); if (fd.get () < 0) diff --git a/gdb/record-btrace.c b/gdb/record-btrace.c index 8b1c9e1..997f442 100644 --- a/gdb/record-btrace.c +++ b/gdb/record-btrace.c @@ -3306,4 +3306,9 @@ to see the actual buffer size."), NULL, show_record_pt_buffer_size_value, record_btrace_conf.bts.size = 64 * 1024; record_btrace_conf.pt.size = 16 * 1024; +#if (LIBIPT_VERSION >= 0x200) + record_btrace_conf.pt.ptwrite = true; +#else + record_btrace_conf.pt.ptwrite = false; +#endif } |