Replace all assert(false) and assert(0) with abort()
[babeltrace.git] / plugins / ctf / common / btr / btr.c
1 /*
2 * Babeltrace - CTF binary type reader (BTR)
3 *
4 * Copyright (c) 2015-2016 EfficiOS Inc. and Linux Foundation
5 * Copyright (c) 2015-2016 Philippe Proulx <pproulx@efficios.com>
6 *
7 * Permission is hereby granted, free of charge, to any person obtaining a copy
8 * of this software and associated documentation files (the "Software"), to deal
9 * in the Software without restriction, including without limitation the rights
10 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11 * copies of the Software, and to permit persons to whom the Software is
12 * furnished to do so, subject to the following conditions:
13 *
14 * The above copyright notice and this permission notice shall be included in
15 * all copies or substantial portions of the Software.
16 *
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23 * SOFTWARE.
24 */
25
26 #include <stdlib.h>
27 #include <stdint.h>
28 #include <stdio.h>
29 #include <stddef.h>
30 #include <stdbool.h>
31 #include <assert.h>
32 #include <string.h>
33 #include <babeltrace/bitfield-internal.h>
34 #include <babeltrace/ctf-ir/field-types.h>
35 #include <babeltrace/ref.h>
36 #include <babeltrace/align-internal.h>
37 #include <glib.h>
38
39 #include "btr.h"
40
41 #define PRINT_ERR_STREAM btr->err_stream
42 #define PRINT_PREFIX "ctf-btr"
43 #include "../print.h"
44
45 #define DIV8(_x) ((_x) >> 3)
46 #define BYTES_TO_BITS(_x) ((_x) * 8)
47 #define BITS_TO_BYTES_FLOOR(_x) DIV8(_x)
48 #define BITS_TO_BYTES_CEIL(_x) DIV8((_x) + 7)
49 #define IN_BYTE_OFFSET(_at) ((_at) & 7)
50
51 /* A visit stack entry */
52 struct stack_entry {
53 /*
54 * Current type of base field, one of:
55 *
56 * * Structure
57 * * Array
58 * * Sequence
59 * * Variant
60 *
61 * Owned by this.
62 */
63 struct bt_ctf_field_type *base_type;
64
65 /* Length of base field (always 1 for variant types) */
66 int64_t base_len;
67
68 /* Lndex of next field to read */
69 int64_t index;
70 };
71
72 /* Visit stack */
73 struct stack {
74 /* Entries (struct stack_entry *) (top is last element) */
75 GPtrArray *entries;
76 };
77
78 /* Reading states */
79 enum btr_state {
80 BTR_STATE_NEXT_FIELD,
81 BTR_STATE_ALIGN_BASIC,
82 BTR_STATE_ALIGN_COMPOUND,
83 BTR_STATE_READ_BASIC_BEGIN,
84 BTR_STATE_READ_BASIC_CONTINUE,
85 BTR_STATE_DONE,
86 };
87
88 /* Binary type reader */
89 struct bt_ctf_btr {
90 /* Bisit stack */
91 struct stack *stack;
92
93 /* Error stream */
94 FILE *err_stream;
95
96 /* Current basic field type */
97 struct bt_ctf_field_type *cur_basic_field_type;
98
99 /* Current state */
100 enum btr_state state;
101
102 /*
103 * Last basic field type's byte order.
104 *
105 * This is used to detect errors since two contiguous basic
106 * types for which the common boundary is not the boundary of
107 * a byte cannot have different byte orders.
108 *
109 * This is set to BT_CTF_BYTE_ORDER_UNKNOWN on reset and when
110 * the last basic field type was a string type.
111 */
112 enum bt_ctf_byte_order last_bo;
113
114 /* Current byte order (copied to last_bo after a successful read) */
115 enum bt_ctf_byte_order cur_bo;
116
117 /* Stitch buffer infos */
118 struct {
119 /* Stitch buffer */
120 uint8_t buf[16];
121
122 /* Offset, within stitch buffer, of first bit */
123 size_t offset;
124
125 /* Length (bits) of data in stitch buffer from offset */
126 size_t at;
127 } stitch;
128
129 /* User buffer infos */
130 struct {
131 /* Address */
132 const uint8_t *addr;
133
134 /* Offset of data from address (bits) */
135 size_t offset;
136
137 /* Current position from offset (bits) */
138 size_t at;
139
140 /* Offset of offset within whole packet (bits) */
141 size_t packet_offset;
142
143 /* Data size in buffer (bits) */
144 size_t sz;
145
146 /* Buffer size (bytes) */
147 size_t buf_sz;
148 } buf;
149
150 /* User stuff */
151 struct {
152 /* Callback functions */
153 struct bt_ctf_btr_cbs cbs;
154
155 /* Private data */
156 void *data;
157 } user;
158 };
159
160 static
161 void stack_entry_free_func(gpointer data)
162 {
163 struct stack_entry *entry = data;
164
165 BT_PUT(entry->base_type);
166 g_free(entry);
167 }
168
169 static
170 struct stack *stack_new(void)
171 {
172 struct stack *stack = NULL;
173
174 stack = g_new0(struct stack, 1);
175 if (!stack) {
176 goto error;
177 }
178
179 stack->entries = g_ptr_array_new_with_free_func(stack_entry_free_func);
180 if (!stack->entries) {
181 goto error;
182 }
183
184 return stack;
185
186 error:
187 g_free(stack);
188
189 return NULL;
190 }
191
192 static
193 void stack_destroy(struct stack *stack)
194 {
195 if (!stack) {
196 return;
197 }
198
199 g_ptr_array_free(stack->entries, TRUE);
200 g_free(stack);
201 }
202
203 static inline
204 int64_t get_compound_field_type_length(struct bt_ctf_btr *btr,
205 struct bt_ctf_field_type *field_type)
206 {
207 int64_t length;
208
209 switch (bt_ctf_field_type_get_type_id(field_type)) {
210 case BT_CTF_FIELD_TYPE_ID_STRUCT:
211 length = (int64_t) bt_ctf_field_type_structure_get_field_count(
212 field_type);
213 break;
214 case BT_CTF_FIELD_TYPE_ID_VARIANT:
215 /* Variant field types always "contain" a single type */
216 length = 1;
217 break;
218 case BT_CTF_FIELD_TYPE_ID_ARRAY:
219 length = bt_ctf_field_type_array_get_length(field_type);
220 break;
221 case BT_CTF_FIELD_TYPE_ID_SEQUENCE:
222 length = btr->user.cbs.query.get_sequence_length(field_type,
223 btr->user.data);
224 break;
225 default:
226 PERR("Cannot get length of field type with type ID %d\n",
227 bt_ctf_field_type_get_type_id(field_type));
228 length = BT_CTF_BTR_STATUS_ERROR;
229 }
230
231 return length;
232 }
233
234 static
235 int stack_push(struct stack *stack, struct bt_ctf_field_type *base_type,
236 size_t base_len)
237 {
238 int ret = 0;
239 struct stack_entry *entry;
240
241 assert(stack);
242 assert(base_type);
243
244 entry = g_new0(struct stack_entry, 1);
245 if (!entry) {
246 ret = BT_CTF_BTR_STATUS_ERROR;
247 goto end;
248 }
249
250 entry->base_type = base_type;
251 bt_get(entry->base_type);
252 entry->base_len = base_len;
253 g_ptr_array_add(stack->entries, entry);
254
255 end:
256 return ret;
257 }
258
259 static
260 int stack_push_with_len(struct bt_ctf_btr *btr,
261 struct bt_ctf_field_type *base_type)
262 {
263 int ret = 0;
264 int64_t base_len = get_compound_field_type_length(btr, base_type);
265
266 if (base_len < 0) {
267 PERR("Failed to get compound field type's length\n");
268 ret = BT_CTF_BTR_STATUS_ERROR;
269 goto end;
270 }
271
272 ret = stack_push(btr->stack, base_type, (size_t) base_len);
273
274 end:
275 return ret;
276 }
277
278 static inline
279 unsigned int stack_size(struct stack *stack)
280 {
281 assert(stack);
282
283 return stack->entries->len;
284 }
285
286 static
287 void stack_pop(struct stack *stack)
288 {
289 assert(stack);
290 assert(stack_size(stack));
291 g_ptr_array_remove_index(stack->entries, stack->entries->len - 1);
292 }
293
294 static inline
295 bool stack_empty(struct stack *stack)
296 {
297 return stack_size(stack) == 0;
298 }
299
300 static
301 void stack_clear(struct stack *stack)
302 {
303 assert(stack);
304
305 if (!stack_empty(stack)) {
306 g_ptr_array_remove_range(stack->entries, 0, stack_size(stack));
307 }
308
309 assert(stack_empty(stack));
310 }
311
312 static inline
313 struct stack_entry *stack_top(struct stack *stack)
314 {
315 assert(stack);
316 assert(stack_size(stack));
317
318 return g_ptr_array_index(stack->entries, stack->entries->len - 1);
319 }
320
321 static inline
322 size_t available_bits(struct bt_ctf_btr *btr)
323 {
324 return btr->buf.sz - btr->buf.at;
325 }
326
327 static inline
328 void consume_bits(struct bt_ctf_btr *btr, size_t incr)
329 {
330 btr->buf.at += incr;
331 }
332
333 static inline
334 bool has_enough_bits(struct bt_ctf_btr *btr, size_t sz)
335 {
336 return available_bits(btr) >= sz;
337 }
338
339 static inline
340 bool at_least_one_bit_left(struct bt_ctf_btr *btr)
341 {
342 return has_enough_bits(btr, 1);
343 }
344
345 static inline
346 size_t packet_at(struct bt_ctf_btr *btr)
347 {
348 return btr->buf.packet_offset + btr->buf.at;
349 }
350
351 static inline
352 size_t buf_at_from_addr(struct bt_ctf_btr *btr)
353 {
354 /*
355 * Considering this:
356 *
357 * ====== offset ===== (17)
358 *
359 * xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx
360 * ^
361 * addr (0) ==== at ==== (12)
362 *
363 * We want this:
364 *
365 * =============================== (29)
366 */
367 return btr->buf.offset + btr->buf.at;
368 }
369
370 static inline
371 int get_basic_field_type_size(struct bt_ctf_btr *btr,
372 struct bt_ctf_field_type *field_type)
373 {
374 int size;
375
376 switch (bt_ctf_field_type_get_type_id(field_type)) {
377 case BT_CTF_FIELD_TYPE_ID_INTEGER:
378 size = bt_ctf_field_type_integer_get_size(field_type);
379 break;
380 case BT_CTF_FIELD_TYPE_ID_FLOAT:
381 {
382 int exp_dig, mant_dig;
383
384 exp_dig =
385 bt_ctf_field_type_floating_point_get_exponent_digits(
386 field_type);
387 mant_dig =
388 bt_ctf_field_type_floating_point_get_mantissa_digits(
389 field_type);
390 if (exp_dig < 0 || mant_dig < 0) {
391 PERR("Failed to get floating point number type's sizes\n");
392 size = BT_CTF_BTR_STATUS_ERROR;
393 }
394
395 size = exp_dig + mant_dig;
396 break;
397 }
398 case BT_CTF_FIELD_TYPE_ID_ENUM:
399 {
400 struct bt_ctf_field_type *int_type;
401
402 int_type = bt_ctf_field_type_enumeration_get_container_type(
403 field_type);
404 if (!int_type) {
405 PERR("Failed to get enumeration type's container type\n");
406 size = BT_CTF_BTR_STATUS_ERROR;
407 goto end;
408 }
409
410 size = get_basic_field_type_size(btr, int_type);
411 BT_PUT(int_type);
412 break;
413 }
414 default:
415 size = BT_CTF_BTR_STATUS_ERROR;
416 break;
417 }
418
419 end:
420 return size;
421 }
422
423 static
424 void stitch_reset(struct bt_ctf_btr *btr)
425 {
426 btr->stitch.offset = 0;
427 btr->stitch.at = 0;
428 }
429
430 static inline
431 size_t stitch_at_from_addr(struct bt_ctf_btr *btr)
432 {
433 return btr->stitch.offset + btr->stitch.at;
434 }
435
436 static
437 void stitch_append_from_buf(struct bt_ctf_btr *btr, size_t sz)
438 {
439 size_t stitch_byte_at;
440 size_t buf_byte_at;
441 size_t nb_bytes;;
442
443 if (sz == 0) {
444 return;
445 }
446
447 stitch_byte_at =
448 BITS_TO_BYTES_FLOOR(stitch_at_from_addr(btr));
449 buf_byte_at = BITS_TO_BYTES_FLOOR(buf_at_from_addr(btr));
450 nb_bytes = BITS_TO_BYTES_CEIL(sz);
451 assert(nb_bytes > 0);
452 memcpy(&btr->stitch.buf[stitch_byte_at], &btr->buf.addr[buf_byte_at],
453 nb_bytes);
454 btr->stitch.at += sz;
455 consume_bits(btr, sz);
456 }
457
458 static
459 void stitch_append_from_remaining_buf(struct bt_ctf_btr *btr)
460 {
461 stitch_append_from_buf(btr, available_bits(btr));
462 }
463
464 static
465 void stitch_set_from_remaining_buf(struct bt_ctf_btr *btr)
466 {
467 stitch_reset(btr);
468 btr->stitch.offset = IN_BYTE_OFFSET(buf_at_from_addr(btr));
469 stitch_append_from_remaining_buf(btr);
470 }
471
472 static inline
473 enum bt_ctf_btr_status read_unsigned_bitfield(const uint8_t *buf, size_t at,
474 int64_t field_size, enum bt_ctf_byte_order bo, uint64_t *v)
475 {
476 enum bt_ctf_btr_status status = BT_CTF_BTR_STATUS_OK;
477
478 switch (bo) {
479 case BT_CTF_BYTE_ORDER_BIG_ENDIAN:
480 case BT_CTF_BYTE_ORDER_NETWORK:
481 bt_bitfield_read_be(buf, uint8_t, at, field_size, v);
482 break;
483 case BT_CTF_BYTE_ORDER_LITTLE_ENDIAN:
484 bt_bitfield_read_le(buf, uint8_t, at, field_size, v);
485 break;
486 default:
487 status = BT_CTF_BTR_STATUS_ERROR;
488 }
489
490 return status;
491 }
492
493 static inline
494 enum bt_ctf_btr_status read_signed_bitfield(const uint8_t *buf, size_t at,
495 int64_t field_size, enum bt_ctf_byte_order bo, int64_t *v)
496 {
497 enum bt_ctf_btr_status status = BT_CTF_BTR_STATUS_OK;
498
499 switch (bo) {
500 case BT_CTF_BYTE_ORDER_BIG_ENDIAN:
501 case BT_CTF_BYTE_ORDER_NETWORK:
502 bt_bitfield_read_be(buf, uint8_t, at, field_size, v);
503 break;
504 case BT_CTF_BYTE_ORDER_LITTLE_ENDIAN:
505 bt_bitfield_read_le(buf, uint8_t, at, field_size, v);
506 break;
507 default:
508 status = BT_CTF_BTR_STATUS_ERROR;
509 }
510
511 return status;
512 }
513
514 typedef enum bt_ctf_btr_status (* read_basic_and_call_cb_t)(struct bt_ctf_btr *,
515 const uint8_t *, size_t);
516
517 static inline
518 enum bt_ctf_btr_status validate_contiguous_bo(struct bt_ctf_btr *btr,
519 enum bt_ctf_byte_order next_bo)
520 {
521 enum bt_ctf_btr_status status = BT_CTF_BTR_STATUS_OK;
522
523 /* Always valid when at a byte boundary */
524 if (packet_at(btr) % 8 == 0) {
525 goto end;
526 }
527
528 /* Always valid if last byte order is unknown */
529 if (btr->last_bo == BT_CTF_BYTE_ORDER_UNKNOWN) {
530 goto end;
531 }
532
533 /* Always valid if next byte order is unknown */
534 if (next_bo == BT_CTF_BYTE_ORDER_UNKNOWN) {
535 goto end;
536 }
537
538 /* Make sure last byte order is compatible with the next byte order */
539 switch (btr->last_bo) {
540 case BT_CTF_BYTE_ORDER_BIG_ENDIAN:
541 case BT_CTF_BYTE_ORDER_NETWORK:
542 if (next_bo != BT_CTF_BYTE_ORDER_BIG_ENDIAN &&
543 next_bo != BT_CTF_BYTE_ORDER_NETWORK) {
544 status = BT_CTF_BTR_STATUS_ERROR;
545 }
546 break;
547 case BT_CTF_BYTE_ORDER_LITTLE_ENDIAN:
548 if (next_bo != BT_CTF_BYTE_ORDER_LITTLE_ENDIAN) {
549 status = BT_CTF_BTR_STATUS_ERROR;
550 }
551 break;
552 default:
553 status = BT_CTF_BTR_STATUS_ERROR;
554 }
555
556 end:
557 return status;
558 }
559
560 static
561 enum bt_ctf_btr_status read_basic_float_and_call_cb(struct bt_ctf_btr *btr,
562 const uint8_t *buf, size_t at)
563 {
564 int ret;
565 double dblval;
566 int64_t field_size;
567 enum bt_ctf_byte_order bo;
568 enum bt_ctf_btr_status status = BT_CTF_BTR_STATUS_OK;
569
570 field_size = get_basic_field_type_size(btr, btr->cur_basic_field_type);
571 bo = bt_ctf_field_type_get_byte_order(btr->cur_basic_field_type);
572 btr->cur_bo = bo;
573
574 switch (field_size) {
575 case 32:
576 {
577 uint64_t v;
578 union {
579 uint32_t u;
580 float f;
581 } f32;
582
583 ret = bt_ctf_field_type_floating_point_get_mantissa_digits(
584 btr->cur_basic_field_type);
585 assert(ret == 24);
586 ret = bt_ctf_field_type_floating_point_get_exponent_digits(
587 btr->cur_basic_field_type);
588 assert(ret == 8);
589 status = read_unsigned_bitfield(buf, at, field_size, bo, &v);
590 if (status != BT_CTF_BTR_STATUS_OK) {
591 PERR("Failed to reader unsigned bitfield\n");
592 goto end;
593 }
594
595 f32.u = (uint32_t) v;
596 dblval = (double) f32.f;
597 break;
598 }
599 case 64:
600 {
601 union {
602 uint64_t u;
603 double d;
604 } f64;
605
606 ret = bt_ctf_field_type_floating_point_get_mantissa_digits(
607 btr->cur_basic_field_type);
608 assert(ret == 53);
609 ret = bt_ctf_field_type_floating_point_get_exponent_digits(
610 btr->cur_basic_field_type);
611 assert(ret == 11);
612 status = read_unsigned_bitfield(buf, at, field_size, bo,
613 &f64.u);
614 if (status != BT_CTF_BTR_STATUS_OK) {
615 PERR("Failed to reader unsigned bitfield\n");
616 goto end;
617 }
618
619 dblval = f64.d;
620 break;
621 }
622 default:
623 /* Only 32-bit and 64-bit fields are supported currently */
624 status = BT_CTF_BTR_STATUS_ERROR;
625 goto end;
626 }
627
628 if (btr->user.cbs.types.floating_point) {
629 status = btr->user.cbs.types.floating_point(dblval,
630 btr->cur_basic_field_type, btr->user.data);
631 }
632
633 end:
634 return status;
635 }
636
637 static inline
638 enum bt_ctf_btr_status read_basic_int_and_call(struct bt_ctf_btr *btr,
639 const uint8_t *buf, size_t at, struct bt_ctf_field_type *int_type,
640 struct bt_ctf_field_type *orig_type)
641 {
642 int signd;
643 int64_t field_size;
644 enum bt_ctf_byte_order bo;
645 enum bt_ctf_btr_status status = BT_CTF_BTR_STATUS_OK;
646
647 signd = bt_ctf_field_type_integer_get_signed(int_type);
648 field_size = get_basic_field_type_size(btr, int_type);
649 if (field_size < 1) {
650 PERR("Failed to get basic field type's size\n");
651 status = BT_CTF_BTR_STATUS_ERROR;
652 goto end;
653 }
654
655 bo = bt_ctf_field_type_get_byte_order(int_type);
656
657 /*
658 * Update current byte order now because we could be reading
659 * the integer value of an enumeration type, and thus we know
660 * here the actual supporting integer type's byte order.
661 */
662 btr->cur_bo = bo;
663
664 if (signd) {
665 int64_t v;
666
667 status = read_signed_bitfield(buf, at, field_size, bo, &v);
668 if (status != BT_CTF_BTR_STATUS_OK) {
669 PERR("Failed to reader signed bitfield\n");
670 goto end;
671 }
672
673 if (btr->user.cbs.types.signed_int) {
674 status = btr->user.cbs.types.signed_int(v,
675 btr->cur_basic_field_type, btr->user.data);
676 }
677 } else {
678 uint64_t v;
679
680 status = read_unsigned_bitfield(buf, at, field_size, bo, &v);
681 if (status != BT_CTF_BTR_STATUS_OK) {
682 PERR("Failed to reader unsigned bitfield\n");
683 goto end;
684 }
685
686 if (btr->user.cbs.types.unsigned_int) {
687 status = btr->user.cbs.types.unsigned_int(v,
688 btr->cur_basic_field_type, btr->user.data);
689 }
690 }
691
692 end:
693 return status;
694 }
695
696 static
697 enum bt_ctf_btr_status read_basic_int_and_call_cb(struct bt_ctf_btr *btr,
698 const uint8_t *buf, size_t at)
699 {
700 return read_basic_int_and_call(btr, buf, at, btr->cur_basic_field_type,
701 btr->cur_basic_field_type);
702 }
703
704 static
705 enum bt_ctf_btr_status read_basic_enum_and_call_cb(struct bt_ctf_btr *btr,
706 const uint8_t *buf, size_t at)
707 {
708 struct bt_ctf_field_type *int_field_type;
709 enum bt_ctf_btr_status status = BT_CTF_BTR_STATUS_OK;
710
711 int_field_type = bt_ctf_field_type_enumeration_get_container_type(
712 btr->cur_basic_field_type);
713 if (!int_field_type) {
714 PERR("Failed to get enumeration type's container type\n");
715 status = BT_CTF_BTR_STATUS_ERROR;
716 goto end;
717 }
718
719 status = read_basic_int_and_call(btr, buf, at,
720 int_field_type, btr->cur_basic_field_type);
721
722 end:
723 BT_PUT(int_field_type);
724
725 return status;
726 }
727
728 static inline
729 enum bt_ctf_btr_status read_basic_type_and_call_continue(struct bt_ctf_btr *btr,
730 read_basic_and_call_cb_t read_basic_and_call_cb)
731 {
732 size_t available;
733 int64_t field_size;
734 int64_t needed_bits;
735 enum bt_ctf_btr_status status = BT_CTF_BTR_STATUS_OK;
736
737 if (!at_least_one_bit_left(btr)) {
738 status = BT_CTF_BTR_STATUS_EOF;
739 goto end;
740 }
741
742 field_size = get_basic_field_type_size(btr, btr->cur_basic_field_type);
743 if (field_size < 1) {
744 PERR("Failed to get basic field type's size\n");
745 status = BT_CTF_BTR_STATUS_ERROR;
746 goto end;
747 }
748
749 available = available_bits(btr);
750 needed_bits = field_size - btr->stitch.at;
751 if (needed_bits <= available) {
752 /* We have all the bits; append to stitch, then decode */
753 stitch_append_from_buf(btr, needed_bits);
754 status = read_basic_and_call_cb(btr, btr->stitch.buf,
755 btr->stitch.offset);
756 if (status != BT_CTF_BTR_STATUS_OK) {
757 PERR("Failed to read basic field\n");
758 goto end;
759 }
760
761 if (stack_empty(btr->stack)) {
762 /* Root is a basic type */
763 btr->state = BTR_STATE_DONE;
764 } else {
765 /* Go to next field */
766 stack_top(btr->stack)->index++;
767 btr->state = BTR_STATE_NEXT_FIELD;
768 btr->last_bo = btr->cur_bo;
769 }
770 goto end;
771 }
772
773 /* We are here; it means we don't have enough data to decode this */
774 stitch_append_from_remaining_buf(btr);
775 status = BT_CTF_BTR_STATUS_EOF;
776
777 end:
778 return status;
779 }
780
781 static inline
782 enum bt_ctf_btr_status read_basic_type_and_call_begin(struct bt_ctf_btr *btr,
783 read_basic_and_call_cb_t read_basic_and_call_cb)
784 {
785 size_t available;
786 int64_t field_size;
787 enum bt_ctf_byte_order bo;
788 enum bt_ctf_btr_status status = BT_CTF_BTR_STATUS_OK;
789
790 if (!at_least_one_bit_left(btr)) {
791 status = BT_CTF_BTR_STATUS_EOF;
792 goto end;
793 }
794
795 field_size = get_basic_field_type_size(btr, btr->cur_basic_field_type);
796
797 if (field_size < 1) {
798 PERR("Failed to get basic field type's size\n");
799 status = BT_CTF_BTR_STATUS_ERROR;
800 goto end;
801 }
802
803 bo = bt_ctf_field_type_get_byte_order(btr->cur_basic_field_type);
804 status = validate_contiguous_bo(btr, bo);
805
806 if (status != BT_CTF_BTR_STATUS_OK) {
807 PERR("Invalid contiguous byte orders\n");
808 goto end;
809 }
810
811 available = available_bits(btr);
812
813 if (field_size <= available) {
814 /* We have all the bits; decode and set now */
815 status = read_basic_and_call_cb(btr, btr->buf.addr,
816 buf_at_from_addr(btr));
817
818 if (status != BT_CTF_BTR_STATUS_OK) {
819 PERR("Failed to read basic type\n");
820 goto end;
821 }
822
823 consume_bits(btr, field_size);
824
825 if (stack_empty(btr->stack)) {
826 /* Root is a basic type */
827 btr->state = BTR_STATE_DONE;
828 } else {
829 /* Go to next field */
830 stack_top(btr->stack)->index++;
831 btr->state = BTR_STATE_NEXT_FIELD;
832 btr->last_bo = btr->cur_bo;
833 }
834
835 goto end;
836 }
837
838 /* We are here; it means we don't have enough data to decode this */
839 stitch_set_from_remaining_buf(btr);
840 btr->state = BTR_STATE_READ_BASIC_CONTINUE;
841 status = BT_CTF_BTR_STATUS_EOF;
842
843 end:
844 return status;
845 }
846
847 static inline
848 enum bt_ctf_btr_status read_basic_int_type_and_call_begin(
849 struct bt_ctf_btr *btr)
850 {
851 return read_basic_type_and_call_begin(btr, read_basic_int_and_call_cb);
852 }
853
854 static inline
855 enum bt_ctf_btr_status read_basic_int_type_and_call_continue(
856 struct bt_ctf_btr *btr)
857 {
858 return read_basic_type_and_call_continue(btr,
859 read_basic_int_and_call_cb);
860 }
861
862 static inline
863 enum bt_ctf_btr_status read_basic_float_type_and_call_begin(
864 struct bt_ctf_btr *btr)
865 {
866 return read_basic_type_and_call_begin(btr,
867 read_basic_float_and_call_cb);
868 }
869
870 static inline
871 enum bt_ctf_btr_status read_basic_float_type_and_call_continue(
872 struct bt_ctf_btr *btr)
873 {
874 return read_basic_type_and_call_continue(btr,
875 read_basic_float_and_call_cb);
876 }
877
878 static inline
879 enum bt_ctf_btr_status read_basic_enum_type_and_call_begin(
880 struct bt_ctf_btr *btr)
881 {
882 return read_basic_type_and_call_begin(btr,
883 read_basic_enum_and_call_cb);
884 }
885
886 static inline
887 enum bt_ctf_btr_status read_basic_enum_type_and_call_continue(
888 struct bt_ctf_btr *btr)
889 {
890 return read_basic_type_and_call_continue(btr,
891 read_basic_enum_and_call_cb);
892 }
893
894 static inline
895 enum bt_ctf_btr_status read_basic_string_type_and_call(
896 struct bt_ctf_btr *btr, bool begin)
897 {
898 size_t buf_at_bytes;
899 const uint8_t *result;
900 size_t available_bytes;
901 const uint8_t *first_chr;
902 enum bt_ctf_btr_status status = BT_CTF_BTR_STATUS_OK;
903
904 if (!at_least_one_bit_left(btr)) {
905 status = BT_CTF_BTR_STATUS_EOF;
906 goto end;
907 }
908
909 assert(buf_at_from_addr(btr) % 8 == 0);
910 available_bytes = BITS_TO_BYTES_FLOOR(available_bits(btr));
911 buf_at_bytes = BITS_TO_BYTES_FLOOR(buf_at_from_addr(btr));
912 first_chr = &btr->buf.addr[buf_at_bytes];
913 result = memchr(first_chr, '\0', available_bytes);
914
915 if (begin && btr->user.cbs.types.string_begin) {
916 status = btr->user.cbs.types.string_begin(
917 btr->cur_basic_field_type, btr->user.data);
918
919 if (status != BT_CTF_BTR_STATUS_OK) {
920 PERR("string_begin() user callback function failed\n");
921 goto end;
922 }
923 }
924
925 if (!result) {
926 /* No null character yet */
927 if (btr->user.cbs.types.string) {
928 status = btr->user.cbs.types.string(
929 (const char *) first_chr,
930 available_bytes, btr->cur_basic_field_type,
931 btr->user.data);
932 if (status != BT_CTF_BTR_STATUS_OK) {
933 PERR("string() user callback function failed\n");
934 goto end;
935 }
936 }
937
938 consume_bits(btr, BYTES_TO_BITS(available_bytes));
939 btr->state = BTR_STATE_READ_BASIC_CONTINUE;
940 status = BT_CTF_BTR_STATUS_EOF;
941 } else {
942 /* Found the null character */
943 size_t result_len = (size_t) (result - first_chr);
944
945 if (btr->user.cbs.types.string && result_len) {
946 status = btr->user.cbs.types.string(
947 (const char *) first_chr,
948 result_len, btr->cur_basic_field_type,
949 btr->user.data);
950 if (status != BT_CTF_BTR_STATUS_OK) {
951 PERR("string() user callback function failed\n");
952 goto end;
953 }
954 }
955
956 if (btr->user.cbs.types.string_end) {
957 status = btr->user.cbs.types.string_end(
958 btr->cur_basic_field_type, btr->user.data);
959 if (status != BT_CTF_BTR_STATUS_OK) {
960 PERR("string_end() user callback function failed\n");
961 goto end;
962 }
963 }
964
965 consume_bits(btr, BYTES_TO_BITS(result_len + 1));
966
967 if (stack_empty(btr->stack)) {
968 /* Root is a basic type */
969 btr->state = BTR_STATE_DONE;
970 } else {
971 /* Go to next field */
972 stack_top(btr->stack)->index++;
973 btr->state = BTR_STATE_NEXT_FIELD;
974 btr->last_bo = btr->cur_bo;
975 }
976 }
977
978 end:
979 return status;
980 }
981
982 static inline
983 enum bt_ctf_btr_status read_basic_begin_state(struct bt_ctf_btr *btr)
984 {
985 enum bt_ctf_btr_status status;
986
987 assert(btr->cur_basic_field_type);
988
989 switch (bt_ctf_field_type_get_type_id(btr->cur_basic_field_type)) {
990 case BT_CTF_FIELD_TYPE_ID_INTEGER:
991 status = read_basic_int_type_and_call_begin(btr);
992 break;
993 case BT_CTF_FIELD_TYPE_ID_FLOAT:
994 status = read_basic_float_type_and_call_begin(btr);
995 break;
996 case BT_CTF_FIELD_TYPE_ID_ENUM:
997 status = read_basic_enum_type_and_call_begin(btr);
998 break;
999 case BT_CTF_FIELD_TYPE_ID_STRING:
1000 status = read_basic_string_type_and_call(btr, true);
1001 break;
1002 default:
1003 abort();
1004 }
1005
1006 return status;
1007 }
1008
1009 static inline
1010 enum bt_ctf_btr_status read_basic_continue_state(struct bt_ctf_btr *btr)
1011 {
1012 enum bt_ctf_btr_status status;
1013
1014 assert(btr->cur_basic_field_type);
1015
1016 switch (bt_ctf_field_type_get_type_id(btr->cur_basic_field_type)) {
1017 case BT_CTF_FIELD_TYPE_ID_INTEGER:
1018 status = read_basic_int_type_and_call_continue(btr);
1019 break;
1020 case BT_CTF_FIELD_TYPE_ID_FLOAT:
1021 status = read_basic_float_type_and_call_continue(btr);
1022 break;
1023 case BT_CTF_FIELD_TYPE_ID_ENUM:
1024 status = read_basic_enum_type_and_call_continue(btr);
1025 break;
1026 case BT_CTF_FIELD_TYPE_ID_STRING:
1027 status = read_basic_string_type_and_call(btr, false);
1028 break;
1029 default:
1030 abort();
1031 }
1032
1033 return status;
1034 }
1035
1036 static inline
1037 size_t bits_to_skip_to_align_to(struct bt_ctf_btr *btr, size_t align)
1038 {
1039 size_t aligned_packet_at;
1040
1041 aligned_packet_at = ALIGN(packet_at(btr), align);
1042
1043 return aligned_packet_at - packet_at(btr);
1044 }
1045
1046 static inline
1047 enum bt_ctf_btr_status align_type_state(struct bt_ctf_btr *btr,
1048 struct bt_ctf_field_type *field_type, enum btr_state next_state)
1049 {
1050 int field_alignment;
1051 size_t skip_bits;
1052 enum bt_ctf_btr_status status = BT_CTF_BTR_STATUS_OK;
1053
1054 /* Get field's alignment */
1055 field_alignment = bt_ctf_field_type_get_alignment(field_type);
1056 if (field_alignment < 0) {
1057 PERR("Failed to get type alignment\n");
1058 status = BT_CTF_BTR_STATUS_ERROR;
1059 goto end;
1060 }
1061
1062 /*
1063 * 0 means "undefined" for variants; what we really want is 1
1064 * (always aligned)
1065 */
1066 if (field_alignment == 0) {
1067 field_alignment = 1;
1068 }
1069
1070 /* Compute how many bits we need to skip */
1071 skip_bits = bits_to_skip_to_align_to(btr, field_alignment);
1072
1073 /* Nothing to skip? aligned */
1074 if (skip_bits == 0) {
1075 btr->state = next_state;
1076 goto end;
1077 }
1078
1079 /* Make sure there's at least one bit left */
1080 if (!at_least_one_bit_left(btr)) {
1081 status = BT_CTF_BTR_STATUS_EOF;
1082 goto end;
1083 }
1084
1085 /* Consume as many bits as possible in what's left */
1086 consume_bits(btr, MIN(available_bits(btr), skip_bits));
1087
1088 /* Are we done now? */
1089 skip_bits = bits_to_skip_to_align_to(btr, field_alignment);
1090
1091 if (skip_bits == 0) {
1092 /* Yes: go to next state */
1093 btr->state = next_state;
1094 goto end;
1095 } else {
1096 /* No: need more data */
1097 status = BT_CTF_BTR_STATUS_EOF;
1098 }
1099
1100 end:
1101 return status;
1102 }
1103
1104 static inline
1105 bool is_compound_type(struct bt_ctf_field_type *field_type)
1106 {
1107 enum bt_ctf_field_type_id id = bt_ctf_field_type_get_type_id(field_type);
1108
1109 return id == BT_CTF_FIELD_TYPE_ID_STRUCT || id == BT_CTF_FIELD_TYPE_ID_ARRAY ||
1110 id == BT_CTF_FIELD_TYPE_ID_SEQUENCE || id == BT_CTF_FIELD_TYPE_ID_VARIANT;
1111 }
1112
1113 static inline
1114 enum bt_ctf_btr_status next_field_state(struct bt_ctf_btr *btr)
1115 {
1116 int ret;
1117 struct stack_entry *top;
1118 struct bt_ctf_field_type *next_field_type = NULL;
1119 enum bt_ctf_btr_status status = BT_CTF_BTR_STATUS_OK;
1120
1121 if (stack_empty(btr->stack)) {
1122 goto end;
1123 }
1124
1125 top = stack_top(btr->stack);
1126
1127 /* Are we done with this base type? */
1128 while (top->index == top->base_len) {
1129 if (btr->user.cbs.types.compound_end) {
1130 status = btr->user.cbs.types.compound_end(
1131 top->base_type, btr->user.data);
1132 if (status != BT_CTF_BTR_STATUS_OK) {
1133 PERR("compound_end() user callback function failed\n");
1134 goto end;
1135 }
1136 }
1137
1138 stack_pop(btr->stack);
1139
1140 /* Are we done with the root type? */
1141 if (stack_empty(btr->stack)) {
1142 btr->state = BTR_STATE_DONE;
1143 goto end;
1144 }
1145
1146 top = stack_top(btr->stack);
1147 top->index++;
1148 }
1149
1150 /* Get next field's type */
1151 switch (bt_ctf_field_type_get_type_id(top->base_type)) {
1152 case BT_CTF_FIELD_TYPE_ID_STRUCT:
1153 ret = bt_ctf_field_type_structure_get_field(
1154 top->base_type, NULL, &next_field_type,
1155 top->index);
1156 if (ret) {
1157 next_field_type = NULL;
1158 }
1159 break;
1160 case BT_CTF_FIELD_TYPE_ID_ARRAY:
1161 next_field_type =
1162 bt_ctf_field_type_array_get_element_type(
1163 top->base_type);
1164 break;
1165 case BT_CTF_FIELD_TYPE_ID_SEQUENCE:
1166 next_field_type =
1167 bt_ctf_field_type_sequence_get_element_type(
1168 top->base_type);
1169 break;
1170 case BT_CTF_FIELD_TYPE_ID_VARIANT:
1171 /* Variant types are dynamic: query the user, he should know! */
1172 next_field_type =
1173 btr->user.cbs.query.get_variant_type(
1174 top->base_type, btr->user.data);
1175 break;
1176 default:
1177 break;
1178 }
1179
1180 if (!next_field_type) {
1181 PERR("Failed to get next field's type\n");
1182 status = BT_CTF_BTR_STATUS_ERROR;
1183 goto end;
1184 }
1185
1186 if (is_compound_type(next_field_type)) {
1187 if (btr->user.cbs.types.compound_begin) {
1188 status = btr->user.cbs.types.compound_begin(
1189 next_field_type, btr->user.data);
1190 if (status != BT_CTF_BTR_STATUS_OK) {
1191 PERR("compound_begin() user callback function failed\n");
1192 goto end;
1193 }
1194 }
1195
1196 ret = stack_push_with_len(btr, next_field_type);
1197 if (ret) {
1198 PERR("Failed to push compound type onto the stack\n");
1199 status = BT_CTF_BTR_STATUS_ERROR;
1200 goto end;
1201 }
1202
1203 /* Next state: align a compound type */
1204 btr->state = BTR_STATE_ALIGN_COMPOUND;
1205 } else {
1206 /* Replace current basic field type */
1207 BT_MOVE(btr->cur_basic_field_type, next_field_type);
1208
1209 /* Next state: align a basic type */
1210 btr->state = BTR_STATE_ALIGN_BASIC;
1211 }
1212
1213 end:
1214 BT_PUT(next_field_type);
1215
1216 return status;
1217 }
1218
1219 static inline
1220 enum bt_ctf_btr_status handle_state(struct bt_ctf_btr *btr)
1221 {
1222 enum bt_ctf_btr_status status = BT_CTF_BTR_STATUS_OK;
1223
1224 switch (btr->state) {
1225 case BTR_STATE_NEXT_FIELD:
1226 status = next_field_state(btr);
1227 break;
1228 case BTR_STATE_ALIGN_BASIC:
1229 status = align_type_state(btr, btr->cur_basic_field_type,
1230 BTR_STATE_READ_BASIC_BEGIN);
1231 break;
1232 case BTR_STATE_ALIGN_COMPOUND:
1233 status = align_type_state(btr, stack_top(btr->stack)->base_type,
1234 BTR_STATE_NEXT_FIELD);
1235 break;
1236 case BTR_STATE_READ_BASIC_BEGIN:
1237 status = read_basic_begin_state(btr);
1238 break;
1239 case BTR_STATE_READ_BASIC_CONTINUE:
1240 status = read_basic_continue_state(btr);
1241 break;
1242 case BTR_STATE_DONE:
1243 break;
1244 }
1245
1246 return status;
1247 }
1248
1249 struct bt_ctf_btr *bt_ctf_btr_create(struct bt_ctf_btr_cbs cbs, void *data,
1250 FILE *err_stream)
1251 {
1252 struct bt_ctf_btr *btr;
1253
1254 btr = g_new0(struct bt_ctf_btr, 1);
1255 if (!btr) {
1256 PERR("Failed to allocate memory for binary type reader\n");
1257 goto end;
1258 }
1259
1260 btr->stack = stack_new();
1261 if (!btr->stack) {
1262 PERR("Failed to create stack\n");
1263 bt_ctf_btr_destroy(btr);
1264 btr = NULL;
1265 goto end;
1266 }
1267
1268 btr->state = BTR_STATE_NEXT_FIELD;
1269 btr->user.cbs = cbs;
1270 btr->user.data = data;
1271 btr->err_stream = err_stream;
1272
1273 end:
1274 return btr;
1275 }
1276
1277 void bt_ctf_btr_destroy(struct bt_ctf_btr *btr)
1278 {
1279 if (btr->stack) {
1280 stack_destroy(btr->stack);
1281 }
1282
1283 BT_PUT(btr->cur_basic_field_type);
1284 g_free(btr);
1285 }
1286
1287 static
1288 void reset(struct bt_ctf_btr *btr)
1289 {
1290 stack_clear(btr->stack);
1291 BT_PUT(btr->cur_basic_field_type);
1292 stitch_reset(btr);
1293 btr->buf.addr = NULL;
1294 btr->last_bo = BT_CTF_BYTE_ORDER_UNKNOWN;
1295 }
1296
1297 size_t bt_ctf_btr_start(struct bt_ctf_btr *btr,
1298 struct bt_ctf_field_type *type, const uint8_t *buf,
1299 size_t offset, size_t packet_offset, size_t sz,
1300 enum bt_ctf_btr_status *status)
1301 {
1302 assert(btr);
1303 assert(buf);
1304 assert(sz > 0);
1305 assert(BYTES_TO_BITS(sz) > offset);
1306 reset(btr);
1307 btr->buf.addr = buf;
1308 btr->buf.offset = offset;
1309 btr->buf.at = 0;
1310 btr->buf.packet_offset = packet_offset;
1311 btr->buf.buf_sz = sz;
1312 btr->buf.sz = BYTES_TO_BITS(sz) - offset;
1313 *status = BT_CTF_BTR_STATUS_OK;
1314
1315 /* Set root type */
1316 if (is_compound_type(type)) {
1317 /* Compound type: push on visit stack */
1318 int stack_ret;
1319
1320 if (btr->user.cbs.types.compound_begin) {
1321 *status = btr->user.cbs.types.compound_begin(
1322 type, btr->user.data);
1323 if (*status != BT_CTF_BTR_STATUS_OK) {
1324 PERR("compound_begin() user callback function failed\n");
1325 goto end;
1326 }
1327 }
1328
1329 stack_ret = stack_push_with_len(btr, type);
1330 if (stack_ret) {
1331 PERR("Failed to push initial compound type onto the stack\n");
1332 *status = BT_CTF_BTR_STATUS_ERROR;
1333 goto end;
1334 }
1335
1336 btr->state = BTR_STATE_ALIGN_COMPOUND;
1337 } else {
1338 /* Basic type: set as current basic type */
1339 btr->cur_basic_field_type = type;
1340 bt_get(btr->cur_basic_field_type);
1341 btr->state = BTR_STATE_ALIGN_BASIC;
1342 }
1343
1344 /* Run the machine! */
1345 while (true) {
1346 *status = handle_state(btr);
1347 if (*status != BT_CTF_BTR_STATUS_OK) {
1348 break;
1349 } else if (btr->state == BTR_STATE_DONE) {
1350 break;
1351 }
1352 }
1353
1354 /* Update packet offset for next time */
1355 btr->buf.packet_offset += btr->buf.at;
1356
1357 end:
1358 return btr->buf.at;
1359 }
1360
1361 size_t bt_ctf_btr_continue(struct bt_ctf_btr *btr,
1362 const uint8_t *buf, size_t sz,
1363 enum bt_ctf_btr_status *status)
1364 {
1365 assert(btr);
1366 assert(buf);
1367 assert(sz > 0);
1368 btr->buf.addr = buf;
1369 btr->buf.offset = 0;
1370 btr->buf.at = 0;
1371 btr->buf.buf_sz = sz;
1372 btr->buf.sz = BYTES_TO_BITS(sz);
1373 *status = BT_CTF_BTR_STATUS_OK;
1374
1375 /* Continue running the machine */
1376 while (true) {
1377 *status = handle_state(btr);
1378 if (*status != BT_CTF_BTR_STATUS_OK) {
1379 break;
1380 } else if (btr->state == BTR_STATE_DONE) {
1381 break;
1382 }
1383 }
1384
1385 /* Update packet offset for next time */
1386 btr->buf.packet_offset += btr->buf.at;
1387
1388 return btr->buf.at;
1389 }
This page took 0.077845 seconds and 5 git commands to generate.