static void write_packet_header(struct ctf_stream_pos *pos, unsigned char *uuid) { struct ctf_stream_pos dummy; /* magic */ ctf_dummy_pos(pos, &dummy); ctf_align_pos(&dummy, sizeof(uint32_t) * CHAR_BIT); ctf_move_pos(&dummy, sizeof(uint32_t) * CHAR_BIT); assert(!ctf_pos_packet(&dummy)); ctf_align_pos(pos, sizeof(uint32_t) * CHAR_BIT); *(uint32_t *) ctf_get_pos_addr(pos) = 0xC1FC1FC1; ctf_move_pos(pos, sizeof(uint32_t) * CHAR_BIT); /* uuid */ ctf_dummy_pos(pos, &dummy); ctf_align_pos(&dummy, sizeof(uint8_t) * CHAR_BIT); ctf_move_pos(&dummy, 16 * CHAR_BIT); assert(!ctf_pos_packet(&dummy)); ctf_align_pos(pos, sizeof(uint8_t) * CHAR_BIT); memcpy(ctf_get_pos_addr(pos), uuid, BABELTRACE_UUID_LEN); ctf_move_pos(pos, BABELTRACE_UUID_LEN * CHAR_BIT); }
static void write_packet_context(struct ctf_stream_pos *pos) { struct ctf_stream_pos dummy; /* content_size */ ctf_dummy_pos(pos, &dummy); ctf_align_pos(&dummy, sizeof(uint64_t) * CHAR_BIT); ctf_move_pos(&dummy, sizeof(uint64_t) * CHAR_BIT); assert(!ctf_pos_packet(&dummy)); ctf_align_pos(pos, sizeof(uint64_t) * CHAR_BIT); *(uint64_t *) ctf_get_pos_addr(pos) = ~0ULL; /* Not known yet */ pos->content_size_loc = (uint64_t *) ctf_get_pos_addr(pos); ctf_move_pos(pos, sizeof(uint64_t) * CHAR_BIT); /* packet_size */ ctf_dummy_pos(pos, &dummy); ctf_align_pos(&dummy, sizeof(uint64_t) * CHAR_BIT); ctf_move_pos(&dummy, sizeof(uint64_t) * CHAR_BIT); assert(!ctf_pos_packet(&dummy)); ctf_align_pos(pos, sizeof(uint64_t) * CHAR_BIT); *(uint64_t *) ctf_get_pos_addr(pos) = pos->packet_size; ctf_move_pos(pos, sizeof(uint64_t) * CHAR_BIT); }
int ctf_string_write(struct bt_stream_pos *ppos, struct bt_definition *definition) { struct definition_string *string_definition = container_of(definition, struct definition_string, p); const struct declaration_string *string_declaration = string_definition->declaration; struct ctf_stream_pos *pos = ctf_pos(ppos); size_t len; char *destaddr; if (!ctf_align_pos(pos, string_declaration->p.alignment)) return -EFAULT; assert(string_definition->value != NULL); len = string_definition->len; if (!ctf_pos_access_ok(pos, len)) return -EFAULT; if (pos->dummy) goto end; destaddr = ctf_get_pos_addr(pos); memcpy(destaddr, string_definition->value, len); end: if (!ctf_move_pos(pos, len * CHAR_BIT)) return -EFAULT; return 0; }
static void write_event_header(struct ctf_stream_pos *pos, char *line, char **tline, size_t len, size_t *tlen, uint64_t *ts) { if (!s_timestamp) return; /* Only need to be executed on first pass (dummy) */ if (pos->dummy) { int has_timestamp = 0; unsigned long sec, usec, msec; unsigned int year, mon, mday, hour, min; /* Extract time from input line */ if (sscanf(line, "[%lu.%lu] ", &sec, &usec) == 2) { *ts = (uint64_t) sec * USEC_PER_SEC + (uint64_t) usec; /* * Default CTF clock has 1GHz frequency. Convert * from usec to nsec. */ *ts *= NSEC_PER_USEC; has_timestamp = 1; } else if (sscanf(line, "[%u-%u-%u %u:%u:%lu.%lu] ", &year, &mon, &mday, &hour, &min, &sec, &msec) == 7) { time_t ep_sec; struct tm ti; memset(&ti, 0, sizeof(ti)); ti.tm_year = year - 1900; /* from 1900 */ ti.tm_mon = mon - 1; /* 0 to 11 */ ti.tm_mday = mday; ti.tm_hour = hour; ti.tm_min = min; ti.tm_sec = sec; ep_sec = babeltrace_timegm(&ti); if (ep_sec != (time_t) -1) { *ts = (uint64_t) ep_sec * NSEC_PER_SEC + (uint64_t) msec * NSEC_PER_MSEC; } has_timestamp = 1; } if (has_timestamp) { *tline = strchr(line, ']'); assert(*tline); (*tline)++; if ((*tline)[0] == ' ') { (*tline)++; } *tlen = len + line - *tline; } } /* timestamp */ ctf_align_pos(pos, sizeof(uint64_t) * CHAR_BIT); if (!pos->dummy) *(uint64_t *) ctf_get_pos_addr(pos) = *ts; ctf_move_pos(pos, sizeof(uint64_t) * CHAR_BIT); }
int ctf_sequence_write(struct bt_stream_pos *ppos, struct bt_definition *definition) { struct definition_sequence *sequence_definition = container_of(definition, struct definition_sequence, p); struct declaration_sequence *sequence_declaration = sequence_definition->declaration; struct bt_declaration *elem = sequence_declaration->elem; struct ctf_stream_pos *pos = ctf_pos(ppos); if (elem->id == CTF_TYPE_INTEGER) { struct declaration_integer *integer_declaration = container_of(elem, struct declaration_integer, p); if (integer_declaration->encoding == CTF_STRING_UTF8 || integer_declaration->encoding == CTF_STRING_ASCII) { if (integer_declaration->len == CHAR_BIT && integer_declaration->p.alignment == CHAR_BIT) { uint64_t len = bt_sequence_len(sequence_definition); if (!ctf_align_pos(pos, integer_declaration->p.alignment)) return -EFAULT; if (!ctf_pos_access_ok(pos, len * CHAR_BIT)) return -EFAULT; memcpy((char *) ctf_get_pos_addr(pos), sequence_definition->string->str, (size_t)len); if (!ctf_move_pos(pos, len * CHAR_BIT)) return -EFAULT; return 0; } } } return bt_sequence_rw(ppos, definition); }
static int bt_ctf_field_structure_serialize(struct bt_ctf_field *field, struct ctf_stream_pos *pos) { size_t i; int ret = 0; struct bt_ctf_field_structure *structure = container_of( field, struct bt_ctf_field_structure, parent); while (!ctf_pos_access_ok(pos, offset_align(pos->offset, field->type->declaration->alignment))) { ret = increase_packet_size(pos); if (ret) { goto end; } } if (!ctf_align_pos(pos, field->type->declaration->alignment)) { ret = -1; goto end; } for (i = 0; i < structure->fields->len; i++) { struct bt_ctf_field *field = g_ptr_array_index( structure->fields, i); ret = bt_ctf_field_serialize(field, pos); if (ret) { break; } } end: return ret; }
static void write_event_header(struct ctf_stream_pos *pos, char *line, char **tline, size_t len, size_t *tlen, uint64_t *ts) { unsigned long sec, usec; if (!s_timestamp) return; /* Only need to be executed on first pass (dummy) */ if (pos->dummy) { int ret; /* Extract time from input line */ ret = sscanf(line, "[%lu.%lu] ", &sec, &usec); if (ret == 2) { *tline = strchr(line, ']'); assert(*tline); (*tline)++; if ((*tline)[0] == ' ') { (*tline)++; } *tlen = len + line - *tline; *ts = (uint64_t) sec * USEC_PER_SEC + (uint64_t) usec; } } /* timestamp */ ctf_align_pos(pos, sizeof(uint64_t) * CHAR_BIT); if (!pos->dummy) *(uint64_t *) ctf_get_pos_addr(pos) = *ts; ctf_move_pos(pos, sizeof(uint64_t) * CHAR_BIT); }
static void trace_string(char *line, struct ctf_stream_pos *pos, size_t len) { struct ctf_stream_pos dummy; int attempt = 0; char *tline = line; /* tline is start of text, after timestamp */ size_t tlen = len; uint64_t ts = 0; printf_debug("read: %s\n", line); for (;;) { int packet_filled = 0; ctf_dummy_pos(pos, &dummy); write_event_header(&dummy, line, &tline, len, &tlen, &ts); if (!ctf_align_pos(&dummy, sizeof(uint8_t) * CHAR_BIT)) packet_filled = 1; if (!ctf_move_pos(&dummy, tlen * CHAR_BIT)) packet_filled = 1; if (packet_filled || ctf_pos_packet(&dummy)) { ctf_pos_pad_packet(pos); write_packet_header(pos, s_uuid); write_packet_context(pos); if (attempt++ == 1) { fprintf(stderr, "[Error] Line too large for packet size (%" PRIu64 "kB) (discarded)\n", pos->packet_size / CHAR_BIT / 1024); return; } continue; } else { break; } } write_event_header(pos, line, &tline, len, &tlen, &ts); if (!ctf_align_pos(pos, sizeof(uint8_t) * CHAR_BIT)) goto error; memcpy(ctf_get_pos_addr(pos), tline, tlen); if (!ctf_move_pos(pos, tlen * CHAR_BIT)) goto error; return; error: fprintf(stderr, "[error] Out of packet bounds when writing event payload\n"); abort(); }
int ctf_struct_rw(struct bt_stream_pos *ppos, struct bt_definition *definition) { struct bt_declaration *declaration = definition->declaration; struct ctf_stream_pos *pos = ctf_pos(ppos); ctf_align_pos(pos, declaration->alignment); return bt_struct_rw(ppos, definition); }
static void write_packet_context(struct ctf_stream_pos *pos) { struct ctf_stream_pos dummy; /* content_size */ ctf_dummy_pos(pos, &dummy); if (!ctf_align_pos(&dummy, sizeof(uint64_t) * CHAR_BIT)) goto error; if (!ctf_move_pos(&dummy, sizeof(uint64_t) * CHAR_BIT)) goto error; assert(!ctf_pos_packet(&dummy)); if (!ctf_align_pos(pos, sizeof(uint64_t) * CHAR_BIT)) goto error; *(uint64_t *) ctf_get_pos_addr(pos) = ~0ULL; /* Not known yet */ pos->content_size_loc = (uint64_t *) ctf_get_pos_addr(pos); if (!ctf_move_pos(pos, sizeof(uint64_t) * CHAR_BIT)) goto error; /* packet_size */ ctf_dummy_pos(pos, &dummy); if (!ctf_align_pos(&dummy, sizeof(uint64_t) * CHAR_BIT)) goto error; if (!ctf_move_pos(&dummy, sizeof(uint64_t) * CHAR_BIT)) goto error; assert(!ctf_pos_packet(&dummy)); if (!ctf_align_pos(pos, sizeof(uint64_t) * CHAR_BIT)) goto error; *(uint64_t *) ctf_get_pos_addr(pos) = pos->packet_size; if (!ctf_move_pos(pos, sizeof(uint64_t) * CHAR_BIT)) goto error; return; error: fprintf(stderr, "[error] Out of packet bounds when writing packet context\n"); abort(); }
static void write_packet_header(struct ctf_stream_pos *pos, unsigned char *uuid) { struct ctf_stream_pos dummy; /* magic */ ctf_dummy_pos(pos, &dummy); if (!ctf_align_pos(&dummy, sizeof(uint32_t) * CHAR_BIT)) goto error; if (!ctf_move_pos(&dummy, sizeof(uint32_t) * CHAR_BIT)) goto error; assert(!ctf_pos_packet(&dummy)); if (!ctf_align_pos(pos, sizeof(uint32_t) * CHAR_BIT)) goto error; *(uint32_t *) ctf_get_pos_addr(pos) = 0xC1FC1FC1; if (!ctf_move_pos(pos, sizeof(uint32_t) * CHAR_BIT)) goto error; /* uuid */ ctf_dummy_pos(pos, &dummy); if (!ctf_align_pos(&dummy, sizeof(uint8_t) * CHAR_BIT)) goto error; if (!ctf_move_pos(&dummy, 16 * CHAR_BIT)) goto error; assert(!ctf_pos_packet(&dummy)); if (!ctf_align_pos(pos, sizeof(uint8_t) * CHAR_BIT)) goto error; memcpy(ctf_get_pos_addr(pos), uuid, BABELTRACE_UUID_LEN); if (!ctf_move_pos(pos, BABELTRACE_UUID_LEN * CHAR_BIT)) goto error; return; error: fprintf(stderr, "[error] Out of packet bounds when writing packet header\n"); abort(); }
int ctf_string_read(struct bt_stream_pos *ppos, struct bt_definition *definition) { struct definition_string *string_definition = container_of(definition, struct definition_string, p); const struct declaration_string *string_declaration = string_definition->declaration; struct ctf_stream_pos *pos = ctf_pos(ppos); size_t len; ssize_t max_len_bits; char *srcaddr; if (!ctf_align_pos(pos, string_declaration->p.alignment)) return -EFAULT; srcaddr = ctf_get_pos_addr(pos); if (pos->offset == EOF) return -EFAULT; /* Not counting \0. Counting in bits. */ max_len_bits = pos->packet_size - pos->offset - CHAR_BIT; if (max_len_bits < 0) return -EFAULT; /* Add \0, counting in bytes. */ len = bt_strnlen(srcaddr, (size_t) max_len_bits / CHAR_BIT) + 1; /* Truncated string, unexpected. Trace probably corrupted. */ if (srcaddr[len - 1] != '\0') return -EFAULT; if (string_definition->alloc_len < len) { string_definition->value = g_realloc(string_definition->value, len); string_definition->alloc_len = len; } printf_debug("CTF string read %s\n", srcaddr); memcpy(string_definition->value, srcaddr, len); string_definition->len = len; if (!ctf_move_pos(pos, len * CHAR_BIT)) return -EFAULT; return 0; }