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