gdb/tracefile-tfile.c - gdb
 Global variables defined
 
 Data types defined
 
 Functions defined
 
 Macros defined
 
 Source code
  
 
 
 
 
 
 
- #include "defs.h"
 
- #include "tracefile.h"
 
- #include "readline/tilde.h"
 
- #include "filestuff.h"
 
- #include "rsp-low.h" 
- #include "regcache.h"
 
- #include "inferior.h"
 
- #include "gdbthread.h"
 
- #include "exec.h" 
- #include "completer.h"
 
- #include "filenames.h"
 
 
- #ifndef O_LARGEFILE
 
- #define O_LARGEFILE 0
 
- #endif
 
 
 
- struct tfile_trace_file_writer
 
- {
 
-   struct trace_file_writer base;
 
 
-   
-   FILE *fp;
 
-   
-   char *pathname;
 
- };
 
 
 
- static int
 
- tfile_target_save (struct trace_file_writer *self,
 
-                    const char *filename)
 
- {
 
-   int err = target_save_trace_data (filename);
 
 
-   return (err >= 0);
 
- }
 
 
 
- static void
 
- tfile_dtor (struct trace_file_writer *self)
 
- {
 
-   struct tfile_trace_file_writer *writer
 
-     = (struct tfile_trace_file_writer *) self;
 
 
-   xfree (writer->pathname);
 
 
-   if (writer->fp != NULL)
 
-     fclose (writer->fp);
 
- }
 
 
 
- static void
 
- tfile_start (struct trace_file_writer *self, const char *filename)
 
- {
 
-   struct tfile_trace_file_writer *writer
 
-     = (struct tfile_trace_file_writer *) self;
 
 
-   writer->pathname = tilde_expand (filename);
 
-   writer->fp = gdb_fopen_cloexec (writer->pathname, "wb");
 
-   if (writer->fp == NULL)
 
-     error (_("Unable to open file '%s' for saving trace data (%s)"),
 
-            writer->pathname, safe_strerror (errno));
 
- }
 
 
 
- static void
 
- tfile_write_header (struct trace_file_writer *self)
 
- {
 
-   struct tfile_trace_file_writer *writer
 
-     = (struct tfile_trace_file_writer *) self;
 
-   int written;
 
 
-   
-   written = fwrite ("\x7fTRACE0\n", 8, 1, writer->fp);
 
-   if (written < 1)
 
-     perror_with_name (writer->pathname);
 
- }
 
 
 
- static void
 
- tfile_write_regblock_type (struct trace_file_writer *self, int size)
 
- {
 
-   struct tfile_trace_file_writer *writer
 
-     = (struct tfile_trace_file_writer *) self;
 
 
-   fprintf (writer->fp, "R %x\n", size);
 
- }
 
 
 
- static void
 
- tfile_write_status (struct trace_file_writer *self,
 
-                     struct trace_status *ts)
 
