Automatic date update in version.in
[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 "common/filestuff.h"
24 #include "common/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 "common/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.  Specify the filename of the trace file.")
47 };
48
49 class tfile_target final : public tracefile_target
50 {
51  public:
52   const target_info &info () const override
53   { return tfile_target_info; }
54
55   void close () override;
56   void fetch_registers (struct regcache *, int) override;
57   enum target_xfer_status xfer_partial (enum target_object object,
58                                                 const char *annex,
59                                                 gdb_byte *readbuf,
60                                                 const gdb_byte *writebuf,
61                                                 ULONGEST offset, ULONGEST len,
62                                                 ULONGEST *xfered_len) override;
63   void files_info () override;
64   int trace_find (enum trace_find_type type, int num,
65                           CORE_ADDR addr1, CORE_ADDR addr2, int *tpp) override;
66   bool get_trace_state_variable_value (int tsv, LONGEST *val) override;
67   traceframe_info_up traceframe_info () override;
68
69   void get_tracepoint_status (struct breakpoint *tp,
70                               struct uploaded_tp *utp) override;
71 };
72
73 /* TFILE trace writer.  */
74
75 struct tfile_trace_file_writer
76 {
77   struct trace_file_writer base;
78
79   /* File pointer to tfile trace file.  */
80   FILE *fp;
81   /* Path name of the tfile trace file.  */
82   char *pathname;
83 };
84
85 /* This is the implementation of trace_file_write_ops method
86    target_save.  We just call the generic target
87    target_save_trace_data to do target-side saving.  */
88
89 static int
90 tfile_target_save (struct trace_file_writer *self,
91                    const char *filename)
92 {
93   int err = target_save_trace_data (filename);
94
95   return (err >= 0);
96 }
97
98 /* This is the implementation of trace_file_write_ops method
99    dtor.  */
100
101 static void
102 tfile_dtor (struct trace_file_writer *self)
103 {
104   struct tfile_trace_file_writer *writer
105     = (struct tfile_trace_file_writer *) self;
106
107   xfree (writer->pathname);
108
109   if (writer->fp != NULL)
110     fclose (writer->fp);
111 }
112
113 /* This is the implementation of trace_file_write_ops method
114    start.  It creates the trace file FILENAME and registers some
115    cleanups.  */
116
117 static void
118 tfile_start (struct trace_file_writer *self, const char *filename)
119 {
120   struct tfile_trace_file_writer *writer
121     = (struct tfile_trace_file_writer *) self;
122
123   writer->pathname = tilde_expand (filename);
124   writer->fp = gdb_fopen_cloexec (writer->pathname, "wb").release ();
125   if (writer->fp == NULL)
126     error (_("Unable to open file '%s' for saving trace data (%s)"),
127            writer->pathname, safe_strerror (errno));
128 }
129
130 /* This is the implementation of trace_file_write_ops method
131    write_header.  Write the TFILE header.  */
132
133 static void
134 tfile_write_header (struct trace_file_writer *self)
135 {
136   struct tfile_trace_file_writer *writer
137     = (struct tfile_trace_file_writer *) self;
138   int written;
139
140   /* Write a file header, with a high-bit-set char to indicate a
141      binary file, plus a hint as what this file is, and a version
142      number in case of future needs.  */
143   written = fwrite ("\x7fTRACE0\n", 8, 1, writer->fp);
144   if (written < 1)
145     perror_with_name (writer->pathname);
146 }
147
148 /* This is the implementation of trace_file_write_ops method
149    write_regblock_type.  Write the size of register block.  */
150
151 static void
152 tfile_write_regblock_type (struct trace_file_writer *self, int size)
153 {
154   struct tfile_trace_file_writer *writer
155     = (struct tfile_trace_file_writer *) self;
156
157   fprintf (writer->fp, "R %x\n", size);
158 }
159
160 /* This is the implementation of trace_file_write_ops method
161    write_status.  */
162
163 static void
164 tfile_write_status (struct trace_file_writer *self,
165                     struct trace_status *ts)
166 {
167   struct tfile_trace_file_writer *writer
168     = (struct tfile_trace_file_writer *) self;
169
170   fprintf (writer->fp, "status %c;%s",
171            (ts->running ? '1' : '0'), stop_reason_names[ts->stop_reason]);
172   if (ts->stop_reason == tracepoint_error
173       || ts->stop_reason == trace_stop_command)
174     {
175       char *buf = (char *) alloca (strlen (ts->stop_desc) * 2 + 1);
176
177       bin2hex ((gdb_byte *) ts->stop_desc, buf, strlen (ts->stop_desc));
178       fprintf (writer->fp, ":%s", buf);
179     }
180   fprintf (writer->fp, ":%x", ts->stopping_tracepoint);
181   if (ts->traceframe_count >= 0)
182     fprintf (writer->fp, ";tframes:%x", ts->traceframe_count);
183   if (ts->traceframes_created >= 0)
184     fprintf (writer->fp, ";tcreated:%x", ts->traceframes_created);
185   if (ts->buffer_free >= 0)
186     fprintf (writer->fp, ";tfree:%x", ts->buffer_free);
187   if (ts->buffer_size >= 0)
188     fprintf (writer->fp, ";tsize:%x", ts->buffer_size);
189   if (ts->disconnected_tracing)
190     fprintf (writer->fp, ";disconn:%x", ts->disconnected_tracing);
191   if (ts->circular_buffer)
192     fprintf (writer->fp, ";circular:%x", ts->circular_buffer);
193   if (ts->start_time)
194     {
195       fprintf (writer->fp, ";starttime:%s",
196       phex_nz (ts->start_time, sizeof (ts->start_time)));
197     }
198   if (ts->stop_time)
199     {
200       fprintf (writer->fp, ";stoptime:%s",
201       phex_nz (ts->stop_time, sizeof (ts->stop_time)));
202     }
203   if (ts->notes != NULL)
204     {
205       char *buf = (char *) alloca (strlen (ts->notes) * 2 + 1);
206
207       bin2hex ((gdb_byte *) ts->notes, buf, strlen (ts->notes));
208       fprintf (writer->fp, ";notes:%s", buf);
209     }
210   if (ts->user_name != NULL)
211     {
212       char *buf = (char *) alloca (strlen (ts->user_name) * 2 + 1);
213
214       bin2hex ((gdb_byte *) ts->user_name, buf, strlen (ts->user_name));
215       fprintf (writer->fp, ";username:%s", buf);
216     }
217   fprintf (writer->fp, "\n");
218 }
219
220 /* This is the implementation of trace_file_write_ops method
221    write_uploaded_tsv.  */
222
223 static void
224 tfile_write_uploaded_tsv (struct trace_file_writer *self,
225                           struct uploaded_tsv *utsv)
226 {
227   char *buf = NULL;
228   struct tfile_trace_file_writer *writer
229     = (struct tfile_trace_file_writer *) self;
230
231   if (utsv->name)
232     {
233       buf = (char *) xmalloc (strlen (utsv->name) * 2 + 1);
234       bin2hex ((gdb_byte *) (utsv->name), buf, strlen (utsv->name));
235     }
236
237   fprintf (writer->fp, "tsv %x:%s:%x:%s\n",
238            utsv->number, phex_nz (utsv->initial_value, 8),
239            utsv->builtin, buf != NULL ? buf : "");
240
241   if (utsv->name)
242     xfree (buf);
243 }
244
245 #define MAX_TRACE_UPLOAD 2000
246
247 /* This is the implementation of trace_file_write_ops method
248    write_uploaded_tp.  */
249
250 static void
251 tfile_write_uploaded_tp (struct trace_file_writer *self,
252                          struct uploaded_tp *utp)
253 {
254   struct tfile_trace_file_writer *writer
255     = (struct tfile_trace_file_writer *) self;
256   char buf[MAX_TRACE_UPLOAD];
257
258   fprintf (writer->fp, "tp T%x:%s:%c:%x:%x",
259            utp->number, phex_nz (utp->addr, sizeof (utp->addr)),
260            (utp->enabled ? 'E' : 'D'), utp->step, utp->pass);
261   if (utp->type == bp_fast_tracepoint)
262     fprintf (writer->fp, ":F%x", utp->orig_size);
263   if (utp->cond)
264     fprintf (writer->fp,
265              ":X%x,%s", (unsigned int) strlen (utp->cond.get ()) / 2,
266              utp->cond.get ());
267   fprintf (writer->fp, "\n");
268   for (const auto &act : utp->actions)
269     fprintf (writer->fp, "tp A%x:%s:%s\n",
270              utp->number, phex_nz (utp->addr, sizeof (utp->addr)), act.get ());
271   for (const auto &act : utp->step_actions)
272     fprintf (writer->fp, "tp S%x:%s:%s\n",
273              utp->number, phex_nz (utp->addr, sizeof (utp->addr)), act.get ());
274   if (utp->at_string)
275     {
276       encode_source_string (utp->number, utp->addr,
277                             "at", utp->at_string.get (),
278                             buf, MAX_TRACE_UPLOAD);
279       fprintf (writer->fp, "tp Z%s\n", buf);
280     }
281   if (utp->cond_string)
282     {
283       encode_source_string (utp->number, utp->addr,
284                             "cond", utp->cond_string.get (),
285                             buf, MAX_TRACE_UPLOAD);
286       fprintf (writer->fp, "tp Z%s\n", buf);
287     }
288   for (const auto &act : utp->cmd_strings)
289     {
290       encode_source_string (utp->number, utp->addr, "cmd", act.get (),
291                             buf, MAX_TRACE_UPLOAD);
292       fprintf (writer->fp, "tp Z%s\n", buf);
293     }
294   fprintf (writer->fp, "tp V%x:%s:%x:%s\n",
295            utp->number, phex_nz (utp->addr, sizeof (utp->addr)),
296            utp->hit_count,
297            phex_nz (utp->traceframe_usage,
298                     sizeof (utp->traceframe_usage)));
299 }
300
301 /* This is the implementation of trace_file_write_ops method
302    write_tdesc.  */
303
304 static void
305 tfile_write_tdesc (struct trace_file_writer *self)
306 {
307   struct tfile_trace_file_writer *writer
308     = (struct tfile_trace_file_writer *) self;
309
310   gdb::optional<std::string> tdesc
311     = target_fetch_description_xml (current_top_target ());
312
313   if (!tdesc)
314     return;
315
316   const char *ptr = tdesc->c_str ();
317
318   /* Write tdesc line by line, prefixing each line with "tdesc ".  */
319   while (ptr != NULL)
320     {
321       const char *next = strchr (ptr, '\n');
322       if (next != NULL)
323         {
324           fprintf (writer->fp, "tdesc %.*s\n", (int) (next - ptr), ptr);
325           /* Skip the \n.  */
326           next++;
327         }
328       else if (*ptr != '\0')
329         {
330           /* Last line, doesn't have a newline.  */
331           fprintf (writer->fp, "tdesc %s\n", ptr);
332         }
333       ptr = next;
334     }
335 }
336
337 /* This is the implementation of trace_file_write_ops method
338    write_definition_end.  */
339
340 static void
341 tfile_write_definition_end (struct trace_file_writer *self)
342 {
343   struct tfile_trace_file_writer *writer
344     = (struct tfile_trace_file_writer *) self;
345
346   fprintf (writer->fp, "\n");
347 }
348
349 /* This is the implementation of trace_file_write_ops method
350    write_raw_data.  */
351
352 static void
353 tfile_write_raw_data (struct trace_file_writer *self, gdb_byte *buf,
354                       LONGEST len)
355 {
356   struct tfile_trace_file_writer *writer
357     = (struct tfile_trace_file_writer *) self;
358
359   if (fwrite (buf, len, 1, writer->fp) < 1)
360     perror_with_name (writer->pathname);
361 }
362
363 /* This is the implementation of trace_file_write_ops method
364    end.  */
365
366 static void
367 tfile_end (struct trace_file_writer *self)
368 {
369   struct tfile_trace_file_writer *writer
370     = (struct tfile_trace_file_writer *) self;
371   uint32_t gotten = 0;
372
373   /* Mark the end of trace data.  */
374   if (fwrite (&gotten, 4, 1, writer->fp) < 1)
375     perror_with_name (writer->pathname);
376 }
377
378 /* Operations to write trace buffers into TFILE format.  */
379
380 static const struct trace_file_write_ops tfile_write_ops =
381 {
382   tfile_dtor,
383   tfile_target_save,
384   tfile_start,
385   tfile_write_header,
386   tfile_write_regblock_type,
387   tfile_write_status,
388   tfile_write_uploaded_tsv,
389   tfile_write_uploaded_tp,
390   tfile_write_tdesc,
391   tfile_write_definition_end,
392   tfile_write_raw_data,
393   NULL,
394   tfile_end,
395 };
396
397 /* Return a trace writer for TFILE format.  */
398
399 struct trace_file_writer *
400 tfile_trace_file_writer_new (void)
401 {
402   struct tfile_trace_file_writer *writer
403     = XNEW (struct tfile_trace_file_writer);
404
405   writer->base.ops = &tfile_write_ops;
406   writer->fp = NULL;
407   writer->pathname = NULL;
408
409   return (struct trace_file_writer *) writer;
410 }
411
412 /* target tfile command */
413
414 static tfile_target tfile_ops;
415
416 #define TRACE_HEADER_SIZE 8
417
418 #define TFILE_PID (1)
419
420 static char *trace_filename;
421 static int trace_fd = -1;
422 static off_t trace_frames_offset;
423 static off_t cur_offset;
424 static int cur_data_size;
425 int trace_regblock_size;
426 static struct buffer trace_tdesc;
427
428 static void tfile_append_tdesc_line (const char *line);
429 static void tfile_interp_line (char *line,
430                                struct uploaded_tp **utpp,
431                                struct uploaded_tsv **utsvp);
432
433 /* Read SIZE bytes into READBUF from the trace frame, starting at
434    TRACE_FD's current position.  Note that this call `read'
435    underneath, hence it advances the file's seek position.  Throws an
436    error if the `read' syscall fails, or less than SIZE bytes are
437    read.  */
438
439 static void
440 tfile_read (gdb_byte *readbuf, int size)
441 {
442   int gotten;
443
444   gotten = read (trace_fd, readbuf, size);
445   if (gotten < 0)
446     perror_with_name (trace_filename);
447   else if (gotten < size)
448     error (_("Premature end of file while reading trace file"));
449 }
450
451 /* Open the tfile target.  */
452
453 static void
454 tfile_target_open (const char *arg, int from_tty)
455 {
456   int flags;
457   int scratch_chan;
458   char header[TRACE_HEADER_SIZE];
459   char linebuf[1000]; /* Should be max remote packet size or so.  */
460   gdb_byte byte;
461   int bytes, i;
462   struct trace_status *ts;
463   struct uploaded_tp *uploaded_tps = NULL;
464   struct uploaded_tsv *uploaded_tsvs = NULL;
465
466   target_preopen (from_tty);
467   if (!arg)
468     error (_("No trace file specified."));
469
470   gdb::unique_xmalloc_ptr<char> filename (tilde_expand (arg));
471   if (!IS_ABSOLUTE_PATH (filename.get ()))
472     filename.reset (concat (current_directory, "/", filename.get (),
473                             (char *) NULL));
474
475   flags = O_BINARY | O_LARGEFILE;
476   flags |= O_RDONLY;
477   scratch_chan = gdb_open_cloexec (filename.get (), flags, 0);
478   if (scratch_chan < 0)
479     perror_with_name (filename.get ());
480
481   /* Looks semi-reasonable.  Toss the old trace file and work on the new.  */
482
483   unpush_target (&tfile_ops);
484
485   trace_filename = filename.release ();
486   trace_fd = scratch_chan;
487
488   /* Make sure this is clear.  */
489   buffer_free (&trace_tdesc);
490
491   bytes = 0;
492   /* Read the file header and test for validity.  */
493   tfile_read ((gdb_byte *) &header, TRACE_HEADER_SIZE);
494
495   bytes += TRACE_HEADER_SIZE;
496   if (!(header[0] == 0x7f
497         && (startswith (header + 1, "TRACE0\n"))))
498     error (_("File is not a valid trace file."));
499
500   push_target (&tfile_ops);
501
502   trace_regblock_size = 0;
503   ts = current_trace_status ();
504   /* We know we're working with a file.  Record its name.  */
505   ts->filename = trace_filename;
506   /* Set defaults in case there is no status line.  */
507   ts->running_known = 0;
508   ts->stop_reason = trace_stop_reason_unknown;
509   ts->traceframe_count = -1;
510   ts->buffer_free = 0;
511   ts->disconnected_tracing = 0;
512   ts->circular_buffer = 0;
513
514   TRY
515     {
516       /* Read through a section of newline-terminated lines that
517          define things like tracepoints.  */
518       i = 0;
519       while (1)
520         {
521           tfile_read (&byte, 1);
522
523           ++bytes;
524           if (byte == '\n')
525             {
526               /* Empty line marks end of the definition section.  */
527               if (i == 0)
528                 break;
529               linebuf[i] = '\0';
530               i = 0;
531               tfile_interp_line (linebuf, &uploaded_tps, &uploaded_tsvs);
532             }
533           else
534             linebuf[i++] = byte;
535           if (i >= 1000)
536             error (_("Excessively long lines in trace file"));
537         }
538
539       /* By now, tdesc lines have been read from tfile - let's parse them.  */
540       target_find_description ();
541
542       /* Record the starting offset of the binary trace data.  */
543       trace_frames_offset = bytes;
544
545       /* If we don't have a blocksize, we can't interpret the
546          traceframes.  */
547       if (trace_regblock_size == 0)
548         error (_("No register block size recorded in trace file"));
549     }
550   CATCH (ex, RETURN_MASK_ALL)
551     {
552       /* Remove the partially set up target.  */
553       unpush_target (&tfile_ops);
554       throw_exception (ex);
555     }
556   END_CATCH
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 }