Convert struct target_ops to C++
[external/binutils.git] / gdb / tracefile-tfile.c
1 /* Trace file TFILE format support in GDB.
2
3    Copyright (C) 1997-2018 Free Software Foundation, Inc.
4
5    This file is part of GDB.
6
7    This program is free software; you can redistribute it and/or modify
8    it under the terms of the GNU General Public License as published by
9    the Free Software Foundation; either version 3 of the License, or
10    (at your option) any later version.
11
12    This program is distributed in the hope that it will be useful,
13    but WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15    GNU General Public License for more details.
16
17    You should have received a copy of the GNU General Public License
18    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
19
20 #include "defs.h"
21 #include "tracefile.h"
22 #include "readline/tilde.h"
23 #include "filestuff.h"
24 #include "rsp-low.h" /* bin2hex */
25 #include "regcache.h"
26 #include "inferior.h"
27 #include "gdbthread.h"
28 #include "exec.h" /* exec_bfd */
29 #include "completer.h"
30 #include "filenames.h"
31 #include "remote.h"
32 #include "xml-tdesc.h"
33 #include "target-descriptions.h"
34 #include "buffer.h"
35 #include <algorithm>
36
37 #ifndef O_LARGEFILE
38 #define O_LARGEFILE 0
39 #endif
40
41 /* The tfile target.  */
42
43 class tfile_target final : public tracefile_target
44 {
45  public:
46   const char *shortname () override
47   { return "tfile"; }
48
49   const char *longname () override
50   { return _("Local trace dump file"); }
51
52   const char *doc () override
53   {
54     return _("\
55 Use a trace file as a target.  Specify the filename of the trace file.");
56   }
57
58   void open (const char *, int) override;
59   void close () override;
60   void fetch_registers (struct regcache *, int) override;
61   enum target_xfer_status xfer_partial (enum target_object object,
62                                                 const char *annex,
63                                                 gdb_byte *readbuf,
64                                                 const gdb_byte *writebuf,
65                                                 ULONGEST offset, ULONGEST len,
66                                                 ULONGEST *xfered_len) override;
67   void files_info () override;
68   int trace_find (enum trace_find_type type, int num,
69                           CORE_ADDR addr1, CORE_ADDR addr2, int *tpp) override;
70   int get_trace_state_variable_value (int tsv, LONGEST *val) override;
71   traceframe_info_up traceframe_info () override;
72
73   void get_tracepoint_status (struct breakpoint *tp,
74                               struct uploaded_tp *utp) override;
75 };
76
77 /* TFILE trace writer.  */
78
79 struct tfile_trace_file_writer
80 {
81   struct trace_file_writer base;
82
83   /* File pointer to tfile trace file.  */
84   FILE *fp;
85   /* Path name of the tfile trace file.  */
86   char *pathname;
87 };
88
89 /* This is the implementation of trace_file_write_ops method
90    target_save.  We just call the generic target
91    target_save_trace_data to do target-side saving.  */
92
93 static int
94 tfile_target_save (struct trace_file_writer *self,
95                    const char *filename)
96 {
97   int err = target_save_trace_data (filename);
98
99   return (err >= 0);
100 }
101
102 /* This is the implementation of trace_file_write_ops method
103    dtor.  */
104
105 static void
106 tfile_dtor (struct trace_file_writer *self)
107 {
108   struct tfile_trace_file_writer *writer
109     = (struct tfile_trace_file_writer *) self;
110
111   xfree (writer->pathname);
112
113   if (writer->fp != NULL)
114     fclose (writer->fp);
115 }
116
117 /* This is the implementation of trace_file_write_ops method
118    start.  It creates the trace file FILENAME and registers some
119    cleanups.  */
120
121 static void
122 tfile_start (struct trace_file_writer *self, const char *filename)
123 {
124   struct tfile_trace_file_writer *writer
125     = (struct tfile_trace_file_writer *) self;
126
127   writer->pathname = tilde_expand (filename);
128   writer->fp = gdb_fopen_cloexec (writer->pathname, "wb").release ();
129   if (writer->fp == NULL)
130     error (_("Unable to open file '%s' for saving trace data (%s)"),
131            writer->pathname, safe_strerror (errno));
132 }
133
134 /* This is the implementation of trace_file_write_ops method
135    write_header.  Write the TFILE header.  */
136
137 static void
138 tfile_write_header (struct trace_file_writer *self)
139 {
140   struct tfile_trace_file_writer *writer
141     = (struct tfile_trace_file_writer *) self;
142   int written;
143
144   /* Write a file header, with a high-bit-set char to indicate a
145      binary file, plus a hint as what this file is, and a version
146      number in case of future needs.  */
147   written = fwrite ("\x7fTRACE0\n", 8, 1, writer->fp);
148   if (written < 1)
149     perror_with_name (writer->pathname);
150 }
151
152 /* This is the implementation of trace_file_write_ops method
153    write_regblock_type.  Write the size of register block.  */
154
155 static void
156 tfile_write_regblock_type (struct trace_file_writer *self, int size)
157 {
158   struct tfile_trace_file_writer *writer
159     = (struct tfile_trace_file_writer *) self;
160
161   fprintf (writer->fp, "R %x\n", size);
162 }
163
164 /* This is the implementation of trace_file_write_ops method
165    write_status.  */
166
167 static void
168 tfile_write_status (struct trace_file_writer *self,
169                     struct trace_status *ts)
170 {
171   struct tfile_trace_file_writer *writer
172     = (struct tfile_trace_file_writer *) self;
173
174   fprintf (writer->fp, "status %c;%s",
175            (ts->running ? '1' : '0'), stop_reason_names[ts->stop_reason]);
176   if (ts->stop_reason == tracepoint_error
177       || ts->stop_reason == trace_stop_command)
178     {
179       char *buf = (char *) alloca (strlen (ts->stop_desc) * 2 + 1);
180
181       bin2hex ((gdb_byte *) ts->stop_desc, buf, strlen (ts->stop_desc));
182       fprintf (writer->fp, ":%s", buf);
183     }
184   fprintf (writer->fp, ":%x", ts->stopping_tracepoint);
185   if (ts->traceframe_count >= 0)
186     fprintf (writer->fp, ";tframes:%x", ts->traceframe_count);
187   if (ts->traceframes_created >= 0)
188     fprintf (writer->fp, ";tcreated:%x", ts->traceframes_created);
189   if (ts->buffer_free >= 0)
190     fprintf (writer->fp, ";tfree:%x", ts->buffer_free);
191   if (ts->buffer_size >= 0)
192     fprintf (writer->fp, ";tsize:%x", ts->buffer_size);
193   if (ts->disconnected_tracing)
194     fprintf (writer->fp, ";disconn:%x", ts->disconnected_tracing);
195   if (ts->circular_buffer)
196     fprintf (writer->fp, ";circular:%x", ts->circular_buffer);
197   if (ts->start_time)
198     {
199       fprintf (writer->fp, ";starttime:%s",
200       phex_nz (ts->start_time, sizeof (ts->start_time)));
201     }
202   if (ts->stop_time)
203     {
204       fprintf (writer->fp, ";stoptime:%s",
205       phex_nz (ts->stop_time, sizeof (ts->stop_time)));
206     }
207   if (ts->notes != NULL)
208     {
209       char *buf = (char *) alloca (strlen (ts->notes) * 2 + 1);
210
211       bin2hex ((gdb_byte *) ts->notes, buf, strlen (ts->notes));
212       fprintf (writer->fp, ";notes:%s", buf);
213     }
214   if (ts->user_name != NULL)
215     {
216       char *buf = (char *) alloca (strlen (ts->user_name) * 2 + 1);
217
218       bin2hex ((gdb_byte *) ts->user_name, buf, strlen (ts->user_name));
219       fprintf (writer->fp, ";username:%s", buf);
220     }
221   fprintf (writer->fp, "\n");
222 }
223
224 /* This is the implementation of trace_file_write_ops method
225    write_uploaded_tsv.  */
226
227 static void
228 tfile_write_uploaded_tsv (struct trace_file_writer *self,
229                           struct uploaded_tsv *utsv)
230 {
231   char *buf = NULL;
232   struct tfile_trace_file_writer *writer
233     = (struct tfile_trace_file_writer *) self;
234
235   if (utsv->name)
236     {
237       buf = (char *) xmalloc (strlen (utsv->name) * 2 + 1);
238       bin2hex ((gdb_byte *) (utsv->name), buf, strlen (utsv->name));
239     }
240
241   fprintf (writer->fp, "tsv %x:%s:%x:%s\n",
242            utsv->number, phex_nz (utsv->initial_value, 8),
243            utsv->builtin, buf != NULL ? buf : "");
244
245   if (utsv->name)
246     xfree (buf);
247 }
248
249 #define MAX_TRACE_UPLOAD 2000
250
251 /* This is the implementation of trace_file_write_ops method
252    write_uploaded_tp.  */
253
254 static void
255 tfile_write_uploaded_tp (struct trace_file_writer *self,
256                          struct uploaded_tp *utp)
257 {
258   struct tfile_trace_file_writer *writer
259     = (struct tfile_trace_file_writer *) self;
260   char buf[MAX_TRACE_UPLOAD];
261
262   fprintf (writer->fp, "tp T%x:%s:%c:%x:%x",
263            utp->number, phex_nz (utp->addr, sizeof (utp->addr)),
264            (utp->enabled ? 'E' : 'D'), utp->step, utp->pass);
265   if (utp->type == bp_fast_tracepoint)
266     fprintf (writer->fp, ":F%x", utp->orig_size);
267   if (utp->cond)
268     fprintf (writer->fp,
269              ":X%x,%s", (unsigned int) strlen (utp->cond) / 2,
270              utp->cond);
271   fprintf (writer->fp, "\n");
272   for (char *act : utp->actions)
273     fprintf (writer->fp, "tp A%x:%s:%s\n",
274              utp->number, phex_nz (utp->addr, sizeof (utp->addr)), act);
275   for (char *act : utp->step_actions)
276     fprintf (writer->fp, "tp S%x:%s:%s\n",
277              utp->number, phex_nz (utp->addr, sizeof (utp->addr)), act);
278   if (utp->at_string)
279     {
280       encode_source_string (utp->number, utp->addr,
281                             "at", utp->at_string, buf, MAX_TRACE_UPLOAD);
282       fprintf (writer->fp, "tp Z%s\n", buf);
283     }
284   if (utp->cond_string)
285     {
286       encode_source_string (utp->number, utp->addr,
287                             "cond", utp->cond_string,
288                             buf, MAX_TRACE_UPLOAD);
289       fprintf (writer->fp, "tp Z%s\n", buf);
290     }
291   for (char *act : utp->cmd_strings)
292     {
293       encode_source_string (utp->number, utp->addr, "cmd", act,
294                             buf, MAX_TRACE_UPLOAD);
295       fprintf (writer->fp, "tp Z%s\n", buf);
296     }
297   fprintf (writer->fp, "tp V%x:%s:%x:%s\n",
298            utp->number, phex_nz (utp->addr, sizeof (utp->addr)),
299            utp->hit_count,
300            phex_nz (utp->traceframe_usage,
301                     sizeof (utp->traceframe_usage)));
302 }
303
304 /* This is the implementation of trace_file_write_ops method
305    write_tdesc.  */
306
307 static void
308 tfile_write_tdesc (struct trace_file_writer *self)
309 {
310   struct tfile_trace_file_writer *writer
311     = (struct tfile_trace_file_writer *) self;
312
313   gdb::optional<std::string> tdesc
314     = target_fetch_description_xml (target_stack);
315
316   if (!tdesc)
317     return;
318
319   const char *ptr = tdesc->c_str ();
320
321   /* Write tdesc line by line, prefixing each line with "tdesc ".  */
322   while (ptr != NULL)
323     {
324       const char *next = strchr (ptr, '\n');
325       if (next != NULL)
326         {
327           fprintf (writer->fp, "tdesc %.*s\n", (int) (next - ptr), ptr);
328           /* Skip the \n.  */
329           next++;
330         }
331       else if (*ptr != '\0')
332         {
333           /* Last line, doesn't have a newline.  */
334           fprintf (writer->fp, "tdesc %s\n", ptr);
335         }
336       ptr = next;
337     }
338 }
339
340 /* This is the implementation of trace_file_write_ops method
341    write_definition_end.  */
342
343 static void
344 tfile_write_definition_end (struct trace_file_writer *self)
345 {
346   struct tfile_trace_file_writer *writer
347     = (struct tfile_trace_file_writer *) self;
348
349   fprintf (writer->fp, "\n");
350 }
351
352 /* This is the implementation of trace_file_write_ops method
353    write_raw_data.  */
354
355 static void
356 tfile_write_raw_data (struct trace_file_writer *self, gdb_byte *buf,
357                       LONGEST len)
358 {
359   struct tfile_trace_file_writer *writer
360     = (struct tfile_trace_file_writer *) self;
361
362   if (fwrite (buf, len, 1, writer->fp) < 1)
363     perror_with_name (writer->pathname);
364 }
365
366 /* This is the implementation of trace_file_write_ops method
367    end.  */
368
369 static void
370 tfile_end (struct trace_file_writer *self)
371 {
372   struct tfile_trace_file_writer *writer
373     = (struct tfile_trace_file_writer *) self;
374   uint32_t gotten = 0;
375
376   /* Mark the end of trace data.  */
377   if (fwrite (&gotten, 4, 1, writer->fp) < 1)
378     perror_with_name (writer->pathname);
379 }
380
381 /* Operations to write trace buffers into TFILE format.  */
382
383 static const struct trace_file_write_ops tfile_write_ops =
384 {
385   tfile_dtor,
386   tfile_target_save,
387   tfile_start,
388   tfile_write_header,
389   tfile_write_regblock_type,
390   tfile_write_status,
391   tfile_write_uploaded_tsv,
392   tfile_write_uploaded_tp,
393   tfile_write_tdesc,
394   tfile_write_definition_end,
395   tfile_write_raw_data,
396   NULL,
397   tfile_end,
398 };
399
400 /* Return a trace writer for TFILE format.  */
401
402 struct trace_file_writer *
403 tfile_trace_file_writer_new (void)
404 {
405   struct tfile_trace_file_writer *writer
406     = XNEW (struct tfile_trace_file_writer);
407
408   writer->base.ops = &tfile_write_ops;
409   writer->fp = NULL;
410   writer->pathname = NULL;
411
412   return (struct trace_file_writer *) writer;
413 }
414
415 /* target tfile command */
416
417 static tfile_target tfile_ops;
418
419 #define TRACE_HEADER_SIZE 8
420
421 #define TFILE_PID (1)
422
423 static char *trace_filename;
424 static int trace_fd = -1;
425 static off_t trace_frames_offset;
426 static off_t cur_offset;
427 static int cur_data_size;
428 int trace_regblock_size;
429 static struct buffer trace_tdesc;
430
431 static void tfile_append_tdesc_line (const char *line);
432 static void tfile_interp_line (char *line,
433                                struct uploaded_tp **utpp,
434                                struct uploaded_tsv **utsvp);
435
436 /* Read SIZE bytes into READBUF from the trace frame, starting at
437    TRACE_FD's current position.  Note that this call `read'
438    underneath, hence it advances the file's seek position.  Throws an
439    error if the `read' syscall fails, or less than SIZE bytes are
440    read.  */
441
442 static void
443 tfile_read (gdb_byte *readbuf, int size)
444 {
445   int gotten;
446
447   gotten = read (trace_fd, readbuf, size);
448   if (gotten < 0)
449     perror_with_name (trace_filename);
450   else if (gotten < size)
451     error (_("Premature end of file while reading trace file"));
452 }
453
454 void
455 tfile_target::open (const char *arg, int from_tty)
456 {
457   int flags;
458   int scratch_chan;
459   char header[TRACE_HEADER_SIZE];
460   char linebuf[1000]; /* Should be max remote packet size or so.  */
461   gdb_byte byte;
462   int bytes, i;
463   struct trace_status *ts;
464   struct uploaded_tp *uploaded_tps = NULL;
465   struct uploaded_tsv *uploaded_tsvs = NULL;
466
467   target_preopen (from_tty);
468   if (!arg)
469     error (_("No trace file specified."));
470
471   gdb::unique_xmalloc_ptr<char> filename (tilde_expand (arg));
472   if (!IS_ABSOLUTE_PATH (filename.get ()))
473     filename.reset (concat (current_directory, "/", filename.get (),
474                             (char *) NULL));
475
476   flags = O_BINARY | O_LARGEFILE;
477   flags |= O_RDONLY;
478   scratch_chan = gdb_open_cloexec (filename.get (), flags, 0);
479   if (scratch_chan < 0)
480     perror_with_name (filename.get ());
481
482   /* Looks semi-reasonable.  Toss the old trace file and work on the new.  */
483
484   unpush_target (&tfile_ops);
485
486   trace_filename = filename.release ();
487   trace_fd = scratch_chan;
488
489   /* Make sure this is clear.  */
490   buffer_free (&trace_tdesc);
491
492   bytes = 0;
493   /* Read the file header and test for validity.  */
494   tfile_read ((gdb_byte *) &header, TRACE_HEADER_SIZE);
495
496   bytes += TRACE_HEADER_SIZE;
497   if (!(header[0] == 0x7f
498         && (startswith (header + 1, "TRACE0\n"))))
499     error (_("File is not a valid trace file."));
500
501   push_target (&tfile_ops);
502
503   trace_regblock_size = 0;
504   ts = current_trace_status ();
505   /* We know we're working with a file.  Record its name.  */
506   ts->filename = trace_filename;
507   /* Set defaults in case there is no status line.  */
508   ts->running_known = 0;
509   ts->stop_reason = trace_stop_reason_unknown;
510   ts->traceframe_count = -1;
511   ts->buffer_free = 0;
512   ts->disconnected_tracing = 0;
513   ts->circular_buffer = 0;
514
515   TRY
516     {
517       /* Read through a section of newline-terminated lines that
518          define things like tracepoints.  */
519       i = 0;
520       while (1)
521         {
522           tfile_read (&byte, 1);
523
524           ++bytes;
525           if (byte == '\n')
526             {
527               /* Empty line marks end of the definition section.  */
528               if (i == 0)
529                 break;
530               linebuf[i] = '\0';
531               i = 0;
532               tfile_interp_line (linebuf, &uploaded_tps, &uploaded_tsvs);
533             }
534           else
535             linebuf[i++] = byte;
536           if (i >= 1000)
537             error (_("Excessively long lines in trace file"));
538         }
539
540       /* By now, tdesc lines have been read from tfile - let's parse them.  */
541       target_find_description ();
542
543       /* Record the starting offset of the binary trace data.  */
544       trace_frames_offset = bytes;
545
546       /* If we don't have a blocksize, we can't interpret the
547          traceframes.  */
548       if (trace_regblock_size == 0)
549         error (_("No register block size recorded in trace file"));
550     }
551   CATCH (ex, RETURN_MASK_ALL)
552     {
553       /* Remove the partially set up target.  */
554       unpush_target (&tfile_ops);
555       throw_exception (ex);
556     }
557   END_CATCH
558
559   inferior_appeared (current_inferior (), TFILE_PID);
560   inferior_ptid = pid_to_ptid (TFILE_PID);
561   add_thread_silent (inferior_ptid);
562
563   if (ts->traceframe_count <= 0)
564     warning (_("No traceframes present in this file."));
565
566   /* Add the file's tracepoints and variables into the current mix.  */
567
568   /* Get trace state variables first, they may be checked when parsing
569      uploaded commands.  */
570   merge_uploaded_trace_state_variables (&uploaded_tsvs);
571
572   merge_uploaded_tracepoints (&uploaded_tps);
573
574   post_create_inferior (&tfile_ops, from_tty);
575 }
576
577 /* Interpret the given line from the definitions part of the trace
578    file.  */
579
580 static void
581 tfile_interp_line (char *line, struct uploaded_tp **utpp,
582                    struct uploaded_tsv **utsvp)
583 {
584   char *p = line;
585
586   if (startswith (p, "R "))
587     {
588       p += strlen ("R ");
589       trace_regblock_size = strtol (p, &p, 16);
590     }
591   else if (startswith (p, "status "))
592     {
593       p += strlen ("status ");
594       parse_trace_status (p, current_trace_status ());
595     }
596   else if (startswith (p, "tp "))
597     {
598       p += strlen ("tp ");
599       parse_tracepoint_definition (p, utpp);
600     }
601   else if (startswith (p, "tsv "))
602     {
603       p += strlen ("tsv ");
604       parse_tsv_definition (p, utsvp);
605     }
606   else if (startswith (p, "tdesc "))
607     {
608       p += strlen ("tdesc ");
609       tfile_append_tdesc_line (p);
610     }
611   else
612     warning (_("Ignoring trace file definition \"%s\""), line);
613 }
614
615 /* Close the trace file and generally clean up.  */
616
617 void
618 tfile_target::close ()
619 {
620   int pid;
621
622   if (trace_fd < 0)
623     return;
624
625   pid = ptid_get_pid (inferior_ptid);
626   inferior_ptid = null_ptid;    /* Avoid confusion from thread stuff.  */
627   exit_inferior_silent (pid);
628
629   ::close (trace_fd);
630   trace_fd = -1;
631   xfree (trace_filename);
632   trace_filename = NULL;
633   buffer_free (&trace_tdesc);
634
635   trace_reset_local_state ();
636 }
637
638 void
639 tfile_target::files_info ()
640 {
641   printf_filtered ("\t`%s'\n", trace_filename);
642 }
643
644 void
645 tfile_target::get_tracepoint_status (struct breakpoint *tp, struct uploaded_tp *utp)
646 {
647   /* Other bits of trace status were collected as part of opening the
648      trace files, so nothing to do here.  */
649 }
650
651 /* Given the position of a traceframe in the file, figure out what
652    address the frame was collected at.  This would normally be the
653    value of a collected PC register, but if not available, we
654    improvise.  */
655
656 static CORE_ADDR
657 tfile_get_traceframe_address (off_t tframe_offset)
658 {
659   CORE_ADDR addr = 0;
660   short tpnum;
661   struct tracepoint *tp;
662   off_t saved_offset = cur_offset;
663
664   /* FIXME dig pc out of collected registers.  */
665
666   /* Fall back to using tracepoint address.  */
667   lseek (trace_fd, tframe_offset, SEEK_SET);
668   tfile_read ((gdb_byte *) &tpnum, 2);
669   tpnum = (short) extract_signed_integer ((gdb_byte *) &tpnum, 2,
670                                           gdbarch_byte_order
671                                               (target_gdbarch ()));
672
673   tp = get_tracepoint_by_number_on_target (tpnum);
674   /* FIXME this is a poor heuristic if multiple locations.  */
675   if (tp && tp->loc)
676     addr = tp->loc->address;
677
678   /* Restore our seek position.  */
679   cur_offset = saved_offset;
680   lseek (trace_fd, cur_offset, SEEK_SET);
681   return addr;
682 }
683
684 /* Given a type of search and some parameters, scan the collection of
685    traceframes in the file looking for a match.  When found, return
686    both the traceframe and tracepoint number, otherwise -1 for
687    each.  */
688
689 int
690 tfile_target::trace_find (enum trace_find_type type, int num,
691                           CORE_ADDR addr1, CORE_ADDR addr2, int *tpp)
692 {
693   short tpnum;
694   int tfnum = 0, found = 0;
695   unsigned int data_size;
696   struct tracepoint *tp;
697   off_t offset, tframe_offset;
698   CORE_ADDR tfaddr;
699
700   if (num == -1)
701     {
702       if (tpp)
703         *tpp = -1;
704       return -1;
705     }
706
707   lseek (trace_fd, trace_frames_offset, SEEK_SET);
708   offset = trace_frames_offset;
709   while (1)
710     {
711       tframe_offset = offset;
712       tfile_read ((gdb_byte *) &tpnum, 2);
713       tpnum = (short) extract_signed_integer ((gdb_byte *) &tpnum, 2,
714                                               gdbarch_byte_order
715                                                   (target_gdbarch ()));
716       offset += 2;
717       if (tpnum == 0)
718         break;
719       tfile_read ((gdb_byte *) &data_size, 4);
720       data_size = (unsigned int) extract_unsigned_integer
721                                      ((gdb_byte *) &data_size, 4,
722                                       gdbarch_byte_order (target_gdbarch ()));
723       offset += 4;
724
725       if (type == tfind_number)
726         {
727           /* Looking for a specific trace frame.  */
728           if (tfnum == num)
729             found = 1;
730         }
731       else
732         {
733           /* Start from the _next_ trace frame.  */
734           if (tfnum > get_traceframe_number ())
735             {
736               switch (type)
737                 {
738                 case tfind_pc:
739                   tfaddr = tfile_get_traceframe_address (tframe_offset);
740                   if (tfaddr == addr1)
741                     found = 1;
742                   break;
743                 case tfind_tp:
744                   tp = get_tracepoint (num);
745                   if (tp && tpnum == tp->number_on_target)
746                     found = 1;
747                   break;
748                 case tfind_range:
749                   tfaddr = tfile_get_traceframe_address (tframe_offset);
750                   if (addr1 <= tfaddr && tfaddr <= addr2)
751                     found = 1;
752                   break;
753                 case tfind_outside:
754                   tfaddr = tfile_get_traceframe_address (tframe_offset);
755                   if (!(addr1 <= tfaddr && tfaddr <= addr2))
756                     found = 1;
757                   break;
758                 default:
759                   internal_error (__FILE__, __LINE__, _("unknown tfind type"));
760                 }
761             }
762         }
763
764       if (found)
765         {
766           if (tpp)
767             *tpp = tpnum;
768           cur_offset = offset;
769           cur_data_size = data_size;
770
771           return tfnum;
772         }
773       /* Skip past the traceframe's data.  */
774       lseek (trace_fd, data_size, SEEK_CUR);
775       offset += data_size;
776       /* Update our own count of traceframes.  */
777       ++tfnum;
778     }
779   /* Did not find what we were looking for.  */
780   if (tpp)
781     *tpp = -1;
782   return -1;
783 }
784
785 /* Prototype of the callback passed to tframe_walk_blocks.  */
786 typedef int (*walk_blocks_callback_func) (char blocktype, void *data);
787
788 /* Callback for traceframe_walk_blocks, used to find a given block
789    type in a traceframe.  */
790
791 static int
792 match_blocktype (char blocktype, void *data)
793 {
794   char *wantedp = (char *) data;
795
796   if (*wantedp == blocktype)
797     return 1;
798
799   return 0;
800 }
801
802 /* Walk over all traceframe block starting at POS offset from
803    CUR_OFFSET, and call CALLBACK for each block found, passing in DATA
804    unmodified.  If CALLBACK returns true, this returns the position in
805    the traceframe where the block is found, relative to the start of
806    the traceframe (cur_offset).  Returns -1 if no callback call
807    returned true, indicating that all blocks have been walked.  */
808
809 static int
810 traceframe_walk_blocks (walk_blocks_callback_func callback,
811                         int pos, void *data)
812 {
813   /* Iterate through a traceframe's blocks, looking for a block of the
814      requested type.  */
815
816   lseek (trace_fd, cur_offset + pos, SEEK_SET);
817   while (pos < cur_data_size)
818     {
819       unsigned short mlen;
820       char block_type;
821
822       tfile_read ((gdb_byte *) &block_type, 1);
823
824       ++pos;
825
826       if ((*callback) (block_type, data))
827         return pos;
828
829       switch (block_type)
830         {
831         case 'R':
832           lseek (trace_fd, cur_offset + pos + trace_regblock_size, SEEK_SET);
833           pos += trace_regblock_size;
834           break;
835         case 'M':
836           lseek (trace_fd, cur_offset + pos + 8, SEEK_SET);
837           tfile_read ((gdb_byte *) &mlen, 2);
838           mlen = (unsigned short)
839                 extract_unsigned_integer ((gdb_byte *) &mlen, 2,
840                                           gdbarch_byte_order
841                                               (target_gdbarch ()));
842           lseek (trace_fd, mlen, SEEK_CUR);
843           pos += (8 + 2 + mlen);
844           break;
845         case 'V':
846           lseek (trace_fd, cur_offset + pos + 4 + 8, SEEK_SET);
847           pos += (4 + 8);
848           break;
849         default:
850           error (_("Unknown block type '%c' (0x%x) in trace frame"),
851                  block_type, block_type);
852           break;
853         }
854     }
855
856   return -1;
857 }
858
859 /* Convenience wrapper around traceframe_walk_blocks.  Looks for the
860    position offset of a block of type TYPE_WANTED in the current trace
861    frame, starting at POS.  Returns -1 if no such block was found.  */
862
863 static int
864 traceframe_find_block_type (char type_wanted, int pos)
865 {
866   return traceframe_walk_blocks (match_blocktype, pos, &type_wanted);
867 }
868
869 /* Look for a block of saved registers in the traceframe, and get the
870    requested register from it.  */
871
872 void
873 tfile_target::fetch_registers (struct regcache *regcache, int regno)
874 {
875   struct gdbarch *gdbarch = regcache->arch ();
876   int offset, regn, regsize, dummy;
877
878   /* An uninitialized reg size says we're not going to be
879      successful at getting register blocks.  */
880   if (!trace_regblock_size)
881     return;
882
883   if (traceframe_find_block_type ('R', 0) >= 0)
884     {
885       gdb_byte *regs = (gdb_byte *) alloca (trace_regblock_size);
886
887       tfile_read (regs, trace_regblock_size);
888
889       for (regn = 0; regn < gdbarch_num_regs (gdbarch); regn++)
890         {
891           if (!remote_register_number_and_offset (regcache->arch (),
892                                                   regn, &dummy, &offset))
893             continue;
894
895           regsize = register_size (gdbarch, regn);
896           /* Make sure we stay within block bounds.  */
897           if (offset + regsize > trace_regblock_size)
898             break;
899           if (regcache_register_status (regcache, regn) == REG_UNKNOWN)
900             {
901               if (regno == regn)
902                 {
903                   regcache_raw_supply (regcache, regno, regs + offset);
904                   break;
905                 }
906               else if (regno == -1)
907                 {
908                   regcache_raw_supply (regcache, regn, regs + offset);
909                 }
910             }
911         }
912     }
913   else
914     tracefile_fetch_registers (regcache, regno);
915 }
916
917 static enum target_xfer_status
918 tfile_xfer_partial_features (const char *annex,
919                              gdb_byte *readbuf, const gdb_byte *writebuf,
920                              ULONGEST offset, ULONGEST len,
921                              ULONGEST *xfered_len)
922 {
923   if (strcmp (annex, "target.xml"))
924     return TARGET_XFER_E_IO;
925
926   if (readbuf == NULL)
927     error (_("tfile_xfer_partial: tdesc is read-only"));
928
929   if (trace_tdesc.used_size == 0)
930     return TARGET_XFER_E_IO;
931
932   if (offset >= trace_tdesc.used_size)
933     return TARGET_XFER_EOF;
934
935   if (len > trace_tdesc.used_size - offset)
936     len = trace_tdesc.used_size - offset;
937
938   memcpy (readbuf, trace_tdesc.buffer + offset, len);
939   *xfered_len = len;
940
941   return TARGET_XFER_OK;
942 }
943
944 enum target_xfer_status
945 tfile_target::xfer_partial (enum target_object object,
946                             const char *annex, gdb_byte *readbuf,
947                             const gdb_byte *writebuf, ULONGEST offset, ULONGEST len,
948                             ULONGEST *xfered_len)
949 {
950   /* We're only doing regular memory and tdesc for now.  */
951   if (object == TARGET_OBJECT_AVAILABLE_FEATURES)
952     return tfile_xfer_partial_features (annex, readbuf, writebuf,
953                                         offset, len, xfered_len);
954   if (object != TARGET_OBJECT_MEMORY)
955     return TARGET_XFER_E_IO;
956
957   if (readbuf == NULL)
958     error (_("tfile_xfer_partial: trace file is read-only"));
959
960   if (get_traceframe_number () != -1)
961     {
962       int pos = 0;
963       enum target_xfer_status res;
964       /* Records the lowest available address of all blocks that
965          intersects the requested range.  */
966       ULONGEST low_addr_available = 0;
967
968       /* Iterate through the traceframe's blocks, looking for
969          memory.  */
970       while ((pos = traceframe_find_block_type ('M', pos)) >= 0)
971         {
972           ULONGEST maddr, amt;
973           unsigned short mlen;
974           enum bfd_endian byte_order = gdbarch_byte_order (target_gdbarch ());
975
976           tfile_read ((gdb_byte *) &maddr, 8);
977           maddr = extract_unsigned_integer ((gdb_byte *) &maddr, 8,
978                                             byte_order);
979           tfile_read ((gdb_byte *) &mlen, 2);
980           mlen = (unsigned short)
981             extract_unsigned_integer ((gdb_byte *) &mlen, 2, byte_order);
982
983           /* If the block includes the first part of the desired
984              range, return as much it has; GDB will re-request the
985              remainder, which might be in a different block of this
986              trace frame.  */
987           if (maddr <= offset && offset < (maddr + mlen))
988             {
989               amt = (maddr + mlen) - offset;
990               if (amt > len)
991                 amt = len;
992
993               if (maddr != offset)
994                 lseek (trace_fd, offset - maddr, SEEK_CUR);
995               tfile_read (readbuf, amt);
996               *xfered_len = amt;
997               return TARGET_XFER_OK;
998             }
999
1000           if (offset < maddr && maddr < (offset + len))
1001             if (low_addr_available == 0 || low_addr_available > maddr)
1002               low_addr_available = maddr;
1003
1004           /* Skip over this block.  */
1005           pos += (8 + 2 + mlen);
1006         }
1007
1008       /* Requested memory is unavailable in the context of traceframes,
1009          and this address falls within a read-only section, fallback
1010          to reading from executable, up to LOW_ADDR_AVAILABLE.  */
1011       if (offset < low_addr_available)
1012         len = std::min (len, low_addr_available - offset);
1013       res = exec_read_partial_read_only (readbuf, offset, len, xfered_len);
1014
1015       if (res == TARGET_XFER_OK)
1016         return TARGET_XFER_OK;
1017       else
1018         {
1019           /* No use trying further, we know some memory starting
1020              at MEMADDR isn't available.  */
1021           *xfered_len = len;
1022           return TARGET_XFER_UNAVAILABLE;
1023         }
1024     }
1025   else
1026     {
1027       /* Fallback to reading from read-only sections.  */
1028       return section_table_read_available_memory (readbuf, offset, len,
1029                                                   xfered_len);
1030     }
1031 }
1032
1033 /* Iterate through the blocks of a trace frame, looking for a 'V'
1034    block with a matching tsv number.  */
1035
1036 int
1037 tfile_target::get_trace_state_variable_value (int tsvnum, LONGEST *val)
1038 {
1039   int pos;
1040   int found = 0;
1041
1042   /* Iterate over blocks in current frame and find the last 'V'
1043      block in which tsv number is TSVNUM.  In one trace frame, there
1044      may be multiple 'V' blocks created for a given trace variable,
1045      and the last matched 'V' block contains the updated value.  */
1046   pos = 0;
1047   while ((pos = traceframe_find_block_type ('V', pos)) >= 0)
1048     {
1049       int vnum;
1050
1051       tfile_read ((gdb_byte *) &vnum, 4);
1052       vnum = (int) extract_signed_integer ((gdb_byte *) &vnum, 4,
1053                                            gdbarch_byte_order
1054                                            (target_gdbarch ()));
1055       if (tsvnum == vnum)
1056         {
1057           tfile_read ((gdb_byte *) val, 8);
1058           *val = extract_signed_integer ((gdb_byte *) val, 8,
1059                                          gdbarch_byte_order
1060                                          (target_gdbarch ()));
1061           found = 1;
1062         }
1063       pos += (4 + 8);
1064     }
1065
1066   return found;
1067 }
1068
1069 /* Callback for traceframe_walk_blocks.  Builds a traceframe_info
1070    object for the tfile target's current traceframe.  */
1071
1072 static int
1073 build_traceframe_info (char blocktype, void *data)
1074 {
1075   struct traceframe_info *info = (struct traceframe_info *) data;
1076
1077   switch (blocktype)
1078     {
1079     case 'M':
1080       {
1081         ULONGEST maddr;
1082         unsigned short mlen;
1083
1084         tfile_read ((gdb_byte *) &maddr, 8);
1085         maddr = extract_unsigned_integer ((gdb_byte *) &maddr, 8,
1086                                           gdbarch_byte_order
1087                                           (target_gdbarch ()));
1088         tfile_read ((gdb_byte *) &mlen, 2);
1089         mlen = (unsigned short)
1090                 extract_unsigned_integer ((gdb_byte *) &mlen,
1091                                           2, gdbarch_byte_order
1092                                           (target_gdbarch ()));
1093
1094         info->memory.emplace_back (maddr, mlen);
1095         break;
1096       }
1097     case 'V':
1098       {
1099         int vnum;
1100
1101         tfile_read ((gdb_byte *) &vnum, 4);
1102         info->tvars.push_back (vnum);
1103       }
1104     case 'R':
1105     case 'S':
1106       {
1107         break;
1108       }
1109     default:
1110       warning (_("Unhandled trace block type (%d) '%c ' "
1111                  "while building trace frame info."),
1112                blocktype, blocktype);
1113       break;
1114     }
1115
1116   return 0;
1117 }
1118
1119 traceframe_info_up
1120 tfile_target::traceframe_info ()
1121 {
1122   traceframe_info_up info (new struct traceframe_info);
1123
1124   traceframe_walk_blocks (build_traceframe_info, 0, info.get ());
1125
1126   return info;
1127 }
1128
1129 /* Handles tdesc lines from tfile by appending the payload to
1130    a global trace_tdesc variable.  */
1131
1132 static void
1133 tfile_append_tdesc_line (const char *line)
1134 {
1135   buffer_grow_str (&trace_tdesc, line);
1136   buffer_grow_str (&trace_tdesc, "\n");
1137 }
1138
1139 void
1140 _initialize_tracefile_tfile (void)
1141 {
1142   add_target_with_completer (&tfile_ops, filename_completer);
1143 }