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