aboutsummaryrefslogtreecommitdiff
path: root/gdb/btrace.c
diff options
context:
space:
mode:
authorFelix Willgerodt <felix.willgerodt@intel.com>2019-02-18 15:50:49 +0100
committerFelix Willgerodt <felix.willgerodt@intel.com>2024-08-14 11:20:57 +0200
commit3bf62223f0f5591c70523e363a496dba6c699e3a (patch)
tree2d1f60312520648fd630cb563c56b7f87fe7326c /gdb/btrace.c
parent6be9971c93f3bbcd4b779e5591697748da6b093e (diff)
downloadgdb-3bf62223f0f5591c70523e363a496dba6c699e3a.zip
gdb-3bf62223f0f5591c70523e363a496dba6c699e3a.tar.gz
gdb-3bf62223f0f5591c70523e363a496dba6c699e3a.tar.bz2
btrace: Extend ptwrite event decoding.
Call the ptwrite filter function whenever a ptwrite event is decoded. The returned string is written to the aux_data string table and a corresponding auxiliary instruction is appended to the function segment. Approved-By: Markus Metzger <markus.t.metzger@intel.com> Reviewed-By: Eli Zaretskii <eliz@gnu.org>
Diffstat (limited to 'gdb/btrace.c')
-rw-r--r--gdb/btrace.c73
1 files changed, 73 insertions, 0 deletions
diff --git a/gdb/btrace.c b/gdb/btrace.c
index d493fbe..95ff27c 100644
--- a/gdb/btrace.c
+++ b/gdb/btrace.c
@@ -41,6 +41,7 @@
#include <inttypes.h>
#include <ctype.h>
#include <algorithm>
+#include <string>
/* Command lists for btrace maintenance commands. */
static struct cmd_list_element *maint_btrace_cmdlist;
@@ -1204,6 +1205,24 @@ pt_btrace_insn (const struct pt_insn &insn)
pt_btrace_insn_flags (insn)};
}
+#if defined (HAVE_PT_INSN_EVENT)
+/* Helper for events that will result in an aux_insn. */
+
+static void
+handle_pt_aux_insn (btrace_thread_info *btinfo, btrace_function *bfun,
+ std::string &aux_str, CORE_ADDR ip)
+{
+ btinfo->aux_data.emplace_back (std::move (aux_str));
+ bfun = ftrace_update_function (btinfo, ip);
+
+ btrace_insn insn {btinfo->aux_data.size () - 1, 0,
+ BTRACE_INSN_AUX, 0};
+
+ ftrace_update_insns (bfun, insn);
+}
+
+#endif /* defined (HAVE_PT_INSN_EVENT) */
+
/* Handle instruction decode events (libipt-v2). */
static int
@@ -1252,6 +1271,60 @@ handle_pt_insn_events (struct btrace_thread_info *btinfo,
bfun->insn_offset - 1, offset);
break;
+#if defined (HAVE_STRUCT_PT_EVENT_VARIANT_PTWRITE)
+ case ptev_ptwrite:
+ {
+ uint64_t pc = 0;
+ std::optional<std::string> ptw_string;
+
+ /* Lookup the PC if available. The event often doesn't provide
+ one, so we look into the last function segment as well.
+ Looking further back makes limited sense for ptwrite. */
+ if (event.ip_suppressed == 0)
+ pc = event.variant.ptwrite.ip;
+ else if (!btinfo->functions.empty ())
+ {
+ std::vector<btrace_insn> &insns
+ = btinfo->functions.back ().insn;
+ for (auto insn = insns.rbegin (); insn != insns.rend ();
+ ++insn)
+ {
+ switch (insn->iclass)
+ {
+ case BTRACE_INSN_AUX:
+ continue;
+
+ case BTRACE_INSN_OTHER:
+ case BTRACE_INSN_CALL:
+ case BTRACE_INSN_RETURN:
+ case BTRACE_INSN_JUMP:
+ pc = insn->pc;
+ break;
+ /* No default to rely on compiler warnings. */
+ }
+ break;
+ }
+ }
+
+ if (pc == 0)
+ warning (_("Failed to determine the PC for ptwrite."));
+
+ if (btinfo->ptw_callback_fun != nullptr)
+ ptw_string
+ = btinfo->ptw_callback_fun (event.variant.ptwrite.payload,
+ pc, btinfo->ptw_context);
+
+ if (ptw_string.has_value () && (*ptw_string).empty ())
+ continue;
+
+ if (!ptw_string.has_value ())
+ *ptw_string = hex_string (event.variant.ptwrite.payload);
+
+ handle_pt_aux_insn (btinfo, bfun, *ptw_string, pc);
+
+ break;
+ }
+#endif /* defined (HAVE_STRUCT_PT_EVENT_VARIANT_PTWRITE) */
}
}
#endif /* defined (HAVE_PT_INSN_EVENT) */