aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--tools/perf/Makefile36
-rw-r--r--tools/perf/arch/x86/Makefile4
-rw-r--r--tools/perf/arch/x86/util/dwarf-regs.c75
-rw-r--r--tools/perf/util/include/dwarf-regs.h8
-rw-r--r--tools/perf/util/probe-finder.c55
5 files changed, 119 insertions, 59 deletions
diff --git a/tools/perf/Makefile b/tools/perf/Makefile
index 3cb3449a964..e8bf2e1ab49 100644
--- a/tools/perf/Makefile
+++ b/tools/perf/Makefile
@@ -173,6 +173,20 @@ uname_R := $(shell sh -c 'uname -r 2>/dev/null || echo not')
173uname_P := $(shell sh -c 'uname -p 2>/dev/null || echo not') 173uname_P := $(shell sh -c 'uname -p 2>/dev/null || echo not')
174uname_V := $(shell sh -c 'uname -v 2>/dev/null || echo not') 174uname_V := $(shell sh -c 'uname -v 2>/dev/null || echo not')
175 175
176ARCH ?= $(shell echo $(uname_M) | sed -e s/i.86/i386/ -e s/sun4u/sparc64/ \
177 -e s/arm.*/arm/ -e s/sa110/arm/ \
178 -e s/s390x/s390/ -e s/parisc64/parisc/ \
179 -e s/ppc.*/powerpc/ -e s/mips.*/mips/ \
180 -e s/sh[234].*/sh/ )
181
182# Additional ARCH settings for x86
183ifeq ($(ARCH),i386)
184 ARCH := x86
185endif
186ifeq ($(ARCH),x86_64)
187 ARCH := x86
188endif
189
176# CFLAGS and LDFLAGS are for the users to override from the command line. 190# CFLAGS and LDFLAGS are for the users to override from the command line.
177 191
178# 192#
@@ -285,7 +299,7 @@ endif
285# Those must not be GNU-specific; they are shared with perl/ which may 299# Those must not be GNU-specific; they are shared with perl/ which may
286# be built by a different compiler. (Note that this is an artifact now 300# be built by a different compiler. (Note that this is an artifact now
287# but it still might be nice to keep that distinction.) 301# but it still might be nice to keep that distinction.)
288BASIC_CFLAGS = -Iutil/include 302BASIC_CFLAGS = -Iutil/include -Iarch/$(ARCH)/include
289BASIC_LDFLAGS = 303BASIC_LDFLAGS =
290 304
291# Guard against environment variables 305# Guard against environment variables
@@ -367,6 +381,7 @@ LIB_H += util/include/asm/byteorder.h
367LIB_H += util/include/asm/swab.h 381LIB_H += util/include/asm/swab.h
368LIB_H += util/include/asm/system.h 382LIB_H += util/include/asm/system.h
369LIB_H += util/include/asm/uaccess.h 383LIB_H += util/include/asm/uaccess.h
384LIB_H += util/include/dwarf-regs.h
370LIB_H += perf.h 385LIB_H += perf.h
371LIB_H += util/cache.h 386LIB_H += util/cache.h
372LIB_H += util/callchain.h 387LIB_H += util/callchain.h
@@ -487,6 +502,15 @@ PERFLIBS = $(LIB_FILE)
487-include config.mak.autogen 502-include config.mak.autogen
488-include config.mak 503-include config.mak
489 504
505ifndef NO_DWARF
506ifneq ($(shell sh -c "(echo '\#include <dwarf.h>'; echo '\#include <libdw.h>'; echo 'int main(void) { Dwarf *dbg; dbg = dwarf_begin(0, DWARF_C_READ); return (long)dbg; }') | $(CC) -x c - $(ALL_CFLAGS) -I/usr/include/elfutils -ldw -lelf -o $(BITBUCKET) $(ALL_LDFLAGS) $(EXTLIBS) "$(QUIET_STDERR)" && echo y"), y)
507 msg := $(warning No libdw.h found or old libdw.h found, disables dwarf support. Please install elfutils-devel/elfutils-dev);
508 NO_DWARF := 1
509endif # Dwarf support
510endif # NO_DWARF
511
512-include arch/$(ARCH)/Makefile
513
490ifeq ($(uname_S),Darwin) 514ifeq ($(uname_S),Darwin)
491 ifndef NO_FINK 515 ifndef NO_FINK
492 ifeq ($(shell test -d /sw/lib && echo y),y) 516 ifeq ($(shell test -d /sw/lib && echo y),y)
@@ -519,15 +543,15 @@ else
519 msg := $(error No libelf.h/libelf found, please install libelf-dev/elfutils-libelf-devel and glibc-dev[el]); 543 msg := $(error No libelf.h/libelf found, please install libelf-dev/elfutils-libelf-devel and glibc-dev[el]);
520endif 544endif
521 545
522ifneq ($(shell sh -c "(echo '\#include <dwarf.h>'; echo '\#include <libdw.h>'; echo 'int main(void) { Dwarf *dbg; dbg = dwarf_begin(0, DWARF_C_READ); return (long)dbg; }') | $(CC) -x c - $(ALL_CFLAGS) -I/usr/include/elfutils -ldw -lelf -o $(BITBUCKET) $(ALL_LDFLAGS) $(EXTLIBS) "$(QUIET_STDERR)" && echo y"), y)
523 msg := $(warning No libdw.h found or old libdw.h found, disables dwarf support. Please install elfutils-devel/elfutils-dev);
524else
525ifndef NO_DWARF 546ifndef NO_DWARF
547ifeq ($(origin PERF_HAVE_DWARF_REGS), undefined)
548 msg := $(warning DWARF register mappings have not been defined for architecture $(ARCH), DWARF support disabled);
549else
526 BASIC_CFLAGS += -I/usr/include/elfutils -DDWARF_SUPPORT 550 BASIC_CFLAGS += -I/usr/include/elfutils -DDWARF_SUPPORT
527 EXTLIBS += -lelf -ldw 551 EXTLIBS += -lelf -ldw
528 LIB_OBJS += $(OUTPUT)util/probe-finder.o 552 LIB_OBJS += $(OUTPUT)util/probe-finder.o
529endif 553endif # PERF_HAVE_DWARF_REGS
530endif 554endif # NO_DWARF
531 555
532ifneq ($(shell sh -c "(echo '\#include <newt.h>'; echo 'int main(void) { newtInit(); newtCls(); return newtFinished(); }') | $(CC) -x c - $(ALL_CFLAGS) -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -lnewt -o $(BITBUCKET) $(ALL_LDFLAGS) $(EXTLIBS) "$(QUIET_STDERR)" && echo y"), y) 556ifneq ($(shell sh -c "(echo '\#include <newt.h>'; echo 'int main(void) { newtInit(); newtCls(); return newtFinished(); }') | $(CC) -x c - $(ALL_CFLAGS) -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -lnewt -o $(BITBUCKET) $(ALL_LDFLAGS) $(EXTLIBS) "$(QUIET_STDERR)" && echo y"), y)
533 msg := $(warning newt not found, disables TUI support. Please install newt-devel or libnewt-dev); 557 msg := $(warning newt not found, disables TUI support. Please install newt-devel or libnewt-dev);
diff --git a/tools/perf/arch/x86/Makefile b/tools/perf/arch/x86/Makefile
new file mode 100644
index 00000000000..15130b50dfe
--- /dev/null
+++ b/tools/perf/arch/x86/Makefile
@@ -0,0 +1,4 @@
1ifndef NO_DWARF
2PERF_HAVE_DWARF_REGS := 1
3LIB_OBJS += $(OUTPUT)arch/$(ARCH)/util/dwarf-regs.o
4endif
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 00000000000..a794d308192
--- /dev/null
+++ b/tools/perf/arch/x86/util/dwarf-regs.c
@@ -0,0 +1,75 @@
1/*
2 * dwarf-regs.c : Mapping of DWARF debug register numbers into register names.
3 * Extracted from probe-finder.c
4 *
5 * Written by Masami Hiramatsu <mhiramat@redhat.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20 *
21 */
22
23#include <libio.h>
24#include <dwarf-regs.h>
25
26/*
27 * Generic dwarf analysis helpers
28 */
29
30#define X86_32_MAX_REGS 8
31const char *x86_32_regs_table[X86_32_MAX_REGS] = {
32 "%ax",
33 "%cx",
34 "%dx",
35 "%bx",
36 "$stack", /* Stack address instead of %sp */
37 "%bp",
38 "%si",
39 "%di",
40};
41
42#define X86_64_MAX_REGS 16
43const char *x86_64_regs_table[X86_64_MAX_REGS] = {
44 "%ax",
45 "%dx",
46 "%cx",
47 "%bx",
48 "%si",
49 "%di",
50 "%bp",
51 "%sp",
52 "%r8",
53 "%r9",
54 "%r10",
55 "%r11",
56 "%r12",
57 "%r13",
58 "%r14",
59 "%r15",
60};
61
62/* TODO: switching by dwarf address size */
63#ifdef __x86_64__
64#define ARCH_MAX_REGS X86_64_MAX_REGS
65#define arch_regs_table x86_64_regs_table
66#else
67#define ARCH_MAX_REGS X86_32_MAX_REGS
68#define arch_regs_table x86_32_regs_table
69#endif
70
71/* Return architecture dependent register string (for kprobe-tracer) */
72const char *get_arch_regstr(unsigned int n)
73{
74 return (n <= ARCH_MAX_REGS) ? arch_regs_table[n] : NULL;
75}
diff --git a/tools/perf/util/include/dwarf-regs.h b/tools/perf/util/include/dwarf-regs.h
new file mode 100644
index 00000000000..cf6727e99c4
--- /dev/null
+++ b/tools/perf/util/include/dwarf-regs.h
@@ -0,0 +1,8 @@
1#ifndef _PERF_DWARF_REGS_H_
2#define _PERF_DWARF_REGS_H_
3
4#ifdef DWARF_SUPPORT
5const char *get_arch_regstr(unsigned int n);
6#endif
7
8#endif
diff --git a/tools/perf/util/probe-finder.c b/tools/perf/util/probe-finder.c
index 3e7977560be..e7ee52fd0e0 100644
--- a/tools/perf/util/probe-finder.c
+++ b/tools/perf/util/probe-finder.c
@@ -31,6 +31,7 @@
31#include <string.h> 31#include <string.h>
32#include <stdarg.h> 32#include <stdarg.h>
33#include <ctype.h> 33#include <ctype.h>
34#include <dwarf-regs.h>
34 35
35#include "string.h" 36#include "string.h"
36#include "event.h" 37#include "event.h"
@@ -38,61 +39,9 @@
38#include "util.h" 39#include "util.h"
39#include "probe-finder.h" 40#include "probe-finder.h"
40 41
41
42/*
43 * Generic dwarf analysis helpers
44 */
45
46#define X86_32_MAX_REGS 8
47const char *x86_32_regs_table[X86_32_MAX_REGS] = {
48 "%ax",
49 "%cx",
50 "%dx",
51 "%bx",
52 "$stack", /* Stack address instead of %sp */
53 "%bp",
54 "%si",
55 "%di",
56};
57
58#define X86_64_MAX_REGS 16
59const char *x86_64_regs_table[X86_64_MAX_REGS] = {
60 "%ax",
61 "%dx",
62 "%cx",
63 "%bx",
64 "%si",
65 "%di",
66 "%bp",
67 "%sp",
68 "%r8",
69 "%r9",
70 "%r10",
71 "%r11",
72 "%r12",
73 "%r13",
74 "%r14",
75 "%r15",
76};
77
78/* TODO: switching by dwarf address size */
79#ifdef __x86_64__
80#define ARCH_MAX_REGS X86_64_MAX_REGS
81#define arch_regs_table x86_64_regs_table
82#else
83#define ARCH_MAX_REGS X86_32_MAX_REGS
84#define arch_regs_table x86_32_regs_table
85#endif
86
87/* Kprobe tracer basic type is up to u64 */ 42/* Kprobe tracer basic type is up to u64 */
88#define MAX_BASIC_TYPE_BITS 64 43#define MAX_BASIC_TYPE_BITS 64
89 44
90/* Return architecture dependent register string (for kprobe-tracer) */
91static const char *get_arch_regstr(unsigned int n)
92{
93 return (n <= ARCH_MAX_REGS) ? arch_regs_table[n] : NULL;
94}
95
96/* 45/*
97 * Compare the tail of two strings. 46 * Compare the tail of two strings.
98 * Return 0 if whole of either string is same as another's tail part. 47 * Return 0 if whole of either string is same as another's tail part.
@@ -447,7 +396,7 @@ static int convert_location(Dwarf_Op *op, struct probe_finder *pf)
447 396
448 regs = get_arch_regstr(regn); 397 regs = get_arch_regstr(regn);
449 if (!regs) { 398 if (!regs) {
450 pr_warning("%u exceeds max register number.\n", regn); 399 pr_warning("Mapping for DWARF register number %u missing on this architecture.", regn);
451 return -ERANGE; 400 return -ERANGE;
452 } 401 }
453 402