- {
 
-   struct tfile_trace_file_writer *writer
 
-     = (struct tfile_trace_file_writer *) self;
 
 
-   fprintf (writer->fp, "status %c;%s",
 
-            (ts->running ? '1' : '0'), stop_reason_names[ts->stop_reason]);
 
-   if (ts->stop_reason == tracepoint_error
 
-       || ts->stop_reason == tstop_command)
 
-     {
 
-       char *buf = (char *) alloca (strlen (ts->stop_desc) * 2 + 1);
 
 
-       bin2hex ((gdb_byte *) ts->stop_desc, buf, strlen (ts->stop_desc));
 
-       fprintf (writer->fp, ":%s", buf);
 
-     }
 
-   fprintf (writer->fp, ":%x", ts->stopping_tracepoint);
 
-   if (ts->traceframe_count >= 0)
 
-     fprintf (writer->fp, ";tframes:%x", ts->traceframe_count);
 
-   if (ts->traceframes_created >= 0)
 
-     fprintf (writer->fp, ";tcreated:%x", ts->traceframes_created);
 
-   if (ts->buffer_free >= 0)
 
-     fprintf (writer->fp, ";tfree:%x", ts->buffer_free);
 
-   if (ts->buffer_size >= 0)
 
-     fprintf (writer->fp, ";tsize:%x", ts->buffer_size);
 
-   if (ts->disconnected_tracing)
 
-     fprintf (writer->fp, ";disconn:%x", ts->disconnected_tracing);
 
-   if (ts->circular_buffer)
 
-     fprintf (writer->fp, ";circular:%x", ts->circular_buffer);
 
-   if (ts->start_time)
 
-     {
 
-       fprintf (writer->fp, ";starttime:%s",
 
-       phex_nz (ts->start_time, sizeof (ts->start_time)));
 
-     }
 
-   if (ts->stop_time)
 
-     {
 
-       fprintf (writer->fp, ";stoptime:%s",
 
-       phex_nz (ts->stop_time, sizeof (ts->stop_time)));
 
-     }
 
-   if (ts->notes != NULL)
 
-     {
 
-       char *buf = (char *) alloca (strlen (ts->notes) * 2 + 1);
 
 
-       bin2hex ((gdb_byte *) ts->notes, buf, strlen (ts->notes));
 
-       fprintf (writer->fp, ";notes:%s", buf);
 
-     }
 
-   if (ts->user_name != NULL)
 
-     {
 
-       char *buf = (char *) alloca (strlen (ts->user_name) * 2 + 1);
 
 
-       bin2hex ((gdb_byte *) ts->user_name, buf, strlen (ts->user_name));
 
-       fprintf (writer->fp, ";username:%s", buf);
 
-     }
 
-   fprintf (writer->fp, "\n");
 
- }
 
 
 
- static void
 
- tfile_write_uploaded_tsv (struct trace_file_writer *self,
 
-                           struct uploaded_tsv *utsv)
 
- {
 
-   char *buf = "";
 
-   struct tfile_trace_file_writer *writer
 
-     = (struct tfile_trace_file_writer *) self;
 
 
-   if (utsv->name)
 
-     {
 
-       buf = (char *) xmalloc (strlen (utsv->name) * 2 + 1);
 
-       bin2hex ((gdb_byte *) (utsv->name), buf, strlen (utsv->name));
 
-     }
 
 
-   fprintf (writer->fp, "tsv %x:%s:%x:%s\n",
 
-            utsv->number, phex_nz (utsv->initial_value, 8),
 
-            utsv->builtin, buf);
 
 
-   if (utsv->name)
 
-     xfree (buf);
 
- }
 
 
- #define MAX_TRACE_UPLOAD 2000
 
 
 
- static void
 
- tfile_write_uploaded_tp (struct trace_file_writer *self,
 
-                          struct uploaded_tp *utp)
 
- {
 
-   struct tfile_trace_file_writer *writer
 
-     = (struct tfile_trace_file_writer *) self;
 
-   int a;
 
-   char *act;
 
-   char buf[MAX_TRACE_UPLOAD];
 
 
-   fprintf (writer->fp, "tp T%x:%s:%c:%x:%x",
 
-            utp->number, phex_nz (utp->addr, sizeof (utp->addr)),
 
-            (utp->enabled ? 'E' : 'D'), utp->step, utp->pass);
 
-   if (utp->type == bp_fast_tracepoint)
 
-     fprintf (writer->fp, ":F%x", utp->orig_size);
 
-   if (utp->cond)
 
-     fprintf (writer->fp,
 
-              ":X%x,%s", (unsigned int) strlen (utp->cond) / 2,
 
-              utp->cond);
 
-   fprintf (writer->fp, "\n");
 
-   for (a = 0; VEC_iterate (char_ptr, utp->actions, a, act); ++a)
 
-     fprintf (writer->fp, "tp A%x:%s:%s\n",
 
-              utp->number, phex_nz (utp->addr, sizeof (utp->addr)), act);
 
-   for (a = 0; VEC_iterate (char_ptr, utp->step_actions, a, act); ++a)
 
-     fprintf (writer->fp, "tp S%x:%s:%s\n",
 
-              utp->number, phex_nz (utp->addr, sizeof (utp->addr)), act);
 
-   if (utp->at_string)
 
-     {
 
-       encode_source_string (utp->number, utp->addr,
 
-                             "at", utp->at_string, buf, MAX_TRACE_UPLOAD);
 
-       fprintf (writer->fp, "tp Z%s\n", buf);
 
-     }
 
-   if (utp->cond_string)
 
-     {
 
-       encode_source_string (utp->number, utp->addr,
 
-                             "cond", utp->cond_string,
 
-                             buf, MAX_TRACE_UPLOAD);
 
-       fprintf (writer->fp, "tp Z%s\n", buf);
 
-     }
 
-   for (a = 0; VEC_iterate (char_ptr, utp->cmd_strings, a, act); ++a)
 
-     {
 
-       encode_source_string (utp->number, utp->addr, "cmd", act,
 
-                             buf, MAX_TRACE_UPLOAD);
 
-       fprintf (writer->fp, "tp Z%s\n", buf);
 
-     }
 
-   fprintf (writer->fp, "tp V%x:%s:%x:%s\n",
 
-            utp->number, phex_nz (utp->addr, sizeof (utp->addr)),
 
-            utp->hit_count,
 
-            phex_nz (utp->traceframe_usage,
 
-                     sizeof (utp->traceframe_usage)));
 
- }
 
 
 
