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) */
}
}
}
}
+/* 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. */
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)