From: Felix Willgerodt Date: Tue, 29 May 2018 06:44:45 +0000 (+0200) Subject: btrace, linux: Enable ptwrite packets. X-Git-Tag: gdb-16-branchpoint~1148 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=77a33bb02413975ccac5ccca315edc72dd6fe25b;p=thirdparty%2Fbinutils-gdb.git btrace, linux: Enable ptwrite packets. Enable ptwrite in the PT config, if it is supported by the kernel. Approved-By: Markus Metzger --- diff --git a/gdb/btrace.c b/gdb/btrace.c index 224341b6b2d..d6188c84ad4 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 5715168d2f0..59e8ae6bef6 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 8b1c9e1e4c8..997f442af55 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 }