cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

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}