parse-regs-options.c (1933B)
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 = 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 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#ifdef HAVE_PERF_REGS_SUPPORT 50 for (r = sample_reg_masks; r->name; r++) { 51 if (r->mask & mask) 52 fprintf(stderr, "%s ", r->name); 53 } 54#endif 55 fputc('\n', stderr); 56 /* just printing available regs */ 57 goto error; 58 } 59#ifdef HAVE_PERF_REGS_SUPPORT 60 for (r = sample_reg_masks; r->name; r++) { 61 if ((r->mask & mask) && !strcasecmp(s, r->name)) 62 break; 63 } 64#endif 65 if (!r || !r->name) { 66 ui__warning("Unknown register \"%s\", check man page or run \"perf record %s?\"\n", 67 s, intr ? "-I" : "--user-regs="); 68 goto error; 69 } 70 71 *mode |= r->mask; 72 73 if (!p) 74 break; 75 76 s = p + 1; 77 } 78 } 79 ret = 0; 80 81 /* default to all possible regs */ 82 if (*mode == 0) 83 *mode = mask; 84error: 85 free(os); 86 return ret; 87} 88 89int 90parse_user_regs(const struct option *opt, const char *str, int unset) 91{ 92 return __parse_regs(opt, str, unset, false); 93} 94 95int 96parse_intr_regs(const struct option *opt, const char *str, int unset) 97{ 98 return __parse_regs(opt, str, unset, true); 99}