Skip to content

Commit 3eee606

Browse files
namhyungacmel
authored andcommitted
perf dwarf-regs: Add get_dwarf_regnum()
The get_dwarf_regnum() returns a DWARF register number from a register name string according to the psABI. Also add two pseudo encodings of DWARF_REG_PC which is a register that are used by PC-relative addressing and DWARF_REG_FB which is a frame base register. They need to be handled in a special way. Signed-off-by: Namhyung Kim <namhyung@kernel.org> Cc: Adrian Hunter <adrian.hunter@intel.com> Cc: Ian Rogers <irogers@google.com> Cc: Ingo Molnar <mingo@kernel.org> Cc: Jiri Olsa <jolsa@kernel.org> Cc: Linus Torvalds <torvalds@linux-foundation.org> Cc: Masami Hiramatsu <mhiramat@kernel.org> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Stephane Eranian <eranian@google.com> Cc: linux-toolchains@vger.kernel.org Cc: linux-trace-devel@vger.kernel.org Link: https://lore.kernel.org/r/20231213001323.718046-3-namhyung@kernel.org Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
1 parent 60cb19b commit 3eee606

3 files changed

Lines changed: 91 additions & 0 deletions

File tree

tools/perf/arch/x86/util/dwarf-regs.c

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,3 +113,41 @@ int regs_query_register_offset(const char *name)
113113
return roff->offset;
114114
return -EINVAL;
115115
}
116+
117+
struct dwarf_regs_idx {
118+
const char *name;
119+
int idx;
120+
};
121+
122+
static const struct dwarf_regs_idx x86_regidx_table[] = {
123+
{ "rax", 0 }, { "eax", 0 }, { "ax", 0 }, { "al", 0 },
124+
{ "rdx", 1 }, { "edx", 1 }, { "dx", 1 }, { "dl", 1 },
125+
{ "rcx", 2 }, { "ecx", 2 }, { "cx", 2 }, { "cl", 2 },
126+
{ "rbx", 3 }, { "edx", 3 }, { "bx", 3 }, { "bl", 3 },
127+
{ "rsi", 4 }, { "esi", 4 }, { "si", 4 }, { "sil", 4 },
128+
{ "rdi", 5 }, { "edi", 5 }, { "di", 5 }, { "dil", 5 },
129+
{ "rbp", 6 }, { "ebp", 6 }, { "bp", 6 }, { "bpl", 6 },
130+
{ "rsp", 7 }, { "esp", 7 }, { "sp", 7 }, { "spl", 7 },
131+
{ "r8", 8 }, { "r8d", 8 }, { "r8w", 8 }, { "r8b", 8 },
132+
{ "r9", 9 }, { "r9d", 9 }, { "r9w", 9 }, { "r9b", 9 },
133+
{ "r10", 10 }, { "r10d", 10 }, { "r10w", 10 }, { "r10b", 10 },
134+
{ "r11", 11 }, { "r11d", 11 }, { "r11w", 11 }, { "r11b", 11 },
135+
{ "r12", 12 }, { "r12d", 12 }, { "r12w", 12 }, { "r12b", 12 },
136+
{ "r13", 13 }, { "r13d", 13 }, { "r13w", 13 }, { "r13b", 13 },
137+
{ "r14", 14 }, { "r14d", 14 }, { "r14w", 14 }, { "r14b", 14 },
138+
{ "r15", 15 }, { "r15d", 15 }, { "r15w", 15 }, { "r15b", 15 },
139+
{ "rip", DWARF_REG_PC },
140+
};
141+
142+
int get_arch_regnum(const char *name)
143+
{
144+
unsigned int i;
145+
146+
if (*name != '%')
147+
return -EINVAL;
148+
149+
for (i = 0; i < ARRAY_SIZE(x86_regidx_table); i++)
150+
if (!strcmp(x86_regidx_table[i].name, name + 1))
151+
return x86_regidx_table[i].idx;
152+
return -ENOENT;
153+
}

tools/perf/util/dwarf-regs.c

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,12 @@
55
* Written by: Masami Hiramatsu <mhiramat@kernel.org>
66
*/
77

8+
#include <stdlib.h>
9+
#include <string.h>
810
#include <debug.h>
911
#include <dwarf-regs.h>
1012
#include <elf.h>
13+
#include <errno.h>
1114
#include <linux/kernel.h>
1215

1316
#ifndef EM_AARCH64
@@ -68,3 +71,34 @@ const char *get_dwarf_regstr(unsigned int n, unsigned int machine)
6871
}
6972
return NULL;
7073
}
74+
75+
__weak int get_arch_regnum(const char *name __maybe_unused)
76+
{
77+
return -ENOTSUP;
78+
}
79+
80+
/* Return DWARF register number from architecture register name */
81+
int get_dwarf_regnum(const char *name, unsigned int machine)
82+
{
83+
char *regname = strdup(name);
84+
int reg = -1;
85+
char *p;
86+
87+
if (regname == NULL)
88+
return -EINVAL;
89+
90+
/* For convenience, remove trailing characters */
91+
p = strpbrk(regname, " ,)");
92+
if (p)
93+
*p = '\0';
94+
95+
switch (machine) {
96+
case EM_NONE: /* Generic arch - use host arch */
97+
reg = get_arch_regnum(regname);
98+
break;
99+
default:
100+
pr_err("ELF MACHINE %x is not supported.\n", machine);
101+
}
102+
free(regname);
103+
return reg;
104+
}

tools/perf/util/include/dwarf-regs.h

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,9 @@
22
#ifndef _PERF_DWARF_REGS_H_
33
#define _PERF_DWARF_REGS_H_
44

5+
#define DWARF_REG_PC 0xd3af9c /* random number */
6+
#define DWARF_REG_FB 0xd3affb /* random number */
7+
58
#ifdef HAVE_DWARF_SUPPORT
69
const char *get_arch_regstr(unsigned int n);
710
/*
@@ -10,6 +13,22 @@ const char *get_arch_regstr(unsigned int n);
1013
* machine: ELF machine signature (EM_*)
1114
*/
1215
const char *get_dwarf_regstr(unsigned int n, unsigned int machine);
16+
17+
int get_arch_regnum(const char *name);
18+
/*
19+
* get_dwarf_regnum - Returns DWARF regnum from register name
20+
* name: architecture register name
21+
* machine: ELF machine signature (EM_*)
22+
*/
23+
int get_dwarf_regnum(const char *name, unsigned int machine);
24+
25+
#else /* HAVE_DWARF_SUPPORT */
26+
27+
static inline int get_dwarf_regnum(const char *name __maybe_unused,
28+
unsigned int machine __maybe_unused)
29+
{
30+
return -1;
31+
}
1332
#endif
1433

1534
#ifdef HAVE_ARCH_REGS_QUERY_REGISTER_OFFSET

0 commit comments

Comments
 (0)