- static void
 
- tfile_write_definition_end (struct trace_file_writer *self)
 
- {
 
-   struct tfile_trace_file_writer *writer
 
-     = (struct tfile_trace_file_writer *) self;
 
 
-   fprintf (writer->fp, "\n");
 
- }
 
 
 
- static void
 
- tfile_write_raw_data (struct trace_file_writer *self, gdb_byte *buf,
 
-                       LONGEST len)
 
- {
 
-   struct tfile_trace_file_writer *writer
 
-     = (struct tfile_trace_file_writer *) self;
 
 
-   if (fwrite (buf, len, 1, writer->fp) < 1)
 
-     perror_with_name (writer->pathname);
 
- }
 
 
 
- static void
 
- tfile_end (struct trace_file_writer *self)
 
- {
 
-   struct tfile_trace_file_writer *writer
 
-     = (struct tfile_trace_file_writer *) self;
 
-   uint32_t gotten = 0;
 
 
-   
-   if (fwrite (&gotten, 4, 1, writer->fp) < 1)
 
-     perror_with_name (writer->pathname);
 
- }
 
 
 
- static const struct trace_file_write_ops tfile_write_ops =
 
- {
 
-   tfile_dtor,
 
-   tfile_target_save,
 
-   tfile_start,
 
-   tfile_write_header,
 
-   tfile_write_regblock_type,
 
-   tfile_write_status,
 
-   tfile_write_uploaded_tsv,
 
-   tfile_write_uploaded_tp,
 
-   tfile_write_definition_end,
 
-   tfile_write_raw_data,
 
-   NULL,
 
-   tfile_end,
 
- };
 
 
 
- struct trace_file_writer *
 
- tfile_trace_file_writer_new (void)
 
- {
 
-   struct tfile_trace_file_writer *writer
 
-     = xmalloc (sizeof (struct tfile_trace_file_writer));
 
 
-   writer->base.ops = &tfile_write_ops;
 
-   writer->fp = NULL;
 
-   writer->pathname = NULL;
 
 
-   return (struct trace_file_writer *) writer;
 
- }
 
 
 
- static struct target_ops tfile_ops;
 
 
 
- #define TRACE_HEADER_SIZE 8
 
 
- #define TFILE_PID (1)
 
 
- static char *trace_filename;
 
- static int trace_fd = -1;
 
- static off_t trace_frames_offset;
 
- static off_t cur_offset;
 
- static int cur_data_size;
 
- int trace_regblock_size;
 
 
- static void tfile_interp_line (char *line,
 
-                                struct uploaded_tp **utpp,
 
-                                struct uploaded_tsv **utsvp);
 
 
 
- static void
 
- tfile_read (gdb_byte *readbuf, int size)
 
- {
 
-   int gotten;
 
 
-   gotten = read (trace_fd, readbuf, size);
 
-   if (gotten < 0)
 
-     perror_with_name (trace_filename);
 
-   else if (gotten < size)
 
-     error (_("Premature end of file while reading trace file"));
 
- }
 
 
- static void
 
- tfile_open (const char *arg, int from_tty)
 
