gdb/ctf.c - gdb
Global variables defined
Data types defined
Functions defined
Macros defined
Source code
- #include "defs.h"
- #include "ctf.h"
- #include "tracepoint.h"
- #include "regcache.h"
- #include <sys/stat.h>
- #include "exec.h"
- #include "completer.h"
- #include "inferior.h"
- #include "gdbthread.h"
- #include "tracefile.h"
- #include <ctype.h>
- #define CTF_MAGIC 0xC1FC1FC1
- #define CTF_SAVE_MAJOR 1
- #define CTF_SAVE_MINOR 8
- #define CTF_METADATA_NAME "metadata"
- #define CTF_DATASTREAM_NAME "datastream"
- #define CTF_EVENT_ID_REGISTER 0
- #define CTF_EVENT_ID_TSV 1
- #define CTF_EVENT_ID_MEMORY 2
- #define CTF_EVENT_ID_FRAME 3
- #define CTF_EVENT_ID_STATUS 4
- #define CTF_EVENT_ID_TSV_DEF 5
- #define CTF_EVENT_ID_TP_DEF 6
- #define CTF_PID (2)
- struct trace_write_handler
- {
-
- FILE *metadata_fd;
-
- FILE *datastream_fd;
-
- size_t content_size;
-
- long packet_start;
- };
- static void
- ctf_save_write_metadata (struct trace_write_handler *handler,
- const char *format, ...)
- {
- va_list args;
- va_start (args, format);
- if (vfprintf (handler->metadata_fd, format, args) < 0)
- error (_("Unable to write metadata file (%s)"),
- safe_strerror (errno));
- va_end (args);
- }
- static int
- ctf_save_write (struct trace_write_handler *handler,
- const gdb_byte *buf, size_t size)
- {
- if (fwrite (buf, size, 1, handler->datastream_fd) != 1)
- error (_("Unable to write file for saving trace data (%s)"),
- safe_strerror (errno));
- handler->content_size += size;
- return 0;
- }
- #define ctf_save_write_uint32(HANDLER, U32) \
- ctf_save_write (HANDLER, (gdb_byte *) &U32, 4)
- #define ctf_save_write_int32(HANDLER, INT32) \
- ctf_save_write ((HANDLER), (gdb_byte *) &(INT32), 4)
- static int
- ctf_save_fseek (struct trace_write_handler *handler, long offset,
- int whence)
- {
- gdb_assert (whence != SEEK_END);
- gdb_assert (whence != SEEK_SET
- || offset <= handler->content_size + handler->packet_start);
- if (fseek (handler->datastream_fd, offset, whence))
- error (_("Unable to seek file for saving trace data (%s)"),
- safe_strerror (errno));
- if (whence == SEEK_CUR)
- handler->content_size += offset;
- return 0;
- }
- static int
- ctf_save_align_write (struct trace_write_handler *handler,
- const gdb_byte *buf,
- size_t size, size_t align_size)
- {
- long offset
- = (align_up (handler->content_size, align_size)
- - handler->content_size);
- if (ctf_save_fseek (handler, offset, SEEK_CUR))
- return -1;
- if (ctf_save_write (handler, buf, size))
- return -1;
- return 0;
- }
- static void
- ctf_save_next_packet (struct trace_write_handler *handler)
- {
- handler->packet_start += (handler->content_size + 4);
- ctf_save_fseek (handler, handler->packet_start, SEEK_SET);
- handler->content_size = 0;
- }
- static void
- ctf_save_metadata_header (struct trace_write_handler *handler)
- {
- const char metadata_fmt[] =
- "\ntrace {\n"
- " major = %u;\n"
- " minor = %u;\n"
- " byte_order = %s;\n"
- " packet.header := struct {\n"
- " uint32_t magic;\n"
- " };\n"
- "};\n"
- "\n"
- "stream {\n"
- " packet.context := struct {\n"
- " uint32_t content_size;\n"
- " uint32_t packet_size;\n"
- " uint16_t tpnum;\n"
- " };\n"
- " event.header := struct {\n"
- " uint32_t id;\n"
- " };\n"
- "};\n";
- ctf_save_write_metadata (handler, "/* CTF %d.%d */\n",
- CTF_SAVE_MAJOR, CTF_SAVE_MINOR);
- ctf_save_write_metadata (handler,
- "typealias integer { size = 8; align = 8; "
- "signed = false; encoding = ascii;}"
- " := ascii;\n");
- ctf_save_write_metadata (handler,
- "typealias integer { size = 8; align = 8; "
- "signed = false; }"
- " := uint8_t;\n");
- ctf_save_write_metadata (handler,
- "typealias integer { size = 16; align = 16;"
- "signed = false; } := uint16_t;\n");
- ctf_save_write_metadata (handler,
- "typealias integer { size = 32; align = 32;"
- "signed = false; } := uint32_t;\n");
- ctf_save_write_metadata (handler,
- "typealias integer { size = 64; align = 64;"
- "signed = false; base = hex;}"
- " := uint64_t;\n");
- ctf_save_write_metadata (handler,
- "typealias integer { size = 32; align = 32;"
- "signed = true; } := int32_t;\n");
- ctf_save_write_metadata (handler,
- "typealias integer { size = 64; align = 64;"
- "signed = true; } := int64_t;\n");
- ctf_save_write_metadata (handler,
- "typealias string { encoding = ascii;"
- " } := chars;\n");
- ctf_save_write_metadata (handler, "\n");
-
- #if WORDS_BIGENDIAN
- #define HOST_ENDIANNESS "be"
- #else
- #define HOST_ENDIANNESS "le"
- #endif
- ctf_save_write_metadata (handler, metadata_fmt,
- CTF_SAVE_MAJOR, CTF_SAVE_MINOR,
- HOST_ENDIANNESS);
- ctf_save_write_metadata (handler, "\n");
- }
- struct ctf_trace_file_writer
- {
- struct trace_file_writer base;
-
- struct trace_write_handler tcs;
- };
- static void
- ctf_dtor (struct trace_file_writer *self)
- {
- struct ctf_trace_file_writer *writer
- = (struct ctf_trace_file_writer *) self;
- if (writer->tcs.metadata_fd != NULL)
- fclose (writer->tcs.metadata_fd);
- if (writer->tcs.datastream_fd != NULL)
- fclose (writer->tcs.datastream_fd);
- }
- static int
- ctf_target_save (struct trace_file_writer *self,
- const char *dirname)
- {
-
- return 0;
- }
- #ifdef USE_WIN32API
- #undef mkdir
- #define mkdir(pathname, mode) mkdir (pathname)
- #endif
- static void
- ctf_start (struct trace_file_writer *self, const char *dirname)
- {
- char *file_name;
- struct cleanup *old_chain;
- struct ctf_trace_file_writer *writer
- = (struct ctf_trace_file_writer *) self;
- int i;
- mode_t hmode = S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH;
-
- if (mkdir (dirname, hmode) && errno != EEXIST)
- error (_("Unable to open directory '%s' for saving trace data (%s)"),
- dirname, safe_strerror (errno));
- memset (&writer->tcs, '\0', sizeof (writer->tcs));
- file_name = xstrprintf ("%s/%s", dirname, CTF_METADATA_NAME);
- old_chain = make_cleanup (xfree, file_name);
- writer->tcs.metadata_fd = fopen (file_name, "w");
- if (writer->tcs.metadata_fd == NULL)
- error (_("Unable to open file '%s' for saving trace data (%s)"),
- file_name, safe_strerror (errno));
- do_cleanups (old_chain);
- ctf_save_metadata_header (&writer->tcs);
- file_name = xstrprintf ("%s/%s", dirname, CTF_DATASTREAM_NAME);
- old_chain = make_cleanup (xfree, file_name);
- writer->tcs.datastream_fd = fopen (file_name, "w");
- if (writer->tcs.datastream_fd == NULL)
- error (_("Unable to open file '%s' for saving trace data (%s)"),
- file_name, safe_strerror (errno));
- do_cleanups (old_chain);
- }
- static void
- ctf_write_header (struct trace_file_writer *self)
- {
- struct ctf_trace_file_writer *writer
- = (struct ctf_trace_file_writer *) self;
- ctf_save_write_metadata (&writer->tcs, "\n");
- ctf_save_write_metadata (&writer->tcs,
- "event {\n\tname = \"memory\";\n\tid = %u;\n"
- "\tfields := struct { \n"
- "\t\tuint64_t address;\n"
- "\t\tuint16_t length;\n"
- "\t\tuint8_t contents[length];\n"
- "\t};\n"
- "};\n", CTF_EVENT_ID_MEMORY);
- ctf_save_write_metadata (&writer->tcs, "\n");
- ctf_save_write_metadata (&writer->tcs,
- "event {\n\tname = \"tsv\";\n\tid = %u;\n"
- "\tfields := struct { \n"
- "\t\tuint64_t val;\n"
- "\t\tuint32_t num;\n"
- "\t};\n"
- "};\n", CTF_EVENT_ID_TSV);
- ctf_save_write_metadata (&writer->tcs, "\n");
- ctf_save_write_metadata (&writer->tcs,
- "event {\n\tname = \"frame\";\n\tid = %u;\n"
- "\tfields := struct { \n"
- "\t};\n"
- "};\n", CTF_EVENT_ID_FRAME);
- ctf_save_write_metadata (&writer->tcs, "\n");
- ctf_save_write_metadata (&writer->tcs,
- "event {\n\tname = \"tsv_def\";\n"
- "\tid = %u;\n\tfields := struct { \n"
- "\t\tint64_t initial_value;\n"
- "\t\tint32_t number;\n"
- "\t\tint32_t builtin;\n"
- "\t\tchars name;\n"
- "\t};\n"
- "};\n", CTF_EVENT_ID_TSV_DEF);
- ctf_save_write_metadata (&writer->tcs, "\n");
- ctf_save_write_metadata (&writer->tcs,
- "event {\n\tname = \"tp_def\";\n"
- "\tid = %u;\n\tfields := struct { \n"
- "\t\tuint64_t addr;\n"
- "\t\tuint64_t traceframe_usage;\n"
- "\t\tint32_t number;\n"
- "\t\tint32_t enabled;\n"
- "\t\tint32_t step;\n"
- "\t\tint32_t pass;\n"
- "\t\tint32_t hit_count;\n"
- "\t\tint32_t type;\n"
- "\t\tchars cond;\n"
- "\t\tuint32_t action_num;\n"
- "\t\tchars actions[action_num];\n"
- "\t\tuint32_t step_action_num;\n"
- "\t\tchars step_actions[step_action_num];\n"
- "\t\tchars at_string;\n"
- "\t\tchars cond_string;\n"
- "\t\tuint32_t cmd_num;\n"
- "\t\tchars cmd_strings[cmd_num];\n"
- "\t};\n"
- "};\n", CTF_EVENT_ID_TP_DEF);
- gdb_assert (writer->tcs.content_size == 0);
- gdb_assert (writer->tcs.packet_start == 0);
-
- self->ops->frame_ops->start (self, 0);
- }
- static void
- ctf_write_regblock_type (struct trace_file_writer *self, int size)
- {
- struct ctf_trace_file_writer *writer
- = (struct ctf_trace_file_writer *) self;
- ctf_save_write_metadata (&writer->tcs, "\n");
- ctf_save_write_metadata (&writer->tcs,
- "event {\n\tname = \"register\";\n\tid = %u;\n"
- "\tfields := struct { \n"
- "\t\tascii contents[%d];\n"
- "\t};\n"
- "};\n",
- CTF_EVENT_ID_REGISTER, size);
- }
- static void
- ctf_write_status (struct trace_file_writer *self,
- struct trace_status *ts)
- {
- struct ctf_trace_file_writer *writer
- = (struct ctf_trace_file_writer *) self;
- uint32_t id;
- int32_t int32;
- ctf_save_write_metadata (&writer->tcs, "\n");
- ctf_save_write_metadata (&writer->tcs,
- "event {\n\tname = \"status\";\n\tid = %u;\n"
- "\tfields := struct { \n"
- "\t\tint32_t stop_reason;\n"
- "\t\tint32_t stopping_tracepoint;\n"
- "\t\tint32_t traceframe_count;\n"
- "\t\tint32_t traceframes_created;\n"
- "\t\tint32_t buffer_free;\n"
- "\t\tint32_t buffer_size;\n"
- "\t\tint32_t disconnected_tracing;\n"
- "\t\tint32_t circular_buffer;\n"
- "\t};\n"
- "};\n",
- CTF_EVENT_ID_STATUS);
- id = CTF_EVENT_ID_STATUS;
-
- ctf_save_align_write (&writer->tcs, (gdb_byte *) &id, 4, 4);
- ctf_save_write_int32 (&writer->tcs, ts->stop_reason);
- ctf_save_write_int32 (&writer->tcs, ts->stopping_tracepoint);
- ctf_save_write_int32 (&writer->tcs, ts->traceframe_count);
- ctf_save_write_int32 (&writer->tcs, ts->traceframes_created);
- ctf_save_write_int32 (&writer->tcs, ts->buffer_free);
- ctf_save_write_int32 (&writer->tcs, ts->buffer_size);
- ctf_save_write_int32 (&writer->tcs, ts->disconnected_tracing);
- ctf_save_write_int32 (&writer->tcs, ts->circular_buffer);
- }
- static void
- ctf_write_uploaded_tsv (struct trace_file_writer *self,
- struct uploaded_tsv *tsv)
- {
- struct ctf_trace_file_writer *writer
- = (struct ctf_trace_file_writer *) self;
- int32_t int32;
- int64_t int64;
- unsigned int len;
- const gdb_byte zero = 0;
-
- int32 = CTF_EVENT_ID_TSV_DEF;
- ctf_save_align_write (&writer->tcs, (gdb_byte *) &int32, 4, 4);
-
- int64 = tsv->initial_value;
- ctf_save_align_write (&writer->tcs, (gdb_byte *) &int64, 8, 8);
-
- ctf_save_write_int32 (&writer->tcs, tsv->number);
-
- ctf_save_write_int32 (&writer->tcs, tsv->builtin);
-
- if (tsv->name != NULL)
- ctf_save_write (&writer->tcs, (gdb_byte *) tsv->name,
- strlen (tsv->name));
- ctf_save_write (&writer->tcs, &zero, 1);
- }
- static void
- ctf_write_uploaded_tp (struct trace_file_writer *self,
- struct uploaded_tp *tp)
- {
- struct ctf_trace_file_writer *writer
- = (struct ctf_trace_file_writer *) self;
- int32_t int32;
- int64_t int64;
- uint32_t u32;
- const gdb_byte zero = 0;
- int a;
- char *act;
-
- int32 = CTF_EVENT_ID_TP_DEF;
- ctf_save_align_write (&writer->tcs, (gdb_byte *) &int32, 4, 4);
-
- int64 = tp->addr;
- ctf_save_align_write (&writer->tcs, (gdb_byte *) &int64, 8, 8);
-
- int64 = tp->traceframe_usage;
- ctf_save_align_write (&writer->tcs, (gdb_byte *) &int64, 8, 8);
-
- ctf_save_write_int32 (&writer->tcs, tp->number);
-
- ctf_save_write_int32 (&writer->tcs, tp->enabled);
-
- ctf_save_write_int32 (&writer->tcs, tp->step);
-
- ctf_save_write_int32 (&writer->tcs, tp->pass);
-
- ctf_save_write_int32 (&writer->tcs, tp->hit_count);
-
- ctf_save_write_int32 (&writer->tcs, tp->type);
-
- if (tp->cond != NULL)
- ctf_save_write (&writer->tcs, (gdb_byte *) tp->cond, strlen (tp->cond));
- ctf_save_write (&writer->tcs, &zero, 1);
-
- u32 = VEC_length (char_ptr, tp->actions);
- ctf_save_align_write (&writer->tcs, (gdb_byte *) &u32, 4, 4);
- for (a = 0; VEC_iterate (char_ptr, tp->actions, a, act); ++a)
- ctf_save_write (&writer->tcs, (gdb_byte *) act, strlen (act) + 1);
-
- u32 = VEC_length (char_ptr, tp->step_actions);
- ctf_save_align_write (&writer->tcs, (gdb_byte *) &u32, 4, 4);
- for (a = 0; VEC_iterate (char_ptr, tp->step_actions, a, act); ++a)
- ctf_save_write (&writer->tcs, (gdb_byte *) act, strlen (act) + 1);
-
- if (tp->at_string != NULL)
- ctf_save_write (&writer->tcs, (gdb_byte *) tp->at_string,
- strlen (tp->at_string));
- ctf_save_write (&writer->tcs, &zero, 1);
-
- if (tp->cond_string != NULL)
- ctf_save_write (&writer->tcs, (gdb_byte *) tp->cond_string,
- strlen (tp->cond_string));
- ctf_save_write (&writer->tcs, &zero, 1);
-
- u32 = VEC_length (char_ptr, tp->cmd_strings);
- ctf_save_align_write (&writer->tcs, (gdb_byte *) &u32, 4, 4);
- for (a = 0; VEC_iterate (char_ptr, tp->cmd_strings, a, act); ++a)
- ctf_save_write (&writer->tcs, (gdb_byte *) act, strlen (act) + 1);
- }
- static void
- ctf_write_definition_end (struct trace_file_writer *self)
- {
- struct ctf_trace_file_writer *writer
- = (struct ctf_trace_file_writer *) self;
- self->ops->frame_ops->end (self);
- }
- static void
- ctf_end (struct trace_file_writer *self)
- {
- struct ctf_trace_file_writer *writer = (struct ctf_trace_file_writer *) self;
- gdb_assert (writer->tcs.content_size == 0);
- }
- static void
- ctf_write_frame_start (struct trace_file_writer *self, uint16_t tpnum)
- {
- struct ctf_trace_file_writer *writer
- = (struct ctf_trace_file_writer *) self;
- uint32_t id = CTF_EVENT_ID_FRAME;
- uint32_t u32;
-
-
- u32 = CTF_MAGIC;
- ctf_save_write_uint32 (&writer->tcs, u32);
-
- ctf_save_fseek (&writer->tcs, 4, SEEK_CUR);
- ctf_save_fseek (&writer->tcs, 4, SEEK_CUR);
-
- ctf_save_write (&writer->tcs, (gdb_byte *) &tpnum, 2);
-
-
- ctf_save_align_write (&writer->tcs, (gdb_byte *) &id, 4, 4);
- }
- static void
- ctf_write_frame_r_block (struct trace_file_writer *self,
- gdb_byte *buf, int32_t size)
- {
- struct ctf_trace_file_writer *writer
- = (struct ctf_trace_file_writer *) self;
- uint32_t id = CTF_EVENT_ID_REGISTER;
-
- ctf_save_align_write (&writer->tcs, (gdb_byte *) &id, 4, 4);
-
- ctf_save_align_write (&writer->tcs, buf, size, 1);
- }
- static void
- ctf_write_frame_m_block_header (struct trace_file_writer *self,
- uint64_t addr, uint16_t length)
- {
- struct ctf_trace_file_writer *writer
- = (struct ctf_trace_file_writer *) self;
- uint32_t event_id = CTF_EVENT_ID_MEMORY;
-
- ctf_save_align_write (&writer->tcs, (gdb_byte *) &event_id, 4, 4);
-
- ctf_save_align_write (&writer->tcs, (gdb_byte *) &addr, 8, 8);
-
- ctf_save_align_write (&writer->tcs, (gdb_byte *) &length, 2, 2);
- }
- static void
- ctf_write_frame_m_block_memory (struct trace_file_writer *self,
- gdb_byte *buf, uint16_t length)
- {
- struct ctf_trace_file_writer *writer
- = (struct ctf_trace_file_writer *) self;
-
- ctf_save_align_write (&writer->tcs, (gdb_byte *) buf, length, 1);
- }
- static void
- ctf_write_frame_v_block (struct trace_file_writer *self,
- int32_t num, uint64_t val)
- {
- struct ctf_trace_file_writer *writer
- = (struct ctf_trace_file_writer *) self;
- uint32_t id = CTF_EVENT_ID_TSV;
-
- ctf_save_align_write (&writer->tcs, (gdb_byte *) &id, 4, 4);
-
- ctf_save_align_write (&writer->tcs, (gdb_byte *) &val, 8, 8);
-
- ctf_save_align_write (&writer->tcs, (gdb_byte *) &num, 4, 4);
- }
- static void
- ctf_write_frame_end (struct trace_file_writer *self)
- {
- struct ctf_trace_file_writer *writer
- = (struct ctf_trace_file_writer *) self;
- uint32_t u32;
- uint32_t t;
-
- ctf_save_fseek (&writer->tcs, writer->tcs.packet_start + 4,
- SEEK_SET);
- u32 = writer->tcs.content_size * TARGET_CHAR_BIT;
- t = writer->tcs.content_size;
- ctf_save_write_uint32 (&writer->tcs, u32);
-
- u32 += 4 * TARGET_CHAR_BIT;
- ctf_save_write_uint32 (&writer->tcs, u32);
- writer->tcs.content_size = t;
-
- ctf_save_fseek (&writer->tcs, writer->tcs.packet_start + t,
- SEEK_SET);
- u32 = 0;
- ctf_save_write_uint32 (&writer->tcs, u32);
- writer->tcs.content_size = t;
- ctf_save_next_packet (&writer->tcs);
- }
- static const struct trace_frame_write_ops ctf_write_frame_ops =
- {
- ctf_write_frame_start,
- ctf_write_frame_r_block,
- ctf_write_frame_m_block_header,
- ctf_write_frame_m_block_memory,
- ctf_write_frame_v_block,
- ctf_write_frame_end,
- };
- static const struct trace_file_write_ops ctf_write_ops =
- {
- ctf_dtor,
- ctf_target_save,
- ctf_start,
- ctf_write_header,
- ctf_write_regblock_type,
- ctf_write_status,
- ctf_write_uploaded_tsv,
- ctf_write_uploaded_tp,
- ctf_write_definition_end,
- NULL,
- &ctf_write_frame_ops,
- ctf_end,
- };
- struct trace_file_writer *
- ctf_trace_file_writer_new (void)
- {
- struct ctf_trace_file_writer *writer
- = xmalloc (sizeof (struct ctf_trace_file_writer));
- writer->base.ops = &ctf_write_ops;
- return (struct trace_file_writer *) writer;
- }
- #if HAVE_LIBBABELTRACE
- #include <babeltrace/babeltrace.h>
- #include <babeltrace/ctf/events.h>
- #include <babeltrace/ctf/iterator.h>
- static int handle_id = -1;
- static struct bt_context *ctx = NULL;
- static struct bt_ctf_iter *ctf_iter = NULL;
- static struct bt_iter_pos *start_pos;
- static char *trace_dirname;
- static struct target_ops ctf_ops;
- static void
- ctf_destroy (void)
- {
- if (ctf_iter != NULL)
- {
- bt_ctf_iter_destroy (ctf_iter);
- ctf_iter = NULL;
- }
- if (ctx != NULL)
- {
- bt_context_put (ctx);
- ctx = NULL;
- }
- }
- static void
- ctf_open_dir (const char *dirname)
- {
- struct bt_iter_pos begin_pos;
- struct bt_iter_pos *pos;
- unsigned int count, i;
- struct bt_ctf_event_decl * const *list;
- ctx = bt_context_create ();
- if (ctx == NULL)
- error (_("Unable to create bt_context"));
- handle_id = bt_context_add_trace (ctx, dirname, "ctf", NULL, NULL, NULL);
- if (handle_id < 0)
- {
- ctf_destroy ();
- error (_("Unable to use libbabeltrace on directory \"%s\""),
- dirname);
- }
- begin_pos.type = BT_SEEK_BEGIN;
- ctf_iter = bt_ctf_iter_create (ctx, &begin_pos, NULL);
- if (ctf_iter == NULL)
- {
- ctf_destroy ();
- error (_("Unable to create bt_iterator"));
- }
-
- bt_ctf_get_event_decl_list (handle_id, ctx, &list, &count);
- for (i = 0; i < count; i++)
- if (strcmp ("register", bt_ctf_get_decl_event_name (list[i])) == 0)
- {
- unsigned int j;
- const struct bt_ctf_field_decl * const *field_list;
- const struct bt_declaration *decl;
- bt_ctf_get_decl_fields (list[i], BT_EVENT_FIELDS, &field_list,
- &count);
- gdb_assert (count == 1);
- gdb_assert (0 == strcmp ("contents",
- bt_ctf_get_decl_field_name (field_list[0])));
- decl = bt_ctf_get_decl_from_field_decl (field_list[0]);
- trace_regblock_size = bt_ctf_get_array_len (decl);
- break;
- }
- }
- #define SET_INT32_FIELD(EVENT, SCOPE, VAR, FIELD) \
- (VAR)->FIELD = (int) bt_ctf_get_int64 (bt_ctf_get_field ((EVENT), \
- (SCOPE), \
- #FIELD))
- static void
- ctf_read_status (struct bt_ctf_event *event, struct trace_status *ts)
- {
- const struct bt_definition *scope
- = bt_ctf_get_top_level_scope (event, BT_EVENT_FIELDS);
- SET_INT32_FIELD (event, scope, ts, stop_reason);
- SET_INT32_FIELD (event, scope, ts, stopping_tracepoint);
- SET_INT32_FIELD (event, scope, ts, traceframe_count);
- SET_INT32_FIELD (event, scope, ts, traceframes_created);
- SET_INT32_FIELD (event, scope, ts, buffer_free);
- SET_INT32_FIELD (event, scope, ts, buffer_size);
- SET_INT32_FIELD (event, scope, ts, disconnected_tracing);
- SET_INT32_FIELD (event, scope, ts, circular_buffer);
- bt_iter_next (bt_ctf_get_iter (ctf_iter));
- }
- static void
- ctf_read_tsv (struct uploaded_tsv **uploaded_tsvs)
- {
- gdb_assert (ctf_iter != NULL);
- while (1)
- {
- struct bt_ctf_event *event;
- const struct bt_definition *scope;
- const struct bt_definition *def;
- uint32_t event_id;
- struct uploaded_tsv *utsv = NULL;
- event = bt_ctf_iter_read_event (ctf_iter);
- scope = bt_ctf_get_top_level_scope (event,
- BT_STREAM_EVENT_HEADER);
- event_id = bt_ctf_get_uint64 (bt_ctf_get_field (event, scope,
- "id"));
- if (event_id != CTF_EVENT_ID_TSV_DEF)
- break;
- scope = bt_ctf_get_top_level_scope (event,
- BT_EVENT_FIELDS);
- def = bt_ctf_get_field (event, scope, "number");
- utsv = get_uploaded_tsv ((int32_t) bt_ctf_get_int64 (def),
- uploaded_tsvs);
- def = bt_ctf_get_field (event, scope, "builtin");
- utsv->builtin = (int32_t) bt_ctf_get_int64 (def);
- def = bt_ctf_get_field (event, scope, "initial_value");
- utsv->initial_value = bt_ctf_get_int64 (def);
- def = bt_ctf_get_field (event, scope, "name");
- utsv->name = xstrdup (bt_ctf_get_string (def));
- if (bt_iter_next (bt_ctf_get_iter (ctf_iter)) < 0)
- break;
- }
- }
- #define SET_ARRAY_FIELD(EVENT, SCOPE, VAR, NUM, ARRAY) \
- do \
- { \
- uint32_t u32, i; \
- const struct bt_definition *def; \
- \
- u32 = (uint32_t) bt_ctf_get_uint64 (bt_ctf_get_field ((EVENT), \
- (SCOPE), \
- #NUM)); \
- def = bt_ctf_get_field ((EVENT), (SCOPE), #ARRAY); \
- for (i = 0; i < u32; i++) \
- { \
- const struct bt_definition *element \
- = bt_ctf_get_index ((EVENT), def, i); \
- \
- VEC_safe_push (char_ptr, (VAR)->ARRAY, \
- xstrdup (bt_ctf_get_string (element))); \
- } \
- } \
- while (0)
- #define SET_STRING_FIELD(EVENT, SCOPE, VAR, FIELD) \
- do \
- { \
- const char *p = bt_ctf_get_string (bt_ctf_get_field ((EVENT), \
- (SCOPE), \
- #FIELD)); \
- \
- if (strlen (p) > 0) \
- (VAR)->FIELD = xstrdup (p); \
- else \
- (VAR)->FIELD = NULL; \
- } \
- while (0)
- static void
- ctf_read_tp (struct uploaded_tp **uploaded_tps)
- {
- gdb_assert (ctf_iter != NULL);
- while (1)
- {
- struct bt_ctf_event *event;
- const struct bt_definition *scope;
- uint32_t u32;
- int32_t int32;
- uint64_t u64;
- struct uploaded_tp *utp = NULL;
- event = bt_ctf_iter_read_event (ctf_iter);
- scope = bt_ctf_get_top_level_scope (event,
- BT_STREAM_EVENT_HEADER);
- u32 = bt_ctf_get_uint64 (bt_ctf_get_field (event, scope,
- "id"));
- if (u32 != CTF_EVENT_ID_TP_DEF)
- break;
- scope = bt_ctf_get_top_level_scope (event,
- BT_EVENT_FIELDS);
- int32 = (int32_t) bt_ctf_get_int64 (bt_ctf_get_field (event,
- scope,
- "number"));
- u64 = bt_ctf_get_uint64 (bt_ctf_get_field (event, scope,
- "addr"));
- utp = get_uploaded_tp (int32, u64, uploaded_tps);
- SET_INT32_FIELD (event, scope, utp, enabled);
- SET_INT32_FIELD (event, scope, utp, step);
- SET_INT32_FIELD (event, scope, utp, pass);
- SET_INT32_FIELD (event, scope, utp, hit_count);
- SET_INT32_FIELD (event, scope, utp, type);
-
- SET_ARRAY_FIELD (event, scope, utp, cmd_num, cmd_strings);
-
- SET_ARRAY_FIELD (event, scope, utp, action_num, actions);
-
- SET_ARRAY_FIELD (event, scope, utp, step_action_num,
- step_actions);
- SET_STRING_FIELD(event, scope, utp, at_string);
- SET_STRING_FIELD(event, scope, utp, cond_string);
- if (bt_iter_next (bt_ctf_get_iter (ctf_iter)) < 0)
- break;
- }
- }
- static void
- ctf_open (const char *dirname, int from_tty)
- {
- struct bt_ctf_event *event;
- uint32_t event_id;
- const struct bt_definition *scope;
- struct uploaded_tsv *uploaded_tsvs = NULL;
- struct uploaded_tp *uploaded_tps = NULL;
- if (!dirname)
- error (_("No CTF directory specified."));
- ctf_open_dir (dirname);
- target_preopen (from_tty);
-
- event = bt_ctf_iter_read_event (ctf_iter);
- scope = bt_ctf_get_top_level_scope (event, BT_STREAM_EVENT_HEADER);
- event_id = bt_ctf_get_uint64 (bt_ctf_get_field (event, scope, "id"));
- if (event_id != CTF_EVENT_ID_FRAME)
- error (_("Wrong event id of the first event"));
-
- bt_iter_next (bt_ctf_get_iter (ctf_iter));
- event = bt_ctf_iter_read_event (ctf_iter);
- scope = bt_ctf_get_top_level_scope (event, BT_STREAM_EVENT_HEADER);
- event_id = bt_ctf_get_uint64 (bt_ctf_get_field (event, scope, "id"));
- if (event_id != CTF_EVENT_ID_STATUS)
- error (_("Wrong event id of the second event"));
- ctf_read_status (event, current_trace_status ());
- ctf_read_tsv (&uploaded_tsvs);
- ctf_read_tp (&uploaded_tps);
- event = bt_ctf_iter_read_event (ctf_iter);
-
- if (event != NULL)
- {
- scope = bt_ctf_get_top_level_scope (event,
- BT_STREAM_EVENT_HEADER);
- event_id = bt_ctf_get_uint64 (bt_ctf_get_field (event,
- scope, "id"));
- if (event_id != CTF_EVENT_ID_FRAME)
- error (_("Wrong event id of the first event of the second packet"));
- }
- start_pos = bt_iter_get_pos (bt_ctf_get_iter (ctf_iter));
- gdb_assert (start_pos->type == BT_SEEK_RESTORE);
- trace_dirname = xstrdup (dirname);
- push_target (&ctf_ops);
- inferior_appeared (current_inferior (), CTF_PID);
- inferior_ptid = pid_to_ptid (CTF_PID);
- add_thread_silent (inferior_ptid);
- merge_uploaded_trace_state_variables (&uploaded_tsvs);
- merge_uploaded_tracepoints (&uploaded_tps);
- post_create_inferior (&ctf_ops, from_tty);
- }
- static void
- ctf_close (struct target_ops *self)
- {
- int pid;
- ctf_destroy ();
- xfree (trace_dirname);
- trace_dirname = NULL;
- pid = ptid_get_pid (inferior_ptid);
- inferior_ptid = null_ptid;
- exit_inferior_silent (pid);
- trace_reset_local_state ();
- }
- static void
- ctf_files_info (struct target_ops *t)
- {
- printf_filtered ("\t`%s'\n", trace_dirname);
- }
- static void
- ctf_fetch_registers (struct target_ops *ops,
- struct regcache *regcache, int regno)
- {
- struct gdbarch *gdbarch = get_regcache_arch (regcache);
- struct bt_ctf_event *event = NULL;
- struct bt_iter_pos *pos;
-
- if (trace_regblock_size == 0)
- return;
- gdb_assert (ctf_iter != NULL);
-
- pos = bt_iter_get_pos (bt_ctf_get_iter (ctf_iter));
- gdb_assert (pos->type == BT_SEEK_RESTORE);
- while (1)
- {
- const char *name;
- struct bt_ctf_event *event1;
- event1 = bt_ctf_iter_read_event (ctf_iter);
- name = bt_ctf_event_name (event1);
- if (name == NULL || strcmp (name, "frame") == 0)
- break;
- else if (strcmp (name, "register") == 0)
- {
- event = event1;
- break;
- }
- if (bt_iter_next (bt_ctf_get_iter (ctf_iter)) < 0)
- break;
- }
-
- bt_iter_set_pos (bt_ctf_get_iter (ctf_iter), pos);
- if (event != NULL)
- {
- int offset, regsize, regn;
- const struct bt_definition *scope
- = bt_ctf_get_top_level_scope (event,
- BT_EVENT_FIELDS);
- const struct bt_definition *array
- = bt_ctf_get_field (event, scope, "contents");
- gdb_byte *regs = (gdb_byte *) bt_ctf_get_char_array (array);
-
- offset = 0;
- for (regn = 0; regn < gdbarch_num_regs (gdbarch); regn++)
- {
- regsize = register_size (gdbarch, regn);
-
- if (offset + regsize >= trace_regblock_size)
- break;
- if (regcache_register_status (regcache, regn) == REG_UNKNOWN)
- {
- if (regno == regn)
- {
- regcache_raw_supply (regcache, regno, regs + offset);
- break;
- }
- else if (regno == -1)
- {
- regcache_raw_supply (regcache, regn, regs + offset);
- }
- }
- offset += regsize;
- }
- }
- else
- tracefile_fetch_registers (regcache, regno);
- }
- static enum target_xfer_status
- ctf_xfer_partial (struct target_ops *ops, enum target_object object,
- const char *annex, gdb_byte *readbuf,
- const gdb_byte *writebuf, ULONGEST offset,
- ULONGEST len, ULONGEST *xfered_len)
- {
-
- if (object != TARGET_OBJECT_MEMORY)
- return -1;
- if (readbuf == NULL)
- error (_("ctf_xfer_partial: trace file is read-only"));
- if (get_traceframe_number () != -1)
- {
- struct bt_iter_pos *pos;
- int i = 0;
- enum target_xfer_status res;
-
- ULONGEST low_addr_available = 0;
- gdb_assert (ctf_iter != NULL);
-
- pos = bt_iter_get_pos (bt_ctf_get_iter (ctf_iter));
- gdb_assert (pos->type == BT_SEEK_RESTORE);
-
- while (1)
- {
- ULONGEST amt;
- uint64_t maddr;
- uint16_t mlen;
- enum bfd_endian byte_order
- = gdbarch_byte_order (target_gdbarch ());
- const struct bt_definition *scope;
- const struct bt_definition *def;
- struct bt_ctf_event *event
- = bt_ctf_iter_read_event (ctf_iter);
- const char *name = bt_ctf_event_name (event);
- if (name == NULL || strcmp (name, "frame") == 0)
- break;
- else if (strcmp (name, "memory") != 0)
- {
- if (bt_iter_next (bt_ctf_get_iter (ctf_iter)) < 0)
- break;
- continue;
- }
- scope = bt_ctf_get_top_level_scope (event,
- BT_EVENT_FIELDS);
- def = bt_ctf_get_field (event, scope, "address");
- maddr = bt_ctf_get_uint64 (def);
- def = bt_ctf_get_field (event, scope, "length");
- mlen = (uint16_t) bt_ctf_get_uint64 (def);
-
- if (maddr <= offset && offset < (maddr + mlen))
- {
- const struct bt_definition *array
- = bt_ctf_get_field (event, scope, "contents");
- const struct bt_declaration *decl
- = bt_ctf_get_decl_from_def (array);
- gdb_byte *contents;
- int k;
- contents = xmalloc (mlen);
- for (k = 0; k < mlen; k++)
- {
- const struct bt_definition *element
- = bt_ctf_get_index (event, array, k);
- contents[k] = (gdb_byte) bt_ctf_get_uint64 (element);
- }
- amt = (maddr + mlen) - offset;
- if (amt > len)
- amt = len;
- memcpy (readbuf, &contents[offset - maddr], amt);
- xfree (contents);
-
- bt_iter_set_pos (bt_ctf_get_iter (ctf_iter), pos);
- if (amt == 0)
- return TARGET_XFER_EOF;
- else
- {
- *xfered_len = amt;
- return TARGET_XFER_OK;
- }
- }
- if (offset < maddr && maddr < (offset + len))
- if (low_addr_available == 0 || low_addr_available > maddr)
- low_addr_available = maddr;
- if (bt_iter_next (bt_ctf_get_iter (ctf_iter)) < 0)
- break;
- }
-
- bt_iter_set_pos (bt_ctf_get_iter (ctf_iter), pos);
-
- if (offset < low_addr_available)
- len = min (len, low_addr_available - offset);
- res = exec_read_partial_read_only (readbuf, offset, len, xfered_len);
- if (res == TARGET_XFER_OK)
- return TARGET_XFER_OK;
- else
- {
-
- *xfered_len = len;
- return TARGET_XFER_UNAVAILABLE;
- }
- }
- else
- {
-
- return section_table_read_available_memory (readbuf, offset, len, xfered_len);
- }
- }
- static int
- ctf_get_trace_state_variable_value (struct target_ops *self,
- int tsvnum, LONGEST *val)
- {
- struct bt_iter_pos *pos;
- int found = 0;
- gdb_assert (ctf_iter != NULL);
-
- pos = bt_iter_get_pos (bt_ctf_get_iter (ctf_iter));
- gdb_assert (pos->type == BT_SEEK_RESTORE);
-
- while (1)
- {
- struct bt_ctf_event *event
- = bt_ctf_iter_read_event (ctf_iter);
- const char *name = bt_ctf_event_name (event);
- if (name == NULL || strcmp (name, "frame") == 0)
- break;
- else if (strcmp (name, "tsv") == 0)
- {
- const struct bt_definition *scope;
- const struct bt_definition *def;
- scope = bt_ctf_get_top_level_scope (event,
- BT_EVENT_FIELDS);
- def = bt_ctf_get_field (event, scope, "num");
- if (tsvnum == (int32_t) bt_ctf_get_uint64 (def))
- {
- def = bt_ctf_get_field (event, scope, "val");
- *val = bt_ctf_get_uint64 (def);
- found = 1;
- }
- }
- if (bt_iter_next (bt_ctf_get_iter (ctf_iter)) < 0)
- break;
- }
-
- bt_iter_set_pos (bt_ctf_get_iter (ctf_iter), pos);
- return found;
- }
- static int
- ctf_get_tpnum_from_frame_event (struct bt_ctf_event *event)
- {
-
- const struct bt_definition *scope
- = bt_ctf_get_top_level_scope (event, BT_STREAM_PACKET_CONTEXT);
- uint64_t tpnum
- = bt_ctf_get_uint64 (bt_ctf_get_field (event, scope, "tpnum"));
- return (int) tpnum;
- }
- static CORE_ADDR
- ctf_get_traceframe_address (void)
- {
- struct bt_ctf_event *event = NULL;
- struct bt_iter_pos *pos;
- CORE_ADDR addr = 0;
- gdb_assert (ctf_iter != NULL);
- pos = bt_iter_get_pos (bt_ctf_get_iter (ctf_iter));
- gdb_assert (pos->type == BT_SEEK_RESTORE);
- while (1)
- {
- const char *name;
- struct bt_ctf_event *event1;
- event1 = bt_ctf_iter_read_event (ctf_iter);
- name = bt_ctf_event_name (event1);
- if (name == NULL)
- break;
- else if (strcmp (name, "frame") == 0)
- {
- event = event1;
- break;
- }
- if (bt_iter_next (bt_ctf_get_iter (ctf_iter)) < 0)
- break;
- }
- if (event != NULL)
- {
- int tpnum = ctf_get_tpnum_from_frame_event (event);
- struct tracepoint *tp
- = get_tracepoint_by_number_on_target (tpnum);
- if (tp && tp->base.loc)
- addr = tp->base.loc->address;
- }
-
- bt_iter_set_pos (bt_ctf_get_iter (ctf_iter), pos);
- return addr;
- }
- static int
- ctf_trace_find (struct target_ops *self, enum trace_find_type type, int num,
- CORE_ADDR addr1, CORE_ADDR addr2, int *tpp)
- {
- int ret = -1;
- int tfnum = 0;
- int found = 0;
- struct bt_iter_pos pos;
- if (num == -1)
- {
- if (tpp != NULL)
- *tpp = -1;
- return -1;
- }
- gdb_assert (ctf_iter != NULL);
-
- bt_iter_set_pos (bt_ctf_get_iter (ctf_iter), start_pos);
- while (1)
- {
- int id;
- struct bt_ctf_event *event;
- const char *name;
- event = bt_ctf_iter_read_event (ctf_iter);
- name = bt_ctf_event_name (event);
- if (event == NULL || name == NULL)
- break;
- if (strcmp (name, "frame") == 0)
- {
- CORE_ADDR tfaddr;
- if (type == tfind_number)
- {
-
- if (tfnum == num)
- found = 1;
- }
- else
- {
-
- if (tfnum > get_traceframe_number ())
- {
- switch (type)
- {
- case tfind_tp:
- {
- struct tracepoint *tp = get_tracepoint (num);
- if (tp != NULL
- && (tp->number_on_target
- == ctf_get_tpnum_from_frame_event (event)))
- found = 1;
- break;
- }
- case tfind_pc:
- tfaddr = ctf_get_traceframe_address ();
- if (tfaddr == addr1)
- found = 1;
- break;
- case tfind_range:
- tfaddr = ctf_get_traceframe_address ();
- if (addr1 <= tfaddr && tfaddr <= addr2)
- found = 1;
- break;
- case tfind_outside:
- tfaddr = ctf_get_traceframe_address ();
- if (!(addr1 <= tfaddr && tfaddr <= addr2))
- found = 1;
- break;
- default:
- internal_error (__FILE__, __LINE__, _("unknown tfind type"));
- }
- }
- }
- if (found)
- {
- if (tpp != NULL)
- *tpp = ctf_get_tpnum_from_frame_event (event);
-
- bt_iter_next (bt_ctf_get_iter (ctf_iter));
- return tfnum;
- }
- tfnum++;
- }
- if (bt_iter_next (bt_ctf_get_iter (ctf_iter)) < 0)
- break;
- }
- return -1;
- }
- static struct traceframe_info *
- ctf_traceframe_info (struct target_ops *self)
- {
- struct traceframe_info *info = XCNEW (struct traceframe_info);
- const char *name;
- struct bt_iter_pos *pos;
- gdb_assert (ctf_iter != NULL);
-
- pos = bt_iter_get_pos (bt_ctf_get_iter (ctf_iter));
- gdb_assert (pos->type == BT_SEEK_RESTORE);
- do
- {
- struct bt_ctf_event *event
- = bt_ctf_iter_read_event (ctf_iter);
- name = bt_ctf_event_name (event);
- if (name == NULL || strcmp (name, "register") == 0
- || strcmp (name, "frame") == 0)
- ;
- else if (strcmp (name, "memory") == 0)
- {
- const struct bt_definition *scope
- = bt_ctf_get_top_level_scope (event,
- BT_EVENT_FIELDS);
- const struct bt_definition *def;
- struct mem_range *r;
- r = VEC_safe_push (mem_range_s, info->memory, NULL);
- def = bt_ctf_get_field (event, scope, "address");
- r->start = bt_ctf_get_uint64 (def);
- def = bt_ctf_get_field (event, scope, "length");
- r->length = (uint16_t) bt_ctf_get_uint64 (def);
- }
- else if (strcmp (name, "tsv") == 0)
- {
- int vnum;
- const struct bt_definition *scope
- = bt_ctf_get_top_level_scope (event,
- BT_EVENT_FIELDS);
- const struct bt_definition *def;
- def = bt_ctf_get_field (event, scope, "num");
- vnum = (int) bt_ctf_get_int64 (def);
- VEC_safe_push (int, info->tvars, vnum);
- }
- else
- {
- warning (_("Unhandled trace block type (%s) "
- "while building trace frame info."),
- name);
- }
- if (bt_iter_next (bt_ctf_get_iter (ctf_iter)) < 0)
- break;
- }
- while (name != NULL && strcmp (name, "frame") != 0);
-
- bt_iter_set_pos (bt_ctf_get_iter (ctf_iter), pos);
- return info;
- }
- static void
- init_ctf_ops (void)
- {
- memset (&ctf_ops, 0, sizeof (ctf_ops));
- init_tracefile_ops (&ctf_ops);
- ctf_ops.to_shortname = "ctf";
- ctf_ops.to_longname = "CTF file";
- ctf_ops.to_doc = "Use a CTF directory as a target.\n\
- Specify the filename of the CTF directory.";
- ctf_ops.to_open = ctf_open;
- ctf_ops.to_close = ctf_close;
- ctf_ops.to_fetch_registers = ctf_fetch_registers;
- ctf_ops.to_xfer_partial = ctf_xfer_partial;
- ctf_ops.to_files_info = ctf_files_info;
- ctf_ops.to_trace_find = ctf_trace_find;
- ctf_ops.to_get_trace_state_variable_value
- = ctf_get_trace_state_variable_value;
- ctf_ops.to_traceframe_info = ctf_traceframe_info;
- }
- #endif
- extern initialize_file_ftype _initialize_ctf;
- void
- _initialize_ctf (void)
- {
- #if HAVE_LIBBABELTRACE
- init_ctf_ops ();
- add_target_with_completer (&ctf_ops, filename_completer);
- #endif
- }