+/*
+ * parse_probe_addr
+ *
+ * Parse probe options.
+ */
+static int parse_probe_opts(struct lttng_event *ev, char *opt)
+{
+ int ret;
+ char s_hex[19];
+ char name[LTTNG_SYMBOL_NAME_LEN];
+
+ if (opt == NULL) {
+ ret = -1;
+ goto end;
+ }
+
+ /* Check for symbol+offset */
+ ret = sscanf(opt, "%[^'+']+%s", name, s_hex);
+ if (ret == 2) {
+ strncpy(ev->attr.probe.symbol_name, name, LTTNG_SYMBOL_NAME_LEN);
+ DBG("probe symbol %s", ev->attr.probe.symbol_name);
+ if (strlen(s_hex) == 0) {
+ ERR("Invalid probe offset %s", s_hex);
+ ret = -1;
+ goto end;
+ }
+ ev->attr.probe.offset = strtoul(s_hex, NULL, 0);
+ DBG("probe offset %" PRIu64, ev->attr.probe.offset);
+ ev->attr.probe.addr = 0;
+ goto end;
+ }
+
+ /* Check for symbol */
+ if (isalpha(name[0])) {
+ ret = sscanf(opt, "%s", name);
+ if (ret == 1) {
+ strncpy(ev->attr.probe.symbol_name, name, LTTNG_SYMBOL_NAME_LEN);
+ DBG("probe symbol %s", ev->attr.probe.symbol_name);
+ ev->attr.probe.offset = 0;
+ DBG("probe offset %" PRIu64, ev->attr.probe.offset);
+ ev->attr.probe.addr = 0;
+ goto end;
+ }
+ }
+
+ /* Check for address */
+ ret = sscanf(opt, "%s", s_hex);
+ if (ret > 0) {
+ if (strlen(s_hex) == 0) {
+ ERR("Invalid probe address %s", s_hex);
+ ret = -1;
+ goto end;
+ }
+ ev->attr.probe.addr = strtoul(s_hex, NULL, 0);
+ DBG("probe addr %" PRIu64, ev->attr.probe.addr);
+ ev->attr.probe.offset = 0;
+ memset(ev->attr.probe.symbol_name, 0, LTTNG_SYMBOL_NAME_LEN);
+ goto end;
+ }
+
+ /* No match */
+ ret = -1;
+
+end:
+ return ret;
+}
+