Add CTFVisitor implementation freescale-nexus
authorChristian Babeux <christian.babeux@efficios.com>
Sun, 13 Oct 2013 03:43:43 +0000 (23:43 -0400)
committerJérémie Galarneau <jeremie.galarneau@efficios.com>
Fri, 13 Dec 2013 21:45:05 +0000 (16:45 -0500)
First implementation of the Freescale Nexus to CTF visitor.

Signed-off-by: Christian Babeux <christian.babeux@efficios.com>
Signed-off-by: Jérémie Galarneau <jeremie.galarneau@efficios.com>
converter/nexus/CTFLogVisitor.cpp
converter/nexus/CTFLogVisitor.h

index 7a7e86f3f9710355d2d0f6ae7a65e253c20878b2..0b7c8dd59dbf00aea85e030b9dedfb8d34a7af43 100644 (file)
  * IN THE SOFTWARE.
  */
 
+#include <cassert>
 #include <sstream>
-
+#include <utility>
 #include "CTFLogVisitor.h"
 #include "NxMessageVisitor.h"
 #include "NxMessage.h"
 
-using std::ostringstream;
-using std::endl;
+using std::map;
+using std::string;
+
+namespace {
+       /* Types */
+       struct bt_ctf_field_type *uint32_bin_type;
+       struct bt_ctf_field_type *uint32_oct_type;
+       struct bt_ctf_field_type *uint32_dec_type;
+       struct bt_ctf_field_type *uint32_hex_type;
+
+       struct bt_ctf_field_type *uint64_bin_type;
+       struct bt_ctf_field_type *uint64_oct_type;
+       struct bt_ctf_field_type *uint64_dec_type;
+       struct bt_ctf_field_type *uint64_hex_type;
+
+       struct bt_ctf_field_type *string_type;
+}
+
+CTFLogVisitor::CTFIntegerField::CTFIntegerField(const string &name,
+               uint32_t value,
+               enum bt_ctf_integer_base base)
+{
+       struct bt_ctf_field_type *type;
+
+       switch (base)
+       {
+       case BT_CTF_INTEGER_BASE_BINARY:
+               type = uint32_bin_type;
+               break;
+       case BT_CTF_INTEGER_BASE_OCTAL:
+               type = uint32_oct_type;
+               break;
+       case BT_CTF_INTEGER_BASE_DECIMAL:
+               type = uint32_dec_type;
+               break;
+       case BT_CTF_INTEGER_BASE_HEXADECIMAL:
+               type = uint32_hex_type;
+               break;
+       default:
+               assert(false);
+               break;
+       };
+
+       create_unsigned_field(name, type, value);
+}
+
+CTFLogVisitor::CTFIntegerField::CTFIntegerField(const string &name,
+               uint64_t value,
+               enum bt_ctf_integer_base base)
+{
+       struct bt_ctf_field_type *type;
+
+       switch (base)
+       {
+       case BT_CTF_INTEGER_BASE_BINARY:
+               type = uint64_bin_type;
+               break;
+       case BT_CTF_INTEGER_BASE_OCTAL:
+               type = uint64_oct_type;
+               break;
+       case BT_CTF_INTEGER_BASE_DECIMAL:
+               type = uint64_dec_type;
+               break;
+       case BT_CTF_INTEGER_BASE_HEXADECIMAL:
+               type = uint64_hex_type;
+               break;
+       default:
+               assert(false);
+               break;
+       };
+
+       create_unsigned_field(name, type, value);
+}
+
+void CTFLogVisitor::CTFIntegerField::create_unsigned_field(const string &name,
+               struct bt_ctf_field_type *type,
+               uint64_t value)
+{
+       int ret = 0;
+       struct bt_ctf_field *field = NULL;
+
+       assert(type);
+
+       field = bt_ctf_field_create(type);
+       assert(field);
+
+       ret = bt_ctf_field_unsigned_integer_set_value(field, value);
+       assert(!ret);
+
+       name_  = name;
+       field_ = field;
+       type_  = type;
+}
+
+CTFLogVisitor::CTFStringField::CTFStringField(const string &name,
+               const string &value)
+{
+       int ret = 0;
+       struct bt_ctf_field *field = NULL;
 
-CTFLogVisitor::CTFLogVisitor(const string& trace_path)
-       : trace_path_(trace_path)
+       field = bt_ctf_field_create(string_type);
+       assert(field);
+
+       ret = bt_ctf_field_string_set_value(field, value.c_str());
+       assert(!ret);
+
+       name_  = name;
+       field_ = field;
+       type_  = string_type;
+}
+
+CTFLogVisitor::CTFLogVisitor(const string &trace_path)
 {
-       // TODO
+       int ret = 0;
+       uint64_t default_clock = 1000000000;
+
+       writer_ = bt_ctf_writer_create(trace_path.c_str());
+
+       /* TODO: How can we handle errors in the visitor? */
+       assert(writer_);
+       ret = bt_ctf_writer_add_environment_field(writer_,
+                                           "converter",
+                                           "Babeltrace Nexus to CTF");
+       assert(!ret);
+
+       /* Clock */
+
+       /*
+        * TODO: Figure out how to obtain clock frequency and precision
+        *       from the traced system.
+        */
+       clock_ = bt_ctf_clock_create("system_clock");
+       assert(clock_);
+
+       ret = bt_ctf_clock_set_description(clock_, "System clock");
+       assert(!ret);
+
+       ret = bt_ctf_clock_set_frequency(clock_, default_clock);
+       assert(!ret);
+
+       ret = bt_ctf_clock_set_is_absolute(clock_, 1);
+       assert(!ret);
+
+       ret = bt_ctf_writer_add_clock(writer_, clock_);
+       assert(!ret);
+
+       /* Stream class */
+       stream_class_ = bt_ctf_stream_class_create("stream0");
+       assert(stream_class_);
+
+       ret = bt_ctf_stream_class_set_clock(stream_class_, clock_);
+       assert(!ret);
+
+       stream_ = bt_ctf_writer_create_stream(writer_, stream_class_);
+       assert(stream_);
+
+       /* Types init */
+       string_type = bt_ctf_field_type_string_create();
+
+       uint32_bin_type = bt_ctf_field_type_integer_create(32);
+       ret = bt_ctf_field_type_integer_set_base(uint32_bin_type,
+                                                BT_CTF_INTEGER_BASE_BINARY);
+       assert(!ret);
+
+       uint64_bin_type = bt_ctf_field_type_integer_create(64);
+       ret = bt_ctf_field_type_integer_set_base(uint64_bin_type,
+                                                BT_CTF_INTEGER_BASE_BINARY);
+       assert(!ret);
+
+       uint32_oct_type = bt_ctf_field_type_integer_create(32);
+       ret = bt_ctf_field_type_integer_set_base(uint32_oct_type,
+                                                BT_CTF_INTEGER_BASE_OCTAL);
+       assert(!ret);
+
+       uint64_oct_type = bt_ctf_field_type_integer_create(64);
+       ret = bt_ctf_field_type_integer_set_base(uint64_oct_type,
+                                                BT_CTF_INTEGER_BASE_OCTAL);
+       assert(!ret);
+
+       uint32_dec_type = bt_ctf_field_type_integer_create(32);
+       ret = bt_ctf_field_type_integer_set_base(uint32_dec_type,
+                                                BT_CTF_INTEGER_BASE_DECIMAL);
+       assert(!ret);
+
+       uint64_dec_type = bt_ctf_field_type_integer_create(64);
+       ret = bt_ctf_field_type_integer_set_base(uint64_dec_type,
+                                                BT_CTF_INTEGER_BASE_DECIMAL);
+       assert(!ret);
+
+       uint32_hex_type = bt_ctf_field_type_integer_create(32);
+       ret = bt_ctf_field_type_integer_set_base(uint32_hex_type,
+                       BT_CTF_INTEGER_BASE_HEXADECIMAL);
+       assert(!ret);
+
+       uint64_hex_type = bt_ctf_field_type_integer_create(64);
+       ret = bt_ctf_field_type_integer_set_base(uint64_hex_type,
+                       BT_CTF_INTEGER_BASE_HEXADECIMAL);
+       assert(!ret);
 }
 
 CTFLogVisitor::~CTFLogVisitor()
 {
-       // TODO
+       /* Free event classes */
+       map<const type_info *, struct bt_ctf_event_class *>::iterator it;
+       for (it = event_class_.begin(); it != event_class_.end(); ++it) {
+               bt_ctf_event_class_put(it->second);
+       }
+
+       /* Free types */
+       bt_ctf_field_type_put(uint32_bin_type);
+       bt_ctf_field_type_put(uint64_bin_type);
+
+       bt_ctf_field_type_put(uint32_oct_type);
+       bt_ctf_field_type_put(uint64_oct_type);
+
+       bt_ctf_field_type_put(uint32_dec_type);
+       bt_ctf_field_type_put(uint64_dec_type);
+
+       bt_ctf_field_type_put(uint32_hex_type);
+       bt_ctf_field_type_put(uint64_hex_type);
+
+       bt_ctf_field_type_put(string_type);
+
+       bt_ctf_clock_put(clock_);
+       bt_ctf_stream_class_put(stream_class_);
+       bt_ctf_stream_put(stream_);
+
+       /* Free writer */
+       bt_ctf_writer_put(writer_);
 }
 
