123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899 |
- // SPDX-License-Identifier: GPL-2.0
- #include <stdbool.h>
- #include <stdlib.h>
- #include <stdint.h>
- #include <string.h>
- #include <stdio.h>
- #include "util/debug.h"
- #include <subcmd/parse-options.h>
- #include "util/perf_regs.h"
- #include "util/parse-regs-options.h"
- static int
- __parse_regs(const struct option *opt, const char *str, int unset, bool intr)
- {
- uint64_t *mode = (uint64_t *)opt->value;
- const struct sample_reg *r = NULL;
- char *s, *os = NULL, *p;
- int ret = -1;
- uint64_t mask;
- if (unset)
- return 0;
- /*
- * cannot set it twice
- */
- if (*mode)
- return -1;
- if (intr)
- mask = arch__intr_reg_mask();
- else
- mask = arch__user_reg_mask();
- /* str may be NULL in case no arg is passed to -I */
- if (str) {
- /* because str is read-only */
- s = os = strdup(str);
- if (!s)
- return -1;
- for (;;) {
- p = strchr(s, ',');
- if (p)
- *p = '\0';
- if (!strcmp(s, "?")) {
- fprintf(stderr, "available registers: ");
- #ifdef HAVE_PERF_REGS_SUPPORT
- for (r = sample_reg_masks; r->name; r++) {
- if (r->mask & mask)
- fprintf(stderr, "%s ", r->name);
- }
- #endif
- fputc('\n', stderr);
- /* just printing available regs */
- goto error;
- }
- #ifdef HAVE_PERF_REGS_SUPPORT
- for (r = sample_reg_masks; r->name; r++) {
- if ((r->mask & mask) && !strcasecmp(s, r->name))
- break;
- }
- #endif
- if (!r || !r->name) {
- ui__warning("Unknown register \"%s\", check man page or run \"perf record %s?\"\n",
- s, intr ? "-I" : "--user-regs=");
- goto error;
- }
- *mode |= r->mask;
- if (!p)
- break;
- s = p + 1;
- }
- }
- ret = 0;
- /* default to all possible regs */
- if (*mode == 0)
- *mode = mask;
- error:
- free(os);
- return ret;
- }
- int
- parse_user_regs(const struct option *opt, const char *str, int unset)
- {
- return __parse_regs(opt, str, unset, false);
- }
- int
- parse_intr_regs(const struct option *opt, const char *str, int unset)
- {
- return __parse_regs(opt, str, unset, true);
- }
|