#include "source.h"
#include "ax.h"
#include "ax-gdb.h"
+#include "memrange.h"
/* readline include files */
#include "readline/readline.h"
typedef struct trace_state_variable tsv_s;
DEF_VEC_O(tsv_s);
-/* Defines a [START, START + LENGTH) memory range. */
-
-struct mem_range
-{
- /* Lowest address in the range. */
- CORE_ADDR start;
-
- /* Length of the range. */
- int length;
-};
-
-typedef struct mem_range mem_range_s;
-
-DEF_VEC_O(mem_range_s);
-
/* An object describing the contents of a traceframe. */
struct traceframe_info
};
struct trace_status *
-current_trace_status ()
+current_trace_status (void)
{
return &trace_status;
}
struct breakpoint *t;
struct command_line *l;
- t = get_tracepoint_by_number (&args, 0, 1);
+ t = get_tracepoint_by_number (&args, NULL, 1);
if (t)
{
char *tmpbuf =
{
for (a = 0, b = 1; b < memranges->next_memrange; b++)
{
- if (memranges->list[a].type == memranges->list[b].type &&
- memranges->list[b].start - memranges->list[a].end <=
- MAX_REGISTER_SIZE)
+ /* If memrange b overlaps or is adjacent to memrange a,
+ merge them. */
+ if (memranges->list[a].type == memranges->list[b].type
+ && memranges->list[b].start <= memranges->list[a].end)
{
- /* memrange b starts before memrange a ends; merge them. */
if (memranges->list[b].end > memranges->list[a].end)
memranges->list[a].end = memranges->list[b].end;
continue; /* next b, same a */
confusing upon reconnection. Just use these calls instead of
full tfind_1 behavior because we're in the middle of detaching,
and there's no point to updating current stack frame etc. */
- set_traceframe_number (-1);
+ set_current_traceframe (-1);
set_traceframe_context (NULL);
}
struct symbol *sym;
struct minimal_symbol *msym;
struct block *block;
- char **canonical, *symname, *save_args = args;
+ char *symname, *save_args = args;
struct dict_iterator iter;
int j, count = 0;
struct gdbarch *gdbarch;
error (_("requires an argument (function, "
"line or *addr) to define a scope"));
- sals = decode_line_1 (&args, 1, NULL, 0, &canonical, NULL);
+ sals = decode_line_1 (&args, 1, NULL, 0, NULL, NULL);
if (sals.nelts == 0)
return; /* Presumably decode_line_1 has already warned. */
if NUM is already current. */
void
-set_traceframe_number (int num)
+set_current_traceframe (int num)
{
int newnum;
clear_traceframe_info ();
}
+/* Make the traceframe NUM be the current trace frame, and do nothing
+ more. */
+
+void
+set_traceframe_number (int num)
+{
+ traceframe_number = num;
+}
+
/* A cleanup used when switching away and back from tfind mode. */
struct current_traceframe_cleanup
{
struct current_traceframe_cleanup *old = arg;
- set_traceframe_number (old->traceframe_number);
+ set_current_traceframe (old->traceframe_number);
}
static void
restore_current_traceframe_cleanup_dtor);
}
+struct cleanup *
+make_cleanup_restore_traceframe_number (void)
+{
+ return make_cleanup_restore_integer (&traceframe_number);
+}
+
/* Given a number and address, return an uploaded tracepoint with that
number, creating if necessary. */
sprintf (buf, "%s_%d", namebase, try_num++);
/* We have an available name, create the variable. */
- tsv = create_trace_state_variable (xstrdup (buf));
+ tsv = create_trace_state_variable (buf);
tsv->initial_value = utsv->initial_value;
tsv->builtin = utsv->builtin;
int trace_fd = -1;
off_t trace_frames_offset;
off_t cur_offset;
+int cur_traceframe_number;
int cur_data_size;
int trace_regblock_size;
ts->disconnected_tracing = 0;
ts->circular_buffer = 0;
+ cur_traceframe_number = -1;
+
/* Read through a section of newline-terminated lines that
define things like tracepoints. */
i = 0;
return addr;
}
+/* Make tfile's selected traceframe match GDB's selected
+ traceframe. */
+
+static void
+set_tfile_traceframe (void)
+{
+ int newnum;
+
+ if (cur_traceframe_number == get_traceframe_number ())
+ return;
+
+ /* Avoid recursion, tfile_trace_find calls us again. */
+ cur_traceframe_number = get_traceframe_number ();
+
+ newnum = target_trace_find (tfind_number,
+ get_traceframe_number (), 0, 0, NULL);
+
+ /* Should not happen. If it does, all bets are off. */
+ if (newnum != get_traceframe_number ())
+ warning (_("could not set tfile's traceframe"));
+}
+
/* Given a type of search and some parameters, scan the collection of
traceframes in the file looking for a match. When found, return
both the traceframe and tracepoint number, otherwise -1 for
off_t offset, tframe_offset;
ULONGEST tfaddr;
+ /* Lookups other than by absolute frame number depend on the current
+ trace selected, so make sure it is correct on the tfile end
+ first. */
+ if (type != tfind_number)
+ set_tfile_traceframe ();
+
lseek (trace_fd, trace_frames_offset, SEEK_SET);
offset = trace_frames_offset;
while (1)
*tpp = tpnum;
cur_offset = offset;
cur_data_size = data_size;
+ cur_traceframe_number = tfnum;
return tfnum;
}
/* Skip past the traceframe's data. */
if (!trace_regblock_size)
return;
+ set_tfile_traceframe ();
+
regs = alloca (trace_regblock_size);
if (traceframe_find_block_type ('R', 0) >= 0)
if (readbuf == NULL)
error (_("tfile_xfer_partial: trace file is read-only"));
- if (traceframe_number != -1)
+ set_tfile_traceframe ();
+
+ if (traceframe_number != -1)
{
int pos = 0;
{
int pos;
+ set_tfile_traceframe ();
+
pos = 0;
while ((pos = traceframe_find_block_type ('V', pos)) >= 0)
{
return traceframe_info;
}
+/* If the target supports the query, return in RESULT the set of
+ collected memory in the current traceframe, found within the LEN
+ bytes range starting at MEMADDR. Returns true if the target
+ supports the query, otherwise returns false, and RESULT is left
+ undefined. */
+
+int
+traceframe_available_memory (VEC(mem_range_s) **result,
+ CORE_ADDR memaddr, ULONGEST len)
+{
+ struct traceframe_info *info = get_traceframe_info ();
+
+ if (info != NULL)
+ {
+ struct mem_range *r;
+ int i;
+
+ *result = NULL;
+
+ for (i = 0; VEC_iterate (mem_range_s, info->memory, i, r); i++)
+ if (mem_ranges_overlap (r->start, r->length, memaddr, len))
+ {
+ ULONGEST lo1, hi1, lo2, hi2;
+ struct mem_range *nr;
+
+ lo1 = memaddr;
+ hi1 = memaddr + len;
+
+ lo2 = r->start;
+ hi2 = r->start + r->length;
+
+ nr = VEC_safe_push (mem_range_s, *result, NULL);
+
+ nr->start = max (lo1, lo2);
+ nr->length = min (hi1, hi2) - nr->start;
+ }
+
+ normalize_mem_ranges (*result);
+ return 1;
+ }
+
+ return 0;
+}
+
/* module initialization */
void
_initialize_tracepoint (void)