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