From: Christian Babeux Date: Sun, 13 Oct 2013 03:43:43 +0000 (-0400) Subject: Add CTFVisitor implementation X-Git-Url: http://git.efficios.com/?p=babeltrace.git;a=commitdiff_plain;h=261e5f5e5df959ce7548519b7e6ca4bfc46b8720 Add CTFVisitor implementation First implementation of the Freescale Nexus to CTF visitor. Signed-off-by: Christian Babeux Signed-off-by: Jérémie Galarneau --- diff --git a/converter/nexus/CTFLogVisitor.cpp b/converter/nexus/CTFLogVisitor.cpp index 7a7e86f3..0b7c8dd5 100644 --- a/converter/nexus/CTFLogVisitor.cpp +++ b/converter/nexus/CTFLogVisitor.cpp @@ -20,37 +20,1078 @@ * IN THE SOFTWARE. */ +#include #include - +#include #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::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_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(×tamp); + 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(×tamp);*/ + + 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(×tamp); + 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(×tamp); + 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(×tamp); + 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(×tamp); + 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(×tamp); + 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(×tamp); + 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(×tamp); + 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(×tamp); + 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(×tamp); + 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(×tamp); + 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(×tamp); + 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(×tamp); + 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(×tamp); + 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(×tamp); + 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(×tamp); + 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(×tamp); + 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(×tamp); + 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(×tamp); + 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(×tamp); + 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 ""; } diff --git a/converter/nexus/CTFLogVisitor.h b/converter/nexus/CTFLogVisitor.h index fa06e068..1711bab4 100644 --- a/converter/nexus/CTFLogVisitor.h +++ b/converter/nexus/CTFLogVisitor.h @@ -23,11 +23,24 @@ #ifndef CTFLOGVISITOR_H #define CTFLOGVISITOR_H +#include #include +#include +#include +#include +#include +#include +#include +#include +#include #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 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 event_class_; }; #endif // CTFLOGVISITOR_H