- {
 
-   volatile struct gdb_exception ex;
 
-   char *temp;
 
-   struct cleanup *old_chain;
 
-   int flags;
 
-   int scratch_chan;
 
-   char header[TRACE_HEADER_SIZE];
 
-   char linebuf[1000]; 
-   gdb_byte byte;
 
-   int bytes, i;
 
-   struct trace_status *ts;
 
-   struct uploaded_tp *uploaded_tps = NULL;
 
-   struct uploaded_tsv *uploaded_tsvs = NULL;
 
-   char *filename;
 
 
-   target_preopen (from_tty);
 
-   if (!arg)
 
-     error (_("No trace file specified."));
 
 
-   filename = tilde_expand (arg);
 
-   if (!IS_ABSOLUTE_PATH(filename))
 
-     {
 
-       temp = concat (current_directory, "/", filename, (char *) NULL);
 
-       xfree (filename);
 
-       filename = temp;
 
-     }
 
 
-   old_chain = make_cleanup (xfree, filename);
 
 
-   flags = O_BINARY | O_LARGEFILE;
 
-   flags |= O_RDONLY;
 
-   scratch_chan = gdb_open_cloexec (filename, flags, 0);
 
-   if (scratch_chan < 0)
 
-     perror_with_name (filename);
 
 
-   
 
-   discard_cleanups (old_chain);        
-   unpush_target (&tfile_ops);
 
 
-   trace_filename = xstrdup (filename);
 
-   trace_fd = scratch_chan;
 
 
-   bytes = 0;
 
-   
-   tfile_read ((gdb_byte *) &header, TRACE_HEADER_SIZE);
 
 
-   bytes += TRACE_HEADER_SIZE;
 
-   if (!(header[0] == 0x7f
 
-         && (strncmp (header + 1, "TRACE0\n", 7) == 0)))
 
-     error (_("File is not a valid trace file."));
 
 
-   push_target (&tfile_ops);
 
 
-   trace_regblock_size = 0;
 
-   ts = current_trace_status ();
 
-   
-   ts->filename = trace_filename;
 
-   
-   ts->running_known = 0;
 
-   ts->stop_reason = trace_stop_reason_unknown;
 
-   ts->traceframe_count = -1;
 
-   ts->buffer_free = 0;
 
-   ts->disconnected_tracing = 0;
 
-   ts->circular_buffer = 0;
 
 
-   TRY_CATCH (ex, RETURN_MASK_ALL)
 
-     {
 
-       
-       i = 0;
 
-       while (1)
 
-         {
 
-           tfile_read (&byte, 1);
 
 
-           ++bytes;
 
-           if (byte == '\n')
 
-             {
 
-               
-               if (i == 0)
 
-                 break;
 
-               linebuf[i] = '\0';
 
-               i = 0;
 
-               tfile_interp_line (linebuf, &uploaded_tps, &uploaded_tsvs);
 
-             }
 
-           else
 
-             linebuf[i++] = byte;
 
-           if (i >= 1000)
 
-             error (_("Excessively long lines in trace file"));
 
-         }
 
 
-       
-       trace_frames_offset = bytes;
 
 
-       
-       if (trace_regblock_size == 0)
 
-         error (_("No register block size recorded in trace file"));
 
-     }
 
-   if (ex.reason < 0)
 
-     {
 
-       
-       unpush_target (&tfile_ops);
 
-       throw_exception (ex);
 
-     }
 
 
-   inferior_appeared (current_inferior (), TFILE_PID);
 
-   inferior_ptid = pid_to_ptid (TFILE_PID);
 
-   add_thread_silent (inferior_ptid);
 
 
-   if (ts->traceframe_count <= 0)
 
-     warning (_("No traceframes present in this file."));
 
 
-   
 
-   
-   merge_uploaded_trace_state_variables (&uploaded_tsvs);
 
 
-   merge_uploaded_tracepoints (&uploaded_tps);
 
 
-   post_create_inferior (&tfile_ops, from_tty);
 
- }
 
 
 
- static void
 
- tfile_interp_line (char *line, struct uploaded_tp **utpp,
 
-                    struct uploaded_tsv **utsvp)
 
