Files
linux-cryptodev-2.6/tools/perf/util/parse-regs-options.c
Dapeng Mi 16dccbb842 perf regs: Remove __weak attributive arch__xxx_reg_mask() functions
Currently, some architecture-specific perf-regs functions, such as
arch__intr_reg_mask() and arch__user_reg_mask(), are defined with the
__weak attribute.

This approach ensures that only functions matching the architecture of
the build/run host are compiled and executed, reducing build time and
binary size.

However, this __weak attribute restricts these functions to be called
only on the same architecture, preventing cross-architecture
functionality.

For example, a perf.data file captured on x86 cannot be parsed on an ARM
platform.

To address this limitation, this patch removes the __weak attribute from
these perf-regs functions.

The architecture-specific code is moved from the arch/ directory to the
util/perf-regs-arch/ directory.

The appropriate architectural functions are then called based on the
EM_HOST.

No functional changes are intended.

Suggested-by: Ian Rogers <irogers@google.com>
Reviewed-by: Ian Rogers <irogers@google.com>
Signed-off-by: Dapeng Mi <dapeng1.mi@linux.intel.com>
Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: Albert Ou <aou@eecs.berkeley.edu>
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Cc: Alexandre Ghiti <alex@ghiti.fr>
Cc: Guo Ren <guoren@kernel.org>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: James Clark <james.clark@linaro.org>
Cc: John Garry <john.g.garry@oracle.com>
Cc: Mike Leach <mike.leach@linaro.org>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Palmer Dabbelt <palmer@dabbelt.com>
Cc: Paul Walmsley <pjw@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Thomas Falcon <thomas.falcon@intel.com>
Cc: Will Deacon <will@kernel.org>
Cc: Xudong Hao <xudong.hao@intel.com>
Cc: Zide Chen <zide.chen@intel.com>
[ Fixed up somme fuzz with s390 and riscv Build files wrt removing perf_regs.o ]
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2026-02-06 12:16:09 -03:00

125 lines
2.3 KiB
C

// 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 <dwarf-regs.h>
#include <subcmd/parse-options.h>
#include "util/perf_regs.h"
#include "util/parse-regs-options.h"
static void list_perf_regs(FILE *fp, uint64_t mask)
{
const char *last_name = NULL;
fprintf(fp, "available registers: ");
for (int reg = 0; reg < 64; reg++) {
const char *name;
if (((1ULL << reg) & mask) == 0)
continue;
name = perf_reg_name(reg, EM_HOST, EF_HOST);
if (name && (!last_name || strcmp(last_name, name)))
fprintf(fp, "%s%s", reg > 0 ? " " : "", name);
last_name = name;
}
fputc('\n', fp);
}
static uint64_t name_to_perf_reg_mask(const char *to_match, uint64_t mask)
{
uint64_t reg_mask = 0;
for (int reg = 0; reg < 64; reg++) {
const char *name;
if (((1ULL << reg) & mask) == 0)
continue;
name = perf_reg_name(reg, EM_HOST, EF_HOST);
if (!name)
continue;
if (!strcasecmp(to_match, name))
reg_mask |= 1ULL << reg;
}
return reg_mask;
}
static int
__parse_regs(const struct option *opt, const char *str, int unset, bool intr)
{
uint64_t *mode = (uint64_t *)opt->value;
char *s, *os = NULL, *p;
int ret = -1;
uint64_t mask;
if (unset)
return 0;
/*
* cannot set it twice
*/
if (*mode)
return -1;
mask = intr ? perf_intr_reg_mask(EM_HOST) : perf_user_reg_mask(EM_HOST);
/* str may be NULL in case no arg is passed to -I */
if (!str) {
*mode = mask;
return 0;
}
/* because str is read-only */
s = os = strdup(str);
if (!s)
return -1;
for (;;) {
uint64_t reg_mask;
p = strchr(s, ',');
if (p)
*p = '\0';
if (!strcmp(s, "?")) {
list_perf_regs(stderr, mask);
goto error;
}
reg_mask = name_to_perf_reg_mask(s, mask);
if (reg_mask == 0) {
ui__warning("Unknown register \"%s\", check man page or run \"perf record %s?\"\n",
s, intr ? "-I" : "--user-regs=");
goto error;
}
*mode |= reg_mask;
if (!p)
break;
s = p + 1;
}
ret = 0;
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);
}