2010-04-12 06:44:55

by Ian Munsie

[permalink] [raw]
Subject:

These patches add the required mappings to use perf probe on PowerPC.

Functionality wise it requires patch 359e4284a3f37aba7fd06d993863de2509d86f54
from the powerpc-next tree to provide the HAVE_REGS_AND_STACK_ACCESS_API
required for CONFIG_KPROBE_EVENT. The code will still compile cleanly without
it and will fail gracefully at runtime on the missing CONFIG_KPROBE_EVENT
support as before.

Part 1 of the patch series moves the arch dependent x86 32 and 64 bit DWARF
register number mappings out into a separate arch directory and adds the
necessary Makefile foo to use it.

Part 2 of the patch series adds the PowerPC mappings.

Thanks,
-Ian


2010-04-12 06:45:26

by Ian Munsie

[permalink] [raw]
Subject: [PATCH 2/2] perf probe: Add PowerPC DWARF register number mappings

From: Ian Munsie <[email protected]>

This patch adds mappings from the register numbers from DWARF to the
register names used in the PowerPC Regs and Stack Access API. This
allows perf probe to be used to record variable contents on PowerPC.

This patch depends on functionality in the powerpc/next tree, though it
will compile fine without it. Specifically this patch depends on
359e4284a3f37aba7fd06d993863de2509d86f54

Signed-off-by: Ian Munsie <[email protected]>
---
tools/perf/arch/powerpc/Makefile | 1 +
tools/perf/arch/powerpc/include/arch_dwarf-regs.h | 6 ++
tools/perf/arch/powerpc/util/dwarf-regs.c | 88 +++++++++++++++++++++
3 files changed, 95 insertions(+), 0 deletions(-)
create mode 100644 tools/perf/arch/powerpc/Makefile
create mode 100644 tools/perf/arch/powerpc/include/arch_dwarf-regs.h
create mode 100644 tools/perf/arch/powerpc/util/dwarf-regs.c

