gdb/
[external/binutils.git] / gdb / ctf.c
1 /* CTF format support.
2
3    Copyright (C) 2012-2013 Free Software Foundation, Inc.
4    Contributed by Hui Zhu <hui_zhu@mentor.com>
5    Contributed by Yao Qi <yao@codesourcery.com>
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 "ctf.h"
24 #include "tracepoint.h"
25 #include "regcache.h"
26
27 #include <ctype.h>
28
29 /* GDB saves trace buffers and other information (such as trace
30    status) got from the remote target into Common Trace Format (CTF).
31    The following types of information are expected to save in CTF:
32
33    1. The length (in bytes) of register cache.  Event "register" will
34    be defined in metadata, which includes the length.
35
36    2. Trace status.  Not implemented yet in CTF writer.
37
38    3. Uploaded trace variables and tracepoints.  Not implemented yet
39    in CTF writer.
40
41    4. Trace frames.  Each trace frame is composed by several blocks
42    of different types ('R', 'M', 'V').  One trace frame is saved in
43    one CTF packet and the blocks of this frame are saved as events.
44    4.1: The trace frame related information (such as the number of
45    tracepoint associated with this frame) is saved in the packet
46    context.
47    4.2: The block 'M', 'R' and 'V' are saved in event "memory",
48    "register" and "tsv" respectively.
49    4.3: When iterating over events, babeltrace can't tell iterator
50    goes to a new packet, so we need a marker or anchor to tell GDB
51    that iterator goes into a new packet or frame.  We define event
52    "frame".  */
53
54 #define CTF_MAGIC               0xC1FC1FC1
55 #define CTF_SAVE_MAJOR          1
56 #define CTF_SAVE_MINOR          8
57
58 #define CTF_METADATA_NAME       "metadata"
59 #define CTF_DATASTREAM_NAME     "datastream"
60
61 /* Reserved event id.  */
62
63 #define CTF_EVENT_ID_REGISTER 0
64 #define CTF_EVENT_ID_TSV 1
65 #define CTF_EVENT_ID_MEMORY 2
66 #define CTF_EVENT_ID_FRAME 3
67
68 /* The state kept while writing the CTF datastream file.  */
69
70 struct trace_write_handler
71 {
72   /* File descriptor of metadata.  */
73   FILE *metadata_fd;
74   /* File descriptor of traceframes.  */
75   FILE *datastream_fd;
76
77   /* This is the content size of the current packet.  */
78   size_t content_size;
79
80   /* This is the start offset of current packet.  */
81   long packet_start;
82 };
83
84 /* Write metadata in FORMAT.  */
85
86 static void
87 ctf_save_write_metadata (struct trace_write_handler *handler,
88                          const char *format, ...)
89 {
90   va_list args;
91
92   va_start (args, format);
93   if (vfprintf (handler->metadata_fd, format, args) < 0)
94     error (_("Unable to write metadata file (%s)"),
95              safe_strerror (errno));
96   va_end (args);
97 }
98
99 /* Write BUF of length SIZE to datastream file represented by
100    HANDLER.  */
101
102 static int
103 ctf_save_write (struct trace_write_handler *handler,
104                 const gdb_byte *buf, size_t size)
105 {
106   if (fwrite (buf, size, 1, handler->datastream_fd) != 1)
107     error (_("Unable to write file for saving trace data (%s)"),
108            safe_strerror (errno));
109
110   handler->content_size += size;
111
112   return 0;
113 }
114
115 /* Write a unsigned 32-bit integer to datastream file represented by
116    HANDLER.  */
117
118 #define ctf_save_write_uint32(HANDLER, U32) \
119   ctf_save_write (HANDLER, (gdb_byte *) &U32, 4)
120
121 /* Set datastream file position.  Update HANDLER->content_size
122    if WHENCE is SEEK_CUR.  */
123
124 static int
125 ctf_save_fseek (struct trace_write_handler *handler, long offset,
126                 int whence)
127 {
128   gdb_assert (whence != SEEK_END);
129   gdb_assert (whence != SEEK_SET
130               || offset <= handler->content_size + handler->packet_start);
131
132   if (fseek (handler->datastream_fd, offset, whence))
133     error (_("Unable to seek file for saving trace data (%s)"),
134            safe_strerror (errno));
135
136   if (whence == SEEK_CUR)
137     handler->content_size += offset;
138
139   return 0;
140 }
141
142 /* Change the datastream file position to align on ALIGN_SIZE,
143    and write BUF to datastream file.  The size of BUF is SIZE.  */
144
145 static int
146 ctf_save_align_write (struct trace_write_handler *handler,
147                       const gdb_byte *buf,
148                       size_t size, size_t align_size)
149 {
150   long offset
151     = (align_up (handler->content_size, align_size)
152        - handler->content_size);
153
154   if (ctf_save_fseek (handler, offset, SEEK_CUR))
155     return -1;
156
157   if (ctf_save_write (handler, buf, size))
158     return -1;
159
160   return 0;
161 }
162
163 /* Write events to next new packet.  */
164
165 static void
166 ctf_save_next_packet (struct trace_write_handler *handler)
167 {
168   handler->packet_start += (handler->content_size + 4);
169   ctf_save_fseek (handler, handler->packet_start, SEEK_SET);
170   handler->content_size = 0;
171 }
172
173 /* Write the CTF metadata header.  */
174
175 static void
176 ctf_save_metadata_header (struct trace_write_handler *handler)
177 {
178   const char metadata_fmt[] =
179   "\ntrace {\n"
180   "     major = %u;\n"
181   "     minor = %u;\n"
182   "     byte_order = %s;\n"             /* be or le */
183   "     packet.header := struct {\n"
184   "             uint32_t magic;\n"
185   "     };\n"
186   "};\n"
187   "\n"
188   "stream {\n"
189   "     packet.context := struct {\n"
190   "             uint32_t content_size;\n"
191   "             uint32_t packet_size;\n"
192   "             uint16_t tpnum;\n"
193   "     };\n"
194   "     event.header := struct {\n"
195   "             uint32_t id;\n"
196   "     };\n"
197   "};\n";
198
199   ctf_save_write_metadata (handler, "/* CTF %d.%d */\n",
200                            CTF_SAVE_MAJOR, CTF_SAVE_MINOR);
201   ctf_save_write_metadata (handler,
202                            "typealias integer { size = 8; align = 8; "
203                            "signed = false; encoding = ascii;}"
204                            " := ascii;\n");
205   ctf_save_write_metadata (handler,
206                            "typealias integer { size = 8; align = 8; "
207                            "signed = false; }"
208                            " := uint8_t;\n");
209   ctf_save_write_metadata (handler,
210                            "typealias integer { size = 16; align = 16;"
211                            "signed = false; } := uint16_t;\n");
212   ctf_save_write_metadata (handler,
213                            "typealias integer { size = 32; align = 32;"
214                            "signed = false; } := uint32_t;\n");
215   ctf_save_write_metadata (handler,
216                            "typealias integer { size = 64; align = 64;"
217                            "signed = false; base = hex;}"
218                            " := uint64_t;\n");
219   ctf_save_write_metadata (handler, "\n");
220
221   ctf_save_write_metadata (handler, metadata_fmt,
222                            CTF_SAVE_MAJOR, CTF_SAVE_MINOR,
223                            BYTE_ORDER == LITTLE_ENDIAN ? "le" : "be");
224   ctf_save_write_metadata (handler, "\n");
225 }
226
227 /* CTF trace writer.  */
228
229 struct ctf_trace_file_writer
230 {
231   struct trace_file_writer base;
232
233   /* States related to writing CTF trace file.  */
234   struct trace_write_handler tcs;
235 };
236
237 /* This is the implementation of trace_file_write_ops method
238    dtor.  */
239
240 static void
241 ctf_dtor (struct trace_file_writer *self)
242 {
243   struct ctf_trace_file_writer *writer
244     = (struct ctf_trace_file_writer *) self;
245
246   if (writer->tcs.metadata_fd != NULL)
247     fclose (writer->tcs.metadata_fd);
248
249   if (writer->tcs.datastream_fd != NULL)
250     fclose (writer->tcs.datastream_fd);
251
252 }
253
254 /* This is the implementation of trace_file_write_ops method
255    target_save.  */
256
257 static int
258 ctf_target_save (struct trace_file_writer *self,
259                  const char *dirname)
260 {
261   /* Don't support save trace file to CTF format in the target.  */
262   return 0;
263 }
264
265 /* This is the implementation of trace_file_write_ops method
266    start.  It creates the directory DIRNAME, metadata and datastream
267    in the directory.  */
268
269 static void
270 ctf_start (struct trace_file_writer *self, const char *dirname)
271 {
272   char *file_name;
273   struct cleanup *old_chain;
274   struct ctf_trace_file_writer *writer
275     = (struct ctf_trace_file_writer *) self;
276   int i;
277
278   /* Create DIRNAME.  */
279   if (mkdir (dirname, S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH)
280       && errno != EEXIST)
281     error (_("Unable to open directory '%s' for saving trace data (%s)"),
282            dirname, safe_strerror (errno));
283
284   memset (&writer->tcs, '\0', sizeof (writer->tcs));
285
286   file_name = xstrprintf ("%s/%s", dirname, CTF_METADATA_NAME);
287   old_chain = make_cleanup (xfree, file_name);
288
289   writer->tcs.metadata_fd = fopen (file_name, "w");
290   if (writer->tcs.metadata_fd == NULL)
291     error (_("Unable to open file '%s' for saving trace data (%s)"),
292            file_name, safe_strerror (errno));
293   do_cleanups (old_chain);
294
295   ctf_save_metadata_header (&writer->tcs);
296
297   file_name = xstrprintf ("%s/%s", dirname, CTF_DATASTREAM_NAME);
298   old_chain = make_cleanup (xfree, file_name);
299   writer->tcs.datastream_fd = fopen (file_name, "w");
300   if (writer->tcs.datastream_fd == NULL)
301     error (_("Unable to open file '%s' for saving trace data (%s)"),
302            file_name, safe_strerror (errno));
303   do_cleanups (old_chain);
304 }
305
306 /* This is the implementation of trace_file_write_ops method
307    write_header.  Write the types of events on trace variable and
308    frame.  */
309
310 static void
311 ctf_write_header (struct trace_file_writer *self)
312 {
313   struct ctf_trace_file_writer *writer
314     = (struct ctf_trace_file_writer *) self;
315
316
317   ctf_save_write_metadata (&writer->tcs, "\n");
318   ctf_save_write_metadata (&writer->tcs,
319                            "event {\n\tname = \"memory\";\n\tid = %u;\n"
320                            "\tfields := struct { \n"
321                            "\t\tuint64_t address;\n"
322                            "\t\tuint16_t length;\n"
323                            "\t\tuint8_t contents[length];\n"
324                            "\t};\n"
325                            "};\n", CTF_EVENT_ID_MEMORY);
326
327   ctf_save_write_metadata (&writer->tcs, "\n");
328   ctf_save_write_metadata (&writer->tcs,
329                            "event {\n\tname = \"tsv\";\n\tid = %u;\n"
330                            "\tfields := struct { \n"
331                            "\t\tuint64_t val;\n"
332                            "\t\tuint32_t num;\n"
333                            "\t};\n"
334                            "};\n", CTF_EVENT_ID_TSV);
335
336   ctf_save_write_metadata (&writer->tcs, "\n");
337   ctf_save_write_metadata (&writer->tcs,
338                            "event {\n\tname = \"frame\";\n\tid = %u;\n"
339                            "\tfields := struct { \n"
340                            "\t};\n"
341                            "};\n", CTF_EVENT_ID_FRAME);
342
343   gdb_assert (writer->tcs.content_size == 0);
344   gdb_assert (writer->tcs.packet_start == 0);
345 }
346
347 /* This is the implementation of trace_file_write_ops method
348    write_regblock_type.  Write the type of register event in
349    metadata.  */
350
351 static void
352 ctf_write_regblock_type (struct trace_file_writer *self, int size)
353 {
354   struct ctf_trace_file_writer *writer
355     = (struct ctf_trace_file_writer *) self;
356
357   ctf_save_write_metadata (&writer->tcs, "\n");
358
359   ctf_save_write_metadata (&writer->tcs,
360                            "event {\n\tname = \"register\";\n\tid = %u;\n"
361                            "\tfields := struct { \n"
362                            "\t\tascii contents[%d];\n"
363                            "\t};\n"
364                            "};\n",
365                            CTF_EVENT_ID_REGISTER, size);
366 }
367
368 /* This is the implementation of trace_file_write_ops method
369    write_status.  */
370
371 static void
372 ctf_write_status (struct trace_file_writer *self,
373                   struct trace_status *ts)
374 {
375   /* It is not supported yet to write trace status into CTF trace
376      data.  */
377 }
378
379 /* This is the implementation of trace_file_write_ops method
380    write_uploaded_tsv.  */
381
382 static void
383 ctf_write_uploaded_tsv (struct trace_file_writer *self,
384                         struct uploaded_tsv *tsv)
385 {
386   /* It is not supported yet to write uploaded trace variables
387      into CTF trace data.  */
388 }
389
390 /* This is the implementation of trace_file_write_ops method
391    write_uploaded_tp.  */
392
393 static void
394 ctf_write_uploaded_tp (struct trace_file_writer *self,
395                        struct uploaded_tp *tp)
396 {
397   /* It is not supported yet to write uploaded tracepoints
398      into CTF trace data.  */
399 }
400
401 /* This is the implementation of trace_file_write_ops method
402    write_definition_end.  */
403
404 static void
405 ctf_write_definition_end (struct trace_file_writer *self)
406 {
407   /* Nothing to do for CTF.  */
408 }
409
410 /* The minimal file size of data stream.  It is required by
411    babeltrace.  */
412
413 #define CTF_FILE_MIN_SIZE               4096
414
415 /* This is the implementation of trace_file_write_ops method
416    end.  */
417
418 static void
419 ctf_end (struct trace_file_writer *self)
420 {
421   struct ctf_trace_file_writer *writer = (struct ctf_trace_file_writer *) self;
422
423   gdb_assert (writer->tcs.content_size == 0);
424   /* The babeltrace requires or assumes that the size of datastream
425      file is greater than 4096 bytes.  If we don't generate enough
426      packets and events, create a fake packet which has zero event,
427       to use up the space.  */
428   if (writer->tcs.packet_start < CTF_FILE_MIN_SIZE)
429     {
430       uint32_t u32;
431
432       /* magic.  */
433       u32 = CTF_MAGIC;
434       ctf_save_write_uint32 (&writer->tcs, u32);
435
436       /* content_size.  */
437       u32 = 0;
438       ctf_save_write_uint32 (&writer->tcs, u32);
439
440       /* packet_size.  */
441       u32 = 12;
442       if (writer->tcs.packet_start + u32 < CTF_FILE_MIN_SIZE)
443         u32 = CTF_FILE_MIN_SIZE - writer->tcs.packet_start;
444
445       u32 *= TARGET_CHAR_BIT;
446       ctf_save_write_uint32 (&writer->tcs, u32);
447
448       /* tpnum.  */
449       u32 = 0;
450       ctf_save_write (&writer->tcs, (gdb_byte *) &u32, 2);
451
452       /* Enlarge the file to CTF_FILE_MIN_SIZE is it is still less
453          than that.  */
454       if (CTF_FILE_MIN_SIZE
455           > (writer->tcs.packet_start + writer->tcs.content_size))
456         {
457           gdb_byte b = 0;
458
459           /* Fake the content size to avoid assertion failure in
460              ctf_save_fseek.  */
461           writer->tcs.content_size = (CTF_FILE_MIN_SIZE
462                                       - 1 - writer->tcs.packet_start);
463           ctf_save_fseek (&writer->tcs, CTF_FILE_MIN_SIZE - 1,
464                           SEEK_SET);
465           ctf_save_write (&writer->tcs, &b, 1);
466         }
467     }
468 }
469
470 /* This is the implementation of trace_frame_write_ops method
471    start.  */
472
473 static void
474 ctf_write_frame_start (struct trace_file_writer *self, uint16_t tpnum)
475 {
476   struct ctf_trace_file_writer *writer
477     = (struct ctf_trace_file_writer *) self;
478   uint32_t id = CTF_EVENT_ID_FRAME;
479   uint32_t u32;
480
481   /* Step 1: Write packet context.  */
482   /* magic.  */
483   u32 = CTF_MAGIC;
484   ctf_save_write_uint32 (&writer->tcs, u32);
485   /* content_size and packet_size..  We still don't know the value,
486      write it later.  */
487   ctf_save_fseek (&writer->tcs, 4, SEEK_CUR);
488   ctf_save_fseek (&writer->tcs, 4, SEEK_CUR);
489   /* Tracepoint number.  */
490   ctf_save_write (&writer->tcs, (gdb_byte *) &tpnum, 2);
491
492   /* Step 2: Write event "frame".  */
493   /* Event Id.  */
494   ctf_save_align_write (&writer->tcs, (gdb_byte *) &id, 4, 4);
495 }
496
497 /* This is the implementation of trace_frame_write_ops method
498    write_r_block.  */
499
500 static void
501 ctf_write_frame_r_block (struct trace_file_writer *self,
502                          gdb_byte *buf, int32_t size)
503 {
504   struct ctf_trace_file_writer *writer
505     = (struct ctf_trace_file_writer *) self;
506   uint32_t id = CTF_EVENT_ID_REGISTER;
507
508   /* Event Id.  */
509   ctf_save_align_write (&writer->tcs, (gdb_byte *) &id, 4, 4);
510
511   /* array contents.  */
512   ctf_save_align_write (&writer->tcs, buf, size, 1);
513 }
514
515 /* This is the implementation of trace_frame_write_ops method
516    write_m_block_header.  */
517
518 static void
519 ctf_write_frame_m_block_header (struct trace_file_writer *self,
520                                 uint64_t addr, uint16_t length)
521 {
522   struct ctf_trace_file_writer *writer
523     = (struct ctf_trace_file_writer *) self;
524   uint32_t event_id = CTF_EVENT_ID_MEMORY;
525
526   /* Event Id.  */
527   ctf_save_align_write (&writer->tcs, (gdb_byte *) &event_id, 4, 4);
528
529   /* Address.  */
530   ctf_save_align_write (&writer->tcs, (gdb_byte *) &addr, 8, 8);
531
532   /* Length.  */
533   ctf_save_align_write (&writer->tcs, (gdb_byte *) &length, 2, 2);
534 }
535
536 /* This is the implementation of trace_frame_write_ops method
537    write_m_block_memory.  */
538
539 static void
540 ctf_write_frame_m_block_memory (struct trace_file_writer *self,
541                                 gdb_byte *buf, uint16_t length)
542 {
543   struct ctf_trace_file_writer *writer
544     = (struct ctf_trace_file_writer *) self;
545
546   /* Contents.  */
547   ctf_save_align_write (&writer->tcs, (gdb_byte *) buf, length, 1);
548 }
549
550 /* This is the implementation of trace_frame_write_ops method
551    write_v_block.  */
552
553 static void
554 ctf_write_frame_v_block (struct trace_file_writer *self,
555                          int32_t num, uint64_t val)
556 {
557   struct ctf_trace_file_writer *writer
558     = (struct ctf_trace_file_writer *) self;
559   uint32_t id = CTF_EVENT_ID_TSV;
560
561   /* Event Id.  */
562   ctf_save_align_write (&writer->tcs, (gdb_byte *) &id, 4, 4);
563
564   /* val.  */
565   ctf_save_align_write (&writer->tcs, (gdb_byte *) &val, 8, 8);
566   /* num.  */
567   ctf_save_align_write (&writer->tcs, (gdb_byte *) &num, 4, 4);
568 }
569
570 /* This is the implementation of trace_frame_write_ops method
571    end.  */
572
573 static void
574 ctf_write_frame_end (struct trace_file_writer *self)
575 {
576   struct ctf_trace_file_writer *writer
577     = (struct ctf_trace_file_writer *) self;
578   uint32_t u32;
579   uint32_t t;
580
581   /* Write the content size to packet header.  */
582   ctf_save_fseek (&writer->tcs, writer->tcs.packet_start + 4,
583                   SEEK_SET);
584   u32 = writer->tcs.content_size * TARGET_CHAR_BIT;
585
586   t = writer->tcs.content_size;
587   ctf_save_write_uint32 (&writer->tcs, u32);
588
589   /* Write the packet size.  */
590   u32 += 4 * TARGET_CHAR_BIT;
591   ctf_save_write_uint32 (&writer->tcs, u32);
592
593   writer->tcs.content_size = t;
594
595   /* Write zero at the end of the packet.  */
596   ctf_save_fseek (&writer->tcs, writer->tcs.packet_start + t,
597                   SEEK_SET);
598   u32 = 0;
599   ctf_save_write_uint32 (&writer->tcs, u32);
600   writer->tcs.content_size = t;
601
602   ctf_save_next_packet (&writer->tcs);
603 }
604
605 /* Operations to write various types of trace frames into CTF
606    format.  */
607
608 static const struct trace_frame_write_ops ctf_write_frame_ops =
609 {
610   ctf_write_frame_start,
611   ctf_write_frame_r_block,
612   ctf_write_frame_m_block_header,
613   ctf_write_frame_m_block_memory,
614   ctf_write_frame_v_block,
615   ctf_write_frame_end,
616 };
617
618 /* Operations to write trace buffers into CTF format.  */
619
620 static const struct trace_file_write_ops ctf_write_ops =
621 {
622   ctf_dtor,
623   ctf_target_save,
624   ctf_start,
625   ctf_write_header,
626   ctf_write_regblock_type,
627   ctf_write_status,
628   ctf_write_uploaded_tsv,
629   ctf_write_uploaded_tp,
630   ctf_write_definition_end,
631   NULL,
632   &ctf_write_frame_ops,
633   ctf_end,
634 };
635
636 /* Return a trace writer for CTF format.  */
637
638 struct trace_file_writer *
639 ctf_trace_file_writer_new (void)
640 {
641   struct ctf_trace_file_writer *writer
642     = xmalloc (sizeof (struct ctf_trace_file_writer));
643
644   writer->base.ops = &ctf_write_ops;
645
646   return (struct trace_file_writer *) writer;
647 }