aboutsummaryrefslogtreecommitdiff
path: root/gdb/nat
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 /gdb/nat
parentccc480801b4779aafe7c27e2b0f472e2e1fab354 (diff)
downloadgdb-77a33bb02413975ccac5ccca315edc72dd6fe25b.zip
gdb-77a33bb02413975ccac5ccca315edc72dd6fe25b.tar.gz
gdb-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>
Diffstat (limited to 'gdb/nat')
-rw-r--r--gdb/nat/linux-btrace.c59
1 files changed, 59 insertions, 0 deletions
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)