]> Git Repo - binutils.git/blob - gdb/tracectf.c
Automatic date update in version.in
[binutils.git] / gdb / tracectf.c
1 /* CTF format support.
2
3    Copyright (C) 2012-2022 Free Software Foundation, Inc.
4    Contributed by Hui Zhu <[email protected]>
5    Contributed by Yao Qi <[email protected]>
6
7    This file is part of GDB.
8
9    This program is free software; you can redistribute it and/or modify
10    it under the terms of the GNU General Public License as published by
11    the Free Software Foundation; either version 3 of the License, or
12    (at your option) any later version.
13
14    This program is distributed in the hope that it will be useful,
15    but WITHOUT ANY WARRANTY; without even the implied warranty of
16    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17    GNU General Public License for more details.
18
19    You should have received a copy of the GNU General Public License
20    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
21
22 #include "defs.h"
23 #include "tracectf.h"
24 #include "tracepoint.h"
25 #include "regcache.h"
26 #include <sys/stat.h>
27 #include "exec.h"
28 #include "completer.h"
29 #include "inferior.h"
30 #include "gdbthread.h"
31 #include "tracefile.h"
32 #include <ctype.h>
33 #include <algorithm>
34 #include "gdbsupport/filestuff.h"
35 #include "gdbarch.h"
36
37 /* The CTF target.  */
38
39 static const target_info ctf_target_info = {
40   "ctf",
41   N_("CTF file"),
42   N_("(Use a CTF directory as a target.\n\
43 Specify the filename of the CTF directory.")
44 };
45
46 class ctf_target final : public tracefile_target
47 {
48 public:
49   const target_info &info () const override
50   { return ctf_target_info; }
51
52   void close () override;
53   void fetch_registers (struct regcache *, int) override;
54   enum target_xfer_status xfer_partial (enum target_object object,
55                                                 const char *annex,
56                                                 gdb_byte *readbuf,
57                                                 const gdb_byte *writebuf,
58                                                 ULONGEST offset, ULONGEST len,
59                                                 ULONGEST *xfered_len) override;
60   void files_info () override;
61   int trace_find (enum trace_find_type type, int num,
62                           CORE_ADDR addr1, CORE_ADDR addr2, int *tpp) override;
63   bool get_trace_state_variable_value (int tsv, LONGEST *val) override;
64   traceframe_info_up traceframe_info () override;
65 };
66
67 /* GDB saves trace buffers and other information (such as trace
68    status) got from the remote target into Common Trace Format (CTF).
69    The following types of information are expected to save in CTF:
70
71    1. The length (in bytes) of register cache.  Event "register" will
72    be defined in metadata, which includes the length.
73
74    2. Trace status.  Event "status" is defined in metadata, which
75    includes all aspects of trace status.
76
77    3. Uploaded trace variables.  Event "tsv_def" is defined in
78    metadata, which is about all aspects of a uploaded trace variable.
79    Uploaded tracepoints.   Event "tp_def" is defined in meta, which
80    is about all aspects of an uploaded tracepoint.  Note that the
81    "sequence" (a CTF type, which is a dynamically-sized array.) is
82    used for "actions" "step_actions" and "cmd_strings".
83
84    4. Trace frames.  Each trace frame is composed by several blocks
85    of different types ('R', 'M', 'V').  One trace frame is saved in
86    one CTF packet and the blocks of this frame are saved as events.
87    4.1: The trace frame related information (such as the number of
88    tracepoint associated with this frame) is saved in the packet
89    context.
90    4.2: The block 'M', 'R' and 'V' are saved in event "memory",
91    "register" and "tsv" respectively.
92    4.3: When iterating over events, babeltrace can't tell iterator
93    goes to a new packet, so we need a marker or anchor to tell GDB
94    that iterator goes into a new packet or frame.  We define event
95    "frame".  */
96
97 #define CTF_MAGIC               0xC1FC1FC1
98 #define CTF_SAVE_MAJOR          1
99 #define CTF_SAVE_MINOR          8
100
101 #define CTF_METADATA_NAME       "metadata"
102 #define CTF_DATASTREAM_NAME     "datastream"
103
104 /* Reserved event id.  */
105
106 #define CTF_EVENT_ID_REGISTER 0
107 #define CTF_EVENT_ID_TSV 1
108 #define CTF_EVENT_ID_MEMORY 2
109 #define CTF_EVENT_ID_FRAME 3
110 #define CTF_EVENT_ID_STATUS 4
111 #define CTF_EVENT_ID_TSV_DEF 5
112 #define CTF_EVENT_ID_TP_DEF 6
113
114 #define CTF_PID (2)
115
116 /* The state kept while writing the CTF datastream file.  */
117
118 struct trace_write_handler
119 {
120   /* File descriptor of metadata.  */
121   FILE *metadata_fd;
122   /* File descriptor of traceframes.  */
123   FILE *datastream_fd;
124
125   /* This is the content size of the current packet.  */
126   size_t content_size;
127
128   /* This is the start offset of current packet.  */
129   long packet_start;
130 };
131
132 /* Write metadata in FORMAT.  */
133
134 static void
135 ctf_save_write_metadata (struct trace_write_handler *handler,
136                          const char *format, ...)
137   ATTRIBUTE_PRINTF (2, 3);
138
139 static void
140 ctf_save_write_metadata (struct trace_write_handler *handler,
141                          const char *format, ...)
142 {
143   va_list args;
144
145   va_start (args, format);
146   if (vfprintf (handler->metadata_fd, format, args) < 0)
147     error (_("Unable to write metadata file (%s)"),
148              safe_strerror (errno));
149   va_end (args);
150 }
151
152 /* Write BUF of length SIZE to datastream file represented by
153    HANDLER.  */
154
155 static int
156 ctf_save_write (struct trace_write_handler *handler,
157                 const gdb_byte *buf, size_t size)
158 {
159   if (fwrite (buf, size, 1, handler->datastream_fd) != 1)
160     error (_("Unable to write file for saving trace data (%s)"),
161            safe_strerror (errno));
162
163   handler->content_size += size;
164
165   return 0;
166 }
167
168 /* Write a unsigned 32-bit integer to datastream file represented by
169    HANDLER.  */
170
171 #define ctf_save_write_uint32(HANDLER, U32) \
172   ctf_save_write (HANDLER, (gdb_byte *) &U32, 4)
173
174 /* Write a signed 32-bit integer to datastream file represented by
175    HANDLER.  */
176
177 #define ctf_save_write_int32(HANDLER, INT32) \
178   ctf_save_write ((HANDLER), (gdb_byte *) &(INT32), 4)
179
180 /* Set datastream file position.  Update HANDLER->content_size
181    if WHENCE is SEEK_CUR.  */
182
183 static int
184 ctf_save_fseek (struct trace_write_handler *handler, long offset,
185                 int whence)
186 {
187   gdb_assert (whence != SEEK_END);
188   gdb_assert (whence != SEEK_SET
189               || offset <= handler->content_size + handler->packet_start);
190
191   if (fseek (handler->datastream_fd, offset, whence))
192     error (_("Unable to seek file for saving trace data (%s)"),
193            safe_strerror (errno));
194
195   if (whence == SEEK_CUR)
196     handler->content_size += offset;
197
198   return 0;
199 }
200
201 /* Change the datastream file position to align on ALIGN_SIZE,
202    and write BUF to datastream file.  The size of BUF is SIZE.  */
203
204 static int
205 ctf_save_align_write (struct trace_write_handler *handler,
206                       const gdb_byte *buf,
207                       size_t size, size_t align_size)
208 {
209   long offset
210     = (align_up (handler->content_size, align_size)
211        - handler->content_size);
212
213   if (ctf_save_fseek (handler, offset, SEEK_CUR))
214     return -1;
215
216   if (ctf_save_write (handler, buf, size))
217     return -1;
218
219   return 0;
220 }
221
222 /* Write events to next new packet.  */
223
224 static void
225 ctf_save_next_packet (struct trace_write_handler *handler)
226 {
227   handler->packet_start += (handler->content_size + 4);
228   ctf_save_fseek (handler, handler->packet_start, SEEK_SET);
229   handler->content_size = 0;
230 }
231
232 /* Write the CTF metadata header.  */
233
234 static void
235 ctf_save_metadata_header (struct trace_write_handler *handler)
236 {
237   ctf_save_write_metadata (handler, "/* CTF %d.%d */\n",
238                            CTF_SAVE_MAJOR, CTF_SAVE_MINOR);
239   ctf_save_write_metadata (handler,
240                            "typealias integer { size = 8; align = 8; "
241                            "signed = false; encoding = ascii;}"
242                            " := ascii;\n");
243   ctf_save_write_metadata (handler,
244                            "typealias integer { size = 8; align = 8; "
245                            "signed = false; }"
246                            " := uint8_t;\n");
247   ctf_save_write_metadata (handler,
248                            "typealias integer { size = 16; align = 16;"
249                            "signed = false; } := uint16_t;\n");
250   ctf_save_write_metadata (handler,
251                            "typealias integer { size = 32; align = 32;"
252                            "signed = false; } := uint32_t;\n");
253   ctf_save_write_metadata (handler,
254                            "typealias integer { size = 64; align = 64;"
255                            "signed = false; base = hex;}"
256                            " := uint64_t;\n");
257   ctf_save_write_metadata (handler,
258                            "typealias integer { size = 32; align = 32;"
259                            "signed = true; } := int32_t;\n");
260   ctf_save_write_metadata (handler,
261                            "typealias integer { size = 64; align = 64;"
262                            "signed = true; } := int64_t;\n");
263   ctf_save_write_metadata (handler,
264                            "typealias string { encoding = ascii;"
265                            " } := chars;\n");
266   ctf_save_write_metadata (handler, "\n");
267
268   /* Get the byte order of the host and write CTF data in this byte
269      order.  */
270 #if WORDS_BIGENDIAN
271 #define HOST_ENDIANNESS "be"
272 #else
273 #define HOST_ENDIANNESS "le"
274 #endif
275
276   ctf_save_write_metadata (handler,
277                            "\ntrace {\n"
278                            "    major = %u;\n"
279                            "    minor = %u;\n"
280                            "    byte_order = %s;\n"
281                            "    packet.header := struct {\n"
282                            "            uint32_t magic;\n"
283                            "    };\n"
284                            "};\n"
285                            "\n"
286                            "stream {\n"
287                            "    packet.context := struct {\n"
288                            "            uint32_t content_size;\n"
289                            "            uint32_t packet_size;\n"
290                            "            uint16_t tpnum;\n"
291                            "    };\n"
292                            "    event.header := struct {\n"
293                            "            uint32_t id;\n"
294                            "    };\n"
295                            "};\n",
296                            CTF_SAVE_MAJOR, CTF_SAVE_MINOR,
297                            HOST_ENDIANNESS);
298   ctf_save_write_metadata (handler, "\n");
299 }
300
301 /* CTF trace writer.  */
302
303 struct ctf_trace_file_writer
304 {
305   struct trace_file_writer base;
306
307   /* States related to writing CTF trace file.  */
308   struct trace_write_handler tcs;
309 };
310
311 /* This is the implementation of trace_file_write_ops method
312    dtor.  */
313
314 static void
315 ctf_dtor (struct trace_file_writer *self)
316 {
317   struct ctf_trace_file_writer *writer
318     = (struct ctf_trace_file_writer *) self;
319
320   if (writer->tcs.metadata_fd != NULL)
321     fclose (writer->tcs.metadata_fd);
322
323   if (writer->tcs.datastream_fd != NULL)
324     fclose (writer->tcs.datastream_fd);
325
326 }
327
328 /* This is the implementation of trace_file_write_ops method
329    target_save.  */
330
331 static int
332 ctf_target_save (struct trace_file_writer *self,
333                  const char *dirname)
334 {
335   /* Don't support save trace file to CTF format in the target.  */
336   return 0;
337 }
338
339 /* This is the implementation of trace_file_write_ops method
340    start.  It creates the directory DIRNAME, metadata and datastream
341    in the directory.  */
342
343 static void
344 ctf_start (struct trace_file_writer *self, const char *dirname)
345 {
346   struct ctf_trace_file_writer *writer
347     = (struct ctf_trace_file_writer *) self;
348   mode_t hmode = S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH;
349
350   /* Create DIRNAME.  */
351   if (mkdir (dirname, hmode) && errno != EEXIST)
352     error (_("Unable to open directory '%s' for saving trace data (%s)"),
353            dirname, safe_strerror (errno));
354
355   memset (&writer->tcs, '\0', sizeof (writer->tcs));
356
357   std::string file_name = string_printf ("%s/%s", dirname, CTF_METADATA_NAME);
358
359   writer->tcs.metadata_fd
360     = gdb_fopen_cloexec (file_name.c_str (), "w").release ();
361   if (writer->tcs.metadata_fd == NULL)
362     error (_("Unable to open file '%s' for saving trace data (%s)"),
363            file_name.c_str (), safe_strerror (errno));
364
365   ctf_save_metadata_header (&writer->tcs);
366
367   file_name = string_printf ("%s/%s", dirname, CTF_DATASTREAM_NAME);
368   writer->tcs.datastream_fd
369     = gdb_fopen_cloexec (file_name.c_str (), "w").release ();
370   if (writer->tcs.datastream_fd == NULL)
371     error (_("Unable to open file '%s' for saving trace data (%s)"),
372            file_name.c_str (), safe_strerror (errno));
373 }
374
375 /* This is the implementation of trace_file_write_ops method
376    write_header.  Write the types of events on trace variable and
377    frame.  */
378
379 static void
380 ctf_write_header (struct trace_file_writer *self)
381 {
382   struct ctf_trace_file_writer *writer
383     = (struct ctf_trace_file_writer *) self;
384
385
386   ctf_save_write_metadata (&writer->tcs, "\n");
387   ctf_save_write_metadata (&writer->tcs,
388                            "event {\n\tname = \"memory\";\n\tid = %u;\n"
389                            "\tfields := struct { \n"
390                            "\t\tuint64_t address;\n"
391                            "\t\tuint16_t length;\n"
392                            "\t\tuint8_t contents[length];\n"
393                            "\t};\n"
394                            "};\n", CTF_EVENT_ID_MEMORY);
395
396   ctf_save_write_metadata (&writer->tcs, "\n");
397   ctf_save_write_metadata (&writer->tcs,
398                            "event {\n\tname = \"tsv\";\n\tid = %u;\n"
399                            "\tfields := struct { \n"
400                            "\t\tuint64_t val;\n"
401                            "\t\tuint32_t num;\n"
402                            "\t};\n"
403                            "};\n", CTF_EVENT_ID_TSV);
404
405   ctf_save_write_metadata (&writer->tcs, "\n");
406   ctf_save_write_metadata (&writer->tcs,
407                            "event {\n\tname = \"frame\";\n\tid = %u;\n"
408                            "\tfields := struct { \n"
409                            "\t};\n"
410                            "};\n", CTF_EVENT_ID_FRAME);
411
412   ctf_save_write_metadata (&writer->tcs, "\n");
413   ctf_save_write_metadata (&writer->tcs,
414                           "event {\n\tname = \"tsv_def\";\n"
415                           "\tid = %u;\n\tfields := struct { \n"
416                           "\t\tint64_t initial_value;\n"
417                           "\t\tint32_t number;\n"
418                           "\t\tint32_t builtin;\n"
419                           "\t\tchars name;\n"
420                           "\t};\n"
421                           "};\n", CTF_EVENT_ID_TSV_DEF);
422
423   ctf_save_write_metadata (&writer->tcs, "\n");
424   ctf_save_write_metadata (&writer->tcs,
425                            "event {\n\tname = \"tp_def\";\n"
426                            "\tid = %u;\n\tfields := struct { \n"
427                            "\t\tuint64_t addr;\n"
428                            "\t\tuint64_t traceframe_usage;\n"
429                            "\t\tint32_t number;\n"
430                            "\t\tint32_t enabled;\n"
431                            "\t\tint32_t step;\n"
432                            "\t\tint32_t pass;\n"
433                            "\t\tint32_t hit_count;\n"
434                            "\t\tint32_t type;\n"
435                            "\t\tchars cond;\n"
436
437                           "\t\tuint32_t action_num;\n"
438                           "\t\tchars actions[action_num];\n"
439
440                           "\t\tuint32_t step_action_num;\n"
441                           "\t\tchars step_actions[step_action_num];\n"
442
443                           "\t\tchars at_string;\n"
444                           "\t\tchars cond_string;\n"
445
446                           "\t\tuint32_t cmd_num;\n"
447                           "\t\tchars cmd_strings[cmd_num];\n"
448                           "\t};\n"
449                           "};\n", CTF_EVENT_ID_TP_DEF);
450
451   gdb_assert (writer->tcs.content_size == 0);
452   gdb_assert (writer->tcs.packet_start == 0);
453
454   /* Create a new packet to contain this event.  */
455   self->ops->frame_ops->start (self, 0);
456 }
457
458 /* This is the implementation of trace_file_write_ops method
459    write_regblock_type.  Write the type of register event in
460    metadata.  */
461
462 static void
463 ctf_write_regblock_type (struct trace_file_writer *self, int size)
464 {
465   struct ctf_trace_file_writer *writer
466     = (struct ctf_trace_file_writer *) self;
467
468   ctf_save_write_metadata (&writer->tcs, "\n");
469
470   ctf_save_write_metadata (&writer->tcs,
471                            "event {\n\tname = \"register\";\n\tid = %u;\n"
472                            "\tfields := struct { \n"
473                            "\t\tascii contents[%d];\n"
474                            "\t};\n"
475                            "};\n",
476                            CTF_EVENT_ID_REGISTER, size);
477 }
478
479 /* This is the implementation of trace_file_write_ops method
480    write_status.  */
481
482 static void
483 ctf_write_status (struct trace_file_writer *self,
484                   struct trace_status *ts)
485 {
486   struct ctf_trace_file_writer *writer
487     = (struct ctf_trace_file_writer *) self;
488   uint32_t id;
489
490   ctf_save_write_metadata (&writer->tcs, "\n");
491   ctf_save_write_metadata (&writer->tcs,
492                            "event {\n\tname = \"status\";\n\tid = %u;\n"
493                            "\tfields := struct { \n"
494                            "\t\tint32_t stop_reason;\n"
495                            "\t\tint32_t stopping_tracepoint;\n"
496                            "\t\tint32_t traceframe_count;\n"
497                            "\t\tint32_t traceframes_created;\n"
498                            "\t\tint32_t buffer_free;\n"
499                            "\t\tint32_t buffer_size;\n"
500                            "\t\tint32_t disconnected_tracing;\n"
501                            "\t\tint32_t circular_buffer;\n"
502                            "\t};\n"
503                            "};\n",
504                            CTF_EVENT_ID_STATUS);
505
506   id = CTF_EVENT_ID_STATUS;
507   /* Event Id.  */
508   ctf_save_align_write (&writer->tcs, (gdb_byte *) &id, 4, 4);
509
510   ctf_save_write_int32 (&writer->tcs, ts->stop_reason);
511   ctf_save_write_int32 (&writer->tcs, ts->stopping_tracepoint);
512   ctf_save_write_int32 (&writer->tcs, ts->traceframe_count);
513   ctf_save_write_int32 (&writer->tcs, ts->traceframes_created);
514   ctf_save_write_int32 (&writer->tcs, ts->buffer_free);
515   ctf_save_write_int32 (&writer->tcs, ts->buffer_size);
516   ctf_save_write_int32 (&writer->tcs, ts->disconnected_tracing);
517   ctf_save_write_int32 (&writer->tcs, ts->circular_buffer);
518 }
519
520 /* This is the implementation of trace_file_write_ops method
521    write_uploaded_tsv.  */
522
523 static void
524 ctf_write_uploaded_tsv (struct trace_file_writer *self,
525                         struct uploaded_tsv *tsv)
526 {
527   struct ctf_trace_file_writer *writer
528     = (struct ctf_trace_file_writer *) self;
529   int32_t int32;
530   int64_t int64;
531   const gdb_byte zero = 0;
532
533   /* Event Id.  */
534   int32 = CTF_EVENT_ID_TSV_DEF;
535   ctf_save_align_write (&writer->tcs, (gdb_byte *) &int32, 4, 4);
536
537   /* initial_value */
538   int64 = tsv->initial_value;
539   ctf_save_align_write (&writer->tcs, (gdb_byte *) &int64, 8, 8);
540
541   /* number */
542   ctf_save_write_int32 (&writer->tcs, tsv->number);
543
544   /* builtin */
545   ctf_save_write_int32 (&writer->tcs, tsv->builtin);
546
547   /* name */
548   if (tsv->name != NULL)
549     ctf_save_write (&writer->tcs, (gdb_byte *) tsv->name,
550                     strlen (tsv->name));
551   ctf_save_write (&writer->tcs, &zero, 1);
552 }
553
554 /* This is the implementation of trace_file_write_ops method
555    write_uploaded_tp.  */
556
557 static void
558 ctf_write_uploaded_tp (struct trace_file_writer *self,
559                        struct uploaded_tp *tp)
560 {
561   struct ctf_trace_file_writer *writer
562     = (struct ctf_trace_file_writer *) self;
563   int32_t int32;
564   int64_t int64;
565   uint32_t u32;
566   const gdb_byte zero = 0;
567
568   /* Event Id.  */
569   int32 = CTF_EVENT_ID_TP_DEF;
570   ctf_save_align_write (&writer->tcs, (gdb_byte *) &int32, 4, 4);
571
572   /* address */
573   int64 = tp->addr;
574   ctf_save_align_write (&writer->tcs, (gdb_byte *) &int64, 8, 8);
575
576   /* traceframe_usage */
577   int64 = tp->traceframe_usage;
578   ctf_save_align_write (&writer->tcs, (gdb_byte *) &int64, 8, 8);
579
580   /* number */
581   ctf_save_write_int32 (&writer->tcs, tp->number);
582
583   /* enabled */
584   ctf_save_write_int32 (&writer->tcs, tp->enabled);
585
586   /* step */
587   ctf_save_write_int32 (&writer->tcs, tp->step);
588
589   /* pass */
590   ctf_save_write_int32 (&writer->tcs, tp->pass);
591
592   /* hit_count */
593   ctf_save_write_int32 (&writer->tcs, tp->hit_count);
594
595   /* type */
596   ctf_save_write_int32 (&writer->tcs, tp->type);
597
598   /* condition  */
599   if (tp->cond != NULL)
600     ctf_save_write (&writer->tcs, (gdb_byte *) tp->cond.get (),
601                     strlen (tp->cond.get ()));
602   ctf_save_write (&writer->tcs, &zero, 1);
603
604   /* actions */
605   u32 = tp->actions.size ();
606   ctf_save_align_write (&writer->tcs, (gdb_byte *) &u32, 4, 4);
607   for (const auto &act : tp->actions)
608     ctf_save_write (&writer->tcs, (gdb_byte *) act.get (),
609                     strlen (act.get ()) + 1);
610
611   /* step_actions */
612   u32 = tp->step_actions.size ();
613   ctf_save_align_write (&writer->tcs, (gdb_byte *) &u32, 4, 4);
614   for (const auto &act : tp->step_actions)
615     ctf_save_write (&writer->tcs, (gdb_byte *) act.get (),
616                     strlen (act.get ()) + 1);
617
618   /* at_string */
619   if (tp->at_string != NULL)
620     ctf_save_write (&writer->tcs, (gdb_byte *) tp->at_string.get (),
621                     strlen (tp->at_string.get ()));
622   ctf_save_write (&writer->tcs, &zero, 1);
623
624   /* cond_string */
625   if (tp->cond_string != NULL)
626     ctf_save_write (&writer->tcs, (gdb_byte *) tp->cond_string.get (),
627                     strlen (tp->cond_string.get ()));
628   ctf_save_write (&writer->tcs, &zero, 1);
629
630   /* cmd_strings */
631   u32 = tp->cmd_strings.size ();
632   ctf_save_align_write (&writer->tcs, (gdb_byte *) &u32, 4, 4);
633   for (const auto &act : tp->cmd_strings)
634     ctf_save_write (&writer->tcs, (gdb_byte *) act.get (),
635                     strlen (act.get ()) + 1);
636
637 }
638
639 /* This is the implementation of trace_file_write_ops method
640    write_tdesc.  */
641
642 static void
643 ctf_write_tdesc (struct trace_file_writer *self)
644 {
645   /* Nothing so far. */
646 }
647
648 /* This is the implementation of trace_file_write_ops method
649    write_definition_end.  */
650
651 static void
652 ctf_write_definition_end (struct trace_file_writer *self)
653 {
654   self->ops->frame_ops->end (self);
655 }
656
657 /* This is the implementation of trace_file_write_ops method
658    end.  */
659
660 static void
661 ctf_end (struct trace_file_writer *self)
662 {
663   struct ctf_trace_file_writer *writer = (struct ctf_trace_file_writer *) self;
664
665   gdb_assert (writer->tcs.content_size == 0);
666 }
667
668 /* This is the implementation of trace_frame_write_ops method
669    start.  */
670
671 static void
672 ctf_write_frame_start (struct trace_file_writer *self, uint16_t tpnum)
673 {
674   struct ctf_trace_file_writer *writer
675     = (struct ctf_trace_file_writer *) self;
676   uint32_t id = CTF_EVENT_ID_FRAME;
677   uint32_t u32;
678
679   /* Step 1: Write packet context.  */
680   /* magic.  */
681   u32 = CTF_MAGIC;
682   ctf_save_write_uint32 (&writer->tcs, u32);
683   /* content_size and packet_size..  We still don't know the value,
684      write it later.  */
685   ctf_save_fseek (&writer->tcs, 4, SEEK_CUR);
686   ctf_save_fseek (&writer->tcs, 4, SEEK_CUR);
687   /* Tracepoint number.  */
688   ctf_save_write (&writer->tcs, (gdb_byte *) &tpnum, 2);
689
690   /* Step 2: Write event "frame".  */
691   /* Event Id.  */
692   ctf_save_align_write (&writer->tcs, (gdb_byte *) &id, 4, 4);
693 }
694
695 /* This is the implementation of trace_frame_write_ops method
696    write_r_block.  */
697
698 static void
699 ctf_write_frame_r_block (struct trace_file_writer *self,
700                          gdb_byte *buf, int32_t size)
701 {
702   struct ctf_trace_file_writer *writer
703     = (struct ctf_trace_file_writer *) self;
704   uint32_t id = CTF_EVENT_ID_REGISTER;
705
706   /* Event Id.  */
707   ctf_save_align_write (&writer->tcs, (gdb_byte *) &id, 4, 4);
708
709   /* array contents.  */
710   ctf_save_align_write (&writer->tcs, buf, size, 1);
711 }
712
713 /* This is the implementation of trace_frame_write_ops method
714    write_m_block_header.  */
715
716 static void
717 ctf_write_frame_m_block_header (struct trace_file_writer *self,
718                                 uint64_t addr, uint16_t length)
719 {
720   struct ctf_trace_file_writer *writer
721     = (struct ctf_trace_file_writer *) self;
722   uint32_t event_id = CTF_EVENT_ID_MEMORY;
723
724   /* Event Id.  */
725   ctf_save_align_write (&writer->tcs, (gdb_byte *) &event_id, 4, 4);
726
727   /* Address.  */
728   ctf_save_align_write (&writer->tcs, (gdb_byte *) &addr, 8, 8);
729
730   /* Length.  */
731   ctf_save_align_write (&writer->tcs, (gdb_byte *) &length, 2, 2);
732 }
733
734 /* This is the implementation of trace_frame_write_ops method
735    write_m_block_memory.  */
736
737 static void
738 ctf_write_frame_m_block_memory (struct trace_file_writer *self,
739                                 gdb_byte *buf, uint16_t length)
740 {
741   struct ctf_trace_file_writer *writer
742     = (struct ctf_trace_file_writer *) self;
743
744   /* Contents.  */
745   ctf_save_align_write (&writer->tcs, (gdb_byte *) buf, length, 1);
746 }
747
748 /* This is the implementation of trace_frame_write_ops method
749    write_v_block.  */
750
751 static void
752 ctf_write_frame_v_block (struct trace_file_writer *self,
753                          int32_t num, uint64_t val)
754 {
755   struct ctf_trace_file_writer *writer
756     = (struct ctf_trace_file_writer *) self;
757   uint32_t id = CTF_EVENT_ID_TSV;
758
759   /* Event Id.  */
760   ctf_save_align_write (&writer->tcs, (gdb_byte *) &id, 4, 4);
761
762   /* val.  */
763   ctf_save_align_write (&writer->tcs, (gdb_byte *) &val, 8, 8);
764   /* num.  */
765   ctf_save_align_write (&writer->tcs, (gdb_byte *) &num, 4, 4);
766 }
767
768 /* This is the implementation of trace_frame_write_ops method
769    end.  */
770
771 static void
772 ctf_write_frame_end (struct trace_file_writer *self)
773 {
774   struct ctf_trace_file_writer *writer
775     = (struct ctf_trace_file_writer *) self;
776   uint32_t u32;
777   uint32_t t;
778
779   /* Write the content size to packet header.  */
780   ctf_save_fseek (&writer->tcs, writer->tcs.packet_start + 4,
781                   SEEK_SET);
782   u32 = writer->tcs.content_size * TARGET_CHAR_BIT;
783
784   t = writer->tcs.content_size;
785   ctf_save_write_uint32 (&writer->tcs, u32);
786
787   /* Write the packet size.  */
788   u32 += 4 * TARGET_CHAR_BIT;
789   ctf_save_write_uint32 (&writer->tcs, u32);
790
791   writer->tcs.content_size = t;
792
793   /* Write zero at the end of the packet.  */
794   ctf_save_fseek (&writer->tcs, writer->tcs.packet_start + t,
795                   SEEK_SET);
796   u32 = 0;
797   ctf_save_write_uint32 (&writer->tcs, u32);
798   writer->tcs.content_size = t;
799
800   ctf_save_next_packet (&writer->tcs);
801 }
802
803 /* Operations to write various types of trace frames into CTF
804    format.  */
805
806 static const struct trace_frame_write_ops ctf_write_frame_ops =
807 {
808   ctf_write_frame_start,
809   ctf_write_frame_r_block,
810   ctf_write_frame_m_block_header,
811   ctf_write_frame_m_block_memory,
812   ctf_write_frame_v_block,
813   ctf_write_frame_end,
814 };
815
816 /* Operations to write trace buffers into CTF format.  */
817
818 static const struct trace_file_write_ops ctf_write_ops =
819 {
820   ctf_dtor,
821   ctf_target_save,
822   ctf_start,
823   ctf_write_header,
824   ctf_write_regblock_type,
825   ctf_write_status,
826   ctf_write_uploaded_tsv,
827   ctf_write_uploaded_tp,
828   ctf_write_tdesc,
829   ctf_write_definition_end,
830   NULL,
831   &ctf_write_frame_ops,
832   ctf_end,
833 };
834
835 /* Return a trace writer for CTF format.  */
836
837 struct trace_file_writer *
838 ctf_trace_file_writer_new (void)
839 {
840   struct ctf_trace_file_writer *writer = XNEW (struct ctf_trace_file_writer);
841
842   writer->base.ops = &ctf_write_ops;
843
844   return (struct trace_file_writer *) writer;
845 }
846
847 #if HAVE_LIBBABELTRACE
848 /* Use libbabeltrace to read CTF data.  The libbabeltrace provides
849    iterator to iterate over each event in CTF data and APIs to get
850    details of event and packet, so it is very convenient to use
851    libbabeltrace to access events in CTF.  */
852
853 #include <babeltrace/babeltrace.h>
854 #include <babeltrace/ctf/events.h>
855 #include <babeltrace/ctf/iterator.h>
856
857 /* The struct pointer for current CTF directory.  */
858 static int handle_id = -1;
859 static struct bt_context *ctx = NULL;
860 static struct bt_ctf_iter *ctf_iter = NULL;
861 /* The position of the first packet containing trace frame.  */
862 static struct bt_iter_pos *start_pos;
863
864 /* The name of CTF directory.  */
865 static char *trace_dirname;
866
867 static ctf_target ctf_ops;
868
869 /* Destroy ctf iterator and context.  */
870
871 static void
872 ctf_destroy (void)
873 {
874   if (ctf_iter != NULL)
875     {
876       bt_ctf_iter_destroy (ctf_iter);
877       ctf_iter = NULL;
878     }
879   if (ctx != NULL)
880     {
881       bt_context_put (ctx);
882       ctx = NULL;
883     }
884 }
885
886 /* Open CTF trace data in DIRNAME.  */
887
888 static void
889 ctf_open_dir (const char *dirname)
890 {
891   struct bt_iter_pos begin_pos;
892   unsigned int count, i;
893   struct bt_ctf_event_decl * const *list;
894
895   ctx = bt_context_create ();
896   if (ctx == NULL)
897     error (_("Unable to create bt_context"));
898   handle_id = bt_context_add_trace (ctx, dirname, "ctf", NULL, NULL, NULL);
899   if (handle_id < 0)
900     {
901       ctf_destroy ();
902       error (_("Unable to use libbabeltrace on directory \"%s\""),
903              dirname);
904     }
905
906   begin_pos.type = BT_SEEK_BEGIN;
907   ctf_iter = bt_ctf_iter_create (ctx, &begin_pos, NULL);
908   if (ctf_iter == NULL)
909     {
910       ctf_destroy ();
911       error (_("Unable to create bt_iterator"));
912     }
913
914   /* Look for the declaration of register block.  Get the length of
915      array "contents" to set trace_regblock_size.  */
916
917   bt_ctf_get_event_decl_list (handle_id, ctx, &list, &count);
918   for (i = 0; i < count; i++)
919     if (strcmp ("register", bt_ctf_get_decl_event_name (list[i])) == 0)
920       {
921         const struct bt_ctf_field_decl * const *field_list;
922         const struct bt_declaration *decl;
923
924         bt_ctf_get_decl_fields (list[i], BT_EVENT_FIELDS, &field_list,
925                                 &count);
926
927         gdb_assert (count == 1);
928         gdb_assert (0 == strcmp ("contents",
929                                  bt_ctf_get_decl_field_name (field_list[0])));
930         decl = bt_ctf_get_decl_from_field_decl (field_list[0]);
931         trace_regblock_size = bt_ctf_get_array_len (decl);
932
933         break;
934       }
935 }
936
937 #define SET_INT32_FIELD(EVENT, SCOPE, VAR, FIELD)                       \
938   (VAR)->FIELD = (int) bt_ctf_get_int64 (bt_ctf_get_field ((EVENT),     \
939                                                            (SCOPE),     \
940                                                            #FIELD))
941
942 #define SET_ENUM_FIELD(EVENT, SCOPE, VAR, TYPE, FIELD)                  \
943   (VAR)->FIELD = (TYPE) bt_ctf_get_int64 (bt_ctf_get_field ((EVENT),    \
944                                                             (SCOPE),    \
945                                                             #FIELD))
946
947
948 /* EVENT is the "status" event and TS is filled in.  */
949
950 static void
951 ctf_read_status (struct bt_ctf_event *event, struct trace_status *ts)
952 {
953   const struct bt_definition *scope
954     = bt_ctf_get_top_level_scope (event, BT_EVENT_FIELDS);
955
956   SET_ENUM_FIELD (event, scope, ts, enum trace_stop_reason, stop_reason);
957   SET_INT32_FIELD (event, scope, ts, stopping_tracepoint);
958   SET_INT32_FIELD (event, scope, ts, traceframe_count);
959   SET_INT32_FIELD (event, scope, ts, traceframes_created);
960   SET_INT32_FIELD (event, scope, ts, buffer_free);
961   SET_INT32_FIELD (event, scope, ts, buffer_size);
962   SET_INT32_FIELD (event, scope, ts, disconnected_tracing);
963   SET_INT32_FIELD (event, scope, ts, circular_buffer);
964
965   bt_iter_next (bt_ctf_get_iter (ctf_iter));
966 }
967
968 /* Read the events "tsv_def" one by one, extract its contents and fill
969    in the list UPLOADED_TSVS.  */
970
971 static void
972 ctf_read_tsv (struct uploaded_tsv **uploaded_tsvs)
973 {
974   gdb_assert (ctf_iter != NULL);
975
976   while (1)
977     {
978       struct bt_ctf_event *event;
979       const struct bt_definition *scope;
980       const struct bt_definition *def;
981       uint32_t event_id;
982       struct uploaded_tsv *utsv = NULL;
983
984       event = bt_ctf_iter_read_event (ctf_iter);
985       scope = bt_ctf_get_top_level_scope (event,
986                                           BT_STREAM_EVENT_HEADER);
987       event_id = bt_ctf_get_uint64 (bt_ctf_get_field (event, scope,
988                                                       "id"));
989       if (event_id != CTF_EVENT_ID_TSV_DEF)
990         break;
991
992       scope = bt_ctf_get_top_level_scope (event,
993                                           BT_EVENT_FIELDS);
994
995       def = bt_ctf_get_field (event, scope, "number");
996       utsv = get_uploaded_tsv ((int32_t) bt_ctf_get_int64 (def),
997                                uploaded_tsvs);
998
999       def = bt_ctf_get_field (event, scope, "builtin");
1000       utsv->builtin = (int32_t) bt_ctf_get_int64 (def);
1001       def = bt_ctf_get_field (event, scope, "initial_value");
1002       utsv->initial_value = bt_ctf_get_int64 (def);
1003
1004       def = bt_ctf_get_field (event, scope, "name");
1005       utsv->name =  xstrdup (bt_ctf_get_string (def));
1006
1007       if (bt_iter_next (bt_ctf_get_iter (ctf_iter)) < 0)
1008         break;
1009     }
1010
1011 }
1012
1013 /* Read the value of element whose index is NUM from CTF and write it
1014    to the corresponding VAR->ARRAY. */
1015
1016 #define SET_ARRAY_FIELD(EVENT, SCOPE, VAR, NUM, ARRAY)  \
1017   do                                                    \
1018     {                                                   \
1019       uint32_t lu32, i;                                         \
1020       const struct bt_definition *def;                          \
1021                                                                 \
1022       lu32 = (uint32_t) bt_ctf_get_uint64 (bt_ctf_get_field ((EVENT),   \
1023                                                              (SCOPE),   \
1024                                                              #NUM));    \
1025       def = bt_ctf_get_field ((EVENT), (SCOPE), #ARRAY);                \
1026       for (i = 0; i < lu32; i++)                                        \
1027         {                                                               \
1028           const struct bt_definition *element                           \
1029             = bt_ctf_get_index ((EVENT), def, i);                       \
1030                                                                         \
1031           (VAR)->ARRAY.emplace_back                                     \
1032             (xstrdup (bt_ctf_get_string (element)));                    \
1033         }                                                               \
1034     }                                                                   \
1035   while (0)
1036
1037 /* Read a string from CTF and set VAR->FIELD. If the length of string
1038    is zero, set VAR->FIELD to NULL.  */
1039
1040 #define SET_STRING_FIELD(EVENT, SCOPE, VAR, FIELD)                      \
1041   do                                                                    \
1042     {                                                                   \
1043       const char *p = bt_ctf_get_string (bt_ctf_get_field ((EVENT),     \
1044                                                            (SCOPE),     \
1045                                                            #FIELD));    \
1046                                                                         \
1047       if (strlen (p) > 0)                                               \
1048         (VAR)->FIELD.reset (xstrdup (p));                               \
1049       else                                                              \
1050         (VAR)->FIELD = NULL;                                            \
1051     }                                                                   \
1052   while (0)
1053
1054 /* Read the events "tp_def" one by one, extract its contents and fill
1055    in the list UPLOADED_TPS.  */
1056
1057 static void
1058 ctf_read_tp (struct uploaded_tp **uploaded_tps)
1059 {
1060   gdb_assert (ctf_iter != NULL);
1061
1062   while (1)
1063     {
1064       struct bt_ctf_event *event;
1065       const struct bt_definition *scope;
1066       uint32_t u32;
1067       int32_t int32;
1068       uint64_t u64;
1069       struct uploaded_tp *utp = NULL;
1070
1071       event = bt_ctf_iter_read_event (ctf_iter);
1072       scope = bt_ctf_get_top_level_scope (event,
1073                                           BT_STREAM_EVENT_HEADER);
1074       u32 = bt_ctf_get_uint64 (bt_ctf_get_field (event, scope,
1075                                                  "id"));
1076       if (u32 != CTF_EVENT_ID_TP_DEF)
1077         break;
1078
1079       scope = bt_ctf_get_top_level_scope (event,
1080                                           BT_EVENT_FIELDS);
1081       int32 = (int32_t) bt_ctf_get_int64 (bt_ctf_get_field (event,
1082                                                             scope,
1083                                                             "number"));
1084       u64 = bt_ctf_get_uint64 (bt_ctf_get_field (event, scope,
1085                                                  "addr"));
1086       utp = get_uploaded_tp (int32, u64,  uploaded_tps);
1087
1088       SET_INT32_FIELD (event, scope, utp, enabled);
1089       SET_INT32_FIELD (event, scope, utp, step);
1090       SET_INT32_FIELD (event, scope, utp, pass);
1091       SET_INT32_FIELD (event, scope, utp, hit_count);
1092       SET_ENUM_FIELD (event, scope, utp, enum bptype, type);
1093
1094       /* Read 'cmd_strings'.  */
1095       SET_ARRAY_FIELD (event, scope, utp, cmd_num, cmd_strings);
1096       /* Read 'actions'.  */
1097       SET_ARRAY_FIELD (event, scope, utp, action_num, actions);
1098       /* Read 'step_actions'.  */
1099       SET_ARRAY_FIELD (event, scope, utp, step_action_num,
1100                        step_actions);
1101
1102       SET_STRING_FIELD(event, scope, utp, at_string);
1103       SET_STRING_FIELD(event, scope, utp, cond_string);
1104
1105       if (bt_iter_next (bt_ctf_get_iter (ctf_iter)) < 0)
1106         break;
1107     }
1108 }
1109
1110 /* This is the implementation of target_ops method to_open.  Open CTF
1111    trace data, read trace status, trace state variables and tracepoint
1112    definitions from the first packet.  Set the start position at the
1113    second packet which contains events on trace blocks.  */
1114
1115 static void
1116 ctf_target_open (const char *dirname, int from_tty)
1117 {
1118   struct bt_ctf_event *event;
1119   uint32_t event_id;
1120   const struct bt_definition *scope;
1121   struct uploaded_tsv *uploaded_tsvs = NULL;
1122   struct uploaded_tp *uploaded_tps = NULL;
1123
1124   if (!dirname)
1125     error (_("No CTF directory specified."));
1126
1127   ctf_open_dir (dirname);
1128
1129   target_preopen (from_tty);
1130
1131   /* Skip the first packet which about the trace status.  The first
1132      event is "frame".  */
1133   event = bt_ctf_iter_read_event (ctf_iter);
1134   scope = bt_ctf_get_top_level_scope (event, BT_STREAM_EVENT_HEADER);
1135   event_id = bt_ctf_get_uint64 (bt_ctf_get_field (event, scope, "id"));
1136   if (event_id != CTF_EVENT_ID_FRAME)
1137     error (_("Wrong event id of the first event"));
1138   /* The second event is "status".  */
1139   bt_iter_next (bt_ctf_get_iter (ctf_iter));
1140   event = bt_ctf_iter_read_event (ctf_iter);
1141   scope = bt_ctf_get_top_level_scope (event, BT_STREAM_EVENT_HEADER);
1142   event_id = bt_ctf_get_uint64 (bt_ctf_get_field (event, scope, "id"));
1143   if (event_id != CTF_EVENT_ID_STATUS)
1144     error (_("Wrong event id of the second event"));
1145   ctf_read_status (event, current_trace_status ());
1146
1147   ctf_read_tsv (&uploaded_tsvs);
1148
1149   ctf_read_tp (&uploaded_tps);
1150
1151   event = bt_ctf_iter_read_event (ctf_iter);
1152   /* EVENT can be NULL if we've already gone to the end of stream of
1153      events.  */
1154   if (event != NULL)
1155     {
1156       scope = bt_ctf_get_top_level_scope (event,
1157                                           BT_STREAM_EVENT_HEADER);
1158       event_id = bt_ctf_get_uint64 (bt_ctf_get_field (event,
1159                                                       scope, "id"));
1160       if (event_id != CTF_EVENT_ID_FRAME)
1161         error (_("Wrong event id of the first event of the second packet"));
1162     }
1163
1164   start_pos = bt_iter_get_pos (bt_ctf_get_iter (ctf_iter));
1165   gdb_assert (start_pos->type == BT_SEEK_RESTORE);
1166
1167   trace_dirname = xstrdup (dirname);
1168   current_inferior ()->push_target (&ctf_ops);
1169
1170   inferior_appeared (current_inferior (), CTF_PID);
1171
1172   thread_info *thr = add_thread_silent (&ctf_ops, ptid_t (CTF_PID));
1173   switch_to_thread (thr);
1174
1175   merge_uploaded_trace_state_variables (&uploaded_tsvs);
1176   merge_uploaded_tracepoints (&uploaded_tps);
1177
1178   post_create_inferior (from_tty);
1179 }
1180
1181 /* This is the implementation of target_ops method to_close.  Destroy
1182    CTF iterator and context.  */
1183
1184 void
1185 ctf_target::close ()
1186 {
1187   ctf_destroy ();
1188   xfree (trace_dirname);
1189   trace_dirname = NULL;
1190
1191   switch_to_no_thread ();       /* Avoid confusion from thread stuff.  */
1192   exit_inferior_silent (current_inferior ());
1193
1194   trace_reset_local_state ();
1195 }
1196
1197 /* This is the implementation of target_ops method to_files_info.
1198    Print the directory name of CTF trace data.  */
1199
1200 void
1201 ctf_target::files_info ()
1202 {
1203   gdb_printf ("\t`%s'\n", trace_dirname);
1204 }
1205
1206 /* This is the implementation of target_ops method to_fetch_registers.
1207    Iterate over events whose name is "register" in current frame,
1208    extract contents from events, and set REGCACHE with the contents.
1209    If no matched events are found, mark registers unavailable.  */
1210
1211 void
1212 ctf_target::fetch_registers (struct regcache *regcache, int regno)
1213 {
1214   struct gdbarch *gdbarch = regcache->arch ();
1215   struct bt_ctf_event *event = NULL;
1216   struct bt_iter_pos *pos;
1217
1218   /* An uninitialized reg size says we're not going to be
1219      successful at getting register blocks.  */
1220   if (trace_regblock_size == 0)
1221     return;
1222
1223   gdb_assert (ctf_iter != NULL);
1224   /* Save the current position.  */
1225   pos = bt_iter_get_pos (bt_ctf_get_iter (ctf_iter));
1226   gdb_assert (pos->type == BT_SEEK_RESTORE);
1227
1228   while (1)
1229     {
1230       const char *name;
1231       struct bt_ctf_event *event1;
1232
1233       event1 = bt_ctf_iter_read_event (ctf_iter);
1234
1235       name = bt_ctf_event_name (event1);
1236
1237       if (name == NULL || strcmp (name, "frame") == 0)
1238         break;
1239       else if (strcmp (name, "register") == 0)
1240         {
1241           event = event1;
1242           break;
1243         }
1244
1245       if (bt_iter_next (bt_ctf_get_iter (ctf_iter)) < 0)
1246         break;
1247     }
1248
1249   /* Restore the position.  */
1250   bt_iter_set_pos (bt_ctf_get_iter (ctf_iter), pos);
1251
1252   if (event != NULL)
1253     {
1254       int offset, regsize, regn;
1255       const struct bt_definition *scope
1256         = bt_ctf_get_top_level_scope (event,
1257                                       BT_EVENT_FIELDS);
1258       const struct bt_definition *array
1259         = bt_ctf_get_field (event, scope, "contents");
1260       gdb_byte *regs = (gdb_byte *) bt_ctf_get_char_array (array);
1261
1262       /* Assume the block is laid out in GDB register number order,
1263          each register with the size that it has in GDB.  */
1264       offset = 0;
1265       for (regn = 0; regn < gdbarch_num_regs (gdbarch); regn++)
1266         {
1267           regsize = register_size (gdbarch, regn);
1268           /* Make sure we stay within block bounds.  */
1269           if (offset + regsize >= trace_regblock_size)
1270             break;
1271           if (regcache->get_register_status (regn) == REG_UNKNOWN)
1272             {
1273               if (regno == regn)
1274                 {
1275                   regcache->raw_supply (regno, regs + offset);
1276                   break;
1277                 }
1278               else if (regno == -1)
1279                 {
1280                   regcache->raw_supply (regn, regs + offset);
1281                 }
1282             }
1283           offset += regsize;
1284         }
1285     }
1286   else
1287     tracefile_fetch_registers (regcache, regno);
1288 }
1289
1290 /* This is the implementation of target_ops method to_xfer_partial.
1291    Iterate over events whose name is "memory" in
1292    current frame, extract the address and length from events.  If
1293    OFFSET is within the range, read the contents from events to
1294    READBUF.  */
1295
1296 enum target_xfer_status
1297 ctf_target::xfer_partial (enum target_object object,
1298                           const char *annex, gdb_byte *readbuf,
1299                           const gdb_byte *writebuf, ULONGEST offset,
1300                           ULONGEST len, ULONGEST *xfered_len)
1301 {
1302   /* We're only doing regular memory for now.  */
1303   if (object != TARGET_OBJECT_MEMORY)
1304     return TARGET_XFER_E_IO;
1305
1306   if (readbuf == NULL)
1307     error (_("ctf_xfer_partial: trace file is read-only"));
1308
1309   if (get_traceframe_number () != -1)
1310     {
1311       struct bt_iter_pos *pos;
1312       enum target_xfer_status res;
1313       /* Records the lowest available address of all blocks that
1314          intersects the requested range.  */
1315       ULONGEST low_addr_available = 0;
1316
1317       gdb_assert (ctf_iter != NULL);
1318       /* Save the current position.  */
1319       pos = bt_iter_get_pos (bt_ctf_get_iter (ctf_iter));
1320       gdb_assert (pos->type == BT_SEEK_RESTORE);
1321
1322       /* Iterate through the traceframe's blocks, looking for
1323          memory.  */
1324       while (1)
1325         {
1326           ULONGEST amt;
1327           uint64_t maddr;
1328           uint16_t mlen;
1329           const struct bt_definition *scope;
1330           const struct bt_definition *def;
1331           struct bt_ctf_event *event
1332             = bt_ctf_iter_read_event (ctf_iter);
1333           const char *name = bt_ctf_event_name (event);
1334
1335           if (name == NULL || strcmp (name, "frame") == 0)
1336             break;
1337           else if (strcmp (name, "memory") != 0)
1338             {
1339               if (bt_iter_next (bt_ctf_get_iter (ctf_iter)) < 0)
1340                 break;
1341
1342               continue;
1343             }
1344
1345           scope = bt_ctf_get_top_level_scope (event,
1346                                               BT_EVENT_FIELDS);
1347
1348           def = bt_ctf_get_field (event, scope, "address");
1349           maddr = bt_ctf_get_uint64 (def);
1350           def = bt_ctf_get_field (event, scope, "length");
1351           mlen = (uint16_t) bt_ctf_get_uint64 (def);
1352
1353           /* If the block includes the first part of the desired
1354              range, return as much it has; GDB will re-request the
1355              remainder, which might be in a different block of this
1356              trace frame.  */
1357           if (maddr <= offset && offset < (maddr + mlen))
1358             {
1359               const struct bt_definition *array
1360                 = bt_ctf_get_field (event, scope, "contents");
1361               gdb_byte *contents;
1362               int k;
1363
1364               contents = (gdb_byte *) xmalloc (mlen);
1365
1366               for (k = 0; k < mlen; k++)
1367                 {
1368                   const struct bt_definition *element
1369                     = bt_ctf_get_index (event, array, k);
1370
1371                   contents[k] = (gdb_byte) bt_ctf_get_uint64 (element);
1372                 }
1373
1374               amt = (maddr + mlen) - offset;
1375               if (amt > len)
1376                 amt = len;
1377
1378               memcpy (readbuf, &contents[offset - maddr], amt);
1379
1380               xfree (contents);
1381
1382               /* Restore the position.  */
1383               bt_iter_set_pos (bt_ctf_get_iter (ctf_iter), pos);
1384
1385               if (amt == 0)
1386                 return TARGET_XFER_EOF;
1387               else
1388                 {
1389                   *xfered_len = amt;
1390                   return TARGET_XFER_OK;
1391                 }
1392             }
1393
1394           if (offset < maddr && maddr < (offset + len))
1395             if (low_addr_available == 0 || low_addr_available > maddr)
1396               low_addr_available = maddr;
1397
1398           if (bt_iter_next (bt_ctf_get_iter (ctf_iter)) < 0)
1399             break;
1400         }
1401
1402       /* Restore the position.  */
1403       bt_iter_set_pos (bt_ctf_get_iter (ctf_iter), pos);
1404
1405       /* Requested memory is unavailable in the context of traceframes,
1406          and this address falls within a read-only section, fallback
1407          to reading from executable, up to LOW_ADDR_AVAILABLE  */
1408       if (offset < low_addr_available)
1409         len = std::min (len, low_addr_available - offset);
1410       res = exec_read_partial_read_only (readbuf, offset, len, xfered_len);
1411
1412       if (res == TARGET_XFER_OK)
1413         return TARGET_XFER_OK;
1414       else
1415         {
1416           /* No use trying further, we know some memory starting
1417              at MEMADDR isn't available.  */
1418           *xfered_len = len;
1419           return TARGET_XFER_UNAVAILABLE;
1420         }
1421     }
1422   else
1423     {
1424       /* Fallback to reading from read-only sections.  */
1425       return section_table_read_available_memory (readbuf, offset, len, xfered_len);
1426     }
1427 }
1428
1429 /* This is the implementation of target_ops method
1430    to_get_trace_state_variable_value.
1431    Iterate over events whose name is "tsv" in current frame.  When the
1432    trace variable is found, set the value of it to *VAL and return
1433    true, otherwise return false.  */
1434
1435 bool
1436 ctf_target::get_trace_state_variable_value (int tsvnum, LONGEST *val)
1437 {
1438   struct bt_iter_pos *pos;
1439   bool found = false;
1440
1441   gdb_assert (ctf_iter != NULL);
1442   /* Save the current position.  */
1443   pos = bt_iter_get_pos (bt_ctf_get_iter (ctf_iter));
1444   gdb_assert (pos->type == BT_SEEK_RESTORE);
1445
1446   /* Iterate through the traceframe's blocks, looking for 'V'
1447      block.  */
1448   while (1)
1449     {
1450       struct bt_ctf_event *event
1451         = bt_ctf_iter_read_event (ctf_iter);
1452       const char *name = bt_ctf_event_name (event);
1453
1454       if (name == NULL || strcmp (name, "frame") == 0)
1455         break;
1456       else if (strcmp (name, "tsv") == 0)
1457         {
1458           const struct bt_definition *scope;
1459           const struct bt_definition *def;
1460
1461           scope = bt_ctf_get_top_level_scope (event,
1462                                               BT_EVENT_FIELDS);
1463
1464           def = bt_ctf_get_field (event, scope, "num");
1465           if (tsvnum == (int32_t) bt_ctf_get_uint64 (def))
1466             {
1467               def = bt_ctf_get_field (event, scope, "val");
1468               *val = bt_ctf_get_uint64 (def);
1469
1470               found = true;
1471             }
1472         }
1473
1474       if (bt_iter_next (bt_ctf_get_iter (ctf_iter)) < 0)
1475         break;
1476     }
1477
1478   /* Restore the position.  */
1479   bt_iter_set_pos (bt_ctf_get_iter (ctf_iter), pos);
1480
1481   return found;
1482 }
1483
1484 /* Return the tracepoint number in "frame" event.  */
1485
1486 static int
1487 ctf_get_tpnum_from_frame_event (struct bt_ctf_event *event)
1488 {
1489   /* The packet context of events has a field "tpnum".  */
1490   const struct bt_definition *scope
1491     = bt_ctf_get_top_level_scope (event, BT_STREAM_PACKET_CONTEXT);
1492   uint64_t tpnum
1493     = bt_ctf_get_uint64 (bt_ctf_get_field (event, scope, "tpnum"));
1494
1495   return (int) tpnum;
1496 }
1497
1498 /* Return the address at which the current frame was collected.  */
1499
1500 static CORE_ADDR
1501 ctf_get_traceframe_address (void)
1502 {
1503   struct bt_ctf_event *event = NULL;
1504   struct bt_iter_pos *pos;
1505   CORE_ADDR addr = 0;
1506
1507   gdb_assert (ctf_iter != NULL);
1508   pos  = bt_iter_get_pos (bt_ctf_get_iter (ctf_iter));
1509   gdb_assert (pos->type == BT_SEEK_RESTORE);
1510
1511   while (1)
1512     {
1513       const char *name;
1514       struct bt_ctf_event *event1;
1515
1516       event1 = bt_ctf_iter_read_event (ctf_iter);
1517
1518       name = bt_ctf_event_name (event1);
1519
1520       if (name == NULL)
1521         break;
1522       else if (strcmp (name, "frame") == 0)
1523         {
1524           event = event1;
1525           break;
1526         }
1527
1528       if (bt_iter_next (bt_ctf_get_iter (ctf_iter)) < 0)
1529         break;
1530     }
1531
1532   if (event != NULL)
1533     {
1534       int tpnum = ctf_get_tpnum_from_frame_event (event);
1535       struct tracepoint *tp
1536         = get_tracepoint_by_number_on_target (tpnum);
1537
1538       if (tp && tp->loc)
1539         addr = tp->loc->address;
1540     }
1541
1542   /* Restore the position.  */
1543   bt_iter_set_pos (bt_ctf_get_iter (ctf_iter), pos);
1544
1545   return addr;
1546 }
1547
1548 /* This is the implementation of target_ops method to_trace_find.
1549    Iterate the events whose name is "frame", extract the tracepoint
1550    number in it.  Return traceframe number when matched.  */
1551
1552 int
1553 ctf_target::trace_find (enum trace_find_type type, int num,
1554                         CORE_ADDR addr1, CORE_ADDR addr2, int *tpp)
1555 {
1556   int tfnum = 0;
1557   int found = 0;
1558
1559   if (num == -1)
1560     {
1561       if (tpp != NULL)
1562         *tpp = -1;
1563       return -1;
1564     }
1565
1566   gdb_assert (ctf_iter != NULL);
1567   /* Set iterator back to the start.  */
1568   bt_iter_set_pos (bt_ctf_get_iter (ctf_iter), start_pos);
1569
1570   while (1)
1571     {
1572       struct bt_ctf_event *event;
1573       const char *name;
1574
1575       event = bt_ctf_iter_read_event (ctf_iter);
1576
1577       name = bt_ctf_event_name (event);
1578
1579       if (event == NULL || name == NULL)
1580         break;
1581
1582       if (strcmp (name, "frame") == 0)
1583         {
1584           CORE_ADDR tfaddr;
1585
1586           if (type == tfind_number)
1587             {
1588               /* Looking for a specific trace frame.  */
1589               if (tfnum == num)
1590                 found = 1;
1591             }
1592           else
1593             {
1594               /* Start from the _next_ trace frame.  */
1595               if (tfnum > get_traceframe_number ())
1596                 {
1597                   switch (type)
1598                     {
1599                     case tfind_tp:
1600                       {
1601                         struct tracepoint *tp = get_tracepoint (num);
1602
1603                         if (tp != NULL
1604                             && (tp->number_on_target
1605                                 == ctf_get_tpnum_from_frame_event (event)))
1606                           found = 1;
1607                         break;
1608                       }
1609                     case tfind_pc:
1610                       tfaddr = ctf_get_traceframe_address ();
1611                       if (tfaddr == addr1)
1612                         found = 1;
1613                       break;
1614                     case tfind_range:
1615                       tfaddr = ctf_get_traceframe_address ();
1616                       if (addr1 <= tfaddr && tfaddr <= addr2)
1617                         found = 1;
1618                       break;
1619                     case tfind_outside:
1620                       tfaddr = ctf_get_traceframe_address ();
1621                       if (!(addr1 <= tfaddr && tfaddr <= addr2))
1622                         found = 1;
1623                       break;
1624                     default:
1625                       internal_error (_("unknown tfind type"));
1626                     }
1627                 }
1628             }
1629           if (found)
1630             {
1631               if (tpp != NULL)
1632                 *tpp = ctf_get_tpnum_from_frame_event (event);
1633
1634               /* Skip the event "frame".  */
1635               bt_iter_next (bt_ctf_get_iter (ctf_iter));
1636
1637               return tfnum;
1638             }
1639           tfnum++;
1640         }
1641
1642       if (bt_iter_next (bt_ctf_get_iter (ctf_iter)) < 0)
1643         break;
1644     }
1645
1646   return -1;
1647 }
1648
1649 /* This is the implementation of target_ops method to_traceframe_info.
1650    Iterate the events whose name is "memory", in current
1651    frame, extract memory range information, and return them in
1652    traceframe_info.  */
1653
1654 traceframe_info_up
1655 ctf_target::traceframe_info ()
1656 {
1657   traceframe_info_up info (new struct traceframe_info);
1658   const char *name;
1659   struct bt_iter_pos *pos;
1660
1661   gdb_assert (ctf_iter != NULL);
1662   /* Save the current position.  */
1663   pos = bt_iter_get_pos (bt_ctf_get_iter (ctf_iter));
1664   gdb_assert (pos->type == BT_SEEK_RESTORE);
1665
1666   do
1667     {
1668       struct bt_ctf_event *event
1669         = bt_ctf_iter_read_event (ctf_iter);
1670
1671       name = bt_ctf_event_name (event);
1672
1673       if (name == NULL || strcmp (name, "register") == 0
1674           || strcmp (name, "frame") == 0)
1675         ;
1676       else if (strcmp (name, "memory") == 0)
1677         {
1678           const struct bt_definition *scope
1679             = bt_ctf_get_top_level_scope (event,
1680                                           BT_EVENT_FIELDS);
1681           const struct bt_definition *def;
1682
1683           def = bt_ctf_get_field (event, scope, "address");
1684           CORE_ADDR start = bt_ctf_get_uint64 (def);
1685
1686           def = bt_ctf_get_field (event, scope, "length");
1687           int length = (uint16_t) bt_ctf_get_uint64 (def);
1688
1689           info->memory.emplace_back (start, length);
1690         }
1691       else if (strcmp (name, "tsv") == 0)
1692         {
1693           int vnum;
1694           const struct bt_definition *scope
1695             = bt_ctf_get_top_level_scope (event,
1696                                           BT_EVENT_FIELDS);
1697           const struct bt_definition *def;
1698
1699           def = bt_ctf_get_field (event, scope, "num");
1700           vnum = (int) bt_ctf_get_uint64 (def);
1701           info->tvars.push_back (vnum);
1702         }
1703       else
1704         {
1705           warning (_("Unhandled trace block type (%s) "
1706                      "while building trace frame info."),
1707                    name);
1708         }
1709
1710       if (bt_iter_next (bt_ctf_get_iter (ctf_iter)) < 0)
1711         break;
1712     }
1713   while (name != NULL && strcmp (name, "frame") != 0);
1714
1715   /* Restore the position.  */
1716   bt_iter_set_pos (bt_ctf_get_iter (ctf_iter), pos);
1717
1718   return info;
1719 }
1720
1721 #endif
1722
1723 /* module initialization */
1724
1725 void _initialize_ctf ();
1726 void
1727 _initialize_ctf ()
1728 {
1729 #if HAVE_LIBBABELTRACE
1730   add_target (ctf_target_info, ctf_target_open, filename_completer);
1731 #endif
1732 }
This page took 0.122354 seconds and 4 git commands to generate.