Commit cf7c7f12 authored by Ian Rogers's avatar Ian Rogers Committed by Arnaldo Carvalho de Melo
Browse files

perf dwarf-regs: Add basic get_dwarf_regnum() for most architectures



Add a basic get_dwarf_regnum() implementation for most architectures by
using the get_dwarf_regstr() tables and returning the index of the name
within the table.

Some minor name and constification clean up for csky.

Signed-off-by: default avatarIan Rogers <irogers@google.com>
Cc: Aditya Bodkhe <aditya.b1@linux.ibm.com>
Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: Albert Ou <aou@eecs.berkeley.edu>
Cc: Alexandre Ghiti <alex@ghiti.fr>
Cc: Andi Kleen <ak@linux.intel.com>
Cc: Athira Rajeev <atrajeev@linux.ibm.com>
Cc: Chun-Tse Shao <ctshao@google.com>
Cc: Dmitriy Vyukov <dvyukov@google.com>
Cc: Dr. David Alan Gilbert <linux@treblig.org>
Cc: Guo Ren <guoren@kernel.org>
Cc: Haibo Xu <haibo1.xu@intel.com>
Cc: Howard Chu <howardchu95@gmail.com>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: James Clark <james.clark@linaro.org>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: John Garry <john.g.garry@oracle.com>
Cc: Krzysztof Łopatowski <krzysztof.m.lopatowski@gmail.com>
Cc: Leo Yan <leo.yan@linux.dev>
Cc: Mark Wielaard <mark@klomp.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: Sergei Trofimovich <slyich@gmail.com>
Cc: Shimin Guo <shimin.guo@skydio.com>
Cc: Stephen Brennan <stephen.s.brennan@oracle.com>
Cc: Thomas Falcon <thomas.falcon@intel.com>
Cc: Will Deacon <will@kernel.org>
Signed-off-by: default avatarArnaldo Carvalho de Melo <acme@redhat.com>
parent d3ab52c3
Loading
Loading
Loading
Loading
+21 −3
Original line number Diff line number Diff line
@@ -2,11 +2,12 @@
// Copyright (C) 2019 Hangzhou C-SKY Microsystems co.,ltd.
// Mapping of DWARF debug register numbers into register names.

#include <errno.h>
#include <stddef.h>
#include <dwarf-regs.h>

