[RFC PATCH v2 05/15] perf tools: Add pt_regs offsets and calling regs for x86

From: He Kuang
Date: Sun May 24 2015 - 04:32:25 EST


Combine pt_regs offset of each registers into arch_regs_table. And add
architecture dependent calling_regs_table.

Signed-off-by: He Kuang <hekuang@xxxxxxxxxx>
---
tools/perf/arch/x86/util/dwarf-regs.c | 100 +++++++++++++++++++++++++++-------
1 file changed, 79 insertions(+), 21 deletions(-)

diff --git a/tools/perf/arch/x86/util/dwarf-regs.c b/tools/perf/arch/x86/util/dwarf-regs.c
index be22dd4..c7f2309 100644
--- a/tools/perf/arch/x86/util/dwarf-regs.c
+++ b/tools/perf/arch/x86/util/dwarf-regs.c
@@ -22,54 +22,112 @@

#include <stddef.h>
#include <dwarf-regs.h>
+#include <string.h>
+#include <linux/ptrace.h>

/*
* Generic dwarf analysis helpers
*/

+#ifndef __x86_64__
#define X86_32_MAX_REGS 8
-const char *x86_32_regs_table[X86_32_MAX_REGS] = {
- "%ax",
+const struct arch_regs_info x86_32_regs_table[X86_32_MAX_REGS] = {
+ ARCH_REGS_INFO("%ax", eax),
+ ARCH_REGS_INFO("%cx", ecx),
+ ARCH_REGS_INFO("%dx", edx),
+ ARCH_REGS_INFO("%bx", ebx),
+ ARCH_REGS_INFO("$stack", esp), /* Stack address instead of %sp */
+ ARCH_REGS_INFO("%bp", ebp),
+ ARCH_REGS_INFO("%si", esi),
+ ARCH_REGS_INFO("%di", edi),
+};
+
+#define X86_32_MAX_CALLING_REGS (2)
+const char *x86_32_calling_regs_table[] = {
"%cx",
"%dx",
- "%bx",
- "$stack", /* Stack address instead of %sp */
- "%bp",
- "%si",
- "%di",
};

+#else
#define X86_64_MAX_REGS 16
-const char *x86_64_regs_table[X86_64_MAX_REGS] = {
- "%ax",
+const struct arch_regs_info x86_64_regs_table[X86_64_MAX_REGS] = {
+ ARCH_REGS_INFO("%ax", rax),
+ ARCH_REGS_INFO("%dx", rdx),
+ ARCH_REGS_INFO("%cx", rcx),
+ ARCH_REGS_INFO("%bx", rbx),
+ ARCH_REGS_INFO("%si", rsi),
+ ARCH_REGS_INFO("%di", rdi),
+ ARCH_REGS_INFO("%bp", rbp),
+ ARCH_REGS_INFO("%sp", rsp),
+ ARCH_REGS_INFO("%r8", r8),
+ ARCH_REGS_INFO("%r9", r9),
+ ARCH_REGS_INFO("%r10", r10),
+ ARCH_REGS_INFO("%r11", r11),
+ ARCH_REGS_INFO("%r12", r12),
+ ARCH_REGS_INFO("%r13", r13),
+ ARCH_REGS_INFO("%r14", r14),
+ ARCH_REGS_INFO("%r15", r15),
+};
+
+#define X86_64_MAX_CALLING_REGS (6)
+const char *x86_64_calling_regs_table[] = {
+ "%di",
+ "%si",
"%dx",
"%cx",
- "%bx",
- "%si",
- "%di",
- "%bp",
- "%sp",
"%r8",
"%r9",
- "%r10",
- "%r11",
- "%r12",
- "%r13",
- "%r14",
- "%r15",
};

+#endif
+
/* TODO: switching by dwarf address size */
#ifdef __x86_64__
#define ARCH_MAX_REGS X86_64_MAX_REGS
#define arch_regs_table x86_64_regs_table
+#define ARCH_MAX_CALLING_REGS X86_64_MAX_CALLING_REGS
+#define arch_calling_regs_table x86_64_calling_regs_table
#else
#define ARCH_MAX_REGS X86_32_MAX_REGS
#define arch_regs_table x86_32_regs_table
+#define ARCH_MAX_CALLING_REGS X86_32_MAX_CALLING_REGS
+#define arch_calling_regs_table x86_32_calling_regs_table
#endif

/* Return architecture dependent register string (for kprobe-tracer) */
const char *get_arch_regstr(unsigned int n)
{
- return (n <= ARCH_MAX_REGS) ? arch_regs_table[n] : NULL;
+ return (n < ARCH_MAX_REGS) ? arch_regs_table[n].name : NULL;
+}
+
+int get_arch_reg_offset(unsigned int n)
+{
+ return (n < ARCH_MAX_REGS) ? arch_regs_table[n].offset : -1;
+}
+
+int get_arch_reg_size(unsigned int n)
+{
+ return (n < ARCH_MAX_REGS) ? arch_regs_table[n].size : -1;
+}
+
+const char *get_arch_calling_reg_str(unsigned int n)
+{
+ return (n < ARCH_MAX_CALLING_REGS) ?
+ arch_calling_regs_table[n] : NULL;
+}
+
+int get_arch_calling_reg_offset(unsigned int n)
+{
+ int i;
+
+ if (n >= ARCH_MAX_CALLING_REGS)
+ return -1;
+
+ for (i = 0; i < ARCH_MAX_REGS; i++) {
+ if (!strcmp(arch_calling_regs_table[n],
+ arch_regs_table[i].name))
+ return arch_regs_table[i].offset;
+ }
+
+ return -1;
}
--
1.8.5.2

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/