+
+static
+struct lttng_userspace_probe_location *
+process_userspace_probe_function_attribute_node(
+ xmlNodePtr attribute_node)
+{
+ xmlChar *content;
+ xmlNodePtr function_attribute_node;
+ char *function_name = NULL, *binary_path = NULL, *lookup_method_name;
+ struct lttng_userspace_probe_location *location = NULL;
+ struct lttng_userspace_probe_location_lookup_method *lookup_method = NULL;
+
+ /*
+ * Process userspace probe location function attributes. The order of
+ * the fields are not guaranteed so we need to iterate over all fields
+ * and check at the end if everything we need for this location type is
+ * there.
+ */
+ for (function_attribute_node =
+ xmlFirstElementChild(attribute_node);
+ function_attribute_node;
+ function_attribute_node = xmlNextElementSibling(
+ function_attribute_node)) {
+ /* Handle function name, binary path and lookup method. */
+ if (!strcmp((const char *) function_attribute_node->name,
+ config_element_userspace_probe_function_location_function_name)) {
+ content = xmlNodeGetContent(function_attribute_node);
+ if (!content) {
+ goto error;
+ }
+
+ function_name = lttng_strndup((char *) content, LTTNG_SYMBOL_NAME_LEN);
+ free(content);
+ if (!function_name) {
+ PERROR("Error duplicating function name");
+ goto error;
+ }
+ } else if (!strcmp((const char *) function_attribute_node->name,
+ config_element_userspace_probe_location_binary_path)) {
+ content = xmlNodeGetContent(function_attribute_node);
+ if (!content) {
+ goto error;
+ }
+
+ binary_path = lttng_strndup((char *) content, LTTNG_PATH_MAX);
+ free(content);
+ if (!binary_path) {
+ PERROR("Error duplicating binary path");
+ goto error;
+ }
+ } else if (!strcmp((const char *) function_attribute_node->name,
+ config_element_userspace_probe_lookup)) {
+ content = xmlNodeGetContent(function_attribute_node);
+ if (!content) {
+ goto error;
+ }
+
+ lookup_method_name = lttng_strndup((char *) content,
+ CONFIG_USERSPACE_PROBE_LOOKUP_METHOD_NAME_MAX_LEN);
+ free(content);
+ if (!lookup_method_name) {
+ PERROR("Error duplicating lookup method name");
+ goto error;
+ }
+
+ /*
+ * function_default lookup method defaults to
+ * function_elf lookup method at the moment.
+ */
+ if (!strcmp(lookup_method_name, config_element_userspace_probe_lookup_function_elf)
+ || !strcmp(lookup_method_name, config_element_userspace_probe_lookup_function_default)) {
+ lookup_method = lttng_userspace_probe_location_lookup_method_function_elf_create();
+ if (!lookup_method) {
+ PERROR("Error creating function default/ELF lookup method");
+ free(lookup_method_name);
+ goto error;
+ }
+ } else {
+ WARN("Unknown function lookup method.");
+ free(lookup_method_name);
+ goto error;
+ }
+ } else {
+ goto error;
+ }
+
+ /* Check if all the necessary fields were found. */
+ if (binary_path && function_name && lookup_method) {
+ location =
+ lttng_userspace_probe_location_function_create(
+ binary_path, function_name,
+ lookup_method);
+ goto end;
+ }
+ }
+error:
+ free(binary_path);
+ free(function_name);
+ if (lookup_method) {
+ lttng_userspace_probe_location_lookup_method_destroy(lookup_method);
+ }
+end:
+ return location;
+}
+
+static
+struct lttng_userspace_probe_location *
+process_userspace_probe_tracepoint_attribute_node(
+ xmlNodePtr attribute_node)
+{
+ xmlChar *content;
+ xmlNodePtr tracepoint_attribute_node;
+ char *lookup_method_name = NULL;
+ char *probe_name = NULL, *provider_name = NULL, *binary_path = NULL;
+ struct lttng_userspace_probe_location *location = NULL;
+ struct lttng_userspace_probe_location_lookup_method *lookup_method = NULL;
+
+ /*
+ * Process userspace probe location tracepoint attributes. The order of
+ * the fields are not guaranteed so we need to iterate over all fields
+ * and check at the end if everything we need for this location type is
+ * there.
+ */
+ for (tracepoint_attribute_node =
+ xmlFirstElementChild(attribute_node); tracepoint_attribute_node;
+ tracepoint_attribute_node = xmlNextElementSibling(
+ tracepoint_attribute_node)) {
+ if (!strcmp((const char *) tracepoint_attribute_node->name,
+ config_element_userspace_probe_tracepoint_location_probe_name)) {
+ content = xmlNodeGetContent(tracepoint_attribute_node);
+ if (!content) {
+ goto error;
+ }
+
+ probe_name = lttng_strndup((char*) content, LTTNG_SYMBOL_NAME_LEN);
+ free(content);
+ if (!probe_name) {
+ PERROR("Error duplicating probe name");
+ goto error;
+ }
+ } else if (!strcmp((const char *) tracepoint_attribute_node->name,
+ config_element_userspace_probe_tracepoint_location_provider_name)) {
+ content = xmlNodeGetContent(tracepoint_attribute_node);
+ if (!content) {
+ goto error;
+ }
+
+ provider_name = lttng_strndup((char*) content, LTTNG_SYMBOL_NAME_LEN);
+ free(content);
+ if (!provider_name) {
+ PERROR("Error duplicating provider name");
+ goto error;
+ }
+ } else if (!strcmp((const char *) tracepoint_attribute_node->name,
+ config_element_userspace_probe_location_binary_path)) {
+ content = xmlNodeGetContent(tracepoint_attribute_node);
+ if (!content) {
+ goto error;
+ }
+
+ binary_path = lttng_strndup((char*) content, LTTNG_PATH_MAX);
+
+ free(content);
+
+ if (!binary_path) {
+ PERROR("Error duplicating binary path");
+ goto error;
+ }
+ } else if (!strcmp((const char *) tracepoint_attribute_node->name,
+ config_element_userspace_probe_lookup)) {
+ content = xmlNodeGetContent(tracepoint_attribute_node);
+ if (!content) {
+ goto error;
+ }
+
+ lookup_method_name = lttng_strndup((char *) content,
+ CONFIG_USERSPACE_PROBE_LOOKUP_METHOD_NAME_MAX_LEN);
+ free(content);
+
+ if (!lookup_method_name) {
+ PERROR("Error duplicating lookup method name");
+ goto error;
+ }
+
+ if (!strcmp(lookup_method_name,
+ config_element_userspace_probe_lookup_tracepoint_sdt)) {
+ lookup_method =
+ lttng_userspace_probe_location_lookup_method_tracepoint_sdt_create();
+ if (!lookup_method) {
+ PERROR("Error creating tracepoint SDT lookup method");
+ free(lookup_method_name);
+ goto error;
+ }
+ } else {
+ WARN("Unknown tracepoint lookup method.");
+ goto error;
+ }
+ } else {
+ WARN("Unknown tracepoint attribute.");
+ goto error;
+ }
+
+ /* Check if all the necessary fields were found. */
+ if (binary_path && provider_name && probe_name && lookup_method) {
+ location =
+ lttng_userspace_probe_location_tracepoint_create(
+ binary_path, provider_name,
+ probe_name, lookup_method);
+ goto end;
+ }
+ }
+error:
+ free(binary_path);
+ free(probe_name);
+ free(provider_name);
+ if (lookup_method) {
+ lttng_userspace_probe_location_lookup_method_destroy(lookup_method);
+ }
+end:
+ return location;
+}
+