- {
 
-   char *p = line;
 
 
-   if (strncmp (p, "R ", strlen ("R ")) == 0)
 
-     {
 
-       p += strlen ("R ");
 
-       trace_regblock_size = strtol (p, &p, 16);
 
-     }
 
-   else if (strncmp (p, "status ", strlen ("status ")) == 0)
 
-     {
 
-       p += strlen ("status ");
 
-       parse_trace_status (p, current_trace_status ());
 
-     }
 
-   else if (strncmp (p, "tp ", strlen ("tp ")) == 0)
 
-     {
 
-       p += strlen ("tp ");
 
-       parse_tracepoint_definition (p, utpp);
 
-     }
 
-   else if (strncmp (p, "tsv ", strlen ("tsv ")) == 0)
 
-     {
 
-       p += strlen ("tsv ");
 
-       parse_tsv_definition (p, utsvp);
 
-     }
 
-   else
 
-     warning (_("Ignoring trace file definition \"%s\""), line);
 
- }
 
 
 
- static void
 
- tfile_close (struct target_ops *self)
 
- {
 
-   int pid;
 
 
-   if (trace_fd < 0)
 
-     return;
 
 
-   pid = ptid_get_pid (inferior_ptid);
 
-   inferior_ptid = null_ptid;        
-   exit_inferior_silent (pid);
 
 
-   close (trace_fd);
 
-   trace_fd = -1;
 
-   xfree (trace_filename);
 
-   trace_filename = NULL;
 
 
-   trace_reset_local_state ();
 
- }
 
 
- static void
 
- tfile_files_info (struct target_ops *t)
 
- {
 
-   printf_filtered ("\t`%s'\n", trace_filename);
 
- }
 
 
- static void
 
- tfile_get_tracepoint_status (struct target_ops *self,
 
-                              struct breakpoint *tp, struct uploaded_tp *utp)
 
- {
 
-   
- }
 
 
 
- static CORE_ADDR
 
- tfile_get_traceframe_address (off_t tframe_offset)
 
- {
 
-   CORE_ADDR addr = 0;
 
-   short tpnum;
 
-   struct tracepoint *tp;
 
-   off_t saved_offset = cur_offset;
 
 
-   FIXME
 
-   
-   lseek (trace_fd, tframe_offset, SEEK_SET);
 
-   tfile_read ((gdb_byte *) &tpnum, 2);
 
-   tpnum = (short) extract_signed_integer ((gdb_byte *) &tpnum, 2,
 
-                                           gdbarch_byte_order
 
-                                               (target_gdbarch ()));
 
 
-   tp = get_tracepoint_by_number_on_target (tpnum);
 
-   FIXME
-   if (tp && tp->base.loc)
 
-     addr = tp->base.loc->address;
 
 
-   
-   cur_offset = saved_offset;
 
-   lseek (trace_fd, cur_offset, SEEK_SET);
 
-   return addr;
 
- }
 
 
 
- static int
 
- tfile_trace_find (struct target_ops *self, enum trace_find_type type, int num,
 
-                   CORE_ADDR addr1, CORE_ADDR addr2, int *tpp)
 
