+ lttng_dynamic_buffer_init(&listing);
+ /*
+ * We must ensure that "listing" is never resized so as to preserve
+ * the validity of the flattened objects.
+ */
+ ret = lttng_dynamic_buffer_set_capacity(&listing, storage_req);
+ if (ret) {
+ ret = -LTTNG_ERR_NOMEM;
+ goto end;
+ }
+
+ cmd_payload_view = lttng_buffer_view_from_dynamic_buffer(
+ &payload_copy.buffer, sizeof(*cmd_header), -1);
+ flat_events_view = lttng_buffer_view_from_view(&cmd_payload_view, 0,
+ nb_events * sizeof(struct lttng_event));
+ ret = lttng_dynamic_buffer_append_view(&listing, &flat_events_view);
+ if (ret) {
+ ret = -LTTNG_ERR_NOMEM;
+ goto free_dynamic_buffer;
+ }
+
+ ext_view = lttng_buffer_view_from_view(&cmd_payload_view,
+ nb_events * sizeof(struct lttng_event), -1);
+ comm_ext_at = ext_view.data;
+
+ {
+ struct lttng_payload_view payload_copy_view =
+ lttng_payload_view_from_payload(
+ &payload_copy, 0, -1);
+
+ for (i = 0; i < nb_events; i++) {
+ struct lttng_event *event = (typeof(event))(
+ listing.data +
+ (sizeof(struct lttng_event) * i));
+ const struct lttcomm_event_extended_header *ext_comm =
+ (typeof(ext_comm)) comm_ext_at;
+ struct lttng_event_extended *event_extended =
+ (typeof(event_extended))(listing.data +
+ listing.size);
+
+ /* Insert struct lttng_event_extended. */
+ ret = lttng_dynamic_buffer_set_size(&listing,
+ listing.size + sizeof(*event_extended));
+ if (ret) {
+ ret = -LTTNG_ERR_NOMEM;
+ goto free_dynamic_buffer;
+ }
+ event->extended.ptr = event_extended;
+
+ comm_ext_at += sizeof(*ext_comm);
+
+ /* Insert filter expression. */
+ if (ext_comm->filter_len) {
+ event_extended->filter_expression =
+ listing.data + listing.size;
+ ret = lttng_dynamic_buffer_append(&listing,
+ comm_ext_at,
+ ext_comm->filter_len);
+ if (ret) {
+ ret = -LTTNG_ERR_NOMEM;
+ goto free_dynamic_buffer;
+ }
+ comm_ext_at += ext_comm->filter_len;
+ }
+
+ /* Insert exclusions. */
+ if (ext_comm->nb_exclusions) {
+ event_extended->exclusions.count =
+ ext_comm->nb_exclusions;
+ event_extended->exclusions.strings =
+ listing.data + listing.size;
+
+ ret = lttng_dynamic_buffer_append(&listing,
+ comm_ext_at,
+ ext_comm->nb_exclusions *
+ LTTNG_SYMBOL_NAME_LEN);
+ if (ret) {
+ ret = -LTTNG_ERR_NOMEM;
+ goto free_dynamic_buffer;
+ }
+ comm_ext_at += ext_comm->nb_exclusions *
+ LTTNG_SYMBOL_NAME_LEN;
+ }
+
+ /* Insert padding to align to 64-bits. */
+ ret = lttng_dynamic_buffer_set_size(&listing,
+ lttng_align_ceil(listing.size,
+ sizeof(uint64_t)));
+ if (ret) {
+ ret = -LTTNG_ERR_NOMEM;
+ goto free_dynamic_buffer;
+ }
+
+ /* Insert flattened userspace probe location. */
+ if (ext_comm->userspace_probe_location_len) {
+ struct lttng_userspace_probe_location
+ *probe_location = NULL;
+ struct lttng_payload_view probe_location_view = lttng_payload_view_from_view(
+ &payload_copy_view,
+ (const char *) comm_ext_at -
+ payload_copy_view.buffer.data,
+ ext_comm->userspace_probe_location_len);
+
+ if (!lttng_payload_view_is_valid(&probe_location_view)) {
+ ret = -LTTNG_ERR_PROBE_LOCATION_INVAL;
+ goto free_dynamic_buffer;
+ }
+
+ ret = lttng_userspace_probe_location_create_from_payload(
+ &probe_location_view,
+ &probe_location);
+ if (ret < 0) {
+ ret = -LTTNG_ERR_PROBE_LOCATION_INVAL;
+ goto free_dynamic_buffer;
+ }
+
+ event_extended->probe_location = (struct lttng_userspace_probe_location
+ *) (listing.data +
+ listing.size);
+ ret = lttng_userspace_probe_location_flatten(
+ probe_location, &listing);
+ lttng_userspace_probe_location_destroy(
+ probe_location);
+ if (ret < 0) {
+ ret = -LTTNG_ERR_PROBE_LOCATION_INVAL;
+ goto free_dynamic_buffer;
+ }
+
+ comm_ext_at += ext_comm->userspace_probe_location_len;
+ }
+ }
+ }
+
+ /* Don't reset listing buffer as we return its content. */
+ *events = (struct lttng_event *) listing.data;
+ lttng_dynamic_buffer_init(&listing);
+ ret = (int) nb_events;
+free_dynamic_buffer:
+ lttng_dynamic_buffer_reset(&listing);
+end:
+ lttng_payload_reset(&payload);
+ lttng_payload_reset(&payload_copy);