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.

gdb/
	* 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.
This commit is contained in:
Markus Metzger 2014-02-03 11:40:50 +01:00
parent 010a18a1b1
commit 9be54cae43
5 changed files with 114 additions and 0 deletions

View file

@ -1,3 +1,13 @@
2015-07-02 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.
2015-07-02 Markus Metzger <markus.t.metzger@intel.com>
* nat/linux-btrace.c (linux_enable_bts): Check for

View file

@ -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);
}

View file

@ -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

View file

@ -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."));
}

View file

@ -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 */