- {
 
-   short tpnum;
 
-   int tfnum = 0, found = 0;
 
-   unsigned int data_size;
 
-   struct tracepoint *tp;
 
-   off_t offset, tframe_offset;
 
-   CORE_ADDR tfaddr;
 
 
-   if (num == -1)
 
-     {
 
-       if (tpp)
 
-         *tpp = -1;
 
-       return -1;
 
-     }
 
 
-   lseek (trace_fd, trace_frames_offset, SEEK_SET);
 
-   offset = trace_frames_offset;
 
-   while (1)
 
-     {
 
-       tframe_offset = offset;
 
-       tfile_read ((gdb_byte *) &tpnum, 2);
 
-       tpnum = (short) extract_signed_integer ((gdb_byte *) &tpnum, 2,
 
-                                               gdbarch_byte_order
 
-                                                   (target_gdbarch ()));
 
-       offset += 2;
 
-       if (tpnum == 0)
 
-         break;
 
-       tfile_read ((gdb_byte *) &data_size, 4);
 
-       data_size = (unsigned int) extract_unsigned_integer
 
-                                      ((gdb_byte *) &data_size, 4,
 
-                                       gdbarch_byte_order (target_gdbarch ()));
 
-       offset += 4;
 
 
-       if (type == tfind_number)
 
-         {
 
-           
-           if (tfnum == num)
 
-             found = 1;
 
-         }
 
-       else
 
-         {
 
-           
-           if (tfnum > get_traceframe_number ())
 
-             {
 
-               switch (type)
 
-                 {
 
-                 case tfind_pc:
 
-                   tfaddr = tfile_get_traceframe_address (tframe_offset);
 
-                   if (tfaddr == addr1)
 
-                     found = 1;
 
-                   break;
 
-                 case tfind_tp:
 
-                   tp = get_tracepoint (num);
 
-                   if (tp && tpnum == tp->number_on_target)
 
-                     found = 1;
 
-                   break;
 
-                 case tfind_range:
 
-                   tfaddr = tfile_get_traceframe_address (tframe_offset);
 
-                   if (addr1 <= tfaddr && tfaddr <= addr2)
 
-                     found = 1;
 
-                   break;
 
-                 case tfind_outside:
 
-                   tfaddr = tfile_get_traceframe_address (tframe_offset);
 
-                   if (!(addr1 <= tfaddr && tfaddr <= addr2))
 
-                     found = 1;
 
-                   break;
 
-                 default:
 
-                   internal_error (__FILE__, __LINE__, _("unknown tfind type"));
 
-                 }
 
-             }
 
-         }
 
 
-       if (found)
 
-         {
 
-           if (tpp)
 
-             *tpp = tpnum;
 
-           cur_offset = offset;
 
-           cur_data_size = data_size;
 
 
-           return tfnum;
 
-         }
 
-       
-       lseek (trace_fd, data_size, SEEK_CUR);
 
-       offset += data_size;
 
-       
-       ++tfnum;
 
-     }
 
-   
-   if (tpp)
 
-     *tpp = -1;
 
-   return -1;
 
- }
 
 
- typedef int (*walk_blocks_callback_func) (char blocktype, void *data);
 
 
 
- static int
 
- match_blocktype (char blocktype, void *data)
 
- {
 
-   char *wantedp = data;
 
 
-   if (*wantedp == blocktype)
 
-     return 1;
 
 
-   return 0;
 
- }
 
 
 
- static int
 
- traceframe_walk_blocks (walk_blocks_callback_func callback,
 
-                         int pos, void *data)
 
- {
 
-   
 
-   lseek (trace_fd, cur_offset + pos, SEEK_SET);
 
-   while (pos < cur_data_size)
 
-     {
 
-       unsigned short mlen;
 
-       char block_type;
 
 
-       tfile_read ((gdb_byte *) &block_type, 1);
 
 
-       ++pos;
 
 
-       if ((*callback) (block_type, data))
 
-         return pos;
 
 
-       switch (block_type)
 
-         {
 
-         case 'R':
 
-           lseek (trace_fd, cur_offset + pos + trace_regblock_size, SEEK_SET);
 
-           pos += trace_regblock_size;
 
-           break;
 
-         case 'M':
 
-           lseek (trace_fd, cur_offset + pos + 8, SEEK_SET);
 
-           tfile_read ((gdb_byte *) &mlen, 2);
 
-           mlen = (unsigned short)
 
-                 extract_unsigned_integer ((gdb_byte *) &mlen, 2,
 
-                                           gdbarch_byte_order
 
-                                               (target_gdbarch ()));
 
-           lseek (trace_fd, mlen, SEEK_CUR);
 
-           pos += (8 + 2 + mlen);
 
-           break;
 
-         case 'V':
 
-           lseek (trace_fd, cur_offset + pos + 4 + 8, SEEK_SET);
 
-           pos += (4 + 8);
 
-           break;
 
-         default:
 
-           error (_("Unknown block type '%c' (0x%x) in trace frame"),
 
-                  block_type, block_type);
 
-           break;
 
-         }
 
-     }
 
 
-   return -1;
 
- }
 
 
 
- static int
 
- traceframe_find_block_type (char type_wanted, int pos)
 
- {
 
-   return traceframe_walk_blocks (match_blocktype, pos, &type_wanted);
 
- }
 
 
 
- static void
 
- tfile_fetch_registers (struct target_ops *ops,
 
-                        struct regcache *regcache, int regno)
 
