diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2015-01-17 13:24:30 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2015-01-17 13:24:30 -0500 |
commit | 59b2858f57bbd42f36aa177d21ab011a87da3de2 (patch) | |
tree | 3299a124180b88117db9ef68e4133426e2309548 | |
parent | fc7f0dd381720ea5ee5818645f7d0e9dece41cb0 (diff) | |
parent | d01de2389c0190f5959f0a1258a2e87d2fe4ca82 (diff) |
Merge branch 'perf-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull perf fixes from Ingo Molnar:
"Mostly tooling fixes, but also two PMU driver fixes"
* 'perf-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
perf tools powerpc: Use dwfl_report_elf() instead of offline.
perf tools: Fix segfault for symbol annotation on TUI
perf test: Fix dwarf unwind using libunwind.
perf tools: Avoid build splat for syscall numbers with uclibc
perf tools: Elide strlcpy warning with uclibc
perf tools: Fix statfs.f_type data type mismatch build error with uclibc
tools: Remove bitops/hweight usage of bits in tools/perf
perf machine: Fix __machine__findnew_thread() error path
perf tools: Fix building error in x86_64 when dwarf unwind is on
perf probe: Propagate error code when write(2) failed
perf/x86/intel: Fix bug for "cycles:p" and "cycles:pp" on SLM
perf/rapl: Fix sysfs_show() initialization for RAPL PMU
26 files changed, 165 insertions, 96 deletions
diff --git a/arch/x86/kernel/cpu/perf_event_intel_ds.c b/arch/x86/kernel/cpu/perf_event_intel_ds.c index 3c895d480cd7..073983398364 100644 --- a/arch/x86/kernel/cpu/perf_event_intel_ds.c +++ b/arch/x86/kernel/cpu/perf_event_intel_ds.c | |||
@@ -568,8 +568,8 @@ struct event_constraint intel_atom_pebs_event_constraints[] = { | |||
568 | }; | 568 | }; |
569 | 569 | ||
570 | struct event_constraint intel_slm_pebs_event_constraints[] = { | 570 | struct event_constraint intel_slm_pebs_event_constraints[] = { |
571 | /* UOPS_RETIRED.ALL, inv=1, cmask=16 (cycles:p). */ | 571 | /* INST_RETIRED.ANY_P, inv=1, cmask=16 (cycles:p). */ |
572 | INTEL_FLAGS_EVENT_CONSTRAINT(0x108001c2, 0xf), | 572 | INTEL_FLAGS_EVENT_CONSTRAINT(0x108000c0, 0x1), |
573 | /* Allow all events as PEBS with no flags */ | 573 | /* Allow all events as PEBS with no flags */ |
574 | INTEL_ALL_EVENT_CONSTRAINT(0, 0x1), | 574 | INTEL_ALL_EVENT_CONSTRAINT(0, 0x1), |
575 | EVENT_CONSTRAINT_END | 575 | EVENT_CONSTRAINT_END |
diff --git a/arch/x86/kernel/cpu/perf_event_intel_rapl.c b/arch/x86/kernel/cpu/perf_event_intel_rapl.c index 673f930c700f..6e434f8e5fc8 100644 --- a/arch/x86/kernel/cpu/perf_event_intel_rapl.c +++ b/arch/x86/kernel/cpu/perf_event_intel_rapl.c | |||
@@ -103,6 +103,13 @@ static struct kobj_attribute format_attr_##_var = \ | |||
103 | 103 | ||
104 | #define RAPL_CNTR_WIDTH 32 /* 32-bit rapl counters */ | 104 | #define RAPL_CNTR_WIDTH 32 /* 32-bit rapl counters */ |
105 | 105 | ||
106 | #define RAPL_EVENT_ATTR_STR(_name, v, str) \ | ||
107 | static struct perf_pmu_events_attr event_attr_##v = { \ | ||
108 | .attr = __ATTR(_name, 0444, rapl_sysfs_show, NULL), \ | ||
109 | .id = 0, \ | ||
110 | .event_str = str, \ | ||
111 | }; | ||
112 | |||
106 | struct rapl_pmu { | 113 | struct rapl_pmu { |
107 | spinlock_t lock; | 114 | spinlock_t lock; |
108 | int hw_unit; /* 1/2^hw_unit Joule */ | 115 | int hw_unit; /* 1/2^hw_unit Joule */ |
@@ -379,23 +386,36 @@ static struct attribute_group rapl_pmu_attr_group = { | |||
379 | .attrs = rapl_pmu_attrs, | 386 | .attrs = rapl_pmu_attrs, |
380 | }; | 387 | }; |
381 | 388 | ||
382 | EVENT_ATTR_STR(energy-cores, rapl_cores, "event=0x01"); | 389 | static ssize_t rapl_sysfs_show(struct device *dev, |
383 | EVENT_ATTR_STR(energy-pkg , rapl_pkg, "event=0x02"); | 390 | struct device_attribute *attr, |
384 | EVENT_ATTR_STR(energy-ram , rapl_ram, "event=0x03"); | 391 | char *page) |
385 | EVENT_ATTR_STR(energy-gpu , rapl_gpu, "event=0x04"); | 392 | { |
393 | struct perf_pmu_events_attr *pmu_attr = \ | ||
394 | container_of(attr, struct perf_pmu_events_attr, attr); | ||
395 | |||
396 | if (pmu_attr->event_str) | ||
397 | return sprintf(page, "%s", pmu_attr->event_str); | ||
398 | |||
399 | return 0; | ||
400 | } | ||
401 | |||
402 | RAPL_EVENT_ATTR_STR(energy-cores, rapl_cores, "event=0x01"); | ||
403 | RAPL_EVENT_ATTR_STR(energy-pkg , rapl_pkg, "event=0x02"); | ||
404 | RAPL_EVENT_ATTR_STR(energy-ram , rapl_ram, "event=0x03"); | ||
405 | RAPL_EVENT_ATTR_STR(energy-gpu , rapl_gpu, "event=0x04"); | ||
386 | 406 | ||
387 | EVENT_ATTR_STR(energy-cores.unit, rapl_cores_unit, "Joules"); | 407 | RAPL_EVENT_ATTR_STR(energy-cores.unit, rapl_cores_unit, "Joules"); |
388 | EVENT_ATTR_STR(energy-pkg.unit , rapl_pkg_unit, "Joules"); | 408 | RAPL_EVENT_ATTR_STR(energy-pkg.unit , rapl_pkg_unit, "Joules"); |
389 | EVENT_ATTR_STR(energy-ram.unit , rapl_ram_unit, "Joules"); | 409 | RAPL_EVENT_ATTR_STR(energy-ram.unit , rapl_ram_unit, "Joules"); |
390 | EVENT_ATTR_STR(energy-gpu.unit , rapl_gpu_unit, "Joules"); | 410 | RAPL_EVENT_ATTR_STR(energy-gpu.unit , rapl_gpu_unit, "Joules"); |
391 | 411 | ||
392 | /* | 412 | /* |
393 | * we compute in 0.23 nJ increments regardless of MSR | 413 | * we compute in 0.23 nJ increments regardless of MSR |
394 | */ | 414 | */ |
395 | EVENT_ATTR_STR(energy-cores.scale, rapl_cores_scale, "2.3283064365386962890625e-10"); | 415 | RAPL_EVENT_ATTR_STR(energy-cores.scale, rapl_cores_scale, "2.3283064365386962890625e-10"); |
396 | EVENT_ATTR_STR(energy-pkg.scale, rapl_pkg_scale, "2.3283064365386962890625e-10"); | 416 | RAPL_EVENT_ATTR_STR(energy-pkg.scale, rapl_pkg_scale, "2.3283064365386962890625e-10"); |
397 | EVENT_ATTR_STR(energy-ram.scale, rapl_ram_scale, "2.3283064365386962890625e-10"); | 417 | RAPL_EVENT_ATTR_STR(energy-ram.scale, rapl_ram_scale, "2.3283064365386962890625e-10"); |
398 | EVENT_ATTR_STR(energy-gpu.scale, rapl_gpu_scale, "2.3283064365386962890625e-10"); | 418 | RAPL_EVENT_ATTR_STR(energy-gpu.scale, rapl_gpu_scale, "2.3283064365386962890625e-10"); |
399 | 419 | ||
400 | static struct attribute *rapl_events_srv_attr[] = { | 420 | static struct attribute *rapl_events_srv_attr[] = { |
401 | EVENT_PTR(rapl_cores), | 421 | EVENT_PTR(rapl_cores), |
diff --git a/tools/include/asm-generic/bitops.h b/tools/include/asm-generic/bitops.h index 6eedba1f7732..653d1bad77de 100644 --- a/tools/include/asm-generic/bitops.h +++ b/tools/include/asm-generic/bitops.h | |||
@@ -22,6 +22,8 @@ | |||
22 | #error only <linux/bitops.h> can be included directly | 22 | #error only <linux/bitops.h> can be included directly |
23 | #endif | 23 | #endif |
24 | 24 | ||
25 | #include <asm-generic/bitops/hweight.h> | ||
26 | |||
25 | #include <asm-generic/bitops/atomic.h> | 27 | #include <asm-generic/bitops/atomic.h> |
26 | 28 | ||
27 | #endif /* __TOOLS_ASM_GENERIC_BITOPS_H */ | 29 | #endif /* __TOOLS_ASM_GENERIC_BITOPS_H */ |
diff --git a/tools/include/asm-generic/bitops/arch_hweight.h b/tools/include/asm-generic/bitops/arch_hweight.h new file mode 100644 index 000000000000..318bb2b202b0 --- /dev/null +++ b/tools/include/asm-generic/bitops/arch_hweight.h | |||
@@ -0,0 +1 @@ | |||
#include "../../../../include/asm-generic/bitops/arch_hweight.h" | |||
diff --git a/tools/include/asm-generic/bitops/const_hweight.h b/tools/include/asm-generic/bitops/const_hweight.h new file mode 100644 index 000000000000..0afd644aff83 --- /dev/null +++ b/tools/include/asm-generic/bitops/const_hweight.h | |||
@@ -0,0 +1 @@ | |||
#include "../../../../include/asm-generic/bitops/const_hweight.h" | |||
diff --git a/tools/include/asm-generic/bitops/hweight.h b/tools/include/asm-generic/bitops/hweight.h new file mode 100644 index 000000000000..290120c01a8e --- /dev/null +++ b/tools/include/asm-generic/bitops/hweight.h | |||
@@ -0,0 +1,7 @@ | |||
1 | #ifndef _TOOLS_LINUX_ASM_GENERIC_BITOPS_HWEIGHT_H_ | ||
2 | #define _TOOLS_LINUX_ASM_GENERIC_BITOPS_HWEIGHT_H_ | ||
3 | |||
4 | #include <asm-generic/bitops/arch_hweight.h> | ||
5 | #include <asm-generic/bitops/const_hweight.h> | ||
6 | |||
7 | #endif /* _TOOLS_LINUX_ASM_GENERIC_BITOPS_HWEIGHT_H_ */ | ||
diff --git a/tools/include/linux/bitops.h b/tools/include/linux/bitops.h index 26005a15e7e2..5ad9ee1dd7f6 100644 --- a/tools/include/linux/bitops.h +++ b/tools/include/linux/bitops.h | |||
@@ -1,9 +1,9 @@ | |||
1 | #ifndef _TOOLS_LINUX_BITOPS_H_ | 1 | #ifndef _TOOLS_LINUX_BITOPS_H_ |
2 | #define _TOOLS_LINUX_BITOPS_H_ | 2 | #define _TOOLS_LINUX_BITOPS_H_ |
3 | 3 | ||
4 | #include <asm/types.h> | ||
4 | #include <linux/kernel.h> | 5 | #include <linux/kernel.h> |
5 | #include <linux/compiler.h> | 6 | #include <linux/compiler.h> |
6 | #include <asm/hweight.h> | ||
7 | 7 | ||
8 | #ifndef __WORDSIZE | 8 | #ifndef __WORDSIZE |
9 | #define __WORDSIZE (__SIZEOF_LONG__ * 8) | 9 | #define __WORDSIZE (__SIZEOF_LONG__ * 8) |
@@ -19,6 +19,11 @@ | |||
19 | #define BITS_TO_U32(nr) DIV_ROUND_UP(nr, BITS_PER_BYTE * sizeof(u32)) | 19 | #define BITS_TO_U32(nr) DIV_ROUND_UP(nr, BITS_PER_BYTE * sizeof(u32)) |
20 | #define BITS_TO_BYTES(nr) DIV_ROUND_UP(nr, BITS_PER_BYTE) | 20 | #define BITS_TO_BYTES(nr) DIV_ROUND_UP(nr, BITS_PER_BYTE) |
21 | 21 | ||
22 | extern unsigned int __sw_hweight8(unsigned int w); | ||
23 | extern unsigned int __sw_hweight16(unsigned int w); | ||
24 | extern unsigned int __sw_hweight32(unsigned int w); | ||
25 | extern unsigned long __sw_hweight64(__u64 w); | ||
26 | |||
22 | /* | 27 | /* |
23 | * Include this here because some architectures need generic_ffs/fls in | 28 | * Include this here because some architectures need generic_ffs/fls in |
24 | * scope | 29 | * scope |
diff --git a/tools/lib/api/fs/debugfs.c b/tools/lib/api/fs/debugfs.c index a74fba6d7743..86ea2d7b8845 100644 --- a/tools/lib/api/fs/debugfs.c +++ b/tools/lib/api/fs/debugfs.c | |||
@@ -67,7 +67,7 @@ int debugfs_valid_mountpoint(const char *debugfs) | |||
67 | 67 | ||
68 | if (statfs(debugfs, &st_fs) < 0) | 68 | if (statfs(debugfs, &st_fs) < 0) |
69 | return -ENOENT; | 69 | return -ENOENT; |
70 | else if (st_fs.f_type != (long) DEBUGFS_MAGIC) | 70 | else if ((long)st_fs.f_type != (long)DEBUGFS_MAGIC) |
71 | return -ENOENT; | 71 | return -ENOENT; |
72 | 72 | ||
73 | return 0; | 73 | return 0; |
diff --git a/tools/lib/api/fs/fs.c b/tools/lib/api/fs/fs.c index 65d9be3f9887..128ef6332a6b 100644 --- a/tools/lib/api/fs/fs.c +++ b/tools/lib/api/fs/fs.c | |||
@@ -79,7 +79,7 @@ static int fs__valid_mount(const char *fs, long magic) | |||
79 | 79 | ||
80 | if (statfs(fs, &st_fs) < 0) | 80 | if (statfs(fs, &st_fs) < 0) |
81 | return -ENOENT; | 81 | return -ENOENT; |
82 | else if (st_fs.f_type != magic) | 82 | else if ((long)st_fs.f_type != magic) |
83 | return -ENOENT; | 83 | return -ENOENT; |
84 | 84 | ||
85 | return 0; | 85 | return 0; |
diff --git a/tools/perf/MANIFEST b/tools/perf/MANIFEST index 83e2887f91a3..fbbfdc39271d 100644 --- a/tools/perf/MANIFEST +++ b/tools/perf/MANIFEST | |||
@@ -6,12 +6,15 @@ tools/lib/symbol/kallsyms.c | |||
6 | tools/lib/symbol/kallsyms.h | 6 | tools/lib/symbol/kallsyms.h |
7 | tools/lib/util/find_next_bit.c | 7 | tools/lib/util/find_next_bit.c |
8 | tools/include/asm/bug.h | 8 | tools/include/asm/bug.h |
9 | tools/include/asm-generic/bitops/arch_hweight.h | ||
9 | tools/include/asm-generic/bitops/atomic.h | 10 | tools/include/asm-generic/bitops/atomic.h |
11 | tools/include/asm-generic/bitops/const_hweight.h | ||
10 | tools/include/asm-generic/bitops/__ffs.h | 12 | tools/include/asm-generic/bitops/__ffs.h |
11 | tools/include/asm-generic/bitops/__fls.h | 13 | tools/include/asm-generic/bitops/__fls.h |
12 | tools/include/asm-generic/bitops/find.h | 14 | tools/include/asm-generic/bitops/find.h |
13 | tools/include/asm-generic/bitops/fls64.h | 15 | tools/include/asm-generic/bitops/fls64.h |
14 | tools/include/asm-generic/bitops/fls.h | 16 | tools/include/asm-generic/bitops/fls.h |
17 | tools/include/asm-generic/bitops/hweight.h | ||
15 | tools/include/asm-generic/bitops.h | 18 | tools/include/asm-generic/bitops.h |
16 | tools/include/linux/bitops.h | 19 | tools/include/linux/bitops.h |
17 | tools/include/linux/compiler.h | 20 | tools/include/linux/compiler.h |
@@ -19,6 +22,8 @@ tools/include/linux/export.h | |||
19 | tools/include/linux/hash.h | 22 | tools/include/linux/hash.h |
20 | tools/include/linux/log2.h | 23 | tools/include/linux/log2.h |
21 | tools/include/linux/types.h | 24 | tools/include/linux/types.h |
25 | include/asm-generic/bitops/arch_hweight.h | ||
26 | include/asm-generic/bitops/const_hweight.h | ||
22 | include/asm-generic/bitops/fls64.h | 27 | include/asm-generic/bitops/fls64.h |
23 | include/asm-generic/bitops/__fls.h | 28 | include/asm-generic/bitops/__fls.h |
24 | include/asm-generic/bitops/fls.h | 29 | include/asm-generic/bitops/fls.h |
@@ -29,6 +34,7 @@ include/linux/list.h | |||
29 | include/linux/hash.h | 34 | include/linux/hash.h |
30 | include/linux/stringify.h | 35 | include/linux/stringify.h |
31 | lib/find_next_bit.c | 36 | lib/find_next_bit.c |
37 | lib/hweight.c | ||
32 | lib/rbtree.c | 38 | lib/rbtree.c |
33 | include/linux/swab.h | 39 | include/linux/swab.h |
34 | arch/*/include/asm/unistd*.h | 40 | arch/*/include/asm/unistd*.h |
diff --git a/tools/perf/Makefile.perf b/tools/perf/Makefile.perf index 67a03a825b3c..aa6a50447c32 100644 --- a/tools/perf/Makefile.perf +++ b/tools/perf/Makefile.perf | |||
@@ -232,12 +232,15 @@ LIB_H += ../include/linux/hash.h | |||
232 | LIB_H += ../../include/linux/stringify.h | 232 | LIB_H += ../../include/linux/stringify.h |
233 | LIB_H += util/include/linux/bitmap.h | 233 | LIB_H += util/include/linux/bitmap.h |
234 | LIB_H += ../include/linux/bitops.h | 234 | LIB_H += ../include/linux/bitops.h |
235 | LIB_H += ../include/asm-generic/bitops/arch_hweight.h | ||
235 | LIB_H += ../include/asm-generic/bitops/atomic.h | 236 | LIB_H += ../include/asm-generic/bitops/atomic.h |
237 | LIB_H += ../include/asm-generic/bitops/const_hweight.h | ||
236 | LIB_H += ../include/asm-generic/bitops/find.h | 238 | LIB_H += ../include/asm-generic/bitops/find.h |
237 | LIB_H += ../include/asm-generic/bitops/fls64.h | 239 | LIB_H += ../include/asm-generic/bitops/fls64.h |
238 | LIB_H += ../include/asm-generic/bitops/fls.h | 240 | LIB_H += ../include/asm-generic/bitops/fls.h |
239 | LIB_H += ../include/asm-generic/bitops/__ffs.h | 241 | LIB_H += ../include/asm-generic/bitops/__ffs.h |
240 | LIB_H += ../include/asm-generic/bitops/__fls.h | 242 | LIB_H += ../include/asm-generic/bitops/__fls.h |
243 | LIB_H += ../include/asm-generic/bitops/hweight.h | ||
241 | LIB_H += ../include/asm-generic/bitops.h | 244 | LIB_H += ../include/asm-generic/bitops.h |
242 | LIB_H += ../include/linux/compiler.h | 245 | LIB_H += ../include/linux/compiler.h |
243 | LIB_H += ../include/linux/log2.h | 246 | LIB_H += ../include/linux/log2.h |
@@ -255,7 +258,6 @@ LIB_H += util/include/linux/linkage.h | |||
255 | LIB_H += util/include/asm/asm-offsets.h | 258 | LIB_H += util/include/asm/asm-offsets.h |
256 | LIB_H += ../include/asm/bug.h | 259 | LIB_H += ../include/asm/bug.h |
257 | LIB_H += util/include/asm/byteorder.h | 260 | LIB_H += util/include/asm/byteorder.h |
258 | LIB_H += util/include/asm/hweight.h | ||
259 | LIB_H += util/include/asm/swab.h | 261 | LIB_H += util/include/asm/swab.h |
260 | LIB_H += util/include/asm/system.h | 262 | LIB_H += util/include/asm/system.h |
261 | LIB_H += util/include/asm/uaccess.h | 263 | LIB_H += util/include/asm/uaccess.h |
@@ -462,10 +464,12 @@ BUILTIN_OBJS += $(OUTPUT)builtin-bench.o | |||
462 | # Benchmark modules | 464 | # Benchmark modules |
463 | BUILTIN_OBJS += $(OUTPUT)bench/sched-messaging.o | 465 | BUILTIN_OBJS += $(OUTPUT)bench/sched-messaging.o |
464 | BUILTIN_OBJS += $(OUTPUT)bench/sched-pipe.o | 466 | BUILTIN_OBJS += $(OUTPUT)bench/sched-pipe.o |
465 | ifeq ($(RAW_ARCH),x86_64) | 467 | ifeq ($(ARCH), x86) |
468 | ifeq ($(IS_64_BIT), 1) | ||
466 | BUILTIN_OBJS += $(OUTPUT)bench/mem-memcpy-x86-64-asm.o | 469 | BUILTIN_OBJS += $(OUTPUT)bench/mem-memcpy-x86-64-asm.o |
467 | BUILTIN_OBJS += $(OUTPUT)bench/mem-memset-x86-64-asm.o | 470 | BUILTIN_OBJS += $(OUTPUT)bench/mem-memset-x86-64-asm.o |
468 | endif | 471 | endif |
472 | endif | ||
469 | BUILTIN_OBJS += $(OUTPUT)bench/mem-memcpy.o | 473 | BUILTIN_OBJS += $(OUTPUT)bench/mem-memcpy.o |
470 | BUILTIN_OBJS += $(OUTPUT)bench/futex-hash.o | 474 | BUILTIN_OBJS += $(OUTPUT)bench/futex-hash.o |
471 | BUILTIN_OBJS += $(OUTPUT)bench/futex-wake.o | 475 | BUILTIN_OBJS += $(OUTPUT)bench/futex-wake.o |
@@ -743,6 +747,9 @@ $(OUTPUT)util/kallsyms.o: ../lib/symbol/kallsyms.c $(OUTPUT)PERF-CFLAGS | |||
743 | $(OUTPUT)util/rbtree.o: ../../lib/rbtree.c $(OUTPUT)PERF-CFLAGS | 747 | $(OUTPUT)util/rbtree.o: ../../lib/rbtree.c $(OUTPUT)PERF-CFLAGS |
744 | $(QUIET_CC)$(CC) -o $@ -c $(CFLAGS) -Wno-unused-parameter -DETC_PERFCONFIG='"$(ETC_PERFCONFIG_SQ)"' $< | 748 | $(QUIET_CC)$(CC) -o $@ -c $(CFLAGS) -Wno-unused-parameter -DETC_PERFCONFIG='"$(ETC_PERFCONFIG_SQ)"' $< |
745 | 749 | ||
750 | $(OUTPUT)util/hweight.o: ../../lib/hweight.c $(OUTPUT)PERF-CFLAGS | ||
751 | $(QUIET_CC)$(CC) -o $@ -c $(CFLAGS) -Wno-unused-parameter -DETC_PERFCONFIG='"$(ETC_PERFCONFIG_SQ)"' $< | ||
752 | |||
746 | $(OUTPUT)util/find_next_bit.o: ../lib/util/find_next_bit.c $(OUTPUT)PERF-CFLAGS | 753 | $(OUTPUT)util/find_next_bit.o: ../lib/util/find_next_bit.c $(OUTPUT)PERF-CFLAGS |
747 | $(QUIET_CC)$(CC) -o $@ -c $(CFLAGS) -Wno-unused-parameter -DETC_PERFCONFIG='"$(ETC_PERFCONFIG_SQ)"' $< | 754 | $(QUIET_CC)$(CC) -o $@ -c $(CFLAGS) -Wno-unused-parameter -DETC_PERFCONFIG='"$(ETC_PERFCONFIG_SQ)"' $< |
748 | 755 | ||
diff --git a/tools/perf/arch/powerpc/util/skip-callchain-idx.c b/tools/perf/arch/powerpc/util/skip-callchain-idx.c index 3bb50eac5542..0c370f81e002 100644 --- a/tools/perf/arch/powerpc/util/skip-callchain-idx.c +++ b/tools/perf/arch/powerpc/util/skip-callchain-idx.c | |||
@@ -103,7 +103,7 @@ static Dwarf_Frame *get_eh_frame(Dwfl_Module *mod, Dwarf_Addr pc) | |||
103 | return NULL; | 103 | return NULL; |
104 | } | 104 | } |
105 | 105 | ||
106 | result = dwarf_cfi_addrframe(cfi, pc, &frame); | 106 | result = dwarf_cfi_addrframe(cfi, pc-bias, &frame); |
107 | if (result) { | 107 | if (result) { |
108 | pr_debug("%s(): %s\n", __func__, dwfl_errmsg(-1)); | 108 | pr_debug("%s(): %s\n", __func__, dwfl_errmsg(-1)); |
109 | return NULL; | 109 | return NULL; |
@@ -128,7 +128,7 @@ static Dwarf_Frame *get_dwarf_frame(Dwfl_Module *mod, Dwarf_Addr pc) | |||
128 | return NULL; | 128 | return NULL; |
129 | } | 129 | } |
130 | 130 | ||
131 | result = dwarf_cfi_addrframe(cfi, pc, &frame); | 131 | result = dwarf_cfi_addrframe(cfi, pc-bias, &frame); |
132 | if (result) { | 132 | if (result) { |
133 | pr_debug("%s(): %s\n", __func__, dwfl_errmsg(-1)); | 133 | pr_debug("%s(): %s\n", __func__, dwfl_errmsg(-1)); |
134 | return NULL; | 134 | return NULL; |
@@ -145,7 +145,7 @@ static Dwarf_Frame *get_dwarf_frame(Dwfl_Module *mod, Dwarf_Addr pc) | |||
145 | * yet used) | 145 | * yet used) |
146 | * -1 in case of errors | 146 | * -1 in case of errors |
147 | */ | 147 | */ |
148 | static int check_return_addr(struct dso *dso, Dwarf_Addr pc) | 148 | static int check_return_addr(struct dso *dso, u64 map_start, Dwarf_Addr pc) |
149 | { | 149 | { |
150 | int rc = -1; | 150 | int rc = -1; |
151 | Dwfl *dwfl; | 151 | Dwfl *dwfl; |
@@ -155,6 +155,7 @@ static int check_return_addr(struct dso *dso, Dwarf_Addr pc) | |||
155 | Dwarf_Addr start = pc; | 155 | Dwarf_Addr start = pc; |
156 | Dwarf_Addr end = pc; | 156 | Dwarf_Addr end = pc; |
157 | bool signalp; | 157 | bool signalp; |
158 | const char *exec_file = dso->long_name; | ||
158 | 159 | ||
159 | dwfl = dso->dwfl; | 160 | dwfl = dso->dwfl; |
160 | 161 | ||
@@ -165,8 +166,10 @@ static int check_return_addr(struct dso *dso, Dwarf_Addr pc) | |||
165 | return -1; | 166 | return -1; |
166 | } | 167 | } |
167 | 168 | ||
168 | if (dwfl_report_offline(dwfl, "", dso->long_name, -1) == NULL) { | 169 | mod = dwfl_report_elf(dwfl, exec_file, exec_file, -1, |
169 | pr_debug("dwfl_report_offline() failed %s\n", | 170 | map_start, false); |
171 | if (!mod) { | ||
172 | pr_debug("dwfl_report_elf() failed %s\n", | ||
170 | dwarf_errmsg(-1)); | 173 | dwarf_errmsg(-1)); |
171 | /* | 174 | /* |
172 | * We normally cache the DWARF debug info and never | 175 | * We normally cache the DWARF debug info and never |
@@ -256,10 +259,10 @@ int arch_skip_callchain_idx(struct thread *thread, struct ip_callchain *chain) | |||
256 | return skip_slot; | 259 | return skip_slot; |
257 | } | 260 | } |
258 | 261 | ||
259 | rc = check_return_addr(dso, ip); | 262 | rc = check_return_addr(dso, al.map->start, ip); |
260 | 263 | ||
261 | pr_debug("DSO %s, nr %" PRIx64 ", ip 0x%" PRIx64 "rc %d\n", | 264 | pr_debug("[DSO %s, sym %s, ip 0x%" PRIx64 "] rc %d\n", |
262 | dso->long_name, chain->nr, ip, rc); | 265 | dso->long_name, al.sym->name, ip, rc); |
263 | 266 | ||
264 | if (rc == 0) { | 267 | if (rc == 0) { |
265 | /* | 268 | /* |
diff --git a/tools/perf/bench/sched-pipe.c b/tools/perf/bench/sched-pipe.c index 07a8d7646a15..005cc283790c 100644 --- a/tools/perf/bench/sched-pipe.c +++ b/tools/perf/bench/sched-pipe.c | |||
@@ -19,12 +19,12 @@ | |||
19 | #include <stdlib.h> | 19 | #include <stdlib.h> |
20 | #include <signal.h> | 20 | #include <signal.h> |
21 | #include <sys/wait.h> | 21 | #include <sys/wait.h> |
22 | #include <linux/unistd.h> | ||
23 | #include <string.h> | 22 | #include <string.h> |
24 | #include <errno.h> | 23 | #include <errno.h> |
25 | #include <assert.h> | 24 | #include <assert.h> |
26 | #include <sys/time.h> | 25 | #include <sys/time.h> |
27 | #include <sys/types.h> | 26 | #include <sys/types.h> |
27 | #include <sys/syscall.h> | ||
28 | 28 | ||
29 | #include <pthread.h> | 29 | #include <pthread.h> |
30 | 30 | ||
diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c index 961cea183a83..616f0fcb4701 100644 --- a/tools/perf/builtin-top.c +++ b/tools/perf/builtin-top.c | |||
@@ -66,7 +66,6 @@ | |||
66 | #include <sys/utsname.h> | 66 | #include <sys/utsname.h> |
67 | #include <sys/mman.h> | 67 | #include <sys/mman.h> |
68 | 68 | ||
69 | #include <linux/unistd.h> | ||
70 | #include <linux/types.h> | 69 | #include <linux/types.h> |
71 | 70 | ||
72 | static volatile int done; | 71 | static volatile int done; |
diff --git a/tools/perf/config/Makefile b/tools/perf/config/Makefile index 5d4b039fe1ed..648e31ff4021 100644 --- a/tools/perf/config/Makefile +++ b/tools/perf/config/Makefile | |||
@@ -20,7 +20,7 @@ NO_PERF_REGS := 1 | |||
20 | 20 | ||
21 | # Additional ARCH settings for x86 | 21 | # Additional ARCH settings for x86 |
22 | ifeq ($(ARCH),x86) | 22 | ifeq ($(ARCH),x86) |
23 | ifeq (${IS_X86_64}, 1) | 23 | ifeq (${IS_64_BIT}, 1) |
24 | CFLAGS += -DHAVE_ARCH_X86_64_SUPPORT | 24 | CFLAGS += -DHAVE_ARCH_X86_64_SUPPORT |
25 | ARCH_INCLUDE = ../../arch/x86/lib/memcpy_64.S ../../arch/x86/lib/memset_64.S | 25 | ARCH_INCLUDE = ../../arch/x86/lib/memcpy_64.S ../../arch/x86/lib/memset_64.S |
26 | LIBUNWIND_LIBS = -lunwind -lunwind-x86_64 | 26 | LIBUNWIND_LIBS = -lunwind -lunwind-x86_64 |
diff --git a/tools/perf/config/Makefile.arch b/tools/perf/config/Makefile.arch index 851cd0172a76..ff95a68741d1 100644 --- a/tools/perf/config/Makefile.arch +++ b/tools/perf/config/Makefile.arch | |||
@@ -1,7 +1,7 @@ | |||
1 | 1 | ||
2 | uname_M := $(shell uname -m 2>/dev/null || echo not) | 2 | uname_M := $(shell uname -m 2>/dev/null || echo not) |
3 | 3 | ||
4 | ARCH ?= $(shell echo $(uname_M) | sed -e s/i.86/i386/ -e s/sun4u/sparc64/ \ | 4 | RAW_ARCH := $(shell echo $(uname_M) | sed -e s/i.86/i386/ -e s/sun4u/sparc64/ \ |
5 | -e s/arm.*/arm/ -e s/sa110/arm/ \ | 5 | -e s/arm.*/arm/ -e s/sa110/arm/ \ |
6 | -e s/s390x/s390/ -e s/parisc64/parisc/ \ | 6 | -e s/s390x/s390/ -e s/parisc64/parisc/ \ |
7 | -e s/ppc.*/powerpc/ -e s/mips.*/mips/ \ | 7 | -e s/ppc.*/powerpc/ -e s/mips.*/mips/ \ |
@@ -9,23 +9,23 @@ ARCH ?= $(shell echo $(uname_M) | sed -e s/i.86/i386/ -e s/sun4u/sparc64/ \ | |||
9 | -e s/tile.*/tile/ ) | 9 | -e s/tile.*/tile/ ) |
10 | 10 | ||
11 | # Additional ARCH settings for x86 | 11 | # Additional ARCH settings for x86 |
12 | ifeq ($(ARCH),i386) | 12 | ifeq ($(RAW_ARCH),i386) |
13 | override ARCH := x86 | 13 | ARCH ?= x86 |
14 | endif | 14 | endif |
15 | 15 | ||
16 | ifeq ($(ARCH),x86_64) | 16 | ifeq ($(RAW_ARCH),x86_64) |
17 | override ARCH := x86 | 17 | ARCH ?= x86 |
18 | IS_X86_64 := 0 | 18 | |
19 | ifeq (, $(findstring m32,$(CFLAGS))) | 19 | ifneq (, $(findstring m32,$(CFLAGS))) |
20 | IS_X86_64 := $(shell echo __x86_64__ | ${CC} -E -x c - | tail -n 1) | 20 | RAW_ARCH := x86_32 |
21 | RAW_ARCH := x86_64 | ||
22 | endif | 21 | endif |
23 | endif | 22 | endif |
24 | 23 | ||
25 | ifeq (${IS_X86_64}, 1) | 24 | ARCH ?= $(RAW_ARCH) |
25 | |||
26 | LP64 := $(shell echo __LP64__ | ${CC} ${CFLAGS} -E -x c - | tail -n 1) | ||
27 | ifeq ($(LP64), 1) | ||
26 | IS_64_BIT := 1 | 28 | IS_64_BIT := 1 |
27 | else ifeq ($(ARCH),x86) | ||
28 | IS_64_BIT := 0 | ||
29 | else | 29 | else |
30 | IS_64_BIT := $(shell echo __LP64__ | ${CC} ${CFLAGS} -E -x c - | tail -n 1) | 30 | IS_64_BIT := 0 |
31 | endif | 31 | endif |
diff --git a/tools/perf/perf-sys.h b/tools/perf/perf-sys.h index a3b13d7dc1d4..6ef68165c9db 100644 --- a/tools/perf/perf-sys.h +++ b/tools/perf/perf-sys.h | |||
@@ -6,7 +6,6 @@ | |||
6 | #include <sys/syscall.h> | 6 | #include <sys/syscall.h> |
7 | #include <linux/types.h> | 7 | #include <linux/types.h> |
8 | #include <linux/perf_event.h> | 8 | #include <linux/perf_event.h> |
9 | #include <asm/unistd.h> | ||
10 | 9 | ||
11 | #if defined(__i386__) | 10 | #if defined(__i386__) |
12 | #define mb() asm volatile("lock; addl $0,0(%%esp)" ::: "memory") | 11 | #define mb() asm volatile("lock; addl $0,0(%%esp)" ::: "memory") |
diff --git a/tools/perf/tests/dwarf-unwind.c b/tools/perf/tests/dwarf-unwind.c index ab28cca2cb97..0bf06bec68c7 100644 --- a/tools/perf/tests/dwarf-unwind.c +++ b/tools/perf/tests/dwarf-unwind.c | |||
@@ -11,6 +11,9 @@ | |||
11 | #include "thread.h" | 11 | #include "thread.h" |
12 | #include "callchain.h" | 12 | #include "callchain.h" |
13 | 13 | ||
14 | /* For bsearch. We try to unwind functions in shared object. */ | ||
15 | #include <stdlib.h> | ||
16 | |||
14 | static int mmap_handler(struct perf_tool *tool __maybe_unused, | 17 | static int mmap_handler(struct perf_tool *tool __maybe_unused, |
15 | union perf_event *event, | 18 | union perf_event *event, |
16 | struct perf_sample *sample __maybe_unused, | 19 | struct perf_sample *sample __maybe_unused, |
@@ -28,7 +31,7 @@ static int init_live_machine(struct machine *machine) | |||
28 | mmap_handler, machine, true); | 31 | mmap_handler, machine, true); |
29 | } | 32 | } |
30 | 33 | ||
31 | #define MAX_STACK 6 | 34 | #define MAX_STACK 8 |
32 | 35 | ||
33 | static int unwind_entry(struct unwind_entry *entry, void *arg) | 36 | static int unwind_entry(struct unwind_entry *entry, void *arg) |
34 | { | 37 | { |
@@ -37,6 +40,8 @@ static int unwind_entry(struct unwind_entry *entry, void *arg) | |||
37 | static const char *funcs[MAX_STACK] = { | 40 | static const char *funcs[MAX_STACK] = { |
38 | "test__arch_unwind_sample", | 41 | "test__arch_unwind_sample", |
39 | "unwind_thread", | 42 | "unwind_thread", |
43 | "compare", | ||
44 | "bsearch", | ||
40 | "krava_3", | 45 | "krava_3", |
41 | "krava_2", | 46 | "krava_2", |
42 | "krava_1", | 47 | "krava_1", |
@@ -88,10 +93,37 @@ static int unwind_thread(struct thread *thread) | |||
88 | return err; | 93 | return err; |
89 | } | 94 | } |
90 | 95 | ||
96 | static int global_unwind_retval = -INT_MAX; | ||
97 | |||
98 | __attribute__ ((noinline)) | ||
99 | static int compare(void *p1, void *p2) | ||
100 | { | ||
101 | /* Any possible value should be 'thread' */ | ||
102 | struct thread *thread = *(struct thread **)p1; | ||
103 | |||
104 | if (global_unwind_retval == -INT_MAX) | ||
105 | global_unwind_retval = unwind_thread(thread); | ||
106 | |||
107 | return p1 - p2; | ||
108 | } | ||
109 | |||
91 | __attribute__ ((noinline)) | 110 | __attribute__ ((noinline)) |
92 | static int krava_3(struct thread *thread) | 111 | static int krava_3(struct thread *thread) |
93 | { | 112 | { |
94 | return unwind_thread(thread); | 113 | struct thread *array[2] = {thread, thread}; |
114 | void *fp = &bsearch; | ||
115 | /* | ||
116 | * make _bsearch a volatile function pointer to | ||
117 | * prevent potential optimization, which may expand | ||
118 | * bsearch and call compare directly from this function, | ||
119 | * instead of libc shared object. | ||
120 | */ | ||
121 | void *(*volatile _bsearch)(void *, void *, size_t, | ||
122 | size_t, int (*)(void *, void *)); | ||
123 | |||
124 | _bsearch = fp; | ||
125 | _bsearch(array, &thread, 2, sizeof(struct thread **), compare); | ||
126 | return global_unwind_retval; | ||
95 | } | 127 | } |
96 | 128 | ||
97 | __attribute__ ((noinline)) | 129 | __attribute__ ((noinline)) |
diff --git a/tools/perf/util/annotate.h b/tools/perf/util/annotate.h index 0784a9420528..cadbdc90a5cb 100644 --- a/tools/perf/util/annotate.h +++ b/tools/perf/util/annotate.h | |||
@@ -116,11 +116,6 @@ struct annotation { | |||
116 | struct annotated_source *src; | 116 | struct annotated_source *src; |
117 | }; | 117 | }; |
118 | 118 | ||
119 | struct sannotation { | ||
120 | struct annotation annotation; | ||
121 | struct symbol symbol; | ||
122 | }; | ||
123 | |||
124 | static inline struct sym_hist *annotation__histogram(struct annotation *notes, int idx) | 119 | static inline struct sym_hist *annotation__histogram(struct annotation *notes, int idx) |
125 | { | 120 | { |
126 | return (((void *)¬es->src->histograms) + | 121 | return (((void *)¬es->src->histograms) + |
@@ -129,8 +124,7 @@ static inline struct sym_hist *annotation__histogram(struct annotation *notes, i | |||
129 | 124 | ||
130 | static inline struct annotation *symbol__annotation(struct symbol *sym) | 125 | static inline struct annotation *symbol__annotation(struct symbol *sym) |
131 | { | 126 | { |
132 | struct sannotation *a = container_of(sym, struct sannotation, symbol); | 127 | return (void *)sym - symbol_conf.priv_size; |
133 | return &a->annotation; | ||
134 | } | 128 | } |
135 | 129 | ||
136 | int addr_map_symbol__inc_samples(struct addr_map_symbol *ams, int evidx); | 130 | int addr_map_symbol__inc_samples(struct addr_map_symbol *ams, int evidx); |
diff --git a/tools/perf/util/cache.h b/tools/perf/util/cache.h index 5cf9e1b5989d..d04d770d90f6 100644 --- a/tools/perf/util/cache.h +++ b/tools/perf/util/cache.h | |||
@@ -71,7 +71,9 @@ extern char *perf_path(const char *fmt, ...) __attribute__((format (printf, 1, 2 | |||
71 | extern char *perf_pathdup(const char *fmt, ...) | 71 | extern char *perf_pathdup(const char *fmt, ...) |
72 | __attribute__((format (printf, 1, 2))); | 72 | __attribute__((format (printf, 1, 2))); |
73 | 73 | ||
74 | #ifndef __UCLIBC__ | ||
74 | /* Matches the libc/libbsd function attribute so we declare this unconditionally: */ | 75 | /* Matches the libc/libbsd function attribute so we declare this unconditionally: */ |
75 | extern size_t strlcpy(char *dest, const char *src, size_t size); | 76 | extern size_t strlcpy(char *dest, const char *src, size_t size); |
77 | #endif | ||
76 | 78 | ||
77 | #endif /* __PERF_CACHE_H */ | 79 | #endif /* __PERF_CACHE_H */ |
diff --git a/tools/perf/util/hweight.c b/tools/perf/util/hweight.c deleted file mode 100644 index 5c1d0d099f0d..000000000000 --- a/tools/perf/util/hweight.c +++ /dev/null | |||
@@ -1,31 +0,0 @@ | |||
1 | #include <linux/bitops.h> | ||
2 | |||
3 | /** | ||
4 | * hweightN - returns the hamming weight of a N-bit word | ||
5 | * @x: the word to weigh | ||
6 | * | ||
7 | * The Hamming Weight of a number is the total number of bits set in it. | ||
8 | */ | ||
9 | |||
10 | unsigned int hweight32(unsigned int w) | ||
11 | { | ||
12 | unsigned int res = w - ((w >> 1) & 0x55555555); | ||
13 | res = (res & 0x33333333) + ((res >> 2) & 0x33333333); | ||
14 | res = (res + (res >> 4)) & 0x0F0F0F0F; | ||
15 | res = res + (res >> 8); | ||
16 | return (res + (res >> 16)) & 0x000000FF; | ||
17 | } | ||
18 | |||
19 | unsigned long hweight64(__u64 w) | ||
20 | { | ||
21 | #if BITS_PER_LONG == 32 | ||
22 | return hweight32((unsigned int)(w >> 32)) + hweight32((unsigned int)w); | ||
23 | #elif BITS_PER_LONG == 64 | ||
24 | __u64 res = w - ((w >> 1) & 0x5555555555555555ul); | ||
25 | res = (res & 0x3333333333333333ul) + ((res >> 2) & 0x3333333333333333ul); | ||
26 | res = (res + (res >> 4)) & 0x0F0F0F0F0F0F0F0Ful; | ||
27 | res = res + (res >> 8); | ||
28 | res = res + (res >> 16); | ||
29 | return (res + (res >> 32)) & 0x00000000000000FFul; | ||
30 | #endif | ||
31 | } | ||
diff --git a/tools/perf/util/include/asm/hweight.h b/tools/perf/util/include/asm/hweight.h deleted file mode 100644 index 36cf26d434a5..000000000000 --- a/tools/perf/util/include/asm/hweight.h +++ /dev/null | |||
@@ -1,8 +0,0 @@ | |||
1 | #ifndef PERF_HWEIGHT_H | ||
2 | #define PERF_HWEIGHT_H | ||
3 | |||
4 | #include <linux/types.h> | ||
5 | unsigned int hweight32(unsigned int w); | ||
6 | unsigned long hweight64(__u64 w); | ||
7 | |||
8 | #endif /* PERF_HWEIGHT_H */ | ||
diff --git a/tools/perf/util/machine.c b/tools/perf/util/machine.c index 94de3e48b490..1bca3a9f2b16 100644 --- a/tools/perf/util/machine.c +++ b/tools/perf/util/machine.c | |||
@@ -389,7 +389,6 @@ static struct thread *__machine__findnew_thread(struct machine *machine, | |||
389 | if (th != NULL) { | 389 | if (th != NULL) { |
390 | rb_link_node(&th->rb_node, parent, p); | 390 | rb_link_node(&th->rb_node, parent, p); |
391 | rb_insert_color(&th->rb_node, &machine->threads); | 391 | rb_insert_color(&th->rb_node, &machine->threads); |
392 | machine->last_match = th; | ||
393 | 392 | ||
394 | /* | 393 | /* |
395 | * We have to initialize map_groups separately | 394 | * We have to initialize map_groups separately |
@@ -400,9 +399,12 @@ static struct thread *__machine__findnew_thread(struct machine *machine, | |||
400 | * leader and that would screwed the rb tree. | 399 | * leader and that would screwed the rb tree. |
401 | */ | 400 | */ |
402 | if (thread__init_map_groups(th, machine)) { | 401 | if (thread__init_map_groups(th, machine)) { |
402 | rb_erase(&th->rb_node, &machine->threads); | ||
403 | thread__delete(th); | 403 | thread__delete(th); |
404 | return NULL; | 404 | return NULL; |
405 | } | 405 | } |
406 | |||
407 | machine->last_match = th; | ||
406 | } | 408 | } |
407 | 409 | ||
408 | return th; | 410 | return th; |
diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c index 7f9b8632e433..94a717bf007d 100644 --- a/tools/perf/util/probe-event.c +++ b/tools/perf/util/probe-event.c | |||
@@ -2052,9 +2052,11 @@ static int write_probe_trace_event(int fd, struct probe_trace_event *tev) | |||
2052 | pr_debug("Writing event: %s\n", buf); | 2052 | pr_debug("Writing event: %s\n", buf); |
2053 | if (!probe_event_dry_run) { | 2053 | if (!probe_event_dry_run) { |
2054 | ret = write(fd, buf, strlen(buf)); | 2054 | ret = write(fd, buf, strlen(buf)); |
2055 | if (ret <= 0) | 2055 | if (ret <= 0) { |
2056 | ret = -errno; | ||
2056 | pr_warning("Failed to write event: %s\n", | 2057 | pr_warning("Failed to write event: %s\n", |
2057 | strerror_r(errno, sbuf, sizeof(sbuf))); | 2058 | strerror_r(errno, sbuf, sizeof(sbuf))); |
2059 | } | ||
2058 | } | 2060 | } |
2059 | free(buf); | 2061 | free(buf); |
2060 | return ret; | 2062 | return ret; |
diff --git a/tools/perf/util/python-ext-sources b/tools/perf/util/python-ext-sources index 16a475a7d492..6c6a6953fa93 100644 --- a/tools/perf/util/python-ext-sources +++ b/tools/perf/util/python-ext-sources | |||
@@ -10,7 +10,7 @@ util/ctype.c | |||
10 | util/evlist.c | 10 | util/evlist.c |
11 | util/evsel.c | 11 | util/evsel.c |
12 | util/cpumap.c | 12 | util/cpumap.c |
13 | util/hweight.c | 13 | ../../lib/hweight.c |
14 | util/thread_map.c | 14 | util/thread_map.c |
15 | util/util.c | 15 | util/util.c |
16 | util/xyarray.c | 16 | util/xyarray.c |
diff --git a/tools/perf/util/unwind-libunwind.c b/tools/perf/util/unwind-libunwind.c index 371219a6daf1..6edf535f65c2 100644 --- a/tools/perf/util/unwind-libunwind.c +++ b/tools/perf/util/unwind-libunwind.c | |||
@@ -185,6 +185,28 @@ static u64 elf_section_offset(int fd, const char *name) | |||
185 | return offset; | 185 | return offset; |
186 | } | 186 | } |
187 | 187 | ||
188 | #ifndef NO_LIBUNWIND_DEBUG_FRAME | ||
189 | static int elf_is_exec(int fd, const char *name) | ||
190 | { | ||
191 | Elf *elf; | ||
192 | GElf_Ehdr ehdr; | ||
193 | int retval = 0; | ||
194 | |||
195 | elf = elf_begin(fd, PERF_ELF_C_READ_MMAP, NULL); | ||
196 | if (elf == NULL) | ||
197 | return 0; | ||
198 | if (gelf_getehdr(elf, &ehdr) == NULL) | ||
199 | goto out; | ||
200 | |||
201 | retval = (ehdr.e_type == ET_EXEC); | ||
202 | |||
203 | out: | ||
204 | elf_end(elf); | ||
205 | pr_debug("unwind: elf_is_exec(%s): %d\n", name, retval); | ||
206 | return retval; | ||
207 | } | ||
208 | #endif | ||
209 | |||
188 | struct table_entry { | 210 | struct table_entry { |
189 | u32 start_ip_offset; | 211 | u32 start_ip_offset; |
190 | u32 fde_offset; | 212 | u32 fde_offset; |
@@ -322,8 +344,12 @@ find_proc_info(unw_addr_space_t as, unw_word_t ip, unw_proc_info_t *pi, | |||
322 | #ifndef NO_LIBUNWIND_DEBUG_FRAME | 344 | #ifndef NO_LIBUNWIND_DEBUG_FRAME |
323 | /* Check the .debug_frame section for unwinding info */ | 345 | /* Check the .debug_frame section for unwinding info */ |
324 | if (!read_unwind_spec_debug_frame(map->dso, ui->machine, &segbase)) { | 346 | if (!read_unwind_spec_debug_frame(map->dso, ui->machine, &segbase)) { |
347 | int fd = dso__data_fd(map->dso, ui->machine); | ||
348 | int is_exec = elf_is_exec(fd, map->dso->name); | ||
349 | unw_word_t base = is_exec ? 0 : map->start; | ||
350 | |||
325 | memset(&di, 0, sizeof(di)); | 351 | memset(&di, 0, sizeof(di)); |
326 | if (dwarf_find_debug_frame(0, &di, ip, 0, map->dso->name, | 352 | if (dwarf_find_debug_frame(0, &di, ip, base, map->dso->name, |
327 | map->start, map->end)) | 353 | map->start, map->end)) |
328 | return dwarf_search_unwind_table(as, ip, &di, pi, | 354 | return dwarf_search_unwind_table(as, ip, &di, pi, |
329 | need_unwind_info, arg); | 355 | need_unwind_info, arg); |