-string CTFLogVisitor::asString() const
+struct bt_ctf_event_class* CTFLogVisitor::create_event_class(const NxMessage *m,
+               const string &name,
+               const CTFFields &fields)
+{
+       int ret = 0;
+       struct bt_ctf_event_class *event_class = NULL;
+
+       event_class = bt_ctf_event_class_create(name.c_str());
+       assert(event_class);
+
+       for (CTFFields::const_iterator it = fields.begin();
+            it != fields.end();
+            ++it) {
+               const char *name = (*it)->name().c_str();
+               struct bt_ctf_field_type *type  = (*it)->type();
+               assert(name);
+               assert(type);
+
+               ret = bt_ctf_event_class_add_field(event_class, type, name);
+               assert(!ret);
+       }
+
+       ret = bt_ctf_stream_class_add_event_class(stream_class_, event_class);
+       assert(!ret);
+
+       event_class_[&typeid(*m)] = event_class;
+
+       return event_class;
+}
+
+struct bt_ctf_event_class*
+CTFLogVisitor::get_event_class(const NxMessage *m) const
+{
+       struct bt_ctf_event_class *event_class = NULL;
+       map<const type_info *, struct bt_ctf_event_class *>::const_iterator it;
+
+       assert(m);
+
+       it = event_class_.find(&typeid(*m));
+
+       if (it != event_class_.end()) {
+               event_class = it->second;
+       }
+
+       return event_class;
+}
+
+
+void CTFLogVisitor::event_set_fields(struct bt_ctf_event *event,
+               const CTFFields &fields) const
+{
+       assert(event);
+
+       for (CTFFields::const_iterator it = fields.begin();
+            it != fields.end();
+            ++it) {
+               int ret = 0;
+               const char *name = (*it)->name().c_str();
+               bt_ctf_field *field = (*it)->field();
+               assert(name);
+               assert(field);
+
+               ret = bt_ctf_event_set_payload(event, name, field);
+               assert(!ret);
+       }
+}
+
+void CTFLogVisitor::append_nexus_message(NxMessage *m,
+               const string &event_name,
+               const CTFFields &fields)
 {
-       // TODO
-       ostringstream os;
+       int ret = 0;
+       struct bt_ctf_event_class *event_class = NULL;
+       struct bt_ctf_event *event = NULL;
+
+       assert(m);
+
+       event_class = get_event_class(m);
 
-       if (useful_visit_) {
-               os << "CTFLogVisitor::asString() == TODO";
-               os << endl;
-               os << "CTF trace path: " << trace_path_;
-               os << endl;
+       if (event_class == NULL) {
+               event_class = create_event_class(m, event_name, fields);
        }
 
-       return os.str();
+       event = bt_ctf_event_create(event_class);
+       assert(event);
+
+       event_set_fields(event, fields);
+
+       ret = bt_ctf_stream_append_event(stream_, event);
+       assert(!ret);
+
+       /*
+        * FIXME: There will only be one event per-packet
+        *        if we flush for each message.
+        */
+       ret = bt_ctf_stream_flush(stream_);
+       assert(!ret);
+
+       bt_ctf_event_put(event);
+}
+
+void CTFLogVisitor::visit(NxDefaultMessage *m)
+{
+       /*
+        * These messages are treated as "unknown" and their payload
+        * won't be decoded. No need to process them.
+        */
+       useful_visit_ = false;
+}
+
+void CTFLogVisitor::visit(NxDebugStatusMessage *m)
+{
+       /* Default Nexus Message fields */
+       CTFIntegerField tcode           ("TCODE",       m->tcode());
+       CTFStringField  tcode_desc      ("TCODE_DESC",  m->tcodeString());
+       CTFIntegerField src_id          ("SRC_ID",      m->sourceId());
+       CTFStringField  src_id_desc     ("SRC_ID_DESC", string(m->sourceIdString()));
+       CTFIntegerField timestamp       ("TIMESTAMP",   m->correctedTimestamp());
+
+       /* Nexus Debug Status fields */
+       CTFIntegerField status          ("STATUS",      m->status(),    BT_CTF_INTEGER_BASE_HEXADECIMAL);
+
+       CTFFields fields;
+
+       fields.push_back(&tcode);
+       fields.push_back(&tcode_desc);
+       fields.push_back(&src_id);
+       fields.push_back(&src_id_desc);
+       fields.push_back(&timestamp);
+       fields.push_back(&status);
+
+       append_nexus_message(m, "Nexus Debug Status Message", fields);
+       useful_visit_ = true;
+}
+
+void CTFLogVisitor::visit(NxDeviceIDMessage *m)
+{
+       /* Default Nexus Message fields */
+       CTFIntegerField tcode           ("TCODE",       m->tcode());
+       CTFStringField  tcode_desc      ("TCODE_DESC",  m->tcodeString());
+       CTFIntegerField src_id          ("SRC_ID",      m->sourceId());
+       CTFStringField  src_id_desc     ("SRC_ID_DESC", string(m->sourceIdString()));
+
+       /* TODO: Confirm that Nexus Device ID Message can't have timestamp */
+       /*CTFIntegerField       timestamp       ("TIMESTAMP",   m->correctedTimestamp());*/
+
+       CTFFields fields;
+
+       fields.push_back(&tcode);
+       fields.push_back(&tcode_desc);
+       fields.push_back(&src_id);
+       fields.push_back(&src_id_desc);
+       /*fields.push_back(&timestamp);*/
+
+       append_nexus_message(m, "Nexus Device ID Message", fields);
+       useful_visit_ = true;
+}
+
+void CTFLogVisitor::visit(NxOwnershipTraceMessage *m)
+{
+       /* Default Nexus Message fields */
+       CTFIntegerField tcode           ("TCODE",       m->tcode());
+       CTFStringField  tcode_desc      ("TCODE_DESC",  m->tcodeString());
+       CTFIntegerField src_id          ("SRC_ID",      m->sourceId());
+       CTFStringField  src_id_desc     ("SRC_ID_DESC", string(m->sourceIdString()));
+       CTFIntegerField timestamp       ("TIMESTAMP",   m->correctedTimestamp());
+
+       /* Nexus Ownership Trace Message fields */
+       CTFIntegerField pid_idx         ("PID_INDEX",           m->pidIndex(),  BT_CTF_INTEGER_BASE_HEXADECIMAL);
+       CTFStringField  pid_idx_desc    ("PID_INDEX_DESC",      string(m->pidIndexString()));
+       CTFIntegerField pid_val         ("PID_VALUE",           m->pidValue());
+       CTFStringField  pid_val_desc    ("PID_VALUE_DESC",      string(m->pidValueString()));
+
+       CTFFields fields;
+
+       fields.push_back(&tcode);
+       fields.push_back(&tcode_desc);
+       fields.push_back(&src_id);
+       fields.push_back(&src_id_desc);
+       fields.push_back(&timestamp);
+       fields.push_back(&pid_idx);
+       fields.push_back(&pid_idx_desc);
+       fields.push_back(&pid_val);
+       fields.push_back(&pid_val_desc);
+
+       append_nexus_message(m, "Nexus Ownership Trace Message", fields);
+       useful_visit_ = true;
+}
+
+void CTFLogVisitor::visit(NxDataAcquisitionMessage *m)
+{
+       /* Default Nexus Message fields */
+       CTFIntegerField tcode           ("TCODE",       m->tcode());
+       CTFStringField  tcode_desc      ("TCODE_DESC",  m->tcodeString());
+       CTFIntegerField src_id          ("SRC_ID",      m->sourceId());
+       CTFStringField  src_id_desc     ("SRC_ID_DESC", string(m->sourceIdString()));
+       CTFIntegerField timestamp       ("TIMESTAMP",   m->correctedTimestamp());
+
+       /* Nexus Data Acquisition Message fields */
+       CTFIntegerField id_tag          ("IDTAG",       m->idtag(),     BT_CTF_INTEGER_BASE_HEXADECIMAL);
+       CTFStringField  id_tag_desc     ("IDTAG_DESC",  string(m->idtagString()));
+       CTFIntegerField dq_data         ("DQDATA",      m->dqdata());
+       CTFStringField  dq_data_desc    ("DQDATA_DESC", string(m->dqdataString()));
+
+       CTFFields fields;
+
+       fields.push_back(&tcode);
+       fields.push_back(&tcode_desc);
+       fields.push_back(&src_id);
+       fields.push_back(&src_id_desc);
+       fields.push_back(&timestamp);
+       fields.push_back(&id_tag);
+       fields.push_back(&id_tag_desc);
+       fields.push_back(&dq_data);
+       fields.push_back(&dq_data_desc);
+
+       append_nexus_message(m, "Nexus Data Acquisition Message", fields);
+       useful_visit_ = true;
+}
+
+void CTFLogVisitor::visit(NxErrorMessage *m)
+{
+       /* Default Nexus Message fields */
+       CTFIntegerField tcode           ("TCODE",       m->tcode());
+       CTFStringField  tcode_desc      ("TCODE_DESC",  m->tcodeString());
+       CTFIntegerField src_id          ("SRC_ID",      m->sourceId());
+       CTFStringField  src_id_desc     ("SRC_ID_DESC", string(m->sourceIdString()));
+       CTFIntegerField timestamp       ("TIMESTAMP",   m->correctedTimestamp());
+
+       /* Nexus Error Message fields */
+       CTFIntegerField etype           ("ETYPE",       m->etype(),     BT_CTF_INTEGER_BASE_HEXADECIMAL);
+       CTFStringField  etype_desc      ("ETYPE_DESC",  string(m->etypeString()));
+       CTFIntegerField ecode           ("ECODE",       m->ecode(),     BT_CTF_INTEGER_BASE_HEXADECIMAL);
+       CTFStringField  ecode_desc      ("ECODE_DESC",  string(m->ecodeString()));
+
+       CTFFields fields;
+
+       fields.push_back(&tcode);
+       fields.push_back(&tcode_desc);
+       fields.push_back(&src_id);
+       fields.push_back(&src_id_desc);
+       fields.push_back(&timestamp);
+       fields.push_back(&etype);
+       fields.push_back(&etype_desc);
+       fields.push_back(&ecode);
+       fields.push_back(&ecode_desc);
+
+       append_nexus_message(m, "Nexus Error Message", fields);
+       useful_visit_ = true;
+}
+
+void CTFLogVisitor::visit(NxProgramTraceSync *m)
+{
+       /* Default Nexus Message fields */
+       CTFIntegerField tcode           ("TCODE",       m->tcode());
+       CTFStringField  tcode_desc      ("TCODE_DESC",  m->tcodeString());
+       CTFIntegerField src_id          ("SRC_ID",      m->sourceId());
+       CTFStringField  src_id_desc     ("SRC_ID_DESC", string(m->sourceIdString()));
+       CTFIntegerField timestamp       ("TIMESTAMP",   m->correctedTimestamp());
+
+       /* Nexus Program Trace Sync fields */
+       CTFIntegerField map             ("MAP",         m->map(),       BT_CTF_INTEGER_BASE_HEXADECIMAL);
+       CTFIntegerField icnt            ("ICNT",        m->icnt());
+       CTFIntegerField hist            ("HIST",        m->hist(),      BT_CTF_INTEGER_BASE_HEXADECIMAL);
+       CTFIntegerField pc64            ("PC",          m->address().address64(), BT_CTF_INTEGER_BASE_HEXADECIMAL);
+       CTFIntegerField pc32            ("PC",          m->address().address32(), BT_CTF_INTEGER_BASE_HEXADECIMAL);
+
+       CTFFields fields;
+
+       fields.push_back(&tcode);
+       fields.push_back(&tcode_desc);
+       fields.push_back(&src_id);
+       fields.push_back(&src_id_desc);
+       fields.push_back(&timestamp);
+       fields.push_back(&map);
+       fields.push_back(&icnt);
+       fields.push_back(&hist);
+
+       /*
+        * TODO: Is it possible for pc to change bitness between messages?
+        *       If so, we should probably add both fields to the trace.
+        */
+       if (m->address().is64bits()) {
+               fields.push_back(&pc64);
+       } else {
+               fields.push_back(&pc32);
+       }
+
+       append_nexus_message(m, "Nexus Program Trace Sync Message", fields);
+       useful_visit_ = true;
+}
+
+void CTFLogVisitor::visit(NxDataTraceWrite *m)
+{
+       /* Default Nexus Message fields */
+       CTFIntegerField tcode           ("TCODE",       m->tcode());
+       CTFStringField  tcode_desc      ("TCODE_DESC",  m->tcodeString());
+       CTFIntegerField src_id          ("SRC_ID",      m->sourceId());
+       CTFStringField  src_id_desc     ("SRC_ID_DESC", string(m->sourceIdString()));
+       CTFIntegerField timestamp       ("TIMESTAMP",   m->correctedTimestamp());
+
+       /* Nexus Data Trace Write fields */
+       CTFIntegerField dsz             ("DSZ",         m->dsz(), BT_CTF_INTEGER_BASE_HEXADECIMAL);
+       CTFStringField  dsz_desc        ("DSZ_DESC",    string(m->dszString()));
+       CTFIntegerField addr            ("UADDR",       m->addr(), BT_CTF_INTEGER_BASE_HEXADECIMAL);
+       CTFIntegerField data            ("DATA",        m->data(), BT_CTF_INTEGER_BASE_HEXADECIMAL);
+
+       CTFFields fields;
+
+       fields.push_back(&tcode);
+       fields.push_back(&tcode_desc);
+       fields.push_back(&src_id);
+       fields.push_back(&src_id_desc);
+       fields.push_back(&timestamp);
+       fields.push_back(&dsz);
+       fields.push_back(&dsz_desc);
+       fields.push_back(&addr);
+       fields.push_back(&data);
+
+       append_nexus_message(m, "Nexus Data Trace Write Message", fields);
+       useful_visit_ = true;
+}
+
+void CTFLogVisitor::visit(NxDataTraceRead *m)
+{
+       /* Default Nexus Message fields */
+       CTFIntegerField tcode           ("TCODE",       m->tcode());
+       CTFStringField  tcode_desc      ("TCODE_DESC",  m->tcodeString());
+       CTFIntegerField src_id          ("SRC_ID",      m->sourceId());
+       CTFStringField  src_id_desc     ("SRC_ID_DESC", string(m->sourceIdString()));
+       CTFIntegerField timestamp       ("TIMESTAMP",   m->correctedTimestamp());
+
+       /* Nexus Data Trace Read fields */
+       CTFIntegerField dsz             ("DSZ",         m->dsz(), BT_CTF_INTEGER_BASE_HEXADECIMAL);
+       CTFStringField  dsz_desc        ("DSZ_DESC",    string(m->dszString()));
+       CTFIntegerField addr            ("UADDR",       m->addr(), BT_CTF_INTEGER_BASE_HEXADECIMAL);
+       CTFIntegerField data            ("DATA",        m->data(), BT_CTF_INTEGER_BASE_HEXADECIMAL);
+
+       CTFFields fields;
+
+       fields.push_back(&tcode);
+       fields.push_back(&tcode_desc);
+       fields.push_back(&src_id);
+       fields.push_back(&src_id_desc);
+       fields.push_back(&timestamp);
+       fields.push_back(&dsz);
+       fields.push_back(&dsz_desc);
+       fields.push_back(&addr);
+       fields.push_back(&data);
+
+       append_nexus_message(m, "Nexus Data Trace Read Message", fields);
+       useful_visit_ = true;
+}
+
+void CTFLogVisitor::visit(NxDataTraceWriteSync *m)
+{
+       /* Default Nexus Message fields */
+       CTFIntegerField tcode           ("TCODE",       m->tcode());
+       CTFStringField  tcode_desc      ("TCODE_DESC",  m->tcodeString());
+       CTFIntegerField src_id          ("SRC_ID",      m->sourceId());
+       CTFStringField  src_id_desc     ("SRC_ID_DESC", string(m->sourceIdString()));
+       CTFIntegerField timestamp       ("TIMESTAMP",   m->correctedTimestamp());
+
+       /* Nexus Data Trace Write Sync fields */
+       CTFIntegerField dsz             ("DSZ",         m->dsz(),       BT_CTF_INTEGER_BASE_HEXADECIMAL);
+       CTFStringField  dsz_desc        ("DSZ_DESC",    string(m->dszString()));
+       CTFIntegerField addr            ("FADDR",       m->addr(),      BT_CTF_INTEGER_BASE_HEXADECIMAL);
+       CTFIntegerField data            ("DATA",        m->data(),      BT_CTF_INTEGER_BASE_HEXADECIMAL);
+
+       CTFFields fields;
+
+       fields.push_back(&tcode);
+       fields.push_back(&tcode_desc);
+       fields.push_back(&src_id);
+       fields.push_back(&src_id_desc);
+       fields.push_back(&timestamp);
+       fields.push_back(&dsz);
+       fields.push_back(&dsz_desc);
+       fields.push_back(&addr);
+       fields.push_back(&data);
+
+       append_nexus_message(m, "Nexus Data Trace Write Sync Message", fields);
+       useful_visit_ = true;
+}
+
+void CTFLogVisitor::visit(NxDataTraceReadSync *m)
+{
+       /* Default Nexus Message fields */
+       CTFIntegerField tcode           ("TCODE",       m->tcode());
+       CTFStringField  tcode_desc      ("TCODE_DESC",  m->tcodeString());
+       CTFIntegerField src_id          ("SRC_ID",      m->sourceId());
+       CTFStringField  src_id_desc     ("SRC_ID_DESC", string(m->sourceIdString()));
+       CTFIntegerField timestamp       ("TIMESTAMP",   m->correctedTimestamp());
+
+       /* Nexus Data Trace Read Sync fields */
+       CTFIntegerField dsz             ("DSZ",         m->dsz(),       BT_CTF_INTEGER_BASE_HEXADECIMAL);
+       CTFStringField  dsz_desc        ("DSZ_DESC",    string(m->dszString()));
+       CTFIntegerField addr            ("FADDR",       m->addr(),      BT_CTF_INTEGER_BASE_HEXADECIMAL);
+       CTFIntegerField data            ("DATA",        m->data(),      BT_CTF_INTEGER_BASE_HEXADECIMAL);
+
+       CTFFields fields;
+
+       fields.push_back(&tcode);
+       fields.push_back(&tcode_desc);
+       fields.push_back(&src_id);
+       fields.push_back(&src_id_desc);
+       fields.push_back(&timestamp);
+       fields.push_back(&dsz);
+       fields.push_back(&dsz_desc);
+       fields.push_back(&addr);
+       fields.push_back(&data);
+
+       append_nexus_message(m, "Nexus Data Trace Read Sync Message", fields);
+       useful_visit_ = true;
+}
+
+void CTFLogVisitor::visit(NxWatchpointMessage *m)
+{
+       /* Default Nexus Message fields */
+       CTFIntegerField tcode           ("TCODE",       m->tcode());
+       CTFStringField  tcode_desc      ("TCODE_DESC",  m->tcodeString());
+       CTFIntegerField src_id          ("SRC_ID",      m->sourceId());
+       CTFStringField  src_id_desc     ("SRC_ID_DESC", string(m->sourceIdString()));
+       CTFIntegerField timestamp       ("TIMESTAMP",   m->correctedTimestamp());
+
+       /* Nexus Watchpoint fields */
+       CTFIntegerField wphit           ("WPHIT",       m->wphit(),             BT_CTF_INTEGER_BASE_HEXADECIMAL);
+       CTFStringField  wphit_desc      ("WPHIT_DESC",  m->wphitString());
+       CTFIntegerField wphit_size      ("WPHIT_SIZE",  m->wphit_size(),        BT_CTF_INTEGER_BASE_HEXADECIMAL);
+
+       CTFFields fields;
+
+       fields.push_back(&tcode);
+       fields.push_back(&tcode_desc);
+       fields.push_back(&src_id);
+       fields.push_back(&src_id_desc);
+       fields.push_back(&timestamp);
+       fields.push_back(&wphit);
+       fields.push_back(&wphit_desc);
+       fields.push_back(&wphit_size);
+
+       append_nexus_message(m, "Nexus Watchpoint Message", fields);
+       useful_visit_ = true;
+}
+
+void CTFLogVisitor::visit(NxResourceFullMessage *m)
+{
+       /* Default Nexus Message fields */
+       CTFIntegerField tcode           ("TCODE",       m->tcode());
+       CTFStringField  tcode_desc      ("TCODE_DESC",  m->tcodeString());
+       CTFIntegerField src_id          ("SRC_ID",      m->sourceId());
+       CTFStringField  src_id_desc     ("SRC_ID_DESC", string(m->sourceIdString()));
+       CTFIntegerField timestamp       ("TIMESTAMP",   m->correctedTimestamp());
+
+       /* Nexus Ressource Full fields */
+       CTFIntegerField rcode           ("RCODE",       m->rcode(),     BT_CTF_INTEGER_BASE_HEXADECIMAL);
+       CTFStringField  rcode_desc      ("RCODE_DESC",  string(m->rcodeString()));
+       CTFIntegerField rdata           ("RDATA",       m->rdata(),     BT_CTF_INTEGER_BASE_HEXADECIMAL);
+
+       CTFFields fields;
+
+       fields.push_back(&tcode);
+       fields.push_back(&tcode_desc);
+       fields.push_back(&src_id);
+       fields.push_back(&src_id_desc);
+       fields.push_back(&timestamp);
+       fields.push_back(&rcode);
+       fields.push_back(&rcode_desc);
+       fields.push_back(&rdata);
+
+       append_nexus_message(m, "Nexus Ressource Full Message", fields);
+       useful_visit_ = true;
+}
+
+void CTFLogVisitor::visit(NxProgramTraceIndirectBranch *m)
+{
+       /* Default Nexus Message fields */
+       CTFIntegerField tcode           ("TCODE",       m->tcode());
+       CTFStringField  tcode_desc      ("TCODE_DESC",  m->tcodeString());
+       CTFIntegerField src_id          ("SRC_ID",      m->sourceId());
+       CTFStringField  src_id_desc     ("SRC_ID_DESC", string(m->sourceIdString()));
+       CTFIntegerField timestamp       ("TIMESTAMP",   m->correctedTimestamp());
+
+       /* Nexus Program Trace Indirect Branch fields */
+       CTFIntegerField btype           ("BTYPE",       m->btype(),                     BT_CTF_INTEGER_BASE_HEXADECIMAL);
+       CTFStringField  btype_desc      ("BTYPE_DESC",  m->btypeString());
+       CTFIntegerField icnt            ("ICNT",        m->icnt());
+       CTFIntegerField hist            ("HIST",        m->hist(),                      BT_CTF_INTEGER_BASE_HEXADECIMAL);
+       CTFIntegerField uaddr64         ("UADDR",       m->address().address64(),       BT_CTF_INTEGER_BASE_HEXADECIMAL);
+       CTFIntegerField uaddr32         ("UADDR",       m->address().address32(),       BT_CTF_INTEGER_BASE_HEXADECIMAL);
+
+       CTFFields fields;
+
+       fields.push_back(&tcode);
+       fields.push_back(&tcode_desc);
+       fields.push_back(&src_id);
+       fields.push_back(&src_id_desc);
+       fields.push_back(&timestamp);
+       fields.push_back(&btype);
+       fields.push_back(&btype_desc);
+       fields.push_back(&icnt);
+       fields.push_back(&hist);
+
+       /*
+        * TODO: Is it possible for uaddr to change bitness between messages?
+        *       If so, we should probably add both fields to the trace.
+        */
+       if (m->address().is64bits()) {
+               fields.push_back(&uaddr64);
+       } else {
+               fields.push_back(&uaddr32);
+       }
+
+       append_nexus_message(m, "Nexus Program Trace Indirect Branch Message", fields);
+       useful_visit_ = true;
+}
+
+void CTFLogVisitor::visit(NxProgramTraceIndirectBranchSync *m)
+{
+       /* Default Nexus Message fields */
+       CTFIntegerField tcode           ("TCODE",       m->tcode());
+       CTFStringField  tcode_desc      ("TCODE_DESC",  m->tcodeString());
+       CTFIntegerField src_id          ("SRC_ID",      m->sourceId());
+       CTFStringField  src_id_desc     ("SRC_ID_DESC", string(m->sourceIdString()));
+       CTFIntegerField timestamp       ("TIMESTAMP",   m->correctedTimestamp());
+
+       /* Nexus Program Trace Indirect Branch Sync fields */
+       CTFIntegerField btype           ("BTYPE",       m->btype(),     BT_CTF_INTEGER_BASE_HEXADECIMAL);
+       CTFStringField  btype_desc      ("BTYPE_DESC",  m->btypeString());
+       CTFIntegerField icnt            ("ICNT",        m->icnt());
+       CTFIntegerField hist            ("HIST",        m->hist(),      BT_CTF_INTEGER_BASE_HEXADECIMAL);
+       CTFIntegerField faddr64         ("FADDR",       m->address().address64(),       BT_CTF_INTEGER_BASE_HEXADECIMAL);
+       CTFIntegerField faddr32         ("FADDR",       m->address().address32(),       BT_CTF_INTEGER_BASE_HEXADECIMAL);
+
+       CTFFields fields;
+
+       fields.push_back(&tcode);
+       fields.push_back(&tcode_desc);
+       fields.push_back(&src_id);
+       fields.push_back(&src_id_desc);
+       fields.push_back(&timestamp);
+       fields.push_back(&btype);
+       fields.push_back(&btype_desc);
+       fields.push_back(&icnt);
+       fields.push_back(&hist);
+
+       /*
+        * TODO: Is it possible for faddr to change bitness between messages?
+        *       If so, we should probably add both fields to the trace.
+        */
+       if (m->address().is64bits()) {
+               fields.push_back(&faddr64);
+       } else {
+               fields.push_back(&faddr32);
+       }
+
+       append_nexus_message(m, "Nexus Program Trace Indirect Branch Sync Message", fields);
+       useful_visit_ = true;
+}
+
+void CTFLogVisitor::visit(NxProgramTraceCorrelation *m)
+{
+       /* Default Nexus Message fields */
+       CTFIntegerField tcode           ("TCODE",       m->tcode());
+       CTFStringField  tcode_desc      ("TCODE_DESC",  m->tcodeString());
+       CTFIntegerField src_id          ("SRC_ID",      m->sourceId());
+       CTFStringField  src_id_desc     ("SRC_ID_DESC", string(m->sourceIdString()));
+       CTFIntegerField timestamp       ("TIMESTAMP",   m->correctedTimestamp());
+
+       /* Nexus Program Trace Correlation fields */
+       CTFIntegerField evcode          ("EVCODE",      m->evcode(),    BT_CTF_INTEGER_BASE_HEXADECIMAL);
+       CTFStringField  evcode_desc     ("EVCODE_DESC", m->evcodeString());
+       CTFIntegerField icnt            ("ICNT",        m->icnt());
+       CTFIntegerField cdata           ("CDATA",       m->cdata(),     BT_CTF_INTEGER_BASE_HEXADECIMAL);
+
+       CTFFields fields;
+
+       fields.push_back(&tcode);
+       fields.push_back(&tcode_desc);
+       fields.push_back(&src_id);
+       fields.push_back(&src_id_desc);
+       fields.push_back(&timestamp);
+       fields.push_back(&evcode);
+       fields.push_back(&evcode_desc);
+       fields.push_back(&icnt);
+       fields.push_back(&cdata);
+
+       append_nexus_message(m, "Nexus Program Trace Correlation Message", fields);
+       useful_visit_ = true;
+}
+
+void CTFLogVisitor::visit(NxDAMInCircuitTraceMessage *m)
+{
+       /* Default Nexus Message fields */
+       CTFIntegerField tcode           ("TCODE",       m->tcode());
+       CTFStringField  tcode_desc      ("TCODE_DESC",  m->tcodeString());
+       CTFIntegerField src_id          ("SRC_ID",      m->sourceId());
+       CTFStringField  src_id_desc     ("SRC_ID_DESC", string(m->sourceIdString()));
+       CTFIntegerField timestamp       ("TIMESTAMP",   m->correctedTimestamp());
+
+       /* Nexus DAM In-Circuit Trace fields */
+       CTFStringField  ict_msg_type    ("ICT_MSG_TYPE",        string(m->ICTMessageType()));
+       CTFIntegerField ddrmid          ("DDRMID",              m->ddrmid());
+       CTFIntegerField ddrsid          ("DDRSID",              m->ddrsid());
+       CTFIntegerField ddrtt           ("DDRTT",               m->ddrtt());
+       CTFStringField  ddrtt_desc      ("DDRTT_DESC",          string(m->ddrttString()));
+       CTFIntegerField ddrsz           ("DDRSZ",               m->ddrsz());
+       CTFIntegerField faddr           ("FADDR",               (m->isSyncMessage() ? m->ddraddr() : 0),        BT_CTF_INTEGER_BASE_HEXADECIMAL);
+       CTFIntegerField uaddr           ("UADDR",               (m->isSyncMessage() ? 0 : m->ddraddr()),        BT_CTF_INTEGER_BASE_HEXADECIMAL);
+       CTFIntegerField dddiec          ("DDDIEC",              m->dddiec());
+
+       CTFFields fields;
+
+       fields.push_back(&tcode);
+       fields.push_back(&tcode_desc);
+       fields.push_back(&src_id);
+       fields.push_back(&src_id_desc);
+       fields.push_back(&timestamp);
+       fields.push_back(&ict_msg_type);
+       fields.push_back(&ddrmid);
+       fields.push_back(&ddrsid);
+       fields.push_back(&ddrtt);
+       fields.push_back(&ddrtt_desc);
+       fields.push_back(&ddrsz);
+       fields.push_back(&faddr);
+       fields.push_back(&uaddr);
+       fields.push_back(&dddiec);
+
+       append_nexus_message(m, "Nexus DAM In-Circuit Trace Message", fields);
+       useful_visit_ = true;
+}
+
+void CTFLogVisitor::visit(NxCAMInCircuitTraceMessage *m)
+{
+       useful_visit_ = false;
+}
+
+void CTFLogVisitor::visit(NxCDMInCircuitTraceMessage *m)
+{
+       useful_visit_ = false;
+}
+
+void CTFLogVisitor::visit(NxDPQMInCircuitTraceMessage *m)
+{
+       /* Default Nexus Message fields */
+       CTFIntegerField tcode           ("TCODE",       m->tcode());
+       CTFStringField  tcode_desc      ("TCODE_DESC",  m->tcodeString());
+       CTFIntegerField src_id          ("SRC_ID",      m->sourceId());
+       CTFStringField  src_id_desc     ("SRC_ID_DESC", string(m->sourceIdString()));
+       CTFIntegerField timestamp       ("TIMESTAMP",   m->correctedTimestamp());
+
+       /* Nexus DPQM In-Circuit Trace fields */
+       CTFStringField  ict_msg_type    ("ICT_MSG_TYPE",        string(m->ICTMessageType()));
+       CTFIntegerField dpdm            ("DBG_MARK",            m->dpdm());
+       CTFIntegerField fqid            ("FQ_ID",               m->fqid(),      BT_CTF_INTEGER_BASE_HEXADECIMAL);
+       CTFIntegerField cnum            ("CH_NUM",              m->cnum(),      BT_CTF_INTEGER_BASE_HEXADECIMAL);
+       CTFIntegerField pnum            ("PORT_NUM",            m->pnum());
+       CTFIntegerField ptype           ("PORT_TYPE",           m->ptype());
+       CTFStringField  ptype_desc      ("PORT_TYPE_DESC",      (m->ptype() ? "Direct Connect" : "Software"));
+       CTFIntegerField qet             ("QEVNT_TYPE",          m->qet());
+       CTFStringField  qet_desc        ("QEVNT_TYPE_DESC",     string(m->queueEventTypeString()));
+       CTFIntegerField orf             ("ORD_REST",            m->orf());
+       /* TODO: Does the erf field indicate enqueue operation rejection? */
+       CTFIntegerField erf             ("ENQ_REJCT",           m->erf());
+       CTFIntegerField err             ("ENQ_RESP",            m->err(),       BT_CTF_INTEGER_BASE_HEXADECIMAL);
+       CTFStringField  err_desc        ("ENQ_RESP_DESC",       m->enqueueRejectionString());
+       CTFIntegerField verb            ("VERBOSE",             m->verb());
+       CTFIntegerField fmbpid          ("FRM_BP_ID",           m->fmbpid(),    BT_CTF_INTEGER_BASE_HEXADECIMAL);
+       CTFIntegerField fmsc            ("FRM_STAT",            m->fmsc(),      BT_CTF_INTEGER_BASE_HEXADECIMAL);
+       CTFIntegerField fmol            ("FRM_OFFSET",          m->fmol(),      BT_CTF_INTEGER_BASE_HEXADECIMAL);
+       CTFIntegerField fmfmt           ("FRM_FMT",             m->fmfmt(),     BT_CTF_INTEGER_BASE_HEXADECIMAL);
+       CTFIntegerField fmpid           ("FRM_PRT_ID",          m->fmpid(),     BT_CTF_INTEGER_BASE_HEXADECIMAL);
+       CTFIntegerField fmaddr          ("FRM_ADDR",            m->fmaddr(),    BT_CTF_INTEGER_BASE_HEXADECIMAL);
+
+       CTFFields fields;
+
+       fields.push_back(&tcode);
+       fields.push_back(&tcode_desc);
+       fields.push_back(&src_id);
+       fields.push_back(&src_id_desc);
+       fields.push_back(&timestamp);
+       fields.push_back(&ict_msg_type);
+       fields.push_back(&dpdm);
+       fields.push_back(&fqid);
+       fields.push_back(&cnum);
+       fields.push_back(&pnum);
+       fields.push_back(&ptype);
+       fields.push_back(&ptype_desc);
+       fields.push_back(&qet);
+       fields.push_back(&qet_desc);
+       fields.push_back(&orf);
+       fields.push_back(&erf);
+       fields.push_back(&err);
+       fields.push_back(&err_desc);
+       fields.push_back(&verb);
+       fields.push_back(&fmbpid);
+       fields.push_back(&fmsc);
+       fields.push_back(&fmol);
+       fields.push_back(&fmfmt);
+       fields.push_back(&fmpid);
+       fields.push_back(&fmaddr);
+
+       append_nexus_message(m, "Nexus DPQM In-Circuit Trace Message", fields);
+       useful_visit_ = true;
+}
+
+void CTFLogVisitor::visit(NxCoreInCircuitTraceMessage *m)
+{
+       /* Default Nexus Message fields */
+       CTFIntegerField tcode           ("TCODE",       m->tcode());
+       CTFStringField  tcode_desc      ("TCODE_DESC",  m->tcodeString());
+       CTFIntegerField src_id          ("SRC_ID",      m->sourceId());
+       CTFStringField  src_id_desc     ("SRC_ID_DESC", string(m->sourceIdString()));
+       CTFIntegerField timestamp       ("TIMESTAMP",   m->correctedTimestamp());
+
+       /* Nexus Core In-Circuit Trace fields */
+       CTFStringField  ict_msg_type    ("ICT_MSG_TYPE",        string(m->ICTMessageType()));
+       CTFIntegerField cksrc           ("CKSRC",               m->cksrc());
+       CTFStringField  cksrc_desc      ("CKSRC_DESC",          string(m->cksrcString()));
+       CTFIntegerField sync            ("SYNC",                m->sync());
+       CTFStringField  sync_desc       ("SYNC_DESC",           string(m->syncString()));
+       CTFIntegerField ckdf            ("CKDF",                m->ckdf());
+       CTFIntegerField ckdata1         ("CKDATA1",             m->ckdata1(),   BT_CTF_INTEGER_BASE_HEXADECIMAL);
+       CTFIntegerField ckdata2         ("CKDATA2",             m->ckdata2(),   BT_CTF_INTEGER_BASE_HEXADECIMAL);
+
+       CTFFields fields;
+
+       fields.push_back(&tcode);
+       fields.push_back(&tcode_desc);
+       fields.push_back(&src_id);
+       fields.push_back(&src_id_desc);
+       fields.push_back(&timestamp);
+       fields.push_back(&ict_msg_type);
+       fields.push_back(&cksrc);
+       fields.push_back(&cksrc_desc);
+       fields.push_back(&sync);
+       fields.push_back(&sync_desc);
+       fields.push_back(&ckdf);
+       fields.push_back(&ckdata1);
+       fields.push_back(&ckdata2);
+
+       append_nexus_message(m, "Nexus Core In-Circuit Trace Message", fields);
+       useful_visit_ = true;
+}
+
+void CTFLogVisitor::visit(NxInCircuitTraceMessage *m)
+{
+       /* Default Nexus Message fields */
+       CTFIntegerField tcode           ("TCODE",       m->tcode());
+       CTFStringField  tcode_desc      ("TCODE_DESC",  m->tcodeString());
+       CTFIntegerField src_id          ("SRC_ID",      m->sourceId());
+       CTFStringField  src_id_desc     ("SRC_ID_DESC", string(m->sourceIdString()));
+       CTFIntegerField timestamp       ("TIMESTAMP",   m->correctedTimestamp());
+
+       /* Nexus In-Circuit Trace fields */
+       CTFStringField  ict_msg_type    ("ICT_MSG_TYPE",        string(m->ICTMessageType()));
+
+       CTFFields fields;
+
+       fields.push_back(&tcode);
+       fields.push_back(&tcode_desc);
+       fields.push_back(&src_id);
+       fields.push_back(&src_id_desc);
+       fields.push_back(&timestamp);
+       fields.push_back(&ict_msg_type);
+
+       append_nexus_message(m, "Nexus In-Circuit Trace Message", fields);
+       useful_visit_ = true;
+}
+
+void CTFLogVisitor::visit(NxTimeStampCorrelation *m)
+{
+       /* Default Nexus Message fields */
+       CTFIntegerField tcode           ("TCODE",       m->tcode());
+       CTFStringField  tcode_desc      ("TCODE_DESC",  m->tcodeString());
+       CTFIntegerField src_id          ("SRC_ID",      m->sourceId());
+       CTFStringField  src_id_desc     ("SRC_ID_DESC", string(m->sourceIdString()));
+       CTFIntegerField timestamp       ("TIMESTAMP",   m->correctedTimestamp());
+
+       /* Nexus Timestamp Correlation fields */
+       CTFIntegerField tcorr           ("TCORR",       m->tcorr(),     BT_CTF_INTEGER_BASE_HEXADECIMAL);
+       CTFIntegerField ttype           ("TTYPE",       m->ttype(),     BT_CTF_INTEGER_BASE_HEXADECIMAL);
+       CTFStringField  ttype_desc      ("TTYPE_DESC",  string(m->ttypeString()));
+
+       CTFFields fields;
+
+       fields.push_back(&tcode);
+       fields.push_back(&tcode_desc);
+       fields.push_back(&src_id);
+       fields.push_back(&src_id_desc);
+       fields.push_back(&timestamp);
+       fields.push_back(&tcorr);
+       fields.push_back(&ttype);
+       fields.push_back(&ttype_desc);
+
+       append_nexus_message(m, "Nexus Timestamp Correlation Message", fields);
+       useful_visit_ = true;
+}
+
+void CTFLogVisitor::visit(NxDPFMInCircuitTraceMessage *m)
+{
+       /* Default Nexus Message fields */
+       CTFIntegerField tcode           ("TCODE",       m->tcode());
+       CTFStringField  tcode_desc      ("TCODE_DESC",  m->tcodeString());
+       CTFIntegerField src_id          ("SRC_ID",      m->sourceId());
+       CTFStringField  src_id_desc     ("SRC_ID_DESC", string(m->sourceIdString()));
+       CTFIntegerField timestamp       ("TIMESTAMP",   m->correctedTimestamp());
+
+       /* Nexus DPFM In-Circuit Trace fields */
+       CTFStringField  ict_msg_type    ("ICT_MSG_TYPE",        string(m->ICTMessageType()));
+       CTFIntegerField fmsel           ("FMAN_SEL",            m->getFmsel());
+       CTFIntegerField lbeat           ("LAST_BEAT",           m->getLbeat());
+       CTFIntegerField btcnt           ("BEAT_CNT",            m->getBtcnt());
+
+       /* TODO: Handle context data as CTF array */
+       /*CTFIntegerField       context         ("CONTEXT",             m->tcode());*/
+
+       CTFFields fields;
+
+       fields.push_back(&tcode);
+       fields.push_back(&tcode_desc);
+       fields.push_back(&src_id);
+       fields.push_back(&src_id_desc);
+       fields.push_back(&timestamp);
+       fields.push_back(&ict_msg_type);
+       fields.push_back(&fmsel);
+       fields.push_back(&lbeat);
+       fields.push_back(&btcnt);
+
+       append_nexus_message(m, "Nexus DPFM In-Circuit Trace Message", fields);
+       useful_visit_ = true;
+}
+
+string CTFLogVisitor::asString() const
+{
+       return "";
 }
index fa06e0683c33c92d187541bfb833920b815b09dd..1711bab4cb66d52bcd16dc6f7738650aec754ed7 100644 (file)
 #ifndef CTFLOGVISITOR_H
 #define CTFLOGVISITOR_H
 
+#include <vector>
 #include <string>
+#include <map>
+#include <typeinfo>
+#include <babeltrace/ctf-writer/writer.h>
+#include <babeltrace/ctf-writer/clock.h>
+#include <babeltrace/ctf-writer/stream.h>
+#include <babeltrace/ctf-writer/event.h>
+#include <babeltrace/ctf-writer/event-types.h>
+#include <babeltrace/ctf-writer/event-fields.h>
 #include "NxMessageVisitor.h"
 
+using std::vector;
 using std::string;
+using std::map;
+using std::type_info;
 
+class NxMessage;
 class NxDefaultMessage;
 class NxDebugStatusMessage;
 class NxDeviceIDMessage;
@@ -53,7 +66,7 @@ class NxCoreInCircuitTraceMessage;
 class NxInCircuitTraceMessage;
 class NxTimeStampCorrelation;
 
-// Convert each Nexus message an equivalent Common Trace Format (CTF) event
+/* Convert each Nexus message an equivalent Common Trace Format (CTF) event */
 class CTFLogVisitor: public NxMessageVisitor
 {
 public:
@@ -61,35 +74,112 @@ public:
        CTFLogVisitor(const string& trace_path);
        virtual ~CTFLogVisitor();
 
-       virtual void visit(NxDefaultMessage *m){useful_visit_ = false;}
-       virtual void visit(NxDebugStatusMessage *m){useful_visit_ = false;}
-       virtual void visit(NxDeviceIDMessage *m){useful_visit_ = false;}
-       virtual void visit(NxOwnershipTraceMessage *m){useful_visit_ = false;}
-       virtual void visit(NxDataAcquisitionMessage *m){useful_visit_ = false;}
-       virtual void visit(NxErrorMessage *m){useful_visit_ = false;}
-       virtual void visit(NxProgramTraceSync *m){useful_visit_ = false;}
-       virtual void visit(NxDataTraceWrite *m){useful_visit_ = false;}
-       virtual void visit(NxDataTraceRead *m){useful_visit_ = false;}
-       virtual void visit(NxDataTraceWriteSync *m){useful_visit_ = false;}
-       virtual void visit(NxDataTraceReadSync *m){useful_visit_ = false;}
-       virtual void visit(NxWatchpointMessage *m){useful_visit_ = false;}
-       virtual void visit(NxResourceFullMessage *m){useful_visit_ = false;}
-       virtual void visit(NxProgramTraceIndirectBranch *m){useful_visit_ = false;}
-       virtual void visit(NxProgramTraceIndirectBranchSync *m){useful_visit_ = false;}
-       virtual void visit(NxProgramTraceCorrelation *m){useful_visit_ = false;}
-       virtual void visit(NxDAMInCircuitTraceMessage *m){useful_visit_ = false;}
-       virtual void visit(NxCAMInCircuitTraceMessage *m){useful_visit_ = false;}
-       virtual void visit(NxCDMInCircuitTraceMessage *m){useful_visit_ = false;}
-       virtual void visit(NxDPQMInCircuitTraceMessage *m){useful_visit_ = false;}
-       virtual void visit(NxCoreInCircuitTraceMessage *m){useful_visit_ = false;}
-       virtual void visit(NxInCircuitTraceMessage *m){useful_visit_ = false;}
-       virtual void visit(NxTimeStampCorrelation *m){useful_visit_ = false;}
-       virtual void visit(NxDPFMInCircuitTraceMessage *m){useful_visit_ = false;}
+       virtual void visit(NxDefaultMessage *m);
+       virtual void visit(NxDebugStatusMessage *m);
+       virtual void visit(NxDeviceIDMessage *m);
+       virtual void visit(NxOwnershipTraceMessage *m);
+       virtual void visit(NxDataAcquisitionMessage *m);
+       virtual void visit(NxErrorMessage *m);
+       virtual void visit(NxProgramTraceSync *m);
+       virtual void visit(NxDataTraceWrite *m);
+       virtual void visit(NxDataTraceRead *m);
+       virtual void visit(NxDataTraceWriteSync *m);
+       virtual void visit(NxDataTraceReadSync *m);
+       virtual void visit(NxWatchpointMessage *m);
+       virtual void visit(NxResourceFullMessage *m);
+       virtual void visit(NxProgramTraceIndirectBranch *m);
+       virtual void visit(NxProgramTraceIndirectBranchSync *m);
+       virtual void visit(NxProgramTraceCorrelation *m);
+       virtual void visit(NxDAMInCircuitTraceMessage *m);
+       virtual void visit(NxCAMInCircuitTraceMessage *m);
+       virtual void visit(NxCDMInCircuitTraceMessage *m);
+       virtual void visit(NxDPQMInCircuitTraceMessage *m);
+       virtual void visit(NxCoreInCircuitTraceMessage *m);
+       virtual void visit(NxInCircuitTraceMessage *m);
+       virtual void visit(NxTimeStampCorrelation *m);
+       virtual void visit(NxDPFMInCircuitTraceMessage *m);
 
        virtual string asString() const;
 
 private:
-       string trace_path_;
+       class CTFField
+       {
+       public:
+               virtual ~CTFField()
+               {
+                       bt_ctf_field_put(field_);
+               }
+
+               string name() const { return name_; }
+               struct bt_ctf_field *field() const { return field_; }
+               struct bt_ctf_field_type *type() const { return type_; }
+
+       protected:
+               /* This class should not be instantiated */
+               CTFField() {}
+               CTFField(const CTFField &rhs) {}
+
+               string name_;
+               struct bt_ctf_field *field_;
+               struct bt_ctf_field_type *type_;
+       };
+
+       class CTFStringField : public CTFField
+       {
+       public:
+               CTFStringField(const string &name, const string &value);
+               ~CTFStringField() {}
+       };
+
+       class CTFIntegerField : public CTFField
+       {
+       public:
+               CTFIntegerField(const string &name,
+                               uint32_t value,
+                               enum bt_ctf_integer_base base
+                                       = BT_CTF_INTEGER_BASE_DECIMAL);
+               CTFIntegerField(const string &name,
+                               uint64_t value,
+                               enum bt_ctf_integer_base base
+                                       = BT_CTF_INTEGER_BASE_DECIMAL);
+
+               ~CTFIntegerField() {}
+       private:
+               void create_unsigned_field(const string &name,
+                               struct bt_ctf_field_type *type,
+                               uint64_t value);
+       };
+
+       typedef vector<CTFField*> CTFFields;
+
+       void append_nexus_message(NxMessage *m,
+                       const string &event_name,
+                       const CTFFields &fields);
+
+       struct bt_ctf_event_class* create_event_class(const NxMessage *m,
+                       const string &name,
+                       const CTFFields &fields);
+
+       struct bt_ctf_event_class* get_event_class(const NxMessage *m) const;
+
+       void event_set_fields(struct bt_ctf_event *event,
+                             const CTFFields &fields) const;
+
+       struct bt_ctf_writer *writer_;
+       struct bt_ctf_clock *clock_;
+       struct bt_ctf_stream_class *stream_class_;
+       struct bt_ctf_stream *stream_;
+
+       struct type_info_compare {
+               bool operator ()(const type_info *a, const type_info *b) const {
+                       return a->before(*b);
+               }
+       };
+
+       /* Events classes */
+       map<const type_info *,
+               struct bt_ctf_event_class *,
+               type_info_compare> event_class_;
 };
 
 #endif // CTFLOGVISITOR_H
This page took 0.045967 seconds and 4 git commands to generate.