- {
 
-   struct gdbarch *gdbarch = get_regcache_arch (regcache);
 
-   int offset, regn, regsize;
 
 
-   
-   if (!trace_regblock_size)
 
-     return;
 
 
-   if (traceframe_find_block_type ('R', 0) >= 0)
 
-     {
 
-       gdb_byte *regs = alloca (trace_regblock_size);
 
 
-       tfile_read (regs, trace_regblock_size);
 
 
-       
-       offset = 0;
 
-       for (regn = 0; regn < gdbarch_num_regs (gdbarch); regn++)
 
-         {
 
-           regsize = register_size (gdbarch, regn);
 
-           
-           if (offset + regsize >= trace_regblock_size)
 
-             break;
 
-           if (regcache_register_status (regcache, regn) == REG_UNKNOWN)
 
-             {
 
-               if (regno == regn)
 
-                 {
 
-                   regcache_raw_supply (regcache, regno, regs + offset);
 
-                   break;
 
-                 }
 
-               else if (regno == -1)
 
-                 {
 
-                   regcache_raw_supply (regcache, regn, regs + offset);
 
-                 }
 
-             }
 
-           offset += regsize;
 
-         }
 
-     }
 
-   else
 
-     tracefile_fetch_registers (regcache, regno);
 
- }
 
 
- static enum target_xfer_status
 
- tfile_xfer_partial (struct target_ops *ops, enum target_object object,
 
-                     const char *annex, gdb_byte *readbuf,
 
-                     const gdb_byte *writebuf, ULONGEST offset, ULONGEST len,
 
-                     ULONGEST *xfered_len)
 
- {
 
-   
-   if (object != TARGET_OBJECT_MEMORY)
 
-     return TARGET_XFER_E_IO;
 
 
-   if (readbuf == NULL)
 
-     error (_("tfile_xfer_partial: trace file is read-only"));
 
 
-   if (get_traceframe_number () != -1)
 
-     {
 
-       int pos = 0;
 
-       enum target_xfer_status res;
 
-       
-       ULONGEST low_addr_available = 0;
 
 
-       
-       while ((pos = traceframe_find_block_type ('M', pos)) >= 0)
 
-         {
 
-           ULONGEST maddr, amt;
 
-           unsigned short mlen;
 
-           enum bfd_endian byte_order = gdbarch_byte_order (target_gdbarch ());
 
 
-           tfile_read ((gdb_byte *) &maddr, 8);
 
-           maddr = extract_unsigned_integer ((gdb_byte *) &maddr, 8,
 
-                                             byte_order);
 
-           tfile_read ((gdb_byte *) &mlen, 2);
 
-           mlen = (unsigned short)
 
-             extract_unsigned_integer ((gdb_byte *) &mlen, 2, byte_order);
 
 
-           
-           if (maddr <= offset && offset < (maddr + mlen))
 
-             {
 
-               amt = (maddr + mlen) - offset;
 
-               if (amt > len)
 
-                 amt = len;
 
 
-               if (maddr != offset)
 
-                 lseek (trace_fd, offset - maddr, SEEK_CUR);
 
-               tfile_read (readbuf, amt);
 
-               *xfered_len = amt;
 
-               return TARGET_XFER_OK;
 
-             }
 
 
-           if (offset < maddr && maddr < (offset + len))
 
-             if (low_addr_available == 0 || low_addr_available > maddr)
 
-               low_addr_available = maddr;
 
 
-           
-           pos += (8 + 2 + mlen);
 
-         }
 
 
-       
-       if (offset < low_addr_available)
 
-         len = min (len, low_addr_available - offset);
 
-       res = exec_read_partial_read_only (readbuf, offset, len, xfered_len);
 
 
-       if (res == TARGET_XFER_OK)
 
-         return TARGET_XFER_OK;
 
-       else
 
-         {
 
-           
-           *xfered_len = len;
 
-           return TARGET_XFER_UNAVAILABLE;
 
-         }
 
-     }
 
-   else
 
-     {
 
-       
-       return section_table_read_available_memory (readbuf, offset, len,
 
-                                                   xfered_len);
 
-     }
 
- }
 
 
 
- static int
 
- tfile_get_trace_state_variable_value (struct target_ops *self,
 
-                                       int tsvnum, LONGEST *val)
 
