mirror of
https://github.com/bminor/binutils-gdb.git
synced 2025-12-29 18:41:27 +00:00
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>
This commit is contained in:
@@ -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) */
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user