/* Trace file support in GDB.
- Copyright (C) 1997-2016 Free Software Foundation, Inc.
+ Copyright (C) 1997-2017 Free Software Foundation, Inc.
This file is part of GDB.
int target_does_save)
{
struct trace_status *ts = current_trace_status ();
- int status;
struct uploaded_tp *uploaded_tps = NULL, *utp;
struct uploaded_tsv *uploaded_tsvs = NULL, *utsv;
ULONGEST offset = 0;
#define MAX_TRACE_UPLOAD 2000
gdb_byte buf[MAX_TRACE_UPLOAD];
- int written;
enum bfd_endian byte_order = gdbarch_byte_order (target_gdbarch ());
/* If the target is to save the data to a file on its own, then just
}
/* Get the trace status first before opening the file, so if the
- target is losing, we can get out without touching files. */
- status = target_get_trace_status (ts);
+ target is losing, we can get out without touching files. Since
+ we're just calling this for side effects, we ignore the
+ result. */
+ target_get_trace_status (ts);
writer->ops->start (writer, filename);
/* Write out the size of a register block. */
writer->ops->write_regblock_type (writer, trace_regblock_size);
+ /* Write out the target description info. */
+ writer->ops->write_tdesc (writer);
+
/* Write out status of the tracing run (aka "tstatus" info). */
writer->ops->write_status (writer, ts);
}
static void
-trace_save_command (char *args, int from_tty)
+tsave_command (char *args, int from_tty)
{
int target_does_save = 0;
char **argv;
if (args == NULL)
error_no_arg (_("file in which to save trace data"));
- argv = gdb_buildargv (args);
- back_to = make_cleanup_freeargv (argv);
+ gdb_argv built_argv (args);
+ argv = built_argv.get ();
for (; *argv; ++argv)
{
if (strcmp (*argv, "-r") == 0)
target_does_save = 1;
- if (strcmp (*argv, "-ctf") == 0)
+ else if (strcmp (*argv, "-ctf") == 0)
generate_ctf = 1;
else if (**argv == '-')
error (_("unknown option `%s'"), *argv);
else
writer = tfile_trace_file_writer_new ();
- make_cleanup (trace_file_writer_xfree, writer);
+ back_to = make_cleanup (trace_file_writer_xfree, writer);
trace_save (filename, writer, target_does_save);
tracefile_fetch_registers (struct regcache *regcache, int regno)
{
struct gdbarch *gdbarch = get_regcache_arch (regcache);
- int regn, pc_regno;
+ struct tracepoint *tp = get_tracepoint (get_tracepoint_number ());
+ int regn;
/* We get here if no register data has been found. Mark registers
as unavailable. */
/* We can often usefully guess that the PC is going to be the same
as the address of the tracepoint. */
- pc_regno = gdbarch_pc_regnum (gdbarch);
-
- /* XXX This guessing code below only works if the PC register isn't
- a pseudo-register. The value of a pseudo-register isn't stored
- in the (non-readonly) regcache -- instead it's recomputed
- (probably from some other cached raw register) whenever the
- register is read. This guesswork should probably move to some
- higher layer. */
- if (pc_regno < 0 || pc_regno >= gdbarch_num_regs (gdbarch))
+ if (tp == NULL || tp->loc == NULL)
return;
- if (regno == -1 || regno == pc_regno)
+ /* But don't try to guess if tracepoint is multi-location... */
+ if (tp->loc->next)
{
- struct tracepoint *tp = get_tracepoint (get_tracepoint_number ());
- gdb_byte *regs;
-
- if (tp && tp->base.loc)
- {
- /* But don't try to guess if tracepoint is multi-location... */
- if (tp->base.loc->next)
- {
- warning (_("Tracepoint %d has multiple "
- "locations, cannot infer $pc"),
- tp->base.number);
- return;
- }
- /* ... or does while-stepping. */
- if (tp->step_count > 0)
- {
- warning (_("Tracepoint %d does while-stepping, "
- "cannot infer $pc"),
- tp->base.number);
- return;
- }
-
- regs = (gdb_byte *) alloca (register_size (gdbarch, pc_regno));
- store_unsigned_integer (regs, register_size (gdbarch, pc_regno),
- gdbarch_byte_order (gdbarch),
- tp->base.loc->address);
- regcache_raw_supply (regcache, pc_regno, regs);
- }
+ warning (_("Tracepoint %d has multiple "
+ "locations, cannot infer $pc"),
+ tp->number);
+ return;
}
+ /* ... or does while-stepping. */
+ else if (tp->step_count > 0)
+ {
+ warning (_("Tracepoint %d does while-stepping, "
+ "cannot infer $pc"),
+ tp->number);
+ return;
+ }
+
+ /* Guess what we can from the tracepoint location. */
+ gdbarch_guess_tracepoint_registers (gdbarch, regcache,
+ tp->loc->address);
}
/* This is the implementation of target_ops method to_has_all_memory. */
void
_initialize_tracefile (void)
{
- add_com ("tsave", class_trace, trace_save_command, _("\
+ add_com ("tsave", class_trace, tsave_command, _("\
Save the trace data to a file.\n\
Use the '-ctf' option to save the data to CTF format.\n\
Use the '-r' option to direct the target to save directly to the file,\n\