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