linux/tools/perf/util/parse-regs-options.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0
   2#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 int
  13__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;
  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 twice
  26         */
  27        if (*mode)
  28                return -1;
  29
  30        if (intr)
  31                mask = arch__intr_reg_mask();
  32        else
  33                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 = 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                                return -1;
  56                        }
  57                        for (r = sample_reg_masks; r->name; r++) {
  58                                if ((r->mask & mask) && !strcasecmp(s, r->name))
  59                                        break;
  60                        }
  61                        if (!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
  85int
  86parse_user_regs(const struct option *opt, const char *str, int unset)
  87{
  88        return __parse_regs(opt, str, unset, false);
  89}
  90
  91int
  92parse_intr_regs(const struct option *opt, const char *str, int unset)
  93{
  94        return __parse_regs(opt, str, unset, true);
  95}
  96