This is the mail archive of the gdb-patches@sourceware.org mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH v2 4/5] btrace: store raw btrace data


Store the raw branch trace data that has been read from the target.

This data can be used for maintenance commands as well as for generating
a core file for the "record save" command.

2015-07-01  Markus Metzger  <markus.t.metzger@intel.com>

	* btrace.c (btrace_fetch): Append the new trace data.
	(btrace_clear): Clear the stored trace data.
	* btrace.h (btrace_thread_info) <data>: New.
	* common/btrace-common.h (btrace_data_clear)
	(btrace_data_append): New.
	* common/btrace-common.c (btrace_data_clear)
	(btrace_data_append): New.
---
 gdb/btrace.c               |  5 +++
 gdb/btrace.h               |  3 ++
 gdb/common/btrace-common.c | 87 ++++++++++++++++++++++++++++++++++++++++++++++
 gdb/common/btrace-common.h |  9 +++++
 4 files changed, 104 insertions(+)

diff --git a/gdb/btrace.c b/gdb/btrace.c
index 561ee7c..87b2601 100644
--- a/gdb/btrace.c
+++ b/gdb/btrace.c
@@ -1260,6 +1260,10 @@ btrace_fetch (struct thread_info *tp)
   /* Compute the trace, provided we have any.  */
   if (!btrace_data_empty (&btrace))
     {
+      /* Store the raw trace data.  The stored data will be cleared in
+	 btrace_clear, so we always append the new trace.  */
+      btrace_data_append (&btinfo->data, &btrace);
+
       btrace_clear_history (btinfo);
       btrace_compute_ftrace (tp, &btrace);
     }
@@ -1296,6 +1300,7 @@ btrace_clear (struct thread_info *tp)
   btinfo->end = NULL;
   btinfo->ngaps = 0;
 
+  btrace_data_clear (&btinfo->data);
   btrace_clear_history (btinfo);
 }
 
diff --git a/gdb/btrace.h b/gdb/btrace.h
index c25dc84..0845b78 100644
--- a/gdb/btrace.h
+++ b/gdb/btrace.h
@@ -248,6 +248,9 @@ struct btrace_thread_info
      the underlying architecture.  */
   struct btrace_target_info *target;
 
+  /* The raw branch trace data for the below branch trace.  */
+  struct btrace_data data;
+
   /* The current branch trace for this thread (both inclusive).
 
      The last instruction of END is the current instruction, which is not
diff --git a/gdb/common/btrace-common.c b/gdb/common/btrace-common.c
index 676428e..95193eb 100644
--- a/gdb/common/btrace-common.c
+++ b/gdb/common/btrace-common.c
@@ -91,3 +91,90 @@ btrace_data_empty (struct btrace_data *data)
 
   internal_error (__FILE__, __LINE__, _("Unkown branch trace format."));
 }
+
+/* See btrace-common.h.  */
+
+void
+btrace_data_clear (struct btrace_data *data)
+{
+  btrace_data_fini (data);
+  btrace_data_init (data);
+}
+
+/* See btrace-common.h.  */
+
+int
+btrace_data_append (struct btrace_data *dst,
+		    const struct btrace_data *src)
+{
+  switch (src->format)
+    {
+    case BTRACE_FORMAT_NONE:
+      return 0;
+
+    case BTRACE_FORMAT_BTS:
+      switch (dst->format)
+	{
+	default:
+	  return -1;
+
+	case BTRACE_FORMAT_NONE:
+	  dst->format = BTRACE_FORMAT_BTS;
+	  dst->variant.bts.blocks = NULL;
+
+	  /* Fall-through.  */
+	case BTRACE_FORMAT_BTS:
+	  {
+	    unsigned int blk;
+
+	    /* We copy blocks in reverse order to have the oldest block at
+	       index zero.  */
+	    blk = VEC_length (btrace_block_s, src->variant.bts.blocks);
+	    while (blk != 0)
+	      {
+		btrace_block_s *block;
+
+		block = VEC_index (btrace_block_s, src->variant.bts.blocks,
+				   --blk);
+
+		VEC_safe_push (btrace_block_s, dst->variant.bts.blocks, block);
+	      }
+	  }
+	}
+      return 0;
+
+    case BTRACE_FORMAT_PT:
+      switch (dst->format)
+	{
+	default:
+	  return -1;
+
+	case BTRACE_FORMAT_NONE:
+	  dst->format = BTRACE_FORMAT_PT;
+	  dst->variant.pt.data = NULL;
+	  dst->variant.pt.size = 0;
+
+	  /* fall-through.  */
+	case BTRACE_FORMAT_BTS:
+	  {
+	    gdb_byte *data;
+	    unsigned long size;
+
+	    size = src->variant.pt.size + dst->variant.pt.size;
+	    data = xmalloc (size);
+
+	    memcpy (data, dst->variant.pt.data, dst->variant.pt.size);
+	    memcpy (data + dst->variant.pt.size, src->variant.pt.data,
+		    src->variant.pt.size);
+
+	    xfree (dst->variant.pt.data);
+
+	    dst->variant.pt.data = data;
+	    dst->variant.pt.size = size;
+	  }
+	}
+      return 0;
+    }
+
+  internal_error (__FILE__, __LINE__, _("Unkown branch trace format."));
+}
diff --git a/gdb/common/btrace-common.h b/gdb/common/btrace-common.h
index ebae17e..f22efc5 100644
--- a/gdb/common/btrace-common.h
+++ b/gdb/common/btrace-common.h
@@ -214,7 +214,16 @@ extern void btrace_data_init (struct btrace_data *data);
 /* Cleanup DATA.  */
 extern void btrace_data_fini (struct btrace_data *data);
 
+/* Clear DATA.  */
+extern void btrace_data_clear (struct btrace_data *data);
+
 /* Return non-zero if DATA is empty; zero otherwise.  */
 extern int btrace_data_empty (struct btrace_data *data);
 
+/* Append the branch trace data from SRC to the end of DST.
+   Both SRC and DST must use the same format.
+   Returns zero on success; a negative number otherwise.  */
+extern int btrace_data_append (struct btrace_data *dst,
+			       const struct btrace_data *src);
+
 #endif /* BTRACE_COMMON_H */
-- 
1.8.3.1


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]