Automatic date update in version.in
[external/binutils.git] / gdb / tracefile.c
1 /* Trace file support in GDB.
2
3    Copyright (C) 1997-2018 Free Software Foundation, Inc.
4
5    This file is part of GDB.
6
7    This program is free software; you can redistribute it and/or modify
8    it under the terms of the GNU General Public License as published by
9    the Free Software Foundation; either version 3 of the License, or
10    (at your option) any later version.
11
12    This program is distributed in the hope that it will be useful,
13    but WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15    GNU General Public License for more details.
16
17    You should have received a copy of the GNU General Public License
18    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
19
20 #include "defs.h"
21 #include "tracefile.h"
22 #include "ctf.h"
23 #include "exec.h"
24 #include "regcache.h"
25
26 /* Helper macros.  */
27
28 #define TRACE_WRITE_R_BLOCK(writer, buf, size)  \
29   writer->ops->frame_ops->write_r_block ((writer), (buf), (size))
30 #define TRACE_WRITE_M_BLOCK_HEADER(writer, addr, size)            \
31   writer->ops->frame_ops->write_m_block_header ((writer), (addr), \
32                                                 (size))
33 #define TRACE_WRITE_M_BLOCK_MEMORY(writer, buf, size)     \
34   writer->ops->frame_ops->write_m_block_memory ((writer), (buf), \
35                                                 (size))
36 #define TRACE_WRITE_V_BLOCK(writer, num, val)   \
37   writer->ops->frame_ops->write_v_block ((writer), (num), (val))
38
39 /* A unique pointer policy class for trace_file_writer.  */
40
41 struct trace_file_writer_deleter
42 {
43   void operator() (struct trace_file_writer *writer)
44   {
45     writer->ops->dtor (writer);
46     xfree (writer);
47   }
48 };
49
50 /* A unique_ptr specialization for trace_file_writer.  */
51
52 typedef std::unique_ptr<trace_file_writer, trace_file_writer_deleter>
53     trace_file_writer_up;
54
55 /* Save tracepoint data to file named FILENAME through WRITER.  WRITER
56    determines the trace file format.  If TARGET_DOES_SAVE is non-zero,
57    the save is performed on the target, otherwise GDB obtains all trace
58    data and saves it locally.  */
59
60 static void
61 trace_save (const char *filename, struct trace_file_writer *writer,
62             int target_does_save)
63 {
64   struct trace_status *ts = current_trace_status ();
65   struct uploaded_tp *uploaded_tps = NULL, *utp;
66   struct uploaded_tsv *uploaded_tsvs = NULL, *utsv;
67
68   ULONGEST offset = 0;
69 #define MAX_TRACE_UPLOAD 2000
70   gdb_byte buf[MAX_TRACE_UPLOAD];
71   enum bfd_endian byte_order = gdbarch_byte_order (target_gdbarch ());
72
73   /* If the target is to save the data to a file on its own, then just
74      send the command and be done with it.  */
75   if (target_does_save)
76     {
77       if (!writer->ops->target_save (writer, filename))
78         error (_("Target failed to save trace data to '%s'."),
79                filename);
80       return;
81     }
82
83   /* Get the trace status first before opening the file, so if the
84      target is losing, we can get out without touching files.  Since
85      we're just calling this for side effects, we ignore the
86      result.  */
87   target_get_trace_status (ts);
88
89   writer->ops->start (writer, filename);
90
91   writer->ops->write_header (writer);
92
93   /* Write descriptive info.  */
94
95   /* Write out the size of a register block.  */
96   writer->ops->write_regblock_type (writer, trace_regblock_size);
97
98   /* Write out the target description info.  */
99   writer->ops->write_tdesc (writer);
100
101   /* Write out status of the tracing run (aka "tstatus" info).  */
102   writer->ops->write_status (writer, ts);
103
104   /* Note that we want to upload tracepoints and save those, rather
105      than simply writing out the local ones, because the user may have
106      changed tracepoints in GDB in preparation for a future tracing
107      run, or maybe just mass-deleted all types of breakpoints as part
108      of cleaning up.  So as not to contaminate the session, leave the
109      data in its uploaded form, don't make into real tracepoints.  */
110
111   /* Get trace state variables first, they may be checked when parsing
112      uploaded commands.  */
113
114   target_upload_trace_state_variables (&uploaded_tsvs);
115
116   for (utsv = uploaded_tsvs; utsv; utsv = utsv->next)
117     writer->ops->write_uploaded_tsv (writer, utsv);
118
119   free_uploaded_tsvs (&uploaded_tsvs);
120
121   target_upload_tracepoints (&uploaded_tps);
122
123   for (utp = uploaded_tps; utp; utp = utp->next)
124     target_get_tracepoint_status (NULL, utp);
125
126   for (utp = uploaded_tps; utp; utp = utp->next)
127     writer->ops->write_uploaded_tp (writer, utp);
128
129   free_uploaded_tps (&uploaded_tps);
130
131   /* Mark the end of the definition section.  */
132   writer->ops->write_definition_end (writer);
133
134   /* Get and write the trace data proper.  */
135   while (1)
136     {
137       LONGEST gotten = 0;
138
139       /* The writer supports writing the contents of trace buffer
140           directly to trace file.  Don't parse the contents of trace
141           buffer.  */
142       if (writer->ops->write_trace_buffer != NULL)
143         {
144           /* We ask for big blocks, in the hopes of efficiency, but
145              will take less if the target has packet size limitations
146              or some such.  */
147           gotten = target_get_raw_trace_data (buf, offset,
148                                               MAX_TRACE_UPLOAD);
149           if (gotten < 0)
150             error (_("Failure to get requested trace buffer data"));
151           /* No more data is forthcoming, we're done.  */
152           if (gotten == 0)
153             break;
154
155           writer->ops->write_trace_buffer (writer, buf, gotten);
156
157           offset += gotten;
158         }
159       else
160         {
161           uint16_t tp_num;
162           uint32_t tf_size;
163           /* Parse the trace buffers according to how data are stored
164              in trace buffer in GDBserver.  */
165
166           gotten = target_get_raw_trace_data (buf, offset, 6);
167
168           if (gotten == 0)
169             break;
170
171           /* Read the first six bytes in, which is the tracepoint
172              number and trace frame size.  */
173           tp_num = (uint16_t)
174             extract_unsigned_integer (&buf[0], 2, byte_order);
175
176           tf_size = (uint32_t)
177             extract_unsigned_integer (&buf[2], 4, byte_order);
178
179           writer->ops->frame_ops->start (writer, tp_num);
180           gotten = 6;
181
182           if (tf_size > 0)
183             {
184               unsigned int block;
185
186               offset += 6;
187
188               for (block = 0; block < tf_size; )
189                 {
190                   gdb_byte block_type;
191
192                   /* We'll fetch one block each time, in order to
193                      handle the extremely large 'M' block.  We first
194                      fetch one byte to get the type of the block.  */
195                   gotten = target_get_raw_trace_data (buf, offset, 1);
196                   if (gotten < 1)
197                     error (_("Failure to get requested trace buffer data"));
198
199                   gotten = 1;
200                   block += 1;
201                   offset += 1;
202
203                   block_type = buf[0];
204                   switch (block_type)
205                     {
206                     case 'R':
207                       gotten
208                         = target_get_raw_trace_data (buf, offset,
209                                                      trace_regblock_size);
210                       if (gotten < trace_regblock_size)
211                         error (_("Failure to get requested trace"
212                                  " buffer data"));
213
214                       TRACE_WRITE_R_BLOCK (writer, buf,
215                                            trace_regblock_size);
216                       break;
217                     case 'M':
218                       {
219                         unsigned short mlen;
220                         ULONGEST addr;
221                         LONGEST t;
222                         int j;
223
224                         t = target_get_raw_trace_data (buf,offset, 10);
225                         if (t < 10)
226                           error (_("Failure to get requested trace"
227                                    " buffer data"));
228
229                         offset += 10;
230                         block += 10;
231
232                         gotten = 0;
233                         addr = (ULONGEST)
234                           extract_unsigned_integer (buf, 8,
235                                                     byte_order);
236                         mlen = (unsigned short)
237                           extract_unsigned_integer (&buf[8], 2,
238                                                     byte_order);
239
240                         TRACE_WRITE_M_BLOCK_HEADER (writer, addr,
241                                                     mlen);
242
243                         /* The memory contents in 'M' block may be
244                            very large.  Fetch the data from the target
245                            and write them into file one by one.  */
246                         for (j = 0; j < mlen; )
247                           {
248                             unsigned int read_length;
249
250                             if (mlen - j > MAX_TRACE_UPLOAD)
251                               read_length = MAX_TRACE_UPLOAD;
252                             else
253                               read_length = mlen - j;
254
255                             t = target_get_raw_trace_data (buf,
256                                                            offset + j,
257                                                            read_length);
258                             if (t < read_length)
259                               error (_("Failure to get requested"
260                                        " trace buffer data"));
261
262                             TRACE_WRITE_M_BLOCK_MEMORY (writer, buf,
263                                                         read_length);
264
265                             j += read_length;
266                             gotten += read_length;
267                           }
268
269                         break;
270                       }
271                     case 'V':
272                       {
273                         int vnum;
274                         LONGEST val;
275
276                         gotten
277                           = target_get_raw_trace_data (buf, offset,
278                                                        12);
279                         if (gotten < 12)
280                           error (_("Failure to get requested"
281                                    " trace buffer data"));
282
283                         vnum  = (int) extract_signed_integer (buf,
284                                                               4,
285                                                               byte_order);
286                         val
287                           = extract_signed_integer (&buf[4], 8,
288                                                     byte_order);
289
290                         TRACE_WRITE_V_BLOCK (writer, vnum, val);
291                       }
292                       break;
293                     default:
294                       error (_("Unknown block type '%c' (0x%x) in"
295                                " trace frame"),
296                              block_type, block_type);
297                     }
298
299                   block += gotten;
300                   offset += gotten;
301                 }
302             }
303           else
304             offset += gotten;
305
306           writer->ops->frame_ops->end (writer);
307         }
308     }
309
310   writer->ops->end (writer);
311 }
312
313 static void
314 tsave_command (const char *args, int from_tty)
315 {
316   int target_does_save = 0;
317   char **argv;
318   char *filename = NULL;
319   int generate_ctf = 0;
320
321   if (args == NULL)
322     error_no_arg (_("file in which to save trace data"));
323
324   gdb_argv built_argv (args);
325   argv = built_argv.get ();
326
327   for (; *argv; ++argv)
328     {
329       if (strcmp (*argv, "-r") == 0)
330         target_does_save = 1;
331       else if (strcmp (*argv, "-ctf") == 0)
332         generate_ctf = 1;
333       else if (**argv == '-')
334         error (_("unknown option `%s'"), *argv);
335       else
336         filename = *argv;
337     }
338
339   if (!filename)
340     error_no_arg (_("file in which to save trace data"));
341
342   if (generate_ctf)
343     trace_save_ctf (filename, target_does_save);
344   else
345     trace_save_tfile (filename, target_does_save);
346
347   if (from_tty)
348     printf_filtered (_("Trace data saved to %s '%s'.\n"),
349                      generate_ctf ? "directory" : "file", filename);
350 }
351
352 /* Save the trace data to file FILENAME of tfile format.  */
353
354 void
355 trace_save_tfile (const char *filename, int target_does_save)
356 {
357   trace_file_writer_up writer (tfile_trace_file_writer_new ());
358   trace_save (filename, writer.get (), target_does_save);
359 }
360
361 /* Save the trace data to dir DIRNAME of ctf format.  */
362
363 void
364 trace_save_ctf (const char *dirname, int target_does_save)
365 {
366   trace_file_writer_up writer (ctf_trace_file_writer_new ());
367   trace_save (dirname, writer.get (), target_does_save);
368 }
369
370 /* Fetch register data from tracefile, shared for both tfile and
371    ctf.  */
372
373 void
374 tracefile_fetch_registers (struct regcache *regcache, int regno)
375 {
376   struct gdbarch *gdbarch = regcache->arch ();
377   struct tracepoint *tp = get_tracepoint (get_tracepoint_number ());
378   int regn;
379
380   /* We get here if no register data has been found.  Mark registers
381      as unavailable.  */
382   for (regn = 0; regn < gdbarch_num_regs (gdbarch); regn++)
383     regcache->raw_supply (regn, NULL);
384
385   /* We can often usefully guess that the PC is going to be the same
386      as the address of the tracepoint.  */
387   if (tp == NULL || tp->loc == NULL)
388     return;
389
390   /* But don't try to guess if tracepoint is multi-location...  */
391   if (tp->loc->next)
392     {
393       warning (_("Tracepoint %d has multiple "
394                  "locations, cannot infer $pc"),
395                tp->number);
396       return;
397     }
398   /* ... or does while-stepping.  */
399   else if (tp->step_count > 0)
400     {
401       warning (_("Tracepoint %d does while-stepping, "
402                  "cannot infer $pc"),
403                tp->number);
404       return;
405     }
406
407   /* Guess what we can from the tracepoint location.  */
408   gdbarch_guess_tracepoint_registers (gdbarch, regcache,
409                                       tp->loc->address);
410 }
411
412 /* This is the implementation of target_ops method to_has_all_memory.  */
413
414 bool
415 tracefile_target::has_all_memory ()
416 {
417   return 1;
418 }
419
420 /* This is the implementation of target_ops method to_has_memory.  */
421
422 bool
423 tracefile_target::has_memory ()
424 {
425   return 1;
426 }
427
428 /* This is the implementation of target_ops method to_has_stack.
429    The target has a stack when GDB has already selected one trace
430    frame.  */
431
432 bool
433 tracefile_target::has_stack ()
434 {
435   return get_traceframe_number () != -1;
436 }
437
438 /* This is the implementation of target_ops method to_has_registers.
439    The target has registers when GDB has already selected one trace
440    frame.  */
441
442 bool
443 tracefile_target::has_registers ()
444 {
445   return get_traceframe_number () != -1;
446 }
447
448 /* This is the implementation of target_ops method to_thread_alive.
449    tracefile has one thread faked by GDB.  */
450
451 bool
452 tracefile_target::thread_alive (ptid_t ptid)
453 {
454   return 1;
455 }
456
457 /* This is the implementation of target_ops method to_get_trace_status.
458    The trace status for a file is that tracing can never be run.  */
459
460 int
461 tracefile_target::get_trace_status (struct trace_status *ts)
462 {
463   /* Other bits of trace status were collected as part of opening the
464      trace files, so nothing to do here.  */
465
466   return -1;
467 }
468
469 tracefile_target::tracefile_target ()
470 {
471   this->to_stratum = process_stratum;
472 }
473
474 void
475 _initialize_tracefile (void)
476 {
477   add_com ("tsave", class_trace, tsave_command, _("\
478 Save the trace data to a file.\n\
479 Use the '-ctf' option to save the data to CTF format.\n\
480 Use the '-r' option to direct the target to save directly to the file,\n\
481 using its own filesystem."));
482 }