diff --git a/tools/perf/arch/powerpc/Makefile b/tools/perf/arch/powerpc/Makefile
new file mode 100644
index 0000000..1191403
--- /dev/null
+++ b/tools/perf/arch/powerpc/Makefile
@@ -0,0 +1 @@
+LIB_OBJS += $(OUTPUT)arch/$(ARCH)/util/dwarf-regs.o
diff --git a/tools/perf/arch/powerpc/include/arch_dwarf-regs.h b/tools/perf/arch/powerpc/include/arch_dwarf-regs.h
new file mode 100644
index 0000000..a7fc588
--- /dev/null
+++ b/tools/perf/arch/powerpc/include/arch_dwarf-regs.h
@@ -0,0 +1,6 @@
+#ifndef _PREF_ARCH_X86_DWARF_REGS_H
+#define _PREF_ARCH_X86_DWARF_REGS_H
+
+#define get_arch_regstr(n) get_arch_regstr(n)
+
+#endif
diff --git a/tools/perf/arch/powerpc/util/dwarf-regs.c b/tools/perf/arch/powerpc/util/dwarf-regs.c
new file mode 100644
index 0000000..48ae0c5
--- /dev/null
+++ b/tools/perf/arch/powerpc/util/dwarf-regs.c
@@ -0,0 +1,88 @@
+/*
+ * Mapping of DWARF debug register numbers into register names.
+ *
+ * Copyright (C) 2010 Ian Munsie, IBM Corporation.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#include <libio.h>
+#include <dwarf-regs.h>
+
+
+struct pt_regs_dwarfnum {
+ const char *name;
+ unsigned int dwarfnum;
+};
+
+#define STR(s) #s
+#define REG_DWARFNUM_NAME(r, num) {.name = r, .dwarfnum = num}
+#define GPR_DWARFNUM_NAME(num) \
+ {.name = STR(%gpr##num), .dwarfnum = num}
+#define REG_DWARFNUM_END {.name = NULL, .dwarfnum = 0}
+
+/*
+ * Reference:
+ * http://refspecs.linuxfoundation.org/ELF/ppc64/PPC-elf64abi-1.9.html
+ */
+static const struct pt_regs_dwarfnum regdwarfnum_table[] = {
+ GPR_DWARFNUM_NAME(0),
+ GPR_DWARFNUM_NAME(1),
+ GPR_DWARFNUM_NAME(2),
+ GPR_DWARFNUM_NAME(3),
+ GPR_DWARFNUM_NAME(4),
+ GPR_DWARFNUM_NAME(5),
+ GPR_DWARFNUM_NAME(6),
+ GPR_DWARFNUM_NAME(7),
+ GPR_DWARFNUM_NAME(8),
+ GPR_DWARFNUM_NAME(9),
+ GPR_DWARFNUM_NAME(10),
+ GPR_DWARFNUM_NAME(11),
+ GPR_DWARFNUM_NAME(12),
+ GPR_DWARFNUM_NAME(13),
+ GPR_DWARFNUM_NAME(14),
+ GPR_DWARFNUM_NAME(15),
+ GPR_DWARFNUM_NAME(16),
+ GPR_DWARFNUM_NAME(17),
+ GPR_DWARFNUM_NAME(18),
+ GPR_DWARFNUM_NAME(19),
+ GPR_DWARFNUM_NAME(20),
+ GPR_DWARFNUM_NAME(21),
+ GPR_DWARFNUM_NAME(22),
+ GPR_DWARFNUM_NAME(23),
+ GPR_DWARFNUM_NAME(24),
+ GPR_DWARFNUM_NAME(25),
+ GPR_DWARFNUM_NAME(26),
+ GPR_DWARFNUM_NAME(27),
+ GPR_DWARFNUM_NAME(28),
+ GPR_DWARFNUM_NAME(29),
+ GPR_DWARFNUM_NAME(30),
+ GPR_DWARFNUM_NAME(31),
+ REG_DWARFNUM_NAME("%msr", 66),
+ REG_DWARFNUM_NAME("%ctr", 109),
+ REG_DWARFNUM_NAME("%link", 108),
+ REG_DWARFNUM_NAME("%xer", 101),
+ REG_DWARFNUM_NAME("%dar", 119),
+ REG_DWARFNUM_NAME("%dsisr", 118),
+ REG_DWARFNUM_END,
+};
+
+/**
+ * get_arch_regstr() - lookup register name from it's DWARF register number
+ * @n: the DWARF register number
+ *
+ * get_arch_regstr() returns the name of the register in struct
+ * regdwarfnum_table from it's DWARF register number. If the register is not
+ * found in the table, this returns NULL;
+ */
+const char *get_arch_regstr(unsigned int n)
+{
+ const struct pt_regs_dwarfnum *roff;
+ for (roff = regdwarfnum_table; roff->name != NULL; roff++)
+ if (roff->dwarfnum == n)
+ return roff->name;
+ return NULL;
+}
--
1.7.0

2010-04-12 06:45:24

by Ian Munsie

[permalink] [raw]
Subject: [PATCH 1/2] perf: Move arch specific code into separate arch directory

From: Ian Munsie <[email protected]>

The perf userspace tool included some architecture specific code to map
registers from the DWARF register number into the names used by the regs
and stack access API.

This patch moves the architecture specific code out into a seperate
arch/x86 directory along with the infrastructure required to use it.

Signed-off-by: Ian Munsie <[email protected]>
---
tools/perf/Makefile | 18 ++++++-
tools/perf/arch/x86/Makefile | 1 +
tools/perf/arch/x86/include/arch_dwarf-regs.h | 6 ++
tools/perf/arch/x86/util/dwarf-regs.c | 75 +++++++++++++++++++++++++
tools/perf/util/include/dwarf-regs.h | 8 +++
tools/perf/util/probe-finder.c | 55 ++----------------
6 files changed, 113 insertions(+), 50 deletions(-)
create mode 100644 tools/perf/arch/x86/Makefile
create mode 100644 tools/perf/arch/x86/include/arch_dwarf-regs.h
create mode 100644 tools/perf/arch/x86/util/dwarf-regs.c
create mode 100644 tools/perf/util/include/dwarf-regs.h

diff --git a/tools/perf/Makefile b/tools/perf/Makefile
index f578b05..07a6ee2 100644
--- a/tools/perf/Makefile
+++ b/tools/perf/Makefile
@@ -172,6 +172,20 @@ uname_R := $(shell sh -c 'uname -r 2>/dev/null || echo not')
uname_P := $(shell sh -c 'uname -p 2>/dev/null || echo not')
uname_V := $(shell sh -c 'uname -v 2>/dev/null || echo not')

