- free(cmd_header);
- cmd_header = NULL;
-
- /*
- * The buffer that is returned must contain a "flat" version of
- * the events that are returned. In other words, all pointers
- * within an lttng_event must point to a location within the returned
- * buffer so that the user may free everything by simply calling free()
- * on the returned buffer. This is needed in order to maintain API
- * compatibility.
- *
- * A first pass is performed to compute the size of the buffer that
- * must be allocated. A second pass is then performed to setup
- * the returned events so that their members always point within the
- * buffer.
- *
- * The layout of the returned buffer is as follows:
- * - struct lttng_event[nb_events],
- * - nb_events times the following:
- * - struct lttng_event_extended,
- * - flattened version of userspace_probe_location
- * - filter_expression
- * - exclusions
- * - padding to align to 64-bits
- */
- comm_ext_at = reception_buffer +
- (nb_events * sizeof(struct lttng_event));
- storage_req = nb_events * sizeof(struct lttng_event);
-
- for (i = 0; i < nb_events; i++) {
- struct lttcomm_event_extended_header *ext_comm =
- (struct lttcomm_event_extended_header *) comm_ext_at;
- int probe_storage_req = 0;
-
- comm_ext_at += sizeof(*ext_comm);
- comm_ext_at += ext_comm->filter_len;
- comm_ext_at +=
- ext_comm->nb_exclusions * LTTNG_SYMBOL_NAME_LEN;
-
- if (ext_comm->userspace_probe_location_len) {
- struct lttng_userspace_probe_location *probe_location = NULL;
- struct lttng_buffer_view probe_location_view;
-
- probe_location_view = lttng_buffer_view_init(
- comm_ext_at, 0,
- ext_comm->userspace_probe_location_len);
-
- /*
- * Create a temporary userspace probe location to
- * determine the size needed by a "flattened" version
- * of that same probe location.
- */
- ret = lttng_userspace_probe_location_create_from_buffer(
- &probe_location_view, &probe_location);
- if (ret < 0) {
- ret = -LTTNG_ERR_PROBE_LOCATION_INVAL;
- goto end;
- }
-
- ret = lttng_userspace_probe_location_flatten(
- probe_location, NULL);
- lttng_userspace_probe_location_destroy(probe_location);
- if (ret < 0) {
- ret = -LTTNG_ERR_PROBE_LOCATION_INVAL;
- goto end;
- }
-
- probe_storage_req = ret;
- comm_ext_at += ext_comm->userspace_probe_location_len;
- }
-
- storage_req += sizeof(struct lttng_event_extended);
- storage_req += ext_comm->filter_len;
- storage_req += ext_comm->nb_exclusions * LTTNG_SYMBOL_NAME_LEN;
- /* Padding to ensure the flat probe is aligned. */
- storage_req = ALIGN_TO(storage_req, sizeof(uint64_t));
- storage_req += probe_storage_req;
- }
-
- 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;
- }
-
- ret = lttng_dynamic_buffer_append(&listing, reception_buffer,
- nb_events * sizeof(struct lttng_event));
- if (ret) {
- ret = -LTTNG_ERR_NOMEM;
- goto free_dynamic_buffer;
- }
-
- comm_ext_at = reception_buffer +
- (nb_events * sizeof(struct lttng_event));
- for (i = 0; i < nb_events; i++) {
- struct lttng_event *event = (struct lttng_event *)
- (listing.data + (sizeof(struct lttng_event) * i));
- struct lttcomm_event_extended_header *ext_comm =
- (struct lttcomm_event_extended_header *) comm_ext_at;
- struct lttng_event_extended *event_extended =
- (struct lttng_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,
- ALIGN_TO(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_buffer_view probe_location_view;