- {
 
-   int pos;
 
-   int found = 0;
 
 
-   
-   pos = 0;
 
-   while ((pos = traceframe_find_block_type ('V', pos)) >= 0)
 
-     {
 
-       int vnum;
 
 
-       tfile_read ((gdb_byte *) &vnum, 4);
 
-       vnum = (int) extract_signed_integer ((gdb_byte *) &vnum, 4,
 
-                                            gdbarch_byte_order
 
-                                            (target_gdbarch ()));
 
-       if (tsvnum == vnum)
 
-         {
 
-           tfile_read ((gdb_byte *) val, 8);
 
-           *val = extract_signed_integer ((gdb_byte *) val, 8,
 
-                                          gdbarch_byte_order
 
-                                          (target_gdbarch ()));
 
-           found = 1;
 
-         }
 
-       pos += (4 + 8);
 
-     }
 
 
-   return found;
 
- }
 
 
 
- static int
 
- build_traceframe_info (char blocktype, void *data)
 
- {
 
-   struct traceframe_info *info = data;
 
 
-   switch (blocktype)
 
-     {
 
-     case 'M':
 
-       {
 
-         struct mem_range *r;
 
-         ULONGEST maddr;
 
-         unsigned short mlen;
 
 
-         tfile_read ((gdb_byte *) &maddr, 8);
 
-         maddr = extract_unsigned_integer ((gdb_byte *) &maddr, 8,
 
-                                           gdbarch_byte_order
 
-                                           (target_gdbarch ()));
 
-         tfile_read ((gdb_byte *) &mlen, 2);
 
-         mlen = (unsigned short)
 
-                 extract_unsigned_integer ((gdb_byte *) &mlen,
 
-                                           2, gdbarch_byte_order
 
-                                           (target_gdbarch ()));
 
 
-         r = VEC_safe_push (mem_range_s, info->memory, NULL);
 
 
-         r->start = maddr;
 
-         r->length = mlen;
 
-         break;
 
-       }
 
-     case 'V':
 
-       {
 
-         int vnum;
 
 
-         tfile_read ((gdb_byte *) &vnum, 4);
 
-         VEC_safe_push (int, info->tvars, vnum);
 
-       }
 
-     case 'R':
 
-     case 'S':
 
-       {
 
-         break;
 
-       }
 
-     default:
 
-       warning (_("Unhandled trace block type (%d) '%c ' "
 
-                  "while building trace frame info."),
 
-                blocktype, blocktype);
 
-       break;
 
-     }
 
 
-   return 0;
 
- }
 
 
- static struct traceframe_info *
 
- tfile_traceframe_info (struct target_ops *self)
 
- {
 
-   struct traceframe_info *info = XCNEW (struct traceframe_info);
 
 
-   traceframe_walk_blocks (build_traceframe_info, 0, info);
 
-   return info;
 
- }
 
 
- static void
 
- init_tfile_ops (void)
 
- {
 
-   init_tracefile_ops (&tfile_ops);
 
 
-   tfile_ops.to_shortname = "tfile";
 
-   tfile_ops.to_longname = "Local trace dump file";
 
-   tfile_ops.to_doc
 
-     = "Use a trace file as a target.  Specify the filename of the trace file.";
 
-   tfile_ops.to_open = tfile_open;
 
-   tfile_ops.to_close = tfile_close;
 
-   tfile_ops.to_fetch_registers = tfile_fetch_registers;
 
-   tfile_ops.to_xfer_partial = tfile_xfer_partial;
 
-   tfile_ops.to_files_info = tfile_files_info;
 
-   tfile_ops.to_get_tracepoint_status = tfile_get_tracepoint_status;
 
-   tfile_ops.to_trace_find = tfile_trace_find;
 
-   tfile_ops.to_get_trace_state_variable_value
 
-     = tfile_get_trace_state_variable_value;
 
-   tfile_ops.to_traceframe_info = tfile_traceframe_info;
 
- }
 
 
- extern initialize_file_ftype _initialize_tracefile_tfile;
 
 
- void
 
- _initialize_tracefile_tfile (void)
 
- {
 
-   init_tfile_ops ();
 
 
-   add_target_with_completer (&tfile_ops, filename_completer);
 
- }