+ARCH ?= $(shell echo $(uname_M) | sed -e s/i.86/i386/ -e s/sun4u/sparc64/ \
+ -e s/arm.*/arm/ -e s/sa110/arm/ \
+ -e s/s390x/s390/ -e s/parisc64/parisc/ \
+ -e s/ppc.*/powerpc/ -e s/mips.*/mips/ \
+ -e s/sh[234].*/sh/ )
+
+# Additional ARCH settings for x86
+ifeq ($(ARCH),i386)
+ ARCH := x86
+endif
+ifeq ($(ARCH),x86_64)
+ ARCH := x86
+endif
+
# CFLAGS and LDFLAGS are for the users to override from the command line.

#
@@ -284,7 +298,7 @@ endif
# Those must not be GNU-specific; they are shared with perl/ which may
# be built by a different compiler. (Note that this is an artifact now
# but it still might be nice to keep that distinction.)
-BASIC_CFLAGS = -Iutil/include
+BASIC_CFLAGS = -Iutil/include -Iarch/$(ARCH)/include
BASIC_LDFLAGS =

# Guard against environment variables
@@ -366,6 +380,7 @@ LIB_H += util/include/asm/byteorder.h
LIB_H += util/include/asm/swab.h
LIB_H += util/include/asm/system.h
LIB_H += util/include/asm/uaccess.h
+LIB_H += util/include/dwarf-regs.h
LIB_H += perf.h
LIB_H += util/cache.h
LIB_H += util/callchain.h
@@ -484,6 +499,7 @@ PERFLIBS = $(LIB_FILE)

-include config.mak.autogen
-include config.mak
+-include arch/$(ARCH)/Makefile

