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; }
int ctf_sequence_read(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; g_string_assign(sequence_definition->string, ""); g_string_insert_len(sequence_definition->string, (gssize)0, (const gchar *)ctf_get_pos_addr(pos), (gssize)len); if (!ctf_move_pos(pos, len * CHAR_BIT)) return -EFAULT; return 0; } } } return bt_sequence_rw(ppos, definition); }
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 = bt_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 */ if (!ctf_align_pos(pos, sizeof(uint64_t) * CHAR_BIT)) goto error; if (!pos->dummy) *(uint64_t *) ctf_get_pos_addr(pos) = *ts; if (!ctf_move_pos(pos, sizeof(uint64_t) * CHAR_BIT)) goto error; return; error: fprintf(stderr, "[error] Out of packet bounds when writing event header\n"); abort(); }