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