ifeq ($(uname_S),Darwin)
ifndef NO_FINK
diff --git a/tools/perf/arch/x86/Makefile b/tools/perf/arch/x86/Makefile
new file mode 100644
index 0000000..1191403
--- /dev/null
+++ b/tools/perf/arch/x86/Makefile
@@ -0,0 +1 @@
+LIB_OBJS += $(OUTPUT)arch/$(ARCH)/util/dwarf-regs.o
diff --git a/tools/perf/arch/x86/include/arch_dwarf-regs.h b/tools/perf/arch/x86/include/arch_dwarf-regs.h
new file mode 100644
index 0000000..9e8da6a
--- /dev/null
+++ b/tools/perf/arch/x86/include/arch_dwarf-regs.h
@@ -0,0 +1,6 @@
+#ifndef _PREF_ARCH_PPC_DWARF_REGS_H
+#define _PREF_ARCH_PPC_DWARF_REGS_H
+
+#define get_arch_regstr(n) get_arch_regstr(n)
+
+#endif
diff --git a/tools/perf/arch/x86/util/dwarf-regs.c b/tools/perf/arch/x86/util/dwarf-regs.c
new file mode 100644
index 0000000..a794d30
--- /dev/null
+++ b/tools/perf/arch/x86/util/dwarf-regs.c
@@ -0,0 +1,75 @@
+/*
+ * dwarf-regs.c : Mapping of DWARF debug register numbers into register names.
+ * Extracted from probe-finder.c
+ *
+ * Written by Masami Hiramatsu <[email protected]>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ */
+
+#include <libio.h>
+#include <dwarf-regs.h>
+
+/*
+ * Generic dwarf analysis helpers
+ */
+
+#define X86_32_MAX_REGS 8
+const char *x86_32_regs_table[X86_32_MAX_REGS] = {
+ "%ax",
+ "%cx",
+ "%dx",
+ "%bx",
+ "$stack", /* Stack address instead of %sp */
+ "%bp",
+ "%si",
+ "%di",
+};
+
+#define X86_64_MAX_REGS 16
+const char *x86_64_regs_table[X86_64_MAX_REGS] = {
+ "%ax",
+ "%dx",
+ "%cx",
+ "%bx",
+ "%si",
+ "%di",
+ "%bp",
+ "%sp",
+ "%r8",
+ "%r9",
+ "%r10",
+ "%r11",
+ "%r12",
+ "%r13",
+ "%r14",
+ "%r15",
+};
+
+/* 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
+#else
+#define ARCH_MAX_REGS X86_32_MAX_REGS
+#define arch_regs_table x86_32_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;
+}
diff --git a/tools/perf/util/include/dwarf-regs.h b/tools/perf/util/include/dwarf-regs.h
new file mode 100644
index 0000000..2a1cf6f
--- /dev/null
+++ b/tools/perf/util/include/dwarf-regs.h
@@ -0,0 +1,8 @@
+#ifndef _PERF_DWARF_REGS_H_
+#define _PERF_DWARF_REGS_H_
+
+#include <arch_dwarf-regs.h>
+
+const char *get_arch_regstr(unsigned int n);
+
+#endif
diff --git a/tools/perf/util/probe-finder.c b/tools/perf/util/probe-finder.c
index a851377..27020fe 100644
--- a/tools/perf/util/probe-finder.c
+++ b/tools/perf/util/probe-finder.c
@@ -31,6 +31,7 @@
#include <string.h>
#include <stdarg.h>
#include <ctype.h>
+#include <dwarf-regs.h>

#include "string.h"
#include "event.h"
@@ -38,57 +39,13 @@
#include "util.h"
#include "probe-finder.h"

-
-/*
- * Generic dwarf analysis helpers
- */
-
-#define X86_32_MAX_REGS 8
-const char *x86_32_regs_table[X86_32_MAX_REGS] = {
- "%ax",
- "%cx",
- "%dx",
- "%bx",
- "$stack", /* Stack address instead of %sp */
- "%bp",
- "%si",
- "%di",
-};
-
-#define X86_64_MAX_REGS 16
-const char *x86_64_regs_table[X86_64_MAX_REGS] = {
- "%ax",
- "%dx",
- "%cx",
- "%bx",
- "%si",
- "%di",
- "%bp",
- "%sp",
- "%r8",
- "%r9",
- "%r10",
- "%r11",
- "%r12",
- "%r13",
- "%r14",
- "%r15",
-};
-
-/* 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
-#else
-#define ARCH_MAX_REGS X86_32_MAX_REGS
-#define arch_regs_table x86_32_regs_table
-#endif
-
/* Return architecture dependent register string (for kprobe-tracer) */
-static const char *get_arch_regstr(unsigned int n)
+#ifndef get_arch_regstr
+const char *get_arch_regstr(unsigned int n __attribute__((unused)))
{
- return (n <= ARCH_MAX_REGS) ? arch_regs_table[n] : NULL;
+ return NULL;
}
+#endif

