diff options
Diffstat (limited to 'tools')
30 files changed, 266 insertions, 92 deletions
diff --git a/tools/lib/lockdep/Makefile b/tools/lib/lockdep/Makefile index da8b7aa3d351..07b0b7542511 100644 --- a/tools/lib/lockdep/Makefile +++ b/tools/lib/lockdep/Makefile | |||
@@ -87,8 +87,8 @@ endif # BUILD_SRC | |||
87 | # We process the rest of the Makefile if this is the final invocation of make | 87 | # We process the rest of the Makefile if this is the final invocation of make |
88 | ifeq ($(skip-makefile),) | 88 | ifeq ($(skip-makefile),) |
89 | 89 | ||
90 | srctree := $(if $(BUILD_SRC),$(BUILD_SRC),$(CURDIR)) | 90 | srctree := $(realpath $(if $(BUILD_SRC),$(BUILD_SRC),$(CURDIR))) |
91 | objtree := $(CURDIR) | 91 | objtree := $(realpath $(CURDIR)) |
92 | src := $(srctree) | 92 | src := $(srctree) |
93 | obj := $(objtree) | 93 | obj := $(objtree) |
94 | 94 | ||
@@ -112,7 +112,7 @@ export Q VERBOSE | |||
112 | 112 | ||
113 | LIBLOCKDEP_VERSION = $(LL_VERSION).$(LL_PATCHLEVEL).$(LL_EXTRAVERSION) | 113 | LIBLOCKDEP_VERSION = $(LL_VERSION).$(LL_PATCHLEVEL).$(LL_EXTRAVERSION) |
114 | 114 | ||
115 | INCLUDES = -I. -I/usr/local/include -I./uinclude $(CONFIG_INCLUDES) | 115 | INCLUDES = -I. -I/usr/local/include -I./uinclude -I./include $(CONFIG_INCLUDES) |
116 | 116 | ||
117 | # Set compile option CFLAGS if not set elsewhere | 117 | # Set compile option CFLAGS if not set elsewhere |
118 | CFLAGS ?= -g -DCONFIG_LOCKDEP -DCONFIG_STACKTRACE -DCONFIG_PROVE_LOCKING -DBITS_PER_LONG=__WORDSIZE -DLIBLOCKDEP_VERSION='"$(LIBLOCKDEP_VERSION)"' -rdynamic -O0 -g | 118 | CFLAGS ?= -g -DCONFIG_LOCKDEP -DCONFIG_STACKTRACE -DCONFIG_PROVE_LOCKING -DBITS_PER_LONG=__WORDSIZE -DLIBLOCKDEP_VERSION='"$(LIBLOCKDEP_VERSION)"' -rdynamic -O0 -g |
diff --git a/tools/lib/lockdep/preload.c b/tools/lib/lockdep/preload.c index f8465a811aa5..23bd69cb5ade 100644 --- a/tools/lib/lockdep/preload.c +++ b/tools/lib/lockdep/preload.c | |||
@@ -418,7 +418,7 @@ int pthread_rwlock_unlock(pthread_rwlock_t *rwlock) | |||
418 | 418 | ||
419 | __attribute__((constructor)) static void init_preload(void) | 419 | __attribute__((constructor)) static void init_preload(void) |
420 | { | 420 | { |
421 | if (__init_state != done) | 421 | if (__init_state == done) |
422 | return; | 422 | return; |
423 | 423 | ||
424 | #ifndef __GLIBC__ | 424 | #ifndef __GLIBC__ |
diff --git a/tools/lib/lockdep/run_tests.sh b/tools/lib/lockdep/run_tests.sh index 5334ad9d39b7..5334ad9d39b7 100644..100755 --- a/tools/lib/lockdep/run_tests.sh +++ b/tools/lib/lockdep/run_tests.sh | |||
diff --git a/tools/lib/lockdep/uinclude/asm/hash.h b/tools/lib/lockdep/uinclude/asm/hash.h new file mode 100644 index 000000000000..d82b170bb216 --- /dev/null +++ b/tools/lib/lockdep/uinclude/asm/hash.h | |||
@@ -0,0 +1,6 @@ | |||
1 | #ifndef __ASM_GENERIC_HASH_H | ||
2 | #define __ASM_GENERIC_HASH_H | ||
3 | |||
4 | /* Stub */ | ||
5 | |||
6 | #endif /* __ASM_GENERIC_HASH_H */ | ||
diff --git a/tools/lib/lockdep/uinclude/linux/rcu.h b/tools/lib/lockdep/uinclude/linux/rcu.h index 4c99fcb5da27..042ee8e463c9 100644 --- a/tools/lib/lockdep/uinclude/linux/rcu.h +++ b/tools/lib/lockdep/uinclude/linux/rcu.h | |||
@@ -13,4 +13,9 @@ static inline int rcu_is_cpu_idle(void) | |||
13 | return 1; | 13 | return 1; |
14 | } | 14 | } |
15 | 15 | ||
16 | static inline bool rcu_is_watching(void) | ||
17 | { | ||
18 | return false; | ||
19 | } | ||
20 | |||
16 | #endif | 21 | #endif |
diff --git a/tools/perf/builtin-buildid-cache.c b/tools/perf/builtin-buildid-cache.c index cfede86161d8..b22dbb16f877 100644 --- a/tools/perf/builtin-buildid-cache.c +++ b/tools/perf/builtin-buildid-cache.c | |||
@@ -63,11 +63,35 @@ static int build_id_cache__kcore_dir(char *dir, size_t sz) | |||
63 | return 0; | 63 | return 0; |
64 | } | 64 | } |
65 | 65 | ||
66 | static bool same_kallsyms_reloc(const char *from_dir, char *to_dir) | ||
67 | { | ||
68 | char from[PATH_MAX]; | ||
69 | char to[PATH_MAX]; | ||
70 | const char *name; | ||
71 | u64 addr1 = 0, addr2 = 0; | ||
72 | int i; | ||
73 | |||
74 | scnprintf(from, sizeof(from), "%s/kallsyms", from_dir); | ||
75 | scnprintf(to, sizeof(to), "%s/kallsyms", to_dir); | ||
76 | |||
77 | for (i = 0; (name = ref_reloc_sym_names[i]) != NULL; i++) { | ||
78 | addr1 = kallsyms__get_function_start(from, name); | ||
79 | if (addr1) | ||
80 | break; | ||
81 | } | ||
82 | |||
83 | if (name) | ||
84 | addr2 = kallsyms__get_function_start(to, name); | ||
85 | |||
86 | return addr1 == addr2; | ||
87 | } | ||
88 | |||
66 | static int build_id_cache__kcore_existing(const char *from_dir, char *to_dir, | 89 | static int build_id_cache__kcore_existing(const char *from_dir, char *to_dir, |
67 | size_t to_dir_sz) | 90 | size_t to_dir_sz) |
68 | { | 91 | { |
69 | char from[PATH_MAX]; | 92 | char from[PATH_MAX]; |
70 | char to[PATH_MAX]; | 93 | char to[PATH_MAX]; |
94 | char to_subdir[PATH_MAX]; | ||
71 | struct dirent *dent; | 95 | struct dirent *dent; |
72 | int ret = -1; | 96 | int ret = -1; |
73 | DIR *d; | 97 | DIR *d; |
@@ -86,10 +110,11 @@ static int build_id_cache__kcore_existing(const char *from_dir, char *to_dir, | |||
86 | continue; | 110 | continue; |
87 | scnprintf(to, sizeof(to), "%s/%s/modules", to_dir, | 111 | scnprintf(to, sizeof(to), "%s/%s/modules", to_dir, |
88 | dent->d_name); | 112 | dent->d_name); |
89 | if (!compare_proc_modules(from, to)) { | 113 | scnprintf(to_subdir, sizeof(to_subdir), "%s/%s", |
90 | scnprintf(to, sizeof(to), "%s/%s", to_dir, | 114 | to_dir, dent->d_name); |
91 | dent->d_name); | 115 | if (!compare_proc_modules(from, to) && |
92 | strlcpy(to_dir, to, to_dir_sz); | 116 | same_kallsyms_reloc(from_dir, to_subdir)) { |
117 | strlcpy(to_dir, to_subdir, to_dir_sz); | ||
93 | ret = 0; | 118 | ret = 0; |
94 | break; | 119 | break; |
95 | } | 120 | } |
diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c index 3c394bf16fa8..af47531b82ec 100644 --- a/tools/perf/builtin-record.c +++ b/tools/perf/builtin-record.c | |||
@@ -287,10 +287,7 @@ static void perf_event__synthesize_guest_os(struct machine *machine, void *data) | |||
287 | * have no _text sometimes. | 287 | * have no _text sometimes. |
288 | */ | 288 | */ |
289 | err = perf_event__synthesize_kernel_mmap(tool, process_synthesized_event, | 289 | err = perf_event__synthesize_kernel_mmap(tool, process_synthesized_event, |
290 | machine, "_text"); | 290 | machine); |
291 | if (err < 0) | ||
292 | err = perf_event__synthesize_kernel_mmap(tool, process_synthesized_event, | ||
293 | machine, "_stext"); | ||
294 | if (err < 0) | 291 | if (err < 0) |
295 | pr_err("Couldn't record guest kernel [%d]'s reference" | 292 | pr_err("Couldn't record guest kernel [%d]'s reference" |
296 | " relocation symbol.\n", machine->pid); | 293 | " relocation symbol.\n", machine->pid); |
@@ -457,10 +454,7 @@ static int __cmd_record(struct record *rec, int argc, const char **argv) | |||
457 | } | 454 | } |
458 | 455 | ||
459 | err = perf_event__synthesize_kernel_mmap(tool, process_synthesized_event, | 456 | err = perf_event__synthesize_kernel_mmap(tool, process_synthesized_event, |
460 | machine, "_text"); | 457 | machine); |
461 | if (err < 0) | ||
462 | err = perf_event__synthesize_kernel_mmap(tool, process_synthesized_event, | ||
463 | machine, "_stext"); | ||
464 | if (err < 0) | 458 | if (err < 0) |
465 | pr_err("Couldn't record kernel reference relocation symbol\n" | 459 | pr_err("Couldn't record kernel reference relocation symbol\n" |
466 | "Symbol resolution may be skewed if relocation was used (e.g. kexec).\n" | 460 | "Symbol resolution may be skewed if relocation was used (e.g. kexec).\n" |
diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c index 3c53ec268fbc..02f985f3a396 100644 --- a/tools/perf/builtin-report.c +++ b/tools/perf/builtin-report.c | |||
@@ -113,14 +113,16 @@ static int report__add_mem_hist_entry(struct perf_tool *tool, struct addr_locati | |||
113 | if (!he) | 113 | if (!he) |
114 | return -ENOMEM; | 114 | return -ENOMEM; |
115 | 115 | ||
116 | err = hist_entry__inc_addr_samples(he, evsel->idx, al->addr); | 116 | if (ui__has_annotation()) { |
117 | if (err) | 117 | err = hist_entry__inc_addr_samples(he, evsel->idx, al->addr); |
118 | goto out; | 118 | if (err) |
119 | goto out; | ||
119 | 120 | ||
120 | mx = he->mem_info; | 121 | mx = he->mem_info; |
121 | err = addr_map_symbol__inc_samples(&mx->daddr, evsel->idx); | 122 | err = addr_map_symbol__inc_samples(&mx->daddr, evsel->idx); |
122 | if (err) | 123 | if (err) |
123 | goto out; | 124 | goto out; |
125 | } | ||
124 | 126 | ||
125 | evsel->hists.stats.total_period += cost; | 127 | evsel->hists.stats.total_period += cost; |
126 | hists__inc_nr_events(&evsel->hists, PERF_RECORD_SAMPLE); | 128 | hists__inc_nr_events(&evsel->hists, PERF_RECORD_SAMPLE); |
@@ -164,14 +166,18 @@ static int report__add_branch_hist_entry(struct perf_tool *tool, struct addr_loc | |||
164 | he = __hists__add_entry(&evsel->hists, al, parent, &bi[i], NULL, | 166 | he = __hists__add_entry(&evsel->hists, al, parent, &bi[i], NULL, |
165 | 1, 1, 0); | 167 | 1, 1, 0); |
166 | if (he) { | 168 | if (he) { |
167 | bx = he->branch_info; | 169 | if (ui__has_annotation()) { |
168 | err = addr_map_symbol__inc_samples(&bx->from, evsel->idx); | 170 | bx = he->branch_info; |
169 | if (err) | 171 | err = addr_map_symbol__inc_samples(&bx->from, |
170 | goto out; | 172 | evsel->idx); |
171 | 173 | if (err) | |
172 | err = addr_map_symbol__inc_samples(&bx->to, evsel->idx); | 174 | goto out; |
173 | if (err) | 175 | |
174 | goto out; | 176 | err = addr_map_symbol__inc_samples(&bx->to, |
177 | evsel->idx); | ||
178 | if (err) | ||
179 | goto out; | ||
180 | } | ||
175 | 181 | ||
176 | evsel->hists.stats.total_period += 1; | 182 | evsel->hists.stats.total_period += 1; |
177 | hists__inc_nr_events(&evsel->hists, PERF_RECORD_SAMPLE); | 183 | hists__inc_nr_events(&evsel->hists, PERF_RECORD_SAMPLE); |
@@ -205,7 +211,9 @@ static int report__add_hist_entry(struct perf_tool *tool, struct perf_evsel *evs | |||
205 | if (err) | 211 | if (err) |
206 | goto out; | 212 | goto out; |
207 | 213 | ||
208 | err = hist_entry__inc_addr_samples(he, evsel->idx, al->addr); | 214 | if (ui__has_annotation()) |
215 | err = hist_entry__inc_addr_samples(he, evsel->idx, al->addr); | ||
216 | |||
209 | evsel->hists.stats.total_period += sample->period; | 217 | evsel->hists.stats.total_period += sample->period; |
210 | hists__inc_nr_events(&evsel->hists, PERF_RECORD_SAMPLE); | 218 | hists__inc_nr_events(&evsel->hists, PERF_RECORD_SAMPLE); |
211 | out: | 219 | out: |
diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c index 76cd510d34d0..5f989a7d8bc2 100644 --- a/tools/perf/builtin-top.c +++ b/tools/perf/builtin-top.c | |||
@@ -176,7 +176,7 @@ static void perf_top__record_precise_ip(struct perf_top *top, | |||
176 | { | 176 | { |
177 | struct annotation *notes; | 177 | struct annotation *notes; |
178 | struct symbol *sym; | 178 | struct symbol *sym; |
179 | int err; | 179 | int err = 0; |
180 | 180 | ||
181 | if (he == NULL || he->ms.sym == NULL || | 181 | if (he == NULL || he->ms.sym == NULL || |
182 | ((top->sym_filter_entry == NULL || | 182 | ((top->sym_filter_entry == NULL || |
@@ -190,7 +190,9 @@ static void perf_top__record_precise_ip(struct perf_top *top, | |||
190 | return; | 190 | return; |
191 | 191 | ||
192 | ip = he->ms.map->map_ip(he->ms.map, ip); | 192 | ip = he->ms.map->map_ip(he->ms.map, ip); |
193 | err = hist_entry__inc_addr_samples(he, counter, ip); | 193 | |
194 | if (ui__has_annotation()) | ||
195 | err = hist_entry__inc_addr_samples(he, counter, ip); | ||
194 | 196 | ||
195 | pthread_mutex_unlock(¬es->lock); | 197 | pthread_mutex_unlock(¬es->lock); |
196 | 198 | ||
diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c index 896f27047ed6..6aa6fb6f7bd9 100644 --- a/tools/perf/builtin-trace.c +++ b/tools/perf/builtin-trace.c | |||
@@ -37,6 +37,10 @@ | |||
37 | # define MADV_UNMERGEABLE 13 | 37 | # define MADV_UNMERGEABLE 13 |
38 | #endif | 38 | #endif |
39 | 39 | ||
40 | #ifndef EFD_SEMAPHORE | ||
41 | # define EFD_SEMAPHORE 1 | ||
42 | #endif | ||
43 | |||
40 | struct tp_field { | 44 | struct tp_field { |
41 | int offset; | 45 | int offset; |
42 | union { | 46 | union { |
@@ -279,6 +283,11 @@ static size_t syscall_arg__scnprintf_strarray(char *bf, size_t size, | |||
279 | 283 | ||
280 | #define SCA_STRARRAY syscall_arg__scnprintf_strarray | 284 | #define SCA_STRARRAY syscall_arg__scnprintf_strarray |
281 | 285 | ||
286 | #if defined(__i386__) || defined(__x86_64__) | ||
287 | /* | ||
288 | * FIXME: Make this available to all arches as soon as the ioctl beautifier | ||
289 | * gets rewritten to support all arches. | ||
290 | */ | ||
282 | static size_t syscall_arg__scnprintf_strhexarray(char *bf, size_t size, | 291 | static size_t syscall_arg__scnprintf_strhexarray(char *bf, size_t size, |
283 | struct syscall_arg *arg) | 292 | struct syscall_arg *arg) |
284 | { | 293 | { |
@@ -286,6 +295,7 @@ static size_t syscall_arg__scnprintf_strhexarray(char *bf, size_t size, | |||
286 | } | 295 | } |
287 | 296 | ||
288 | #define SCA_STRHEXARRAY syscall_arg__scnprintf_strhexarray | 297 | #define SCA_STRHEXARRAY syscall_arg__scnprintf_strhexarray |
298 | #endif /* defined(__i386__) || defined(__x86_64__) */ | ||
289 | 299 | ||
290 | static size_t syscall_arg__scnprintf_fd(char *bf, size_t size, | 300 | static size_t syscall_arg__scnprintf_fd(char *bf, size_t size, |
291 | struct syscall_arg *arg); | 301 | struct syscall_arg *arg); |
@@ -839,6 +849,10 @@ static size_t syscall_arg__scnprintf_signum(char *bf, size_t size, struct syscal | |||
839 | 849 | ||
840 | #define SCA_SIGNUM syscall_arg__scnprintf_signum | 850 | #define SCA_SIGNUM syscall_arg__scnprintf_signum |
841 | 851 | ||
852 | #if defined(__i386__) || defined(__x86_64__) | ||
853 | /* | ||
854 | * FIXME: Make this available to all arches. | ||
855 | */ | ||
842 | #define TCGETS 0x5401 | 856 | #define TCGETS 0x5401 |
843 | 857 | ||
844 | static const char *tioctls[] = { | 858 | static const char *tioctls[] = { |
@@ -860,6 +874,7 @@ static const char *tioctls[] = { | |||
860 | }; | 874 | }; |
861 | 875 | ||
862 | static DEFINE_STRARRAY_OFFSET(tioctls, 0x5401); | 876 | static DEFINE_STRARRAY_OFFSET(tioctls, 0x5401); |
877 | #endif /* defined(__i386__) || defined(__x86_64__) */ | ||
863 | 878 | ||
864 | #define STRARRAY(arg, name, array) \ | 879 | #define STRARRAY(arg, name, array) \ |
865 | .arg_scnprintf = { [arg] = SCA_STRARRAY, }, \ | 880 | .arg_scnprintf = { [arg] = SCA_STRARRAY, }, \ |
@@ -941,9 +956,16 @@ static struct syscall_fmt { | |||
941 | { .name = "getrlimit", .errmsg = true, STRARRAY(0, resource, rlimit_resources), }, | 956 | { .name = "getrlimit", .errmsg = true, STRARRAY(0, resource, rlimit_resources), }, |
942 | { .name = "ioctl", .errmsg = true, | 957 | { .name = "ioctl", .errmsg = true, |
943 | .arg_scnprintf = { [0] = SCA_FD, /* fd */ | 958 | .arg_scnprintf = { [0] = SCA_FD, /* fd */ |
959 | #if defined(__i386__) || defined(__x86_64__) | ||
960 | /* | ||
961 | * FIXME: Make this available to all arches. | ||
962 | */ | ||
944 | [1] = SCA_STRHEXARRAY, /* cmd */ | 963 | [1] = SCA_STRHEXARRAY, /* cmd */ |
945 | [2] = SCA_HEX, /* arg */ }, | 964 | [2] = SCA_HEX, /* arg */ }, |
946 | .arg_parm = { [1] = &strarray__tioctls, /* cmd */ }, }, | 965 | .arg_parm = { [1] = &strarray__tioctls, /* cmd */ }, }, |
966 | #else | ||
967 | [2] = SCA_HEX, /* arg */ }, }, | ||
968 | #endif | ||
947 | { .name = "kill", .errmsg = true, | 969 | { .name = "kill", .errmsg = true, |
948 | .arg_scnprintf = { [1] = SCA_SIGNUM, /* sig */ }, }, | 970 | .arg_scnprintf = { [1] = SCA_SIGNUM, /* sig */ }, }, |
949 | { .name = "linkat", .errmsg = true, | 971 | { .name = "linkat", .errmsg = true, |
diff --git a/tools/perf/config/Makefile b/tools/perf/config/Makefile index c48d44958172..0331ea2701a3 100644 --- a/tools/perf/config/Makefile +++ b/tools/perf/config/Makefile | |||
@@ -478,7 +478,7 @@ else | |||
478 | endif | 478 | endif |
479 | 479 | ||
480 | ifeq ($(feature-libbfd), 1) | 480 | ifeq ($(feature-libbfd), 1) |
481 | EXTLIBS += -lbfd | 481 | EXTLIBS += -lbfd -lz -liberty |
482 | endif | 482 | endif |
483 | 483 | ||
484 | ifdef NO_DEMANGLE | 484 | ifdef NO_DEMANGLE |
diff --git a/tools/perf/config/feature-checks/Makefile b/tools/perf/config/feature-checks/Makefile index 12e551346fa6..523b7bc10553 100644 --- a/tools/perf/config/feature-checks/Makefile +++ b/tools/perf/config/feature-checks/Makefile | |||
@@ -121,7 +121,7 @@ test-libpython-version.bin: | |||
121 | $(BUILD) $(FLAGS_PYTHON_EMBED) | 121 | $(BUILD) $(FLAGS_PYTHON_EMBED) |
122 | 122 | ||
123 | test-libbfd.bin: | 123 | test-libbfd.bin: |
124 | $(BUILD) -DPACKAGE='"perf"' -lbfd -ldl | 124 | $(BUILD) -DPACKAGE='"perf"' -lbfd -lz -liberty -ldl |
125 | 125 | ||
126 | test-liberty.bin: | 126 | test-liberty.bin: |
127 | $(CC) -o $(OUTPUT)$@ test-libbfd.c -DPACKAGE='"perf"' -lbfd -ldl -liberty | 127 | $(CC) -o $(OUTPUT)$@ test-libbfd.c -DPACKAGE='"perf"' -lbfd -ldl -liberty |
diff --git a/tools/perf/design.txt b/tools/perf/design.txt index 67e5d0cace85..63a0e6f04a01 100644 --- a/tools/perf/design.txt +++ b/tools/perf/design.txt | |||
@@ -454,7 +454,6 @@ So to start with, in order to add HAVE_PERF_EVENTS to your Kconfig, you | |||
454 | will need at least this: | 454 | will need at least this: |
455 | - asm/perf_event.h - a basic stub will suffice at first | 455 | - asm/perf_event.h - a basic stub will suffice at first |
456 | - support for atomic64 types (and associated helper functions) | 456 | - support for atomic64 types (and associated helper functions) |
457 | - set_perf_event_pending() implemented | ||
458 | 457 | ||
459 | If your architecture does have hardware capabilities, you can override the | 458 | If your architecture does have hardware capabilities, you can override the |
460 | weak stub hw_perf_event_init() to register hardware counters. | 459 | weak stub hw_perf_event_init() to register hardware counters. |
diff --git a/tools/perf/perf.h b/tools/perf/perf.h index 7daa806d9050..e84fa26bc1be 100644 --- a/tools/perf/perf.h +++ b/tools/perf/perf.h | |||
@@ -100,8 +100,8 @@ | |||
100 | 100 | ||
101 | #ifdef __aarch64__ | 101 | #ifdef __aarch64__ |
102 | #define mb() asm volatile("dmb ish" ::: "memory") | 102 | #define mb() asm volatile("dmb ish" ::: "memory") |
103 | #define wmb() asm volatile("dmb ishld" ::: "memory") | 103 | #define wmb() asm volatile("dmb ishst" ::: "memory") |
104 | #define rmb() asm volatile("dmb ishst" ::: "memory") | 104 | #define rmb() asm volatile("dmb ishld" ::: "memory") |
105 | #define cpu_relax() asm volatile("yield" ::: "memory") | 105 | #define cpu_relax() asm volatile("yield" ::: "memory") |
106 | #endif | 106 | #endif |
107 | 107 | ||
diff --git a/tools/perf/tests/vmlinux-kallsyms.c b/tools/perf/tests/vmlinux-kallsyms.c index 2bd13edcbc17..3d9088003a5b 100644 --- a/tools/perf/tests/vmlinux-kallsyms.c +++ b/tools/perf/tests/vmlinux-kallsyms.c | |||
@@ -26,7 +26,6 @@ int test__vmlinux_matches_kallsyms(void) | |||
26 | struct map *kallsyms_map, *vmlinux_map; | 26 | struct map *kallsyms_map, *vmlinux_map; |
27 | struct machine kallsyms, vmlinux; | 27 | struct machine kallsyms, vmlinux; |
28 | enum map_type type = MAP__FUNCTION; | 28 | enum map_type type = MAP__FUNCTION; |
29 | struct ref_reloc_sym ref_reloc_sym = { .name = "_stext", }; | ||
30 | u64 mem_start, mem_end; | 29 | u64 mem_start, mem_end; |
31 | 30 | ||
32 | /* | 31 | /* |
@@ -70,14 +69,6 @@ int test__vmlinux_matches_kallsyms(void) | |||
70 | */ | 69 | */ |
71 | kallsyms_map = machine__kernel_map(&kallsyms, type); | 70 | kallsyms_map = machine__kernel_map(&kallsyms, type); |
72 | 71 | ||
73 | sym = map__find_symbol_by_name(kallsyms_map, ref_reloc_sym.name, NULL); | ||
74 | if (sym == NULL) { | ||
75 | pr_debug("dso__find_symbol_by_name "); | ||
76 | goto out; | ||
77 | } | ||
78 | |||
79 | ref_reloc_sym.addr = UM(sym->start); | ||
80 | |||
81 | /* | 72 | /* |
82 | * Step 5: | 73 | * Step 5: |
83 | * | 74 | * |
@@ -89,7 +80,6 @@ int test__vmlinux_matches_kallsyms(void) | |||
89 | } | 80 | } |
90 | 81 | ||
91 | vmlinux_map = machine__kernel_map(&vmlinux, type); | 82 | vmlinux_map = machine__kernel_map(&vmlinux, type); |
92 | map__kmap(vmlinux_map)->ref_reloc_sym = &ref_reloc_sym; | ||
93 | 83 | ||
94 | /* | 84 | /* |
95 | * Step 6: | 85 | * Step 6: |
diff --git a/tools/perf/util/annotate.c b/tools/perf/util/annotate.c index 469eb679fb9d..3aa555ff9d89 100644 --- a/tools/perf/util/annotate.c +++ b/tools/perf/util/annotate.c | |||
@@ -8,6 +8,8 @@ | |||
8 | */ | 8 | */ |
9 | 9 | ||
10 | #include "util.h" | 10 | #include "util.h" |
11 | #include "ui/ui.h" | ||
12 | #include "sort.h" | ||
11 | #include "build-id.h" | 13 | #include "build-id.h" |
12 | #include "color.h" | 14 | #include "color.h" |
13 | #include "cache.h" | 15 | #include "cache.h" |
@@ -489,7 +491,7 @@ static int symbol__inc_addr_samples(struct symbol *sym, struct map *map, | |||
489 | { | 491 | { |
490 | struct annotation *notes; | 492 | struct annotation *notes; |
491 | 493 | ||
492 | if (sym == NULL || use_browser != 1 || !sort__has_sym) | 494 | if (sym == NULL) |
493 | return 0; | 495 | return 0; |
494 | 496 | ||
495 | notes = symbol__annotation(sym); | 497 | notes = symbol__annotation(sym); |
@@ -1399,3 +1401,8 @@ int hist_entry__annotate(struct hist_entry *he, size_t privsize) | |||
1399 | { | 1401 | { |
1400 | return symbol__annotate(he->ms.sym, he->ms.map, privsize); | 1402 | return symbol__annotate(he->ms.sym, he->ms.map, privsize); |
1401 | } | 1403 | } |
1404 | |||
1405 | bool ui__has_annotation(void) | ||
1406 | { | ||
1407 | return use_browser == 1 && sort__has_sym; | ||
1408 | } | ||
diff --git a/tools/perf/util/annotate.h b/tools/perf/util/annotate.h index b2aef59d6bb2..56ad4f5287de 100644 --- a/tools/perf/util/annotate.h +++ b/tools/perf/util/annotate.h | |||
@@ -151,6 +151,8 @@ void symbol__annotate_zero_histogram(struct symbol *sym, int evidx); | |||
151 | void symbol__annotate_decay_histogram(struct symbol *sym, int evidx); | 151 | void symbol__annotate_decay_histogram(struct symbol *sym, int evidx); |
152 | void disasm__purge(struct list_head *head); | 152 | void disasm__purge(struct list_head *head); |
153 | 153 | ||
154 | bool ui__has_annotation(void); | ||
155 | |||
154 | int symbol__tty_annotate(struct symbol *sym, struct map *map, | 156 | int symbol__tty_annotate(struct symbol *sym, struct map *map, |
155 | struct perf_evsel *evsel, bool print_lines, | 157 | struct perf_evsel *evsel, bool print_lines, |
156 | bool full_paths, int min_pcnt, int max_lines); | 158 | bool full_paths, int min_pcnt, int max_lines); |
diff --git a/tools/perf/util/event.c b/tools/perf/util/event.c index 1fc1c2f04772..b0f3ca850e9e 100644 --- a/tools/perf/util/event.c +++ b/tools/perf/util/event.c | |||
@@ -470,23 +470,32 @@ static int find_symbol_cb(void *arg, const char *name, char type, | |||
470 | return 1; | 470 | return 1; |
471 | } | 471 | } |
472 | 472 | ||
473 | u64 kallsyms__get_function_start(const char *kallsyms_filename, | ||
474 | const char *symbol_name) | ||
475 | { | ||
476 | struct process_symbol_args args = { .name = symbol_name, }; | ||
477 | |||
478 | if (kallsyms__parse(kallsyms_filename, &args, find_symbol_cb) <= 0) | ||
479 | return 0; | ||
480 | |||
481 | return args.start; | ||
482 | } | ||
483 | |||
473 | int perf_event__synthesize_kernel_mmap(struct perf_tool *tool, | 484 | int perf_event__synthesize_kernel_mmap(struct perf_tool *tool, |
474 | perf_event__handler_t process, | 485 | perf_event__handler_t process, |
475 | struct machine *machine, | 486 | struct machine *machine) |
476 | const char *symbol_name) | ||
477 | { | 487 | { |
478 | size_t size; | 488 | size_t size; |
479 | const char *filename, *mmap_name; | 489 | const char *mmap_name; |
480 | char path[PATH_MAX]; | ||
481 | char name_buff[PATH_MAX]; | 490 | char name_buff[PATH_MAX]; |
482 | struct map *map; | 491 | struct map *map; |
492 | struct kmap *kmap; | ||
483 | int err; | 493 | int err; |
484 | /* | 494 | /* |
485 | * We should get this from /sys/kernel/sections/.text, but till that is | 495 | * We should get this from /sys/kernel/sections/.text, but till that is |
486 | * available use this, and after it is use this as a fallback for older | 496 | * available use this, and after it is use this as a fallback for older |
487 | * kernels. | 497 | * kernels. |
488 | */ | 498 | */ |
489 | struct process_symbol_args args = { .name = symbol_name, }; | ||
490 | union perf_event *event = zalloc((sizeof(event->mmap) + | 499 | union perf_event *event = zalloc((sizeof(event->mmap) + |
491 | machine->id_hdr_size)); | 500 | machine->id_hdr_size)); |
492 | if (event == NULL) { | 501 | if (event == NULL) { |
@@ -502,30 +511,19 @@ int perf_event__synthesize_kernel_mmap(struct perf_tool *tool, | |||
502 | * see kernel/perf_event.c __perf_event_mmap | 511 | * see kernel/perf_event.c __perf_event_mmap |
503 | */ | 512 | */ |
504 | event->header.misc = PERF_RECORD_MISC_KERNEL; | 513 | event->header.misc = PERF_RECORD_MISC_KERNEL; |
505 | filename = "/proc/kallsyms"; | ||
506 | } else { | 514 | } else { |
507 | event->header.misc = PERF_RECORD_MISC_GUEST_KERNEL; | 515 | event->header.misc = PERF_RECORD_MISC_GUEST_KERNEL; |
508 | if (machine__is_default_guest(machine)) | ||
509 | filename = (char *) symbol_conf.default_guest_kallsyms; | ||
510 | else { | ||
511 | sprintf(path, "%s/proc/kallsyms", machine->root_dir); | ||
512 | filename = path; | ||
513 | } | ||
514 | } | ||
515 | |||
516 | if (kallsyms__parse(filename, &args, find_symbol_cb) <= 0) { | ||
517 | free(event); | ||
518 | return -ENOENT; | ||
519 | } | 516 | } |
520 | 517 | ||
521 | map = machine->vmlinux_maps[MAP__FUNCTION]; | 518 | map = machine->vmlinux_maps[MAP__FUNCTION]; |
519 | kmap = map__kmap(map); | ||
522 | size = snprintf(event->mmap.filename, sizeof(event->mmap.filename), | 520 | size = snprintf(event->mmap.filename, sizeof(event->mmap.filename), |
523 | "%s%s", mmap_name, symbol_name) + 1; | 521 | "%s%s", mmap_name, kmap->ref_reloc_sym->name) + 1; |
524 | size = PERF_ALIGN(size, sizeof(u64)); | 522 | size = PERF_ALIGN(size, sizeof(u64)); |
525 | event->mmap.header.type = PERF_RECORD_MMAP; | 523 | event->mmap.header.type = PERF_RECORD_MMAP; |
526 | event->mmap.header.size = (sizeof(event->mmap) - | 524 | event->mmap.header.size = (sizeof(event->mmap) - |
527 | (sizeof(event->mmap.filename) - size) + machine->id_hdr_size); | 525 | (sizeof(event->mmap.filename) - size) + machine->id_hdr_size); |
528 | event->mmap.pgoff = args.start; | 526 | event->mmap.pgoff = kmap->ref_reloc_sym->addr; |
529 | event->mmap.start = map->start; | 527 | event->mmap.start = map->start; |
530 | event->mmap.len = map->end - event->mmap.start; | 528 | event->mmap.len = map->end - event->mmap.start; |
531 | event->mmap.pid = machine->pid; | 529 | event->mmap.pid = machine->pid; |
diff --git a/tools/perf/util/event.h b/tools/perf/util/event.h index faf6e219be21..851fa06f4a42 100644 --- a/tools/perf/util/event.h +++ b/tools/perf/util/event.h | |||
@@ -214,8 +214,7 @@ int perf_event__synthesize_threads(struct perf_tool *tool, | |||
214 | struct machine *machine, bool mmap_data); | 214 | struct machine *machine, bool mmap_data); |
215 | int perf_event__synthesize_kernel_mmap(struct perf_tool *tool, | 215 | int perf_event__synthesize_kernel_mmap(struct perf_tool *tool, |
216 | perf_event__handler_t process, | 216 | perf_event__handler_t process, |
217 | struct machine *machine, | 217 | struct machine *machine); |
218 | const char *symbol_name); | ||
219 | 218 | ||
220 | int perf_event__synthesize_modules(struct perf_tool *tool, | 219 | int perf_event__synthesize_modules(struct perf_tool *tool, |
221 | perf_event__handler_t process, | 220 | perf_event__handler_t process, |
@@ -279,4 +278,7 @@ size_t perf_event__fprintf_mmap2(union perf_event *event, FILE *fp); | |||
279 | size_t perf_event__fprintf_task(union perf_event *event, FILE *fp); | 278 | size_t perf_event__fprintf_task(union perf_event *event, FILE *fp); |
280 | size_t perf_event__fprintf(union perf_event *event, FILE *fp); | 279 | size_t perf_event__fprintf(union perf_event *event, FILE *fp); |
281 | 280 | ||
281 | u64 kallsyms__get_function_start(const char *kallsyms_filename, | ||
282 | const char *symbol_name); | ||
283 | |||
282 | #endif /* __PERF_RECORD_H */ | 284 | #endif /* __PERF_RECORD_H */ |
diff --git a/tools/perf/util/include/asm/hash.h b/tools/perf/util/include/asm/hash.h new file mode 100644 index 000000000000..d82b170bb216 --- /dev/null +++ b/tools/perf/util/include/asm/hash.h | |||
@@ -0,0 +1,6 @@ | |||
1 | #ifndef __ASM_GENERIC_HASH_H | ||
2 | #define __ASM_GENERIC_HASH_H | ||
3 | |||
4 | /* Stub */ | ||
5 | |||
6 | #endif /* __ASM_GENERIC_HASH_H */ | ||
diff --git a/tools/perf/util/include/linux/bitops.h b/tools/perf/util/include/linux/bitops.h index 45cf10a562bd..dadfa7e54287 100644 --- a/tools/perf/util/include/linux/bitops.h +++ b/tools/perf/util/include/linux/bitops.h | |||
@@ -87,13 +87,15 @@ static __always_inline unsigned long __ffs(unsigned long word) | |||
87 | return num; | 87 | return num; |
88 | } | 88 | } |
89 | 89 | ||
90 | typedef const unsigned long __attribute__((__may_alias__)) long_alias_t; | ||
91 | |||
90 | /* | 92 | /* |
91 | * Find the first set bit in a memory region. | 93 | * Find the first set bit in a memory region. |
92 | */ | 94 | */ |
93 | static inline unsigned long | 95 | static inline unsigned long |
94 | find_first_bit(const unsigned long *addr, unsigned long size) | 96 | find_first_bit(const unsigned long *addr, unsigned long size) |
95 | { | 97 | { |
96 | const unsigned long *p = addr; | 98 | long_alias_t *p = (long_alias_t *) addr; |
97 | unsigned long result = 0; | 99 | unsigned long result = 0; |
98 | unsigned long tmp; | 100 | unsigned long tmp; |
99 | 101 | ||
diff --git a/tools/perf/util/machine.c b/tools/perf/util/machine.c index ded74590b92f..c872991e0f65 100644 --- a/tools/perf/util/machine.c +++ b/tools/perf/util/machine.c | |||
@@ -496,19 +496,22 @@ static int symbol__in_kernel(void *arg, const char *name, | |||
496 | return 1; | 496 | return 1; |
497 | } | 497 | } |
498 | 498 | ||
499 | static void machine__get_kallsyms_filename(struct machine *machine, char *buf, | ||
500 | size_t bufsz) | ||
501 | { | ||
502 | if (machine__is_default_guest(machine)) | ||
503 | scnprintf(buf, bufsz, "%s", symbol_conf.default_guest_kallsyms); | ||
504 | else | ||
505 | scnprintf(buf, bufsz, "%s/proc/kallsyms", machine->root_dir); | ||
506 | } | ||
507 | |||
499 | /* Figure out the start address of kernel map from /proc/kallsyms */ | 508 | /* Figure out the start address of kernel map from /proc/kallsyms */ |
500 | static u64 machine__get_kernel_start_addr(struct machine *machine) | 509 | static u64 machine__get_kernel_start_addr(struct machine *machine) |
501 | { | 510 | { |
502 | const char *filename; | 511 | char filename[PATH_MAX]; |
503 | char path[PATH_MAX]; | ||
504 | struct process_args args; | 512 | struct process_args args; |
505 | 513 | ||
506 | if (machine__is_default_guest(machine)) | 514 | machine__get_kallsyms_filename(machine, filename, PATH_MAX); |
507 | filename = (char *)symbol_conf.default_guest_kallsyms; | ||
508 | else { | ||
509 | sprintf(path, "%s/proc/kallsyms", machine->root_dir); | ||
510 | filename = path; | ||
511 | } | ||
512 | 515 | ||
513 | if (symbol__restricted_filename(filename, "/proc/kallsyms")) | 516 | if (symbol__restricted_filename(filename, "/proc/kallsyms")) |
514 | return 0; | 517 | return 0; |
@@ -829,9 +832,25 @@ static int machine__create_modules(struct machine *machine) | |||
829 | return 0; | 832 | return 0; |
830 | } | 833 | } |
831 | 834 | ||
835 | const char *ref_reloc_sym_names[] = {"_text", "_stext", NULL}; | ||
836 | |||
832 | int machine__create_kernel_maps(struct machine *machine) | 837 | int machine__create_kernel_maps(struct machine *machine) |
833 | { | 838 | { |
834 | struct dso *kernel = machine__get_kernel(machine); | 839 | struct dso *kernel = machine__get_kernel(machine); |
840 | char filename[PATH_MAX]; | ||
841 | const char *name; | ||
842 | u64 addr = 0; | ||
843 | int i; | ||
844 | |||
845 | machine__get_kallsyms_filename(machine, filename, PATH_MAX); | ||
846 | |||
847 | for (i = 0; (name = ref_reloc_sym_names[i]) != NULL; i++) { | ||
848 | addr = kallsyms__get_function_start(filename, name); | ||
849 | if (addr) | ||
850 | break; | ||
851 | } | ||
852 | if (!addr) | ||
853 | return -1; | ||
835 | 854 | ||
836 | if (kernel == NULL || | 855 | if (kernel == NULL || |
837 | __machine__create_kernel_maps(machine, kernel) < 0) | 856 | __machine__create_kernel_maps(machine, kernel) < 0) |
@@ -850,6 +869,13 @@ int machine__create_kernel_maps(struct machine *machine) | |||
850 | * Now that we have all the maps created, just set the ->end of them: | 869 | * Now that we have all the maps created, just set the ->end of them: |
851 | */ | 870 | */ |
852 | map_groups__fixup_end(&machine->kmaps); | 871 | map_groups__fixup_end(&machine->kmaps); |
872 | |||
873 | if (maps__set_kallsyms_ref_reloc_sym(machine->vmlinux_maps, name, | ||
874 | addr)) { | ||
875 | machine__destroy_kernel_maps(machine); | ||
876 | return -1; | ||
877 | } | ||
878 | |||
853 | return 0; | 879 | return 0; |
854 | } | 880 | } |
855 | 881 | ||
diff --git a/tools/perf/util/machine.h b/tools/perf/util/machine.h index 477133015440..f77e91e483dc 100644 --- a/tools/perf/util/machine.h +++ b/tools/perf/util/machine.h | |||
@@ -18,6 +18,8 @@ union perf_event; | |||
18 | #define HOST_KERNEL_ID (-1) | 18 | #define HOST_KERNEL_ID (-1) |
19 | #define DEFAULT_GUEST_KERNEL_ID (0) | 19 | #define DEFAULT_GUEST_KERNEL_ID (0) |
20 | 20 | ||
21 | extern const char *ref_reloc_sym_names[]; | ||
22 | |||
21 | struct machine { | 23 | struct machine { |
22 | struct rb_node rb_node; | 24 | struct rb_node rb_node; |
23 | pid_t pid; | 25 | pid_t pid; |
diff --git a/tools/perf/util/map.c b/tools/perf/util/map.c index 3b97513f0e77..39cd2d0faff6 100644 --- a/tools/perf/util/map.c +++ b/tools/perf/util/map.c | |||
@@ -39,6 +39,7 @@ void map__init(struct map *map, enum map_type type, | |||
39 | map->start = start; | 39 | map->start = start; |
40 | map->end = end; | 40 | map->end = end; |
41 | map->pgoff = pgoff; | 41 | map->pgoff = pgoff; |
42 | map->reloc = 0; | ||
42 | map->dso = dso; | 43 | map->dso = dso; |
43 | map->map_ip = map__map_ip; | 44 | map->map_ip = map__map_ip; |
44 | map->unmap_ip = map__unmap_ip; | 45 | map->unmap_ip = map__unmap_ip; |
@@ -288,7 +289,7 @@ u64 map__rip_2objdump(struct map *map, u64 rip) | |||
288 | if (map->dso->rel) | 289 | if (map->dso->rel) |
289 | return rip - map->pgoff; | 290 | return rip - map->pgoff; |
290 | 291 | ||
291 | return map->unmap_ip(map, rip); | 292 | return map->unmap_ip(map, rip) - map->reloc; |
292 | } | 293 | } |
293 | 294 | ||
294 | /** | 295 | /** |
@@ -311,7 +312,7 @@ u64 map__objdump_2mem(struct map *map, u64 ip) | |||
311 | if (map->dso->rel) | 312 | if (map->dso->rel) |
312 | return map->unmap_ip(map, ip + map->pgoff); | 313 | return map->unmap_ip(map, ip + map->pgoff); |
313 | 314 | ||
314 | return ip; | 315 | return ip + map->reloc; |
315 | } | 316 | } |
316 | 317 | ||
317 | void map_groups__init(struct map_groups *mg) | 318 | void map_groups__init(struct map_groups *mg) |
diff --git a/tools/perf/util/map.h b/tools/perf/util/map.h index 18068c6b71c1..257e513205ce 100644 --- a/tools/perf/util/map.h +++ b/tools/perf/util/map.h | |||
@@ -36,6 +36,7 @@ struct map { | |||
36 | bool erange_warned; | 36 | bool erange_warned; |
37 | u32 priv; | 37 | u32 priv; |
38 | u64 pgoff; | 38 | u64 pgoff; |
39 | u64 reloc; | ||
39 | u32 maj, min; /* only valid for MMAP2 record */ | 40 | u32 maj, min; /* only valid for MMAP2 record */ |
40 | u64 ino; /* only valid for MMAP2 record */ | 41 | u64 ino; /* only valid for MMAP2 record */ |
41 | u64 ino_generation;/* only valid for MMAP2 record */ | 42 | u64 ino_generation;/* only valid for MMAP2 record */ |
diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c index d248fca6d7ed..1e15df10a88c 100644 --- a/tools/perf/util/parse-events.c +++ b/tools/perf/util/parse-events.c | |||
@@ -1091,12 +1091,12 @@ int is_valid_tracepoint(const char *event_string) | |||
1091 | static bool is_event_supported(u8 type, unsigned config) | 1091 | static bool is_event_supported(u8 type, unsigned config) |
1092 | { | 1092 | { |
1093 | bool ret = true; | 1093 | bool ret = true; |
1094 | int open_return; | ||
1094 | struct perf_evsel *evsel; | 1095 | struct perf_evsel *evsel; |
1095 | struct perf_event_attr attr = { | 1096 | struct perf_event_attr attr = { |
1096 | .type = type, | 1097 | .type = type, |
1097 | .config = config, | 1098 | .config = config, |
1098 | .disabled = 1, | 1099 | .disabled = 1, |
1099 | .exclude_kernel = 1, | ||
1100 | }; | 1100 | }; |
1101 | struct { | 1101 | struct { |
1102 | struct thread_map map; | 1102 | struct thread_map map; |
@@ -1108,7 +1108,20 @@ static bool is_event_supported(u8 type, unsigned config) | |||
1108 | 1108 | ||
1109 | evsel = perf_evsel__new(&attr); | 1109 | evsel = perf_evsel__new(&attr); |
1110 | if (evsel) { | 1110 | if (evsel) { |
1111 | ret = perf_evsel__open(evsel, NULL, &tmap.map) >= 0; | 1111 | open_return = perf_evsel__open(evsel, NULL, &tmap.map); |
1112 | ret = open_return >= 0; | ||
1113 | |||
1114 | if (open_return == -EACCES) { | ||
1115 | /* | ||
1116 | * This happens if the paranoid value | ||
1117 | * /proc/sys/kernel/perf_event_paranoid is set to 2 | ||
1118 | * Re-run with exclude_kernel set; we don't do that | ||
1119 | * by default as some ARM machines do not support it. | ||
1120 | * | ||
1121 | */ | ||
1122 | evsel->attr.exclude_kernel = 1; | ||
1123 | ret = perf_evsel__open(evsel, NULL, &tmap.map) >= 0; | ||
1124 | } | ||
1112 | perf_evsel__delete(evsel); | 1125 | perf_evsel__delete(evsel); |
1113 | } | 1126 | } |
1114 | 1127 | ||
diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c index a8a9b6cd93a8..d8b048c20cde 100644 --- a/tools/perf/util/probe-event.c +++ b/tools/perf/util/probe-event.c | |||
@@ -336,8 +336,8 @@ static int add_exec_to_probe_trace_events(struct probe_trace_event *tevs, | |||
336 | return ret; | 336 | return ret; |
337 | 337 | ||
338 | for (i = 0; i < ntevs && ret >= 0; i++) { | 338 | for (i = 0; i < ntevs && ret >= 0; i++) { |
339 | /* point.address is the addres of point.symbol + point.offset */ | ||
339 | offset = tevs[i].point.address - stext; | 340 | offset = tevs[i].point.address - stext; |
340 | offset += tevs[i].point.offset; | ||
341 | tevs[i].point.offset = 0; | 341 | tevs[i].point.offset = 0; |
342 | zfree(&tevs[i].point.symbol); | 342 | zfree(&tevs[i].point.symbol); |
343 | ret = e_snprintf(buf, 32, "0x%lx", offset); | 343 | ret = e_snprintf(buf, 32, "0x%lx", offset); |
diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c index 0b39a48e5110..5da6ce74c676 100644 --- a/tools/perf/util/session.c +++ b/tools/perf/util/session.c | |||
@@ -1008,6 +1008,12 @@ static int perf_session__process_user_event(struct perf_session *session, union | |||
1008 | if (err == 0) | 1008 | if (err == 0) |
1009 | perf_session__set_id_hdr_size(session); | 1009 | perf_session__set_id_hdr_size(session); |
1010 | return err; | 1010 | return err; |
1011 | case PERF_RECORD_HEADER_EVENT_TYPE: | ||
1012 | /* | ||
1013 | * Depreceated, but we need to handle it for sake | ||
1014 | * of old data files create in pipe mode. | ||
1015 | */ | ||
1016 | return 0; | ||
1011 | case PERF_RECORD_HEADER_TRACING_DATA: | 1017 | case PERF_RECORD_HEADER_TRACING_DATA: |
1012 | /* setup for reading amidst mmap */ | 1018 | /* setup for reading amidst mmap */ |
1013 | lseek(fd, file_offset, SEEK_SET); | 1019 | lseek(fd, file_offset, SEEK_SET); |
diff --git a/tools/perf/util/symbol-elf.c b/tools/perf/util/symbol-elf.c index 759456728703..3e9f336740fa 100644 --- a/tools/perf/util/symbol-elf.c +++ b/tools/perf/util/symbol-elf.c | |||
@@ -751,6 +751,8 @@ int dso__load_sym(struct dso *dso, struct map *map, | |||
751 | if (strcmp(elf_name, kmap->ref_reloc_sym->name)) | 751 | if (strcmp(elf_name, kmap->ref_reloc_sym->name)) |
752 | continue; | 752 | continue; |
753 | kmap->ref_reloc_sym->unrelocated_addr = sym.st_value; | 753 | kmap->ref_reloc_sym->unrelocated_addr = sym.st_value; |
754 | map->reloc = kmap->ref_reloc_sym->addr - | ||
755 | kmap->ref_reloc_sym->unrelocated_addr; | ||
754 | break; | 756 | break; |
755 | } | 757 | } |
756 | } | 758 | } |
@@ -922,6 +924,7 @@ int dso__load_sym(struct dso *dso, struct map *map, | |||
922 | (u64)shdr.sh_offset); | 924 | (u64)shdr.sh_offset); |
923 | sym.st_value -= shdr.sh_addr - shdr.sh_offset; | 925 | sym.st_value -= shdr.sh_addr - shdr.sh_offset; |
924 | } | 926 | } |
927 | new_symbol: | ||
925 | /* | 928 | /* |
926 | * We need to figure out if the object was created from C++ sources | 929 | * We need to figure out if the object was created from C++ sources |
927 | * DWARF DW_compile_unit has this, but we don't always have access | 930 | * DWARF DW_compile_unit has this, but we don't always have access |
@@ -933,7 +936,6 @@ int dso__load_sym(struct dso *dso, struct map *map, | |||
933 | if (demangled != NULL) | 936 | if (demangled != NULL) |
934 | elf_name = demangled; | 937 | elf_name = demangled; |
935 | } | 938 | } |
936 | new_symbol: | ||
937 | f = symbol__new(sym.st_value, sym.st_size, | 939 | f = symbol__new(sym.st_value, sym.st_size, |
938 | GELF_ST_BIND(sym.st_info), elf_name); | 940 | GELF_ST_BIND(sym.st_info), elf_name); |
939 | free(demangled); | 941 | free(demangled); |
diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c index 39ce9adbaaf0..e89afc097d8a 100644 --- a/tools/perf/util/symbol.c +++ b/tools/perf/util/symbol.c | |||
@@ -627,7 +627,7 @@ static int dso__split_kallsyms_for_kcore(struct dso *dso, struct map *map, | |||
627 | * kernel range is broken in several maps, named [kernel].N, as we don't have | 627 | * kernel range is broken in several maps, named [kernel].N, as we don't have |
628 | * the original ELF section names vmlinux have. | 628 | * the original ELF section names vmlinux have. |
629 | */ | 629 | */ |
630 | static int dso__split_kallsyms(struct dso *dso, struct map *map, | 630 | static int dso__split_kallsyms(struct dso *dso, struct map *map, u64 delta, |
631 | symbol_filter_t filter) | 631 | symbol_filter_t filter) |
632 | { | 632 | { |
633 | struct map_groups *kmaps = map__kmap(map)->kmaps; | 633 | struct map_groups *kmaps = map__kmap(map)->kmaps; |
@@ -692,6 +692,12 @@ static int dso__split_kallsyms(struct dso *dso, struct map *map, | |||
692 | char dso_name[PATH_MAX]; | 692 | char dso_name[PATH_MAX]; |
693 | struct dso *ndso; | 693 | struct dso *ndso; |
694 | 694 | ||
695 | if (delta) { | ||
696 | /* Kernel was relocated at boot time */ | ||
697 | pos->start -= delta; | ||
698 | pos->end -= delta; | ||
699 | } | ||
700 | |||
695 | if (count == 0) { | 701 | if (count == 0) { |
696 | curr_map = map; | 702 | curr_map = map; |
697 | goto filter_symbol; | 703 | goto filter_symbol; |
@@ -721,6 +727,10 @@ static int dso__split_kallsyms(struct dso *dso, struct map *map, | |||
721 | curr_map->map_ip = curr_map->unmap_ip = identity__map_ip; | 727 | curr_map->map_ip = curr_map->unmap_ip = identity__map_ip; |
722 | map_groups__insert(kmaps, curr_map); | 728 | map_groups__insert(kmaps, curr_map); |
723 | ++kernel_range; | 729 | ++kernel_range; |
730 | } else if (delta) { | ||
731 | /* Kernel was relocated at boot time */ | ||
732 | pos->start -= delta; | ||
733 | pos->end -= delta; | ||
724 | } | 734 | } |
725 | filter_symbol: | 735 | filter_symbol: |
726 | if (filter && filter(curr_map, pos)) { | 736 | if (filter && filter(curr_map, pos)) { |
@@ -976,6 +986,23 @@ static int validate_kcore_modules(const char *kallsyms_filename, | |||
976 | return 0; | 986 | return 0; |
977 | } | 987 | } |
978 | 988 | ||
989 | static int validate_kcore_addresses(const char *kallsyms_filename, | ||
990 | struct map *map) | ||
991 | { | ||
992 | struct kmap *kmap = map__kmap(map); | ||
993 | |||
994 | if (kmap->ref_reloc_sym && kmap->ref_reloc_sym->name) { | ||
995 | u64 start; | ||
996 | |||
997 | start = kallsyms__get_function_start(kallsyms_filename, | ||
998 | kmap->ref_reloc_sym->name); | ||
999 | if (start != kmap->ref_reloc_sym->addr) | ||
1000 | return -EINVAL; | ||
1001 | } | ||
1002 | |||
1003 | return validate_kcore_modules(kallsyms_filename, map); | ||
1004 | } | ||
1005 | |||
979 | struct kcore_mapfn_data { | 1006 | struct kcore_mapfn_data { |
980 | struct dso *dso; | 1007 | struct dso *dso; |
981 | enum map_type type; | 1008 | enum map_type type; |
@@ -1019,8 +1046,8 @@ static int dso__load_kcore(struct dso *dso, struct map *map, | |||
1019 | kallsyms_filename)) | 1046 | kallsyms_filename)) |
1020 | return -EINVAL; | 1047 | return -EINVAL; |
1021 | 1048 | ||
1022 | /* All modules must be present at their original addresses */ | 1049 | /* Modules and kernel must be present at their original addresses */ |
1023 | if (validate_kcore_modules(kallsyms_filename, map)) | 1050 | if (validate_kcore_addresses(kallsyms_filename, map)) |
1024 | return -EINVAL; | 1051 | return -EINVAL; |
1025 | 1052 | ||
1026 | md.dso = dso; | 1053 | md.dso = dso; |
@@ -1113,15 +1140,41 @@ out_err: | |||
1113 | return -EINVAL; | 1140 | return -EINVAL; |
1114 | } | 1141 | } |
1115 | 1142 | ||
1143 | /* | ||
1144 | * If the kernel is relocated at boot time, kallsyms won't match. Compute the | ||
1145 | * delta based on the relocation reference symbol. | ||
1146 | */ | ||
1147 | static int kallsyms__delta(struct map *map, const char *filename, u64 *delta) | ||
1148 | { | ||
1149 | struct kmap *kmap = map__kmap(map); | ||
1150 | u64 addr; | ||
1151 | |||
1152 | if (!kmap->ref_reloc_sym || !kmap->ref_reloc_sym->name) | ||
1153 | return 0; | ||
1154 | |||
1155 | addr = kallsyms__get_function_start(filename, | ||
1156 | kmap->ref_reloc_sym->name); | ||
1157 | if (!addr) | ||
1158 | return -1; | ||
1159 | |||
1160 | *delta = addr - kmap->ref_reloc_sym->addr; | ||
1161 | return 0; | ||
1162 | } | ||
1163 | |||
1116 | int dso__load_kallsyms(struct dso *dso, const char *filename, | 1164 | int dso__load_kallsyms(struct dso *dso, const char *filename, |
1117 | struct map *map, symbol_filter_t filter) | 1165 | struct map *map, symbol_filter_t filter) |
1118 | { | 1166 | { |
1167 | u64 delta = 0; | ||
1168 | |||
1119 | if (symbol__restricted_filename(filename, "/proc/kallsyms")) | 1169 | if (symbol__restricted_filename(filename, "/proc/kallsyms")) |
1120 | return -1; | 1170 | return -1; |
1121 | 1171 | ||
1122 | if (dso__load_all_kallsyms(dso, filename, map) < 0) | 1172 | if (dso__load_all_kallsyms(dso, filename, map) < 0) |
1123 | return -1; | 1173 | return -1; |
1124 | 1174 | ||
1175 | if (kallsyms__delta(map, filename, &delta)) | ||
1176 | return -1; | ||
1177 | |||
1125 | symbols__fixup_duplicate(&dso->symbols[map->type]); | 1178 | symbols__fixup_duplicate(&dso->symbols[map->type]); |
1126 | symbols__fixup_end(&dso->symbols[map->type]); | 1179 | symbols__fixup_end(&dso->symbols[map->type]); |
1127 | 1180 | ||
@@ -1133,7 +1186,7 @@ int dso__load_kallsyms(struct dso *dso, const char *filename, | |||
1133 | if (!dso__load_kcore(dso, map, filename)) | 1186 | if (!dso__load_kcore(dso, map, filename)) |
1134 | return dso__split_kallsyms_for_kcore(dso, map, filter); | 1187 | return dso__split_kallsyms_for_kcore(dso, map, filter); |
1135 | else | 1188 | else |
1136 | return dso__split_kallsyms(dso, map, filter); | 1189 | return dso__split_kallsyms(dso, map, delta, filter); |
1137 | } | 1190 | } |
1138 | 1191 | ||
1139 | static int dso__load_perf_map(struct dso *dso, struct map *map, | 1192 | static int dso__load_perf_map(struct dso *dso, struct map *map, |
@@ -1283,6 +1336,8 @@ int dso__load(struct dso *dso, struct map *map, symbol_filter_t filter) | |||
1283 | 1336 | ||
1284 | if (syms_ss && runtime_ss) | 1337 | if (syms_ss && runtime_ss) |
1285 | break; | 1338 | break; |
1339 | } else { | ||
1340 | symsrc__destroy(ss); | ||
1286 | } | 1341 | } |
1287 | 1342 | ||
1288 | } | 1343 | } |
@@ -1424,7 +1479,7 @@ static int find_matching_kcore(struct map *map, char *dir, size_t dir_sz) | |||
1424 | continue; | 1479 | continue; |
1425 | scnprintf(kallsyms_filename, sizeof(kallsyms_filename), | 1480 | scnprintf(kallsyms_filename, sizeof(kallsyms_filename), |
1426 | "%s/%s/kallsyms", dir, dent->d_name); | 1481 | "%s/%s/kallsyms", dir, dent->d_name); |
1427 | if (!validate_kcore_modules(kallsyms_filename, map)) { | 1482 | if (!validate_kcore_addresses(kallsyms_filename, map)) { |
1428 | strlcpy(dir, kallsyms_filename, dir_sz); | 1483 | strlcpy(dir, kallsyms_filename, dir_sz); |
1429 | ret = 0; | 1484 | ret = 0; |
1430 | break; | 1485 | break; |
@@ -1479,7 +1534,7 @@ static char *dso__find_kallsyms(struct dso *dso, struct map *map) | |||
1479 | if (fd != -1) { | 1534 | if (fd != -1) { |
1480 | close(fd); | 1535 | close(fd); |
1481 | /* If module maps match go with /proc/kallsyms */ | 1536 | /* If module maps match go with /proc/kallsyms */ |
1482 | if (!validate_kcore_modules("/proc/kallsyms", map)) | 1537 | if (!validate_kcore_addresses("/proc/kallsyms", map)) |
1483 | goto proc_kallsyms; | 1538 | goto proc_kallsyms; |
1484 | } | 1539 | } |
1485 | 1540 | ||