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:
parent
010a18a1b1
commit
9be54cae43
5 changed files with 114 additions and 0 deletions
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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."));
|
||||
}
|
||||
|
|
|
@ -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 */
|
||||
|
|
Loading…
Reference in a new issue