/*
* Compare the tail of two strings.
@@ -397,7 +354,7 @@ static void convert_location(Dwarf_Op *op, struct probe_finder *pf)

regs = get_arch_regstr(regn);
if (!regs)
- die("%u exceeds max register number.", regn);
+ die("Mapping for DWARF register number %u missing on this architecture.", regn);

tvar->value = xstrdup(regs);
if (ref) {
--
1.7.0

2010-04-12 12:37:39

by Masami Hiramatsu

[permalink] [raw]
Subject: Re: [PATCH 1/2] perf: Move arch specific code into separate arch directory

Hi Ian,

Ian Munsie wrote:
> From: Ian Munsie <[email protected]>
>
> The perf userspace tool included some architecture specific code to map
> registers from the DWARF register number into the names used by the regs
> and stack access API.
>
> This patch moves the architecture specific code out into a seperate
> arch/x86 directory along with the infrastructure required to use it.

Nice! :)
I have just some comments on it.

>
> Signed-off-by: Ian Munsie <[email protected]>
> ---
> tools/perf/Makefile | 18 ++++++-
> tools/perf/arch/x86/Makefile | 1 +
> tools/perf/arch/x86/include/arch_dwarf-regs.h | 6 ++
> tools/perf/arch/x86/util/dwarf-regs.c | 75 +++++++++++++++++++++++++
> tools/perf/util/include/dwarf-regs.h | 8 +++
> tools/perf/util/probe-finder.c | 55 ++----------------
> 6 files changed, 113 insertions(+), 50 deletions(-)
> create mode 100644 tools/perf/arch/x86/Makefile
> create mode 100644 tools/perf/arch/x86/include/arch_dwarf-regs.h
> create mode 100644 tools/perf/arch/x86/util/dwarf-regs.c
> create mode 100644 tools/perf/util/include/dwarf-regs.h
>
> diff --git a/tools/perf/Makefile b/tools/perf/Makefile
> index f578b05..07a6ee2 100644
> --- a/tools/perf/Makefile
> +++ b/tools/perf/Makefile
> @@ -172,6 +172,20 @@ uname_R := $(shell sh -c 'uname -r 2>/dev/null || echo not')
> uname_P := $(shell sh -c 'uname -p 2>/dev/null || echo not')
> uname_V := $(shell sh -c 'uname -v 2>/dev/null || echo not')
>
> +ARCH ?= $(shell echo $(uname_M) | sed -e s/i.86/i386/ -e s/sun4u/sparc64/ \
> + -e s/arm.*/arm/ -e s/sa110/arm/ \
> + -e s/s390x/s390/ -e s/parisc64/parisc/ \
> + -e s/ppc.*/powerpc/ -e s/mips.*/mips/ \
> + -e s/sh[234].*/sh/ )
> +
> +# Additional ARCH settings for x86
> +ifeq ($(ARCH),i386)
> + ARCH := x86
> +endif
> +ifeq ($(ARCH),x86_64)
> + ARCH := x86
> +endif
> +
> # CFLAGS and LDFLAGS are for the users to override from the command line.
>
> #
> @@ -284,7 +298,7 @@ endif
> # Those must not be GNU-specific; they are shared with perl/ which may
> # be built by a different compiler. (Note that this is an artifact now
> # but it still might be nice to keep that distinction.)
> -BASIC_CFLAGS = -Iutil/include
> +BASIC_CFLAGS = -Iutil/include -Iarch/$(ARCH)/include
> BASIC_LDFLAGS =
>
> # Guard against environment variables
> @@ -366,6 +380,7 @@ LIB_H += util/include/asm/byteorder.h
> LIB_H += util/include/asm/swab.h
> LIB_H += util/include/asm/system.h
> LIB_H += util/include/asm/uaccess.h
> +LIB_H += util/include/dwarf-regs.h
> LIB_H += perf.h
> LIB_H += util/cache.h
> LIB_H += util/callchain.h
> @@ -484,6 +499,7 @@ PERFLIBS = $(LIB_FILE)
>
> -include config.mak.autogen
> -include config.mak
> +-include arch/$(ARCH)/Makefile
>
> ifeq ($(uname_S),Darwin)
> ifndef NO_FINK

Could you add a check whether the get_arch_regstr() is defined
(or dwarf-regs.h is exist) in Makefile?
If it is not defined, we'd better drop dwarf support(so set NO_DWARF),
because it means we haven't ported perf probe on that architecture yet. :)

> diff --git a/tools/perf/arch/x86/Makefile b/tools/perf/arch/x86/Makefile
> new file mode 100644
> index 0000000..1191403
> --- /dev/null
> +++ b/tools/perf/arch/x86/Makefile
> @@ -0,0 +1 @@
> +LIB_OBJS += $(OUTPUT)arch/$(ARCH)/util/dwarf-regs.o
> diff --git a/tools/perf/arch/x86/include/arch_dwarf-regs.h b/tools/perf/arch/x86/include/arch_dwarf-regs.h
> new file mode 100644
> index 0000000..9e8da6a
> --- /dev/null
> +++ b/tools/perf/arch/x86/include/arch_dwarf-regs.h
> @@ -0,0 +1,6 @@
> +#ifndef _PREF_ARCH_PPC_DWARF_REGS_H
> +#define _PREF_ARCH_PPC_DWARF_REGS_H

_PREF_ARCH_X86_DWARF_REGS_H ?

> +
> +#define get_arch_regstr(n) get_arch_regstr(n)

If we checked above dwarf support, we don't need this odd macro.

