diff options
-rw-r--r-- | tools/perf/Makefile | 36 | ||||
-rw-r--r-- | tools/perf/arch/x86/Makefile | 4 | ||||
-rw-r--r-- | tools/perf/arch/x86/util/dwarf-regs.c | 75 | ||||
-rw-r--r-- | tools/perf/util/include/dwarf-regs.h | 8 | ||||
-rw-r--r-- | tools/perf/util/probe-finder.c | 55 |
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') | |||
173 | uname_P := $(shell sh -c 'uname -p 2>/dev/null || echo not') | 173 | uname_P := $(shell sh -c 'uname -p 2>/dev/null || echo not') |
174 | uname_V := $(shell sh -c 'uname -v 2>/dev/null || echo not') | 174 | uname_V := $(shell sh -c 'uname -v 2>/dev/null || echo not') |
175 | 175 | ||
176 | ARCH ?= $(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 | ||
183 | ifeq ($(ARCH),i386) | ||
184 | ARCH := x86 | ||
185 | endif | ||
186 | ifeq ($(ARCH),x86_64) | ||
187 | ARCH := x86 | ||
188 | endif | ||
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.) |
288 | BASIC_CFLAGS = -Iutil/include | 302 | BASIC_CFLAGS = -Iutil/include -Iarch/$(ARCH)/include |
289 | BASIC_LDFLAGS = | 303 | BASIC_LDFLAGS = |
290 | 304 | ||
291 | # Guard against environment variables | 305 | # Guard against environment variables |
@@ -367,6 +381,7 @@ LIB_H += util/include/asm/byteorder.h | |||
367 | LIB_H += util/include/asm/swab.h | 381 | LIB_H += util/include/asm/swab.h |
368 | LIB_H += util/include/asm/system.h | 382 | LIB_H += util/include/asm/system.h |
369 | LIB_H += util/include/asm/uaccess.h | 383 | LIB_H += util/include/asm/uaccess.h |
384 | LIB_H += util/include/dwarf-regs.h | ||
370 | LIB_H += perf.h | 385 | LIB_H += perf.h |
371 | LIB_H += util/cache.h | 386 | LIB_H += util/cache.h |
372 | LIB_H += util/callchain.h | 387 | LIB_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 | ||
505 | ifndef NO_DWARF | ||
506 | ifneq ($(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 | ||
509 | endif # Dwarf support | ||
510 | endif # NO_DWARF | ||
511 | |||
512 | -include arch/$(ARCH)/Makefile | ||
513 | |||
490 | ifeq ($(uname_S),Darwin) | 514 | ifeq ($(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]); |
520 | endif | 544 | endif |
521 | 545 | ||
522 | ifneq ($(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); | ||
524 | else | ||
525 | ifndef NO_DWARF | 546 | ifndef NO_DWARF |
547 | ifeq ($(origin PERF_HAVE_DWARF_REGS), undefined) | ||
548 | msg := $(warning DWARF register mappings have not been defined for architecture $(ARCH), DWARF support disabled); | ||
549 | else | ||
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 |
529 | endif | 553 | endif # PERF_HAVE_DWARF_REGS |
530 | endif | 554 | endif # NO_DWARF |
531 | 555 | ||
532 | ifneq ($(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) | 556 | ifneq ($(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 @@ | |||
1 | ifndef NO_DWARF | ||
2 | PERF_HAVE_DWARF_REGS := 1 | ||
3 | LIB_OBJS += $(OUTPUT)arch/$(ARCH)/util/dwarf-regs.o | ||
4 | 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 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 | ||
31 | const 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 | ||
43 | const 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) */ | ||
72 | const 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 | ||
5 | const 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 | ||
47 | const 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 | ||
59 | const 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) */ | ||
91 | static 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 | ||