aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFelix Willgerodt <felix.willgerodt@intel.com>2018-05-29 08:44:45 +0200
committerFelix Willgerodt <felix.willgerodt@intel.com>2024-08-14 11:20:56 +0200
commit77a33bb02413975ccac5ccca315edc72dd6fe25b (patch)
tree56ae437eea12ff626e3d7e0a8b65425034dec0a5
parentccc480801b4779aafe7c27e2b0f472e2e1fab354 (diff)
downloadbinutils-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.c8
-rw-r--r--gdb/nat/linux-btrace.c59
-rw-r--r--gdb/record-btrace.c5
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
}