#define CSKY_ABIV2_MAX_REGS 73
const char *csky_dwarf_regs_table_abiv2[CSKY_ABIV2_MAX_REGS] = {
static const char * const csky_dwarf_regs_table_abiv2[CSKY_ABIV2_MAX_REGS] = {
	/* r0 ~ r8 */
	"%a0", "%a1", "%a2", "%a3", "%regs0", "%regs1", "%regs2", "%regs3",
	/* r9 ~ r15 */
@@ -27,7 +28,7 @@ const char *csky_dwarf_regs_table_abiv2[CSKY_ABIV2_MAX_REGS] = {
};

#define CSKY_ABIV1_MAX_REGS 57
const char *csky_dwarf_regs_table_abiv1[CSKY_ABIV1_MAX_REGS] = {
static const char * const csky_dwarf_regs_table_abiv1[CSKY_ABIV1_MAX_REGS] = {
	/* r0 ~ r8 */
	"%sp", "%regs9", "%a0", "%a1", "%a2", "%a3", "%regs0", "%regs1",
	/* r9 ~ r15 */
@@ -41,10 +42,27 @@ const char *csky_dwarf_regs_table_abiv1[CSKY_ABIV1_MAX_REGS] = {
	"%epc",
};

const char *get_csky_regstr(unsigned int n, unsigned int flags)
const char *__get_csky_regstr(unsigned int n, unsigned int flags)
{
	if (flags & EF_CSKY_ABIV2)
		return (n < CSKY_ABIV2_MAX_REGS) ? csky_dwarf_regs_table_abiv2[n] : NULL;

	return (n < CSKY_ABIV1_MAX_REGS) ? csky_dwarf_regs_table_abiv1[n] : NULL;
}

static int __get_dwarf_regnum(const char *const *regstr, size_t num_regstr, const char *name)
{
	for (size_t i = 0; i < num_regstr; i++) {
		if (regstr[i] && !strcmp(regstr[i], name))
			return i;
	}
	return -ENOENT;
}

int __get_csky_regnum(const char *name, unsigned int flags)
{
	if (flags & EF_CSKY_ABIV2)
		return __get_dwarf_regnum(csky_dwarf_regs_table_abiv2, CSKY_ABIV2_MAX_REGS, name);

	return __get_dwarf_regnum(csky_dwarf_regs_table_abiv1, CSKY_ABIV1_MAX_REGS, name);
}
+54 −4
Original line number Diff line number Diff line
@@ -27,11 +27,11 @@
#include "../arch/mips/include/dwarf-regs-table.h"
#include "../arch/loongarch/include/dwarf-regs-table.h"

#define __get_dwarf_regstr(tbl, n) (((n) < ARRAY_SIZE(tbl)) ? (tbl)[(n)] : NULL)

/* Return architecture dependent register string (for kprobe-tracer) */
const char *get_dwarf_regstr(unsigned int n, unsigned int machine, unsigned int flags)
{
	#define __get_dwarf_regstr(tbl, n) (((n) < ARRAY_SIZE(tbl)) ? (tbl)[(n)] : NULL)

	if (machine == EM_NONE) {
		/* Generic arch - use host arch */
		machine = EM_HOST;
@@ -46,7 +46,7 @@ const char *get_dwarf_regstr(unsigned int n, unsigned int machine, unsigned int
	case EM_AARCH64:
		return __get_dwarf_regstr(aarch64_regstr_tbl, n);
	case EM_CSKY:
		return get_csky_regstr(n, flags);
		return __get_csky_regstr(n, flags);
	case EM_SH:
		return __get_dwarf_regstr(sh_regstr_tbl, n);
	case EM_S390:
@@ -69,15 +69,28 @@ const char *get_dwarf_regstr(unsigned int n, unsigned int machine, unsigned int
		pr_err("ELF MACHINE %x is not supported.\n", machine);
	}
	return NULL;

	#undef __get_dwarf_regstr
}

static int __get_dwarf_regnum(const char *const *regstr, size_t num_regstr, const char *name)
{
	for (size_t i = 0; i < num_regstr; i++) {
		if (regstr[i] && !strcmp(regstr[i], name))
			return i;
	}
	return -ENOENT;
}

/* Return DWARF register number from architecture register name */
int get_dwarf_regnum(const char *name, unsigned int machine, unsigned int flags __maybe_unused)
int get_dwarf_regnum(const char *name, unsigned int machine, unsigned int flags)
{
	char *regname = strdup(name);
	int reg = -1;
	char *p;

	#define _get_dwarf_regnum(tbl, name) __get_dwarf_regnum(tbl, ARRAY_SIZE(tbl), name)

	if (regname == NULL)
		return -EINVAL;

@@ -97,11 +110,48 @@ int get_dwarf_regnum(const char *name, unsigned int machine, unsigned int flags
	case EM_386:
		reg = __get_dwarf_regnum_i386(name);
		break;
	case EM_ARM:
		reg = _get_dwarf_regnum(arm_regstr_tbl, name);
		break;
	case EM_AARCH64:
		reg = _get_dwarf_regnum(aarch64_regstr_tbl, name);
		break;
	case EM_CSKY:
		reg = __get_csky_regnum(name, flags);
		break;
	case EM_SH:
		reg = _get_dwarf_regnum(sh_regstr_tbl, name);
		break;
	case EM_S390:
		reg = _get_dwarf_regnum(s390_regstr_tbl, name);
		break;
	case EM_PPC:
	case EM_PPC64:
		reg = _get_dwarf_regnum(powerpc_regstr_tbl, name);
		break;
	case EM_RISCV:
		reg = _get_dwarf_regnum(riscv_regstr_tbl, name);
		break;
	case EM_SPARC:
	case EM_SPARCV9:
		reg = _get_dwarf_regnum(sparc_regstr_tbl, name);
		break;
	case EM_XTENSA:
		reg = _get_dwarf_regnum(xtensa_regstr_tbl, name);
		break;
	case EM_MIPS:
		reg = _get_dwarf_regnum(mips_regstr_tbl, name);
		break;
	case EM_LOONGARCH:
		reg = _get_dwarf_regnum(loongarch_regstr_tbl, name);
		break;
	default:
		pr_err("ELF MACHINE %x is not supported.\n", machine);
	}
	free(regname);
	return reg;

	#undef _get_dwarf_regnum
}

static int get_libdw_frame_nregs(unsigned int machine, unsigned int flags __maybe_unused)
+3 −2
Original line number Diff line number Diff line
@@ -89,8 +89,6 @@
#define DWARF_REG_FB  0xd3affb /* random number */

#ifdef HAVE_LIBDW_SUPPORT
const char *get_csky_regstr(unsigned int n, unsigned int flags);

/**
 * get_dwarf_regstr() - Returns ftrace register string from DWARF regnum.
 * @n: DWARF register number.
@@ -99,6 +97,9 @@ const char *get_csky_regstr(unsigned int n, unsigned int flags);
 */
const char *get_dwarf_regstr(unsigned int n, unsigned int machine, unsigned int flags);

const char *__get_csky_regstr(unsigned int n, unsigned int flags);
int __get_csky_regnum(const char *name, unsigned int flags);

int __get_dwarf_regnum_i386(const char *name);
int __get_dwarf_regnum_x86_64(const char *name);
int __get_dwarf_regnum_for_perf_regnum_i386(int perf_regnum);