> +
> +#endif
> diff --git a/tools/perf/arch/x86/util/dwarf-regs.c b/tools/perf/arch/x86/util/dwarf-regs.c
> new file mode 100644
> index 0000000..a794d30
> --- /dev/null
> +++ b/tools/perf/arch/x86/util/dwarf-regs.c
> @@ -0,0 +1,75 @@
> +/*
> + * dwarf-regs.c : Mapping of DWARF debug register numbers into register names.
> + * Extracted from probe-finder.c
> + *
> + * Written by Masami Hiramatsu <[email protected]>
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License as published by
> + * the Free Software Foundation; either version 2 of the License, or
> + * (at your option) any later version.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
> + * GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this program; if not, write to the Free Software
> + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
> + *
> + */
> +
> +#include <libio.h>
> +#include <dwarf-regs.h>
> +
> +/*
> + * Generic dwarf analysis helpers
> + */
> +
> +#define X86_32_MAX_REGS 8
> +const char *x86_32_regs_table[X86_32_MAX_REGS] = {
> + "%ax",
> + "%cx",
> + "%dx",
> + "%bx",
> + "$stack", /* Stack address instead of %sp */
> + "%bp",
> + "%si",
> + "%di",
> +};
> +
> +#define X86_64_MAX_REGS 16
> +const char *x86_64_regs_table[X86_64_MAX_REGS] = {
> + "%ax",
> + "%dx",
> + "%cx",
> + "%bx",
> + "%si",
> + "%di",
> + "%bp",
> + "%sp",
> + "%r8",
> + "%r9",
> + "%r10",
> + "%r11",
> + "%r12",
> + "%r13",
> + "%r14",
> + "%r15",
> +};
> +
> +/* 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
> +#else
> +#define ARCH_MAX_REGS X86_32_MAX_REGS
> +#define arch_regs_table x86_32_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;
> +}
> diff --git a/tools/perf/util/include/dwarf-regs.h b/tools/perf/util/include/dwarf-regs.h
> new file mode 100644
> index 0000000..2a1cf6f
> --- /dev/null
> +++ b/tools/perf/util/include/dwarf-regs.h
> @@ -0,0 +1,8 @@
> +#ifndef _PERF_DWARF_REGS_H_
> +#define _PERF_DWARF_REGS_H_
> +
> +#include <arch_dwarf-regs.h>
> +
> +const char *get_arch_regstr(unsigned int n);
> +
> +#endif
> diff --git a/tools/perf/util/probe-finder.c b/tools/perf/util/probe-finder.c
> index a851377..27020fe 100644
> --- a/tools/perf/util/probe-finder.c
> +++ b/tools/perf/util/probe-finder.c
> @@ -31,6 +31,7 @@
> #include <string.h>
> #include <stdarg.h>
> #include <ctype.h>
> +#include <dwarf-regs.h>
>
> #include "string.h"
> #include "event.h"
> @@ -38,57 +39,13 @@
> #include "util.h"
> #include "probe-finder.h"
>
> -
> -/*
> - * Generic dwarf analysis helpers
> - */
> -
> -#define X86_32_MAX_REGS 8
> -const char *x86_32_regs_table[X86_32_MAX_REGS] = {
> - "%ax",
> - "%cx",
> - "%dx",
> - "%bx",
> - "$stack", /* Stack address instead of %sp */
> - "%bp",
> - "%si",
> - "%di",
> -};
> -
> -#define X86_64_MAX_REGS 16
> -const char *x86_64_regs_table[X86_64_MAX_REGS] = {
> - "%ax",
> - "%dx",
> - "%cx",
> - "%bx",
> - "%si",
> - "%di",
> - "%bp",
> - "%sp",
> - "%r8",
> - "%r9",
> - "%r10",
> - "%r11",
> - "%r12",
> - "%r13",
> - "%r14",
> - "%r15",
> -};
> -
> -/* 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
> -#else
> -#define ARCH_MAX_REGS X86_32_MAX_REGS
> -#define arch_regs_table x86_32_regs_table
> -#endif
> -
> /* Return architecture dependent register string (for kprobe-tracer) */
> -static const char *get_arch_regstr(unsigned int n)
> +#ifndef get_arch_regstr
> +const char *get_arch_regstr(unsigned int n __attribute__((unused)))
> {
> - return (n <= ARCH_MAX_REGS) ? arch_regs_table[n] : NULL;
> + return NULL;
> }
> +#endif

Again, if we add a check in Makefile, we can remove this completely.

