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: Ian Rogers <[email protected]>
---
 .../util/dwarf-regs-arch/dwarf-regs-csky.c    | 24 +++++++-
 tools/perf/util/dwarf-regs.c                  | 58 +++++++++++++++++--
 tools/perf/util/include/dwarf-regs.h          |  5 +-
 3 files changed, 78 insertions(+), 9 deletions(-)

diff --git a/tools/perf/util/dwarf-regs-arch/dwarf-regs-csky.c 
b/tools/perf/util/dwarf-regs-arch/dwarf-regs-csky.c
index d38ef1f07f3e..86394ed46397 100644
--- a/tools/perf/util/dwarf-regs-arch/dwarf-regs-csky.c
+++ b/tools/perf/util/dwarf-regs-arch/dwarf-regs-csky.c
@@ -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);
+}
diff --git a/tools/perf/util/dwarf-regs.c b/tools/perf/util/dwarf-regs.c
index 1f7d892612df..dffa0c8bdd14 100644
--- a/tools/perf/util/dwarf-regs.c
+++ b/tools/perf/util/dwarf-regs.c
@@ -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)
diff --git a/tools/perf/util/include/dwarf-regs.h 
b/tools/perf/util/include/dwarf-regs.h
index 00881f1d45d6..a120c97a5fac 100644
--- a/tools/perf/util/include/dwarf-regs.h
+++ b/tools/perf/util/include/dwarf-regs.h
@@ -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);
-- 
2.52.0.457.g6b5491de43-goog


Reply via email to