96 lines · c
1// SPDX-License-Identifier: GPL-2.02#include <stdbool.h>3#include <stdlib.h>4#include <stdint.h>5#include <string.h>6#include <stdio.h>7#include "util/debug.h"8#include <subcmd/parse-options.h>9#include "util/perf_regs.h"10#include "util/parse-regs-options.h"11 12static int13__parse_regs(const struct option *opt, const char *str, int unset, bool intr)14{15 uint64_t *mode = (uint64_t *)opt->value;16 const struct sample_reg *r = NULL;17 char *s, *os = NULL, *p;18 int ret = -1;19 uint64_t mask;20 21 if (unset)22 return 0;23 24 /*25 * cannot set it twice26 */27 if (*mode)28 return -1;29 30 if (intr)31 mask = arch__intr_reg_mask();32 else33 mask = arch__user_reg_mask();34 35 /* str may be NULL in case no arg is passed to -I */36 if (str) {37 /* because str is read-only */38 s = os = strdup(str);39 if (!s)40 return -1;41 42 for (;;) {43 p = strchr(s, ',');44 if (p)45 *p = '\0';46 47 if (!strcmp(s, "?")) {48 fprintf(stderr, "available registers: ");49 for (r = arch__sample_reg_masks(); r->name; r++) {50 if (r->mask & mask)51 fprintf(stderr, "%s ", r->name);52 }53 fputc('\n', stderr);54 /* just printing available regs */55 goto error;56 }57 for (r = arch__sample_reg_masks(); r->name; r++) {58 if ((r->mask & mask) && !strcasecmp(s, r->name))59 break;60 }61 if (!r || !r->name) {62 ui__warning("Unknown register \"%s\", check man page or run \"perf record %s?\"\n",63 s, intr ? "-I" : "--user-regs=");64 goto error;65 }66 67 *mode |= r->mask;68 69 if (!p)70 break;71 72 s = p + 1;73 }74 }75 ret = 0;76 77 /* default to all possible regs */78 if (*mode == 0)79 *mode = mask;80error:81 free(os);82 return ret;83}84 85int86parse_user_regs(const struct option *opt, const char *str, int unset)87{88 return __parse_regs(opt, str, unset, false);89}90 91int92parse_intr_regs(const struct option *opt, const char *str, int unset)93{94 return __parse_regs(opt, str, unset, true);95}96