>
> /*
> * Compare the tail of two strings.
> @@ -397,7 +354,7 @@ static void convert_location(Dwarf_Op *op, struct probe_finder *pf)
>
> regs = get_arch_regstr(regn);
> if (!regs)
> - die("%u exceeds max register number.", regn);
> + die("Mapping for DWARF register number %u missing on this architecture.", regn);
>
> tvar->value = xstrdup(regs);
> if (ref) {

Thank you,

--
Masami Hiramatsu
e-mail: [email protected]

2010-04-12 12:40:29

by Masami Hiramatsu

[permalink] [raw]
Subject: Re: [PATCH 2/2] perf probe: Add PowerPC DWARF register number mappings

Hi Ian,

Ian Munsie wrote:
> From: Ian Munsie <[email protected]>
>
> This patch adds mappings from the register numbers from DWARF to the
> register names used in the PowerPC Regs and Stack Access API. This
> allows perf probe to be used to record variable contents on PowerPC.
>
> This patch depends on functionality in the powerpc/next tree, though it
> will compile fine without it. Specifically this patch depends on
> 359e4284a3f37aba7fd06d993863de2509d86f54
>
> Signed-off-by: Ian Munsie <[email protected]>
> ---
> tools/perf/arch/powerpc/Makefile | 1 +
> tools/perf/arch/powerpc/include/arch_dwarf-regs.h | 6 ++
> tools/perf/arch/powerpc/util/dwarf-regs.c | 88 +++++++++++++++++++++
> 3 files changed, 95 insertions(+), 0 deletions(-)
> create mode 100644 tools/perf/arch/powerpc/Makefile
> create mode 100644 tools/perf/arch/powerpc/include/arch_dwarf-regs.h
> create mode 100644 tools/perf/arch/powerpc/util/dwarf-regs.c
>
> diff --git a/tools/perf/arch/powerpc/Makefile b/tools/perf/arch/powerpc/Makefile
> new file mode 100644
> index 0000000..1191403
> --- /dev/null
> +++ b/tools/perf/arch/powerpc/Makefile
> @@ -0,0 +1 @@
> +LIB_OBJS += $(OUTPUT)arch/$(ARCH)/util/dwarf-regs.o
> diff --git a/tools/perf/arch/powerpc/include/arch_dwarf-regs.h b/tools/perf/arch/powerpc/include/arch_dwarf-regs.h
> new file mode 100644
> index 0000000..a7fc588
> --- /dev/null
> +++ b/tools/perf/arch/powerpc/include/arch_dwarf-regs.h
> @@ -0,0 +1,6 @@
> +#ifndef _PREF_ARCH_X86_DWARF_REGS_H
> +#define _PREF_ARCH_X86_DWARF_REGS_H

_PREF_ARCH_PPC_DWARF_REGS_H? :)

> +
> +#define get_arch_regstr(n) get_arch_regstr(n)
> +
> +#endif

Thank you,

--
Masami Hiramatsu
e-mail: [email protected]

2010-04-13 08:44:45

by Ian Munsie

[permalink] [raw]
Subject: Re: [PATCH 1/2] perf: Move arch specific code into separate arch directory

Hi Masami,

Thanks for the feedback

Excerpts from Masami Hiramatsu's message of Mon Apr 12 22:37:03 +1000 2010:
> Could you add a check whether the get_arch_regstr() is defined
> (or dwarf-regs.h is exist) in Makefile?
> If it is not defined, we'd better drop dwarf support(so set NO_DWARF),
> because it means we haven't ported perf probe on that architecture yet. :)

I was a little reluctant to do that when I first read your message
because it felt like adding autoconf stuff into the Makefile and the
code should already fail gracefully on architectures without the
register mappings. But, since the Makefile already has some autoconf
like magic and it would make the code cleaner, I'll play with the idea a
bit more tomorrow.

> > diff --git a/tools/perf/arch/x86/include/arch_dwarf-regs.h b/tools/perf/arch/x86/include/arch_dwarf-regs.h
> > new file mode 100644
> > index 0000000..9e8da6a
> > --- /dev/null
> > +++ b/tools/perf/arch/x86/include/arch_dwarf-regs.h
> > @@ -0,0 +1,6 @@
> > +#ifndef _PREF_ARCH_PPC_DWARF_REGS_H
> > +#define _PREF_ARCH_PPC_DWARF_REGS_H
>
> _PREF_ARCH_X86_DWARF_REGS_H ?

Nice catch (oops)


Cheers,
-Ian